Skip to content

Instantly share code, notes, and snippets.

@creationix
Created December 9, 2009 21:30
Show Gist options
  • Save creationix/252838 to your computer and use it in GitHub Desktop.
Save creationix/252838 to your computer and use it in GitHub Desktop.
sqlite3 wrapper for node.js
var sys = require('sys');
function Sqlite(path) {
var conn = process.createChildProcess("sqlite3", ['-batch', '-header', '-nullvalue', "\r", '-separator', "\t", path]),
queue = [], dequeued = 0,
callback, want_close = false;
function parse(string) {
var raw, headers;
// Parse the output into cells. newline for row, tab for field, and
// carriage return for null values.
raw = string.split("\n").map(function (row) {
return row.split("\t").map(function (item) {
return item === "\r" ? null : item;
});
});
// pop off the always trailing empty row
raw.pop();
// Strip off the first row, it's the column names
headers = raw.shift();
// Merge the rest into an array of json objects
return raw.map(function (row) {
var data = {};
headers.map(function (name, index) {
data[name] = row[index];
});
return data;
});
}
function cycle(string) {
// debug(queue.length);
var next;
// When we get data, call the callback and clear everything.
if (string) {
callback(string);
callback = null;
}
// If the queue is empty, we're done
if (queue.length === 0) {
if (want_close) {
conn.close();
}
return;
}
// If no query is active, insert another
if (!callback) {
// Use a delayed shift queue instead of shifting every time.
next = queue[dequeued];
dequeued += 1;
if (dequeued * 2 > queue.length) {
queue = queue.slice(dequeued);
dequeued = 0;
}
callback = next[1];
conn.write(next[0]);
}
}
conn.addListener("output", cycle);
conn.addListener("error", function (data) {
if (data) {
sys.puts('<span style="color:red">');
sys.puts("ERROR: " + sys.inspect(data));
sys.puts('<span style="color:red">');
}
});
this.query = function (sql, cb) {
queue.push([sql + ";\n", function (string) {
cb(parse(string));
}]);
cycle();
};
this.command = function (command) {
queue.push(["." + command + "\n", sys.puts]);
cycle();
};
this.close = function () {
want_close = true;
cycle();
};
}
var db = new Sqlite('test.db');
// db.command('schema');
for (var i = 0; i < 100000; i += 1) {
db.query("SELECT * from reservations LIMIT 2", function () {});
}
db.close();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment