Comparing version 0.1.5 to 0.1.6
@@ -1521,2 +1521,2 @@ /** | ||
return id; | ||
} | ||
} |
@@ -262,33 +262,37 @@ /** | ||
'@collection': model | ||
}, partName, index = 0; | ||
}; | ||
if (filter) { | ||
if (filter.where) { | ||
Object.keys(filter.where).forEach(function (k) { | ||
var cond = filter.where[k]; | ||
var spec = false; | ||
partName = 'where' + (index++); | ||
if (cond && cond.constructor.name === 'Object') { | ||
spec = Object.keys(cond)[0]; | ||
cond = cond[spec]; | ||
} | ||
if (spec) { | ||
if (spec === 'between') { | ||
// mop: XXX need to check docs | ||
throw new Error("between statements not supported for arangodb"); | ||
} else { | ||
// bindVars[partName] = cond; | ||
// query.push('x.' + k + ' IN @' + partName); | ||
} | ||
if (filter.where) { | ||
var csql = self.buildWhere(filter.where, self, model); | ||
query.push(csql.query.join(' ')); | ||
Object.keys(csql.bindVars).forEach(function(bkey){ | ||
bindVars[bkey] = csql.bindVars[bkey]; | ||
}); | ||
} | ||
} | ||
if (filter.order) { | ||
var keys = filter.order; | ||
if (typeof keys === 'string') { | ||
keys = keys.split(','); | ||
} | ||
var args = {}; | ||
for (var index in keys) { | ||
var m = keys[index].match(/\s+(A|DE)SC$/); | ||
var key = keys[index]; | ||
key = key.replace(/\s+(A|DE)SC$/, '').trim(); | ||
if (m && m[1] === 'DE') { | ||
args[key] = 'DESC'; | ||
} else { | ||
bindVars[partName] = cond; | ||
query.push('FILTER x.`' + k + '` == @' + partName); | ||
args[key] = 'ASC'; | ||
} | ||
}.bind(self)); | ||
} | ||
var order = ''; | ||
Object.keys(args).forEach(function (kx) { | ||
order += 'x.`' + kx + '` ' + args[kx]; | ||
}); | ||
query.push('SORT ' + order); | ||
} | ||
if (filter.order) { | ||
// var order = 'i.' + filter.order; | ||
// if (typeof order === 'string') order = [order]; | ||
// query.sort(order.join(', ')); | ||
} | ||
if (filter.limit) { | ||
@@ -306,2 +310,3 @@ query.push('LIMIT @skip, @limit'); | ||
} | ||
self.client.query(maql, function (err, cursor) { | ||
@@ -348,2 +353,3 @@ if (err) { | ||
}; | ||
// TODO: implement | ||
@@ -417,2 +423,146 @@ Arango.prototype.count = function (model, callback, where) { | ||
.createHashIndex(fields, {unique: unique}, callback); | ||
}; | ||
}; | ||
Arango.prototype.buildWhere = function buildWhere(conds, adapter, model) { | ||
'use strict'; | ||
var qw = {}, cs = [], or = [], bindVars = {}, cix = 0, | ||
self = adapter, | ||
props = self._models[model].properties; | ||
Object.keys(conds).forEach(function (key) { | ||
if (key !== 'or') { | ||
qw = parseCond(cs, bindVars, key, props, conds, self, cix); | ||
} else { | ||
conds[key].forEach(function (oconds) { | ||
Object.keys(oconds).forEach(function (okey) { | ||
or = parseCond(or, bindVars, okey, props, oconds, self, cix); | ||
}); | ||
}); | ||
} | ||
cix++; | ||
}); | ||
if (cs.length === 0 && or.length === 0) { | ||
return ''; | ||
} | ||
var orop = ''; | ||
if (or.length) { | ||
orop = ' (' + or.join(' OR ') + ') '; | ||
} | ||
orop += (orop !== "" && cs.length > 0) ? ' AND ' : ''; | ||
return qw; | ||
}; | ||
Arango.prototype.toDatabase = function (prop, val, esc) { | ||
"use strict"; | ||
if (val === null) { | ||
return ''; | ||
} | ||
if (!prop) { | ||
return val; | ||
} | ||
if (prop.type.name === 'Number') { | ||
return val; | ||
} | ||
if (prop.type.name === 'Date') { | ||
if (!val) { | ||
return 0; | ||
} | ||
if (typeof val === 'string') { | ||
val = Date.parse(val); | ||
} | ||
if (val instanceof Date) { | ||
val = val.getTime(); | ||
} | ||
return val; | ||
} | ||
if (prop.type.name === "Boolean") { | ||
return val ? 1 : 0; | ||
} | ||
return esc ? '\'' + val.toString() + '\'' : val.toString(); | ||
}; | ||
var parseCond = function (cs, bindVars, key, props, conds, self, cix) { | ||
'use strict'; | ||
var keyEscaped = 'FILTER x.`' + key + '`'; | ||
var val = conds[key]; | ||
if (val === null) { | ||
cs.push(keyEscaped + '\'\''); | ||
} else if (val.constructor.name === 'Object') { | ||
Object.keys(val).forEach(function (condType) { | ||
val = self.toDatabase(props[key], val[condType], true); | ||
var sqlCond = keyEscaped; | ||
if ((condType === 'inq' || condType === 'nin') && val.length === 0) { | ||
cs.push(condType === 'inq' ? 0 : 1); | ||
return true; | ||
} | ||
switch (condType.toString().toLowerCase()) { | ||
case 'gt': | ||
sqlCond += ' > '; | ||
break; | ||
case 'gte': | ||
sqlCond += ' >= '; | ||
break; | ||
case 'lt': | ||
sqlCond += ' < '; | ||
break; | ||
case 'lte': | ||
sqlCond += ' <= '; | ||
break; | ||
case 'between': | ||
sqlCond += ' '; | ||
break; | ||
case 'inq': | ||
case 'in': | ||
sqlCond += ' IN '; | ||
break; | ||
case 'nin': | ||
sqlCond += ' NOT IN '; | ||
break; | ||
case 'neq': | ||
case 'ne': | ||
sqlCond += ' != '; | ||
break; | ||
case 'regex': | ||
sqlCond += ' REGEXP '; | ||
break; | ||
case 'like': | ||
sqlCond += ' LIKE '; | ||
break; | ||
case 'nlike': | ||
sqlCond += ' NOT LIKE '; | ||
break; | ||
default: | ||
sqlCond += ' ' + condType + ' '; | ||
break; | ||
} | ||
if(condType === 'between') { | ||
sqlCond += ' >= @whereL'; | ||
sqlCond += ' AND x.`' + key + '`'; | ||
sqlCond += ' <= @whereG'; | ||
bindVars['whereL'] = val[0]; | ||
bindVars['whereG'] = val[1]; | ||
} else if (condType === 'in' || condType === 'inq' || condType === 'nin') { | ||
sqlCond += ' @where' + cix; | ||
bindVars['where' + cix] = val; | ||
} else { | ||
sqlCond += val; | ||
} | ||
cs.push(sqlCond); | ||
}); | ||
} else if (/^\//gi.test(conds[key])) { | ||
var reg = val.toString().split('/'); | ||
cs.push(keyEscaped + ' REGEXP "' + reg[1] + '"'); | ||
} else { | ||
val = self.toDatabase(props[key], val, false); | ||
cs.push(keyEscaped + ' == @where' + cix); | ||
bindVars['where' + cix] = val; | ||
} | ||
return { | ||
query : cs, | ||
bindVars: bindVars | ||
}; | ||
}; |
@@ -8,16 +8,29 @@ /** | ||
function quote(value) { | ||
var quote = function (value) { | ||
return '"' + value + '"'; | ||
} | ||
}; | ||
exports.initialize = function initializeSchema(schema, callback) { | ||
if (!fb) | ||
'use strict'; | ||
if (!fb) { | ||
return; | ||
schema.adapter = new FB(schema); | ||
} | ||
var options = {}, s = schema.settings; | ||
fb.attachOrCreate(schema.settings, | ||
function(err, client) { | ||
options.host = s.host; | ||
options.port = s.port; | ||
options.database = s.database || 'test.fdb'; | ||
options.user = s.username || 'sysdba'; | ||
options.password = s.password || 'aea0be33'; | ||
schema.adapter = new FB(schema, s); | ||
if (s.pool) { | ||
fb.pool(s.pool, options) | ||
.get(function (err, client) { | ||
if (!err) { | ||
schema.adapter.client = client; | ||
callback(); | ||
console.log('FB', typeof client.execute) | ||
process.nextTick(function () { | ||
callback(); | ||
}); | ||
} else { | ||
@@ -27,98 +40,197 @@ console.error(err); | ||
} | ||
}); | ||
} else { | ||
fb.attachOrCreate(options, function (err, client) { | ||
if (!err) { | ||
schema.adapter.client = client; | ||
console.log('FB', typeof client.execute) | ||
process.nextTick(function () { | ||
callback(); | ||
}); | ||
} else { | ||
console.error(err); | ||
throw new Error(err); | ||
} | ||
} | ||
); | ||
); | ||
} | ||
}; | ||
function FB(schema) { | ||
function FB(schema, s) { | ||
this.name = 'firebird'; | ||
this._models = {}; | ||
this.collections = {}; | ||
this.client = {}; | ||
this.schema = schema; | ||
this.s = s; | ||
} | ||
FB.prototype.define = function(descr) { | ||
if (!descr.settings) | ||
FB.prototype.define = function (descr) { | ||
if (!descr.settings) { | ||
descr.settings = {}; | ||
} | ||
this._models[descr.model.modelName] = descr; | ||
}; | ||
FB.prototype.automigrate = function(cb) { | ||
var wait = 0; | ||
FB.prototype.autoupdate = function (callback) { | ||
var self = this; | ||
this.client.startTransaction( | ||
function(err, tr) { | ||
Object.keys(self._models).forEach( | ||
function(name) { | ||
var table = self.schema.tableName(name); | ||
var model = self._models[name]; | ||
wait += 1; | ||
self.client.execute('SELECT a.RDB$RELATION_NAME FROM RDB$RELATIONS a' + | ||
' WHERE RDB$SYSTEM_FLAG = 0 AND RDB$RELATION_TYPE = 0', function (err, relations) { | ||
if (err) { | ||
console.log('err', err) | ||
} | ||
var sql = 'RECREATE TABLE ' + quote(table) + '(\n' + | ||
' "id" INTEGER NOT NULL,\n'; | ||
var tables = ((relations || [])[0] || []).map(function (item) { | ||
return (item || '').replace(/^\s+|\s+$/, ''); | ||
}); | ||
var len = Object.keys(self._models).length; | ||
Object.keys(model.properties).forEach( | ||
function(field) { | ||
var str; | ||
if (field === 'id') | ||
return; | ||
var f = model.properties[field]; | ||
switch (f.type.name) { | ||
case 'String': | ||
str = 'Varchar(' + (f.length || 255) + ')'; | ||
break; | ||
case 'Number': | ||
str = 'Double precision'; | ||
break; | ||
case 'Date': | ||
str = 'Timestamp'; | ||
break; | ||
case 'Boolean': | ||
str = 'Smallint'; | ||
break; | ||
default: | ||
str = 'Blob sub_type 1'; | ||
} | ||
sql += ' ' + quote(field) + ' ' + str + (f.allowNull === false || f['null'] === false ? ' NOT NULL,' : ',') + '\n'; | ||
Object.keys(self._models).forEach(function (name) { | ||
if (tables.indexOf(name) === -1) { | ||
var table = self.schema.tableName(name); | ||
var model = self._models[name]; | ||
self.client.startTransaction(function (err, tr) { | ||
var sql = 'CREATE TABLE ' + quote(table) + '(\n' + | ||
' "id" INTEGER NOT NULL,\n'; | ||
Object.keys(model.properties).forEach(function (field) { | ||
var str; | ||
if (field === 'id') { | ||
return; | ||
} | ||
var f = model.properties[field]; | ||
switch (f.type.name) { | ||
case 'String': | ||
str = 'Varchar(' + (f.length || f.limit || 255) + ')'; | ||
break; | ||
case 'Number': | ||
str = 'Double precision'; | ||
break; | ||
case 'Date': | ||
str = 'Timestamp'; | ||
break; | ||
case 'Boolean': | ||
str = 'Smallint'; | ||
break; | ||
default: | ||
str = 'Blob sub_type 1'; | ||
} | ||
sql += ' ' + quote(field) + ' ' + str + (f.allowNull === false || f['null'] === false ? ' NOT NULL,' : ',') + '\n'; | ||
} | ||
); | ||
sql += ' PRIMARY KEY ("id"))'; | ||
console.log('sql:', sql) | ||
tr.execute(sql, function (err) { | ||
if (!err) { | ||
var sequence = quote(table + '_SEQ'); | ||
tr.execute('create generator ' + sequence); | ||
tr.execute('set generator ' + sequence + ' to 0'); | ||
tr.execute( | ||
'CREATE TRIGGER ' + quote(table + '_BI') + ' FOR ' + quote(table) + '\n' + | ||
'ACTIVE BEFORE INSERT POSITION 0\n' + | ||
'AS\n' + | ||
'BEGIN\n' + | ||
' IF (NEW."id" IS NULL) THEN\n' + | ||
' NEW."id" = GEN_ID(' + sequence + ', 1);\n' + | ||
'END', function () { | ||
if (--len === 0) { | ||
tr.commit(callback); | ||
} | ||
); | ||
sql += ' PRIMARY KEY ("id"))'; | ||
}); | ||
} else { | ||
if (--len === 0) { | ||
tr.rollback(callback); | ||
} | ||
} | ||
}); | ||
}); | ||
} else { | ||
// TODO actualise | ||
if (--len === 0) { | ||
console.log('autoupdate end') | ||
callback(); | ||
} | ||
} | ||
}); | ||
}); | ||
}; | ||
tr.execute(sql, function(err) { | ||
console.log(arguments); | ||
if (!err) { | ||
var sequence = quote(table + '_SEQ'); | ||
tr.execute('create generator ' + sequence); | ||
tr.execute('set generator ' + sequence + ' to 0'); | ||
tr.execute( | ||
'CREATE TRIGGER ' + quote(table + '_BI') + ' FOR ' + quote(table) + '\n' + | ||
'ACTIVE BEFORE INSERT POSITION 0\n' + | ||
'AS\n' + | ||
'BEGIN\n' + | ||
' IF (NEW."id" IS NULL) THEN\n' + | ||
' NEW."id" = GEN_ID(' + sequence + ', 1);\n' + | ||
'END', done); | ||
} else { | ||
done(err); | ||
} | ||
}); | ||
FB.prototype.automigrate = function (cb) { | ||
var wait = 0; | ||
var self = this; | ||
this.client.startTransaction(function (err, tr) { | ||
Object.keys(self._models).forEach( | ||
function (name) { | ||
var table = self.schema.tableName(name); | ||
var model = self._models[name]; | ||
wait += 1; | ||
var sql = 'RECREATE TABLE ' + quote(table) + '(\n' + | ||
' "id" INTEGER NOT NULL,\n'; | ||
Object.keys(model.properties).forEach( | ||
function (field) { | ||
var str; | ||
if (field === 'id') | ||
return; | ||
var f = model.properties[field]; | ||
switch (f.type.name) { | ||
case 'String': | ||
str = 'Varchar(' + (f.length || 255) + ')'; | ||
break; | ||
case 'Number': | ||
str = 'Double precision'; | ||
break; | ||
case 'Date': | ||
str = 'Timestamp'; | ||
break; | ||
case 'Boolean': | ||
str = 'Smallint'; | ||
break; | ||
default: | ||
str = 'Blob sub_type 1'; | ||
} | ||
sql += ' ' + quote(field) + ' ' + str + (f.allowNull === false || f['null'] === false ? ' NOT NULL,' : ',') + '\n'; | ||
} | ||
); | ||
); | ||
sql += ' PRIMARY KEY ("id"))'; | ||
if (wait === 0) { | ||
cb(); | ||
tr.execute(sql, function (err) { | ||
if (!err) { | ||
var sequence = quote(table + '_SEQ'); | ||
tr.execute('create generator ' + sequence); | ||
tr.execute('set generator ' + sequence + ' to 0'); | ||
tr.execute( | ||
'CREATE TRIGGER ' + quote(table + '_BI') + ' FOR ' + quote(table) + '\n' + | ||
'ACTIVE BEFORE INSERT POSITION 0\n' + | ||
'AS\n' + | ||
'BEGIN\n' + | ||
' IF (NEW."id" IS NULL) THEN\n' + | ||
' NEW."id" = GEN_ID(' + sequence + ', 1);\n' + | ||
'END', done); | ||
} else { | ||
done(err); | ||
} | ||
}); | ||
} | ||
function done(err) { | ||
if (err) { | ||
tr.rollback(cb); | ||
} else { | ||
if (--wait === 0) { | ||
tr.commit(cb); | ||
} | ||
); | ||
if (wait === 0) { | ||
cb(); | ||
} | ||
function done(err) { | ||
if (err) { | ||
tr.rollback(cb); | ||
} else { | ||
if (--wait === 0) { | ||
tr.commit(cb); | ||
} | ||
} | ||
} | ||
} | ||
); | ||
}; | ||
FB.prototype.create = function(name, data, callback) { | ||
FB.prototype.create = function (name, data, callback) { | ||
var table = this.schema.tableName(name); | ||
@@ -132,9 +244,9 @@ var sql = 'INSERT INTO ' + quote(table); | ||
Object.keys(data).forEach( | ||
function(key) { | ||
if (key === 'id') | ||
return; | ||
fields.push(quote(key)); | ||
values.push('?'); | ||
params.push(data[key]); | ||
} | ||
function (key) { | ||
if (key === 'id') | ||
return; | ||
fields.push(quote(key)); | ||
values.push('?'); | ||
params.push(data[key]); | ||
} | ||
); | ||
@@ -151,5 +263,5 @@ | ||
this.client.execute(sql, params, | ||
function(err, result) { | ||
callback(err, (result) ? result[0] : undefined); | ||
} | ||
function (err, result) { | ||
callback(err, (result) ? result[0] : undefined); | ||
} | ||
); | ||
@@ -168,3 +280,3 @@ }; | ||
FB.prototype.save = function(name, data, callback) { | ||
FB.prototype.save = function (name, data, callback) { | ||
var table = this.schema.tableName(name); | ||
@@ -178,12 +290,12 @@ var sql = 'UPDATE ' + quote(table) + ' SET '; | ||
Object.keys(data).forEach( | ||
function(key) { | ||
if (key === 'id') | ||
return; | ||
fields.push(quote(key) + ' = ?'); | ||
if ((data[key]) && (model.properties[key].type.name === 'Date')) { | ||
params.push(new Date(data[key])); | ||
} else { | ||
params.push(data[key]); | ||
} | ||
function (key) { | ||
if (key === 'id') | ||
return; | ||
fields.push(quote(key) + ' = ?'); | ||
if ((data[key]) && (model.properties[key].type.name === 'Date')) { | ||
params.push(new Date(data[key])); | ||
} else { | ||
params.push(data[key]); | ||
} | ||
} | ||
); | ||
@@ -200,9 +312,9 @@ sql += fields.join(',') + ' WHERE "id"=?'; | ||
this.client.query(sql, id, | ||
function(err, result) { | ||
callback(err, (result && result.length === 1) ? result[0] : undefined); | ||
} | ||
function (err, result) { | ||
callback(err, (result && result.length === 1) ? result[0] : undefined); | ||
} | ||
); | ||
}; | ||
FB.prototype.all = function(name, filter, callback) { | ||
FB.prototype.all = function (name, filter, callback) { | ||
if ('function' === typeof filter) { | ||
@@ -240,73 +352,73 @@ callback = filter; | ||
Object.keys(conds).forEach( | ||
function(key) { | ||
var keyEscaped = quote(key); | ||
var val = conds[key]; | ||
var lst, i; | ||
if (conds[key] === null) { | ||
cs.push(keyEscaped + ' IS NULL'); | ||
} else if (conds[key].constructor.name === 'Object') { | ||
switch (Object.keys(conds[key])[0]) { | ||
case 'gt': | ||
cs.push(keyEscaped + ' > ?'); | ||
params.push(val.gt); | ||
break; | ||
case 'gte': | ||
cs.push(keyEscaped + ' >= ?'); | ||
params.push(val.gte); | ||
break; | ||
case 'lt': | ||
cs.push(keyEscaped + ' < ?'); | ||
params.push(val.lt); | ||
break; | ||
case 'lte': | ||
cs.push(keyEscaped + ' <= ?'); | ||
params.push(val.lte); | ||
break; | ||
case 'between': | ||
cs.push(keyEscaped + ' BETWEEN ? AND ?'); | ||
params.push(val.between[0]); | ||
params.push(val.between[1]); | ||
break; | ||
case 'in': | ||
case 'inq': | ||
if (val.inq instanceof Array) { | ||
lst = new Array(val.inq.length); | ||
for (i = 0; i < val.inq.length; i++) { | ||
lst[i] = '?'; | ||
params.push(val.inq[i]); | ||
} | ||
} else { | ||
lst = [val.inq]; | ||
params.push(val.inq); | ||
function (key) { | ||
var keyEscaped = quote(key); | ||
var val = conds[key]; | ||
var lst, i; | ||
if (conds[key] === null) { | ||
cs.push(keyEscaped + ' IS NULL'); | ||
} else if (conds[key].constructor.name === 'Object') { | ||
switch (Object.keys(conds[key])[0]) { | ||
case 'gt': | ||
cs.push(keyEscaped + ' > ?'); | ||
params.push(val.gt); | ||
break; | ||
case 'gte': | ||
cs.push(keyEscaped + ' >= ?'); | ||
params.push(val.gte); | ||
break; | ||
case 'lt': | ||
cs.push(keyEscaped + ' < ?'); | ||
params.push(val.lt); | ||
break; | ||
case 'lte': | ||
cs.push(keyEscaped + ' <= ?'); | ||
params.push(val.lte); | ||
break; | ||
case 'between': | ||
cs.push(keyEscaped + ' BETWEEN ? AND ?'); | ||
params.push(val.between[0]); | ||
params.push(val.between[1]); | ||
break; | ||
case 'in': | ||
case 'inq': | ||
if (val.inq instanceof Array) { | ||
lst = new Array(val.inq.length); | ||
for (i = 0; i < val.inq.length; i++) { | ||
lst[i] = '?'; | ||
params.push(val.inq[i]); | ||
} | ||
cs.push(keyEscaped + ' IN (' + lst.join(',') + ')'); | ||
break; | ||
case 'nin': | ||
if (val.nin instanceof Array) { | ||
lst = new Array(val.nin.length); | ||
for (i = 0; i < val.nin.length; i++) { | ||
lst[i] = '?'; | ||
params.push(val.nin[i]); | ||
} | ||
} else { | ||
lst = [val.nin]; | ||
params.push(val.nin); | ||
} else { | ||
lst = [val.inq]; | ||
params.push(val.inq); | ||
} | ||
cs.push(keyEscaped + ' IN (' + lst.join(',') + ')'); | ||
break; | ||
case 'nin': | ||
if (val.nin instanceof Array) { | ||
lst = new Array(val.nin.length); | ||
for (i = 0; i < val.nin.length; i++) { | ||
lst[i] = '?'; | ||
params.push(val.nin[i]); | ||
} | ||
cs.push(keyEscaped + ' NOT IN (' + lst.join(',') + ')'); | ||
break; | ||
case 'ne': | ||
case 'neq': | ||
cs.push(keyEscaped + ' != ?'); | ||
params.push(val.neq); | ||
break; | ||
case 'regexp': | ||
cs.push(keyEscaped + ' REGEXP ?'); | ||
params.push(val.lte); | ||
break; | ||
} | ||
} else { | ||
cs.push(keyEscaped + ' = ?'); | ||
params.push(val); | ||
} else { | ||
lst = [val.nin]; | ||
params.push(val.nin); | ||
} | ||
cs.push(keyEscaped + ' NOT IN (' + lst.join(',') + ')'); | ||
break; | ||
case 'ne': | ||
case 'neq': | ||
cs.push(keyEscaped + ' != ?'); | ||
params.push(val.neq); | ||
break; | ||
case 'regexp': | ||
cs.push(keyEscaped + ' REGEXP ?'); | ||
params.push(val.lte); | ||
break; | ||
} | ||
} else { | ||
cs.push(keyEscaped + ' = ?'); | ||
params.push(val); | ||
} | ||
} | ||
); | ||
@@ -341,3 +453,3 @@ if (cs.length === 0) { | ||
FB.prototype.destroyAll = function(name, callback) { | ||
FB.prototype.destroyAll = function (name, callback) { | ||
var table = this.schema.tableName(name); | ||
@@ -354,5 +466,5 @@ var sql = 'DELETE FROM ' + quote(table); | ||
this.client.execute('SELECT count(*) FROM ' + quote(table) + buildWhere(where), params, | ||
function(err, result) { | ||
callback(err, (result) ? result[0][0] : undefined); | ||
} | ||
function (err, result) { | ||
callback(err, (result) ? result[0][0] : undefined); | ||
} | ||
); | ||
@@ -363,14 +475,14 @@ | ||
Object.keys(conds || {}).forEach( | ||
function(key) { | ||
if (conds[key] === null) { | ||
cs.push(quote(key) + ' IS NULL'); | ||
function (key) { | ||
if (conds[key] === null) { | ||
cs.push(quote(key) + ' IS NULL'); | ||
} else { | ||
cs.push(quote(key) + ' = ?'); | ||
if (model.properties[key].type.name === 'Date') { | ||
params.push(new Date(conds[key])); | ||
} else { | ||
cs.push(quote(key) + ' = ?'); | ||
if (model.properties[key].type.name === 'Date') { | ||
params.push(new Date(conds[key])); | ||
} else { | ||
params.push(conds[key]); | ||
} | ||
params.push(conds[key]); | ||
} | ||
} | ||
} | ||
); | ||
@@ -385,5 +497,5 @@ return cs.length ? ' WHERE ' + cs.join(' AND ') : ''; | ||
this.client.execute(sql, id, | ||
function(err, data) { | ||
callback(err, (data) ? data.length === 1 : undefined); | ||
} | ||
function (err, data) { | ||
callback(err, (data) ? data.length === 1 : undefined); | ||
} | ||
); | ||
@@ -397,3 +509,3 @@ }; | ||
FB.prototype.updateOrCreate = function(name, data, callback) { | ||
FB.prototype.updateOrCreate = function (name, data, callback) { | ||
var table = this.schema.tableName(name); | ||
@@ -407,7 +519,7 @@ var sql = 'UPDATE OR INSERT INTO ' + quote(table); | ||
Object.keys(data).forEach( | ||
function(key) { | ||
fields.push(quote(key)); | ||
values.push('?'); | ||
params.push(data[key]); | ||
} | ||
function (key) { | ||
fields.push(quote(key)); | ||
values.push('?'); | ||
params.push(data[key]); | ||
} | ||
); | ||
@@ -422,6 +534,6 @@ | ||
this.client.execute(sql, params, | ||
function(err) { | ||
callback(err, data); | ||
} | ||
function (err) { | ||
callback(err, data); | ||
} | ||
); | ||
}; |
@@ -190,4 +190,5 @@ /** | ||
this.collection(model).findOne({_id: id}, function (err, data) { | ||
if (data) | ||
if (data) { | ||
data.id = id; | ||
} | ||
callback(err, data); | ||
@@ -264,6 +265,4 @@ }); | ||
} | ||
if (filter.skip) { | ||
cursor.skip(filter.skip); | ||
} else if (filter.offset) { | ||
cursor.skip(filter.offset); | ||
if (filter.skip || filter.offset) { | ||
cursor.skip(filter.skip || filter.offset); | ||
} | ||
@@ -270,0 +269,0 @@ cursor.toArray(function (err, data) { |
@@ -886,3 +886,9 @@ /** | ||
} | ||
sqlCond += (condType === 'in' || condType === 'inq' || condType === 'nin') ? '(' + val + ')' : val; | ||
if(condType === 'between') { | ||
sqlCond += val[0] + ' AND ' + val[1]; | ||
} else if (condType === 'in' || condType === 'inq' || condType === 'nin') { | ||
sqlCond += '(' + val + ')'; | ||
} else { | ||
sqlCond += val; | ||
} | ||
cs.push(sqlCond); | ||
@@ -939,2 +945,2 @@ }); | ||
} | ||
} | ||
} |
@@ -6,3 +6,3 @@ /** | ||
var safeRequire = utils.safeRequire; | ||
var neo4j = safeRequire('neo4j'); | ||
var neo4j = safeRequire('node-neo4j'); | ||
@@ -26,12 +26,16 @@ exports.initialize = function initializeSchema(schema, callback) { | ||
} | ||
if (schema.settings.database) { | ||
url += '/' + schema.settings.database; | ||
} else { | ||
url += '/'; | ||
} | ||
/* | ||
if (schema.settings.database) { | ||
url += '/' + schema.settings.database; | ||
} else { | ||
url += '/'; | ||
} | ||
*/ | ||
url = 'http://' + url; | ||
schema.settings.url = url; | ||
} | ||
schema.client = new neo4j.GraphDatabase(schema.settings.url); | ||
schema.adapter = new Neo4j(schema.settings, schema.client); | ||
var client = new neo4j(schema.settings.url); | ||
schema.adapter = new Neo4j(schema.settings, client); | ||
schema.adapter.client = client; | ||
process.nextTick(callback); | ||
@@ -41,12 +45,12 @@ }; | ||
function Neo4j(s, client) { | ||
this.name = 'neo4j'; | ||
this.name = 'neo4j'; | ||
this._models = {}; | ||
this.client = client; | ||
this.cache = {}; | ||
this.s = s; | ||
this.settings = s; | ||
} | ||
Neo4j.prototype.define = function defineModel(descr) { | ||
this.mixClassMethods(descr.model, descr.properties); | ||
this.mixInstanceMethods(descr.model.prototype, descr.properties); | ||
// this.mixClassMethods(descr.model, descr.properties); | ||
// this.mixInstanceMethods(descr.model.prototype, descr.properties); | ||
this._models[descr.model.modelName] = descr; | ||
@@ -57,13 +61,13 @@ }; | ||
* Update existing database collections. | ||
* @param {Function} cb | ||
* @param {Function} callback | ||
*/ | ||
Neo4j.prototype.autoupdate = function (cb) { | ||
cb(); | ||
Neo4j.prototype.autoupdate = function (callback) { | ||
return callback && callback(); | ||
}; | ||
Neo4j.prototype.createIndexHelper = function(cls, indexName) { | ||
Neo4j.prototype.createIndexHelper = function (cls, indexName) { | ||
var db = this.client; | ||
var method = 'findBy' + indexName[0].toUpperCase() + indexName.substr(1); | ||
cls[method] = function(value, cb) { | ||
db.getIndexedNode(cls.modelName, indexName, value, function(err, node) { | ||
cls[method] = function (value, cb) { | ||
db.getIndexedNode(cls.modelName, indexName, value, function (err, node) { | ||
if (err) | ||
@@ -84,3 +88,3 @@ return cb(err); | ||
Object.keys(properties).forEach(function(name) { | ||
Object.keys(properties).forEach(function (name) { | ||
if (properties[name].index) { | ||
@@ -91,3 +95,3 @@ neo.createIndexHelper(cls, name); | ||
cls.setupCypherQuery = function(name, queryStr, rowHandler) { | ||
cls.setupCypherQuery = function (name, queryStr, rowHandler) { | ||
cls[name] = function cypherQuery(params, cb) { | ||
@@ -102,7 +106,7 @@ if (typeof params === 'function') { | ||
var i = 0; | ||
var q = queryStr.replace(/\?/g, function() { | ||
var q = queryStr.replace(/\?/g, function () { | ||
return params[i++]; | ||
}); | ||
neo.client.query(function(err, result) { | ||
neo.client.query(function (err, result) { | ||
if (err) | ||
@@ -123,13 +127,15 @@ return cb(err, []); | ||
cls.relationshipExists = function relationshipExists(from, to, type, direction, cb) { | ||
neo.node(from, function(err, node) { | ||
neo.node(from, function (err, node) { | ||
if (err) | ||
return cb(err); | ||
node._getRelationships(direction, type, function(err, rels) { | ||
if (err && cb) | ||
node._getRelationships(direction, type, function (err, rels) { | ||
if (err && cb) { | ||
return cb(err); | ||
if (err && !cb) | ||
} | ||
if (err && !cb) { | ||
throw err; | ||
} | ||
var found = false; | ||
if (rels && rels.forEach) { | ||
rels.forEach(function(r) { | ||
rels.forEach(function (r) { | ||
if (r.start.id === from && r.end.id === to) { | ||
@@ -147,3 +153,3 @@ found = true; | ||
var fromNode, toNode; | ||
neo.node(id1, function(err, node) { | ||
neo.node(id1, function (err, node) { | ||
if (err && cb) | ||
@@ -156,3 +162,3 @@ return cb(err); | ||
}); | ||
neo.node(id2, function(err, node) { | ||
neo.node(id2, function (err, node) { | ||
if (err && cb) | ||
@@ -177,4 +183,4 @@ return cb(err); | ||
// only create relationship if it is not exists | ||
cls.ensureRelationshipTo = function(id1, id2, type, data, cb) { | ||
cls.relationshipExists(id1, id2, type, 'outgoing', function(err, exists) { | ||
cls.ensureRelationshipTo = function (id1, id2, type, data, cb) { | ||
cls.relationshipExists(id1, id2, type, 'outgoing', function (err, exists) { | ||
if (err && cb) | ||
@@ -193,3 +199,2 @@ return cb(err); | ||
var neo = this; | ||
/** | ||
@@ -206,41 +211,35 @@ * @param obj - Object or id of object to check relation with | ||
Neo4j.prototype.node = function find(id, callback) { | ||
if (this.cache[id]) { | ||
callback(null, this.cache[id]); | ||
} else { | ||
this.client.getNodeById(id, function(err, node) { | ||
if (node) { | ||
this.cache[id] = node; | ||
} | ||
callback(err, node); | ||
}.bind(this)); | ||
} | ||
Neo4j.prototype.findById = function findById(model, id, callback) { | ||
var self = this; | ||
self.client.readNode(id, function (err, node) { | ||
if (!node) { | ||
return callback && callback(err, null); | ||
} | ||
var id = node._id; | ||
delete node._id; | ||
node = self.fromDatabase(model, node); | ||
node.id = id; | ||
return callback && callback(err, node); | ||
}.bind(self)); | ||
}; | ||
Neo4j.prototype.create = function create(model, data, callback) { | ||
data.nodeType = model; | ||
var node = this.client.createNode(); | ||
node.data = cleanup(data); | ||
node.data.nodeType = model; | ||
node.save(function(err) { | ||
var cdata = {}; | ||
cdata.nodeType = model; | ||
var self = this, props = self._models[model].properties; | ||
Object.keys(data).forEach(function (key) { | ||
cdata[key] = self.toDatabase(props[key], data[key]); | ||
}); | ||
self.client.insertNode(cdata, model, function (err, node) { | ||
if (err) { | ||
return callback(err); | ||
} | ||
this.cache[node.id] = node; | ||
node.index(model, 'id', node.id, function(err) { | ||
if (err) | ||
return callback(err); | ||
this.updateIndexes(model, node, function(err) { | ||
if (err) | ||
return callback(err); | ||
callback(null, node.id); | ||
}); | ||
}.bind(this)); | ||
}.bind(this)); | ||
callback(err, node._id); | ||
}); | ||
}; | ||
Neo4j.prototype.updateIndexes = function updateIndexes(model, node, cb) { | ||
Neo4j.prototype.updateIndexes = function updateIndexes(model, node, callback) { | ||
var props = this._models[model].properties; | ||
var wait = 1; | ||
Object.keys(props).forEach(function(key) { | ||
Object.keys(props).forEach(function (key) { | ||
if (props[key].index && node.data[key]) { | ||
@@ -255,6 +254,7 @@ wait += 1; | ||
var error = false; | ||
function done(err) { | ||
error = error || err; | ||
if (--wait === 0) { | ||
cb(error); | ||
callback(error); | ||
} | ||
@@ -265,64 +265,17 @@ } | ||
Neo4j.prototype.save = function save(model, data, callback) { | ||
var self = this; | ||
this.node(data.id, function(err, node) { | ||
//delete id property since that's redundant and we use the node.id | ||
delete data.id; | ||
if (err) | ||
return callback(err); | ||
node.data = cleanup(data); | ||
node.save(function(err) { | ||
if (err) | ||
return callback(err); | ||
self.updateIndexes(model, node, function(err) { | ||
if (err) | ||
return console.log(err); | ||
//map node id to the id property being sent back | ||
node.data.id = node.id; | ||
callback(null, node.data); | ||
}); | ||
}); | ||
}); | ||
var self = this, id = data.id; | ||
self.updateAttributes(model, id, data, function (err, updatedNode) { | ||
return callback && callback(err, updatedNode); | ||
}.bind(self)); | ||
}; | ||
Neo4j.prototype.exists = function exists(model, id, callback) { | ||
delete this.cache[id]; | ||
this.node(id, callback); | ||
}; | ||
Neo4j.prototype.findById = function findById(model, id, callback) { | ||
delete this.cache[id]; | ||
this.node(id, function(err, node) { | ||
if (node && node.data) { | ||
node.data.id = id; | ||
} | ||
callback(err, this.readFromDb(model, node && node.data)); | ||
this.findById(model, id, function (err, data) { | ||
return callback(err, !err && data) | ||
}.bind(this)); | ||
}; | ||
Neo4j.prototype.readFromDb = function readFromDb(model, data) { | ||
if (!data) | ||
return data; | ||
var res = {}; | ||
var props = this._models[model].properties; | ||
Object.keys(data).forEach(function(key) { | ||
if (props[key] && props[key].type.name === 'Date') { | ||
res[key] = new Date(data[key]); | ||
} else { | ||
res[key] = data[key]; | ||
} | ||
}); | ||
return res; | ||
}; | ||
Neo4j.prototype.destroy = function destroy(model, id, callback) { | ||
var force = true; | ||
this.node(id, function(err, node) { | ||
if (err) | ||
return callback(err); | ||
node.delete(function(err) { | ||
if (err) | ||
return callback(err); | ||
delete this.cache[id]; | ||
}.bind(this), force); | ||
this.client.deleteNode(id, function (err, node) { | ||
callback(err, node); | ||
}); | ||
@@ -339,96 +292,275 @@ }; | ||
} | ||
this.client.queryNodeIndex(model, 'id:*', function(err, nodes) { | ||
if (nodes) { | ||
nodes = nodes.map(function(obj) { | ||
obj.data.id = obj.id; | ||
return this.readFromDb(model, obj.data); | ||
}.bind(this)); | ||
var self = this, query = ['MATCH (data:' + model + ')']; | ||
query.push('WHERE data.nodeType = \'' + model + '\''); | ||
if (filter) { | ||
if (filter.where) { | ||
var sql = self.buildWhere(filter.where, self, model); | ||
query.push(sql); | ||
} | ||
if (filter) { | ||
nodes = nodes ? nodes.filter(applyFilter(filter)) : nodes; | ||
if (filter.order) { | ||
var key = filter.order.split(' ')[0]; | ||
var dir = filter.order.split(' ')[1]; | ||
nodes = nodes.sort(function(a, b) { | ||
return a[key] > b[key]; | ||
}); | ||
if (dir === 'DESC') | ||
nodes = nodes.reverse(); | ||
} | ||
} | ||
query.push('RETURN data'); | ||
if (filter.order) { | ||
var order = 'data.' + filter.order; | ||
if (typeof order === 'string') { | ||
order = [order]; | ||
} | ||
callback(err, nodes); | ||
query.push('ORDER BY ', order.join(', ')); | ||
} | ||
if (filter.limit) { | ||
if (filter.skip) { | ||
query.push('SKIP ' + (filter.skip || 0)); | ||
} | ||
query.push('LIMIT ' + filter.limit); | ||
} | ||
self.client.cypherQuery(query.join(' '), function (err, res) { | ||
var data = (res || {}).data || []; | ||
data = data.map(function (obj) { | ||
var cleared = self.fromDatabase(model, obj); | ||
cleared.id = obj._id; | ||
return cleared; | ||
}); | ||
return callback && callback(err, data); | ||
}.bind(self)); | ||
}; | ||
Neo4j.prototype.destroyAll = function destroyAll(model, callback) { | ||
var query = 'MATCH (data:' + model + ') ' + | ||
'WHERE data.nodeType = \'' + model + '\' ' + | ||
'DELETE data RETURN count(data)'; | ||
this.client.cypherQuery(query, function (err, res) { | ||
callback(err, res); | ||
}.bind(this)); | ||
}; | ||
Neo4j.prototype.allNodes = function all(model, callback) { | ||
this.client.queryNodeIndex(model, 'id:*', function(err, nodes) { | ||
callback(err, nodes); | ||
Neo4j.prototype.count = function count(model, callback, filter) { | ||
var self = this, query = ['MATCH (data:' + model + ')']; | ||
query.push('WHERE data.nodeType = \'' + model + '\''); | ||
if (filter) { | ||
if (filter.where) { | ||
var sql = self.buildWhere(filter.where, self, model); | ||
query.push(sql); | ||
} | ||
} | ||
query.push('RETURN count(data) AS count'); | ||
self.client.cypherQuery(query.join(' '), function (err, res) { | ||
var count = 0; | ||
if (res && res.data) { | ||
count = res.data[0] || 0; | ||
} | ||
return callback && callback(err, count); | ||
}.bind(self)); | ||
}; | ||
Neo4j.prototype.updateAttributes = function updateAttributes(model, id, data, callback) { | ||
var self = this, props = self._models[model].properties; | ||
self.findById(model, id, function (err, node) { | ||
Object.keys(data).forEach(function (key) { | ||
data[key] = self.toDatabase(props[key], data[key]); | ||
}); | ||
var merged = merge(node, data); | ||
merged.id = id; | ||
merged.nodeType = model; | ||
self.client.updateNode(id, merged, function (err, updated) { | ||
return callback && callback(err, updated); | ||
}); | ||
}.bind(self)); | ||
}; | ||
/** | ||
* Update rows | ||
* @param {String} model | ||
* @param {Object} filter | ||
* @param {Object} data | ||
* @param {Function} callback | ||
*/ | ||
Neo4j.prototype.update = function (model, filter, data, callback) { | ||
if ('function' === typeof filter) { | ||
return filter(new Error("Get parametrs undefined"), null); | ||
} | ||
if ('function' === typeof data) { | ||
return data(new Error("Set parametrs undefined"), null); | ||
} | ||
var self = this, cdata = {}, props = self._models[model].properties; | ||
filter = filter.where ? filter.where : filter; | ||
Object.keys(data).forEach(function (key) { | ||
cdata[key] = self.toDatabase(props[key], data[key]); | ||
}); | ||
self.client.updateNodesWithLabelsAndProperties(model, filter, cdata, [], false, function (err, updatedNodes) { | ||
return callback && callback(err, updatedNodes); | ||
}); | ||
}; | ||
function applyFilter(filter) { | ||
if (typeof filter.where === 'function') { | ||
return filter.where; | ||
Neo4j.prototype.toDatabase = function (prop, val, esc) { | ||
"use strict"; | ||
if (val === null) { | ||
return ''; | ||
} | ||
var keys = Object.keys(filter.where || {}); | ||
return function(obj) { | ||
var pass = true; | ||
keys.forEach(function(key) { | ||
if (!test(filter.where[key], obj[key])) { | ||
pass = false; | ||
} | ||
}); | ||
return pass; | ||
}; | ||
if (!prop) { | ||
return val; | ||
} | ||
function test(example, value) { | ||
if (typeof value === 'string' && example && example.constructor.name === 'RegExp') { | ||
return value.match(example); | ||
if (prop.type.name === 'Number') { | ||
return val; | ||
} | ||
if (prop.type.name === 'Date') { | ||
if (!val) { | ||
return 0; | ||
} | ||
if (typeof value === 'object' && value.constructor.name === 'Date' && typeof example === 'object' && example.constructor.name === 'Date') { | ||
return example.toString() === value.toString(); | ||
if (typeof val === 'string') { | ||
val = Date.parse(val); | ||
} | ||
// not strict equality | ||
return example === value; | ||
if (val instanceof Date) { | ||
val = val.getTime(); | ||
} | ||
return val; | ||
} | ||
} | ||
if (prop.type.name === "Boolean") { | ||
return val ? 1 : 0; | ||
} | ||
return esc ? '\'' + val.toString() + '\'' : val.toString(); | ||
}; | ||
Neo4j.prototype.destroyAll = function destroyAll(model, callback) { | ||
var wait, error = null; | ||
this.allNodes(model, function(err, collection) { | ||
if (err) | ||
return callback(err); | ||
wait = collection.length; | ||
collection && collection.forEach && collection.forEach(function(node) { | ||
node.delete(done, true); | ||
}); | ||
}); | ||
Neo4j.prototype.fromDatabase = function (model, data) { | ||
if (!data) { | ||
return null; | ||
} | ||
var clean = {}; | ||
var props = this._models[model].properties; | ||
Object.keys(data).forEach(function (key) { | ||
var val = data[key]; | ||
if (!props[key]) { | ||
return; | ||
} | ||
function done(err) { | ||
error = error || err; | ||
if (--wait === 0) { | ||
callback(error); | ||
if (props[key].type.name === 'Date' && val !== null) { | ||
if (val !== '') { | ||
clean[key] = new Date(val); | ||
} else { | ||
clean[key] = ''; | ||
} | ||
} else { | ||
clean[key] = val; | ||
} | ||
} | ||
}); | ||
return clean; | ||
}; | ||
Neo4j.prototype.count = function count(model, callback, conds) { | ||
this.all(model, {where: conds}, function(err, collection) { | ||
callback(err, collection ? collection.length : 0); | ||
Neo4j.prototype.buildWhere = function buildWhere(conds, adapter, model) { | ||
'use strict'; | ||
var cs = [], or = [], | ||
self = adapter, | ||
props = self._models[model].properties; | ||
Object.keys(conds).forEach(function (key) { | ||
if (key !== 'or') { | ||
cs = parseCond(cs, key, props, conds, self); | ||
} else { | ||
conds[key].forEach(function (oconds) { | ||
Object.keys(oconds).forEach(function (okey) { | ||
or = parseCond(or, okey, props, oconds, self); | ||
}); | ||
}); | ||
} | ||
}); | ||
if (cs.length === 0 && or.length === 0) { | ||
return ''; | ||
} | ||
var orop = ""; | ||
if (or.length) { | ||
orop = ' (' + or.join(' OR ') + ') '; | ||
} | ||
orop += (orop !== "" && cs.length > 0) ? ' AND ' : ''; | ||
return 'AND ' + orop + cs.join(' AND '); | ||
}; | ||
Neo4j.prototype.updateAttributes = function updateAttributes(model, id, data, cb) { | ||
data.id = id; | ||
this.node(id, function(err, node) { | ||
this.save(model, merge(node.data, data), cb); | ||
}.bind(this)); | ||
var parseCond = function (cs, key, props, conds, self) { | ||
'use strict'; | ||
var keyEscaped = 'data.' + key; | ||
var val = conds[key]; | ||
if (val === null) { | ||
cs.push(keyEscaped + '\'\''); | ||
} else if (val.constructor.name === 'Object') { | ||
Object.keys(val).forEach(function (condType) { | ||
val = self.toDatabase(props[key], val[condType], true); | ||
var sqlCond = keyEscaped; | ||
if ((condType === 'inq' || condType === 'nin') && val.length === 0) { | ||
cs.push(condType === 'inq' ? 0 : 1); | ||
return true; | ||
} | ||
switch (condType.toString().toLowerCase()) { | ||
case 'gt': | ||
sqlCond += ' > '; | ||
break; | ||
case 'gte': | ||
sqlCond += ' >= '; | ||
break; | ||
case 'lt': | ||
sqlCond += ' < '; | ||
break; | ||
case 'lte': | ||
sqlCond += ' <= '; | ||
break; | ||
case 'between': | ||
sqlCond += ''; | ||
break; | ||
case 'inq': | ||
case 'in': | ||
sqlCond += ' IN '; | ||
break; | ||
case 'nin': | ||
sqlCond = ' NOT ( '+keyEscaped+' IN ['+val+'])'; | ||
break; | ||
case 'neq': | ||
case 'ne': | ||
sqlCond = ' NOT ( '+keyEscaped+' = '+val+' )'; | ||
break; | ||
case 'regex': | ||
sqlCond += ' REGEXP '; | ||
break; | ||
case 'like': | ||
sqlCond += ' LIKE '; | ||
break; | ||
case 'nlike': | ||
sqlCond += ' NOT LIKE '; | ||
break; | ||
default: | ||
sqlCond += ' ' + condType + ' '; | ||
break; | ||
} | ||
if (condType === 'between') { | ||
sqlCond = val[0] + ' <= ' + keyEscaped + ' <= ' + val[1]; | ||
} else if (condType === 'in' || condType === 'inq') { | ||
sqlCond += '[' + val + ']'; | ||
} else if (condType === 'neq' || condType === 'ne' || condType === 'nin') { | ||
} else { | ||
sqlCond += val; | ||
} | ||
cs.push(sqlCond); | ||
}); | ||
} else if (/^\//gi.test(conds[key])) { | ||
var reg = val.toString().split('/'); | ||
cs.push(keyEscaped + ' REGEXP "' + reg[1] + '"'); | ||
} else { | ||
val = self.toDatabase(props[key], val, true); | ||
cs.push(keyEscaped + ' = ' + val); | ||
} | ||
return cs; | ||
}; | ||
function cleanup(data) { | ||
if (!data) | ||
var cleanup = function (data) { | ||
if (!data) { | ||
return null; | ||
} | ||
var res = {}; | ||
Object.keys(data).forEach(function(key) { | ||
Object.keys(data).forEach(function (key) { | ||
var v = data[key]; | ||
@@ -446,9 +578,9 @@ if (v === null) { | ||
return res; | ||
} | ||
}; | ||
function merge(base, update) { | ||
Object.keys(update).forEach(function(key) { | ||
var merge = function (base, update) { | ||
Object.keys(update).forEach(function (key) { | ||
base[key] = update[key]; | ||
}); | ||
return base; | ||
} | ||
}; |
@@ -92,5 +92,5 @@ /** | ||
PG.prototype.query = function (sql, callback) { | ||
var time = Date.now(); | ||
var log = this.log; | ||
this.client.query(sql, function (err, data) { | ||
var self = this,time = Date.now(); | ||
var log = self.log; | ||
self.client.query(sql, function (err, data) { | ||
if (log) { | ||
@@ -367,3 +367,3 @@ log(sql, time); | ||
if (filter.limit) { | ||
out += self.buildLimit(filter.limit, (filter.offset || '0')); | ||
out += self.buildLimit(filter.limit, (filter.offset || filter.skip || '0')); | ||
} | ||
@@ -374,3 +374,3 @@ | ||
function getTableStatus(model, cb) { | ||
function getTableStatus(cls, model, callback) { | ||
function decoratedCallback(err, data) { | ||
@@ -380,9 +380,8 @@ data.forEach(function (field) { | ||
}); | ||
cb(err, data); | ||
return callback && callback(err, data); | ||
} | ||
this.query('SELECT column_name as "Field", udt_name as "Type", is_nullable as "Null", column_default as "Default" FROM information_schema.COLUMNS WHERE table_name = \'' + this.table(model) + '\'', decoratedCallback); | ||
cls.query('SELECT column_name as "Field", udt_name as "Type", is_nullable as "Null", column_default as "Default" FROM information_schema.COLUMNS WHERE table_name = \'' + cls.table(model) + '\'', decoratedCallback); | ||
} | ||
PG.prototype.autoupdate = function (cb) { | ||
PG.prototype.autoupdate = function (callback) { | ||
var self = this; | ||
@@ -393,3 +392,3 @@ var wait = 0; | ||
var indexes = []; | ||
getTableStatus.call(self, model, function (err, fields) { | ||
getTableStatus(self, model, function (err, fields) { | ||
if (!err && fields.length) { | ||
@@ -407,4 +406,4 @@ self.alterTable(model, fields, indexes, done); | ||
} | ||
if (--wait === 0 && cb) { | ||
cb(); | ||
if (--wait === 0) { | ||
return callback && callback(); | ||
} | ||
@@ -773,3 +772,9 @@ } | ||
} | ||
sqlCond += (condType === 'in' || condType === 'inq' || condType === 'nin') ? '(' + val + ')' : val; | ||
if (condType === 'between') { | ||
sqlCond += val[0] + ' AND ' + val[1]; | ||
} else if (condType === 'in' || condType === 'inq' || condType === 'nin') { | ||
sqlCond += '(' + val + ')'; | ||
} else { | ||
sqlCond += val; | ||
} | ||
cs.push(sqlCond); | ||
@@ -807,2 +812,2 @@ }); | ||
return '"' + name.replace(/\./g, '"."') + '"'; | ||
} | ||
} |
@@ -94,3 +94,2 @@ /** | ||
function RethinkDB(s, schema) { | ||
var i, n; | ||
this.name = 'rethink'; | ||
@@ -101,3 +100,3 @@ this._models = {}; | ||
this.schema = schema; | ||
this.s = s; | ||
this.settings = s; | ||
this.database = s.database; | ||
@@ -120,3 +119,3 @@ } | ||
var self = this; | ||
r.connect({host: self.s.host, port: self.s.port}, function (err, client) { | ||
r.connect({host: self.settings.host, port: self.settings.port}, function (err, client) { | ||
if (err) { | ||
@@ -170,3 +169,3 @@ return callback && callback(err); | ||
if (Object.keys(properties).length > 0) { | ||
r.connect({host: self.s.host, port: self.s.port}, function (err, client) { | ||
r.connect({host: self.settings.host, port: self.settings.port}, function (err, client) { | ||
if (err) { | ||
@@ -647,9 +646,5 @@ return callback && callback(err); | ||
case 'between': | ||
if (!indexed && hasIndex) { | ||
promise = promise.between(cond[0], cond[1], {index: k}); | ||
indexed = true; | ||
} else { | ||
queryParts.push(r.row(k).ge(cond[0]).and(r.row(k).le(cond[1]))); | ||
} | ||
queryParts.push(r.row(k).ge(cond[0]).and(r.row(k).le(cond[1]))); | ||
break; | ||
case 'in': | ||
case 'inq': | ||
@@ -675,2 +670,3 @@ var expr1 = '(function(row) { return ' + JSON.stringify(cond) + '.indexOf(row.' + k + ') >= 0 })'; | ||
break; | ||
case 'ne': | ||
case 'neq': | ||
@@ -677,0 +673,0 @@ queryParts.push(r.row(k).ne(cond)); |
@@ -243,4 +243,7 @@ /** | ||
if (props[key]) { | ||
if ((props[key].type.name || '').toString().toLowerCase() === 'json' && typeof val == "string") { data[key] = JSON.parse(val); } | ||
else { data[key] = val; } | ||
if ((props[key].type.name || '').toString().toLowerCase() === 'json' && typeof val == "string") { | ||
data[key] = JSON.parse(val); | ||
} else { | ||
data[key] = val; | ||
} | ||
} | ||
@@ -262,4 +265,5 @@ }); | ||
this.queryOne(sql, function (err, data) { | ||
if (err) | ||
if (err) { | ||
return callback(err); | ||
} | ||
callback(null, data && data['1'] === 1); | ||
@@ -266,0 +270,0 @@ }); |
@@ -35,3 +35,3 @@ /** | ||
this.db = new Db(s.database, s); | ||
this.db.open(function(err, client) { | ||
this.db.open(function (err, client) { | ||
if (err) { | ||
@@ -50,3 +50,3 @@ throw err; | ||
TingoDB.prototype.define = function(descr) { | ||
TingoDB.prototype.define = function (descr) { | ||
if (!descr.settings) { | ||
@@ -58,4 +58,4 @@ descr.settings = {}; | ||
self.collections[descr.model.modelName] = self.db.collection(descr.model.modelName); | ||
setTimeout(function() { | ||
Object.keys(descr.properties).forEach(function(k) { | ||
setTimeout(function () { | ||
Object.keys(descr.properties).forEach(function (k) { | ||
if (typeof descr.properties[k].index !== 'undefined' || typeof descr.properties[k].unique !== 'undefined') { | ||
@@ -74,6 +74,5 @@ var fields = {}, params = {}; | ||
TingoDB.prototype.autoupdate = function(callback) { | ||
TingoDB.prototype.autoupdate = function (callback) { | ||
var self = this; | ||
var settings = self.settings; | ||
if (!fs.existsSync(settings.database)) { | ||
@@ -83,11 +82,13 @@ console.log('Database directory not exists ' + settings.database + ', please create!'); | ||
} else { | ||
return callback && callback(); | ||
setTimeout(function () { | ||
return callback && callback(); | ||
}, 1000); | ||
} | ||
}; | ||
TingoDB.prototype.defineProperty = function(model, prop, params) { | ||
TingoDB.prototype.defineProperty = function (model, prop, params) { | ||
this._models[model].properties[prop] = params; | ||
}; | ||
TingoDB.prototype.collection = function(name) { | ||
TingoDB.prototype.collection = function (name) { | ||
var self = this; | ||
@@ -100,3 +101,3 @@ if (!self.collections[name]) { | ||
TingoDB.prototype.ensureIndex = function(model, fields, params, callback) { | ||
TingoDB.prototype.ensureIndex = function (model, fields, params, callback) { | ||
this.collection(model).ensureIndex(fields, params); | ||
@@ -106,14 +107,14 @@ return callback(null); | ||
TingoDB.prototype.create = function(model, data, callback) { | ||
TingoDB.prototype.create = function (model, data, callback) { | ||
if (data.id === null) { | ||
delete data.id; | ||
} | ||
this.collection(model).insert(data, {}, function(err, m) { | ||
callback(err, err ? null : m[0]._id); | ||
this.collection(model).insert(data, {}, function (err, m) { | ||
return callback && callback(err, err ? null : m[0]._id); | ||
}); | ||
}; | ||
TingoDB.prototype.save = function(model, data, callback) { | ||
TingoDB.prototype.save = function (model, data, callback) { | ||
var id = data.id; | ||
this.collection(model).update({_id: id}, data, function(err) { | ||
this.collection(model).update({_id: id}, data, function (err) { | ||
callback(err); | ||
@@ -123,3 +124,3 @@ }); | ||
TingoDB.prototype.update = function(model, filter, data, callback) { | ||
TingoDB.prototype.update = function (model, filter, data, callback) { | ||
if ('function' === typeof filter) { | ||
@@ -132,3 +133,3 @@ return filter(new Error("Get parametrs undefined"), null); | ||
filter = filter.where ? filter.where : filter; | ||
this.collection(model).update(filter, data, function(err) { | ||
this.collection(model).update(filter, data, function (err) { | ||
callback(err); | ||
@@ -138,4 +139,4 @@ }); | ||
TingoDB.prototype.exists = function(model, id, callback) { | ||
this.collection(model).findOne({_id: id}, function(err, data) { | ||
TingoDB.prototype.exists = function (model, id, callback) { | ||
this.collection(model).findOne({_id: id}, function (err, data) { | ||
callback(err, !err && data); | ||
@@ -146,3 +147,3 @@ }); | ||
TingoDB.prototype.findById = function findById(model, id, callback) { | ||
this.collection(model).findOne({_id: id}, function(err, data) { | ||
this.collection(model).findOne({_id: id}, function (err, data) { | ||
if (data) { | ||
@@ -160,3 +161,3 @@ data.id = id; | ||
} | ||
this.findById(model, data.id, function(err, inst) { | ||
this.findById(model, data.id, function (err, inst) { | ||
if (err) | ||
@@ -168,3 +169,3 @@ return callback(err); | ||
delete data.id; | ||
adapter.create(model, data, function(err, id) { | ||
adapter.create(model, data, function (err, id) { | ||
if (err) | ||
@@ -229,6 +230,6 @@ return callback(err); | ||
} | ||
cursor.toArray(function(err, data) { | ||
cursor.toArray(function (err, data) { | ||
if (err) | ||
return callback(err); | ||
callback(null, data.map(function(o) { | ||
callback(null, data.map(function (o) { | ||
o.id = o._id; | ||
@@ -253,3 +254,3 @@ return o; | ||
TingoDB.prototype.disconnect = function() { | ||
TingoDB.prototype.disconnect = function () { | ||
this.client.close(); | ||
@@ -260,3 +261,3 @@ }; | ||
var query = {}; | ||
Object.keys(filter).forEach(function(k) { | ||
Object.keys(filter).forEach(function (k) { | ||
var cond = filter[k]; | ||
@@ -263,0 +264,0 @@ var spec = false; |
@@ -196,3 +196,3 @@ module.exports = BaseSQL; | ||
} | ||
try { | ||
@@ -199,0 +199,0 @@ self.command(sql, function () { |
@@ -15,3 +15,3 @@ exports.inherits = function(newClass, baseClass) { | ||
var str = module; | ||
if(module === 'rethinkdb') { str = module + ' generic-pool moment'; } | ||
if(module === 'rethinkdb') { str = module + ' generic-pool moment async'; } | ||
console.log('Run "npm install ' + str + '" command to using ' + module + ' database engine'); | ||
@@ -132,4 +132,4 @@ process.exit(1); | ||
case 'between': | ||
// need | ||
outs = val !== conds[condType] ? true : false; | ||
var bt = conds[condType]; | ||
outs = (val >= bt[0] && val <= bt[1]) ? true : false; | ||
break; | ||
@@ -145,2 +145,3 @@ case 'inq': | ||
case 'nin': | ||
outs = true; | ||
conds[condType].forEach(function(cval) { | ||
@@ -147,0 +148,0 @@ if (val === cval) { |
{ | ||
"name": "caminte", | ||
"description": "ORM for every database: redis, mysql, neo4j, mongodb, rethinkdb, postgres, sqlite, tingodb", | ||
"version": "0.1.5", | ||
"version": "0.1.6", | ||
"author": { | ||
@@ -119,3 +119,3 @@ "name": "Aleksej Gordejev", | ||
"riak-js": ">= 1.0.0", | ||
"neo4j": ">= 0.2.5", | ||
"node-neo4j": "^2.0.3", | ||
"mongodb": ">= 2.0.0", | ||
@@ -126,5 +126,5 @@ "felix-couchdb": ">= 1.0.0", | ||
"cassandra-driver": ">=2.1.0", | ||
"arangojs" : ">= 4.2.0" | ||
"arangojs": ">= 4.2.0" | ||
}, | ||
"optionalDependencies": {} | ||
} |
@@ -16,3 +16,3 @@ /** | ||
var Article = schema.define('article', { | ||
active: {type: schema.Number, limit: 1, index: true}, | ||
active: {type: schema.Number, limit: 1, default: 0, index: true}, | ||
mainpage: {type: schema.Number, limit: 1, index: true}, | ||
@@ -34,7 +34,6 @@ language: {type: schema.String, limit: 5, default: "en", index: true}, | ||
create_id: {type: schema.Number, limit: 21, index: true}, | ||
modify_id: {type: schema.Number, limit: 21}, | ||
modify_id: {type: schema.Number, limit: 21, index: true}, | ||
meta_keys: {type: schema.String, limit: 155}, | ||
meta_desc: {type: schema.String, limit: 155} | ||
}, {}); | ||
/* Validators */ | ||
@@ -41,0 +40,0 @@ Article.validatesPresenceOf('title', 'alias'); |
@@ -16,10 +16,10 @@ /** | ||
var Category = schema.define('category', { | ||
active: {type: schema.Number, default: 0, limit: 1, index: true}, | ||
section: {type: schema.String, limit: 20, default: "product", index: true}, | ||
language: {type: schema.String, limit: 5, default: "en", index: true}, | ||
active: {type: schema.Number, 'default': 0, limit: 1, index: true}, | ||
section: {type: schema.String, limit: 20, 'default': "product", index: true}, | ||
language: {type: schema.String, limit: 5, 'default': "en", index: true}, | ||
title: {type: schema.String, limit: 155}, | ||
description: {type: schema.String, limit: 255}, | ||
translation: {type: schema.Text}, | ||
category_id: {type: schema.Number, default: 0, limit: 11}, | ||
sort_order: {type: schema.Number, limit: 11, default: 1}, | ||
category_id: {type: schema.Number, 'default': 0, limit: 11, index: true}, | ||
sort_order: {type: schema.Number, limit: 11, 'default': 1}, | ||
image_source: {type: schema.String, limit: 255}, | ||
@@ -32,3 +32,3 @@ image_thumbs: {type: schema.Text}, | ||
modify_id: {type: schema.Number, limit: 21}, | ||
create_ts: {type: schema.Date}, | ||
create_ts: {type: schema.Date, 'default': Date.now}, | ||
modify_ts: {type: schema.Date} | ||
@@ -35,0 +35,0 @@ }, {}); |
@@ -92,5 +92,3 @@ /** | ||
port : '7474', | ||
database : 'test', | ||
username : 'neo4j', | ||
password : 'test' | ||
database : 'test' | ||
}; | ||
@@ -97,0 +95,0 @@ |
@@ -16,3 +16,3 @@ /** | ||
var User = schema.define('user', { | ||
active: {type: schema.Number, limit: 1, default: -1, index: true}, | ||
active: {type: schema.Number, limit: 1, default: 0, index: true}, | ||
language: {type: schema.String, limit: 5, default: "en"}, | ||
@@ -19,0 +19,0 @@ provider: {type: schema.String, limit: 50, default: "password"}, |
@@ -13,2 +13,3 @@ /** | ||
var config = require('./../lib/database'); | ||
var samples = require('./../lib/data'); | ||
var dbConf = config[driver]; | ||
@@ -23,13 +24,3 @@ var ArticleModel = require('./../lib/Article'); | ||
'use strict'; | ||
var id, newArticle = { | ||
language: 'en', | ||
category_id: 1, | ||
title: 'My Article', | ||
alias: 'my-article', | ||
mainpage: 0, | ||
params: { | ||
title: 1, | ||
categories: 1 | ||
} | ||
}; | ||
var id, newArticle = samples.articles[1]; | ||
@@ -50,5 +41,5 @@ before(function (done) { | ||
created.category_id.should.eql(1); | ||
created.alias.should.eql('my-article'); | ||
created.title.should.eql('My Article'); | ||
created.language.should.eql('en'); | ||
created.alias.should.eql(newArticle.alias); | ||
created.title.should.eql(newArticle.title); | ||
created.language.should.eql(newArticle.language); | ||
id = created.id; | ||
@@ -55,0 +46,0 @@ done(); |
@@ -13,2 +13,3 @@ /** | ||
var config = require('./../lib/database'); | ||
var samples = require('./../lib/data'); | ||
var dbConf = config[driver]; | ||
@@ -23,7 +24,3 @@ var CategoryModel = require('./../lib/Category'); | ||
'use strict'; | ||
var id, newCategory = { | ||
category_id: 2, | ||
title: 'My Category', | ||
section: 'my-category' | ||
}; | ||
var id, newCategory = samples.categories[0]; | ||
@@ -43,5 +40,5 @@ before(function (done) { | ||
created.id.should.not.eql(null); | ||
created.category_id.should.eql(2); | ||
created.section.should.eql('my-category'); | ||
created.title.should.eql('My Category'); | ||
created.category_id.should.eql(newCategory.category_id); | ||
created.section.should.eql(newCategory.section); | ||
created.title.should.eql(newCategory.title); | ||
id = created.id; | ||
@@ -76,4 +73,4 @@ done(); | ||
should.deepEqual(found.id, id); | ||
found.section.should.eql('my-category'); | ||
found.title.should.eql('My Category'); | ||
found.section.should.eql(newCategory.section); | ||
found.title.should.eql(newCategory.title); | ||
done(); | ||
@@ -80,0 +77,0 @@ }); |
@@ -13,2 +13,3 @@ /** | ||
var config = require('./../lib/database'); | ||
var samples = require('./../lib/data'); | ||
var dbConf = config[driver]; | ||
@@ -23,11 +24,3 @@ var UserModel = require('./../lib/User'); | ||
'use strict'; | ||
var id, newUser = { | ||
language: 'en', | ||
first_name: 'Alex', | ||
last_name: 'Gordan', | ||
screen_name: 'alex', | ||
email: 'bubles@example.com', | ||
password: 'AAAAAAAAA', | ||
age: 45 | ||
}; | ||
var id, newUser = samples.users[0]; | ||
@@ -34,0 +27,0 @@ before(function (done) { |
@@ -13,2 +13,3 @@ /** | ||
var config = require('./../lib/database'); | ||
var samples = require('./../lib/data'); | ||
var dbConf = config[driver]; | ||
@@ -28,21 +29,3 @@ var UserModel = require('./../lib/User'); | ||
'use strict'; | ||
var article, user, newUser = { | ||
language: 'en', | ||
first_name: 'Alex', | ||
last_name: 'Gordan', | ||
screen_name: 'alex', | ||
email: 'rubles@example.com', | ||
password: 'AAAAAAAAA', | ||
age: 45 | ||
}, newArticle = { | ||
language: 'en', | ||
category_id: 1, | ||
title: 'My Article', | ||
alias: 'my-article', | ||
mainpage: 0, | ||
params: { | ||
title: 1, | ||
categories: 1 | ||
} | ||
}; | ||
var article, user, newUser = samples.users[0], newArticle = samples.articles[0]; | ||
@@ -49,0 +32,0 @@ User.hasMany(Article, {as: 'articles', foreignKey: 'create_id'}); |
@@ -14,2 +14,3 @@ /** | ||
var config = require('./../lib/database'); | ||
var samples = require('./../lib/data'); | ||
var dbConf = config[driver]; | ||
@@ -27,8 +28,3 @@ var CategoryModel = require('./../lib/Category'); | ||
'use strict'; | ||
var category, newCategory = { | ||
active: 0, | ||
category_id: 2, | ||
title: 'My Category', | ||
section: 'my-category' | ||
}; | ||
var category, newCategory = samples.categories[0]; | ||
@@ -35,0 +31,0 @@ before(function (done) { |
@@ -14,2 +14,3 @@ /** | ||
var config = require('./../lib/database'); | ||
var samples = require('./../lib/data'); | ||
var dbConf = config[driver]; | ||
@@ -27,18 +28,11 @@ var UserModel = require('./../lib/User'); | ||
'use strict'; | ||
var suser, user, newUser = { | ||
language: 'en', | ||
first_name: 'Alex', | ||
last_name: 'Gordan', | ||
screen_name: 'alex', | ||
email: 'rubles@example.com', | ||
password: 'AAAAAAAAA', | ||
age: 45 | ||
}, email = 'bubles@example.com'; | ||
var user1, user2, | ||
newUser1 = samples.users[0], | ||
newUser2 = samples.users[0]; | ||
before(function (done) { | ||
user = new User(newUser); | ||
suser = new User(newUser); | ||
user1 = new User(newUser1); | ||
user2 = new User(newUser2); | ||
schema.autoupdate(function(){ | ||
suser.email = email; | ||
suser.save(done); | ||
user1.save(done); | ||
}); | ||
@@ -53,5 +47,5 @@ }); | ||
it('invalid', function (done) { | ||
user.first_name = null; | ||
user.isValid(function (valid) { | ||
it('must be invalid', function (done) { | ||
user1.first_name = null; | ||
user1.isValid(function (valid) { | ||
valid.should.be.false; | ||
@@ -62,5 +56,5 @@ done(); | ||
it('valid', function (done) { | ||
user.first_name = 'Alex'; | ||
user.isValid(function (valid) { | ||
it('must be valid', function (done) { | ||
user1.first_name = 'Alex'; | ||
user1.isValid(function (valid) { | ||
valid.should.be.true; | ||
@@ -75,5 +69,5 @@ done(); | ||
it('invalid', function (done) { | ||
user.language = 'by'; | ||
user.isValid(function (valid) { | ||
it('must be invalid', function (done) { | ||
user1.language = 'by'; | ||
user1.isValid(function (valid) { | ||
valid.should.be.false; | ||
@@ -84,5 +78,5 @@ done(); | ||
it('valid', function (done) { | ||
user.language = 'ru'; | ||
user.isValid(function (valid) { | ||
it('must be valid', function (done) { | ||
user1.language = 'ru'; | ||
user1.isValid(function (valid) { | ||
valid.should.be.true; | ||
@@ -96,5 +90,5 @@ done(); | ||
it('invalid', function (done) { | ||
user.password = 'xx'; | ||
user.isValid(function (valid) { | ||
it('must be invalid', function (done) { | ||
user1.password = 'xx'; | ||
user1.isValid(function (valid) { | ||
valid.should.be.false; | ||
@@ -105,5 +99,5 @@ done(); | ||
it('valid', function (done) { | ||
user.password = 'AAAAAAAAA'; | ||
user.isValid(function (valid) { | ||
it('must be valid', function (done) { | ||
user1.password = 'AAAAAAAAA'; | ||
user1.isValid(function (valid) { | ||
valid.should.be.true; | ||
@@ -118,5 +112,5 @@ done(); | ||
it('invalid', function (done) { | ||
user.age = 'xx'; | ||
user.isValid(function (valid) { | ||
it('must be invalid', function (done) { | ||
user1.age = 'xx'; | ||
user1.isValid(function (valid) { | ||
valid.should.be.false; | ||
@@ -127,5 +121,5 @@ done(); | ||
it('valid', function (done) { | ||
user.age = 45; | ||
user.isValid(function (valid) { | ||
it('must be valid', function (done) { | ||
user1.age = 45; | ||
user1.isValid(function (valid) { | ||
valid.should.be.true; | ||
@@ -140,5 +134,5 @@ done(); | ||
it('invalid', function (done) { | ||
user.screen_name = 'admin'; | ||
user.isValid(function (valid) { | ||
it('must be invalid', function (done) { | ||
user1.screen_name = 'admin'; | ||
user1.isValid(function (valid) { | ||
valid.should.be.false; | ||
@@ -149,5 +143,5 @@ done(); | ||
it('valid', function (done) { | ||
user.screen_name = 'boss'; | ||
user.isValid(function (valid) { | ||
it('must be valid', function (done) { | ||
user1.screen_name = 'boss'; | ||
user1.isValid(function (valid) { | ||
valid.should.be.true; | ||
@@ -162,5 +156,5 @@ done(); | ||
it('invalid', function (done) { | ||
user.screen_name = 'red in'; | ||
user.isValid(function (valid) { | ||
it('must be invalid', function (done) { | ||
user1.screen_name = 'red in'; | ||
user1.isValid(function (valid) { | ||
valid.should.be.false; | ||
@@ -171,5 +165,5 @@ done(); | ||
it('valid', function (done) { | ||
user.screen_name = 'hugoboss'; | ||
user.isValid(function (valid) { | ||
it('must be valid', function (done) { | ||
user1.screen_name = 'hugoboss'; | ||
user1.isValid(function (valid) { | ||
valid.should.be.true; | ||
@@ -184,5 +178,5 @@ done(); | ||
it('invalid', function (done) { | ||
user.email = email; | ||
user.isValid(function (valid) { | ||
it('must be invalid', function (done) { | ||
user1.email = newUser2.email; | ||
user1.isValid(function (valid) { | ||
valid.should.be.false; | ||
@@ -193,5 +187,5 @@ done(); | ||
it('valid', function (done) { | ||
user.email = newUser.email; | ||
user.isValid(function (valid) { | ||
it('must be valid', function (done) { | ||
user1.email = newUser1.email; | ||
user1.isValid(function (valid) { | ||
valid.should.be.true; | ||
@@ -204,8 +198,7 @@ done(); | ||
describe('#validate', function () { | ||
it('invalid', function (done) { | ||
user.email = 'hg hj h'; | ||
user.isValid(function (valid) { | ||
it('must be invalid', function (done) { | ||
user1.email = 'hg hj h'; | ||
user1.isValid(function (valid) { | ||
valid.should.be.false; | ||
@@ -216,5 +209,5 @@ done(); | ||
it('valid', function (done) { | ||
user.email = newUser.email; | ||
user.isValid(function (valid) { | ||
it('must be valid', function (done) { | ||
user1.email = newUser1.email; | ||
user1.isValid(function (valid) { | ||
valid.should.be.true; | ||
@@ -221,0 +214,0 @@ done(); |
@@ -13,2 +13,3 @@ /** | ||
var config = require('./../lib/database'); | ||
var samples = require('./../lib/data'); | ||
var dbConf = config[driver]; | ||
@@ -26,6 +27,3 @@ var ArticleModel = require('./../lib/Article'); | ||
'use strict'; | ||
var article, id, newArticle = { | ||
title: 'test 1', | ||
alias: 'test-1' | ||
}; | ||
var article, id, newArticle = samples.articles[0]; | ||
@@ -37,10 +35,16 @@ before(function (done) { | ||
after(function (done) { | ||
Article.destroyAll(done); | ||
done(); | ||
}); | ||
describe('create', function () { | ||
describe('create unit with initial data', function () { | ||
article = new Article(newArticle); | ||
it('article should be object', function () { | ||
it('unit should be created', function () { | ||
article = new Article(newArticle); | ||
article.should.be.type('object'); | ||
article.active.should.eql(newArticle.active); | ||
article.language.should.eql(newArticle.language); | ||
article.category_id.should.eql(newArticle.category_id); | ||
article.title.should.eql(newArticle.title); | ||
article.alias.should.eql(newArticle.alias); | ||
article.mainpage.should.eql(newArticle.mainpage); | ||
}); | ||
@@ -50,5 +54,5 @@ | ||
describe('isValid', function () { | ||
describe('validate created unit', function () { | ||
it('validated', function (done) { | ||
it('unit must be valid', function (done) { | ||
article.isValid(function (valid) { | ||
@@ -63,5 +67,5 @@ valid.should.be.true; | ||
describe('save', function () { | ||
describe('save unit', function () { | ||
it('should be have #save', function () { | ||
it('unit should be have #save method', function () { | ||
article.should.be.have.property('save'); | ||
@@ -71,3 +75,3 @@ article.save.should.be.type('function'); | ||
it('call', function (done) { | ||
it('unit must be saved', function (done) { | ||
article.save(function (err) { | ||
@@ -84,5 +88,5 @@ should.not.exist(err); | ||
describe('updateAttributes', function () { | ||
describe('update unit attributes', function () { | ||
it('should be have #updateAttributes', function () { | ||
it('unit should be have #updateAttributes method', function () { | ||
article.should.be.have.property('updateAttributes'); | ||
@@ -92,3 +96,3 @@ article.updateAttributes.should.be.type('function'); | ||
it('call', function (done) { | ||
it('unit must be updated', function (done) { | ||
article.updateAttributes({ | ||
@@ -105,5 +109,5 @@ title: 'test 2' | ||
describe('destroy', function () { | ||
describe('destroy unit', function () { | ||
it('should be have #destroy', function () { | ||
it('unit should be have #destroy method', function () { | ||
article.should.be.have.property('destroy'); | ||
@@ -113,3 +117,3 @@ article.destroy.should.be.type('function'); | ||
it('call', function (done) { | ||
it('unit must be destroyed', function (done) { | ||
article.destroy(function (err) { | ||
@@ -116,0 +120,0 @@ should.not.exist(err); |
@@ -13,2 +13,3 @@ /** | ||
var config = require('./../lib/database'); | ||
var samples = require('./../lib/data'); | ||
var dbConf = config[driver]; | ||
@@ -26,6 +27,3 @@ var CategoryModel = require('./../lib/Category'); | ||
'use strict'; | ||
var category, id, newCategory = { | ||
title: 'test 1', | ||
section: 'test-1' | ||
}; | ||
var category, id, newCategory = samples.categories[0]; | ||
@@ -37,3 +35,3 @@ before(function (done) { | ||
after(function (done) { | ||
Category.destroyAll(done); | ||
done(); | ||
}); | ||
@@ -48,3 +46,3 @@ | ||
it('validate', function (done) { | ||
it('must be valid', function (done) { | ||
category.isValid(function (valid) { | ||
@@ -66,3 +64,3 @@ valid.should.be.true; | ||
it('call', function (done) { | ||
it('must be saved', function (done) { | ||
category.save(function (err) { | ||
@@ -79,2 +77,20 @@ should.not.exist(err); | ||
describe('updateAttributes', function () { | ||
it('should be have #updateAttributes', function () { | ||
category.should.be.have.property('updateAttributes'); | ||
category.updateAttributes.should.be.type('function'); | ||
}); | ||
it('must be updated', function (done) { | ||
category.updateAttributes({ | ||
title: 'test 2' | ||
}, function (err) { | ||
should.not.exist(err); | ||
done(); | ||
}); | ||
}); | ||
}); | ||
describe('destroy', function () { | ||
@@ -87,3 +103,3 @@ | ||
it('call', function (done) { | ||
it('must be destroyed', function (done) { | ||
category.destroy(function (err) { | ||
@@ -90,0 +106,0 @@ should.not.exist(err); |
@@ -13,2 +13,3 @@ /** | ||
var config = require('./../lib/database'); | ||
var samples = require('./../lib/data'); | ||
var dbConf = config[driver]; | ||
@@ -26,11 +27,3 @@ var UserModel = require('./../lib/User'); | ||
'use strict'; | ||
var user, id, newUser = { | ||
language: 'en', | ||
first_name: 'Alex', | ||
last_name: 'Gordan', | ||
screen_name: 'alex', | ||
email: 'bubles@example.com', | ||
password: 'AAAAAAAAA', | ||
age: 45 | ||
}; | ||
var user, id, newUser = samples.users[0]; | ||
@@ -42,3 +35,3 @@ before(function (done) { | ||
after(function (done) { | ||
User.destroyAll(done); | ||
done(); | ||
}); | ||
@@ -53,3 +46,3 @@ | ||
it('validate', function (done) { | ||
it('must be valid', function (done) { | ||
user.isValid(function (valid) { | ||
@@ -71,3 +64,3 @@ valid.should.be.true; | ||
it('call', function (done) { | ||
it('must be saved', function (done) { | ||
user.save(function (err) { | ||
@@ -84,2 +77,21 @@ should.not.exist(err); | ||
describe('updateAttributes', function () { | ||
it('should be have #updateAttributes', function () { | ||
user.should.be.have.property('updateAttributes'); | ||
user.updateAttributes.should.be.type('function'); | ||
}); | ||
it('must be updated', function (done) { | ||
user.updateAttributes({ | ||
screen_name: 'bigboss' | ||
}, function (err) { | ||
should.not.exist(err); | ||
done(); | ||
}); | ||
}); | ||
}); | ||
describe('destroy', function () { | ||
@@ -92,3 +104,3 @@ | ||
it('call', function (done) { | ||
it('must be destroyed', function (done) { | ||
user.destroy(function (err) { | ||
@@ -95,0 +107,0 @@ should.not.exist(err); |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
692569
72
13667
61