From d5a48f1c25d3f7e354348a0ae940a0be276ab5ea Mon Sep 17 00:00:00 2001 From: artemave Date: Mon, 26 Mar 2018 15:35:49 +0100 Subject: [PATCH] Add better-sqlite3 as sqlite module --- sqliteDriver.js | 69 ++++++++++++++++++++++++++++-- test/describeDatabase.js | 91 +++++++++++++++++++++++++++------------- test/sqliteSpec.js | 2 +- 3 files changed, 129 insertions(+), 33 deletions(-) diff --git a/sqliteDriver.js b/sqliteDriver.js index 65f1309..e2ce270 100644 --- a/sqliteDriver.js +++ b/sqliteDriver.js @@ -4,8 +4,71 @@ var debug = require('debug')('sworm:sqlite'); var urlUtils = require('url') module.exports = function() { - var sqlite = optionalRequire('sqlite3'); + var Database; + try { + Database = require('better-sqlite3'); + return betterSqliteInit(Database); + } catch (e) { + if (e.code === 'MODULE_NOT_FOUND') { + try { + Database = require('sqlite3').Database; + return sqliteInit(Database); + } catch (e) { + if (e.code === 'MODULE_NOT_FOUND') { + throw new Error("Driver not found, please install either better-sqlite3 or sqlite3 modules"); + } + throw e; + } + } + throw e; + } +}; + +function betterSqliteInit(Database) { + return { + query: function(query, params, options) { + debug(query, params); + if (options.statement || options.insert) { + var statement = this.connection.prepare(query); + var res = statement.run(params); + return Promise.resolve({ + id: params.hasOwnProperty(options.id) ? params[options.id] : res.lastInsertROWID, + changes: res.changes + }); + } else if (options.exec || options.multiline) { + return Promise.resolve(this.connection.exec(query)); + } else { + var statement = this.connection.prepare(query); + try { + return Promise.resolve(statement.all(params)); + } catch (e) { + if (e.message === 'This statement does not return data. Use run() instead') { + return Promise.resolve(statement.run(params)); + } + return Promise.reject(e); + } + } + }, + + insert: function(query, params, options) { + return this.query(query, params, options) + }, + + connect: function(options) { + var config = parseConfig(options) + this.connection = new Database(config.filename, config); + return Promise.resolve() + }, + + close: function() { + this.connection.close(); + return Promise.resolve(); + } + }; +}; + +function sqliteInit(Database) { return { query: function(query, params, options) { var self = this; @@ -54,9 +117,9 @@ module.exports = function() { return promisify(function(cb) { if (options.mode) { - self.connection = new sqlite.Database(config.filename, config.mode, cb); + self.connection = new Database(config.filename, config.mode, cb); } else { - self.connection = new sqlite.Database(config.filename, cb); + self.connection = new Database(config.filename, cb); } }); }, diff --git a/test/describeDatabase.js b/test/describeDatabase.js index 6698738..875cf03 100644 --- a/test/describeDatabase.js +++ b/test/describeDatabase.js @@ -10,9 +10,42 @@ require('es6-promise').polyfill(); module.exports = function(name, config, database, otherTests) { describe(name, function() { + if (database.driverModuleName instanceof Array) { + database.driverModuleName.forEach(function(driverModuleName) { + describe(driverModuleName + ' module', function() { + var modulesToDisable = database.driverModuleName.filter(function(moduleName) { + return moduleName !== driverModuleName; + }); + + before(function() { + return Promise.all( + modulesToDisable.map(function(moduleName) { + var modulePath = process.cwd() + "/node_modules/" + moduleName; + delete require.cache[require.resolve(moduleName)] + return fs.rename(modulePath, modulePath + ".disabled"); + }) + ); + }); + after(function() { + return Promise.all( + modulesToDisable.map(function(moduleName) { + var modulePath = process.cwd() + "/node_modules/" + moduleName; + return fs.rename(modulePath + ".disabled", modulePath); + }) + ); + }); + describeDatabase(driverModuleName); + }); + }); + } else { + describeDatabase(database.driverModuleName); + } + }); + + function describeDatabase (driverModuleName) { if (!database.noModule) { - describe("missing modules", function() { - var moduleName = __dirname + "/../node_modules/" + database.driverModuleName; + describe("missing module", function() { + var moduleName = __dirname + "/../node_modules/" + driverModuleName; beforeEach(function() { return fs.rename(moduleName, moduleName + ".missing"); @@ -25,7 +58,7 @@ module.exports = function(name, config, database, otherTests) { it("throws an exception if the driver module is not present", function() { return expect(function() { sworm.db(config).connect(); - }).to.throw("npm install " + database.driverModuleName); + }).to.throw(driverModuleName); }); }); } @@ -119,7 +152,7 @@ module.exports = function(name, config, database, otherTests) { it("can insert", function() { var p = person({ - name: "bob" + name: "bob" }); return p.save().then(function() { expect(p.id).to.exist; @@ -158,7 +191,7 @@ module.exports = function(name, config, database, otherTests) { table: 'people' }); var p = person({ - name: "bob" + name: "bob" }); return p.save().then(function() { expect(p.id).to.exist; @@ -472,10 +505,10 @@ module.exports = function(name, config, database, otherTests) { return p.save().then(function() { return db.query("select * from people").then(function(people) { expect(database.clean(people)).to.eql([{ - id: p.id, - name: "jane", - address_id: null, - photo: null + id: p.id, + name: "jane", + address_id: null, + photo: null }]); }); }); @@ -664,9 +697,9 @@ module.exports = function(name, config, database, otherTests) { it("can update an entity with compound keys", function() { var pa = personAddress({ - person_id: 12, - address_id: 34, - rating: 1 + person_id: 12, + address_id: 34, + rating: 1 }); return pa.save().then(function() { @@ -752,10 +785,10 @@ module.exports = function(name, config, database, otherTests) { return describe("model queries", function() { it("can pass parameters to a query", function() { return person({ - name: "bob" + name: "bob" }).save().then(function() { return person({ - name: "jane" + name: "jane" }).save().then(function() { return person.query("select name from people where name = @name", { name: "jane" @@ -805,10 +838,10 @@ module.exports = function(name, config, database, otherTests) { describe("foreign keys", function() { it("can save a many to one relationship", function() { var bob = person({ - name: "bob", - address: address({ - address: "15, Rue d'Essert" - }) + name: "bob", + address: address({ + address: "15, Rue d'Essert" + }) }); return bob.save().then(function() { @@ -847,9 +880,9 @@ module.exports = function(name, config, database, otherTests) { it("can save a many to one relationship with function that returns undefined", function() { var bobsAddress; var bob = person({ - name: "bob", - address: function () { - } + name: "bob", + address: function () { + } }); return bob.save().then(function() { @@ -977,8 +1010,8 @@ module.exports = function(name, config, database, otherTests) { return db.query("select * from addresses").then(function(addresses) { expect(database.clean(addresses)).to.eql([ { - id: bob.address_id, - address: "15, Rue d'Essert" + id: bob.address_id, + address: "15, Rue d'Essert" } ]); return db.query("select * from people order by name").then(function(people) { @@ -1055,16 +1088,16 @@ module.exports = function(name, config, database, otherTests) { } var bob = person({ - name: "bob" + name: "bob" }); var jane = person({ - name: "jane" + name: "jane" }); var fremantle = address({ - address: "Fremantle" + address: "Fremantle" }); var essert = address({ - address: "15 Rue d'Essert" + address: "15 Rue d'Essert" }); livesIn(bob, fremantle); @@ -1573,7 +1606,7 @@ module.exports = function(name, config, database, otherTests) { name: 'name' }) }) - + return db.queryGraph(def, 'select ' + 'people.id as person_id, name, addresses.id as address_id, address ' + @@ -1757,5 +1790,5 @@ module.exports = function(name, config, database, otherTests) { }); }); }); - }); + } }; diff --git a/test/sqliteSpec.js b/test/sqliteSpec.js index 87cd163..ecc4a68 100644 --- a/test/sqliteSpec.js +++ b/test/sqliteSpec.js @@ -41,7 +41,7 @@ var database = { return records; }, - driverModuleName: "sqlite3" + driverModuleName: ["sqlite3", "better-sqlite3"] }; var config = {