Streamline some dependencies, and add tests for query parser
This commit is contained in:
parent
0b9d4bf7c1
commit
7a3c5b7e79
@ -1,78 +0,0 @@
|
||||
/**
|
||||
* Polyfills for very handy methods that are standardized, but not fully implemented in Javascript engines
|
||||
*/
|
||||
module.exports = (function() {
|
||||
if (!Array.prototype.fill) {
|
||||
Array.prototype.fill = function(value) {
|
||||
// Steps 1-2.
|
||||
if (this == null) {
|
||||
throw new TypeError('this is null or not defined');
|
||||
}
|
||||
|
||||
var O = Object(this);
|
||||
|
||||
// Steps 3-5.
|
||||
var len = O.length >>> 0;
|
||||
|
||||
// Steps 6-7.
|
||||
var start = arguments[1];
|
||||
var relativeStart = start >> 0;
|
||||
|
||||
// Step 8.
|
||||
var k = relativeStart < 0 ?
|
||||
Math.max(len + relativeStart, 0) :
|
||||
Math.min(relativeStart, len);
|
||||
|
||||
// Steps 9-10.
|
||||
var end = arguments[2];
|
||||
var relativeEnd = end === undefined ?
|
||||
len : end >> 0;
|
||||
|
||||
// Step 11.
|
||||
var final = relativeEnd < 0 ?
|
||||
Math.max(len + relativeEnd, 0) :
|
||||
Math.min(relativeEnd, len);
|
||||
|
||||
// Step 12.
|
||||
while (k < final) {
|
||||
O[k] = value;
|
||||
k++;
|
||||
}
|
||||
|
||||
// Step 13.
|
||||
return O;
|
||||
};
|
||||
}
|
||||
|
||||
if ( !String.prototype.contains ) {
|
||||
String.prototype.contains = function() {
|
||||
return String.prototype.indexOf.apply( this, arguments ) !== -1;
|
||||
};
|
||||
}
|
||||
|
||||
if (!String.prototype.startsWith) {
|
||||
Object.defineProperty(String.prototype, 'startsWith', {
|
||||
enumerable: false,
|
||||
configurable: false,
|
||||
writable: false,
|
||||
value: function (searchString, position) {
|
||||
position = position || 0;
|
||||
return this.lastIndexOf(searchString, position) === position;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (!String.prototype.endsWith) {
|
||||
Object.defineProperty(String.prototype, 'endsWith', {
|
||||
value: function (searchString, position) {
|
||||
var subjectString = this.toString();
|
||||
if (position === undefined || position > subjectString.length) {
|
||||
position = subjectString.length;
|
||||
}
|
||||
position -= searchString.length;
|
||||
var lastIndex = subjectString.indexOf(searchString, position);
|
||||
return lastIndex !== -1 && lastIndex === position;
|
||||
}
|
||||
});
|
||||
}
|
||||
}());
|
@ -1,8 +1,7 @@
|
||||
"use strict";
|
||||
|
||||
/** @module helpers */
|
||||
|
||||
require('./es6-polyfill');
|
||||
require('es6-shim');
|
||||
|
||||
/** @alias module:helpers */
|
||||
var h = {
|
||||
|
@ -792,13 +792,12 @@ var QueryBuilder = function(driver, adapter) {
|
||||
/**
|
||||
* Run the generated delete query
|
||||
*
|
||||
* @method delete
|
||||
* @param {String} table - The table to insert into
|
||||
* @param {Object} [where] - Where clause for delete statement
|
||||
* @param {Function} callback - Callback for handling response from the database
|
||||
* @return void
|
||||
*/
|
||||
this['delete'] = function (/*table, [where], callback*/) {
|
||||
this.delete = function (/*table, [where], callback*/) {
|
||||
var args = getArgs('table:string, [where], callback:function', arguments);
|
||||
|
||||
if (args.where)
|
||||
|
@ -29,26 +29,6 @@ var filterMatches = function(array) {
|
||||
return output;
|
||||
};
|
||||
|
||||
var parseJoin = function(sql) {
|
||||
var matches = {};
|
||||
var output = {};
|
||||
|
||||
// Get clause components
|
||||
matches['function'] = sql.match(matchPatterns['function']);
|
||||
matches.identifiers = sql.match(matchPatterns.identifier);
|
||||
matches.operators = sql.match(matchPatterns.operator);
|
||||
|
||||
// Get everything at once for ordering
|
||||
matches.combined = sql.match(matchPatterns.combined);
|
||||
|
||||
// Flatten the matches to increase relevance
|
||||
Object.keys(matches).forEach(function(key) {
|
||||
output[key] = filterMatches(matches[key]);
|
||||
});
|
||||
|
||||
return output;
|
||||
};
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
@ -61,6 +41,32 @@ var QueryParser = function(driver) {
|
||||
// That 'new' keyword is annoying
|
||||
if ( ! (this instanceof QueryParser)) return new QueryParser(driver);
|
||||
|
||||
/**
|
||||
* Tokenize the sql into parts for additional processing
|
||||
*
|
||||
* @param {String} sql
|
||||
* @return {Object}
|
||||
*/
|
||||
this.parseJoin = function(sql) {
|
||||
var matches = {};
|
||||
var output = {};
|
||||
|
||||
// Get clause components
|
||||
matches['function'] = sql.match(matchPatterns['function']);
|
||||
matches.identifiers = sql.match(matchPatterns.identifier);
|
||||
matches.operators = sql.match(matchPatterns.operator);
|
||||
|
||||
// Get everything at once for ordering
|
||||
matches.combined = sql.match(matchPatterns.combined);
|
||||
|
||||
// Flatten the matches to increase relevance
|
||||
Object.keys(matches).forEach(function(key) {
|
||||
output[key] = filterMatches(matches[key]);
|
||||
});
|
||||
|
||||
return output;
|
||||
};
|
||||
|
||||
/**
|
||||
* Return the output of the parsing of the join condition
|
||||
*
|
||||
@ -68,7 +74,7 @@ var QueryParser = function(driver) {
|
||||
* @return {String} - The parsed/escaped join condition
|
||||
*/
|
||||
this.compileJoin = function(condition) {
|
||||
var parts = parseJoin(condition);
|
||||
var parts = this.parseJoin(condition);
|
||||
var count = parts.identifiers.length;
|
||||
var i;
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "ci-node-query",
|
||||
"version": "0.0.2",
|
||||
"version": "0.0.3",
|
||||
"description": "A query builder for node based on the one in CodeIgniter",
|
||||
"author": "Timothy J Warren <tim@timshomepage.net>",
|
||||
"engines": {
|
||||
@ -15,11 +15,11 @@
|
||||
},
|
||||
"main": "lib/node-query.js",
|
||||
"dependencies": {
|
||||
"async": "^0.9.0",
|
||||
"getargs": ""
|
||||
"getargs": "",
|
||||
"es6-shim":""
|
||||
},
|
||||
"bundledDependencies": [
|
||||
"async","getargs"
|
||||
"es6-shim","getargs"
|
||||
],
|
||||
"devDependencies": {
|
||||
"grunt": "^0.4.5",
|
||||
|
@ -26,7 +26,7 @@ testBase._setUp(qb, function(test, err, rows) {
|
||||
throw new Error(err);
|
||||
}
|
||||
|
||||
test.ok(rows, 'Valid result for generated query');
|
||||
test.ok(rows, 'mysql2: Valid result for generated query');
|
||||
test.done();
|
||||
});
|
||||
|
||||
|
@ -26,7 +26,7 @@ testBase._setUp(qb, function(test, err, rows) {
|
||||
throw new Error(err);
|
||||
}
|
||||
|
||||
test.ok(rows, 'Valid result for generated query');
|
||||
test.ok(rows, 'mysql: Valid result for generated query');
|
||||
test.done();
|
||||
});
|
||||
|
||||
|
@ -32,7 +32,7 @@ testBase._setUp(qb, function(test, err, result) {
|
||||
console.error('SQL syntax error', err);
|
||||
}
|
||||
|
||||
test.ok(result, 'Valid result for generated query');
|
||||
test.ok(result, 'pg: Valid result for generated query');
|
||||
test.done();
|
||||
});
|
||||
|
||||
|
52
tests/query-parser_test.js
Normal file
52
tests/query-parser_test.js
Normal file
@ -0,0 +1,52 @@
|
||||
'use strict';
|
||||
|
||||
// Use the base driver as a mock for testing
|
||||
var driver = require('../lib/driver');
|
||||
var parser = require('../lib/query-parser')(driver);
|
||||
|
||||
module.exports = {
|
||||
'Parse join tests' : {
|
||||
'Simple equals condition': function(test) {
|
||||
var matches = parser.parseJoin('table1.field1=table2.field2');
|
||||
test.deepEqual(['table1.field1','=','table2.field2'], matches.combined);
|
||||
test.done();
|
||||
},
|
||||
'Db.table.field condition': function(test) {
|
||||
var matches = parser.parseJoin('db1.table1.field1!=db2.table2.field2');
|
||||
test.deepEqual(['db1.table1.field1','!=', 'db2.table2.field2'], matches.combined);
|
||||
test.done();
|
||||
},
|
||||
'Underscore in identifier': function(test) {
|
||||
var matches = parser.parseJoin('table_1.field1 = tab_le2.field_2');
|
||||
test.deepEqual(['table_1.field1', '=', 'tab_le2.field_2'], matches.combined);
|
||||
test.done();
|
||||
},
|
||||
'Function in condition': function(test) {
|
||||
var matches = parser.parseJoin('table1.field1 > SUM(3+6)');
|
||||
test.deepEqual(['table1.field1', '>', 'SUM(3+6)'], matches.combined);
|
||||
test.done();
|
||||
}
|
||||
},
|
||||
'Compile join tests': {
|
||||
'Simple equals condition': function(test) {
|
||||
var join = parser.compileJoin('table1.field1=table2.field2');
|
||||
test.deepEqual('"table1"."field1"="table2"."field2"', join);
|
||||
test.done();
|
||||
},
|
||||
'Db.table.field condition': function(test) {
|
||||
var join = parser.compileJoin('db1.table1.field1!=db2.table2.field2');
|
||||
test.deepEqual('"db1"."table1"."field1"!="db2"."table2"."field2"', join);
|
||||
test.done();
|
||||
},
|
||||
'Underscore in identifier': function(test) {
|
||||
var join = parser.compileJoin('table_1.field1 = tab_le2.field_2');
|
||||
test.deepEqual('"table_1"."field1"="tab_le2"."field_2"', join);
|
||||
test.done();
|
||||
},
|
||||
'Function in condition': function(test) {
|
||||
var join = parser.compileJoin('table1.field1 > SUM(3+6)');
|
||||
test.deepEqual('"table1"."field1">SUM(3+6)', join);
|
||||
test.done();
|
||||
}
|
||||
}
|
||||
};
|
Loading…
Reference in New Issue
Block a user