Documentation
Related Topics

Labels
Documentation Downloads
All Versions
Implementing Persistence on JavaScript Clients
This section provides the following detailed information on implementing client-side persistence for JavaScript-based clients such as those that use Cordova:
- About promises
- Initialize a connection to the data store
- Define a persistent class
- Build the persistence schema for your class
- Initialize the persistence mechanism with a class schema
- Get an instance of AK.PersistenceManager
- Call methods of AK.PersistenceManager to access persistent data
- Close all instances of AK.PersistenceManager
For information about implementing client-side persistence on native iOS and Android clients, see Implementing Persistence on Native Clients.
You must add the Akula JS library and other files to your JavaScript project before you can use Akula's persistence mechanism in a JavaScript app. For information, see Configuring the Client Development Environment.
About promises
The Akula persistence mechanism relies heavily on promises, a way of structuring your callback methods in JavaScript. As a result, you should understand how promises work prior to implementing persistence on a JavaScript client.
Promises provide a simple way to register actions when an asynchronous method is invoked. The actions do not occur immediately, and the thread continues processing, but by registering a promise, you ensure that some action will occur at a later time. The action that occurs later can be a failure, success, or other action such as showing the progress of an asynchronous call.
Akula uses the Q.js library for its promise implementation.
When you call a method that uses promises, you use the then()
core promise method to define and handle the eventual return values. The following shows the signature of the then()
method:
promise.then(onFulfilled, onRejected, onProgress)
You typically use this core promise method in the following way:
persistenceManager.pm_method( args )
.then(success_callback( return_object ) {
// onFulfilled handler
}, failure_callback( return_object ) {
// onRejected handler
}
);
The success_callback
function is invoked if the persistence manager's method executes successfully. In promises, this is sometimes referred to as being fulfilled. The success callback's argument is an object whose structure is defined by the persistence manager method that you called. For example, the add()
method returns a boolean. The getObjects()
method, on the other hand, returns an array of objects.
The failure_callback
function is invoked if the persistence manager's method is rejected. The failure callback's argument specifies the reason for the failure. This object is a string that contains the error message.
You can optionally ignore the return value of a callback by leaving it out of your function call. You might do this when using promises with methods such as close()
or initilializeEntityStore()
. These methods do not return anything.
Akula also supports other core methods of the promises implementation, including done()
, finally()
, catch()
, and progress()
. For additional information about these methods in Q, see the Q API reference.
Initialize a connection to the data store
The persistence data store is the local database where the client reads and writes data to and from.
You must initialize the data store when using Akula's persistence mechanism with JavaScript-based clients such as Cordova. Once initialized, you can open a connection to the data store by its name. The JavaScript persistence mechanism also supports multiple data stores.
To initialize a data store so that you can open a connection to it, use the
AK.PersistenceManager class's static initializeDataStore()
method. In Cordova, for example, you would typically call this method in the deviceready
event handler. This event is triggered when the document and all scripts have been loaded.
The following example initializes a connection to the Akula SQLite data store in the deviceready
event handler:
The initializeDataStore()
method takes three arguments, name,
type
, and options
. The following table describes these arguments:
Argument | Description |
---|---|
name | (Required) The name of the data store. Because the JavaScript persistence mechanism supports multiple data stores, you must give each data store a unique name. |
type | (Required) The plugin that you use to connect to the data store. Akula includes the Cordova SQLite plugin with a file named akula-cordova-sqlite-plugin.js. To use this plugin, set the |
options | (Optional) A JavaScript object that defines plugin-specific creation options. For example, if the data store were encrypted, you might be required to provide an initial passphrase. |
Define a persistent class
Unlike native clients, JavaScript clients can use any object as a model. You do not need to define a new class that represents the data model to the persistence mechanism. Instead, you just create an object and structure your data with that new object.
The following example creates a new object in JavaScript that can be used as a data model:
You later use this object to defines instances of the data. You pass the name of the object as a string to initialize the schema.
Build the persistence schema for your class
You can build the persistence schema for your class in one of the following ways:
- Using the programmatic API
- Using an XML string or file
The following sections describe these two approaches.
Creating a schema programmatically
You can build a schema by using methods of the
AK.SchemaBuilder class. You first create the fields and indexes, and then call the toSchema()
method to validate the schema and get a reference to it.
The following example adds a field and an index to a new schema:
The index field is optional.
Even though this example defines a single index field, it is passed as an array (["custid"]
).
The previous example could also be written like the following by using method chaining:
The addField()
method takes a JavaScript Map with the following fields:
Field | Description |
---|---|
name | (Required) The name of the field. |
type | (Required) The data type for this field. Possible values are "STRING", "INTEGER", "REAL", "BINARY", and "DATE". |
isKey | (Optional) Specifies whether this field is a primary key. Set to If the |
isNullable | (Optional) Specifies whether this field can be null or not. Set to true to allow the field to be null. Otherwise, false . The default value is true . Fields that are defined as primary keys are automatically not nullable, regardless of the value of this argument. |
The addIndex()
method takes a JavaScript Map with the following fields:
Field | Description |
---|---|
name | (Required) The name of the index. |
fields | (Required) A string or a JavaScript Array of field names. |
To remove a field from your schema, call the removeField()
method on the AK.SchemaBuilder class. This method takes a single argument, which is the name of the field that you want to remove.
To remove an index from your schema, use the removeIndex()
method on the AK.SchemaBuilder class. This method takes a single argument, which is the name of the index that you want to remove.
The toSchema()
method returns a schema object that has the following methods:
getFields()
getKeyFields()
getIndexes()
Creating a schema from XML
You can create a schema for JavaScript persistence by using an XML string to create a DOM object. You then pass this object to the AK.SchemaBuilder class.
The following example creates a schema from an XML string:
You can also read in an XML file from the file system and parse it with the DOMParser.
Initialize the persistence mechanism with a class schema
After creating a schema, you register the entity store on the client with the specified schema. You must initialize the entity store with the schema before you can add, remove, or update objects in the data store.
To register the entity store, you call the
AK.PersistenceManager class's static initializeEntityStore()
method.
Argument | Description |
---|---|
entityClass | The name of the data object, or model, that stores data in the schema's structure. For example, "Customer". |
schema | The schema that you want to register. |
dataStoreName | The name of the data store that you want to register this schema with. |
options | (Optional) Additional values that the entity store might require. If you are using sync, you can pass the sync endpoint as an argument. The sync mechanism will use this sync endpoint on all |
The following example initializes the entity store:
Get an instance of AK.PersistenceManager
To get an instance of the
AK.PersistenceManager class in your JavaScript app, call the static AK.PersistenceManger.getInstance()
method .
The following example gets an instance of the AK.PersistenceManager:
This example gets the instance of the persistence manager within the then()
method of the initializeDataStore()
method's promise. You typically do this after the entities and stores are created and registered.
Getting an instance of the persistence manager opens a connection to all data stores that have been registered with it. You can open and use a single connection, or create and use several connections. You must also be sure to clean up your persistence manager instances with the close()
method.
Call methods of AK.PersistenceManager to access persistent data
After you get an instance of the AK.PersistenceManager class, you can then use methods of that class to create, read, update, and delete data in the persistent data store.
The methods of the AK.PersistenceManager class are asynchronous. As a result, these methods return promises, which you can then use to process the results when the results are returned.
The AK.PersistenceManager defines the following methods for accessing persistent data:
Method | Description | Promise onFulfilled Object |
---|---|---|
add() | Inserts a new object into the persistence store. This method takes two arguments, the name of object type to add, and the object itself. The persistence manager automatically adds a local key to each object's row that you add (with the field name | Boolean. true if the add was successful. Otherwise, false . |
remove() | Deletes an object from the persistence store. This method takes two arguments, the name of the object type to delete from the data store, and the object itself. | Boolean. true if the remove was successful. Otherwise, false . |
getObjectByLocalKey() | Gets an object from the persistent storage by its local key. This method takes two arguments, the name of the object type and an ID. | A single object whose structure matches the schema that you defined for the given entity class. This object is populated with the persisted values. If there are no matches to the local key you pass in, Akula returns |
getObjects() | Returns all objects from persistent storage of a specific type. This method takes a single argument, a string that is the name of the object type. | A JavaScript Array of objects. These objects match the schema that you defined for the given entity class. They are populated with the persisted values. If there are no objects matching the type that you pass in, Akula returns an empty Array. |
getObjectsByFilter() | Returns all objects from the persistent storage of a specific type, as long as those objects match a SQL WHERE clause. This method takes three arguments: the object type, the WHERE clause that you use as a filter, and the values to insert into the WHERE clause. | A JavaScript Array of objects. These objects match the schema that you defined for the given entity class. They are populated with the persisted values. If there are no objects matching the type that you pass in or the WHERE clause, Akula returns an empty Array. |
update() | Replaces an object in the persistent store with the new object that you pass in. This method takes two arguments, the name of the object type to replace, and the new object. | Boolean. true if the update was successful. Otherwise, false . |
When adding binary data, you must base-64 encode it prior to adding it to the data store. When getting binary data from the data store, you should decode it.
For each of these methods, the object returned to the onFailure promise is a string that includes the error message.
Examples
The following example defines an object, and then adds a new instance of that object to the persistence store with the add()
method:
The following example updates an existing object in the persistence store with the update()
method:
The following example gets all objects of type Customer:
The following example gets objects of type Customer that also have a last name of "Cumberbatch" by using the getFilteredObjects()
method:
The following example uses promise chaining to get the first returned object from the persistent data store and then delete with the remove()
method:
Close all instances of AK.PersistenceManager
After you use the AK.PersistenceManager, you should explicitly close it to free up any resources that connect to the persistent data store.
To close a connection to the persistence managaer, call the close()
method, as the following example shows:
After closing a persistence manager connection, you must call the getInstance()
method again to open a new connection.