jaydata
Version:
Cross-platform HTML5 data-management, JavaScript Language Query (JSLQ) support for OData, SQLite, WebSQL, IndexedDB, YQL and Facebook (packaged for Node.JS)
943 lines (888 loc) • 46.5 kB
JavaScript
// JayData 1.5.10
// Dual licensed under MIT and GPL v2
// Copyright JayStack Technologies (http://jaydata.org/licensing)
//
// JayData is a standards-based, cross-platform Javascript library and a set of
// practices to access and manipulate data from various online and offline sources.
//
// Credits:
// Hajnalka Battancs, Dániel József, János Roden, László Horváth, Péter Nochta
// Péter Zentai, Róbert Bónay, Szabolcs Czinege, Viktor Borza, Viktor Lázár,
// Zoltán Gyebrovszki, Gábor Dolla
//
// More info: http://jaydata.org
(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define("jaydata/indexeddb",["jaydata/core"],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.$data = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(_dereq_,module,exports){
;
var _core = _dereq_('jaydata/core');
var _core2 = _interopRequireDefault(_core);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
_core2.default.IndexedDBConverter = {
fromDb: {
'$data.Enum': function $dataEnum(v, enumType) {
return _core2.default.Container.convertTo(v, enumType);
},
'$data.Byte': _core2.default.Container.proxyConverter,
'$data.SByte': _core2.default.Container.proxyConverter,
'$data.Decimal': _core2.default.Container.proxyConverter,
'$data.Float': _core2.default.Container.proxyConverter,
'$data.Int16': _core2.default.Container.proxyConverter,
'$data.Int64': _core2.default.Container.proxyConverter,
'$data.Integer': _core2.default.Container.proxyConverter,
'$data.Int32': _core2.default.Container.proxyConverter,
'$data.Number': _core2.default.Container.proxyConverter,
'$data.Date': _core2.default.Container.proxyConverter,
'$data.DateTimeOffset': _core2.default.Container.proxyConverter,
'$data.Duration': _core2.default.Container.proxyConverter,
'$data.Day': _core2.default.Container.proxyConverter,
'$data.Time': _core2.default.Container.proxyConverter,
'$data.String': _core2.default.Container.proxyConverter,
'$data.Boolean': _core2.default.Container.proxyConverter,
'$data.Blob': function $dataBlob(b) {
return b ? _core2.default.Container.convertTo(b, _core2.default.Blob) : b;
},
'$data.Array': function $dataArray(arr) {
if (arr === undefined) {
return new _core2.default.Array();
}return arr;
},
'$data.Object': _core2.default.Container.proxyConverter,
"$data.Guid": function $dataGuid(g) {
return g ? _core2.default.parseGuid(g).toString() : g;
},
'$data.GeographyPoint': function $dataGeographyPoint(g) {
if (g) {
return new _core2.default.GeographyPoint(g);
}return g;
},
'$data.GeographyLineString': function $dataGeographyLineString(g) {
if (g) {
return new _core2.default.GeographyLineString(g);
}return g;
},
'$data.GeographyPolygon': function $dataGeographyPolygon(g) {
if (g) {
return new _core2.default.GeographyPolygon(g);
}return g;
},
'$data.GeographyMultiPoint': function $dataGeographyMultiPoint(g) {
if (g) {
return new _core2.default.GeographyMultiPoint(g);
}return g;
},
'$data.GeographyMultiLineString': function $dataGeographyMultiLineString(g) {
if (g) {
return new _core2.default.GeographyMultiLineString(g);
}return g;
},
'$data.GeographyMultiPolygon': function $dataGeographyMultiPolygon(g) {
if (g) {
return new _core2.default.GeographyMultiPolygon(g);
}return g;
},
'$data.GeographyCollection': function $dataGeographyCollection(g) {
if (g) {
return new _core2.default.GeographyCollection(g);
}return g;
},
'$data.GeometryPoint': function $dataGeometryPoint(g) {
if (g) {
return new _core2.default.GeometryPoint(g);
}return g;
},
'$data.GeometryLineString': function $dataGeometryLineString(g) {
if (g) {
return new _core2.default.GeometryLineString(g);
}return g;
},
'$data.GeometryPolygon': function $dataGeometryPolygon(g) {
if (g) {
return new _core2.default.GeometryPolygon(g);
}return g;
},
'$data.GeometryMultiPoint': function $dataGeometryMultiPoint(g) {
if (g) {
return new _core2.default.GeometryMultiPoint(g);
}return g;
},
'$data.GeometryMultiLineString': function $dataGeometryMultiLineString(g) {
if (g) {
return new _core2.default.GeometryMultiLineString(g);
}return g;
},
'$data.GeometryMultiPolygon': function $dataGeometryMultiPolygon(g) {
if (g) {
return new _core2.default.GeometryMultiPolygon(g);
}return g;
},
'$data.GeometryCollection': function $dataGeometryCollection(g) {
if (g) {
return new _core2.default.GeometryCollection(g);
}return g;
}
},
toDb: {
'$data.Enum': _core2.default.Container.proxyConverter,
'$data.Byte': _core2.default.Container.proxyConverter,
'$data.SByte': _core2.default.Container.proxyConverter,
'$data.Decimal': _core2.default.Container.proxyConverter,
'$data.Float': _core2.default.Container.proxyConverter,
'$data.Int16': _core2.default.Container.proxyConverter,
'$data.Int64': _core2.default.Container.proxyConverter,
'$data.Integer': _core2.default.Container.proxyConverter,
'$data.Int32': _core2.default.Container.proxyConverter,
'$data.Number': _core2.default.Container.proxyConverter,
'$data.Date': _core2.default.Container.proxyConverter,
'$data.DateTimeOffset': _core2.default.Container.proxyConverter,
'$data.Duration': _core2.default.Container.proxyConverter,
'$data.Day': _core2.default.Container.proxyConverter,
'$data.Time': _core2.default.Container.proxyConverter,
'$data.String': _core2.default.Container.proxyConverter,
'$data.Boolean': _core2.default.Container.proxyConverter,
'$data.Blob': function $dataBlob(b) {
return b ? _core2.default.Blob.toString(b) : b;
},
'$data.Array': function $dataArray(arr) {
return arr ? JSON.parse(JSON.stringify(arr)) : arr;
},
'$data.Object': _core2.default.Container.proxyConverter,
"$data.Guid": function $dataGuid(g) {
return g ? g.toString() : g;
},
'$data.GeographyPoint': function $dataGeographyPoint(g) {
if (g) {
return g;
}return g;
},
'$data.GeographyLineString': function $dataGeographyLineString(g) {
if (g) {
return g;
}return g;
},
'$data.GeographyPolygon': function $dataGeographyPolygon(g) {
if (g) {
return g;
}return g;
},
'$data.GeographyMultiPoint': function $dataGeographyMultiPoint(g) {
if (g) {
return g;
}return g;
},
'$data.GeographyMultiLineString': function $dataGeographyMultiLineString(g) {
if (g) {
return g;
}return g;
},
'$data.GeographyMultiPolygon': function $dataGeographyMultiPolygon(g) {
if (g) {
return g;
}return g;
},
'$data.GeographyCollection': function $dataGeographyCollection(g) {
if (g) {
return g;
}return g;
},
'$data.GeometryPoint': function $dataGeometryPoint(g) {
if (g) {
return g;
}return g;
},
'$data.GeometryLineString': function $dataGeometryLineString(g) {
if (g) {
return g;
}return g;
},
'$data.GeometryPolygon': function $dataGeometryPolygon(g) {
if (g) {
return g;
}return g;
},
'$data.GeometryMultiPoint': function $dataGeometryMultiPoint(g) {
if (g) {
return g;
}return g;
},
'$data.GeometryMultiLineString': function $dataGeometryMultiLineString(g) {
if (g) {
return g;
}return g;
},
'$data.GeometryMultiPolygon': function $dataGeometryMultiPolygon(g) {
if (g) {
return g;
}return g;
},
'$data.GeometryCollection': function $dataGeometryCollection(g) {
if (g) {
return g;
}return g;
}
}
};
},{"jaydata/core":"jaydata/core"}],2:[function(_dereq_,module,exports){
;
var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol ? "symbol" : typeof obj; };
var _core = _dereq_('jaydata/core');
var _core2 = _interopRequireDefault(_core);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
_core2.default.Class.define('$data.storageProviders.indexedDb.IndexedDBStorageProvider', _core2.default.StorageProviderBase, null, {
constructor: function constructor(cfg, ctxInstance) {
// mapping IndexedDB types to browser invariant name
this.indexedDB = _core2.default.__global.indexedDB || _core2.default.__global.webkitIndexedDB || _core2.default.__global.mozIndexedDB || _core2.default.__global.msIndexedDB;
this.IDBRequest = _core2.default.__global.IDBRequest || _core2.default.__global.webkitIDBRequest || _core2.default.__global.mozIDBRequest || _core2.default.__global.msIDBRequest;
this.IDBTransaction = _core2.default.__global.IDBTransaction || _core2.default.__global.webkitIDBTransaction || _core2.default.__global.mozIDBTransaction || _core2.default.__global.msIDBTransaction;
this.IDBTransactionType = { READ_ONLY: "readonly", READ_WRITE: "readwrite", VERSIONCHANGE: "versionchange" };
if (typeof this.IDBTransaction.READ_ONLY !== 'undefined' && typeof this.IDBTransaction.READ_WRITE !== 'undefined') {
this.IDBTransactionType.READ_ONLY = this.IDBTransaction.READ_ONLY;
this.IDBTransactionType.READ_WRITE = this.IDBTransaction.READ_WRITE;
}
this.IDBKeyRange = _core2.default.__global.IDBKeyRange || _core2.default.__global.webkitIDBKeyRange || _core2.default.__global.mozIDBKeyRange || _core2.default.__global.msIDBKeyRange;
this.IDBDatabaseException = _core2.default.__global.IDBDatabaseException || _core2.default.__global.webkitIDBDatabaseException || _core2.default.__global.mozIDBDatabaseException || _core2.default.__global.msIDBDatabaseException;
this.IDBOpenDBRequest = _core2.default.__global.IDBOpenDBRequest || _core2.default.__global.webkitIDBOpenDBRequest || _core2.default.__global.mozIDBOpenDBRequest || _core2.default.__global.msIDBOpenDBRequest;
this.newVersionAPI = !!(_core2.default.__global.IDBFactory && IDBFactory.prototype.deleteDatabase);
this.sequenceStore = '__jayData_sequence';
this.SqlCommands = [];
this.context = {};
this.providerConfiguration = _core2.default.typeSystem.extend({
databaseName: _core2.default.defaults.defaultDatabaseName,
version: 1,
dbCreation: _core2.default.storageProviders.DbCreationType.DropTableIfChanged,
memoryOperations: true
}, cfg);
this._setupExtensionMethods();
if (ctxInstance) this.originalContext = ctxInstance.getType();
},
supportedBinaryOperators: {
value: {
equal: { mapTo: ' == ', dataType: _core2.default.Boolean },
notEqual: { mapTo: ' != ', dataType: _core2.default.Boolean },
equalTyped: { mapTo: ' == ', dataType: _core2.default.Boolean },
notEqualTyped: { mapTo: ' != ', dataType: _core2.default.Boolean },
greaterThan: { mapTo: ' > ', dataType: _core2.default.Boolean },
greaterThanOrEqual: { mapTo: ' >= ', dataType: _core2.default.Boolean },
lessThan: { mapTo: ' < ', dataType: _core2.default.Boolean },
lessThenOrEqual: { mapTo: ' <= ', dataType: _core2.default.Boolean },
or: { mapTo: ' || ', dataType: _core2.default.Boolean },
and: { mapTo: ' && ', dataType: _core2.default.Boolean }
//'in': { mapTo: ' in ', dataType: $data.Boolean, resolvableType: [$data.Array, $data.Queryable] }
}
},
supportedSetOperations: {
value: {
length: {},
toArray: {},
forEach: {}
},
enumerable: true,
writable: true
},
supportedFieldOperations: {
value: {},
enumerable: true,
writable: true
},
supportedUnaryOperators: {
value: {},
enumerable: true,
writable: true
},
_setupExtensionMethods: function _setupExtensionMethods() {
/// <summary>
/// Sets the extension method 'setCallback' on IDBRequest, IDBOpenDBRequest, and IDBTransaction types
/// </summary>
var self = this;
var idbRequest = this.IDBRequest;
var idbTran = this.IDBTransaction;
var idbOpenDBRequest = this.IDBOpenDBRequest;
var setCallbacks = function setCallbacks(callbackSettings) {
/// <summary>
/// Sets the callbacks on the object.
/// </summary>
/// <param name="callbackSettings">Named value pairs of the callbacks</param>
if ((typeof callbackSettings === 'undefined' ? 'undefined' : _typeof(callbackSettings)) !== 'object') _core.Guard.raise(new _core.Exception('Invalid callbackSettings', null, callbackSettings));
for (var i in callbackSettings) {
if (typeof this[i] === 'undefined' || typeof callbackSettings[i] !== 'function') continue;
this[i] = callbackSettings[i];
}
//if (this.readyState == self.IDBRequest.DONE)
// console.log('WARNING: request finished before setCallbacks. Do not use breakpoints between creating the request object and finishing the setting of callbacks');
return this;
};
if (idbRequest && typeof idbRequest.prototype.setCallbacks !== 'function') idbRequest.prototype.setCallbacks = setCallbacks;
if (idbTran && typeof idbTran.prototype.setCallbacks !== 'function') idbTran.prototype.setCallbacks = setCallbacks;
if (idbOpenDBRequest && typeof idbOpenDBRequest.prototype.setCallbacks !== 'function') idbOpenDBRequest.prototype.setCallbacks = setCallbacks;
},
supportedDataTypes: {
value: [_core2.default.Integer, _core2.default.Number, _core2.default.Date, _core2.default.String, _core2.default.Boolean, _core2.default.Blob, _core2.default.Array, _core2.default.Object, _core2.default.Guid, _core2.default.GeographyPoint, _core2.default.GeographyLineString, _core2.default.GeographyPolygon, _core2.default.GeographyMultiPoint, _core2.default.GeographyMultiLineString, _core2.default.GeographyMultiPolygon, _core2.default.GeographyCollection, _core2.default.GeometryPoint, _core2.default.GeometryLineString, _core2.default.GeometryPolygon, _core2.default.GeometryMultiPoint, _core2.default.GeometryMultiLineString, _core2.default.GeometryMultiPolygon, _core2.default.GeometryCollection, _core2.default.Byte, _core2.default.SByte, _core2.default.Decimal, _core2.default.Float, _core2.default.Int16, _core2.default.Int32, _core2.default.Int64, _core2.default.Duration, _core2.default.Day, _core2.default.Time, _core2.default.DateTimeOffset],
writable: false
},
fieldConverter: { value: _core2.default.IndexedDBConverter },
supportedAutoincrementKeys: {
value: {
'$data.Integer': true,
'$data.Int32': true,
'$data.Guid': function $dataGuid() {
return _core2.default.createGuid();
}
}
},
_getObjectStoreDefinition: function _getObjectStoreDefinition(setDefinition) {
var contextStore = {
storeName: setDefinition.TableName
};
var keyFields = setDefinition.PhysicalType.memberDefinitions.getKeyProperties();
if (0 == keyFields.length) {
var error = new Error("Entity must have a key field: " + contextStore.storeName);
error.name = "KeyNotFoundError";
throw error;
}
/*if (1 != keyFields.length) {
var error = new Error("Entity must have only one key field: " + contextStore.storeName);
error.name = "MultipleKeysNotSupportedError";
throw error;
}*/
//var keyField = keyFields[0];
/*for (var i = 0; i < keyFields.length; i++) {
if (keyFields[i].computed === true &&
("$data.Integer" !== Container.resolveName(keyFields[i].type))) {
var error = new Error("Computed key field must be of integer type: " + contextStore.storeName);
error.name = "ComputedKeyFieldError";
throw error;
}
if (keyFields.length > 2 && keyFields[i].computed) {
var error = new Error("With multiple keys the computed field is not allowed: " + contextStore.storeName);
error.name = "MultipleComputedKeyFieldError";
throw error;
}
}*/
if (keyFields.length > 2 && keyFields.some(function (memDef) {
return memDef.computed;
})) {
_core.Guard.raise("With multiple keys the computed field is not allowed: " + contextStore.storeName, "MultipleComputedKeyFieldError");
}
for (var i = 0; i < keyFields.length; i++) {
var typeName = _core.Container.resolveName(keyFields[i].type);
if (keyFields[i].computed && !this.supportedAutoincrementKeys[typeName]) {
console.log("WARRNING! '" + typeName + "' not supported as computed Key!");
}
}
contextStore.keyFields = keyFields;
return contextStore;
},
_getObjectStoreDefinitions: function _getObjectStoreDefinitions() {
var objectStoreDefinitions = [];
var self = this;
self.context._storageModel.forEach(function (memDef) {
var objectStoreDefinition = self._getObjectStoreDefinition(memDef);
objectStoreDefinitions.push(objectStoreDefinition);
});
return objectStoreDefinitions;
},
_oldCreateDB: function _oldCreateDB(setVersionTran, definitions, onready) {
var self = this;
setVersionTran.db.onversionchange = function (event) {
return event.target.close();
};
self._createDB(setVersionTran.db, definitions);
setVersionTran.oncomplete = onready;
},
_createDB: function _createDB(db, definitions) {
for (var i = 0; i < definitions.length; i++) {
if (definitions[i].dropIfExists && db.objectStoreNames.contains(definitions[i].storeName)) {
db.deleteObjectStore(definitions[i].storeName);
}
}
for (var i = 0; i < definitions.length; i++) {
var storeDef = definitions[i];
if (!db.objectStoreNames.contains(storeDef.storeName)) {
var settings = {};
if (storeDef.keyFields.length == 1) {
settings = {
keyPath: storeDef.keyFields[0].name
//autoIncrement: storeDef.keyFields[0].computed
};
var typeName = _core.Container.resolveName(storeDef.keyFields[0].type);
settings.autoIncrement = this.supportedAutoincrementKeys[typeName] ? true : false;
} else {
settings.key = [];
for (var i = 0; i < storeDef.keyFields.length; i++) {
settings.key.push(storeDef.keyFields[i].name);
}
}
db.createObjectStore(storeDef.storeName, settings);
}
}
},
_hasDbChanges: function _hasDbChanges(db, definitions, dropTabes) {
var isOriginal = true;
for (var i = 0; i < definitions.length; i++) {
isOriginal = isOriginal && db.objectStoreNames.contains(definitions[i].storeName);
if (dropTabes) {
definitions[i].dropIfExists = true;
isOriginal = false;
}
}
return !isOriginal;
},
onupgradeneeded: function onupgradeneeded(objectStoreDefinitions) {
var self = this;
return function (e) {
var db = e.target.result;
db.onversionchange = function (event) {
return event.target.close();
};
var hasTableChanges = self._hasDbChanges(db, objectStoreDefinitions, self.providerConfiguration.dbCreation == _core2.default.storageProviders.DbCreationType.DropAllExistingTables);
if (hasTableChanges) self._createDB(db, objectStoreDefinitions);
};
},
initializeStore: function initializeStore(callBack) {
callBack = _core2.default.PromiseHandlerBase.createCallbackSettings(callBack);
var self = this;
this.initializeMemoryStore({
success: function success() {
var objectStoreDefinitions;
try {
objectStoreDefinitions = self._getObjectStoreDefinitions();
} catch (e) {
console.log(objectStoreDefinitions);
callBack.error(e);
return;
}
self.indexedDB.open(self.providerConfiguration.databaseName).setCallbacks({
onsuccess: function onsuccess(e) {
var db = e.target.result;
db.onversionchange = function (event) {
return event.target.close();
};
var hasTableChanges = self._hasDbChanges(db, objectStoreDefinitions, self.providerConfiguration.dbCreation == _core2.default.storageProviders.DbCreationType.DropAllExistingTables);
//oldAPI
if (db.setVersion) {
if (db.version === "" || hasTableChanges) {
db.setVersion((parseInt(db.version) || 0) + 1).setCallbacks({
onsuccess: function onsuccess(e) {
var db = e.target.result;
self._oldCreateDB(db /*setVerTran*/, objectStoreDefinitions, function (e) {
self.db = e.target.db;
callBack.success(self.context);
});
},
onerror: function onerror() {
var v = arguments;
},
onblocked: function onblocked() {
var v = arguments;
}
});
return;
};
} else if (hasTableChanges) {
//newVersionAPI
db.close();
var version = parseInt(db.version) + 1;
self.indexedDB.open(self.providerConfiguration.databaseName, version).setCallbacks({
onsuccess: function onsuccess(e) {
self.db = e.target.result;
callBack.success(self.context);
},
onupgradeneeded: self.onupgradeneeded(objectStoreDefinitions),
onerror: callBack.error,
onabort: callBack.error,
onblocked: callBack.error
});
return;
}
self.db = db;
callBack.success(self.context);
},
//newVersionAPI
onupgradeneeded: self.onupgradeneeded(objectStoreDefinitions),
onerror: callBack.error,
onabort: callBack.error,
onblocked: callBack.error
});
},
error: callBack.error
});
},
initializeMemoryStore: function initializeMemoryStore(callBack) {
callBack = _core2.default.PromiseHandlerBase.createCallbackSettings(callBack);
var self = this;
if (self.originalContext && self.providerConfiguration.memoryOperations) {
self.operationProvider = new self.originalContext({ name: 'InMemory' });
self.operationProvider.onReady({
success: function success() {
self.supportedBinaryOperators = self.operationProvider.storageProvider.supportedBinaryOperators;
self.supportedSetOperations = self.operationProvider.storageProvider.supportedSetOperations;
self.supportedFieldOperations = self.operationProvider.storageProvider.supportedFieldOperations;
self.supportedUnaryOperators = self.operationProvider.storageProvider.supportedUnaryOperators;
callBack.success();
},
error: callBack.error
});
} else {
callBack.success();
}
},
_initializeStore: function _initializeStore(callBack) {
callBack = _core2.default.PromiseHandlerBase.createCallbackSettings(callBack);
var self = this;
var initDb = function initDb(db) {
db.onversionchange = function (event) {
var ret = event.target.close();
return ret;
};
var newSequences = [];
self.context._storageModel.forEach(function (memDef) {
function createStore() {
/// <summary>
/// Creates a store for 'memDef'
/// </summary>
var osParam = {};
var keySettings = self._getKeySettings(memDef);
if (self.newVersionAPI) {
if (keySettings.autoIncrement) newSequences.push(memDef.TableName);
} else {
osParam.autoIncrement = keySettings.autoIncrement;
}
if (keySettings.keyPath !== undefined) osParam.keyPath = keySettings.keyPath;
db.createObjectStore(memDef.TableName, osParam);
}
if (db.objectStoreNames.contains(memDef.TableName)) {
// ObjectStore already present.
if (self.providerConfiguration.dbCreation === _core2.default.storageProviders.DbCreationType.DropAllExistingTables) {
// Force drop and recreate object store
db.deleteObjectStore(memDef.TableName);
createStore();
}
} else {
// Store does not exists yet, we need to create it
createStore();
}
});
if (newSequences.length > 0 && !db.objectStoreNames.contains(self.sequenceStore)) {
// Sequence store does not exists yet, we create it
db.createObjectStore(self.sequenceStore, { keyPath: 'store' });
newSequences = [];
}
return newSequences;
};
var newSequences = null;
// Creating openCallbacks settings for both type of db.open() method
var openCallbacks = {
onupgradeneeded: function onupgradeneeded(event) {
newSequences = initDb(event.target.result);
},
onerror: callBack.error,
onblocked: callBack.error,
onsuccess: function onsuccess(event) {
self.db = event.target.result;
self.db.onversionchange = function (event) {
event.target.close();
};
if (self.newVersionAPI) {
if (newSequences && newSequences.length > 0) {
var store = self.db.transaction([self.sequenceStore], self.IDBTransactionType.READ_WRITE).setCallbacks({
onerror: callBack.error,
oncomplete: function oncomplete() {
callBack.success(self.context);
}
}).objectStore(self.sequenceStore);
switch (self.providerConfiguration.dbCreation) {
case _core2.default.storageProviders.DbCreationType.DropAllExistingTables:
case _core2.default.storageProviders.DbCreationType.DropTableIfChanged:
// Clearing all data
store.clear();
break;
default:
// Removing data for newly created stores, if they previously existed
newSequences.forEach(function (item) {
store['delete'](item);
});
break;
}
}
callBack.success(self.context);
} else {
// Calling setVersion on webkit
var versionRequest = self.db.setVersion(self.providerConfiguration.version.toString()).setCallbacks({
onerror: callBack.error,
onblocked: callBack.error,
onsuccess: function onsuccess(event) {
initDb(self.db);
versionRequest.result.oncomplete = function (evt) {
callBack.success(self.context);
};
}
});
}
}
};
// For Firefox we need to pass the version here
if (self.newVersionAPI) self.indexedDB.open(self.providerConfiguration.databaseName, parseInt(self.providerConfiguration.version, 10)).setCallbacks(openCallbacks);else self.indexedDB.open(self.providerConfiguration.databaseName).setCallbacks(openCallbacks);
},
executeQuery: function executeQuery(query, callBack) {
callBack = _core2.default.PromiseHandlerBase.createCallbackSettings(callBack);
var self = this;
//var compiledQuery = self._compile(query);
// Creating read only transaction for query. Results are passed in transaction's oncomplete event
var entitySet = query.context.getEntitySetFromElementType(query.defaultType);
var store = self.db.transaction([entitySet.tableName], self.IDBTransactionType.READ_ONLY).setCallbacks({
onerror: callBack.error,
onabort: callBack.error,
oncomplete: function oncomplete(event) {
if (self.operationProvider) {
self.operationProvider.storageProvider.dataSource[entitySet.tableName] = query.rawDataList;
self.operationProvider.storageProvider.executeQuery(query, {
success: function success(query) {
if (query.expression.nodeType === _core2.default.Expressions.ExpressionType.Count) {
query.rawDataList[0] = { cnt: query.rawDataList[0] };
}
callBack.success(query);
},
error: callBack.error
});
} else {
callBack.success(query);
}
}
}).objectStore(entitySet.tableName);
var modelBinderCompiler = _core.Container.createModelBinderConfigCompiler(query, []);
modelBinderCompiler.Visit(query.expression);
if (self.operationProvider) {
store.openCursor().onsuccess = function (event) {
// We currently support only toArray() so let's just dump all data
var cursor = event.target.result;
if (cursor) {
var value = cursor.value;
query.rawDataList.push(cursor.value);
cursor['continue']();
}
};
} else {
switch (query.expression.nodeType) {
case _core2.default.Expressions.ExpressionType.Count:
store.count().onsuccess = function (event) {
var count = event.target.result;
query.rawDataList.push({ cnt: count });
};
break;
default:
store.openCursor().onsuccess = function (event) {
// We currently support only toArray() so let's just dump all data
var cursor = event.target.result;
if (cursor) {
var value = cursor.value;
query.rawDataList.push(cursor.value);
cursor['continue']();
}
};
break;
}
};
},
_getKeySettings: function _getKeySettings(memDef) {
/// <summary>
/// Gets key settings for item type's member definition
/// </summary>
/// <param name="memDef">memDef of item</param>
/// <returns>KeySettings object</returns>
var self = this;
var settings = { autoIncrement: false };
var keys = [];
memDef.PhysicalType.memberDefinitions.getPublicMappedProperties().forEach(function (item) {
if (item.key) {
// We found a key
keys.push(item.name);
}
if (item.computed) {
// AutoIncrement field, must be key
if (!item.key) _core.Guard.raise(new _core.Exception('Only key field can be a computed field!'));
var typeName = _core.Container.resolveName(item.type);
if (self.supportedAutoincrementKeys[typeName] === true) {
settings.autoIncrement = true;
}
}
});
if (keys.length > 1) {
if (settings.autoIncrement) _core.Guard.raise(new _core.Exception('Auto increment is only valid for a single key!'));
// Setting key fields (composite key)
settings.keys = keys;
} else if (keys.length == 1) {
// Simple key
settings.keyPath = keys[0];
} else {
_core.Guard.raise(new _core.Exception('No valid key found!'));
}
return settings;
},
saveChanges: function saveChanges(callBack, changedItems) {
var self = this;
// Building independent blocks and processing them sequentially
var independentBlocks = self.buildIndependentBlocks(changedItems);
function saveNextIndependentBlock() {
/// <summary>
/// Saves the next independent block
/// </summary>
if (independentBlocks.length === 0) {
// No more blocks left, calling success callback
callBack.success();
} else {
var KeySettingsCache = function KeySettingsCache() {
/// <summary>
/// Simple cache for key settings of types
/// </summary>
var cache = {};
this.getSettingsForItem = function (item) {
var typeName = item.data.getType().fullName;
if (!cache.hasOwnProperty(typeName)) {
cache[typeName] = self._getKeySettings(self.context._storageModel.getStorageModel(item.data.getType()));
}
return cache[typeName];
};
};
// 'Popping' next block
var currentBlock = independentBlocks.shift();
// Collecting stores of items for transaction initialize
var storesObj = {};
// Generating physicalData
var convertedItems = currentBlock.map(function (item) {
storesObj[item.entitySet.tableName] = true;
item.physicalData = {};
item.entitySet.elementType.memberDefinitions.getPublicMappedProperties().forEach(function (memDef) {
var typeName = _core.Container.resolveName(memDef.type);
if (memDef.key && memDef.computed && item.data[memDef.name] == undefined) {
if (typeof self.supportedAutoincrementKeys[typeName] === 'function') {
var keyValue = self.supportedAutoincrementKeys[typeName]();
item.data[memDef.name] = self.fieldConverter.toDb[typeName](keyValue);
} else {
// Autogenerated fields for new items should not be present in the physicalData
return;
}
}
if (!memDef.inverseProperty && typeof memDef.concurrencyMode === 'undefined' && (memDef.key === true || item.data.entityState === _core2.default.EntityState.Added || item.data.changedProperties && item.data.changedProperties.some(function (def) {
return def.name === memDef.name;
}))) {
if (self.fieldConverter.toDb[typeName]) {
item.physicalData[memDef.name] = self.fieldConverter.toDb[typeName](item.data[memDef.name]);
} else {
var value = item.data[memDef.name];
if (value !== undefined) {
value = JSON.parse(JSON.stringify(value));
}
item.physicalData[memDef.name] = value;
}
}
});
return item;
});
var stores = [];
for (var i in storesObj) {
stores.push(i);
}
var tran = self.db.transaction(stores, self.IDBTransactionType.READ_WRITE).setCallbacks({
onerror: function onerror(event) {
// Only call the error callback when it's not because of an abort
// aborted cases should call the error callback there
if (!event.target || !self.IDBDatabaseException || event.target && self.IDBDatabaseException && event.target.errorCode !== self.IDBDatabaseException.ABORT_ERR) callBack.error(event);
},
oncomplete: function oncomplete(event) {
// Moving to next block
saveNextIndependentBlock();
}
});
var ksCache = new KeySettingsCache();
convertedItems.forEach(function (item) {
// Getting store and keysettings for the current item
var store = tran.objectStore(item.entitySet.tableName);
var keySettings = ksCache.getSettingsForItem(item);
// Contains the keys that should be passed for create, update and delete (composite keys)
var itemKeys = keySettings.keys && keySettings.keys.map(function (key) {
return item.physicalData[key];
}) || null;
try {
var cursorAction = function cursorAction(action) {
/// <summary>
/// Find the current item in the store, and calls the action on it. Error raised when item was not found
/// </summary>
/// <param name="action">Action to call on the item</param>
var key = keySettings.keyPath ? item.physicalData[keySettings.keyPath] : itemKeys;
var data = item.physicalData;
store.openCursor(self.IDBKeyRange.only(key)).onsuccess = function (event) {
try {
var cursor = event.target.result;
if (cursor) action(cursor, key, data);else _core.Guard.raise(new _core.Exception('Object not found', null, item));
} catch (ex) {
tran.abort();
callBack.error(ex);
}
};
};
switch (item.data.entityState) {
case _core2.default.EntityState.Added:
if (!keySettings.keyPath) {
// Item needs explicit keys
store.add(item.physicalData, itemKeys);
} else {
store.add(item.physicalData).onsuccess = function (event) {
// Saves the generated key back to the entity
item.data[keySettings.keyPath] = event.target.result;
};
}
break;
case _core2.default.EntityState.Deleted:
// Deletes the item
cursorAction(function (cursor) {
cursor['delete']();
});
break;
case _core2.default.EntityState.Modified:
// Updates the item
cursorAction(function (cursor, key, data) {
cursor.update(_core2.default.typeSystem.extend(cursor.value, data));
});
break;
case _core2.default.EntityState.Unchanged:
break;
default:
_core.Guard.raise(new _core.Exception('Not supported entity state', null, item));
}
} catch (ex) {
// Abort on exceptions
tran.abort();
callBack.error(ex);
}
});
}
}
saveNextIndependentBlock();
},
_compile: function _compile(query) {
var sqlText = _core.Container.createIndexedDBCompiler().compile(query);
return sqlText;
}
}, {
isSupported: {
get: function get() {
return _core2.default.__global.indexedDB || _core2.default.__global.webkitIndexedDB || _core2.default.__global.mozIndexedDB || _core2.default.__global.msIndexedDB ? true : false;
},
set: function set() {}
}
});
if (_core2.default.storageProviders.indexedDb.IndexedDBStorageProvider.isSupported) _core2.default.StorageProviderBase.registerProvider('indexedDb', _core2.default.storageProviders.indexedDb.IndexedDBStorageProvider);
},{"jaydata/core":"jaydata/core"}],3:[function(_dereq_,module,exports){
;
Object.defineProperty(exports, "__esModule", {
value: true
});
var _core = _dereq_('jaydata/core');
var _core2 = _interopRequireDefault(_core);
var _IndexedDBConverter = _dereq_('./IndexedDBConverter.js');
var _IndexedDBConverter2 = _interopRequireDefault(_IndexedDBConverter);
var _IndexedDBStorageProvider = _dereq_('./IndexedDBStorageProvider.js');
var _IndexedDBStorageProvider2 = _interopRequireDefault(_IndexedDBStorageProvider);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
exports.default = _core2.default;
module.exports = exports['default'];
},{"./IndexedDBConverter.js":1,"./IndexedDBStorageProvider.js":2,"jaydata/core":"jaydata/core"}]},{},[3])(3)
});