Commit d5fb474f authored by Marco Mariani's avatar Marco Mariani

docs: small style/content fixes

parent 7ac5b5a8
......@@ -5,6 +5,12 @@
margin-bottom: 0.4em;
}
pre {
padding-left: 15px;
padding-righ: 15px;
}
a.button {
-moz-border-radius:6px;
......
<h4><a href="./getting_started.html#download-fork" style="color:#008800">Downloads</a></h4>
<h4><a href="./getting_started.html">Getting Started</a></h4>
......@@ -55,7 +55,8 @@ NB: digest **is not implemented yet**.
.. code-block:: javascript
dav_storage.createDescription(url, auth_type, [realm], [username], [password]);
dav_storage.createDescription(url, auth_type,
[realm], [username], [password]);
All parameters are strings.
......@@ -103,17 +104,20 @@ Here is the description:
{
"type": "index",
"indices": [{
"id": "index_title_subject.json", // doc id where to store indices
"index": ["title", "subject"], // metadata to index
// doc id where to store indices
"id": "index_title_subject.json",
// metadata to index
"index": ["title", "subject"],
"attachment": "db.json", // default "body"
"metadata": { // additional metadata to add to database, default undefined
// additional metadata to add to database, default undefined
"metadata": {
"type": "Dataset",
"format": "application/json",
"title": "My index database",
"creator": "Me"
},
// default equal to parent sub_storage field
"sub_storage": <sub storage where to store index>
// default equal to parent sub_storage field
}, {
"id": "index_year.json",
"index": "year"
......
......@@ -6,7 +6,7 @@ What are Complex Queries?
In jIO, a complex query can ask a storage server to select, filter, sort, or
limit a document list before sending it back. If the server is not able to do
so, the complex query tool can act on the retreived list by itself. Only the
so, the complex query tool can do the filtering by itself on the client. Only the
``allDocs()`` method can use complex queries.
A query can either be a string (using a specific language useful for writing
......@@ -25,16 +25,15 @@ Complex queries can be used like database queries, for tasks such as:
For some storages (like localStorage), complex queries can be a powerful tool
to query accessible documents. When querying documents on a distant storage,
some server-side logic should be run to avoid having to request large amount of
documents to run a query on the client. If distant storages are static, an
alternative would be to use an indexStorage with appropriate indices as complex
queries will always try to run the query on the index before querying documents
itself.
some server-side logic should be run to avoid returning too many documents
to the client. If distant storages are static, an alternative would be to use
an indexStorage with appropriate indices as complex queries will always try
to run the query on the index before querying documents itself.
How to use Complex Queries with jIO?
------------------------------------
Complex queries can be triggered by including the option named query in the ``allDocs()`` method call.
Complex queries can be triggered by including the option named **query** in the ``allDocs()`` method call.
Example:
......@@ -64,7 +63,10 @@ Example:
options = {
query: '(creator:"% Doe") AND (format:"pdf")',
limit: [0, 100],
sort_on: [['last_modified', 'descending'], ['creation_date', 'descending']],
sort_on: [
['last_modified', 'descending'],
['creation_date', 'descending']
],
select_list: ['title'],
wildcard_character: '%'
};
......@@ -86,15 +88,20 @@ for how to use these methods, in and outside jIO. The module provides:
{
parseStringToObject: [Function: parseStringToObject],
stringEscapeRegexpCharacters: [Function: stringEscapeRegexpCharacters],
stringEscapeRegexpCharacters:
[Function: stringEscapeRegexpCharacters],
select: [Function: select],
sortOn: [Function: sortOn],
limit: [Function: limit],
convertStringToRegExp: [Function: convertStringToRegExp],
QueryFactory: { [Function: QueryFactory] create: [Function] },
Query: [Function: Query],
SimpleQuery: { [Function: SimpleQuery] super_: [Function: Query] },
ComplexQuery: { [Function: ComplexQuery] super_: [Function: Query] }
SimpleQuery: {
[Function: SimpleQuery] super_: [Function: Query]
},
ComplexQuery: {
[Function: ComplexQuery] super_: [Function: Query]
}
}
(Reference API coming soon.)
......@@ -113,7 +120,8 @@ Basic example:
var query = 'title: "Document number 1"';
// running the query
var result = complex_queries.QueryFactory.create(query).exec(object_list);
var result = complex_queries.QueryFactory.
create(query).exec(object_list);
// console.log(result);
// [ { "title": "Document number 1", "creator": "John Doe"} ]
......@@ -132,8 +140,12 @@ Other example:
}
);
// this case is equal to:
var result = complex_queries.QueryFactory.create(query).exec(object_list);
complex_queries.sortOn([['title', 'ascending'], ['year', 'descending']], result);
var result = complex_queries.QueryFactory.
create(query).exec(object_list);
complex_queries.sortOn([
['title', 'ascending'],
['year', 'descending']
], result);
complex_queries.limit([20, 20], result);
complex_queries.select(['title', 'year'], result);
......@@ -179,7 +191,8 @@ Example, convert Query object into a human readable string:
.. code-block:: javascript
var query = complex_queries.QueryFactory.create('year: < 2000 OR title: "*a"'),
var query = complex_queries.QueryFactory.
create('year: < 2000 OR title: "*a"'),
option = {
"wildcard_character": "*",
"limit": [0, 10]
......@@ -196,19 +209,24 @@ Example, convert Query object into a human readable string:
query.onParseStart = function (object, option) {
object.start = "The wildcard character is '" +
(option.wildcard_character || "%") +
"' and we need only the " + option.limit[1] + " elements from the numero " +
"' and we need only the " +
option.limit[1] +
" elements from the number " +
option.limit[0] + ". ";
};
query.onParseSimpleQuery = function (object, option) {
object.parsed = object.parsed.key + " " + human_read[object.parsed.operator] +
object.parsed = object.parsed.key +
" " + human_read[object.parsed.operator] +
object.parsed.value;
};
query.onParseComplexQuery = function (object, option) {
object.parsed = "I want all document where " +
object.parsed.query_list.join(" " + object.parsed.operator.toLowerCase() +
" ") + ". ";
object.parsed.query_list.join(" " +
object.parsed.operator.toLowerCase() +
" ") +
". ";
};
query.onParseEnd = function (object, option) {
......@@ -216,8 +234,9 @@ Example, convert Query object into a human readable string:
};
console.log(query.parse(option));
// logged: "The wildcard character is '*' and we need only the 10 elements
// from the numero 0. I want all document where year is lower than 2000 or title
// logged: "The wildcard character is '*' and we need
// only the 10 elements from the number 0. I want all
// document where year is lower than 2000 or title
// matches *a. Thank you!"
......@@ -237,7 +256,7 @@ Below you can find schemas for constructing queries.
"type": "string",
"format": "complex",
"default": "complex",
"description": "The type is used to recognize the query type."
"description": "Type is used to recognize the query type"
},
"operator": {
"type": "string",
......@@ -252,7 +271,9 @@ Below you can find schemas for constructing queries.
},
"required": true,
"default": [],
"description": "query_list is a list of queries which can be in serialized format of in object format."
"description": "query_list is a list of queries which " +
"can be in serialized format " +
"or in object format."
}
}
}
......@@ -269,7 +290,7 @@ Below you can find schemas for constructing queries.
"type": "string",
"format": "simple",
"default": "simple",
"description": "The type is used to recognize the query type."
"description": "Type is used to recognize the query type."
},
"operator": {
"type": "string",
......
......@@ -19,7 +19,7 @@ To build the library you have to:
* Compile JS/CC parser.
``$ make`` (until we find how to compile it with grunt)
``$ make`` (until we find out how to compile it with grunt)
* Run build.
......@@ -44,7 +44,8 @@ Create a constructor:
function MyStorage(storage_description) {
this._value = storage_description.value;
if (typeof this._value !== 'string') {
throw new TypeError("'value' description property is not a string");
throw new TypeError("'value' description property " +
"is not a string");
}
}
......@@ -53,17 +54,17 @@ Create 10 methods: ``post``, ``put``, ``putAttachment``, ``get``, ``getAttachmen
.. code-block:: javascript
MyStorage.prototype.post = function (command, metadata, option) {
MyStorage.prototype.post = function(command, metadata, option) {
var document_id = metadata._id;
// [...]
};
MyStorage.prototype.get = function (command, param, option) {
MyStorage.prototype.get = function(command, param, option) {
var document_id = param._id;
// [...]
};
MyStorage.prototype.putAttachment = function (command, param, option) {
MyStorage.prototype.putAttachment = function(command, param, option) {
var document_id = param._id;
var attachment_id = param._attachment;
var attachment_data = param._blob;
......@@ -99,21 +100,21 @@ The third parameter ``option`` is the option parameter provided by the jIO user.
Methods should return the following objects:
* post --> success("created", {"id": new_generated_id})
* **post()** --> ``success("created", {"id": new_generated_id})``
* put, remove, putAttachment or removeAttachment --> success(204)
* **put()**, ``remove``, ``putAttachment`` or ``removeAttachment`` --> ``success(204)``
* get --> success("ok", {"data": document_metadata})
* **get()** --> ``success("ok", {"data": document_metadata})``
* getAttachment -->
* **getAttachment()** -->
success("ok", {"data": binary_string, "content_type": content_type})
``success("ok", {"data": binary_string, "content_type": content_type})``
// or
success("ok", {"data": new Blob([data], {"type": content_type})})
``success("ok", {"data": new Blob([data], {"type": content_type})})``
* allDocs --> success("ok", {"data": row_object})
* **allDocs()** --> ``success("ok", {"data": row_object})``
* check -->
* **check()** -->
.. code-block:: javascript
......@@ -123,7 +124,7 @@ Methods should return the following objects:
// or
error("conflict", "corrupted", "incoherent document or storage")
* repair -->
* **repair()** -->
.. code-block:: javascript
......@@ -131,8 +132,10 @@ Methods should return the following objects:
// if metadata doesn't promides "_id" -> repair storage state
success("no_content")
// or
error("conflict", "corrupted", "impossible to repair document or storage")
// DON'T DESIGN STORAGES IF THEIR IS NO WAY TO REPAIR INCOHERENT STATES
error("conflict", "corrupted",
"impossible to repair document or storage")
// DON'T DESIGN STORAGES IF THERE IS NO WAY
// TO REPAIR INCOHERENT STATES
After creating all methods, your storage must be added to jIO. This is done
with the ``jIO.addStorage()`` method, which requires two parameters: the storage
......@@ -205,7 +208,7 @@ The following actions can be used:
* ``update`` - bind the selected job to this one
* ``deny`` - reject the job
The following condition function can be used:
The following condition functions can be used:
* ``sameStorageDescription`` - check if the storage descriptions are different.
* ``areWriters`` - check if the commands are ``post``, ``put``, ``putAttachment``, ``remove``, ``removeAttachment``, or ``repair``.
......@@ -226,19 +229,24 @@ You can create two types of function: job condition, and job comparison.
// Job Condition
// Check if the job is a get command
jIO.addJobRuleCondition("isGetMethod", function (job) {
return job.method === 'get';
});
// Job Comparison
// Check if the jobs have the same 'title' property only if they are strings
jIO.addJobRuleCondition("sameTitleIfString", function (job, selected_job) {
if (typeof job.kwargs.title === 'string' &&
typeof selected_job.kwargs.title === 'string') {
return job.kwargs.title === selected_job.kwargs.title;
}
return false;
});
// Check if the jobs have the same 'title' property
// only if they are strings
jIO.addJobRuleCondition("sameTitleIfString",
function (job, selected_job) {
if (typeof job.kwargs.title === 'string' &&
typeof selected_job.kwargs.title === 'string') {
return job.kwargs.title === selected_job.kwargs.title;
}
return false;
});
Add job rules
......@@ -248,8 +256,9 @@ You just have to define job rules in the jIO options:
.. code-block:: javascript
// Do not accept to post or put a document which title is equal to another
// already running post or put document title
// Do not accept to post or put a document which title is equal
// to another already running post or put document title
var jio_instance = jIO.createJIO(storage_description, {
"job_rules": [{
"code_name": "avoid similar title",
......
......@@ -5,17 +5,14 @@
Getting started
===============
This walkthrough is designed to get you started using a basic jIO instance.
#. Download jIO core, the storages you want to use as well as the
complex-queries scripts and the dependencies required for the storages
you intend to use. :ref:`[Download & Fork] <download-fork>`
#. :ref:`Download <download-fork>` the core jIO, the storages you need and the
dependencies required for them.
#. Add the scripts to your HTML page in the following order:
.. code-block:: html
<!-- jio core + dependency -->
<!-- jio core + dependencies -->
<script src="sha256.amd.js"></script>
<script src="rsvp-custom.js"></script>
<script src="jio.js"></script>
......@@ -63,20 +60,30 @@ This walkthrough is designed to get you started using a basic jIO instance.
#. The jIO API provides ten main methods to manage documents across the storage(s) specified in your jIO storage tree.
====================== ===================================================== ========================================
Method Example call Description
====================== ===================================================== ========================================
``post()`` :js:`my_jio.post(document, [options]);` Creates a new document
``put()`` :js:`my_jio.put(document, [options]);` Creates/Updates a document
``putAttachment()`` :js:`my_jio.putAttachement(attachment, [options]);` Updates/Adds an attachment to a document
``get()`` :js:`my_jio.get(document, [options]);` Reads a document
``getAttachment()`` :js:`my_jio.getAttachment(attachment, [options]);` Reads a document attachment
``remove()`` :js:`my_jio.remove(document, [options]);` Deletes a document and its attachments
``removeAttachment()`` :js:`my_jio.removeAttachment(attachment, [options]);` Deletes a document attachment
``allDocs()`` :js:`my_jio.allDocs([options]);` Retrieves a list of existing documents
``check()`` :js:`my_jio.check(document, [options]);` Check the document state
``repair()`` :js:`my_jio.repair(document, [options]);` Repair the document
====================== ===================================================== ========================================
====================== ========================================================
Method Example
====================== ========================================================
``post()`` | :js:`my_jio.post(document, [options]);`
| Creates a new document
``put()`` | :js:`my_jio.put(document, [options]);`
| Creates/Updates a document
``putAttachment()`` | :js:`my_jio.putAttachement(attachment, [options]);`
| Updates/Adds an attachment to a document
``get()`` | :js:`my_jio.get(document, [options]);`
| Reads a document
``getAttachment()`` | :js:`my_jio.getAttachment(attachment, [options]);`
| Reads a document attachment
``remove()`` | :js:`my_jio.remove(document, [options]);`
| Deletes a document and its attachments
``removeAttachment()`` | :js:`my_jio.removeAttachment(attachment, [options]);`
| Deletes a document's attachment
``allDocs()`` | :js:`my_jio.allDocs([options]);`
| Retrieves a list of existing documents
``check()`` | :js:`my_jio.check(document, [options]);`
| Check the document state
``repair()`` | :js:`my_jio.repair(document, [options]);`
| Repair the document
====================== ========================================================
......
......@@ -98,7 +98,10 @@ metadata object can contain several values. Example:
// or
"key": ["value1", "value2"],
// or
"key": {"attribute name": "attribute value", "content": "value"},
"key": {
"attribute name": "attribute value",
"content": "value"
},
// or
"key": [
{"scheme": "DCTERMS.URI", "content": "http://foo.com/bar"},
......
......@@ -2,8 +2,7 @@ How to manage documents?
========================
jIO is mapped after the CouchDB APIs and extends them to provide unified, scalable
and high performance access via JavaScript to a wide variety of different
storage backends.
and high performance access via JavaScript to a wide variety of storage backends.
If you are not familiar with `Apache CouchDB <http://couchdb.apache.org/>`_:
it is a scalable, fault-tolerant, and schema-free document-oriented database.
......@@ -17,11 +16,11 @@ What is a document?
-------------------
A document is an association of metadata and attachment(s). The metadata is the
set of properties of the document and the attachments are the binaries of the content
of the document.
set of properties of the document and the attachments are binary (or text) objects
that represent the content of the document.
In jIO, metadata is just a dictionary with keys and values (JSON object), and
attachments are just simple strings.
In jIO, the metadata is a dictionary with keys and values (a JSON object), and
attachments are simple strings.
.. code-block:: javascript
......@@ -58,7 +57,7 @@ Basic Methods
-------------
Below you can see examples of the main jIO methods. All examples are using
revisions (as in revision storage or replicate revision storage), so you can
revisions (as in revision storage or replicated revision storage), so you can
see how method calls should be made with either of these storages.
.. code-block:: javascript
......@@ -79,8 +78,10 @@ see how method calls should be made with either of these storages.
});
// add an attachment to a document
jio_instance.putAttachment({"_id": "my_document", "_attachment": "its_attachment",
"_data": "abc", "_mimetype": "text/plain"}).
jio_instance.putAttachment({"_id": "my_document",
"_attachment": "its_attachment",
"_data": "abc",
"_mimetype": "text/plain"}).
then(function (response) {
// console.log(response);
});
......@@ -92,7 +93,8 @@ see how method calls should be made with either of these storages.
});
// read an attachment
jio_instance.getAttachment({"_id": "my_document", "_attachment": "its_attachment"}).
jio_instance.getAttachment({"_id": "my_document",
"_attachment": "its_attachment"}).
then(function (response) {
// console.log(response);
});
......@@ -104,7 +106,8 @@ see how method calls should be made with either of these storages.
});
// delete an attachment
jio_instance.removeAttachment({"_id": "my_document", "_attachment": "its_attachment"}).
jio_instance.removeAttachment({"_id": "my_document",
"_attachment": "its_attachment"}).
then(function (response) {
// console.log(response);
});
......@@ -137,8 +140,10 @@ To retrieve jIO responses, you have to provide callbacks like this:
.. code-block:: javascript
jio_instance.post(metadata, [options]).
then([responseCallback], [errorCallback], [progressionCallback]);
jio_instance.post(metadata, [options]).
then([responseCallback],
[errorCallback],
[progressionCallback]);
* On command success, ``responseCallback`` will be called with the jIO response as first parameter.
......@@ -253,10 +258,10 @@ In case of error, the ``errorCallback`` first parameter will look like:
Example: How to store a video on localStorage
---------------------------------------------
How to store a video on localStorage
------------------------------------
The following shows how to create a new jIO in localStorage and then post a document with two attachments.
The following example shows how to create a new jIO in localStorage and then post a document with two attachments.
.. code-block:: javascript
......
This diff is collapsed.
......@@ -44,12 +44,12 @@ Bad Example
}
Use JSLint
^^^^^^^^^^
Using JSLint
^^^^^^^^^^^^
`JSLint <http://www.jslint.com/>`_ is a quality tool that inspects code and warns
about potential problems. It is available online and can also be integrated
into several development environments, so errors will be highlighted when
into several development environments, so errors can be highlighted when
writing code.
Before validating your code in JSLint, you should use a code
......@@ -59,9 +59,14 @@ are a number of beautifiers available online. The following ones seem to work be
* `JSbeautifier.org <http://jsbeautifier.org/>`_
* `JS-Beautify <http://alexis.m2osw.com/js-beautify/>`_
In this project, JavaScript sources have to begin with the header: :js:`/*jslint indent: 2,
maxlen: 80, nomen: true */`, which means it uses two spaces indentation, 80
maximum characters per line and the use of '_' as first character in a variable name is allowed.
In this project, JavaScript sources have to begin with the header:
.. code-block:: javascript
/*jslint indent: 2, maxlen: 80, nomen: true */
which means it uses two spaces indentation, 80
maximum characters per line and allows variable names starting with '_'.
Other JSLint options can be added in sub functions if necessary.
Some allowed options are:
......@@ -77,7 +82,7 @@ Some allowed options are:
Coding Conventions
------------------
Coding conventions include generic patterns that ensure that written code follows certain formatting conventions.
Coding conventions include generic patterns that ensure the written code follows certain formatting conventions.
Uses two-space indentation
......@@ -502,8 +507,8 @@ Additional Readings
Resources, additional reading materials and links:
* `JavaScript Patterns <http://shop.oreilly.com/product/9780596806767.do>`_, main ressource used.
* `JSLint <http://www.jslint.com/>`_, code quality.
* `JavaScript Patterns <http://shop.oreilly.com/product/9780596806767.do>`_, main resource used.
* `JSLint <http://www.jslint.com/>`_, code quality tool.
* `YUIDoc <http://yuilibrary.com/projects/yuidoc>`_, generate documentation from code.
......@@ -5,7 +5,7 @@ Revision Storages: Conflicts and Resolution
Why Conflicts can Occur
-----------------------
Using jIO you can store documents in multiple storage locations. With
Using jIO you can store documents in multiple locations. With an
increasing number of users working on a document and some storages not being
available or responding too slow, conflicts are more likely to occur. jIO
defines a conflict as multiple versions of a document existing in a storage
......@@ -26,7 +26,7 @@ will select the **latest**, **left-most** version on the document tree, along wi
conflicting versions (when option **conflicts: true** is set in order for
developers to setup a routine to solve conflicts.
Technically a conflict is solved by deleting alternative versions of a document
Technically, a conflict is solved by deleting alternative versions of a document
("cutting leaves off from the document tree"). When a user decides to keep a
version of a document and manually deletes all conflicting versions, the
storage tree is updated accordingly and the document is available in a single
......@@ -35,13 +35,15 @@ version on all storages.
Simple Conflict Example
-----------------------
.. TODO this is a little confusing
You are keeping a namecard file on your PC updating from your smartphone. Your
smartphone ran out of battery and is offline when you update your namecard on
your PC with your new email adress. Someone else changes this email from your PC
and once your smartphone is recharged, you go back online and the previous
update is executed.
#. Set up the storage tree
#. Set up the storage tree:
.. code-block:: javascript
......@@ -64,7 +66,7 @@ update is executed.
});
#. Create the namecard on your smartphone
#. Create the namecard on your smartphone:
.. code-block:: javascript
......@@ -76,9 +78,9 @@ update is executed.
// response.rev -> "1-5782E71F1E4BF698FA3793D9D5A96393"
});
This will create the document on your webDav and local storage
This will create the document on your WebDAV and local storage
#. Someone else updates your shared namecard on Webdav
#. Someone else updates your shared namecard on WebDAV:
.. code-block:: javascript
......@@ -92,9 +94,9 @@ update is executed.
});
Your smartphone is offline, so now you will have one version (1-578...) on
your smartphone and another version on webDav (2-068...) on your PC.
your smartphone and another version on WebDAV (2-068...) on your PC.
#. You modify the namecard while being offline
#. You modify the namecard while being offline:
.. code-block:: javascript
......@@ -114,7 +116,7 @@ update is executed.
});
#. Later, your smartphone is online and you retrieve the other version of the namecard.
#. Later, your smartphone is online and you retrieve the other version of the namecard:
.. code-block:: javascript
......@@ -128,7 +130,7 @@ update is executed.
left-most version on the document tree (2-375... and labels all other
versions as conflicting 2-068...).
#. Retrieve conflicts by setting option
#. Retrieve conflicts by setting option:
.. code-block:: javascript
......@@ -143,7 +145,7 @@ update is executed.
The conflicting version (*2-068E...*) is displayed, because **{conflicts: true}** was
specified in the GET call. Deleting either version will solve the conflict.
#. Delete conflicting version
#. Delete conflicting version:
.. code-block:: javascript
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment