Offline and Online Mobile Data Access
Contents |
Introduction
Openbravo Mobile applications use a client side Data Access Layer to work with data. This layer expects to work with Backbone.Model
and Backbone.Collection
as data structures.
A WebSQL database is used to persist data locally in the browser.
Client Side Data Access Layer (DAL)
OB.Dal
is the layer that abstracts the saving/querying/removing Models in Openbravo Web POS. It was designed inspired in the server side Data Access Layer but with two main differences:
- It runs in the client browser
- It has an asynchronous API
API
-
OB.Dal.find(Model, Criteria, successCallback, errorCallback, context)
: Returns aBackbone.Collection
with containing objects matching theCriteria
-
OB.Dal.get(Model, ID, successCallback, errorCallback)
: Returns aBackbone.Model
for the given record ID -
OB.Dal.save(modelInstance, successCallback, errorCallback)
: Saves aBackbone.Model
instance the cache -
OB.Dal.remove(modelInstance, successCallback, errorCallback)
: Removes aBackbone.Model
instance from the cache
API by Example
Querying
// Querying/Finding function success(collection) { window.console.log(collection); } function error(tx) { window.console.error(tx); } OB.Dal.find(OB.Model.TaxRate, null, success, error);
- The
Model
(e.g.OB.Model.TaxRate
) parameter is theBackbone.Model
definition of this entity - The
criteria
object can be null. If null, all objects are retrieved - The
find
returns aBackbone.Collection
// Querying specifying a search criteria function success(collection) { window.console.log(collection); } function error(tx) { window.console.error(tx); } // Using simplified API, defaults to equal OB.Dal.find(OB.Model.TaxRate, { taxSearchKey: 'IVA18' }, success, error); // Using the full API OB.Dal.find(OB.Model.TaxRate, { name: { operator: OB.Dal.CONTAINS, value: '18' } }, success, error);
- The
criteria
is an Object containing a key/value that defaults to equal or a full object using the available operators:-
OB.Dal.EQ
(Equals) -
OB.Dal.NEQ
(Not Equals) -
OB.Dal.CONTAINS
-
OB.Dal.STARTSWITH
-
OB.Dal.ENDSWITH
-
- The
criteria
Object can has attributes to define query options as:-
_whereClause
(append to the sql a where clause) -
_orderByClause
(append to the sql an order by) -
_limit
(append to the sql a limit)
-
Getting by ID
If you know the ID of the object you want, you can use the OB.Dal.get
method.
function success(model) { window.console.log(model); } function error(tx) { window.console.error(tx); } OB.Dal.get(OB.Model.TaxRate, 'D61CD889CF2E42A7B46C935ACA0538FF', success, error);
-
OB.Model.TaxRate
is theBackbone.Model
definition - The second parameter is a String with the UUID of the object you want to retreive
- The
get
returns aBackbone.Model
or null if not found
Saving
When you need to persist a modified object, use OB.Dal.save
function success(tx) { window.console.log(tx); } function error(tx) { window.console.error(tx); } var rateObj = new OB.Model.TaxRate(); rateObj.set('rate', 21); OB.Dal.save(rateObj, save, error);
Removing
To delete/remove an object from the cache, use OB.Dal.remove
function success(tx) { window.console.log(tx); } function error(tx) { window.console.error(tx); } // Finding an object and removing it from the cache OB.Dal.find(OB.Model.TaxRate, { taxSearchKey: 'IVA18' }, function (collection) { // inline callback if(!collection.length) { return; // no record found } OB.Dal.remove(collection.at(0), success, error); }, error);
Finding entering a sql clause
Finding models with more accuracy.
function success(tx) { window.console.log(tx); } function error(tx) { window.console.error(tx); } OB.Dal.query(OB.Model.ProductCharacteristic, 'select distinct(characteristic_id), _identifier from m_product_ch', [], success, error, this);
-
OB.Model.ProductCharacteristic
is theBackbone.Model
definition - The second parameter is a String with the sql you want to launch
- The third parameter is an array of parameters to replace in the sql
- The
query
returns aBackbone.Collection
Model Definition Requirements
To use OB.Dal
, a Web POS Backbone.Model
must have the following properties:
-
modelName
: String - Name of the model in the client, e.g.Product
-
tableName
: String - Name of the table in the WebSQL db, e.g.m_product
-
entityName
: String - Name of the DAL entity in the server, e.g.Product
-
source
: String - Java class name in the server that provides service to the model, e.g.org.openbravo.retail.posterminal.master.Product
-
properties
: Array - Ordered array of String that holds the DAL property names for this model. -
propertyMap
:<String, String>
mapping<property, column name>
-
createStatement
: String - Valid DDL statement to create the table in the WebSQL database. Note: Must follow SQLite conventions -
dropStatement
: String - Valid DDL statement to drop the table in the WebSQL database -
local
: Boolean - Defines if the model is local and only requires the db table -
online
: Boolean - Defines if the model is online and all operations are generate a request to the server
Example of Model definition
ProductCategory = Backbone.Model.extend({ modelName: 'ProductCategory', tableName: 'm_product_category', entityName: 'ProductCategory', source: 'org.openbravo.retail.posterminal.master.Category', properties: ['id', 'searchKey', 'name', 'img', '_identifier', '_idx'], propertyMap: { 'id': 'm_product_category_id', 'searchKey': 'value', 'name': 'name', 'img': 'ad_image_id', '_identifier': '_identifier', '_idx': '_idx' }, createStatement: 'CREATE TABLE IF NOT EXISTS m_product_category (m_product_category_id TEXT PRIMARY KEY , value TEXT , name TEXT , ad_image_id TEXT , _identifier TEXT , _idx NUMERIC)', dropStatement: 'DROP TABLE IF EXISTS m_product_category', insertStatement: 'INSERT INTO m_product_category(m_product_category_id, value, name, ad_image_id, _identifier, _idx) VALUES (?, ?, ?, ?, ?, ?)' });
Automatic Model Generation
The Openbravo Web POS infrastructure provides a way to automatically generate the client side model definition directly from the Application Dictionary definition. For including a client side model you only need to make a request to the OBPOS_Main/ClientModel
component, e.g.
../../org.openbravo.client.kernel/OBPOS_Main/ClientModel?entity=PricingProductPrice&modelName=ProductPrice&source=org.openbravo.retail.posterminal.master.ProductPrice
Notes:
-
entity
: The name of the Entity in DAL (server side) e.g.PricingProductPrice
-
modelName
: The name of the model in the client side e.g.ProductPrice
-
source
: The Java implementation in the server side that provides the data for this model e.g.org.openbravo.retail.posterminal.master.ProductPrice
This request generates the following Model definition automatically:
(function () { var ProductPrice = Backbone.Model.extend({ modelName: 'ProductPrice', tableName: 'm_productprice', entityName: 'PricingProductPrice', source: 'org.openbravo.retail.posterminal.master.ProductPrice', properties: ['id', 'priceListVersion', 'product', 'listPrice', 'standardPrice', 'priceLimit', '_identifier', '_idx'], propertyMap: { 'id': 'm_productprice_id', 'priceListVersion': 'm_pricelist_version_id', 'product': 'm_product_id', 'listPrice': 'pricelist', 'standardPrice': 'pricestd', 'priceLimit': 'pricelimit', '_identifier': '_identifier', '_idx': '_idx' }, createStatement: 'CREATE TABLE IF NOT EXISTS m_productprice (m_productprice_id TEXT PRIMARY KEY , m_pricelist_version_id TEXT /* rest of properties */)', dropStatement: 'DROP TABLE IF EXISTS m_productprice', insertStatement: 'INSERT INTO m_productprice(m_productprice_id, m_pricelist_version_id, m_product_id, pricelist, pricestd, pricelimit, _identifier, _idx) VALUES (?, ?, ?, ?, ?, ?, ?, ?)' }); var ProductPriceList = Backbone.Collection.extend({ model: ProductPrice }); window.OB = window.OB || {}; window.OB.Model = window.OB.Model || {}; window.OB.Collection = window.OB.Collection || {}; window.OB.Model.ProductPrice = ProductPrice; window.OB.Collection.ProductPriceList = ProductPriceList; }());
Local vs Offline vs Online Models
OB.Dal
requires that the Backbone.Model
definition contain some properties, depending on which type of Model you're working with, some properties are required.
What does local and online mean?
When you're working with a local model (local:true
), you only require from the platform the table structure, and you'll create instances of this model in the client side. One example of a local model is OB.Model.Order
. The generation of Order is created in the client side, and then uploaded to the server.
When you're working with a non-local model (local:false
), you want that the platform use the source
property to request data and cache it locally. One example of a non-local model is OB.Model.BusinessPartner
. After a successful login, all the Business Partner available for the POS terminal get downloaded and cached in the client.
The online model (online:true
), you're defining that all operations using OB.Dal
and this model definition, need to happen in the server. An example of this model is the data required for the Cash Management window (e.g. OB.OBPOSCashMgmt.Model.DepositsDrops
).
- When
local
is false: Required model definition -modelName, tableName, entityName, source, properties, propertyMap, createStatement, dropStatement
- When
local
is true: Required model definition -modelName, tableName, entityName, properties, propertyMap, createStatement, dropStatement
- When
online
is true: Required model definition -modelName, source