Skip to content

Commit

Permalink
Refactor the sql common code so that postgres uses serial _id columns…
Browse files Browse the repository at this point in the history
…, but sqlite uses rowid as before.
  • Loading branch information
creationix committed Dec 16, 2009
1 parent b07a4b5 commit a853cd1
Show file tree
Hide file tree
Showing 3 changed files with 62 additions and 23 deletions.
55 changes: 34 additions & 21 deletions lib/persistence/common/sql.js
Expand Up @@ -73,13 +73,23 @@ function condition_to_sql(condition, value) {
throw "Invalid operator " + operator;
}

function Store(conn, name, columns) {
// overrides needs to contain at least the following
// index_col: the name of the special index column rowid in sqlite and oid in postgres
// do_insert: function (promise, data, keys, values)
// do_update: function (promise, data, pairs)

function Store(conn, name, columns, overrides) {
var key,
types = [];

this.name = name;
this.conn = conn;


if (overrides.types) {
types = overrides.types;
delete overrides.types;
}

if (columns) {
for (key in columns) {
if (columns.hasOwnProperty(key)) {
Expand All @@ -89,13 +99,19 @@ function Store(conn, name, columns) {

conn.execute("CREATE TABLE " + name + "(" + types.join(", ") +")").wait();
}

if (overrides) {
process.mixin(this, overrides);
}


}
Store.prototype = {

get: function (id) {
var promise = new process.Promise();
this.conn.query(
"SELECT rowid AS _id, * FROM " + this.name + " WHERE rowid = ?",
"SELECT " + this.index_col + " AS _id, * FROM " + this.name + " WHERE " + this.index_col + " = ?",
id
).addCallback(function (data) {
promise.emitSuccess(data[0]);
Expand All @@ -114,7 +130,7 @@ Store.prototype = {
conditions = [conditions];
}

sql = "SELECT rowid AS _id, * FROM " + this.name + " WHERE " +
sql = "SELECT " + this.index_col + " AS _id, * FROM " + this.name + " WHERE " +
conditions.map(function (group) {
var ands = [], key;
for (key in group) {
Expand All @@ -132,13 +148,22 @@ Store.prototype = {
},

each: function (row_callback) {
return this.conn.query("SELECT rowid AS _id, * FROM " + this.name, row_callback);
return this.conn.query("SELECT " + this.index_col + " AS _id, * FROM " + this.name, row_callback);
},

all: function () {
return this.conn.query("SELECT rowid AS _id, * FROM " + this.name);
return this.conn.query("SELECT " + this.index_col + " AS _id, * FROM " + this.name);
},

do_update: function (promise, data, pairs) {
this.conn.execute("UPDATE " + this.name +
" SET " + pairs.join(", ") +
" WHERE " + this.index_col + " = " + sql_escape(data._id)
).addCallback(function () {
promise.emitSuccess();
});
},

// Save a data object to the database. If it already has an _id do an update.
save: function (data) {
var keys = [],
Expand All @@ -153,27 +178,15 @@ Store.prototype = {
pairs.push(key + " = " + sql_escape(data[key]));
}
}
this.conn.execute("UPDATE " + this.name +
" SET " + pairs.join(", ") +
" WHERE rowid = " + sql_escape(data._id)
).addCallback(function () {
promise.emitSuccess();
});
this.do_update(promise, data, pairs);
} else {
for (key in data) {
if (data.hasOwnProperty(key)) {
keys.push(key);
values.push(sql_escape(data[key]));
}
}
this.conn.query("INSERT INTO " +
this.name + "(" + keys.join(", ") + ")" +
" VALUES (" + values.join(", ") + ");" +
"SELECT last_insert_rowid() AS rowid"
).addCallback(function (result) {
data._id = parseInt(result[0].rowid, 10);
promise.emitSuccess(data._id);
});
this.do_insert(promise, data, keys, values);
}
return promise;
},
Expand All @@ -185,7 +198,7 @@ Store.prototype = {
data = {_id: data};
}
this.conn.execute("DELETE FROM " + this.name +
" WHERE rowid = " + sql_escape(data._id)
" WHERE " + this.index_col + " = " + sql_escape(data._id)
).addCallback(function () {
delete data._id;
promise.emitSuccess();
Expand Down
15 changes: 14 additions & 1 deletion lib/persistence/postgres.js
Expand Up @@ -371,7 +371,20 @@ function Connection(args) {
}
Connection.prototype = new process.EventEmitter();
Connection.prototype.get_store = function (name, columns) {
return new sqllib.Store(this, name, columns);
return new sqllib.Store(this, name, columns, {
do_insert: function (promise, data, keys, values) {
this.conn.query("INSERT INTO " +
this.name + "(" + keys.join(", ") + ")" +
" VALUES (" + values.join(", ") + ")" +
" RETURNING _id"
).addCallback(function (result) {
data._id = parseInt(result[0]._id, 10);
promise.emitSuccess(data._id);
});
},
index_col: '_id',
types: ["_id SERIAL"]
});
};

exports.new_connection = function (connection_parameters) {
Expand Down
15 changes: 14 additions & 1 deletion lib/persistence/sqlite.js
Expand Up @@ -196,7 +196,20 @@ function Connection(path) {
}
Connection.prototype = new process.EventEmitter();
Connection.prototype.get_store = function (name, columns) {
return new sqllib.Store(this, name, columns);
return new sqllib.Store(this, name, columns, {
do_insert: function (promise, data, keys, values) {
this.conn.query("INSERT INTO " +
this.name + "(" + keys.join(", ") + ")" +
" VALUES (" + values.join(", ") + ");" +
"SELECT last_insert_rowid() AS _id"
).addCallback(function (result) {
data._id = parseInt(result[0]._id, 10);
promise.emitSuccess(data._id);
});
},

index_col: 'rowid'
});
};

exports.new_connection = function (connection_parameters) {
Expand Down

0 comments on commit a853cd1

Please sign in to comment.