Commit e90c5e22 by Konstantin Käfer

add caching mode to sqlite3

parent 9fcd390a
var sqlite3 = module.exports = exports = require('./sqlite3_bindings');
var path = require('path');
var EventEmitter = require('events').EventEmitter;
var Database = sqlite3.Database;
......@@ -11,6 +12,36 @@ function errorCallback(args) {
}
}
sqlite3.cached = {
Database: function(file, a, b) {
if (file === '' || file === ':memory:') {
// Don't cache special databases.
return new Database(file, a, b);
}
if (file[0] !== '/') {
file = path.join(process.cwd(), file);
}
if (!sqlite3.cached.objects[file]) {
var db =sqlite3.cached.objects[file] = new Database(file, a, b);
}
else {
// Make sure the callback is called.
var db = sqlite3.cached.objects[file];
var callback = (typeof a === 'number') ? b : a;
if (typeof callback === 'function') {
function cb() { callback.call(db, null); }
if (db.open) process.nextTick(cb);
else db.once('open', cb);
}
}
return db;
},
objects: {}
};
// Database#prepare(sql, [bind1, bind2, ...], [callback])
Database.prototype.prepare = function(sql) {
var params = Array.prototype.slice.call(arguments, 1);
......
......@@ -28,6 +28,8 @@ void Database::Init(Handle<Object> target) {
NODE_SET_PROTOTYPE_METHOD(constructor_template, "parallelize", Parallelize);
NODE_SET_PROTOTYPE_METHOD(constructor_template, "configure", Configure);
NODE_SET_GETTER(constructor_template, "open", OpenGetter);
target->Set(String::NewSymbol("Database"),
constructor_template->GetFunction());
}
......@@ -192,6 +194,12 @@ int Database::EIO_AfterOpen(eio_req *req) {
return 0;
}
Handle<Value> Database::OpenGetter(Local<String> str, const AccessorInfo& accessor) {
HandleScope scope;
Database* db = ObjectWrap::Unwrap<Database>(accessor.This());
return Boolean::New(db->open);
}
Handle<Value> Database::Close(const Arguments& args) {
HandleScope scope;
Database* db = ObjectWrap::Unwrap<Database>(args.This());
......
......@@ -121,6 +121,8 @@ protected:
static int EIO_Open(eio_req *req);
static int EIO_AfterOpen(eio_req *req);
static Handle<Value> OpenGetter(Local<String> str, const AccessorInfo& accessor);
void Schedule(EIO_Callback callback, Baton* baton, bool exclusive = false);
void Process();
......
var sqlite3 = require('sqlite3');
var assert = require('assert');
var helper = require('./support/helper');
if (process.setMaxListeners) process.setMaxListeners(0);
exports['test caching Database objects while opening'] = function(beforeExit) {
var filename = 'test/tmp/test_cache.db';
helper.deleteFile(filename);
var opened1 = false, opened2 = false
var db1 = new sqlite3.cached.Database(filename, function(err) {
if (err) throw err;
opened1 = true;
});
var db2 = new sqlite3.cached.Database(filename, function(err) {
if (err) throw err;
opened2 = true;
});
assert.equal(db1, db2);
beforeExit(function() {
assert.ok(opened1);
assert.ok(opened2);
});
};
exports['test caching Database objects after it is open'] = function(beforeExit) {
var filename = 'test/tmp/test_cache2.db';
helper.deleteFile(filename);
var opened1 = false, opened2 = false
var db1, db2;
db1 = new sqlite3.cached.Database(filename, function(err) {
if (err) throw err;
opened1 = true;
setTimeout(function() {
db2 = new sqlite3.cached.Database(filename, function(err) {
opened2 = true;
});
}, 100);
});
beforeExit(function() {
assert.equal(db1, db2);
assert.ok(opened1);
assert.ok(opened2);
});
};
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment