• Home
  • Getting Started
  • Documentation
  • API References
  • Downloads
  • Support
Verivo
DevCenter
  • Welcome, Anonymous
  • |
  • Log in
  1. 2.5 Documentation
  2. Data Persistence and Synchronization
  3. Storing Persistent Data on the Client
  4. Implementing Persistence on JavaScript Clients
Printable version    

Documentation

Related Topics

Page: Implementing Persistence on JavaScript Clients
Page: Syncing in a Cordova/JavaScript Client
Page: Handling Synchronization Success and Failure
Page: Storing Persistent Data on the Client
Page: Handling Exceptions and Errors
Page: Allow Cross Origin Requests in a Browser App
Page: Remote Data Access from JavaScript Clients
Page: Encrypting Data in the Persistent Data Store
Page: Route Sync Module
Page: Writing a Custom Sync Module
Page: Synchronization Overview
  

Labels

  • persistence
  • javascript
  • cordova
  • 1_0_1_release

Documentation Downloads

  • Installing and Configuring Akula
  • Building Akula Apps
  • Release Notes

All Versions

Latest Official Version (2.5)
Version 3.0 Beta
Version 2.5
Version 2.1
Version 2.0
Version 1.5
Version 1.0.1
Your Rating: Thanks for voting! Please Wait Please Wait Results: PatheticBadOKGoodOutstanding! 3 rates
Implementing Persistence on Native Clients      Synchronizing Client Data with the Akula Server

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:

ArgumentDescription
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 type argument to "akula-cordova-sqlite-plugin".

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:

MyModel.js

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:

FieldDescription
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 true to specify this field as a primary key. Otherwise, false. The default value is false.

If the isKey field is set to true, then the field is also used as an index.

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:

FieldDescription
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.

ArgumentDescription
entityClassThe name of the data object, or model, that stores data in the schema's structure. For example, "Customer".
schemaThe schema that you want to register.
dataStoreNameThe 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 sync() method calls. This is optional – you can also define the sync endpoint in each sync() method call. For more information, see Syncing in a Cordova/JavaScript Client.

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:

MethodDescriptionPromise 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 AKULA_LOCAL_KEY). The local key is a unique identifier.

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 null.

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.

                                               
 
Implementing Persistence on Native Clients      Synchronizing Client Data with the Akula Server
  • Last edited by rcrouse@verivo.com on 2014-10-17 14:51:38.0

  • Privacy Policy | Legal Information
    © Copyright 2014, Verivo Software, Inc. All Rights Reserved.