JSONStore provides API reference
information for Cordova Android, iOS, Windows 8
Universal, and native Android and iOS applications.
Store
Open and initialize a collection
Starts
one or more collections. Starting or provisioning a JSONStore collection
means that the persistent storage that is used to contain collections
and documents is created, if it does not exist. If the store is encrypted
and a correct password is passed, the required security procedures
to make the data accessible are run. There is minimal effort in initializing
all the collections when an application starts.
After you open
a collection, an accessor to the collection is available, which gives
access to collection APIs. It allows developers to call functions
such as find, add, and replace on
an initialized collection.
It is possible to initialize multiple
times with different collections. New collections are initialized
without affecting collections that are already initialized.
Destroy
Completely wipes data for all
users, destroys the internal storage, and clears security artifacts.
The
destroy function removes the following data:
Close all
Locks access to all the collections
in a store until the collections are reinitialized. Where initialize can
be considered a login, close can be considered a
logout.
Start, commit, and rollback transaction
A
transaction is a set of operations that must all succeed for the operations
to manipulate the store. If any operation fails, the transaction can
be rolled back to revert the store to its previous state. After a
transaction is started, it is important that you handle committing
or rolling back your transactions to prevent excess processing. Three
operations exist in the
Store API
for transactions:
- Start transaction
- Begin a snapshot in which the store is reverted to if the transaction
fails.
- Commit transaction
- Inform the store that all operations in the transaction succeeded,
and all changes can be finalized.
- Rollback transaction
- Inform the store that an operation in the transaction failed,
and all changes must be discarded.
Note: Due to system limitations with
multi-threaded transactions, transactions are not supported in Android
2.3.x for Cordova applications. To use transactions in a Cordova application
in Android 2.3.x, you can create a Cordova plug-in that uses the native
Android JSONStore API to execute the code for the transaction. The
whole transaction must be done in the same thread because multi-threaded
transactions do not work properly in Android 2.3.x.
Collection
Store and add a document
You can add a
document or array of documents to a collection. You can also pass
an array of objects (for example [{name: 'carlos'}, {name:
'tim'}]) instead of a single object. Every object in the
array is stored as a new document inside the collection.
Remove a document
Marks one or more documents
as removed from a collection. Removed documents are not returned by
the find or count operations.
Find All Documents, Find Documents by Id, and Find
With Query
You can find documents in a collection by their
search fields and extra search fields. An internal search field,
_id,
holds a unique integer identifier that can be used to find the document
(Find by Id). You can search for documents with the following APIs:
- Find All Documents
- Returns every document in a collection.
- Find All Dirty Documents
- Returns every document in a collection that is marked dirty.
- Find by Id
- Find the document with the corresponding _id search
key value.
- Find With Query or Query Parts
- Find all documents that match a query or all query parts. For
more information, see the Search Query format section at Additional references.
Filter returns what is being indexed, which might be
different than what was saved to a collection. Some examples of unexpected
results are:
- If your search field has uppercase letters, the result is returned
in all lowercase letters.
- If you pass something that is not a string, it is indexed as a
string. For example, 1 is '1', 1.0 is '1.0', true is '1',
and false is '0'.
- If your filter criteria includes non top-level search fields,
you might get a single string with all the terms that are joined by
a special identifier (-@-). For example, 'carlos-@-mike-@-dgonz'.
Replace a document and change documents
You
can use the Replace API to replace
the contents of a document in the collection with new data, which
is based on the _id. If the data contains the _id field
of a document in the database, the document is replaced with the data
and all search fields are reindexed for that document.
The Change API
is similar to the Replace API,
but the Replace is based on a
set of search field criteria instead of _id. The Replace API
can be emulated by performing the Change API
with the search field criteria of only _id. All search
fields in the search field criteria must exist in the documents in
the store, and in the data that is passed to the Change API.
Count All Documents, Count All Dirty Documents, and
Count With Query
The
Count API
returns an integer number by counting the total number of documents
that match the query. There are three
Count APIs:
- Count All Documents
- Give the total count of all documents in the collection.
- Count All Dirty Documents
- Give the total number of documents in the collection that are
currently marked dirty.
- Count With Query or Query Parts
- Give the total number of documents that match a specific search
query. For more information, see the Search Query format section at Additional references.
Remove Collection and Clear Collection
Removing
a collection deletes all data that is associated with a collection,
and causes the collection accessor to be no longer usable.
Clearing
a collection deletes all documents in the collection. This operation
keeps the collection open after it completes.
Mark Clean
The Mark Clean API
is used to remove the dirty flag from a document in the collection,
and deletes the document completely from the collection if it was
marked dirty by a remove document operation. The Mark
Clean API is useful when used with the Find
All Dirty Documents API to sync the collection
with a remote database.
Additional references
Search Query format
When an API requires
a search query, a common format is followed for the collection. A
query consists of an array of objects where each key/value pair is
ANDed together. Each object in the array is ORed together. For example:
[{fn: "Mike", age: 30}, {fn: "Carlos", age: 36}]
is
represented as (with fuzzy search):
(fn LIKE "%Mike%" AND age LIKE "%30%") OR (fn LIKE "%Carlos%" AND age LIKE "%36%")
Search Query Parts format
The following
examples use pseudocode to convey how query parts work. A query such
as
{name: 'carlos', age: 10} can be passed a modifier
such as
{exact: true}, which ensures only items that
exactly match name and age are returned. Query parts give you the
flexibility of adding modifiers to any part of the query. For example:
queryPart1 = QueryPart().like('name', 'carlos').lessThan('age', 10);
The
previous example is transformed into something like:
('name' LIKE %carlos%) AND (age < 10)
You
can also create another query part, for example:
queryPart2 = QueryPart().equal('name', 'mike')
When
you add various query parts with the
find API,
for example:
find([queryPart1, queryPart2]
You
get something like:
( ('name' LIKE %carlos%) AND (age < 10) ) OR (name EQUAL 'mike')
Limit and Offset
Passing a limit to an
API's options restricts the number of results by the number specified.
It is also possible to pass an offset to skip results by the number
specified. To pass an offset, a limit must also be passed. This API
is useful for implementing pagination or for optimization. By limiting
the data to a subset that is necessary, the memory and processing
power is reduced.
Fuzzy Search versus Exact Search
The default
behavior is fuzzy searching, which means that queries return partial
results. For example, the query {name: 'carl'} finds 'carlos' and 'carl' (for
example, name LIKE '%carl%'). When {exact:
true} is passed, matches are exact but not case-sensitive.
For example, 'hello' matches 'Hello' (for
example, name.toLowerCase() = 'hello'). Integer matching
is not type-sensitive. For example, "1" matches both "1"
and "1.0". Numbers are stored as their decimal representation.
For example, "1" is stored as "1.0".
Boolean values are indexed as 1 (true) and 0 (false).