jaydata
Version:
Cross-platform HTML5 data-management, JavaScript Language Query (JSLQ) support for OData, SQLite, WebSQL, IndexedDB, YQL and Facebook (packaged for Node.JS)
1,013 lines (919 loc) • 109 kB
JavaScript
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
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 _index = require('../TypeSystem/index.js');
var _index2 = _interopRequireDefault(_index);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
(function () {
_index2.default.defaults = _index2.default.defaults || {};
_index2.default.defaults.defaultDatabaseName = 'JayDataDefault';
_index2.default.defaults.enableRelatedEntityReadMethods = true;
_index2.default.defaults.relatedEntityReadMethodPrefix = 'get';
_index2.default.defaults.relatedEntityProxyPrefix = '$relatedProxy';
})();
_index2.default.Class.define('$data.StorageModel', null, null, {
constructor: function constructor() {
///<field name="LogicalType" type="$data.Entity">User defined type</field>
this.ComplexTypes = [];
this.Enums = [];
this.Associations = [];
},
LogicalType: {},
LogicalTypeName: {},
PhysicalType: {},
PhysicalTypeName: {},
EventHandlers: {},
TableName: {},
TableOptions: { value: undefined },
ComplexTypes: {},
Enums: {},
Associations: {},
ContextType: {},
Roles: {}
}, null);
_index2.default.Class.define('$data.Association', null, null, {
constructor: function constructor(initParam) {
if (initParam) {
this.From = initParam.From;
this.FromType = initParam.FromType;
this.FromMultiplicity = initParam.FromMultiplicity;
this.FromPropertyName = initParam.FromPropertyName;
this.To = initParam.To;
this.ToType = initParam.ToType;
this.ToMultiplicity = initParam.ToMultiplicity;
this.ToPropertyName = initParam.ToPropertyName;
}
},
From: {},
FromType: {},
FromMultiplicity: {},
FromPropertyName: {},
To: {},
ToType: {},
ToMultiplicity: {},
ToPropertyName: {},
ReferentialConstraint: {}
}, null);
_index2.default.Class.define('$data.ComplexType', _index2.default.Association, null, {}, null);
/**
* @public
* @module $data.EntityContext
*/
/**
* Provides facilities for querying and working with entity data as objects
*/
_index2.default.Class.define('$data.EntityContext', null, null, {
/**
* @constructs $data.EntityContext
* Provides facilities for querying and working with entity data as objects
* @param {Object} storageProviderCfg - Storage provider specific configuration object
* @param {string} storageProviderCfg.provider - Storage provider type name: 'oData', 'indexedDb', 'webSql', 'sqLite', 'mongoDB'
* @param {string} [storageProviderCfg.oDataServiceHost=/odata.svc] - URI of OData endpoint. Provider: OData
* @param {string} [storageProviderCfg.maxDataServiceVersion=4.0] - Maximal OData version. Provider: OData
* @param {string} [storageProviderCfg.dataServiceVersion] - version of your OData endpoint. Provider: OData
* @param {string} [storageProviderCfg.user] - login name for basic auth. Provider: OData
* @param {string} [storageProviderCfg.password] - password for basic auth. Provider: OData
* @param {string} [storageProviderCfg.UpdateMethod=PATCH] - HTTP verb used while updating entities, this should be configured according the accepted verb by your OData endpoint. Provider: OData
* @param {string} [storageProviderCfg.databaseName] - database name created by the following providers: webSql, sqLite, indexedDb, mongoDB
* @example <caption>initialize OData context</caption>
* var northwind = new Northwind({
* provider: 'oData',
* oDataServiceHost: '/api/odata.svc'
* });
* northwind.onReady(function() {
* //work with your context
* });
*
* @example <caption>initialize webSql context</caption>
* var northwind = new Northwind({
* provider: 'webSql',
* databaseName: 'Northwind'
* });
* northwind.onReady(function() {
* //work with your context
* });
*/
constructor: function constructor(storageProviderCfg) {
if (_index2.default.ItemStore && 'ContextRegister' in _index2.default.ItemStore) _index2.default.ItemStore.ContextRegister.apply(this, arguments);
if (storageProviderCfg.queryCache) this.queryCache = storageProviderCfg.queryCache;
if ("string" === typeof storageProviderCfg) {
if (0 === storageProviderCfg.indexOf("http")) {
storageProviderCfg = {
name: "oData",
oDataServiceHost: storageProviderCfg
};
} else {
storageProviderCfg = {
name: "local",
databaseName: storageProviderCfg
};
}
}
if ("provider" in storageProviderCfg) {
storageProviderCfg.name = storageProviderCfg.provider;
}
//Initialize properties
this.lazyLoad = false;
this.trackChanges = false;
this._entitySetReferences = {};
this._storageModel = [];
var ctx = this;
ctx._isOK = false;
var origSuccessInitProvider = this._successInitProvider;
this._successInitProvider = function (errorOrContext) {
if (errorOrContext instanceof _index2.default.EntityContext) {
origSuccessInitProvider(ctx);
} else {
origSuccessInitProvider(ctx, errorOrContext);
}
};
this._storageModel.getStorageModel = function (typeName) {
var name = _index.Container.resolveName(typeName);
return ctx._storageModel[name];
};
if (typeof storageProviderCfg.name === 'string') {
var tmp = storageProviderCfg.name;
storageProviderCfg.name = [tmp];
}
var i = 0,
providerType;
var providerList = [].concat(storageProviderCfg.name);
var callBack = _index2.default.PromiseHandlerBase.createCallbackSettings({ success: this._successInitProvider, error: this._successInitProvider });
this._initStorageModelSync();
this._initStorageModelNavigationProperties();
ctx._initializeEntitySets(ctx.getType());
_index2.default.StorageProviderLoader.load(providerList, {
success: function success(providerType) {
ctx.storageProvider = new providerType(storageProviderCfg, ctx);
ctx.storageProvider.setContext(ctx);
ctx.stateManager = new _index2.default.EntityStateManager(ctx);
var contextType = ctx.getType();
if (providerType.name in contextType._storageModelCache) {
ctx._storageModel = contextType._storageModelCache[providerType.name];
} else {
_index2.default.defaults.enableRelatedEntityReadMethods && ctx._applyRelatedEntityMethodsToTypes();
ctx._initializeStorageModel();
contextType._storageModelCache[providerType.name] = ctx._storageModel;
}
_index2.default.defaults.enableRelatedEntityReadMethods && ctx._applyRelatedEntityMethodsToContext();
//ctx._initializeEntitySets(contextType);
if (storageProviderCfg && storageProviderCfg.user) Object.defineProperty(ctx, 'user', { value: storageProviderCfg.user, enumerable: true });
if (storageProviderCfg && storageProviderCfg.checkPermission) Object.defineProperty(ctx, 'checkPermission', { value: storageProviderCfg.checkPermission, enumerable: true });
//ctx._isOK = false;
ctx._initializeStore(callBack);
},
error: function error() {
callBack.error('Provider fallback failed!');
}
});
this.addEventListener = function (eventName, fn) {
var delegateName = "on" + eventName;
if (!(delegateName in this)) {
this[delegateName] = new _index2.default.Event(eventName, this);
}
this[delegateName].attach(fn);
};
this.removeEventListener = function (eventName, fn) {
var delegateName = "on" + eventName;
if (!(delegateName in this)) {
return;
}
this[delegateName].detach(fn);
};
this.raiseEvent = function (eventName, data) {
var delegateName = "on" + eventName;
if (!(delegateName in this)) {
return;
}
this[delegateName].fire(data);
};
this.ready = this.onReady({
success: _index2.default.defaultSuccessCallback,
error: function error() {
if (_index2.default.PromiseHandler !== _index2.default.PromiseHandlerBase) {
_index2.default.defaultErrorCallback.apply(this, arguments);
} else {
_index2.default.Trace.error(arguments);
}
}
});
},
beginTransaction: function beginTransaction() {
var tables = null;
var callBack = null;
var isWrite = false;
function readParam(value) {
if (_index.Guard.isNullOrUndefined(value)) return;
if (typeof value === 'boolean') {
isWrite = value;
} else if (Array.isArray(value)) {
tables = value;
} else {
callBack = value;
}
}
readParam(arguments[0]);
readParam(arguments[1]);
readParam(arguments[2]);
var pHandler = new _index2.default.PromiseHandler();
callBack = pHandler.createCallback(callBack);
//callBack = $data.PromiseHandlerBase.createCallbackSettings(callBack);
this.storageProvider._beginTran(tables, isWrite, callBack);
return pHandler.getPromise();
},
_isReturnTransaction: function _isReturnTransaction(transaction) {
return transaction instanceof _index2.default.Base || transaction === 'returnTransaction';
},
_applyTransaction: function _applyTransaction(scope, cb, args, transaction, isReturnTransaction) {
if (isReturnTransaction === true) {
if (transaction instanceof _index2.default.Transaction) {
Array.prototype.push.call(args, transaction);
cb.apply(scope, args);
} else {
this.beginTransaction(function (tran) {
Array.prototype.push.call(args, tran);
cb.apply(scope, args);
});
}
} else {
cb.apply(scope, args);
}
},
getDataType: function getDataType(dataType) {
// Obsolate
if (typeof dataType == "string") {
var memDef_dataType = this[dataType];
if (memDef_dataType === undefined || memDef_dataType === null) {
memDef_dataType = eval(dataType);
}
return memDef_dataType;
}
return dataType;
},
_initializeEntitySets: function _initializeEntitySets(ctor) {
for (var i = 0, l = this._storageModel.length; i < l; i++) {
var storageModel = this._storageModel[i];
if (storageModel.BaseType) continue;
this[storageModel.ItemName] = new _index2.default.EntitySet(storageModel.LogicalType, this, storageModel.ItemName, storageModel.EventHandlers, storageModel.Roles);
var sm = this[storageModel.ItemName];
sm.name = storageModel.ItemName;
sm.tableName = storageModel.TableName;
sm.tableOptions = storageModel.TableOptions;
sm.eventHandlers = storageModel.EventHandlers;
this._entitySetReferences[storageModel.LogicalType.name] = sm;
this._initializeActions(sm, ctor, ctor.getMemberDefinition(storageModel.ItemName));
}
},
_initializeStore: function _initializeStore(callBack) {
if (this.storageProvider) {
this.storageProvider.initializeStore(callBack);
}
},
_createNavPropStorageModel: function _createNavPropStorageModel(logicalType) {
var ctx = this;
logicalType.memberDefinitions.getPublicMappedProperties().filter(function (it) {
return it.inverseProperty;
}).forEach(function (memDef) {
var item = _index.Container.resolveType(memDef.elementType || memDef.dataType);
if (!ctx._storageModel.filter(function (it) {
return it.LogicalType == item;
})[0]) {
var storageModel = new _index2.default.StorageModel();
storageModel.TableName = memDef.name;
storageModel.TableOptions = item.tableOptions;
storageModel.ItemName = item.name;
storageModel.LogicalType = item;
storageModel.LogicalTypeName = item.name;
storageModel.PhysicalTypeName = _index2.default.EntityContext._convertLogicalTypeNameToPhysical(storageModel.LogicalTypeName);
storageModel.ContextType = ctx.getType();
ctx._storageModel.push(storageModel);
var name = _index.Container.resolveName(item);
ctx._storageModel[name] = storageModel;
ctx._createNavPropStorageModel(storageModel.LogicalType);
}
});
},
_initStorageModelNavigationProperties: function _initStorageModelNavigationProperties() {
for (var i = 0; i < this._storageModel.length; i++) {
var storageModel = this._storageModel[i];
this._createNavPropStorageModel(storageModel.LogicalType);
}
},
_initStorageModelSync: function _initStorageModelSync() {
var _memDefArray = this.getType().memberDefinitions.asArray();
for (var i = 0; i < _memDefArray.length; i++) {
var item = _memDefArray[i];
if ('dataType' in item) {
var itemResolvedDataType = _index.Container.resolveType(item.dataType);
if (itemResolvedDataType && itemResolvedDataType.isAssignableTo && itemResolvedDataType.isAssignableTo(_index2.default.EntitySet)) {
var elementType = _index.Container.resolveType(item.elementType);
var storageModel = new _index2.default.StorageModel();
storageModel.TableName = item.tableName || item.name;
storageModel.TableOptions = item.tableOptions;
storageModel.ItemName = item.name;
storageModel.LogicalType = elementType;
storageModel.LogicalTypeName = elementType.name;
storageModel.PhysicalTypeName = _index2.default.EntityContext._convertLogicalTypeNameToPhysical(storageModel.LogicalTypeName);
storageModel.ContextType = this.getType();
storageModel.Roles = item.roles;
if (item.indices) {
storageModel.indices = item.indices;
}
if (item.beforeCreate) {
if (!storageModel.EventHandlers) storageModel.EventHandlers = {};
storageModel.EventHandlers.beforeCreate = item.beforeCreate;
}
if (item.beforeRead) {
if (!storageModel.EventHandlers) storageModel.EventHandlers = {};
storageModel.EventHandlers.beforeRead = item.beforeRead;
}
if (item.beforeUpdate) {
if (!storageModel.EventHandlers) storageModel.EventHandlers = {};
storageModel.EventHandlers.beforeUpdate = item.beforeUpdate;
}
if (item.beforeDelete) {
if (!storageModel.EventHandlers) storageModel.EventHandlers = {};
storageModel.EventHandlers.beforeDelete = item.beforeDelete;
}
if (item.afterCreate) {
if (!storageModel.EventHandlers) storageModel.EventHandlers = {};
storageModel.EventHandlers.afterCreate = item.afterCreate;
}
if (item.afterRead) {
if (!storageModel.EventHandlers) storageModel.EventHandlers = {};
storageModel.EventHandlers.afterRead = item.afterRead;
}
if (item.afterUpdate) {
if (!storageModel.EventHandlers) storageModel.EventHandlers = {};
storageModel.EventHandlers.afterUpdate = item.afterUpdate;
}
if (item.afterDelete) {
if (!storageModel.EventHandlers) storageModel.EventHandlers = {};
storageModel.EventHandlers.afterDelete = item.afterDelete;
}
this._storageModel.push(storageModel);
var name = _index.Container.resolveName(elementType);
this._storageModel[name] = storageModel;
if (elementType.inheritedTo) {
var ctx = this;
elementType.inheritedTo.forEach(function (type) {
var storageModel = new _index2.default.StorageModel();
storageModel.TableName = item.tableName || item.name;
storageModel.TableOptions = item.tableOptions;
storageModel.ItemName = item.name;
storageModel.LogicalType = type;
storageModel.LogicalTypeName = type.name;
storageModel.PhysicalTypeName = _index2.default.EntityContext._convertLogicalTypeNameToPhysical(storageModel.LogicalTypeName);
storageModel.ContextType = ctx.getType();
storageModel.BaseType = elementType;
ctx._storageModel.push(storageModel);
var name = _index.Container.resolveName(type);
ctx._storageModel[name] = storageModel;
});
}
}
}
}
},
_inheritanceMemberDefinitions: function _inheritanceMemberDefinitions(type, memdefs) {
var self = this;
if (type.inheritedTo) {
type.inheritedTo.forEach(function (it) {
memdefs = self._inheritanceMemberDefinitions(it, memdefs.concat(it.memberDefinitions.getPublicMappedProperties()));
});
}
return memdefs;
},
_buildDbInstanceDefinition: function _buildDbInstanceDefinition(storageModel, dbEntityInstanceDefinition) {
storageModel.Associations = storageModel.Associations || [];
storageModel.ComplexTypes = storageModel.ComplexTypes || [];
storageModel.Enums = storageModel.Enums || [];
var memberDefinitions = this._inheritanceMemberDefinitions(storageModel.LogicalType, storageModel.LogicalType.memberDefinitions.getPublicMappedProperties());
for (var j = 0; j < memberDefinitions.length; j++) {
var memDef = memberDefinitions[j];
///<param name="memDef" type="MemberDefinition">Member definition instance</param>
var memDefResolvedDataType = _index.Container.resolveType(memDef.dataType);
if ((this.storageProvider.supportedDataTypes.indexOf(memDefResolvedDataType) > -1 || memDefResolvedDataType.isAssignableTo && memDefResolvedDataType.isAssignableTo(_index2.default.Enum)) && _index.Guard.isNullOrUndefined(memDef.inverseProperty)) {
//copy member definition
var t = JSON.parse(JSON.stringify(memDef));
//change datatype to resolved type
t.dataType = memDefResolvedDataType;
dbEntityInstanceDefinition[memDef.name] = t;
if (memDefResolvedDataType.isAssignableTo && memDefResolvedDataType.isAssignableTo(_index2.default.Enum)) {
this._build_EnumDefinition(dbEntityInstanceDefinition, storageModel, memDefResolvedDataType, memDef);
}
continue;
}
this._buildDbType_navigationPropertyComplite(memDef, memDefResolvedDataType, storageModel);
if ((memDefResolvedDataType === _index2.default.Array || memDefResolvedDataType.isAssignableTo && memDefResolvedDataType.isAssignableTo(_index2.default.EntitySet)) && memDef.inverseProperty && memDef.inverseProperty !== '$$unbound') {
this._buildDbType_Collection_OneManyDefinition(dbEntityInstanceDefinition, storageModel, memDefResolvedDataType, memDef);
} else {
if (memDef.inverseProperty) {
if (memDef.inverseProperty === '$$unbound') {
//member definition is navigation but not back reference
if (memDefResolvedDataType === _index2.default.Array) {
this._buildDbType_Collection_OneManyDefinition(dbEntityInstanceDefinition, storageModel, memDefResolvedDataType, memDef);
} else {
this._buildDbType_ElementType_OneManyDefinition(dbEntityInstanceDefinition, storageModel, memDefResolvedDataType, memDef);
}
} else {
//member definition is navigation property one..one or one..many case
var fields = memDefResolvedDataType.memberDefinitions.getMember(memDef.inverseProperty);
if (fields) {
if (fields.elementType) {
//member definition is one..many connection
var referealResolvedType = _index.Container.resolveType(fields.elementType);
this._buildDbType_ElementType_OneManyDefinition(dbEntityInstanceDefinition, storageModel, memDefResolvedDataType, memDef);
} else {
//member definition is one..one connection
this._buildDbType_ElementType_OneOneDefinition(dbEntityInstanceDefinition, storageModel, memDefResolvedDataType, memDef);
}
} else {
if (typeof intellisense === 'undefined') {
_index.Guard.raise(new _index.Exception('Inverse property not valid'));
}
}
}
} else {
//member definition is a complex type
this._buildDbType_addComplexTypePropertyDefinition(dbEntityInstanceDefinition, storageModel, memDefResolvedDataType, memDef);
}
}
}
},
_initializeStorageModel: function _initializeStorageModel() {
var _memDefArray = this.getType().memberDefinitions.asArray();
if (typeof intellisense !== 'undefined') return;
for (var i = 0; i < this._storageModel.length; i++) {
var storageModel = this._storageModel[i];
///<param name="storageModel" type="$data.StorageModel">Storage model item</param>
var dbEntityInstanceDefinition = {};
this._buildDbInstanceDefinition(storageModel, dbEntityInstanceDefinition);
this._buildDbType_modifyInstanceDefinition(dbEntityInstanceDefinition, storageModel, this);
var dbEntityClassDefinition = {};
dbEntityClassDefinition.convertTo = this._buildDbType_generateConvertToFunction(storageModel, this);
this._buildDbType_modifyClassDefinition(dbEntityClassDefinition, storageModel, this);
//create physical type
//TODO
storageModel.PhysicalType = _index2.default.Class.define(storageModel.PhysicalTypeName, _index2.default.Entity, storageModel.LogicalType.container, dbEntityInstanceDefinition, dbEntityClassDefinition);
}
},
_initializeActions: function _initializeActions(es, ctor, esDef) {
if (esDef && esDef.actions) {
var actionKeys = Object.keys(esDef.actions);
for (var i = 0; i < actionKeys.length; i++) {
var actionName = actionKeys[i];
var action = esDef.actions[actionName];
if (typeof action === 'function') {
es[actionName] = action;
} else {
var actionDef = _index2.default.MemberDefinition.translateDefinition(action, actionName, ctor);
if (actionDef instanceof _index2.default.MemberDefinition && actionDef.kind === _index2.default.MemberTypes.method) {
es[actionName] = actionDef.method;
}
}
}
}
},
_buildDbType_navigationPropertyComplite: function _buildDbType_navigationPropertyComplite(memDef, memDefResolvedDataType, storageModel) {
if (!memDef.inverseProperty) {
var refMemDefs = null;
if (memDefResolvedDataType === _index2.default.Array || memDefResolvedDataType.isAssignableTo && memDefResolvedDataType.isAssignableTo(_index2.default.EntitySet)) {
var refStorageModel = this._storageModel.getStorageModel(_index.Container.resolveType(memDef.elementType));
if (refStorageModel) {
refMemDefs = [];
var pubDefs = refStorageModel.LogicalType.memberDefinitions.getPublicMappedProperties();
for (var i = 0; i < pubDefs.length; i++) {
var m = pubDefs[i];
if (m.inverseProperty == memDef.name && _index.Container.resolveType(m.dataType) === _index.Container.resolveType(storageModel.LogicalType)) refMemDefs.push(m);
}
}
} else {
var refStorageModel = this._storageModel.getStorageModel(memDefResolvedDataType);
if (refStorageModel) {
refMemDefs = [];
var pubDefs = refStorageModel.LogicalType.memberDefinitions.getPublicMappedProperties();
for (var i = 0; i < pubDefs.length; i++) {
var m = pubDefs[i];
if (m.elementType && m.inverseProperty == memDef.name && _index.Container.resolveType(m.elementType) === storageModel.LogicalType) refMemDefs.push(m);else if (m.inverseProperty == memDef.name && _index.Container.resolveType(m.dataType) === storageModel.LogicalType) refMemDefs.push(m);
}
}
}
if (refMemDefs) {
if (refMemDefs.length > 1) {
if (typeof intellisense !== 'undefined') {
_index.Guard.raise(new _index.Exception('More than one inverse property refer to this member definition: ' + memDef.name + ', type: ' + _index.Container.resolveName(storageModel.LogicalType)));
}
}
var refMemDef = refMemDefs.pop();
if (refMemDef) {
memDef.inverseProperty = refMemDef.name;
}
}
} else {
var refStorageModel = null;
if (memDefResolvedDataType === _index2.default.Array || memDefResolvedDataType.isAssignableTo && memDefResolvedDataType.isAssignableTo(_index2.default.EntitySet)) {
refStorageModel = this._storageModel.getStorageModel(_index.Container.resolveType(memDef.elementType));
} else {
refStorageModel = this._storageModel.getStorageModel(memDefResolvedDataType);
}
var p = refStorageModel.LogicalType.memberDefinitions.getMember(memDef.inverseProperty);
if (p) {
if (p.inverseProperty) {
if (p.inverseProperty != memDef.name) {
if (typeof intellisense === 'undefined') {
_index.Guard.raise(new _index.Exception('Inverse property mismatch'));
}
}
} else {
p.inverseProperty = memDef.name;
}
}
}
},
_buildDbType_generateConvertToFunction: function _buildDbType_generateConvertToFunction(storageModel) {
return function (instance) {
return instance;
};
},
_buildDbType_modifyInstanceDefinition: function _buildDbType_modifyInstanceDefinition(instanceDefinition, storageModel) {
return;
},
_buildDbType_modifyClassDefinition: function _buildDbType_modifyClassDefinition(classDefinition, storageModel) {
return;
},
_buildDbType_addComplexTypePropertyDefinition: function _buildDbType_addComplexTypePropertyDefinition(dbEntityInstanceDefinition, storageModel, memDef_dataType, memDef) {
this._addNavigationPropertyDefinition(dbEntityInstanceDefinition, memDef, memDef.name, _index2.default.MemberTypes.complexProperty);
var complexType = this._createComplexElement(storageModel.LogicalType, "", memDef.name, memDef_dataType, "", "");
storageModel.ComplexTypes[memDef.name] = complexType;
storageModel.ComplexTypes.push(complexType);
},
_buildDbType_Collection_OneManyDefinition: function _buildDbType_Collection_OneManyDefinition(dbEntityInstanceDefinition, storageModel, memDef_dataType, memDef) {
var refereedType = _index.Container.resolveType(memDef.elementType);
if (refereedType === undefined || refereedType === null) {
if (typeof intellisense === 'undefined') {
_index.Guard.raise(new _index.Exception("Element type definition error", "Field definition", memDef));
}
}
var refereedStorageModel = this._storageModel.getStorageModel(refereedType);
//var refereedStorageModel = this._storageModel.filter(function (s) { return s.LogicalType === refereedType; })[0];
if (!refereedStorageModel) {
if (typeof intellisense === 'undefined') {
_index.Guard.raise(new _index.Exception("No EntitySet definition for the following element type", "Field definition", memDef));
}
}
this._addNavigationPropertyDefinition(dbEntityInstanceDefinition, memDef, memDef.name);
var associationType = memDef.inverseProperty === '$$unbound' ? '$$unbound' : '0..1';
var association = this._addAssociationElement(memDef.definedBy, associationType, memDef.name, refereedStorageModel.LogicalType, "*", memDef.inverseProperty);
storageModel.Associations[memDef.name] = association;
storageModel.Associations.push(association);
},
_buildDbType_ElementType_OneManyDefinition: function _buildDbType_ElementType_OneManyDefinition(dbEntityInstanceDefinition, storageModel, memDef_dataType, memDef) {
var refereedType = _index.Container.resolveType(memDef.dataType);
if (refereedType === undefined || refereedType === null) {
if (typeof intellisense === 'undefined') {
_index.Guard.raise(new _index.Exception("Element type definition error", "Field definition", memDef));
}
}
var refereedStorageModel = this._storageModel.getStorageModel(refereedType);
//var refereedStorageModel = this._storageModel.filter(function (s) { return s.LogicalType === refereedType; })[0];
if (!refereedStorageModel) {
if (typeof intellisense === 'undefined') {
_index.Guard.raise(new _index.Exception("No EntitySet definition for the following element type", "Field definition", memDef));
}
}
this._addNavigationPropertyDefinition(dbEntityInstanceDefinition, memDef, memDef.name);
var associationType = memDef.inverseProperty === '$$unbound' ? '$$unbound' : '*';
var association = this._addAssociationElement(memDef.definedBy, associationType, memDef.name, refereedType, "0..1", memDef.inverseProperty);
storageModel.Associations[memDef.name] = association;
storageModel.Associations.push(association);
},
_buildDbType_ElementType_OneOneDefinition: function _buildDbType_ElementType_OneOneDefinition(dbEntityInstanceDefinition, storageModel, memDef_dataType, memDef) {
var refereedType = _index.Container.resolveType(memDef.dataType);
if (refereedType === undefined || refereedType === null) {
if (typeof intellisense === 'undefined') {
_index.Guard.raise(new _index.Exception("Element type definition error", "Field definition", memDef));
}
}
var refereedStorageModel = this._storageModel.getStorageModel(refereedType);;
//var refereedStorageModel = this._storageModel.filter(function (s) { return s.LogicalType === refereedType; })[0];
if (!refereedStorageModel) {
if (typeof intellisense === 'undefined') {
_index.Guard.raise(new _index.Exception("No EntitySet definition following element type", "Field definition", memDef));
}
}
var refereedMemberDefinition = refereedStorageModel.LogicalType.memberDefinitions.getMember(memDef.inverseProperty);
if (!refereedMemberDefinition.required && !memDef.required) {
if (typeof intellisense === 'undefined') {
if (typeof intellisense === 'undefined') {
_index.Guard.raise(new _index.Exception('In one to one connection, one side must required!', 'One to One connection', memDef));
}
}
}
this._addNavigationPropertyDefinition(dbEntityInstanceDefinition, memDef, memDef.name);
var association = this._addAssociationElement(memDef.definedBy, memDef.required ? "0..1" : "1", memDef.name, refereedStorageModel.LogicalType, memDef.required ? "1" : "0..1", memDef.inverseProperty);
storageModel.Associations[memDef.name] = association;
storageModel.Associations.push(association);
},
_addNavigationPropertyDefinition: function _addNavigationPropertyDefinition(definition, member, associationName, kind) {
var t = JSON.parse(JSON.stringify(member));
t.dataType = _index2.default.EntitySet;
t.notMapped = true;
t.kind = kind ? kind : _index2.default.MemberTypes.navProperty;
t.association = associationName;
definition[member.name] = t;
},
_addAssociationElement: function _addAssociationElement(fromType, fromMultiplicity, fromPropName, toType, toMultiplicity, toPropName) {
return new _index2.default.Association({
From: fromType.name,
FromType: fromType,
FromMultiplicity: fromMultiplicity,
FromPropertyName: fromPropName,
To: toType.name,
ToType: toType,
ToMultiplicity: toMultiplicity,
ReferentialConstraint: [],
ToPropertyName: toPropName
});
},
_createComplexElement: function _createComplexElement(fromType, fromMultiplicity, fromPropName, toType, toMultiplicity, toPropName) {
return new _index2.default.ComplexType({
From: fromType.name,
FromType: fromType,
FromMultiplicity: fromMultiplicity,
FromPropertyName: fromPropName,
To: toType.name,
ToType: toType,
ToMultiplicity: toMultiplicity,
ReferentialConstraint: [],
ToPropertyName: toPropName
});
},
_build_EnumDefinition: function _build_EnumDefinition(dbEntityInstanceDefinition, storageModel, memDefResolvedDataType, memDef) {
storageModel.Enums.push(memDefResolvedDataType);
var typeName = _index.Container.resolveName(memDefResolvedDataType);
var converterGroups = this.storageProvider.fieldConverter;
var createEnumConverter = function createEnumConverter(converterGroup) {
converterGroup[typeName] = function (value) {
return converterGroup["$data.Enum"].call(this, value, memDefResolvedDataType);
};
};
for (var i in converterGroups) {
if (!converterGroups[i][typeName] && converterGroups[i]["$data.Enum"]) {
createEnumConverter(converterGroups[i]);
if (_index2.default.SqLiteFieldMapping) _index2.default.SqLiteFieldMapping[typeName] = 'INTEGER';
}
}
},
_successInitProvider: function _successInitProvider(context, error) {
if (context instanceof _index2.default.EntityContext && context._isOK !== undefined) {
if (!error) {
context._isOK = true;
if (context.onReadyFunction) {
for (var i = 0; i < context.onReadyFunction.length; i++) {
context.onReadyFunction[i].success(context);
}
context.onReadyFunction = undefined;
}
} else {
context._isOK = error;
if (context.onReadyFunction) {
for (var i = 0; i < context.onReadyFunction.length; i++) {
context.onReadyFunction[i].error(error);
}
context.onReadyFunction = undefined;
}
}
}
},
/**
* Sets the callback function to be called when the initialization of the {@link $data.EntityContext} has successfully finished.
* @event $data.EntityContext#onReady
* @param {function|function[]} fn - Success callback
* @returns {$.Deferred}
*/
onReady: function onReady(fn) {
/// <signature>
/// <summary>
///
/// </summary>
/// <param name="successCallback" type="Function">
/// <summary>Success callback</summary>
/// <param name="entityContext" type="$data.EntityContext">Current entityContext object</param>
/// </param>
/// <returns type="" />
/// </signature>
/// <signature>
/// <summary>
/// Sets the callback functions to be called when the initialization of the EntityContext has finished.
/// </summary>
/// <param name="callbacks" type="Object">
/// Success and error callbacks definition.
/// Example: [code]{ success: function(db) { .. }, error: function() { .. } }[/code]
/// </param>
/// <returns type="$.Deferred" />
/// </signature>
var pHandler = new _index2.default.PromiseHandler();
var callBack = pHandler.createCallback(fn);
if (this._isOK === true) {
callBack.success(this);
} else if (this._isOK !== false) {
callBack.error(this._isOK);
} else {
this.onReadyFunction = this.onReadyFunction || [];
this.onReadyFunction.push(callBack);
}
return pHandler.getPromise();
},
ready: { type: _index2.default.Promise },
getEntitySetFromElementType: function getEntitySetFromElementType(elementType) {
/// <signature>
/// <summary>Gets the matching EntitySet for an element type.</summary>
/// <param name="elementType" type="Function" />
/// <returns type="$data.EntitySet" />
/// </signature>
/// <signature>
/// <summary>Gets the matching EntitySet for an element type.</summary>
/// <param name="elementType" type="String" />
/// <returns type="$data.EntitySet" />
/// </signature>
var result = this._entitySetReferences[elementType];
if (!result) {
try {
result = this._entitySetReferences[eval(elementType).name];
} catch (ex) {}
}
if (!result && elementType.isAssignableTo && elementType.isAssignableTo(_index2.default.Entity)) {
if (!this._storageModel[elementType.name]) {
var storageModel = new _index2.default.StorageModel();
storageModel.TableName = elementType.name;
storageModel.ItemName = elementType.name;
storageModel.LogicalType = elementType;
storageModel.LogicalTypeName = elementType.name;
var dbEntityInstanceDefinition = {};
this._buildDbInstanceDefinition(storageModel, dbEntityInstanceDefinition);
var dbEntityClassDefinition = {};
dbEntityClassDefinition.convertTo = this._buildDbType_generateConvertToFunction(storageModel, this);
storageModel.PhysicalTypeName = _index2.default.EntityContext._convertLogicalTypeNameToPhysical(storageModel.LogicalTypeName);
storageModel.PhysicalType = _index2.default.Class.define(storageModel.PhysicalTypeName, _index2.default.Entity, storageModel.LogicalType.container, dbEntityInstanceDefinition, dbEntityClassDefinition);
storageModel.ContextType = this.getType();
this._storageModel.push(storageModel);
var name = _index.Container.resolveName(elementType);
this._storageModel[name] = storageModel;
}
result = this._entitySetReferences[elementType.name] = new _index2.default.EntitySet(elementType, this, elementType.name);
result.tableName = storageModel.TableName;
}
//console.log(Object.keys(this._entitySetReferences), Object.keys(this._storageModel), elementType.name);
return result;
},
executeQuery: function executeQuery(queryable, callBack, transaction) {
var query = new _index2.default.Query(queryable.expression, queryable.defaultType, this);
query.transaction = transaction instanceof _index2.default.Transaction ? transaction : undefined;
var returnTransaction = this._isReturnTransaction(transaction);
callBack = _index2.default.PromiseHandlerBase.createCallbackSettings(callBack);
var that = this;
var clbWrapper = {};
clbWrapper.success = that.executeQuerySuccess(that, returnTransaction, callBack);
clbWrapper.error = that.executeQueryError(that, returnTransaction, callBack);
var sets = query.getEntitySets();
var authorizedFn = function authorizedFn() {
var ex = true;
var wait = false;
var ctx = that;
var readyFn = function readyFn(cancel) {
if (cancel === false) ex = false;
if (ex) {
if (query.transaction) {
if (_index2.default.QueryCache && _index2.default.QueryCache.isInCache(that, query)) {
_index2.default.QueryCache.executeQuery(that, query, clbWrapper);
} else {
ctx.storageProvider.executeQuery(query, clbWrapper);
}
} else {
ctx.beginTransaction(function (tran) {
query.transaction = tran;
if (_index2.default.QueryCache && _index2.default.QueryCache.isInCache(that, query)) {
_index2.default.QueryCache.executeQuery(that, query, clbWrapper);
} else {
ctx.storageProvider.executeQuery(query, clbWrapper);
}
});
}
} else {
query.rawDataList = [];
query.result = [];
clbWrapper.success(query);
}
};
var i = 0;
var callbackFn = function callbackFn(cancel) {
if (cancel === false) ex = false;
var es = sets[i];
if (es.beforeRead) {
i++;
var r = es.beforeRead.call(this, sets, query);
if (typeof r === 'function') {
r.call(this, i < sets.length && ex ? callbackFn : readyFn, sets, query);
} else {
if (r === false) ex = false;
if (i < sets.length && ex) {
callbackFn();
} else readyFn();
}
} else readyFn();
};
if (sets.length) callbackFn();else readyFn();
};
if (this.user && this.checkPermission) {
this.checkPermission(query.expression.nodeType === _index2.default.Expressions.ExpressionType.BatchDelete ? _index2.default.Access.DeleteBatch : _index2.default.Access.Read, this.user, sets, {
success: authorizedFn,
error: clbWrapper.error
});
} else authorizedFn();
},
executeQuerySuccess: function executeQuerySuccess(that, returnTransaction, callBack) {
return function (query) {
if (_index2.default.QueryCache && _index2.default.QueryCache.isCacheable(that, query)) {
_index2.default.QueryCache.addToCache(that, query);
}
query.buildResultSet(that);
if (_index2.default.ItemStore && 'QueryResultModifier' in _index2.default.ItemStore) _index2.default.ItemStore.QueryResultModifier.call(that, query);
var successResult;
if (query.expression.nodeType === _index2.default.Expressions.ExpressionType.Single || query.expression.nodeType === _index2.default.Expressions.ExpressionType.Find || query.expression.nodeType === _index2.default.Expressions.ExpressionType.Count || query.expression.nodeType === _index2.default.Expressions.ExpressionType.BatchDelete || query.expression.nodeType === _index2.default.Expressions.ExpressionType.Some || query.expression.nodeType === _index2.default.Expressions.ExpressionType.Every) {
if (query.result.length !== 1) {
callBack.error(new _index.Exception('result count failed'));
return;
}
successResult = query.result[0];
} else if (query.expression.nodeType === _index2.default.Expressions.ExpressionType.First) {
if (query.result.length === 0) {
callBack.error(new _index.Exception('result count failed'));
return;
}
successResult = query.result[0];
} else {
if (typeof query.__count === 'number' && query.result) query.result.totalCount = query.__count;
that.storageProvider._buildContinuationFunction(that, query);
successResult = query.result;
}
var readyFn = function readyFn() {
that._applyTransaction(callBack, callBack.success, [successResult], query.transaction, returnTransaction);
/*if (returnTransaction === true) {
if (query.transaction)
callBack.success(successResult, query.transaction);
else {
that.beginTransaction(function (tran) {
callBack.success(successResult, tran);
});
}
}
else
callBack.success(successResult);*/
};
var i = 0;
var sets = query.getEntitySets();
var callbackFn = function callbackFn() {
var es = sets[i];
if (es.afterRead) {
i++;
var r = es.afterRead.call(this, successResult, sets, query);
if (typeof r === 'function') {
r.call(this, i < sets.length ? callbackFn : readyFn, successResult, sets, query);
} else {
if (i < sets.length) {
callbackFn();
} else readyFn();
}
} else readyFn();
};
if (sets.length) callbackFn();else readyFn();
};
},
executeQueryError: function executeQueryError(that, returnTransaction, callBack) {
return function () {
if (returnTransaction) callBack.error.apply(this, arguments);else callBack.error.apply(this, Array.prototype.filter.call(arguments, function (p) {
return !(p instanceof _index2.default.Transaction);
}));
};
},
batchExecuteQuery: function batchExecuteQuery(queryableOptions, callBack, transaction) {
var pHandler = new _index2.default.PromiseHandler();
var cbWrapper = pHandler.createCallback(callBack);
var self = this;
var methodOperationMappings = {
count: 'length',
length: 'length',
forEach: 'forEach',
toArray: 'toArray',
single: 'single',
some: 'some',
every: 'every',
first: 'first',
removeAll: 'batchDelete'
};
var methodFrameMappings = {
count: 'CountExpression',
length: 'CountExpression',