diff --git a/README.md b/README.md index 6e92d19..f755a49 100644 --- a/README.md +++ b/README.md @@ -108,7 +108,7 @@ through the `QueryCollection` API that will be discussed later: tasks.tags.remove(tag)l tasks.tags.list(tx, function(allTags) { console.log(allTags); }); -Persisting objects +Persisting/removing objects ------------------ Similar to [hibernate](http://www.hibernate.org), `persistence.js` @@ -127,6 +127,10 @@ be persisted using the `persistence.add` function: persistence.add(t); } +Objects can also be removed from the database: + + persistence.remove(c); + All changes made to tracked objects can be flushed to the database by using `persistence.flush`, which takes a transaction object and callback function as arguments. A new transaction can be started using diff --git a/persistence.js b/persistence.js index 6e08f8e..7f791c6 100644 --- a/persistence.js +++ b/persistence.js @@ -29,6 +29,7 @@ var persistence = window.persistence || {}; var conn = null; var entityMeta = {}; var trackedObjects = {}; + var objectsToRemove = {}; persistence.trackedObjects = trackedObjects; @@ -99,16 +100,16 @@ var persistence = window.persistence || {}; */ persistence.schemaSync = function (callback) { var queries = []; - for ( var entityName in entityMeta) { + for (var entityName in entityMeta) { if (entityMeta.hasOwnProperty(entityName)) { var meta = entityMeta[entityName]; var rowDef = ''; - for ( var prop in meta.fields) { + for (var prop in meta.fields) { if (meta.fields.hasOwnProperty(prop)) { rowDef += prop + " " + meta.fields[prop] + ", "; } } - for ( var rel in meta.hasOne) { + for (var rel in meta.hasOne) { if (meta.hasOne.hasOwnProperty(rel)) { var otherMeta = meta.hasOne[rel].type.meta; rowDef += rel + " VARCHAR(255), "; @@ -117,7 +118,7 @@ var persistence = window.persistence || {}; + "` ON `" + meta.name + "` (`" + rel + "`)", null ]); } } - for ( var rel in meta.hasMany) { + for (var rel in meta.hasMany) { if (meta.hasMany.hasOwnProperty(rel) && meta.hasMany[rel].manyToMany) { var tableName = meta.hasMany[rel].tableName; if (!generatedTables[tableName]) { @@ -161,6 +162,16 @@ var persistence = window.persistence || {}; } }; + /** + * Marks the object to be removed (on next flush) + * @param obj object to be removed + */ + persistence.remove = function(obj) { + if (!objectsToRemove[obj.id]) { + objectsToRemove[obj.id] = obj; + } + }; + /** * Persists all changes to the database * @@ -174,24 +185,45 @@ var persistence = window.persistence || {}; persistence.transaction(function(tx) { persistence.flush(tx, callback); }); return; } - var objArray = []; - for ( var id in trackedObjects) { + var persistObjArray = []; + for (var id in trackedObjects) { if (trackedObjects.hasOwnProperty(id)) { - objArray.push(trackedObjects[id]); + persistObjArray.push(trackedObjects[id]); + } + } + var removeObjArray = []; + for (var id in objectsToRemove) { + if (objectsToRemove.hasOwnProperty(id)) { + removeObjArray.push(objectsToRemove[id]); + delete trackedObjects[id]; // Stop tracking } } - function persistOneEntity () { - var obj = objArray.pop(); + function removeOneObject() { + var obj = removeObjArray.pop(); + remove(obj, tx, function () { + if (removeObjArray.length > 0) { + removeOneObject(); + } else if (callback) { + callback(); + } + }); + } + function persistOneObject () { + var obj = persistObjArray.pop(); save(obj, tx, function () { - if (objArray.length > 0) { - persistOneEntity(); + if (persistObjArray.length > 0) { + persistOneObject(); + } else if(removeObjArray.length > 0) { + removeOneObject(); } else if (callback) { callback(); } }); } - if (objArray.length > 0) { - persistOneEntity(); + if (persistObjArray.length > 0) { + persistOneObject(); + } else if(removeObjArray.length > 0) { + removeOneObject(); } else if(callback) { callback(); } @@ -528,8 +560,16 @@ var persistence = window.persistence || {}; } function remove (obj, tx, callback) { - var sql = "DELETE FROM `" + obj._type + "` WHERE id = '" + obj.id + "'"; - tx.executeSql(sql, null, callback); + var queries = [["DELETE FROM `" + obj._type + "` WHERE id = '" + obj.id + "'", null]]; + var meta = persistence.getMeta(obj._type); + for (var rel in meta.hasMany) { + if (meta.hasMany.hasOwnProperty(rel) && meta.hasMany[rel].manyToMany) { + var tableName = meta.hasMany[rel].tableName; + //var inverseProperty = meta.hasMany[rel].inverseProperty; + queries.push(["DELETE FROM `" + tableName + "` WHERE `" + meta.name + '_' + rel + "` = '" + obj.id + "'", null]); + } + } + executeQueriesSeq(tx, queries, callback); } /** @@ -552,7 +592,7 @@ var persistence = window.persistence || {}; } else if (callback) { callback.apply(this, callbackArgs); } - }); + }, function(_, err) { console.log(err); }); } if (queries.length > 0) { executeOne(); diff --git a/persistence.min.js b/persistence.min.js index 202a7b3..da20c7d 100644 --- a/persistence.min.js +++ b/persistence.min.js @@ -24,28 +24,29 @@ OTHER DEALINGS IN THE SOFTWARE. */ var persistence=window.persistence||{}; -(function(){function k(a){function b(d){var e=this;this.id=H();this._new=true;this._type=a;this._dirtyProperties={};this._data={};this._data_obj={};for(var h in c.fields)(function(){if(c.fields.hasOwnProperty(h)){var f=h;e.__defineSetter__(f,function(j){e._data[f]=j;e._dirtyProperties[f]=true});e.__defineGetter__(f,function(){return e._data[f]})}})();for(var g in c.hasOne)c.hasOne.hasOwnProperty(g)&&function(){var f=g;e.__defineSetter__(f,function(j){if(j==null){e._data[f]=null;e._data_obj[f]=undefined}else if(j.id){e._data[f]= +(function(){function k(a){function b(d){var e=this;this.id=J();this._new=true;this._type=a;this._dirtyProperties={};this._data={};this._data_obj={};for(var h in c.fields)(function(){if(c.fields.hasOwnProperty(h)){var f=h;e.__defineSetter__(f,function(j){e._data[f]=j;e._dirtyProperties[f]=true});e.__defineGetter__(f,function(){return e._data[f]})}})();for(var g in c.hasOne)c.hasOne.hasOwnProperty(g)&&function(){var f=g;e.__defineSetter__(f,function(j){if(j==null){e._data[f]=null;e._data_obj[f]=undefined}else if(j.id){e._data[f]= j.id;e._data_obj[f]=j;persistence.add(j)}else e._data[f]=j;e._dirtyProperties[f]=true});e.__defineGetter__(f,function(){if(e._data[f]===null||e._data_obj[f]!==undefined)return e._data_obj[f];else throw"Property '"+f+"' with id: "+e._data[f]+" not fetched, either prefetch it or fetch it manually.";})}();for(g in c.hasMany)c.hasMany.hasOwnProperty(g)&&function(){var f=g;if(c.hasMany[f].manyToMany){e.__defineSetter__(f,function(){throw"Not yet supported.";});e.__defineGetter__(f,function(){if(this._data[f])return e._data[f]; else{var j=c.hasMany[f].type.meta,l=new u(j.name);l.initManyToMany(e,f);l._additionalJoinSqls.push("LEFT JOIN `"+c.hasMany[f].tableName+"` AS mtm ON mtm.`"+j.name+"_"+c.hasMany[f].inverseProperty+"` = `"+j.name+"`.`id` ");l._additionalWhereSqls.push("mtm.`"+c.name+"_"+f+"` = '"+e.id+"'");return e._data[f]=l}})}else{e.__defineSetter__(f,function(){throw"Not yet supported.";});e.__defineGetter__(f,function(){if(this._data[f])return e._data[f];else{var j=(new v(c.hasMany[f].type.meta.name)).filter(c.hasMany[f].inverseProperty, -"=",e);return e._data[f]=j}})}}();for(var i in d)if(d.hasOwnProperty(i))e[i]=d[i]}if(C[a])return C[a];var c=s[a];b.meta=c;b.prototype.equals=function(d){return this.id==d.id};b.all=function(){return new v(a)};b.hasMany=function(d,e,h){var g=e.meta;if(g.hasMany[h]){var i=c.name+"_"+d+"_"+g.name,f=g.name+"_"+h+"_"+c.name;if(i>f)i=f;c.hasMany[d]={type:e,inverseProperty:h,manyToMany:true,tableName:i};g.hasMany[h]={type:b,inverseProperty:d,manyToMany:true,tableName:i};delete c.hasOne[d]}else{c.hasMany[d]= -{type:e,inverseProperty:h};g.hasOne[h]={type:b,inverseProperty:d}}};b.hasOne=function(d,e){c.hasOne[d]={type:e}};return C[a]=b}function r(a,b,c){var d=s[a._type],e=[],h=[],g=[],i=[];for(var f in a._dirtyProperties)if(a._dirtyProperties.hasOwnProperty(f)){e.push("`"+f+"`");h.push(persistence.entityValToDbVal(a[f]));g.push("?");i.push("`"+f+"` = ?")}var j=[];for(f in d.hasMany)if(d.hasMany.hasOwnProperty(f))j=j.concat(a[f].persistQueries());n(b,j,function(){if(e.length===0)c();else{a._dirtyProperties= -{};if(a._new){e.push("id");h.push(a.id);g.push("?");var l="INSERT INTO `"+a._type+"` ("+e.join(", ")+") VALUES ("+g.join(", ")+")";a._new=false}else l="UPDATE `"+a._type+"` SET "+i.join(",")+" WHERE id = '"+a.id+"'";b.executeSql(l,h,c)}})}function n(a,b,c){function d(){var g=b.pop();a.executeSql(g[0],g[1],function(){if(b.length>0)d();else c&&c.apply(this,e)})}for(var e=[],h=3;h0)d();else c&&c.apply(this,e)}function H(){for(var a=[],b=0;b<32;b++)a[b]= -"0123456789ABCDEF".substr(Math.floor(Math.random()*16),1);a[12]="4";a[16]="0123456789ABCDEF".substr(a[16]&3|8,1);return a.join("")}function I(){this.sql=function(){return"1=1"};this.match=function(){return true};this.makeFit=function(){};this.makeNotFit=function(){}}function J(a,b){this.sql=function(c,d){return"("+a.sql(c,d)+" AND "+b.sql(c,d)+")"};this.match=function(c){return a.match(c)&&b.match(c)};this.makeFit=function(c){a.makeFit(c);b.makeFit(c)};this.makeNotFit=function(c){a.makeNotFit(c); -b.makeNotFit(c)}}function K(a,b,c){this.sql=function(d,e){if(b==="="&&c===null)return"`"+d+a+"` IS NULL";else if(b==="!="&&c===null)return"`"+d+a+"` IS NOT NULL";else{e.push(persistence.entityValToDbVal(c));return"`"+d+a+"` "+b+" ?"}};this.match=function(d){switch(b){case "=":return d[a]===c;case "!=":return d[a]!==c;case "<":return d[a]":return d[a]>c;case ">=":return d[a]>=c}};this.makeFit=function(d){if(b==="=")d[a]=c;else throw"Sorry, can't perform makeFit for other filters than ="; -};this.makeNotFit=function(d){if(b==="=")d[a]=null;else throw"Sorry, can't perform makeNotFit for other filters than =";}}function o(){}function v(a){this.init(a,v)}function u(a){this.init(a,u);this._localAdded=[];this._localRemoved=[]}var s={},t={};persistence.trackedObjects=t;persistence.getMeta=function(a){return s[a]};persistence.connect=function(a,b,c){persistence._conn=persistence.db.connect(a,b,c)};persistence.transaction=function(a){persistence._conn.transaction(a)};persistence.define=function(a, -b){if(s[a])return k(a);s[a]={name:a,fields:b,hasMany:{},hasOne:{}};return k(a)};var x={};persistence.schemaSync=function(a){var b=[];for(var c in s)if(s.hasOwnProperty(c)){var d=s[c],e="";for(var h in d.fields)if(d.fields.hasOwnProperty(h))e+=h+" "+d.fields[h]+", ";for(var g in d.hasOne)if(d.hasOne.hasOwnProperty(g)){var i=d.hasOne[g].type.meta;e+=g+" VARCHAR(255), ";b.push(["CREATE INDEX IF NOT EXISTS `"+d.name+"_"+g+"_"+i.name+"` ON `"+d.name+"` (`"+g+"`)",null])}for(g in d.hasMany)if(d.hasMany.hasOwnProperty(g)&& -d.hasMany[g].manyToMany){var f=d.hasMany[g].tableName;if(!x[f]){i=d.hasMany[g].type.meta;b.push(["CREATE INDEX IF NOT EXISTS `"+f+"_"+d.name+"_"+g+"` ON `"+f+"` (`"+d.name+"_"+g+"`)",null]);b.push(["CREATE INDEX IF NOT EXISTS `"+f+"_"+i.name+"_"+d.hasMany[g].inverseProperty+"` ON `"+f+"` (`"+i.name+"_"+d.hasMany[g].inverseProperty+"`)",null]);b.push(["CREATE TABLE IF NOT EXISTS `"+f+"` (`"+d.name+"_"+g+"` VARCHAR(32), `"+i.name+"_"+d.hasMany[g].inverseProperty+"` VARCHAR(32))",null]);x[f]=true}}e= -e.substring(0,e.length-2);x[d.name]=true;b.push(["CREATE TABLE IF NOT EXISTS `"+d.name+"` ( id VARCHAR(32) PRIMARY KEY, "+e+")",null])}persistence.transaction(function(j){n(j,b,a,j)})};persistence.add=function(a){t[a.id]||(t[a.id]=a)};persistence.flush=function(a,b){function c(){var h=d.pop();r(h,a,function(){if(d.length>0)c();else b&&b()})}if(a){var d=[];for(var e in t)t.hasOwnProperty(e)&&d.push(t[e]);if(d.length>0)c();else b&&b()}else persistence.transaction(function(h){persistence.flush(h,b)})}; -persistence.clean=function(){t={}};persistence.reset=function(a){function b(){var d=c.pop();a.executeSql("DROP TABLE "+d,null,function(){c.length>0&&b()})}var c=[];for(p in x)x.hasOwnProperty(p)&&c.push(p);b();persistence.clean();x={}};persistence.rowToEntity=function(a,b,c){c=c||"";if(t[b[c+"id"]])return t[b[c+"id"]];var d=s[a];a=new (k(a));a.id=b[c+"id"];a._new=false;for(var e in b)if(b.hasOwnProperty(e))if(e.substring(0,c.length)===c){var h=e.substring(c.length);if(h!="id")a[h]=persistence.dbValToEntityVal(b[e], -d.fields[h])}return a};persistence.dbValToEntityVal=function(a,b){switch(b){case "BOOL":return a===1;default:return a}};persistence.entityValToDbVal=function(a,b){return a===undefined?null:a.id?a.id:b==="BOOL"?a?1:0:a};var C={};o.prototype.persistQueries=function(){return[]};o.prototype.init=function(a,b){this._filter=new I;this._orderColumns=[];this._prefetchFields=[];this._additionalJoinSqls=[];this._additionalWhereSqls=[];this._entityName=a;this._constructor=b;this._limit=-1;this._skip=0};o.prototype.clone= -function(){var a=new this._constructor(this._entityName);a._filter=this._filter;a._prefetchFields=this._prefetchFields.slice(0);a._orderColumns=this._orderColumns.slice(0);a._limit=this._limit;a._skip=this._skip;return a};o.prototype.filter=function(a,b,c){var d=this.clone();d._filter=new J(this._filter,new K(a,b,c));return d};o.prototype.order=function(a,b){b=b||true;var c=this.clone();c._orderColumns.push([a,b]);return c};o.prototype.limit=function(a){var b=this.clone();b._limit=a;return b};o.prototype.skip= -function(a){var b=this.clone();b._skip=a;return b};o.prototype.prefetch=function(a){var b=this.clone();b._prefetchFields.push(a);return b};o.prototype.add=function(a){if(!a.id||!a._type)throw"Cannot add object of non-entity type onto collection.";persistence.add(a);this._filter.makeFit(a)};o.prototype.remove=function(a){if(!a.id||!a._type)throw"Cannot remove object of non-entity type from collection.";persistence.add(a);this._filter.makeNotFit(a)};v.prototype=new o;v.prototype.list=function(a,b){function c(m, -y,w){var z=["`"+y+"`.id AS "+w+"id"];for(var q in m.fields)m.fields.hasOwnProperty(q)&&z.push("`"+y+"`.`"+q+"` AS `"+w+q+"`");for(q in m.hasOne)m.hasOne.hasOwnProperty(q)&&z.push("`"+y+"`.`"+q+"` AS `"+w+q+"`");return z}var d=this;if(a){for(var e=this._entityName,h=persistence.getMeta(e),g=[],i=e+"_",f=c(h,h.name,i),j=this._additionalJoinSqls.join(" "),l=0;l0)B+=" ORDER BY "+this._orderColumns.map(function(m){return"`"+i+m[0]+"` "+(m[1]?"ASC":"DESC")}).join(", ");if(this._limit>=0)B+=" LIMIT "+this._limit;if(this._skip>0)B+=" OFFSET "+this._skip;persistence.flush(a,function(){a.executeSql(B,g,function(m){for(var y=[],w=0;wf)i=f;c.hasMany[d]={type:e,inverseProperty:h,manyToMany:true,tableName:i};g.hasMany[h]={type:b,inverseProperty:d,manyToMany:true,tableName:i};delete c.hasOne[d]}else{c.hasMany[d]= +{type:e,inverseProperty:h};g.hasOne[h]={type:b,inverseProperty:d}}};b.hasOne=function(d,e){c.hasOne[d]={type:e}};return D[a]=b}function q(a,b,c){var d=t[a._type],e=[],h=[],g=[],i=[];for(var f in a._dirtyProperties)if(a._dirtyProperties.hasOwnProperty(f)){e.push("`"+f+"`");h.push(persistence.entityValToDbVal(a[f]));g.push("?");i.push("`"+f+"` = ?")}var j=[];for(f in d.hasMany)if(d.hasMany.hasOwnProperty(f))j=j.concat(a[f].persistQueries());E(b,j,function(){if(e.length===0)c();else{a._dirtyProperties= +{};if(a._new){e.push("id");h.push(a.id);g.push("?");var l="INSERT INTO `"+a._type+"` ("+e.join(", ")+") VALUES ("+g.join(", ")+")";a._new=false}else l="UPDATE `"+a._type+"` SET "+i.join(",")+" WHERE id = '"+a.id+"'";b.executeSql(l,h,c)}})}function r(a,b,c){var d=[["DELETE FROM `"+a._type+"` WHERE id = '"+a.id+"'",null]],e=persistence.getMeta(a._type);for(var h in e.hasMany)e.hasMany.hasOwnProperty(h)&&e.hasMany[h].manyToMany&&d.push(["DELETE FROM `"+e.hasMany[h].tableName+"` WHERE `"+e.name+"_"+h+ +"` = '"+a.id+"'",null]);E(b,d,c)}function E(a,b,c){function d(){var g=b.pop();a.executeSql(g[0],g[1],function(){if(b.length>0)d();else c&&c.apply(this,e)},function(i,f){console.log(f)})}for(var e=[],h=3;h0)d();else c&&c.apply(this,e)}function J(){for(var a=[],b=0;b<32;b++)a[b]="0123456789ABCDEF".substr(Math.floor(Math.random()*16),1);a[12]="4";a[16]="0123456789ABCDEF".substr(a[16]&3|8,1);return a.join("")}function K(){this.sql=function(){return"1=1"}; +this.match=function(){return true};this.makeFit=function(){};this.makeNotFit=function(){}}function L(a,b){this.sql=function(c,d){return"("+a.sql(c,d)+" AND "+b.sql(c,d)+")"};this.match=function(c){return a.match(c)&&b.match(c)};this.makeFit=function(c){a.makeFit(c);b.makeFit(c)};this.makeNotFit=function(c){a.makeNotFit(c);b.makeNotFit(c)}}function M(a,b,c){this.sql=function(d,e){if(b==="="&&c===null)return"`"+d+a+"` IS NULL";else if(b==="!="&&c===null)return"`"+d+a+"` IS NOT NULL";else{e.push(persistence.entityValToDbVal(c)); +return"`"+d+a+"` "+b+" ?"}};this.match=function(d){switch(b){case "=":return d[a]===c;case "!=":return d[a]!==c;case "<":return d[a]":return d[a]>c;case ">=":return d[a]>=c}};this.makeFit=function(d){if(b==="=")d[a]=c;else throw"Sorry, can't perform makeFit for other filters than =";};this.makeNotFit=function(d){if(b==="=")d[a]=null;else throw"Sorry, can't perform makeNotFit for other filters than =";}}function n(){}function v(a){this.init(a,v)}function u(a){this.init(a, +u);this._localAdded=[];this._localRemoved=[]}var t={},s={},A={};persistence.trackedObjects=s;persistence.getMeta=function(a){return t[a]};persistence.connect=function(a,b,c){persistence._conn=persistence.db.connect(a,b,c)};persistence.transaction=function(a){persistence._conn.transaction(a)};persistence.define=function(a,b){if(t[a])return k(a);t[a]={name:a,fields:b,hasMany:{},hasOne:{}};return k(a)};var x={};persistence.schemaSync=function(a){var b=[];for(var c in t)if(t.hasOwnProperty(c)){var d= +t[c],e="";for(var h in d.fields)if(d.fields.hasOwnProperty(h))e+=h+" "+d.fields[h]+", ";for(var g in d.hasOne)if(d.hasOne.hasOwnProperty(g)){var i=d.hasOne[g].type.meta;e+=g+" VARCHAR(255), ";b.push(["CREATE INDEX IF NOT EXISTS `"+d.name+"_"+g+"_"+i.name+"` ON `"+d.name+"` (`"+g+"`)",null])}for(g in d.hasMany)if(d.hasMany.hasOwnProperty(g)&&d.hasMany[g].manyToMany){var f=d.hasMany[g].tableName;if(!x[f]){i=d.hasMany[g].type.meta;b.push(["CREATE INDEX IF NOT EXISTS `"+f+"_"+d.name+"_"+g+"` ON `"+f+ +"` (`"+d.name+"_"+g+"`)",null]);b.push(["CREATE INDEX IF NOT EXISTS `"+f+"_"+i.name+"_"+d.hasMany[g].inverseProperty+"` ON `"+f+"` (`"+i.name+"_"+d.hasMany[g].inverseProperty+"`)",null]);b.push(["CREATE TABLE IF NOT EXISTS `"+f+"` (`"+d.name+"_"+g+"` VARCHAR(32), `"+i.name+"_"+d.hasMany[g].inverseProperty+"` VARCHAR(32))",null]);x[f]=true}}e=e.substring(0,e.length-2);x[d.name]=true;b.push(["CREATE TABLE IF NOT EXISTS `"+d.name+"` ( id VARCHAR(32) PRIMARY KEY, "+e+")",null])}persistence.transaction(function(j){E(j, +b,a,j)})};persistence.add=function(a){s[a.id]||(s[a.id]=a)};persistence.remove=function(a){A[a.id]||(A[a.id]=a)};persistence.flush=function(a,b){function c(){var i=g.pop();r(i,a,function(){if(g.length>0)c();else b&&b()})}function d(){var i=e.pop();q(i,a,function(){if(e.length>0)d();else if(g.length>0)c();else b&&b()})}if(a){var e=[];for(var h in s)s.hasOwnProperty(h)&&e.push(s[h]);var g=[];for(h in A)if(A.hasOwnProperty(h)){g.push(A[h]);delete s[h]}if(e.length>0)d();else if(g.length>0)c();else b&& +b()}else persistence.transaction(function(i){persistence.flush(i,b)})};persistence.clean=function(){s={}};persistence.reset=function(a){function b(){var d=c.pop();a.executeSql("DROP TABLE "+d,null,function(){c.length>0&&b()})}var c=[];for(p in x)x.hasOwnProperty(p)&&c.push(p);b();persistence.clean();x={}};persistence.rowToEntity=function(a,b,c){c=c||"";if(s[b[c+"id"]])return s[b[c+"id"]];var d=t[a];a=new (k(a));a.id=b[c+"id"];a._new=false;for(var e in b)if(b.hasOwnProperty(e))if(e.substring(0,c.length)=== +c){var h=e.substring(c.length);if(h!="id")a[h]=persistence.dbValToEntityVal(b[e],d.fields[h])}return a};persistence.dbValToEntityVal=function(a,b){switch(b){case "BOOL":return a===1;default:return a}};persistence.entityValToDbVal=function(a,b){return a===undefined?null:a.id?a.id:b==="BOOL"?a?1:0:a};var D={};n.prototype.persistQueries=function(){return[]};n.prototype.init=function(a,b){this._filter=new K;this._orderColumns=[];this._prefetchFields=[];this._additionalJoinSqls=[];this._additionalWhereSqls= +[];this._entityName=a;this._constructor=b;this._limit=-1;this._skip=0};n.prototype.clone=function(){var a=new this._constructor(this._entityName);a._filter=this._filter;a._prefetchFields=this._prefetchFields.slice(0);a._orderColumns=this._orderColumns.slice(0);a._limit=this._limit;a._skip=this._skip;return a};n.prototype.filter=function(a,b,c){var d=this.clone();d._filter=new L(this._filter,new M(a,b,c));return d};n.prototype.order=function(a,b){b=b||true;var c=this.clone();c._orderColumns.push([a, +b]);return c};n.prototype.limit=function(a){var b=this.clone();b._limit=a;return b};n.prototype.skip=function(a){var b=this.clone();b._skip=a;return b};n.prototype.prefetch=function(a){var b=this.clone();b._prefetchFields.push(a);return b};n.prototype.add=function(a){if(!a.id||!a._type)throw"Cannot add object of non-entity type onto collection.";persistence.add(a);this._filter.makeFit(a)};n.prototype.remove=function(a){if(!a.id||!a._type)throw"Cannot remove object of non-entity type from collection."; +persistence.add(a);this._filter.makeNotFit(a)};v.prototype=new n;v.prototype.list=function(a,b){function c(m,y,w){var z=["`"+y+"`.id AS "+w+"id"];for(var o in m.fields)m.fields.hasOwnProperty(o)&&z.push("`"+y+"`.`"+o+"` AS `"+w+o+"`");for(o in m.hasOne)m.hasOne.hasOwnProperty(o)&&z.push("`"+y+"`.`"+o+"` AS `"+w+o+"`");return z}var d=this;if(a){for(var e=this._entityName,h=persistence.getMeta(e),g=[],i=e+"_",f=c(h,h.name,i),j=this._additionalJoinSqls.join(" "),l=0;l0)C+=" ORDER BY "+this._orderColumns.map(function(m){return"`"+i+m[0]+"` "+(m[1]?"ASC":"DESC")}).join(", ");if(this._limit>=0)C+=" LIMIT "+this._limit;if(this._skip>0)C+=" OFFSET "+ +this._skip;persistence.flush(a,function(){a.executeSql(C,g,function(m){for(var y=[],w=0;w