JSONStore API concepts
JSONStore provides API reference information for hybrid Android, iOS, Windows 8, and Windows Phone 8, 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 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 already initialized.
Destroy
Completely wipes data for all users, destroys the internal storage, and clears security artifacts. The destroy function removes the following data:
- All documents.
- All collections.
- All stores. See JSONStore multiple user support.
- All JSONStore metadata and security artifacts. See JSONStore security.
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 the 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.
Due to system limitations with multi-threaded transactions, transactions are not supported in Android 2.3.x for hybrid applications. To use transactions in a hybrid application in Android 2.3.x, 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
We can add a document or array of documents to a collection. We 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
We can find documents in a collection by their search fields and extra search fields. An internal search field, _id, holds a unique integer identifier used to find the document (Find by Id). We 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. See 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 the search field has upper case letters, the result is returned in all lower-case letters.
- If we 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 the 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
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. See 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)
We can also create another query part, for example:
queryPart2 = QueryPart().equal('name', 'mike')
When we 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).
Parent topic: JSONStore