Commit b72f6bcd by Orlando Vazquez

get query working now. should even be able to handle multi statement queries!

parent 88a01961
/* /*
Copyright (c) 2009, Eric Fredricksen <e@fredricksen.net> Copyright (c) 2009, Eric Fredricksen <e@fredricksen.net>
Copyright (c) 2010, Orlando Vazquez <ovazquez@gmail.com>
Permission to use, copy, modify, and/or distribute this software for any Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above purpose with or without fee is hereby granted, provided that the above
...@@ -14,31 +15,15 @@ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF ...@@ -14,31 +15,15 @@ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/ */
// TODO: async var sys = require("sys");
var puts = sys.puts;
var sqlite = require("./sqlite3_bindings");
var bindings = require("./sqlite3_bindings"); var Database = exports.Database = sqlite.Database;
process.mixin(GLOBAL, bindings);
process.mixin(exports, bindings);
Database.prototype.query = function (sql, bindings, queryCallback) {
var self = this;
// Conform somewhat to http://dev.w3.org/html5/webdatabase/#sql
exports.SQLITE_DELETE = 9;
exports.SQLITE_INSERT = 18;
exports.SQLITE_UPDATE = 23;
exports.openDatabaseSync = function (name, version, displayName,
estimatedSize, creationCallback) {
// 2nd-4th parameters are ignored
var db = new DatabaseSync(name);
if (creationCallback) creationCallback(db);
return db;
}
DatabaseSync.prototype.query = function (sql, bindings, callback) {
// TODO: error callback
if (typeof(bindings) == "function") { if (typeof(bindings) == "function") {
var tmp = bindings; var tmp = bindings;
bindings = callback; bindings = callback;
...@@ -46,59 +31,74 @@ DatabaseSync.prototype.query = function (sql, bindings, callback) { ...@@ -46,59 +31,74 @@ DatabaseSync.prototype.query = function (sql, bindings, callback) {
} }
var all = []; var all = [];
var stmt = this.prepare(sql);
while(stmt) {
if (bindings) {
if (Object.prototype.toString.call(bindings) === "[object Array]") {
for (var i = 0; i < stmt.bindParameterCount(); ++i)
stmt.bind(i+1, bindings.shift());
} else {
for (var key in bindings)
if (bindings.hasOwnProperty(key))
stmt.bind(key, bindings[key]);
}
}
var rows = [];
while (true) { // Iterate over the list of bindings. Since we can't use something as
var row = stmt.step(); // simple as a for or while loop, we'll use the event loop
if (!row) break; function doBindingsByIndex(statement, bindings, queryCallback, startIndex) {
rows.push(row); (function (statement, bindings, startIndex) {
} var innerFunction = arguments.callee;
if (!bindings.length) {
rows.rowsAffected = this.changes(); process.nextTick(function () {
rows.insertId = this.lastInsertRowid(); queryCallback(statement);
});
return;
}
all.push(rows); startIndex = startIndex || 1;
var value = bindings.shift();
stmt.finalize(); puts("setting index " + startIndex + " to " + value);
stmt = this.prepare(stmt.tail); process.nextTick(function () {
statement.bind(startIndex, value, function () {
innerFunction(statement, bindings, startIndex+1);
});
});
})(statement, bindings, startIndex);
} }
if (all.length == 0) { function queryDone(statement, rows) {
var result = null; if (statement.tail) {
} else { puts("omg it has a tail");
for (var i = 0; i < all.length; ++i) { self.prepare(statement.tail, onPrepare);
var resultset = all[i];
resultset.all = all;
resultset.rows = {item: function (index) { return resultset[index]; },
length: resultset.length};
} }
var result = all[0]; queryCallback(undefined, rows);
} }
if (typeof(callback) == "function") {
callback.apply(result, all);
}
return result;
}
function doStep(statement) {
var rows = [];
(function () {
var innerFunction = arguments.callee;
statement.step(function (error, row) {
if (error) throw error;
if (!row) {
// rows.rowsAffected = this.changes();
// rows.insertId = this.lastInsertRowid();
process.nextTick(function () {
queryDone(statement, rows);
});
return;
}
rows.push(row);
puts("added " + inspect(row));
process.nextTick(innerFunction);
});
})();
}
// TODO: void *sqlite3_commit_hook(sqlite3*, int(*)(void*), void*); function onPrepare(error, statement) {
// TODO: void *sqlite3_rollback_hook(sqlite3*, void(*)(void *), void*); puts("prep args " + inspect(arguments));
if (bindings) {
if (Object.prototype.toString.call(bindings) === "[object Array]") {
doBindingsByIndex(statement, bindings, doStep);
}
else {
// TODO index by keys
}
}
}
this.prepare(sql, onPrepare);
}
function SQLTransactionSync(db, txCallback, errCallback, successCallback) { function SQLTransactionSync(db, txCallback, errCallback, successCallback) {
this.database = db; this.database = db;
...@@ -119,7 +119,7 @@ function SQLTransactionSync(db, txCallback, errCallback, successCallback) { ...@@ -119,7 +119,7 @@ function SQLTransactionSync(db, txCallback, errCallback, successCallback) {
function unroll() { function unroll() {
that.rolledBack = true; that.rolledBack = true;
} }
db.addListener("rollback", unroll); db.addListener("rollback", unroll);
this.executeSql("BEGIN TRANSACTION"); this.executeSql("BEGIN TRANSACTION");
...@@ -128,16 +128,15 @@ function SQLTransactionSync(db, txCallback, errCallback, successCallback) { ...@@ -128,16 +128,15 @@ function SQLTransactionSync(db, txCallback, errCallback, successCallback) {
db.removeListener("rollback", unroll); db.removeListener("rollback", unroll);
if (!this.rolledBack && successCallback) if (!this.rolledBack && successCallback)
successCallback(this); successCallback(this);
} }
DatabaseSync.prototype.transaction = function (txCallback, errCallback, Database.prototype.transaction = function (txCallback, errCallback,
successCallback) { successCallback) {
var tx = new SQLTransactionSync(this, txCallback, var tx = new SQLTransactionSync(this, txCallback,
errCallback, successCallback); errCallback, successCallback);
} }
// TODO: readTransaction() // TODO: readTransaction()
...@@ -878,6 +878,9 @@ protected: ...@@ -878,6 +878,9 @@ protected:
} }
} }
} }
else if (SQLITE_DONE) {
// no more results
}
else { else {
step_req->error_msg = (char *) step_req->error_msg = (char *)
sqlite3_errmsg(sqlite3_db_handle(*sto)); sqlite3_errmsg(sqlite3_db_handle(*sto));
......
var fs = require("fs");
process.mixin(GLOBAL, require("assert"));
process.mixin(GLOBAL, require("sys"));
var sqlite = require("./sqlite");
var db = new sqlite.Database();
db.open("mydatabase.db", function () {
puts("opened the db");
db.query("SELECT * FROM foo WHERE baz < ? OR baz > ?; SELECT 1;", [6, 3], function (error, result) {
puts(inspect(arguments));
puts("query callback " + inspect(result));
});
});
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