Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Refactor to make adapters simpler

  • Loading branch information...
commit 849cac4ee113d24abb53931befcf2ec4da92993b 1 parent 8125cc9
mde authored
Showing with 154 additions and 158 deletions.
  1. +11 −0 lib/adapters/base_adapter.js
  2. +108 −151 lib/adapters/sql/postgres.js
  3. +35 −7 lib/index.js
View
11 lib/adapters/base_adapter.js
@@ -8,6 +8,17 @@ BaseAdapter = function () {
BaseAdapter.prototype = new EventEmitter();
utils.mixin(BaseAdapter.prototype, new (function () {
+
+ this.all = function (query, callback) {};
+
+ this.update = function (data, query, callback) {};
+
+ this.remove = function (query, callback) {};
+
+ this.save = function (data, opts, callback) {};
+
+ this.createTable = function (names, callback) {};
+
})());
module.exports.BaseAdapter = BaseAdapter;
View
259 lib/adapters/sql/postgres.js
@@ -12,8 +12,8 @@ _baseConfig = {
user: process.env.USER
, database: process.env.USER
, password: null
-, port: 5432
, host: null
+, port: 5432
};
Adapter = function (options) {
@@ -34,122 +34,6 @@ Adapter.prototype.constructor = Adapter;
utils.mixin(Adapter.prototype, new (function () {
- var _insert = function (data, callback) {
- var self = this
- , items = Array.isArray(data) ? data : [data]
- , modelName = items[0].type
- , ctor = model[modelName]
- , reg = model.descriptionRegistry
- , props = reg[modelName].properties
- , prop
- , def
- , datatypes = model.datatypes
- , sql = '';
-
- items.forEach(function (item) {
- var cols = []
- , vals = [];
-
- // If using string UUID ids
- if (!ctor.autoIncrementId) {
- item.id = utils.string.uuid();
- cols.push(self._columnizePropertyName('id'));
- vals.push(datatypes.string.serialize(item.id, {
- escape: true
- , useQuotes: true
- }));
- }
- else {
- cols.push(self._columnizePropertyName('id'));
- vals.push('DEFAULT');
- }
-
- for (var p in props) {
- def = props[p];
- prop = item[p];
- // Use the same definition of NULL as for updates
- prop = self._serializeValue(prop, def.datatype);
- if (prop != 'NULL') {
- cols.push(self._columnizePropertyName(p, {
- useQuotes: true
- }));
- vals.push(prop);
- }
- }
- sql += 'INSERT INTO ' + self._tableizeModelName(modelName) + ' ';
- sql += '(' + cols.join(', ') + ')';
- sql += ' VALUES ';
- sql += '(' + vals.join(', ') + ')';
- sql += ' RETURNING id'
- sql += ';\n';
- });
-
- this.exec(sql, function (err, res) {
- var item
- , rows;
- if (err) {
- callback(err, null);
- }
- else {
- rows = res.rows;
- for (var i = 0, ii = items.length; i < ii; i++) {
- item = items[i];
- item.id = rows[i].id;
- item._saved = true;
- }
- callback(null, items.length == 1 ? items[0] : items);
- }
- });
- }
-
- , _update = function (data, query, callback) {
- var modelName = data.type
- , reg = model.descriptionRegistry
- , props = reg[modelName].properties
- , prop
- , def
- , datatypes = model.datatypes
- , sql = ''
- , updates = []
- , update;
-
- // Bail out if instance isn't valid
- if (!data.isValid()) {
- return callback(data.errors, null);
- }
-
- // Iterate over the properties in the params, make sure each
- // property exists in the definition
- for (var p in data) {
- def = props[p];
- prop = data[p];
- if (props.hasOwnProperty(p)) {
- update = this._columnizePropertyName(p, {
- useQuotes: true
- }) +
- ' = ';
-
- update += this._serializeValue(prop, def.datatype);
-
- updates.push(update);
- }
- }
- sql += 'UPDATE ' + this._tableizeModelName(modelName) + ' SET ';
- sql += updates.join(', ') + ' ';
- sql += 'WHERE ' + this._serializeConditions(query.conditions);
- sql += ';'
-
- this.exec(sql, function (err, res) {
- if (err) {
- callback(err, null);
- }
- else {
- data._saved = true;
- callback(null, data);
- }
- });
- };
-
this.init = function () {
this.client = new pg.Client(this.config);
};
@@ -222,8 +106,52 @@ utils.mixin(Adapter.prototype, new (function () {
});
};
- this.update = function (data, query, callback) {
- _update.apply(this, arguments);
+ this.update = function (data, query, opts, callback) {
+ var modelName = data.type
+ , reg = model.descriptionRegistry
+ , props = reg[modelName].properties
+ , prop
+ , def
+ , datatypes = model.datatypes
+ , sql = ''
+ , updates = []
+ , update;
+
+ // Bail out if instance isn't valid
+ if (!data.isValid()) {
+ return callback(data.errors, null);
+ }
+
+ // Iterate over the properties in the params, make sure each
+ // property exists in the definition
+ for (var p in data) {
+ def = props[p];
+ prop = data[p];
+ if (props.hasOwnProperty(p)) {
+ update = this._columnizePropertyName(p, {
+ useQuotes: true
+ }) +
+ ' = ';
+
+ update += this._serializeValue(prop, def.datatype);
+
+ updates.push(update);
+ }
+ }
+ sql += 'UPDATE ' + this._tableizeModelName(modelName) + ' SET ';
+ sql += updates.join(', ') + ' ';
+ sql += 'WHERE ' + this._serializeConditions(query.conditions);
+ sql += ';'
+
+ this.exec(sql, function (err, res) {
+ if (err) {
+ callback(err, null);
+ }
+ else {
+ data._saved = true;
+ callback(null, data);
+ }
+ });
};
this.remove = function (query, callback) {
@@ -242,42 +170,71 @@ utils.mixin(Adapter.prototype, new (function () {
};
this.save = function (data, opts, callback) {
- var saved
- , item;
+ var self = this
+ , items = Array.isArray(data) ? data : [data]
+ , modelName = items[0].type
+ , ctor = model[modelName]
+ , reg = model.descriptionRegistry
+ , props = reg[modelName].properties
+ , prop
+ , def
+ , datatypes = model.datatypes
+ , sql = '';
+
+ items.forEach(function (item) {
+ var cols = []
+ , vals = [];
+
+ // If using string UUID ids
+ if (!ctor.autoIncrementId) {
+ item.id = utils.string.uuid();
+ cols.push(self._columnizePropertyName('id'));
+ vals.push(datatypes.string.serialize(item.id, {
+ escape: true
+ , useQuotes: true
+ }));
+ }
+ else {
+ cols.push(self._columnizePropertyName('id'));
+ vals.push('DEFAULT');
+ }
- // Bulk save only works on new items -- existing item should only
- // be when doing instance.save
- if (Array.isArray(data)) {
- saved = false;
- for (var i = 0, ii = data.length; i < ii; i++) {
- item = data[i];
- if (item._saved) {
- return callback(new Error('A bulk-save can only have new ' +
- 'items in it.'), null);
- }
- // Bail out if instance isn't valid
- if (!item.isValid()) {
- return callback(item.errors, null);
+ for (var p in props) {
+ def = props[p];
+ prop = item[p];
+ // Use the same definition of NULL as for updates
+ prop = self._serializeValue(prop, def.datatype);
+ if (prop != 'NULL') {
+ cols.push(self._columnizePropertyName(p, {
+ useQuotes: true
+ }));
+ vals.push(prop);
}
}
- }
- else {
- saved = data._saved;
- // Bail out if instance isn't valid
- if (!data.isValid()) {
- return callback(data.errors, null);
- }
- }
+ sql += 'INSERT INTO ' + self._tableizeModelName(modelName) + ' ';
+ sql += '(' + cols.join(', ') + ')';
+ sql += ' VALUES ';
+ sql += '(' + vals.join(', ') + ')';
+ sql += ' RETURNING id'
+ sql += ';\n';
+ });
- // Existing instance, create dummy Query object and do update
- if (saved) {
- query = new Query(model[data.type], {id: data.id}, {});
- _update.apply(this, [data, query, callback]);
- }
- // New instance(s), insert
- else {
- _insert.apply(this, [data, callback]);
- }
+ this.exec(sql, function (err, res) {
+ var item
+ , rows;
+ if (err) {
+ callback(err, null);
+ }
+ else {
+ rows = res.rows;
+ for (var i = 0, ii = items.length; i < ii; i++) {
+ item = items[i];
+ item.id = rows[i].id;
+ item._saved = true;
+ }
+ callback(null, items.length == 1 ? items[0] : items);
+ }
+ });
};
View
42 lib/index.js
@@ -351,22 +351,50 @@ utils.mixin(model, new (function () {
, callback = args.pop()
, data = args.shift()
, opts = args.shift() || {}
- , adapt;
+ , adapt
+ , saved;
adapt = model.adapters[name];
if (!adapt) {
throw new Error('Adapter not found for ' + name);
}
- if (data.errors) {
- callback(data.errors, null);
+ // Collection
+ // Bulk save only works on new items -- existing item should only
+ // be when doing instance.save
+ if (Array.isArray(data)) {
+ saved = false;
+ for (var i = 0, ii = data.length; i < ii; i++) {
+ item = data[i];
+ if (item._saved) {
+ return callback(new Error('A bulk-save can only have new ' +
+ 'items in it.'), null);
+ }
+ // Bail out if instance isn't valid
+ if (!item.isValid()) {
+ return callback(item.errors, null);
+ }
+ }
}
+ // Single item
else {
- if (model.useTimestamps && data._saved) {
- data.updatedAt = new Date();
+ saved = data._saved;
+ // Bail out if instance isn't valid
+ if (!data.isValid()) {
+ return callback(data.errors, null);
+ }
+ // Already existing instance, use update
+ if (saved) {
+ if (model.useTimestamps) {
+ data.updatedAt = new Date();
+ }
+ // Re-route to update
+ return obj.update.apply(obj, [data, {id: data.id},
+ opts, callback]);
}
- return adapt.save.apply(adapt, [data, opts, callback]);
}
+
+ return adapt.save.apply(adapt, [data, opts, callback]);
};
obj.update = function () {
@@ -390,7 +418,7 @@ utils.mixin(model, new (function () {
throw new Error('Adapter not found for ' + name);
}
- return adapt.update.apply(adapt, [data, query, callback]);
+ return adapt.update.apply(adapt, [data, query, opts, callback]);
};
obj.remove = function () {
Please sign in to comment.
Something went wrong with that request. Please try again.