jaydata
Version:
Cross-platform HTML5 data-management, JavaScript Language Query (JSLQ) support for OData, SQLite, WebSQL, IndexedDB, YQL and Facebook (packaged for Node.JS)
423 lines (397 loc) • 18.4 kB
JavaScript
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
var _index = require('../TypeSystem/index.js');
var _index2 = _interopRequireDefault(_index);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
///EntitySet is responsible for
/// -creating and holding entityType through schema
/// - provide Add method
/// - provide Delete method
/// - provide Update method
/// - provide queryProvider for queryable
_index2.default.EntitySchemaConfig = function EntitySchemaConfig() {
this.Name = "";
};
_index2.default.entitySetState = { created: 0, defined: 1, active: 2 };
_index2.default.Class.defineEx('$data.EntitySet', [{ type: _index2.default.Queryable, params: [new _index2.default.Class.ConstructorParameter(1)] }], null, {
constructor: function constructor(elementType, context, collectionName, eventHandlers, roles) {
/// <signature>
/// <summary>Represents a typed entity set that is used to perform create, read, update, and delete operations</summary>
/// <param name="elementType" type="Function" subClassOf="$data.Entity">Type of entity set elements, elementType must be subclass of $data.Entity</param>
/// <param name="context" type="$data.EntityContext">Context of the EntitySet</param>
/// <param name="collectionName" type="String">Name of the EntitySet</param>
/// </signature>
this.createNew = this[elementType.name] = this.elementType = this.defaultType = elementType;
var self = this;
context['createAdd' + elementType.name] = function (initData) {
var entity = new elementType(initData);
return self.add(entity);
};
this.stateManager = new _index2.default.EntityStateManager(this);
this.collectionName = collectionName;
this.roles = roles;
for (var i in eventHandlers) {
this[i] = eventHandlers[i];
}
},
addNew: function addNew(item, cb) {
var callback = _index2.default.PromiseHandlerBase.createCallbackSettings(cb);
var _item = new this.createNew(item);
this.entityContext.saveChanges(cb);
return _item;
},
executeQuery: function executeQuery(expression, on_ready) {
//var compiledQuery = this.entityContext
var callBack = _index2.default.PromiseHandlerBase.createCallbackSettings(on_ready);
this.entityContext.executeQuery(expression, callBack);
},
getTraceString: function getTraceString(expression) {
return this.entityContext.getTraceString(expression);
},
setContext: function setContext(entityContext) {
this.entitySetState = _index2.default.entitySetState.active;
this.entityContext = entityContext;
this.entityContext[this.schema.name] = this[this.schema.name];
},
_trackEntity: function _trackEntity(entity) {
var trackedEntities = this.entityContext.stateManager.trackedEntities;
for (var i = 0; i < trackedEntities.length; i++) {
if (trackedEntities[i].data === entity) return;
}
trackedEntities.push({ entitySet: this, data: entity });
},
add: function add(entity) {
/// <signature>
/// <summary>Creates a typed entity and adds to the context.</summary>
/// <param name="entity" type="Object">The init parameters whish is based on Entity</param>
/// <example>
///
/// Persons.add({ Name: 'John', Email: 'john@example.com', Age: 30, Gender: 'Male' });
///
/// </example>
/// </signature>
/// <signature>
/// <summary>Adds the given entity to the context.</summary>
/// <param name="entity" type="$data.Entity">The entity to add</param>
/// <example>
///
/// Persons.add(new $news.Types.Person({ Name: 'John', Email: 'john@example.com', Age: 30, Gender: 'Male' }));
///
/// </example>
/// <example>
///
/// var person = new $news.Types.Person({ Name: 'John', Email: 'john@example.com', Age: 30, Gender: 'Male' });
/// Persons.add(person);
///
/// </example>
/// </signature>
var data = entity;
if (entity instanceof _index2.default.EntityWrapper) {
data = entity.getEntity();
} else if (!(entity instanceof this.createNew)) {
data = new this.createNew(entity);
}
data.entityState = _index2.default.EntityState.Added;
data.changedProperties = undefined;
data.context = this.entityContext;
this._trackEntity(data);
return data;
},
addMany: function addMany(entities) {
var result = [];
var self = this;
entities.forEach(function (entity) {
result.push(self.add(entity));
});
return result;
},
remove: function remove(entity) {
/// <signature>
/// <summary>Creates a typed entity and marks it as Deleted.</summary>
/// <param name="entity" type="Object">The init parameters whish is based on Entity</param>
/// <example>
/// Person will be marked as Deleted where an id is 5. Id is a key of entity.
/// Persons.remove({ Id: 5 });
///
/// </example>
/// </signature>
/// <signature>
/// <summary>Marks the given entity as Deleted.</summary>
/// <param name="entity" type="$data.Entity">The entity to remove</param>
/// <example>
///
/// Persons.remove(person);
///
/// </example>
/// <example>
/// Person will be marked as Deleted where an Id is 5. Id is a key of entity.
/// Persons.add(new $news.Types.Person({ Id: 5 }));
///
/// </example>
/// </signature>
var data = entity;
if (entity instanceof _index2.default.EntityWrapper) {
data = entity.getEntity();
} else if (!(entity instanceof this.createNew)) {
data = new this.createNew(entity);
}
data.entityState = _index2.default.EntityState.Deleted;
data.changedProperties = undefined;
this._trackEntity(data);
},
attach: function attach(entity, mode) {
/// <signature>
/// <summary>Creates a typed entity and adds to the Context with Unchanged state.</summary>
/// <param name="entity" type="Object">The init parameters whish is based on Entity</param>
/// <example>
///
/// Persons.attach({ Id: 5, Email: 'newEmail@example.com' });
///
/// </example>
/// </signature>
/// <signature>
/// <summary>Adds to the context and sets state Unchanged.</summary>
/// <param name="entity" type="$data.Entity">The entity to attach</param>
/// <example>
///
/// Persons.attach(person);
///
/// </example>
/// <example>
/// Set an entity's related entities without loading
///
/// var categoryPromo = new $news.Types.Category({ Id: 5 });
/// Category.attach(categoryPromo);
/// var article = new $news.Types.Article({ Title: 'New Article title', Body: 'Article body', Category: [ categoryPromo ] });
/// Article.attach(article);
///
/// </example>
/// </signature>
var data = entity;
if (entity instanceof _index2.default.EntityWrapper) {
data = entity.getEntity();
} else if (!(entity instanceof this.createNew)) {
data = new this.createNew(entity);
}
for (var i = 0; i < this.entityContext.stateManager.trackedEntities.length; i++) {
var current = this.entityContext.stateManager.trackedEntities[i];
if (current.data === data) break;
if (current.data.equals(data)) {
_index.Guard.raise(new _index.Exception("Context already contains this entity!!!"));
}
}
if (mode === true) {
if (data.changedProperties && data.changedProperties.length > 0) {
data.entityState = _index2.default.EntityState.Modified;
} else {
data.entityState = _index2.default.EntityState.Unchanged;
}
} else {
if (typeof mode === "string") mode = _index2.default.EntityAttachMode[mode];
var attachMode = mode || _index2.default.EntityAttachMode[_index2.default.EntityAttachMode.defaultMode];
if (typeof attachMode === "function") {
attachMode.call(_index2.default.EntityAttachMode, data);
} else {
data.entityState = _index2.default.EntityState.Unchanged;
data.changedProperties = undefined;
}
}
/*if (!keepChanges) {
data.entityState = $data.EntityState.Unchanged;
data.changedProperties = undefined;
}*/
data.context = this.entityContext;
this._trackEntity(data);
},
detach: function detach(entity) {
/// <signature>
/// <summary>Creates a typed entity and detach from the Context with Detached state.</summary>
/// <param name="entity" type="Object">The init parameters whish is based on Entity</param>
/// <example>
/// Person will be Detached where an id is 5. Id is a key of entity.
/// Persons.detach({ Id: 5 });
///
/// </example>
/// </signature>
/// <signature>
/// <summary>Detach from the context and sets state Detached.</summary>
/// <param name="entity" type="$data.Entity">The entity to detach</param>
/// <example>
///
/// Persons.detach(person);
///
/// </example>
/// <example>
/// Person will be Detached where an Id is 5. Id is a key of entity.
/// Persons.add(new $news.Types.Person({ Id: 5 }));
///
/// </example>
/// </signature>
var data = entity;
if (entity instanceof _index2.default.EntityWrapper) {
data = entity.getEntity();
} else if (!(entity instanceof this.createNew)) {
data = new this.createNew(entity);
}
var existsItem;
var trackedEnt = this.entityContext.stateManager.trackedEntities;
for (var i = 0; i < trackedEnt.length; i++) {
if (trackedEnt[i].data.equals(data)) existsItem = trackedEnt[i];
}
//var existsItem = this.entityContext.stateManager.trackedEntities.filter(function (i) { return i.data.equals(data); }).pop();
if (existsItem) {
var idx = this.entityContext.stateManager.trackedEntities.indexOf(existsItem);
entity.entityState = _index2.default.EntityState.Detached;
this.entityContext.stateManager.trackedEntities.splice(idx, 1);
return;
}
},
attachOrGet: function attachOrGet(entity, mode) {
/// <signature>
/// <summary>Creates a typed entity and adds to the Context with Unchanged state.</summary>
/// <param name="entity" type="Object">The init parameters whish is based on Entity</param>
/// <returns type="$data.Entity" />
/// <example>
/// Id is a key of entity.
/// var person = Persons.attachOrGet({ Id: 5 });
///
/// </example>
/// </signature>
/// <signature>
/// <summary>If not in context then adds to it and sets state Unchanged.</summary>
/// <param name="entity" type="$data.Entity">The entity to detach</param>
/// <returns type="$data.Entity" />
/// <example>
///
/// var attachedPerson = Persons.attachOrGet(person);
///
/// </example>
/// <example>
/// Id is a key of entity.
/// var p = new $news.Types.Person({ Id: 5 });
/// var attachedPerson = Persons.attachOrGet(p);
///
/// </example>
/// </signature>
var data = entity;
if (entity instanceof _index2.default.EntityWrapper) {
data = entity.getEntity();
} else if (!(entity instanceof this.createNew)) {
data = new this.createNew(entity);
}
var existsItem;
var trackedEnt = this.entityContext.stateManager.trackedEntities;
for (var i = 0; i < trackedEnt.length; i++) {
if (trackedEnt[i].data.equals(data)) existsItem = trackedEnt[i];
}
//var existsItem = this.entityContext.stateManager.trackedEntities.filter(function (i) { return i.data.equals(data); }).pop();
if (existsItem) {
return existsItem.data;
}
if (typeof mode === "string") mode = _index2.default.EntityAttachMode[mode];
var attachMode = mode || _index2.default.EntityAttachMode[_index2.default.EntityAttachMode.defaultMode];
if (typeof attachMode === "function") {
attachMode.call(_index2.default.EntityAttachMode, data);
} else {
data.entityState = _index2.default.EntityState.Unchanged;
data.changedProperties = undefined;
}
//data.entityState = $data.EntityState.Unchanged;
//data.changedProperties = undefined;
data.context = this.entityContext;
this._trackEntity(data);
return data;
},
//find: function (keys) {
// //todo global scope
// if (!this.entityKeys) {
// this.entityKeys = this.createNew.memberDefinition.filter(function (prop) { return prop.key; }, this);
// }
// this.entityContext.stateManager.trackedEntities.forEach(function (item) {
// if (item.entitySet == this) {
// var isOk = true;
// this.entityKeys.forEach(function (item, index) { isOK = isOk && (item.data[item.name] == keys[index]); }, this);
// if (isOk) {
// return item.data;
// }
// }
// }, this);
// //TODO: db call
// return null;
//},
loadItemProperty: function loadItemProperty(entity, memberDefinition, callback) {
/// <signature>
/// <summary>Loads a property of the entity through the storage provider.</summary>
/// <param name="entity" type="$data.Entity">Entity object</param>
/// <param name="property" type="String">Property name</param>
/// <param name="callback" type="Function">
/// <summary>Callback function</summary>
/// <param name="propertyValue" />
/// </param>
/// <returns type="$.Deferred" />
/// </signature>
/// <signature>
/// <summary>Loads a property of the entity through the storage provider.</summary>
/// <param name="entity" type="$data.Entity">Entity object</param>
/// <param name="property" type="String">Property name</param>
/// <param name="callbacks" type="Object">
/// Success and error callbacks definition.
/// Example: [code]{ success: function(db) { .. }, error: function() { .. } }[/code]
/// </param>
/// <returns type="$.Deferred" />
/// </signature>
/// <signature>
/// <summary>Loads a property of the entity through the storage provider.</summary>
/// <param name="entity" type="$data.Entity">Entity object</param>
/// <param name="property" type="$data.MemberDefinition">Property definition</param>
/// <param name="callback" type="Function">
/// <summary>Callback function</summary>
/// <param name="propertyValue" />
/// </param>
/// <returns type="$.Deferred" />
/// </signature>
/// <signature>
/// <summary>Loads a property of the entity through the storage provider.</summary>
/// <param name="entity" type="$data.Entity">Entity object</param>
/// <param name="property" type="$data.MemberDefinition">Property definition</param>
/// <param name="callbacks" type="Object">
/// Success and error callbacks definition.
/// Example: [code]{ success: function(db) { .. }, error: function() { .. } }[/code]
/// </param>
/// <returns type="$.Deferred" />
/// </signature>
return this.entityContext.loadItemProperty(entity, memberDefinition, callback);
},
saveChanges: function saveChanges() {
return this.entityContext.saveChanges.apply(this.entityContext, arguments);
},
addProperty: function addProperty(name, getter, setter) {
return this.elementType.addProperty.apply(this.elementType, arguments);
},
expression: {
get: function get() {
if (!this._expression) {
var ec = _index.Container.createEntityContextExpression(this.entityContext);
//var name = entitySet.collectionName;
//var entitySet = this.entityContext[entitySetName];
var memberdef = this.entityContext.getType().getMemberDefinition(this.collectionName);
var es = _index.Container.createEntitySetExpression(ec, _index.Container.createMemberInfoExpression(memberdef), null, this);
this._expression = es;
}
return this._expression;
},
set: function set(value) {
this._expression = value;
}
},
getFieldUrl: function getFieldUrl(keys, field) {
return this.entityContext.getFieldUrl(keys, field, this);
},
bulkInsert: function bulkInsert(fields, datas, callback) {
return this.entityContext.bulkInsert(this, fields, datas, callback);
}
}, null);
exports.default = _index2.default;
module.exports = exports['default'];