diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..e279081 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +build +build/* +coverage +coverage/* \ No newline at end of file diff --git a/Gruntfile.js b/Gruntfile.js index 29655db..4fe9c41 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -1,9 +1,14 @@ module.exports = function(grunt) { 'use strict'; + var tests = 'tests/**/*_test.js'; + var src = 'lib/**/*.js'; + var reportDir = 'coverage'; + // Project configuration grunt.initConfig({ pkg: grunt.file.readJSON('package.json'), + clean: [ 'build' ], jsdoc: { dist: { src: ['lib/*.js', 'README.md'], @@ -15,18 +20,45 @@ module.exports = function(grunt) { } }, nodeunit: { - all: ['tests/**/*_test.js'], + all: [tests], options: { reporter: 'verbose' } + }, + watch: { + files: [src, tests], + tasks: 'default' + }, + instrument: { + files: src, + options: { + lazy: true, + basePath : 'build/instrument/' + } + }, + storeCoverage : { + options : { + dir: reportDir + } + }, + makeReport: { + src: 'build/reports/**/*.json', + options: { + type: ['lcov', 'html'], + dir: reportDir, + print: 'detail' + } } }); grunt.loadNpmTasks('grunt-jsdoc'); + grunt.loadNpmTasks('grunt-contrib-clean'); grunt.loadNpmTasks('grunt-contrib-nodeunit'); + grunt.loadNpmTasks('grunt-istanbul'); grunt.registerTask('default', ['nodeunit','jsdoc']); grunt.registerTask('tests', 'nodeunit'); grunt.registerTask('docs', 'jsdoc'); + grunt.registerTask('cover', ['clean', 'instrument', 'tests', 'storeCoverage', 'makeReport']); }; \ No newline at end of file diff --git a/lib/query-builder.js b/lib/query-builder.js index 56c3bb7..7506552 100755 --- a/lib/query-builder.js +++ b/lib/query-builder.js @@ -120,7 +120,7 @@ var QueryBuilder = function(driver, adapter) { val = "%" + val + "%"; } - conj = (state.queryMap.length < 1) ? ' WHERE ' : ' ' + conj + ''; + conj = (state.queryMap.length < 1) ? ' WHERE ' : ' ' + conj + ' '; _p.appendMap(conj, like, 'like'); state.whereValues.push(val); @@ -192,12 +192,12 @@ var QueryBuilder = function(driver, adapter) { Object.keys(state.whereMap).forEach(function(field) { // Split each key by spaces, in case there // is an operator such as >, <, !=, etc. - var fieldArray = field.split(' '); + var fieldArray = field.trim().split(' ').map(helpers.stringTrim); var item = driver.quoteIdentifiers(fieldArray[0]); // Simple key value, or an operator? - item += (fieldArray.length === 1) ? '=?' : " " + fieldArray[1] + " ?"; + item += (fieldArray.length === 1 || fieldArray[1] === '') ? '=?' : " " + fieldArray[1] + " ?"; var firstItem = state.queryMap[0], lastItem = state.queryMap[state.queryMap.length - 1]; @@ -244,25 +244,29 @@ var QueryBuilder = function(driver, adapter) { }); }); }, - whereIn: function(key, val, inClause, conj) { - key = driver.quoteIdentifiers(key); - var params = []; - params.fill('?', 0, val.length); + whereIn: function(/*key, val, inClause, conj*/) { + var args = getArgs('key:string, val:array, inClause:string, conj:string', arguments); - val.forEach(function(value) { + args.key = driver.quoteIdentifiers(args.key); + var params = new Array(args.val.length); + params.fill('?'); + + args.val.forEach(function(value) { state.whereValues.push(value); }); - conj = (state.queryMap.length > 0) ? " " + conj + " " : ' WHERE '; - var str = key + " " + inClause + " (" + params.join(',') + ") "; + args.conj = (state.queryMap.length > 0) ? " " + args.conj + " " : ' WHERE '; + var str = args.key + " " + args.inClause + " (" + params.join(',') + ") "; - _p.appendMap(conj, str, 'whereIn'); + _p.appendMap(args.conj, str, 'whereIn'); }, run: function(type, table, callback, sql, vals) { if ( ! sql) { sql = _p.compile(type, table); } +//console.log(sql); +//console.log('------------------------'); if ( ! vals) { diff --git a/package.json b/package.json index 7da7bf2..6d6f2e9 100755 --- a/package.json +++ b/package.json @@ -17,7 +17,9 @@ }, "devDependencies": { "grunt": "^0.4.5", + "grunt-contrib-clean": "^0.6.0", "grunt-contrib-nodeunit": "^0.4.1", + "grunt-istanbul": "^0.3.0", "grunt-jsdoc": ">=0.6.1", "jsdoc": "^3.3.0-alpha9", "mysql": "^2.5.2", @@ -30,5 +32,8 @@ "mysql2": "", "pg": "" }, - "license": "MIT" + "license": "MIT", + "scripts": { + "test": "grunt tests" + } } diff --git a/tests/query-builder-base.js b/tests/query-builder-base.js index d75dd9c..39b5918 100644 --- a/tests/query-builder-base.js +++ b/tests/query-builder-base.js @@ -84,17 +84,161 @@ module.exports = (function() { .orderBy('id, key') .get(base.testCallback.bind(test, test)); + test.done(); + }, + 'Select get': function(test) { + base.qb.select('id, key as k, val') + .get('create_test', 2, 1, base.testCallback.bind(test, test)); + + test.done(); + }, + 'Select from get': function(test) { + base.qb.select('id, key as k, val') + .from('create_test ct') + .where('id >', 1) + .get(base.testCallback.bind(test, test)); + + test.done(); + }, + 'Select from limit get': function(test) { + base.qb.select('id, key as k, val') + .from('create_test ct') + .where('id >', 1) + .limit(3) + .get(base.testCallback.bind(test, test)); + test.done(); } }, 'Grouping tests' : { + 'Using grouping method': function(test) { + base.qb.select('id, key as k, val') + .from('create_test') + .groupStart() + .where('id >', 1) + .where('id <', 900) + .groupEnd() + .limit(2, 1) + .get(base.testCallback.bind(test, test)); + test.done(); + }, + 'Using or grouping method': function(test) { + base.qb.select('id, key as k, val') + .from('create_test') + .groupStart() + .where('id >', 1) + .where('id <', 900) + .groupEnd() + .orGroupStart() + .where('id', 0) + .groupEnd() + .limit(2, 1) + .get(base.testCallback.bind(test, test)); + + test.done(); + }, + 'Using or not grouping method': function(test) { + base.qb.select('id, key as k, val') + .from('create_test') + .groupStart() + .where('id >', 1) + .where('id <', 900) + .groupEnd() + .orNotGroupStart() + .where('id', 0) + .groupEnd() + .limit(2, 1) + .get(base.testCallback.bind(test, test)); + + test.done(); + } }, 'Where in tests' : { + 'Where in': function(test) { + base.qb.from('create_test') + .whereIn('id', [0, 6, 56, 563, 341]) + .get(base.testCallback.bind(test, test)); + test.done(); + }, + 'Or Where in': function(test) { + base.qb.from('create_test') + .where('key', 'false') + .orWhereIn('id', [0, 6, 56, 563, 341]) + .get(base.testCallback.bind(test, test)); + + test.done(); + }, + 'Where Not in': function(test) { + base.qb.from('create_test') + .where('key', 'false') + .whereNotIn('id', [0, 6, 56, 563, 341]) + .get(base.testCallback.bind(test, test)); + + test.done(); + }, + 'Or Where Not in': function(test) { + base.qb.from('create_test') + .where('key', 'false') + .orWhereNotIn('id', [0, 6, 56, 563, 341]) + .get(base.testCallback.bind(test, test)); + + test.done(); + } }, 'Query modifier tests': { + 'Order By': function(test) { + base.qb.select('id, key as k, val') + .from('create_test') + .where('id >', 0) + .where('id <', 9000) + .orderBy('id', 'DESC') + .orderBy('k', "ASC") + .limit(5, 2) + .get(base.testCallback.bind(test, test)); + test.done(); + }, + 'Group by': function(test) { + base.qb.select('id, key as k, val') + .from('create_test') + .where('id >', 0) + .where('id <', 9000) + .groupBy('k') + .groupBy(['id', 'val']) + .orderBy('id', 'DESC') + .orderBy('k', "ASC") + .limit(5, 2) + .get(base.testCallback.bind(test, test)); + + test.done(); + }, + 'Or Where': function(test) { + base.qb.select('id, key as k, val') + .from('create_test') + .where(' id ', 1) + .orWhere('key >', 0) + .limit(2, 1) + .get(base.testCallback.bind(test, test)); + + test.done(); + }, + 'Like' : function(test) { + base.qb.from('create_test') + .like('key', 'og') + .get(base.testCallback.bind(test, test)); + + test.done(); + }, + 'Or Like': function(test) { + base.qb.from('create_test') + .like('key', 'og') + .orLike('key', 'val') + .get(base.testCallback.bind(test, test)); + + test.done(); + } }, 'DB update tests' : {