From a14119d0b9779f5dee1df317fba1e0d518fa8524 Mon Sep 17 00:00:00 2001 From: "Timothy J. Warren" Date: Fri, 31 Oct 2014 11:57:44 -0400 Subject: [PATCH] Add sqlite driver, with dblite adapter --- lib/adapters/dblite.js | 29 ++++++++++ lib/drivers/sqlite.js | 16 +++++ lib/query-builder.js | 2 +- lib/query-parser.js | 5 +- package.json | 21 +++++-- tests/adapters/dblite_test.js | 50 ++++++++++++++++ tests/base_test.js | 6 +- tests/config-travis.json | 4 ++ tests/config.json | 4 ++ tests/sql/mysql.sql | 90 +---------------------------- tests/sql/pgsql.sql | 106 +--------------------------------- tests/sql/sqlite.sql | 81 +------------------------- 12 files changed, 130 insertions(+), 284 deletions(-) create mode 100644 lib/adapters/dblite.js create mode 100644 lib/drivers/sqlite.js create mode 100644 tests/adapters/dblite_test.js diff --git a/lib/adapters/dblite.js b/lib/adapters/dblite.js new file mode 100644 index 0000000..5a77f23 --- /dev/null +++ b/lib/adapters/dblite.js @@ -0,0 +1,29 @@ +'use strict'; + +var adapter = require('../adapter'), + getArgs = require('getargs'); + +/** @module adapters/dblite */ +var Dblite = function(instance) { + + // That 'new' keyword is annoying + if ( ! (this instanceof Dblite)) return new Dblite(instance); + + /** + * Run the sql query as a prepared statement + * + * @param {String} sql - The sql with placeholders + * @param {Array} params - The values to insert into the query + * @param {Function} callback - Callback to run when a response is recieved + * @return void + */ + adapter.execute = function(/*sql, params, callback*/) { + var args = getArgs('sql:string, [params]:array, callback:function', arguments); + + instance.query(args.sql, args.params, args.callback); + }; + + return adapter; +} + +module.exports = Dblite; \ No newline at end of file diff --git a/lib/drivers/sqlite.js b/lib/drivers/sqlite.js new file mode 100644 index 0000000..ffda240 --- /dev/null +++ b/lib/drivers/sqlite.js @@ -0,0 +1,16 @@ +"use strict"; + +/** + * Driver for PostgreSQL databases + * + * @module drivers/pg + */ +module.exports = (function() { + delete require.cache[require.resolve('../driver')]; + var driver = require('../driver'); + + // Sqlite doesn't have a truncate command + driver.hasTruncate = false; + + return driver; +}()); diff --git a/lib/query-builder.js b/lib/query-builder.js index be6acb4..822cd3f 100755 --- a/lib/query-builder.js +++ b/lib/query-builder.js @@ -159,7 +159,7 @@ var QueryBuilder = function(driver, adapter) { { obj[args.$key] = args.$val; } - else if ( ! helpers.isScalar(args.$key)) + else { obj = args.$key; } diff --git a/lib/query-parser.js b/lib/query-parser.js index 73544c3..72f984e 100644 --- a/lib/query-parser.js +++ b/lib/query-parser.js @@ -20,10 +20,7 @@ var filterMatches = function(array) { if (helpers.isScalar(array) || helpers.isNull(array) || helpers.isUndefined(array)) return output; array.forEach(function(item) { - if ( ! helpers.isUndefined(item)) - { - output.push(item); - } + output.push(item); }); return output; diff --git a/package.json b/package.json index b35dd94..b7cd5b0 100755 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "ci-node-query", - "version": "0.1.1", + "version": "0.2.0", "description": "A query builder for node based on the one in CodeIgniter", "author": "Timothy J Warren ", "engines": { @@ -10,27 +10,40 @@ "type": "git", "url": "https://github.com/timw4mail/node-query.git" }, + "keywords": [ + "codeigniter", + "mysql2", + "mysql", + "query builder", + "pg", + "postgres", + "sqlite", + "dblite" + ], "bugs": { "url": "https://github.com/timw4mail/node-query/issues" }, "main": "lib/node-query.js", "dependencies": { "getargs": "", - "es6-shim":"" + "es6-shim": "" }, "bundledDependencies": [ - "es6-shim","getargs" + "es6-shim", + "getargs" ], "devDependencies": { + "dblite": "^0.6.1", "grunt": "^0.4.5", + "grunt-cli": "", "grunt-contrib-clean": "^0.6.0", "grunt-contrib-nodeunit": "^0.4.1", "grunt-istanbul": "^0.3.0", "grunt-jsdoc": ">=0.6.1", - "grunt-cli":"", "jsdoc": "^3.3.0-alpha9", "mysql": "^2.5.2", "mysql2": "^0.12.5", + "node-firebird": "^0.2.3", "nodeunit": "^0.9.0", "pg": "^3.6.2" }, diff --git a/tests/adapters/dblite_test.js b/tests/adapters/dblite_test.js new file mode 100644 index 0000000..01593f8 --- /dev/null +++ b/tests/adapters/dblite_test.js @@ -0,0 +1,50 @@ +'use strict'; + +// Load the test base +delete require.cache[require.resolve('../query-builder-base')]; +var testBase = require('../query-builder-base'); +var tests = testBase.tests; + +// Load the test config file +var adapterName = 'dblite'; + +// Set up the connection +var sqlite = require(adapterName).withSQLite('3.8.6+'); +var connection = sqlite(':memory:'); + +// Set up the query builder object +var nodeQuery = require('../../lib/node-query'); +var qb = nodeQuery('sqlite', connection, adapterName); + +// Set up the sqlite database +var sql = 'CREATE TABLE IF NOT EXISTS "create_test" ("id" INTEGER PRIMARY KEY, "key" TEXT, "val" TEXT);' + +'CREATE TABLE IF NOT EXISTS "create_join" ("id" INTEGER PRIMARY KEY, "key" TEXT, "val" TEXT);'; +connection.query(sql); + +// Set up the test base +testBase._setUp(qb, function(test, err, rows) { + if (err != null) { + test.done(); + throw new Error(err); + } + + // Insert/Update/Delete queries return undefined + if (rows === undefined) { + rows = {}; + } + + test.ok(rows, 'dblite: Valid result for generated query'); + test.done(); +}); + +tests["dblite adapter with query builder"] = function(test) { + test.expect(1); + test.ok(testBase.qb); + + // Close the db connection + connection.close(); + test.done(); +}; + +// Export the final test object +module.exports = tests; \ No newline at end of file diff --git a/tests/base_test.js b/tests/base_test.js index c5dffc7..99acd66 100755 --- a/tests/base_test.js +++ b/tests/base_test.js @@ -7,7 +7,11 @@ var modules = { 'node-query': require('../lib/node-query'), 'drivers/pg': require('../lib/drivers/pg'), 'drivers/mysql': require('../lib/drivers/mysql'), - adapter: require('../lib/adapter') + 'drivers/sqlite': require('../lib/drivers/sqlite'), + 'adapters/mysql': require('../lib/adapters/mysql'), + 'adapters/mysql2': require('../lib/adapters/mysql2'), + 'adapters/pg': require('../lib/adapters/pg'), + 'adapters/dblite': require('../lib/adapters/dblite') }; module.exports = { diff --git a/tests/config-travis.json b/tests/config-travis.json index 11d9002..6a6bc62 100644 --- a/tests/config-travis.json +++ b/tests/config-travis.json @@ -20,5 +20,9 @@ "pg": { "driver": "pg", "conn": "postgres://postgres@localhost/test" + }, + "dblite": { + "driver": "sqlite", + "conn": ":memory:" } } \ No newline at end of file diff --git a/tests/config.json b/tests/config.json index 83aecb5..8988c22 100644 --- a/tests/config.json +++ b/tests/config.json @@ -20,5 +20,9 @@ "pg": { "driver": "pg", "conn": "postgres://test:test@localhost/test" + }, + "dblite": { + "driver": "sqlite", + "conn": ":memory:" } } \ No newline at end of file diff --git a/tests/sql/mysql.sql b/tests/sql/mysql.sql index db3834a..d856f1b 100644 --- a/tests/sql/mysql.sql +++ b/tests/sql/mysql.sql @@ -25,92 +25,4 @@ CREATE TABLE `create_test` ( `val` text ); ALTER TABLE `create_test` - ADD PRIMARY KEY (`id`); - --- TABLE TEST -DROP TABLE IF EXISTS TEST1; -CREATE TABLE TEST1 ( - TEST_NAME CHAR(30) NOT NULL, - TEST_ID INTEGER DEFAULT '0' NOT NULL, - TEST_DATE TIMESTAMP NOT NULL -); -ALTER TABLE TEST1 ADD CONSTRAINT PK_TEST PRIMARY KEY (TEST_ID); - --- TABLE TEST2 with some CONSTRAINTs and an INDEX -DROP TABLE IF EXISTS TEST2; -CREATE TABLE TEST2 ( - ID INTEGER NOT NULL, - FIELD1 INTEGER, - FIELD2 CHAR(15), - FIELD3 VARCHAR(50), - FIELD4 INTEGER, - FIELD5 INTEGER, - ID2 INTEGER NOT NULL -); - -ALTER TABLE TEST2 ADD CONSTRAINT PK_TEST2 PRIMARY KEY (ID2); -ALTER TABLE TEST2 ADD CONSTRAINT TEST2_FIELD1ID_IDX UNIQUE (ID, FIELD1); -ALTER TABLE TEST2 ADD CONSTRAINT TEST2_FIELD4_IDX UNIQUE (FIELD4); -CREATE INDEX TEST2_FIELD5_IDX ON TEST2(FIELD5); - --- TABLE NUMBERS -DROP TABLE IF EXISTS NUMBERS; -CREATE TABLE NUMBERS ( - NUMBER INTEGER DEFAULT '0' NOT NULL, - EN CHAR(100) NOT NULL, - FR CHAR(100) NOT NULL -); - --- TABLE NEWTABLE -DROP TABLE IF EXISTS NEWTABLE; -CREATE TABLE NEWTABLE ( - ID INT DEFAULT 0 NOT NULL, - SOMENAME VARCHAR (12), - SOMEDATE TIMESTAMP NOT NULL -); -ALTER TABLE NEWTABLE ADD CONSTRAINT PKINDEX_IDX PRIMARY KEY (ID); - --- DROP SEQUENCE IF EXISTS NEWTABLE_SEQ CASCADE; --- CREATE SEQUENCE NEWTABLE_SEQ INCREMENT 1 START 1; - --- VIEW on TEST -CREATE OR REPLACE VIEW `testview`( - TEST_NAME, - TEST_ID, - TEST_DATE -) AS -SELECT * -FROM TEST1 -WHERE TEST_NAME LIKE 't%'; - --- VIEW on NUMBERS -CREATE OR REPLACE VIEW `numbersview`( - NUMBER, - TRANS_EN, - TRANS_FR -) AS -SELECT * -FROM NUMBERS -WHERE NUMBER > 100; - --- TABLEs for testing CONSTRAINTs -DROP TABLE IF EXISTS testconstraints; -CREATE TABLE testconstraints ( - someid integer NOT NULL, - somename varchar(10) NOT NULL, - CONSTRAINT testconstraints_id_pk PRIMARY KEY (someid) -); -DROP TABLE IF EXISTS testconstraints2; -CREATE TABLE testconstraints2 ( - ext_id integer NOT NULL, - modified date, - uniquefield varchar(10) NOT NULL, - usraction integer NOT NULL, - CONSTRAINT testconstraints_id_fk FOREIGN KEY (ext_id) - REFERENCES testconstraints (someid) - ON UPDATE CASCADE - ON DELETE CASCADE, - CONSTRAINT unique_2_fields_idx UNIQUE (modified, usraction), - CONSTRAINT uniquefld_idx UNIQUE (uniquefield) -); - + ADD PRIMARY KEY (`id`); \ No newline at end of file diff --git a/tests/sql/pgsql.sql b/tests/sql/pgsql.sql index 1516ea8..ab30e87 100644 --- a/tests/sql/pgsql.sql +++ b/tests/sql/pgsql.sql @@ -11,108 +11,4 @@ CREATE TABLE create_test ( id integer NOT NULL, key text, val text -); - --- TABLE TEST -CREATE TABLE IF NOT EXISTS TEST1 ( - TEST_NAME CHAR(30) NOT NULL, - TEST_ID INTEGER DEFAULT '0' NOT NULL, - TEST_DATE TIMESTAMP NOT NULL -); -ALTER TABLE TEST1 DROP CONSTRAINT IF EXISTS PK_TEST CASCADE; -ALTER TABLE TEST1 ADD CONSTRAINT PK_TEST PRIMARY KEY (TEST_ID); - --- TABLE TEST2 with some CONSTRAINTs and an INDEX -CREATE TABLE IF NOT EXISTS TEST2 ( - ID INTEGER NOT NULL, - FIELD1 INTEGER, - FIELD2 CHAR(15), - FIELD3 VARCHAR(50), - FIELD4 INTEGER, - FIELD5 INTEGER, - ID2 INTEGER NOT NULL -); -ALTER TABLE TEST2 DROP CONSTRAINT IF EXISTS PK_TEST2 CASCADE; -ALTER TABLE TEST2 DROP CONSTRAINT IF EXISTS TEST2_FIELD1ID_IDX CASCADE; -ALTER TABLE TEST2 DROP CONSTRAINT IF EXISTS TEST2_FIELD4_IDX CASCADE; -DROP INDEX IF EXISTS TEST2_FIELD5_IDX; - -ALTER TABLE TEST2 ADD CONSTRAINT PK_TEST2 PRIMARY KEY (ID2); -ALTER TABLE TEST2 ADD CONSTRAINT TEST2_FIELD1ID_IDX UNIQUE (ID, FIELD1); -ALTER TABLE TEST2 ADD CONSTRAINT TEST2_FIELD4_IDX UNIQUE (FIELD4); -CREATE INDEX TEST2_FIELD5_IDX ON TEST2(FIELD5); - --- TABLE NUMBERS -CREATE TABLE IF NOT EXISTS NUMBERS ( - NUMBER INTEGER DEFAULT '0' NOT NULL, - EN CHAR(100) NOT NULL, - FR CHAR(100) NOT NULL -); - --- TABLE NEWTABLE -CREATE TABLE IF NOT EXISTS NEWTABLE ( - ID INT DEFAULT 0 NOT NULL, - SOMENAME VARCHAR (12), - SOMEDATE TIMESTAMP NOT NULL -); -ALTER TABLE NEWTABLE DROP CONSTRAINT IF EXISTS PKINDEX_IDX CASCADE; -ALTER TABLE NEWTABLE ADD CONSTRAINT PKINDEX_IDX PRIMARY KEY (ID); - -DROP SEQUENCE IF EXISTS NEWTABLE_SEQ CASCADE; -CREATE SEQUENCE NEWTABLE_SEQ INCREMENT 1 START 1; - --- VIEW on TEST -CREATE OR REPLACE VIEW "testview"( - TEST_NAME, - TEST_ID, - TEST_DATE -) AS -SELECT * -FROM TEST1 -WHERE TEST_NAME LIKE 't%'; - --- VIEW on NUMBERS -CREATE OR REPLACE VIEW "numbersview"( - NUMBER, - TRANS_EN, - TRANS_FR -) AS -SELECT * -FROM NUMBERS -WHERE NUMBER > 100; - --- TRIGGER on NEWTABLE -DROP FUNCTION IF EXISTS add_stamp() CASCADE; -CREATE OR REPLACE FUNCTION add_stamp() RETURNS OPAQUE AS ' - BEGIN - IF (NEW.somedate IS NULL OR NEW.somedate = 0) THEN - NEW.somedate := CURRENT_TIMESTAMP; - RETURN NEW; - END IF; - END; -' LANGUAGE 'plpgsql'; - -DROP TRIGGER IF EXISTS ADDCURRENTDATE ON newtable; - -CREATE TRIGGER ADDCURRENTDATE -BEFORE INSERT OR UPDATE -ON newtable FOR EACH ROW - EXECUTE PROCEDURE add_stamp(); - --- TABLEs for testing CONSTRAINTs -CREATE TABLE IF NOT EXISTS testconstraints ( - someid integer NOT NULL, - somename character varying(10) NOT NULL, - CONSTRAINT testconstraints_id_pk PRIMARY KEY (someid) -); -CREATE TABLE IF NOT EXISTS testconstraints2 ( - ext_id integer NOT NULL, - modified date, - uniquefield character varying(10) NOT NULL, - usraction integer NOT NULL, - CONSTRAINT testconstraints_id_fk FOREIGN KEY (ext_id) - REFERENCES testconstraints (someid) MATCH SIMPLE - ON UPDATE CASCADE ON DELETE CASCADE, - CONSTRAINT unique_2_fields_idx UNIQUE (modified, usraction), - CONSTRAINT uniquefld_idx UNIQUE (uniquefield) -); +); \ No newline at end of file diff --git a/tests/sql/sqlite.sql b/tests/sql/sqlite.sql index babf32c..b600651 100644 --- a/tests/sql/sqlite.sql +++ b/tests/sql/sqlite.sql @@ -1,82 +1,3 @@ -- sample data to test SQLite CREATE TABLE IF NOT EXISTS "create_test" ("id" INTEGER PRIMARY KEY, "key" TEXT, "val" TEXT); -CREATE TABLE IF NOT EXISTS "create_join" ("id" INTEGER PRIMARY KEY, "key" TEXT, "val" TEXT); -CREATE TABLE IF NOT EXISTS "create_delete" ("id" INTEGER PRIMARY KEY, "key" TEXT, "val" TEXT); - --- TABLE TEST -DROP TABLE IF EXISTS TEST1; -CREATE TABLE TEST1 ( - TEST_NAME TEXT NOT NULL, - TEST_ID INTEGER DEFAULT '0' NOT NULL, - TEST_DATE TEXT NOT NULL, - CONSTRAINT PK_TEST PRIMARY KEY (TEST_ID) -); - --- TABLE TEST2 with some CONSTRAINTs and an INDEX -DROP TABLE IF EXISTS TEST2; -CREATE TABLE TEST2 ( - ID INTEGER NOT NULL, - FIELD1 INTEGER, - FIELD2 TEXT, - FIELD3 TEXT, - FIELD4 INTEGER, - FIELD5 INTEGER, - ID2 INTEGER NOT NULL, - CONSTRAINT PK_TEST2 PRIMARY KEY (ID2), - CONSTRAINT TEST2_FIELD1ID_IDX UNIQUE (ID, FIELD1), - CONSTRAINT TEST2_FIELD4_IDX UNIQUE (FIELD4) -); -CREATE INDEX TEST2_FIELD5_IDX ON TEST2 (FIELD5); - --- TABLE NUMBERS -DROP TABLE IF EXISTS NUMBERS; -CREATE TABLE NUMBERS ( - NUMBER INTEGER DEFAULT 0 NOT NULL, - EN TEXT NOT NULL, - FR TEXT NOT NULL -); - --- TABLE NEWTABLE -DROP TABLE IF EXISTS NEWTABLE; -CREATE TABLE NEWTABLE ( - ID INTEGER DEFAULT 0 NOT NULL, - SOMENAME TEXT, - SOMEDATE TEXT NOT NULL, - CONSTRAINT PKINDEX_IDX PRIMARY KEY (ID) -); - --- VIEW on TEST -DROP VIEW IF EXISTS "testview"; -CREATE VIEW "testview" AS -SELECT * -FROM TEST1 -WHERE TEST_NAME LIKE 't%'; - --- VIEW on NUMBERS -DROP VIEW IF EXISTS "numbersview"; -CREATE VIEW "numbersview" AS -SELECT * -FROM NUMBERS -WHERE NUMBER > 100; - --- TABLEs for testing CONSTRAINTs -DROP TABLE IF EXISTS "testconstraints"; -CREATE TABLE "testconstraints" ( - someid integer NOT NULL, - somename TEXT NOT NULL, - CONSTRAINT testconstraints_id_pk PRIMARY KEY (someid) -); - -DROP TABLE IF EXISTS "testconstraints2"; -CREATE TABLE "testconstraints2" ( - ext_id integer NOT NULL, - modified text, - uniquefield text NOT NULL, - usraction integer NOT NULL, - CONSTRAINT testconstraints_id_fk FOREIGN KEY (ext_id) - REFERENCES testconstraints (someid) - ON UPDATE CASCADE - ON DELETE CASCADE, - CONSTRAINT unique_2_fields_idx UNIQUE (modified, usraction), - CONSTRAINT uniquefld_idx UNIQUE (uniquefield) -); \ No newline at end of file +CREATE TABLE IF NOT EXISTS "create_join" ("id" INTEGER PRIMARY KEY, "key" TEXT, "val" TEXT); \ No newline at end of file