Skip to content

Commit

Permalink
Add support for sqlite3
Browse files Browse the repository at this point in the history
  • Loading branch information
Jeff Kunkle committed Dec 2, 2011
1 parent e885b46 commit 96d51b2
Show file tree
Hide file tree
Showing 4 changed files with 222 additions and 2 deletions.
3 changes: 3 additions & 0 deletions lib/persistence.store.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ exports.init = function(persistence, config) {
case 'mysql':
persistenceStore = require('./persistence.store.mysql');
break;
case 'sqlite3':
persistenceStore = require('./persistence.store.sqlite3');
break;
default:
persistenceStore = require('./persistence.store.mysql');
break;
Expand Down
122 changes: 122 additions & 0 deletions lib/persistence.store.sqlite3.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
/**
* This back-end depends on the node.js asynchronous SQLite3 driver as found on:
* https://github.com/developmentseed/node-sqlite3
* Easy install using npm:
* npm install sqlite3
* @author Eugene Ware
* @author Jeff Kunkle
* @author Joe Ferner
*/
var sys = require('sys');
var sql = require('./persistence.store.sql');
var sqlite = require('sqlite3');

var db, username, password;

function log(o) {
sys.print(sys.inspect(o) + "\n");
}


exports.config = function(persistence, dbPath) {
exports.getSession = function(cb) {
var that = {};
cb = cb || function() { };
var conn = new sqlite.Database(dbPath, cb);

var session = new persistence.Session(that);
session.transaction = function (explicitCommit, fn) {
if (typeof arguments[0] === "function") {
fn = arguments[0];
explicitCommit = false;
}
var tx = transaction(conn);
if (explicitCommit) {
tx.executeSql("START TRANSACTION", null, function(){
fn(tx)
});
}
else
fn(tx);
};

session.close = function(cb) {
cb = cb || function() {};
conn.close(cb);
};
return session;
};

function transaction(conn){
var that = {};
// TODO: add check for db opened or closed
that.executeSql = function(query, args, successFn, errorFn){
function cb(err, result){
if (err) {
log(err.message);
that.errorHandler && that.errorHandler(err);
errorFn && errorFn(null, err);
return;
}
if (successFn) {
successFn(result);
}
}
if (persistence.debug) {
sys.print(query + "\n");
args && args.length > 0 && sys.print(args.join(",") + "\n")
}
if (!args) {
conn.all(query, cb);
}
else {
conn.all(query, args, cb);
}
}

that.commit = function(session, callback){
session.flush(that, function(){
that.executeSql("COMMIT", null, callback);
})
}

that.rollback = function(session, callback){
that.executeSql("ROLLBACK", null, function() {
session.clean();
callback();
});
}
return that;
}

///////////////////////// SQLite dialect

persistence.sqliteDialect = {
// columns is an array of arrays, e.g.
// [["id", "VARCHAR(32)", "PRIMARY KEY"], ["name", "TEXT"]]
createTable: function(tableName, columns) {
var tm = persistence.typeMapper;
var sql = "CREATE TABLE IF NOT EXISTS `" + tableName + "` (";
var defs = [];
for(var i = 0; i < columns.length; i++) {
var column = columns[i];
defs.push("`" + column[0] + "` " + tm.columnType(column[1]) + (column[2] ? " " + column[2] : ""));
}
sql += defs.join(", ");
sql += ')';
return sql;
},

// columns is array of column names, e.g.
// ["id"]
createIndex: function(tableName, columns, options) {
options = options || {};
return "CREATE "+(options.unique?"UNIQUE ":"")+"INDEX IF NOT EXISTS `" + tableName + "__" + columns.join("_") +
"` ON `" + tableName + "` (" +
columns.map(function(col) { return "`" + col + "`"; }).join(", ") + ")";
}
};

sql.config(persistence, persistence.sqliteDialect);
};

3 changes: 1 addition & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,5 @@
"version": "0.2.5",
"engine": "node >=0.2.0",
"author": "Zef Hemel",
"directories": {"lib": "./lib"},
"dependencies": {"mysql": ">=0.7.0", "sqlite": ">=1.0.2"}
"directories": {"lib": "./lib"}
}
96 changes: 96 additions & 0 deletions test/node/test.sqlite3.store.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
// $ expresso -s test.sqlite3.store.js

var assert = require('assert');
var persistence = require('../../lib/persistence').persistence;
var persistenceStore = require('../../lib/persistence.store.sqlite3');

var dbPath = __dirname + '/test-sqlite3.db';
persistenceStore.config(persistence, dbPath);

var Task = persistence.define('Task', {
username: 'TEXT'
});

var data = {
username: 'test'
};

var data2 = {
username: 'test2'
};

var task, task2, session;

// remove test database
function removeDb() {
try {
require('fs').unlinkSync(dbPath);
} catch (err) {
}
}

module.exports = {
init: function(done) {
removeDb();
session = persistenceStore.getSession(function () {
session.schemaSync(done);
});
},
add: function(done) {
task = new Task(session, data);
session.add(task);
session.flush(function(result, err) {
assert.ifError(err);
done();
});
},
get: function(done) {
Task.findBy(session, 'id', task.id, function(task) {
assert.equal(task.username, data.username);
done();
});
},
update: function(done) {
task.username = 'test2';
Task.findBy(session, 'id', task.id, function(task) {
assert.equal(task.username, 'test2');
done();
});
},
remove: function(done) {
session.remove(task);
session.flush(function(result, err) {
assert.ifError(err);
Task.findBy(session, 'id', task.id, function(task) {
assert.equal(task, null);
done();
});
});
},
addMultiple: function(done) {
task = new Task(session, data);
session.add(task);
task2 = new Task(session, data2);
session.add(task2);
session.flush(function(result, err) {
assert.ifError(err);
var count = 0;
Task.all(session).order('username', true).each(function(row) {
count++;
if (count == 1) {
assert.equal(row.username, data.username);
}
if (count == 2) {
assert.equal(row.username, data2.username);
done();
}
});
});
},
afterAll: function(done) {
session.close(function() {
removeDb();
done();
});
}
};

0 comments on commit 96d51b2

Please sign in to comment.