Add firebird adapter, and quote the table name in all the methods

This commit is contained in:
Timothy Warren 2014-11-04 12:34:05 -05:00
parent 9264cc3438
commit d20769170c
8 changed files with 192 additions and 19 deletions

View File

@ -11,6 +11,7 @@ A node query builder for various SQL databases, based on CodeIgniter's query bui
* pg * pg
* dblite * dblite
* sqlite3 * sqlite3
* node-firebird
### Installation ### Installation

View File

@ -0,0 +1,29 @@
'use strict';
var adapter = require('../adapter'),
getArgs = require('getargs');
/** @module adapters/node-firebird */
var NodeFirebird = function(instance) {
// That 'new' keyword is annoying
if ( ! (this instanceof NodeFirebird)) return new NodeFirebird(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], callback:function', arguments);
instance.execute(args.sql, args.params, args.callback);
};
return adapter;
}
module.exports = NodeFirebird;

47
lib/drivers/firebird.js Normal file
View File

@ -0,0 +1,47 @@
"use strict";
var helpers = require('../helpers');
/**
* Driver for Firebird databases
*
* @module drivers/firebird
*/
module.exports = (function() {
delete require.cache[require.resolve('../driver')];
var driver = require('../driver');
driver.hasTruncate = false;
/**
* Generate a limit clause for firebird, which uses the syntax closest to the SQL standard
*
* @param {String} sql
* @param {Number} limit
* @param {Number} offset
* @return {String}
*/
driver.limit = function(origSql, limit, offset) {
var sql = 'FIRST ' + limit;
if (helpers.isNumber(offset))
{
sql += ' SKIP ' + offset;
}
return origSql.replace(/SELECT/i, "SELECT " + sql);;
};
/**
* SQL to insert a group of rows
*
* @param {String} table - The table to insert to
* @param {Array} [data] - The array of object containing data to insert
* @return {String}
*/
driver.insertBatch = function(table, data) {
throw new Error("Not Implemented");
};
return driver;
}());

View File

