diff --git a/README.md b/README.md index c1dff6448..102f0102b 100644 --- a/README.md +++ b/README.md @@ -56,7 +56,7 @@ The low-level bindings directly interface with the SQLite C API. The API approximately matches the SQLite3 API when it makes sense. var sys = require('sys'), - sqlite = require('sqlite/sqlite3_bindings'); + sqlite = require('sqlite'); var db = new sqlite.Database(); @@ -99,7 +99,7 @@ approximately matches the SQLite3 API when it makes sense. To create a new database object: - var db = sqlite_bindings.Database(); + var db = sqlite.Database(); ### database.open(filename, function (error) {}) @@ -113,6 +113,23 @@ A filename of ":memory:" may be used to create an in-memory database. Close the database handle. +### database.executeScript(SQL, function (error) {}); + + db.executeScript + ( "CREATE TABLE table1 (id, name);" + + "CREATE TABLE table2 (id, age);" + + "INSERT INTO table1 (1, 'Mister Shake');" + + "INSER INTO table2 (1, 34);" + , function (error) { + if (error) throw error; + // ... + }); + +Execute multiple semi-colon separated SQL statements. Statements must take no +placeholders. Each statements will be executed with a single step() and then +reset. This is ideally suited to executing DDL statements that take no +arguments and return no results. + ### database.prepare(SQL, [options,] function (error, statement) {}) Create a prepared statement from an SQL string. Prepared statements can be diff --git a/sqlite.js b/sqlite.js index 0c7f98161..f4dc14d4c 100644 --- a/sqlite.js +++ b/sqlite.js @@ -18,14 +18,6 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. var sys = require("sys"); var sqlite = require("./sqlite3_bindings"); -// load numeric constants from sqlite3_bindings -for (prop in sqlite) { - var obj = sqlite[prop]; - if ((obj === +obj) || (toString.call(obj) === '[object Number]') ) { - exports[prop] = sqlite[prop]; - } -} - var Database = exports.Database = function () { var self = this; @@ -40,28 +32,48 @@ Database.prototype = { constructor: Database, }; -function _queryDone(db, statement) { - if (statement.tail) { - statement.finalize(function () { - db.prepareAndStep(statement.tail, onPrepare); - }); - return; +Database.prototype.query = function(sql, bindings, rowCallback) { + var self = this; + + if (typeof(bindings) == "function") { + rowCallback = bindings; + bindings = undefined; } - statement.finalize(function () { - // if there are any queries queued, let them know it's safe to go - db.emit("ready"); + this.prepare(sql, function(error, statement) { + function next() { + _doStep(self, statement, rowCallback); + } + + if (error) { + return rowCallback (error); + } + if (statement) { + if (Array.isArray(bindings)) { + statement.bindArray(bindings, next); + } + else if (typeof(bindings) === 'object') { + statement.bindObject(bindings, next); + } + else { + next(); + } + } + else { + rowCallback(); + } }); } function _doStep(db, statement, rowCallback) { statement.step(function (error, row) { - if (error) - return rowCallback (error); + if (error) { + return rowCallback(error); + } if (!row) { rowCallback(); - _queryDone(db, statement); + statement.finalize(function(){}); return; } rowCallback(undefined, row); @@ -70,48 +82,38 @@ function _doStep(db, statement, rowCallback) { }); } -function _onPrepare(db, statement, bindings, rowCallback) { - function next() { - _doStep(db, statement, rowCallback); - } - if (Array.isArray(bindings)) { - statement.bindArray(bindings, next); - } - else if (typeof(bindings) === 'object') { - statement.bindObject(bindings, next); - } -} - -Database.prototype.query = function(sql, bindings, rowCallback, prepareMode) { - var self = this; - - if (typeof(bindings) == "function") { - prepareMode = rowCallback || sqlite.EXEC_EMPTY; - rowCallback = bindings; - bindings = []; - } - if (typeof(prepareMode) == "undefined") - prepareMode = sqlite.EXEC_EMPTY; - - this.prepareAndStep(sql, function(error, statement) { - if (error) - return rowCallback (error); - if (statement) { - _onPrepare(self, statement, bindings, rowCallback); - } else { - rowCallback(); - } - }, prepareMode); -} - -Database.prototype.insert = function(sql, insertCallback) { +// Execute SQL statements separated by semi-colons. +// SQL must contain no placeholders. Results are discarded. +Database.prototype.executeScript = function (script, callback) { var self = this; - this.prepareAndStep(sql, function(error, info) { - if (error) - return insertCallback (error); - - insertCallback (undefined, (info ? info.last_inserted_id : 0)); - }, sqlite.EXEC_LAST_INSERT_ID); + (function stepOverSQL(sql) { + self.prepare(sql, function(error, statement) { + if (error) { + return callback(error); + } + + statement.step(function (error, row) { + var tail; + if (error) { + callback(error); + return; + } + if (!row) { + statement.finalize(function(){}); + + tail = statement.tail; + if (typeof tail == "string") { + tail = tail.trim(); + } + if (tail) { + stepOverSQL(tail); + } + else { + callback(); + } + } + }); + }); + })(script); } - diff --git a/tests/lib/common.js b/tests/lib/common.js index d9dd0db5b..80743c7b0 100644 --- a/tests/lib/common.js +++ b/tests/lib/common.js @@ -34,6 +34,7 @@ exports.insertMany = function (db, table, fields, rows, callback) { } db.prepare(sql, function (error, stmt) { + if (error) return callback(error); statement = stmt; doStep(--i); });