1
0
Fork 0

Remove bluebird dependency, add public query method, and re-add tests for node-firebird

Dieser Commit ist enthalten in:
Timothy Warren 2016-02-12 11:40:21 -05:00
Ursprung 383d632bb0
Commit 0ccd692267
22 geänderte Dateien mit 187 neuen und 101 gelöschten Zeilen

Datei anzeigen

@ -3,8 +3,15 @@ sudo: false
node_js:
- "node"
- "5.6"
- "5.5"
- "5.4"
- "5.3"
- "5.2"
- "5.1"
- "5.0"
- "4.3"
- "4.2"
- "4.1"
- "4.0"

8
CHANGELOG.md Normale Datei
Datei anzeigen

@ -0,0 +1,8 @@
# Changelog
## 3.2.0
* Added public `query` method for making arbitrary sql calls
* Added back tests for `node-query` adapter. Using this adapter with promises is not currently supported.
## 3.1.0
* Added support for promises on query execution methods

9
LICENSE.md Normale Datei
Datei anzeigen

@ -0,0 +1,9 @@
The MIT License (MIT)
Copyright (c) 2015 Timothy J. Warren
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

Datei anzeigen

@ -7,6 +7,9 @@ A node query builder for various SQL databases, based on [CodeIgniter](http://ww
[![Code Climate](https://codeclimate.com/github/timw4mail/node-query/badges/gpa.svg)](https://codeclimate.com/github/timw4mail/node-query)
[![Test Coverage](https://codeclimate.com/github/timw4mail/node-query/badges/coverage.svg)](https://codeclimate.com/github/timw4mail/node-query/coverage)
### Features
* Callback and Promise API for making database calls.
### Supported adapters
* mysql
@ -72,7 +75,6 @@ As of version 2, `where` and `having` type methods parse the values passed to lo
* Generated documentation is in the docs/ folder
* The API is documented in [API.md](./API.md)
* `tests/query-builder-base.js` contains a lot of usage examples
* The `tests/adapters` folder contains examples of how to set up a connection for the appropriate database library
* The documentation generated for the latest dev build is also [Available](https://github.timshomepage.net/node-query/docs/)

Datei anzeigen

@ -269,9 +269,9 @@ class QueryBuilder {
// Pass the sql and values to the adapter to run on the database
if (callback) {
return this.adapter.execute(sql, vals, callback);
return this.query(sql, vals, callback);
} else {
return this.adapter.execute(sql, vals);
return this.query(sql, vals);
}
}
@ -295,6 +295,19 @@ class QueryBuilder {
// ! Miscellaneous Methods
// ----------------------------------------------------------------------------
/**
* Manually make an sql query
* Returns a promise if no callback is provided
*
* @param {string} sql - The sql to execute
* @param {array} [params] - The query parameters
* @param {function} [callback] - Optional callback
* @return {void|Promise} - Returns a promise if no callback is supplied
*/
query(/*sql:string, [params]:array, [callback]:function*/) {
return this.adapter.execute.apply(this.adapter, arguments);
}
/**
* Reset the object state for a new query
*

Datei anzeigen

@ -2,7 +2,7 @@
let Adapter = require('../Adapter'),
getArgs = require('getargs'),
Promise = require('bluebird');
promisify = require('../promisify');
module.exports = class dblite extends Adapter {
/**
@ -15,10 +15,9 @@ module.exports = class dblite extends Adapter {
*/
execute(/*sql, params, callback*/) {
let args = getArgs('sql:string, [params]:array, [callback]:function', arguments);
let instance = Promise.promisifyAll(this.instance);
if (! args.callback) {
return instance.queryAsync(args.sql, args.params);
return promisify(this.instance.query)(args.sql, args.params);
}
return this.instance.query(args.sql, args.params, args.callback);

Datei anzeigen

@ -2,7 +2,7 @@
let Adapter = require('../Adapter'),
getArgs = require('getargs'),
Promise = require('bluebird');
promisify = require('../promisify');
module.exports = class mysql extends Adapter {
/**
@ -14,11 +14,10 @@ module.exports = class mysql extends Adapter {
* @return {void|Promise} - Returns a promise if no callback is provided
*/
execute(sql, params, callback) {
let args = getArgs('sql:string, [params], [callback]:function', arguments);
let instance = Promise.promisifyAll(this.instance);
let args = getArgs('sql:string, [params]:array, [callback]:function', arguments);
if (! args.callback) {
return instance.queryAsync(args.sql, args.params);
return promisify(this.instance.query)(args.sql, args.params);
}
return this.instance.query(args.sql, args.params, args.callback);

Datei anzeigen

@ -2,7 +2,7 @@
let Adapter = require('../Adapter'),
getArgs = require('getargs'),
Promise = require('bluebird');
promisify = require('../promisify');
module.exports = class mysql2 extends Adapter {
/**
@ -14,11 +14,10 @@ module.exports = class mysql2 extends Adapter {
* @return {void|Promise} - Returns a promise if no callback is provided
*/
execute(/*sql, params, callback*/) {
let args = getArgs('sql:string, [params], [callback]:function', arguments);
let instance = Promise.promisifyAll(this.instance);
let args = getArgs('sql:string, [params]:array, [callback]:function', arguments);
if (! args.callback) {
return instance.executeAsync(args.sql, args.params);
return promisify(this.instance.execute)(args.sql, args.params);
}
return this.instance.execute(args.sql, args.params, args.callback);

Datei anzeigen

@ -1,8 +1,7 @@
'use strict';
let Adapter = require('../Adapter'),
getArgs = require('getargs'),
Promise = require('bluebird');
getArgs = require('getargs');
module.exports = class nodefirebird extends Adapter {
/**
@ -15,10 +14,20 @@ module.exports = class nodefirebird extends Adapter {
*/
execute(/*sql, params, callback*/) {
let args = getArgs('sql:string, [params], [callback]:function', arguments);
let instance = Promise.promisifyAll(this.instance);
if (! args.callback) {
return instance.queryAsync(args.sql, args.params);
//return instance.queryAsync(args.sql, args.params);
if (! args.callback) {
return new Promise((resolve, reject) => {
this.instance.query(args.sql, args.params, (err, result) => {
if (err) {
return reject(err);
}
return resolve(result);
});
});
}
}
return this.instance.query(args.sql, args.params, args.callback);

Datei anzeigen

@ -1,8 +1,7 @@
'use strict';
let Adapter = require('../Adapter'),
getArgs = require('getargs'),
Promise = require('bluebird');
getArgs = require('getargs');
module.exports = class pg extends Adapter {
/**
@ -15,7 +14,6 @@ module.exports = class pg extends Adapter {
*/
execute(/*sql, params, callback*/) {
let args = getArgs('sql:string, [params]:array, [callback]:function', arguments);
let instance = Promise.promisifyAll(this.instance);
// Replace question marks with numbered placeholders, because this adapter is different...
let count = 0;
@ -25,7 +23,15 @@ module.exports = class pg extends Adapter {
});
if (! args.callback) {
return instance.queryAsync(args.sql, args.params);
return new Promise((resolve, reject) => {
this.instance.query(args.sql, args.params, (err, result) => {
if (err) {
return reject(err);
}
return resolve(result);
});
});
}
return this.instance.query(args.sql, args.params, args.callback);

Datei anzeigen

@ -7,7 +7,7 @@ let helpers = require('../helpers');
*
* @module drivers/firebird
*/
module.exports = (function() {
module.exports = (() => {
delete require.cache[require.resolve('../Driver')];
let driver = require('../Driver');
@ -21,7 +21,7 @@ module.exports = (function() {
* @param {Number|null} offset - Number of rows to skip
* @return {String} - Modified SQL statement
*/
driver.limit = function(origSql, limit, offset) {
driver.limit = (origSql, limit, offset) => {
let sql = `FIRST ${limit}`;
if (helpers.isNumber(offset))
@ -38,9 +38,9 @@ module.exports = (function() {
* @return {void}
* @throws {Error}
*/
driver.insertBatch = function() {
driver.insertBatch = () => {
throw new Error('Not Implemented');
};
return driver;
}());
})();

Datei anzeigen

@ -5,7 +5,7 @@
*
* @module drivers/mysql
*/
module.exports = (function() {
module.exports = (() => {
delete require.cache[require.resolve('../Driver')];
let driver = require('../Driver'),
helpers = require('../helpers');
@ -21,7 +21,7 @@ module.exports = (function() {
* @param {Number|null} offset - Number of rows to skip
* @return {String} - Modified SQL statement
*/
driver.limit = function(sql, limit, offset) {
driver.limit = (sql, limit, offset) => {
if (! helpers.isNumber(offset)) {
return sql += ` LIMIT ${limit}`;
}
@ -31,4 +31,4 @@ module.exports = (function() {
return driver;
}());
})();

Datei anzeigen

@ -5,9 +5,9 @@
*
* @module drivers/pg
*/
module.exports = (function() {
module.exports = (() => {
delete require.cache[require.resolve('../Driver')];
let driver = require('../Driver');
return driver;
}());
})();

26
lib/promisify.js Normale Datei
Datei anzeigen

@ -0,0 +1,26 @@
'use strict';
/*eslint-disable prefer-arrow-callback*/
/**
* Function to convert a callback function into a promise
*
* @see http://eddmann.com/posts/promisifying-error-first-asynchronous-callbacks-in-javascript/
* @example promisify(fs.readFile)('hello.txt', 'utf8')
* .then(console.log)
* .catch(console.error)
* @param {Function} fn - the callback function to convert
* @return {Promise} - the new promise
*/
function promisify(fn) {
return function () {
let args = [].slice.call(arguments);
return new Promise(function(resolve, reject) {
fn.apply(undefined, args.concat((error, value) => {
return error ? reject(error) : resolve(value);
}));
});
};
}
module.exports = promisify;
/*eslint-enable prefer-arrow-callback*/

Datei anzeigen

@ -1,6 +1,6 @@
{
"name": "ci-node-query",
"version": "3.1.0",
"version": "3.2.0",
"description": "A query builder for node based on the one in CodeIgniter",
"author": "Timothy J Warren <tim@timshomepage.net>",
"engines": {
@ -36,7 +36,6 @@
},
"main": "lib/NodeQuery.js",
"dependencies": {
"bluebird": "^3.1.4",
"dblite": "~0.7.6",
"getargs": "~0.0.8",
"mysql": "~2.10.2",

Datei anzeigen

@ -93,6 +93,6 @@ if (connection) {
.get();
expect(promise).to.be.fulfilled;
});
});
});
}

Datei anzeigen

@ -23,30 +23,32 @@ let connection = mysql2.createConnection(config.conn);
// Set up the query builder object
let nodeQuery = reload('../../lib/NodeQuery');
let qb = nodeQuery.init('mysql', connection, adapterName);
qb.query(qb.driver.truncate('create_test')).then(() => {
suite('Mysql2 adapter tests -', () => {
suite('Mysql2 adapter tests -', () => {
require('./mysql-base')(qb, nodeQuery, expect, testRunner, promiseTestRunner);
require('./mysql-base')(qb, nodeQuery, expect, testRunner, promiseTestRunner);
test('Test Insert Batch', done => {
let data = [
{
id: 5441,
key: 3,
val: new Buffer('7'),
}, {
id: 891,
key: 34,
val: new Buffer('10 o\'clock'),
}, {
id: 481,
key: 403,
val: new Buffer('97'),
},
];
test('Test Insert Batch', done => {
let data = [
{
id: 5441,
key: 3,
val: new Buffer('7'),
}, {
id: 891,
key: 34,
val: new Buffer('10 o\'clock'),
}, {
id: 481,
key: 403,
val: new Buffer('97'),
},
];
qb.insertBatch('create_test', data, (err, rows) => {
expect(err).is.not.ok;
return done();
qb.insertBatch('create_test', data, (err, rows) => {
expect(err).is.not.ok;
return done();
});
});
});
});

Datei anzeigen

@ -24,29 +24,32 @@ let connection = mysql.createConnection(config.conn);
let nodeQuery = reload('../../lib/NodeQuery');
let qb = nodeQuery.init('mysql', connection);
suite('Mysql adapter tests -', () => {
require('./mysql-base')(qb, nodeQuery, expect, testRunner, promiseTestRunner);
qb.query(qb.driver.truncate('create_test')).then(() => {
suite('Mysql adapter tests -', () => {
test('Test Insert Batch', done => {
let data = [
{
id: 544,
key: 3,
val: new Buffer('7'),
}, {
id: 89,
key: 34,
val: new Buffer('10 o\'clock'),
}, {
id: 48,
key: 403,
val: new Buffer('97'),
},
];
require('./mysql-base')(qb, nodeQuery, expect, testRunner, promiseTestRunner);
qb.insertBatch('create_test', data, (err, rows) => {
expect(err).is.not.ok;
return done();
test('Test Insert Batch', done => {
let data = [
{
id: 544,
key: 3,
val: new Buffer('7'),
}, {
id: 89,
key: 34,
val: new Buffer('10 o\'clock'),
}, {
id: 48,
key: 403,
val: new Buffer('97'),
},
];
qb.insertBatch('create_test', data, (err, rows) => {
expect(err).is.not.ok;
return done();
});
});
});
});

Datei anzeigen

@ -4,6 +4,7 @@
const path = require('path');
const reload = require('require-reload')(require);
const testBase = reload('../base');
const promisify = require('../../lib/promisify');
const expect = reload('chai').expect;
const testRunner = testBase.testRunner;
const promiseTestRunner = testBase.promiseTestRunner;
@ -22,19 +23,11 @@ if (process.env.CI || process.env.JENKINS_HOME) {
return;
}
suite('Firebird adapter tests -', () => {
// Set up the query builder object
suiteSetup('Database connection', connected => {
Firebird.attach(config.conn, (err, db) => {
qb = nodeQuery.init('firebird', db, adapterName);
return connected(err);
});
});
testRunner(qb, (err, done) => {
expect(err).is.not.ok;
done();
});
suite('Adapter-specific tests', () => {
// Promisifying the connection seems to be the only way to get
// this test suite to run consistently.
promisify(Firebird.attach)(config.conn).then(db => {
qb = nodeQuery.init('firebird', db, adapterName);
suite('Firebird adapter tests -', () => {
test('nodeQuery.getQuery = nodeQuery.init', () => {
expect(nodeQuery.getQuery())
.to.be.deep.equal(qb);
@ -44,8 +37,23 @@ suite('Firebird adapter tests -', () => {
qb.driver.insertBatch('create_test', []);
}).to.throw(Error, "Not Implemented");
});
/*---------------------------------------------------------------------------
Callback Tests
---------------------------------------------------------------------------*/
testRunner(qb, (err, done) => {
expect(err).is.not.ok;
done();
});
/*---------------------------------------------------------------------------
Promise Tests
---------------------------------------------------------------------------*/
/*qb.adapter.execute(qb.driver.truncate('create_test')).then(() => {
promiseTestRunner(qb);
});*/
suiteTeardown(() => {
qb.end();
});
});
suiteTeardown(() => {
qb.end();
});
});
}).catch(err => {
throw new Error(err);
});

Datei anzeigen

@ -17,17 +17,15 @@ let config = reload(configFile)[adapterName];
// Set up the connection
let pg = reload(adapterName);
let connection = new pg.Client(config.conn);
connection.connect(err => {
if (err) {
throw new Error(err);
}
});
// Set up the query builder object
let nodeQuery = reload('../../lib/NodeQuery');
let qb = nodeQuery.init('pg', connection);
suite('Pg adapter tests -', () => {
suiteSetup(done => {
return connection.connect(done);
});
test('nodeQuery.getQuery = nodeQuery.init', () => {
expect(nodeQuery.getQuery())
.to.be.deep.equal(qb);

Datei anzeigen

@ -3,10 +3,9 @@
const chai = require('chai');
const chaiAsPromised = require('chai-as-promised');
chai.use(chaiAsPromised);
const expect = chai.expect;
module.exports = {
expect: expect,
expect: chai.expect,
tests: require('./base/tests'),
testRunner: require('./base/adapterCallbackTestRunner'),
promiseTestRunner: require('./base/adapterPromiseTestRunner'),

Datei anzeigen

@ -42,7 +42,7 @@ let mixedSet = function mixedSet(/* $letName, $valType, $key, [$val] */) {
return state[args.$letName];
};
let whereMock = function() {
let whereMock = function () {
let args = getArgs('key:string|object, [val]', arguments);
state.whereMap = [];