@ -284,6 +284,7 @@ var QueryBuilder = function(driver, adapter) {
//console.log(state.queryMap); //console.log(state.queryMap);
//console.log(sql); //console.log(sql);
//console.log(vals); //console.log(vals);
//console.log(callback);
//console.log('------------------------'); //console.log('------------------------');
// Reset the state so another query can be built // Reset the state so another query can be built
@ -768,13 +769,13 @@ var QueryBuilder = function(driver, adapter) {
*/ */
this.insert = function(/* table, data, callback */) { this.insert = function(/* table, data, callback */) {
var args = getArgs('table:string, [data]:object, callback:function', arguments); var args = getArgs('table:string, [data]:object, callback:function', arguments);
args.table = driver.quoteTable(args.table);
if (args.data) { if (args.data) {
this.set(args.data); this.set(args.data);
} }
// Run the query // Run the query
_p.run('insert', args.table, args.callback); _p.run('insert', driver.quoteTable(args.table), args.callback);
}; };
/** /**
@ -804,12 +805,13 @@ var QueryBuilder = function(driver, adapter) {
*/ */
this.update = function(/*table, data, callback*/) { this.update = function(/*table, data, callback*/) {
var args = getArgs('table:string, [data]:object, callback:function', arguments); var args = getArgs('table:string, [data]:object, callback:function', arguments);
if (args.data) { if (args.data) {
this.set(args.data); this.set(args.data);
} }
// Run the query // Run the query
_p.run('update', args.table, args.callback); _p.run('update', driver.quoteTable(args.table), args.callback);
}; };
/** /**
@ -829,7 +831,7 @@ var QueryBuilder = function(driver, adapter) {
} }
// Run the query // Run the query
_p.run('delete', args.table, args.callback); _p.run('delete', driver.quoteTable(args.table), args.callback);
}; };
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
@ -861,7 +863,7 @@ var QueryBuilder = function(driver, adapter) {
* @return {String} * @return {String}
*/ */
this.getCompiledInsert = function(table, reset) { this.getCompiledInsert = function(table, reset) {
return _p.getCompile('insert', table, reset); return _p.getCompile('insert', driver.quoteTable(table), reset);
}; };
/** /**
@ -872,7 +874,7 @@ var QueryBuilder = function(driver, adapter) {
* @return {String} * @return {String}
*/ */
this.getCompiledUpdate = function(table, reset) { this.getCompiledUpdate = function(table, reset) {
return _p.getCompile('update', table, reset); return _p.getCompile('update', driver.quoteTable(table), reset);
}; };
/** /**
@ -883,7 +885,7 @@ var QueryBuilder = function(driver, adapter) {
* @return {String} * @return {String}
*/ */
this.getCompiledDelete = function(table, reset) { this.getCompiledDelete = function(table, reset) {
return _p.getCompile('delete', table, reset); return _p.getCompile('delete', driver.quoteTable(table), reset);
}; };
return this; return this;

View File

@ -1,6 +1,6 @@
{ {
"name": "ci-node-query", "name": "ci-node-query",
"version": "1.0.0", "version": "1.1.0",
"description": "A query builder for node based on the one in CodeIgniter", "description": "A query builder for node based on the one in CodeIgniter",
"author": "Timothy J Warren <tim@timshomepage.net>", "author": "Timothy J Warren <tim@timshomepage.net>",
"engines": { "engines": {
@ -19,7 +19,9 @@
"postgres", "postgres",
"sqlite", "sqlite",
"dblite", "dblite",
"sqlite3" "sqlite3",
"firebird",
"node-firebird"
], ],
"bugs": { "bugs": {
"url": "https://github.com/timw4mail/node-query/issues" "url": "https://github.com/timw4mail/node-query/issues"
@ -44,7 +46,7 @@
"jsdoc": "^3.3.0-alpha9", "jsdoc": "^3.3.0-alpha9",
"mysql": "^2.5.2", "mysql": "^2.5.2",
"mysql2": "^0.12.5", "mysql2": "^0.12.5",
"node-firebird": "^0.2.3", "node-firebird": "^0.2.4",
"nodeunit": "^0.9.0", "nodeunit": "^0.9.0",
"pg": "^3.6.2", "pg": "^3.6.2",
"sqlite3": "^3.0.2" "sqlite3": "^3.0.2"

View File

@ -0,0 +1,83 @@
'use strict';
// Load the test base
var testBase = require('../query-builder-base');
// Load the test config file
var adapterName = 'node-firebird';
var config = require('../config.json')[adapterName];
config.conn.database = __dirname + config.conn.database;
var nodeQuery = require('../../lib/node-query');
// Set up the connection
try {
var Firebird = require(adapterName);
var conn = null;
var qb = null;
} catch (e) {
// Export an empty testBase.testsuite if module not loaded
console.log(e);
console.log("Database adapter firebird not found");
module.exports = {};
}
// Setup testbase from the inside out
// Because the connection is async, utilize
// the setUp function from nodeunit to get the connection
testBase.tests.setUp = function(cb) {
if ( ! conn)
{
// Connect to the database
Firebird.attach(config.conn, function(err, db) {
if (err) {
throw new Error(err);
console.error(err);
}
conn = db;
// Set up the query builder object
qb = nodeQuery.init('firebird', db, adapterName);
testBase._setUp(qb, function(test, err, result) {
if (err) {
test.done();
throw new Error(err);
}
result = result || [];
test.ok(result, 'firebird: Valid result for generated query');
test.done();
});
cb();
});
}
else
{
cb();
}
};
//delete testBase.tests['DB update tests'];
testBase.tests['DB update tests']['Test Insert Batch'] = function(test) {
test.expect(1);
test.throws(function() {
qb.insertBatch({}, (function() {}));
}, Error, "Insert Batch not implemented for firebird");
test.done();
};
testBase.tests["firebird adapter with query builder"] = function(test) {
test.expect(1);
test.ok(testBase.qb);
// Disconnect from the db
conn.detach();
test.done();
};
module.exports = testBase.tests;

View File

@ -24,5 +24,14 @@
"dblite": { "dblite": {
"driver": "sqlite", "driver": "sqlite",
"conn": ":memory:" "conn": ":memory:"
},
"node-firebird": {
"driver": "firebird",
"conn": {
"host": "127.0.0.1",
"database": "/../FB_TEST_DB.FDB",
"user": "SYSDBA",
"password": "masterkey"
}
} }
} }

View File

@ -310,8 +310,8 @@ module.exports = (function QueryBuilderTestBase() {
'Test Insert': function(test) { 'Test Insert': function(test) {
test.expect(1); test.expect(1);
base.qb.set('id', 98) base.qb.set('id', 98)
.set('key', 84) .set('key', "84")
.set('val', 120) .set('val', new Buffer("120"))
.insert('create_test', base.testCallback.bind(this, test)); .insert('create_test', base.testCallback.bind(this, test));
}, },
'Test Insert Object': function(test) { 'Test Insert Object': function(test) {
@ -319,7 +319,7 @@ module.exports = (function QueryBuilderTestBase() {
base.qb.insert('create_test', { base.qb.insert('create_test', {
id: 587, id: 587,
key: 1, key: 1,
val: 2 val: new Buffer('2')
}, base.testCallback.bind(this, test)); }, base.testCallback.bind(this, test));
}, },
'Test Insert Batch': function(test) { 'Test Insert Batch': function(test) {
@ -327,15 +327,15 @@ module.exports = (function QueryBuilderTestBase() {
var data = [{ var data = [{
id: 544, id: 544,
key: 3, key: 3,
val: 7 val: new Buffer('7')
}, { }, {
id: 89, id: 89,
key: 34, key: 34,
val: "10 o'clock" val: new Buffer("10 o'clock")
}, { }, {
id: 48, id: 48,
key: 403, key: 403,
val: 97 val: new Buffer('97')
}]; }];
base.qb.insertBatch('create_test', data, base.testCallback.bind(this, test)); base.qb.insertBatch('create_test', data, base.testCallback.bind(this, test));
@ -346,7 +346,7 @@ module.exports = (function QueryBuilderTestBase() {
.update('create_test', { .update('create_test', {
id: 7, id: 7,
key: 'gogle', key: 'gogle',
val: 'non-word' val: new Buffer('non-word')
}, base.testCallback.bind(this, test)); }, base.testCallback.bind(this, test));
}, },
'Test set Array Update': function(test) { 'Test set Array Update': function(test) {
@ -354,7 +354,7 @@ module.exports = (function QueryBuilderTestBase() {
var object = { var object = {
id: 22, id: 22,
key: 'gogle', key: 'gogle',
val: 'non-word' val: new Buffer('non-word')
}; };
base.qb.set(object) base.qb.set(object)
@ -366,7 +366,7 @@ module.exports = (function QueryBuilderTestBase() {
base.qb.where('id', 36) base.qb.where('id', 36)
.set('id', 36) .set('id', 36)
.set('key', 'gogle') .set('key', 'gogle')
.set('val', 'non-word') .set('val', new Buffer('non-word'))
.update('create_test', base.testCallback.bind(this, test)); .update('create_test', base.testCallback.bind(this, test));
}, },
'Test delete': function(test) { 'Test delete': function(test) {