From 6e1f689cfd8f820090c4ab15519114f4d3bf929f Mon Sep 17 00:00:00 2001 From: Sean Fridman Date: Fri, 10 Apr 2015 21:38:31 -0400 Subject: Overhaul DB impl Make DB schema aware Add autoincrement support Add custom ID field support --- app/node_modules/okresource/index.js | 126 +++++++++++++++-------------------- 1 file changed, 54 insertions(+), 72 deletions(-) (limited to 'app/node_modules/okresource/index.js') diff --git a/app/node_modules/okresource/index.js b/app/node_modules/okresource/index.js index 0e8498f..df89617 100644 --- a/app/node_modules/okresource/index.js +++ b/app/node_modules/okresource/index.js @@ -20,17 +20,6 @@ function OKResource(options) { var schema = options.schema; var spec = schema.spec; - // Iterate through spec to find field which will act as the - // resource id in da db. - var idField = Object.keys(spec).reduce(function(idField, prop) { - var propSpec = spec[prop]; - if (propSpec.id) - idField = prop; - return idField; - // If schema has a prop called 'id', default to that one - }, spec.id && 'id'); - if (!idField) - throw new Error('Bad schema: no ID field'); var type = options.type; this._db = options.db; @@ -51,12 +40,6 @@ function OKResource(options) { enumerable: true }); - Object.defineProperty(this, 'idField', { - value: idField, - writable: false, - enumerable: true - }); - // Whether this resource represents a specific data point // or a whole class of data Object.defineProperty(this, 'bound', { @@ -74,19 +57,22 @@ OKResource.prototype.assertValid = function(data) { }; OKResource.prototype.all = function() { - return this._db.getAll(this.type); + return this._db.all(this.type); }; -OKResource.prototype.create = function(data) { +OKResource.prototype.getID = function(data) { data = data || {}; + return data[this._schema.idField]; +}; + +OKResource.prototype.create = function(data) { var type = this.type; var db = this._db; - var id = data[this.idField]; return Q.promise(function(resolve, reject) { - if (!id) { - reject(new Error('Data does not contain ID property')); + if (!data) { + reject(new Error('No data provided')); } else { - db.create(type, data).then(resolve).fail(reject); + db.insert(type, data).then(resolve).fail(reject); } }); }; @@ -94,13 +80,11 @@ OKResource.prototype.create = function(data) { OKResource.prototype.destroy = function(id) { var db = this._db; var type = this.type; - var query = {}; - query[this.idField] = id; return Q.promise(function(resolve, reject) { if (!id) { - reject(new Error('No ID given')); + reject(new Error('No ID provided')); } else { - db.remove(type, query).then(resolve).fail(reject); + db.remove(type, id).then(resolve).fail(reject); } }); }; @@ -111,7 +95,7 @@ OKResource.prototype.find = function(query) { var type = this.type; return Q.promise(function(resolve, reject) { if (!query) { - throw new Error('No query given'); + throw new Error('No query provided'); } else { db.find(type, query).then(resolve).fail(reject); } @@ -121,53 +105,64 @@ OKResource.prototype.find = function(query) { OKResource.prototype.get = function(id) { var db = this._db; var type = this.type; - var idField = this.idField; return Q.promise(function(resolve, reject) { if (!id) { - throw new Error('No ID given'); + throw new Error('No ID provided'); } else { - // We have the id, but we still need - // to resolve which field is the id field - // to match - var query = {}; - query[idField] = id; - db.get(type, query).then(resolve).fail(reject); + db.get(type, id).then(resolve).fail(reject); } }); }; OKResource.prototype.update = function(id, data) { - data = data || {}; var db = this._db; var type = this.type; - var idField = this.idField; return Q.promise(function(resolve, reject) { if (!id) { reject(new Error('No resource ID provided')); - } else { - var query = {}; - query[idField] = id; - db.put(type, query, data).then(resolve).fail(reject);; + } else if (!data) { + reject(new Error('No data provided')); + }else { + db.update(type, id, data).then(resolve).fail(reject);; } }); }; +/** + * Update all resources with the given ids with the given data + */ +OKResource.prototype.updateBatch = function(ids, datas) { + // var type = this.type; + // var db = this._db; + // var idField = this.idField; + // return Q.promise(function(resolve, reject) { + // if (!ids || !ids.length || !datas || !datas.length || + // ids.length !== datas.length) { + // reject(new Error('Bad input')); + // } else { + // var queries = ids.map(function(id, i) { + // var query = {}; + // query[idField] = datas[i][idField]; + // return query; + // }); + // db.putAll(type, queries, datas).then(resolve).fail(reject); + // } + // }); +}; + OKResource.prototype.updateOrCreate = function(id, data) { data = data || {}; var type = this.type; var db = this._db; - var idField = this.idField; - var query = {}; - query[idField] = id; return Q.promise(function(resolve, reject) { if (!id) { - reject(new Error('No resource ID provided')); + reject(new Error('No ID provided')); } else { - db.get(type, query).then(function(persisted) { + db.get(type, id).then(function(persisted) { if (persisted) { - db.put(type, query, data).then(resolve).fail(reject); + db.update(type, id, data).then(resolve).fail(reject); } else { - db.create(type, data).then(resolve).fail(reject); + db.insert(type, data).then(resolve).fail(reject); } }).fail(reject); } @@ -196,11 +191,15 @@ function OKResourceInstance(resource, options) { // configuration, but may not actually be present // in the database and need custom logic to handle this. var staticData = cloneDeep(options.static); - var id = staticData[resource.idField]; + var id = resource.getID(staticData); if (!id) throw new Error( 'Cannot create static OKResourceInstance without an ID field'); + this.getID = function() { + return id; + }; + /** * Ensure that static data is provided on get */ @@ -209,9 +208,9 @@ function OKResourceInstance(resource, options) { resource.get(id).then(function(data) { // Note the assign call. Don't expose private references! if (data) { - resolve(assign({}, data, cloneDeep(staticData))); + resolve(assign(data, cloneDeep(staticData))); } else { - resolve(assign({}, cloneDeep(staticData))); + resolve(cloneDeep(staticData)); } }).fail(reject); }); @@ -286,14 +285,9 @@ function OKResourceInstance(resource, options) { }); Object.defineProperty(this, 'spec', { - value: resource.spec, - writable: false, - enumerable: true - }); - - Object.defineProperty(this, 'id', { - value: id, - writable: false, + get: function() { + return resource.spec + }, enumerable: true }); @@ -303,23 +297,11 @@ function OKResourceInstance(resource, options) { enumerable: true }); - Object.defineProperty(this, 'idField', { - value: resource.idField, - writable: false, - enumerable: true - }); - Object.defineProperty(this, 'bound', { value: true, writable: false, enumerable: true }); - - Object.defineProperty(this, 'class', { - value: resource, - writable: false, - enumerable: true - }); } module.exports = OKResource; -- cgit v1.2.3-70-g09d2 From 4021d7846ce164f3f0c3cb37d3a1d82d2de489d9 Mon Sep 17 00:00:00 2001 From: Sean Fridman Date: Fri, 10 Apr 2015 23:09:05 -0400 Subject: Give views sorted resources --- app/node_modules/okdb/index.js | 11 +++++++++++ app/node_modules/okquery/index.js | 3 ++- app/node_modules/okresource/index.js | 11 ++++++++++- 3 files changed, 23 insertions(+), 2 deletions(-) (limited to 'app/node_modules/okresource/index.js') diff --git a/app/node_modules/okdb/index.js b/app/node_modules/okdb/index.js index 7639ec6..c00087c 100644 --- a/app/node_modules/okdb/index.js +++ b/app/node_modules/okdb/index.js @@ -117,6 +117,17 @@ FSDB.prototype.remove = function(collection, id) { } }; +FSDB.prototype.sortBy = function(collection, prop, descend) { + var schema = this._schemas[collection]; + if (!schema) + return resolve(null, new Error('No such collection type')); + if (!prop) + return resolve(null, new Error('Bad input')); + + var result = this._db(collection).sortByOrder([prop], [!descend]); + return resolve(result); +}; + FSDB.prototype.find = function(collection, id) { var schema = this._schemas[collection]; if (!schema) diff --git a/app/node_modules/okquery/index.js b/app/node_modules/okquery/index.js index 89c8b73..9cc8b78 100644 --- a/app/node_modules/okquery/index.js +++ b/app/node_modules/okquery/index.js @@ -96,7 +96,8 @@ function queryDynamic(resource) { function queryAll(resource) { return function() { - return resource.all(); + // Always return sorted results + return resource.sortBy('__index'); }; } diff --git a/app/node_modules/okresource/index.js b/app/node_modules/okresource/index.js index df89617..8c0bb16 100644 --- a/app/node_modules/okresource/index.js +++ b/app/node_modules/okresource/index.js @@ -122,12 +122,21 @@ OKResource.prototype.update = function(id, data) { reject(new Error('No resource ID provided')); } else if (!data) { reject(new Error('No data provided')); - }else { + } else { db.update(type, id, data).then(resolve).fail(reject);; } }); }; + +/** + * Get all documents in collection sorted by property, + * optionally in descending order + */ +OKResource.prototype.sortBy = function(prop, descend) { + return this._db.sortBy(this.type, prop, descend); +}; + /** * Update all resources with the given ids with the given data */ -- cgit v1.2.3-70-g09d2 From a20297451b88c604b16a35223be4b25528713c6d Mon Sep 17 00:00:00 2001 From: Sean Fridman Date: Sat, 11 Apr 2015 01:36:09 -0400 Subject: Implement FSDB.updateBatch and OKResource.updateBatch --- app/node_modules/okdb/index.js | 20 ++++++++++++++++++++ app/node_modules/okresource/index.js | 36 ++++++++++++++---------------------- 2 files changed, 34 insertions(+), 22 deletions(-) (limited to 'app/node_modules/okresource/index.js') diff --git a/app/node_modules/okdb/index.js b/app/node_modules/okdb/index.js index c00087c..ffe3ff1 100644 --- a/app/node_modules/okdb/index.js +++ b/app/node_modules/okdb/index.js @@ -101,6 +101,26 @@ FSDB.prototype.update = function(collection, id, data) { } }; +/** + * TODO Should be atomic ¯\_(ツ)_/¯ + */ +FSDB.prototype.updateBatch = function(collection, ids, datas) { + var schema = this._schemas[collection]; + if (!schema) + return resolve(null, new Error('No such collection type')); + if (!ids || !ids.length || !datas || !datas.length || + ids.length !== datas.length) { + return resolve(null, new Error('Bad input')); + } + + var doc = this._db(collection); + var results = ids.map(function(id, i) { + return doc.chain().find(getQuery(schema, id)).assign(datas[i]).value(); + }); + + return resolve(results); +}; + FSDB.prototype.remove = function(collection, id) { var schema = this._schemas[collection]; if (!schema) diff --git a/app/node_modules/okresource/index.js b/app/node_modules/okresource/index.js index 8c0bb16..c3f9adb 100644 --- a/app/node_modules/okresource/index.js +++ b/app/node_modules/okresource/index.js @@ -128,6 +128,20 @@ OKResource.prototype.update = function(id, data) { }); }; +OKResource.prototype.updateBatch = function(ids, datas) { + var self = this; + var db = this._db; + var type = this.type; + return Q.promise(function(resolve, reject) { + if (!ids || !ids.length || !datas || !datas.length || + ids.length !== datas.length) { + reject(new Error('Bad input')); + } else { + db.updateBatch(type, ids, datas).then(resolve).fail(reject); + } + }); +} + /** * Get all documents in collection sorted by property, @@ -137,28 +151,6 @@ OKResource.prototype.sortBy = function(prop, descend) { return this._db.sortBy(this.type, prop, descend); }; -/** - * Update all resources with the given ids with the given data - */ -OKResource.prototype.updateBatch = function(ids, datas) { - // var type = this.type; - // var db = this._db; - // var idField = this.idField; - // return Q.promise(function(resolve, reject) { - // if (!ids || !ids.length || !datas || !datas.length || - // ids.length !== datas.length) { - // reject(new Error('Bad input')); - // } else { - // var queries = ids.map(function(id, i) { - // var query = {}; - // query[idField] = datas[i][idField]; - // return query; - // }); - // db.putAll(type, queries, datas).then(resolve).fail(reject); - // } - // }); -}; - OKResource.prototype.updateOrCreate = function(id, data) { data = data || {}; var type = this.type; -- cgit v1.2.3-70-g09d2