Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
154 changes: 77 additions & 77 deletions lib/sqlite3.js
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ SQLite3.prototype.save = function (model, data, callback) {
var sql = 'UPDATE ' + this.tableEscaped(model) + ' SET ' +
Object.keys(data).map(function (key) {
queryParams.push(data[key]);
return '`' + key + '` = ?';
return key + ' = ?';
}).join(', ') + ' WHERE id = ' + data.id;

this.command(sql, queryParams, function (err) {
Expand All @@ -81,7 +81,7 @@ SQLite3.prototype.create = function (model, data, callback) {
questions.push('?');
return data[key];
});
var sql = 'INSERT INTO ' + this.tableEscaped(model) + ' (`' + Object.keys(data).join('`, `') + '`) VALUES ('
var sql = 'INSERT INTO ' + this.tableEscaped(model) + ' (' + Object.keys(data).join(',') + ') VALUES ('
sql += questions.join(',');
sql += ')';
this.command(sql, values, function (err) {
Expand All @@ -96,7 +96,7 @@ SQLite3.prototype.updateOrCreate = function (model, data, callback) {
questions.push('?');
return data[key];
});
var sql = 'INSERT OR REPLACE INTO ' + this.tableEscaped(model) + ' (`' + Object.keys(data).join('`, `') + '`) VALUES ('
var sql = 'INSERT OR REPLACE INTO ' + this.tableEscaped(model) + ' (' + Object.keys(data).join(',') + ') VALUES ('
sql += questions.join(',');
sql += ')';
this.command(sql, values, function (err) {
Expand All @@ -112,7 +112,6 @@ SQLite3.prototype.toFields = function (model, data) {
var props = this._models[model].properties;
Object.keys(data).forEach(function (key) {
if (props[key]) {
if (typeof data[key] === 'undefined') return;
fields.push('`' + key.replace(/\./g, '`.`') + '` = ' + this.toDatabase(props[key], data[key]));
}
}.bind(this));
Expand Down Expand Up @@ -215,17 +214,9 @@ SQLite3.prototype.fromDatabase = function (model, data) {
var props = this._models[model].properties;
Object.keys(data).forEach(function (key) {
var val = data[key];
if (typeof val === 'undefined' || val === null) {
return;
}
if (props[key]) {
switch (props[key].type.name) {
case 'Date':
if (props[key].type.name === 'Date') {
val = new Date(parseInt(val));
break;
case 'Boolean':
val = new Boolean(val);
break;
}
}
data[key] = val;
Expand All @@ -241,7 +232,7 @@ SQLite3.prototype.exists = function (model, id, callback) {
var sql = 'SELECT 1 FROM ' + this.tableEscaped(model) + ' WHERE id = ' + id + ' LIMIT 1';
this.queryOne(sql, function (err, data) {
if (err) return callback(err);
callback(null, !!(data && data['1'] === 1));
callback(null, data && data['1'] === 1);
});
};

Expand Down Expand Up @@ -296,7 +287,7 @@ SQLite3.prototype.all = function all(model, filter, callback) {

return sql;

function buildWhere(conds) {
function buildWhere(conds) {
var cs = [];
Object.keys(conds).forEach(function (key) {
var keyEscaped = '`' + key.replace(/\./g, '`.`') + '`';
Expand Down Expand Up @@ -329,22 +320,14 @@ function buildWhere(conds) {
case 'nin':
sqlCond += ' NOT IN ';
break;
case 'like':
sqlCond += ' LIKE ';
break;
case 'between':
sqlCond += ' BETWEEN ? AND ?';
queryParams.push(conds[key][condType][0]);
queryParams.push(conds[key][condType][1]);
break;
}
if (condType == 'inq' || condType == 'nin')
sqlCond += '(' + val + ')';
else if (condType == 'like')
sqlCond += "'" + val + "'";
else
sqlCond += val;
if (condType !== 'between' && condType !== 'inq' && condType !== 'nin' && condType !== 'like') {
sqlCond += (condType == 'inq' || condType == 'nin') ? '(' + val + ')' : val;
if (condType !== 'between' && condType !== 'inq' && condType !== 'nin') {
sqlCond += '?';
queryParams.push(conds[key][condType]);
}
Expand All @@ -359,13 +342,7 @@ function buildWhere(conds) {

function buildOrderBy(order) {
if (typeof order === 'string') order = [order];
return 'ORDER BY ' + order.map(function(o) {
var t = o.split(/\s+/);
if (t.length === 1) {
return '`' + o + '`';
}
return '`' + t[0] + '` ' + t[1];
}).join(', ');
return 'ORDER BY ' + order.join(', ');
}

function buildLimit(limit, offset) {
Expand All @@ -392,7 +369,6 @@ SQLite3.prototype.count = function count(model, callback, where) {
if (conds[key] === null) {
cs.push(keyEscaped + ' IS NULL');
} else {
if (conds[key] === undefined) return
cs.push(keyEscaped + ' = ?');
queryParams.push(self.toDatabase(props[key], conds[key]));
}
Expand All @@ -411,11 +387,7 @@ SQLite3.prototype.autoupdate = function (cb) {
Object.keys(this._models).forEach(function (model) {
wait += 1;
self.queryAll('PRAGMA table_info(' + self.tableEscaped(model)+')', function (err, fields) {
if (err) {
self.createTable(model);
} else {
self.alterTable(model, fields, done);
}
self.alterTable(model, fields, done);
});
});

Expand Down Expand Up @@ -469,35 +441,29 @@ SQLite3.prototype.alterTable = function (model, actualFields, done) {
});

if (needs_rebuild) {
// first step, we need to run query in one transaction
self.command('BEGIN TRANSACTION',function(){
// second step, rename the current table
self.command('ALTER TABLE ' + self.tableEscaped(model) + 'RENAME TO ' + self.escapeName('temp__'+self.table(model)),function(){
// third step create the new table
self.createTable(model,function(){
// fourth step: move the data from the old table to the
// new one
var fields = '';
// if a column was removed take the columns from the
// model, else from the old table, but dont expect
// some miracle to some complex datamigration, this
// you have to do yourself.
if (column_droped) {
fields = propNames.join(',');
} else {
var fields = actualFields.map(function(field){
return field.name
}).join(',');
}
self.command('INSERT INTO '+ self.tableEscaped(model) + '(' + fields + ') SELECT ' + fields + ' FROM ' + self.escapeName('temp__'+self.table(model)),function(){
// fifth step: drop the renamed table
self.command('DROP TABLE ' + self.escapeName('temp__'+self.table(model)),function(){
//sixth and final step: commit transaction
self.command('COMMIT',done);
});
});
})
});
// first step, rename the current table
self.command('ALTER TABLE ' + this.tableEscaped(model) + 'RENAME TO ' + self.escapeName('temp__'+self.table(model)),function(){
// second step create the new table
self.createTable(model,function(){
// third step: move the data from the old table to the
// new one
var fields = '';
// if a column was removed take the columns from the
// model, else from the old table, but dont expect
// some miracle to some complex datamigration, this
// you have to do yourself.
if (column_droped) {
fields = propNames.join(',');
} else {
var fields = actualFields.map(function(field){
return field.name
}).join(',');
}
self.command('INSERT INTO '+ self.tableEscaped(model) + '(' + fields + ') SELECT ' + fields + ' FROM ' + self.escapeName('temp__'+self.table(model)),function(){
// fourth and final step: drop the renamed table
self.command('DROP TABLE ' + self.escapeName('temp__'+self.table(model)),done);
});
})
});
} else {
done();
Expand All @@ -524,27 +490,61 @@ SQLite3.prototype.propertiesSQL = function (model) {

SQLite3.prototype.propertySettingsSQL = function (model, prop) {
var p = this._models[model].properties[prop];
return datatype(p) +
//// In case in the future support user defined PK, un-comment the following:
// (p.primaryKey === true ? ' PRIMARY KEY' : '') +
// (p.primaryKey === true && p.autoIncrement === true ? ' AUTOINCREMENT' : '') +
(p.allowNull === false || p['null'] === false ? ' NOT NULL' : ' NULL') +
(p.unique === true ? ' UNIQUE' : '') +
(typeof p.default === "number" ? ' DEFAULT ' + p.default :'') +
(typeof p.default === "string" ? ' DEFAULT \'' + p.default + '\'' :'');
return datatype(p) + ' ' +
(p.allowNull === false || p['null'] === false ? 'NOT NULL' : 'NULL');
};

function dataTypeforNumber(p) {
var dataType = "INT(11)";

if (p.dataType !== undefined) {
switch (p.dataType) {
case 'real':
case 'decimal':
case 'float':
case 'double':
dataType = 'REAL';
break;
default:
dataType = 'INT(11)';
break;
}
}

return dataType;
}

function dataTypeForBoolean(p) {
var dataType = 'TINYINT(1)';

if (p.default !== undefined) {
switch (p.default) {
case false:
dataType = 'TINYINT(1) DEFAULT 0';
break;
case true:
dataType = 'TINYINT(1) DEFAULT 1';
break;
default:
// not valid
break;
}
}

return dataType;
}

function datatype(p) {
switch (p.type.name) {
case 'String':
return 'VARCHAR(' + (p.limit || 255) + ')';
case 'Text':
return 'TEXT';
case 'Number':
return 'INT(11)';
return dataTypeforNumber(p);
case 'Date':
return 'DATETIME';
case 'Boolean':
return 'TINYINT(1)';
return dataTypeForBoolean(p);
}
}