From 873bfbc9ebca61e0fdf7e23c0c7244974ee86a03 Mon Sep 17 00:00:00 2001 From: "Timothy J. Warren" Date: Thu, 23 Oct 2014 11:59:42 -0400 Subject: [PATCH] Fix handling of functions in a select clause --- README.md | 4 ++-- docs/driver.js.html | 15 ++++++++++++++- docs/index.html | 4 ++-- lib/driver.js | 15 ++++++++++++++- tests/query-builder-base.js | 8 ++++++++ 5 files changed, 40 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index adbb120..0801b1a 100755 --- a/README.md +++ b/README.md @@ -6,10 +6,10 @@ A node query builder for various SQL databases, based on CodeIgniter's query bui var nodeQuery = require('node-query'); - var mysql = ... // Database module connection + var connection = ... // Database module connection // Three arguments: database type, database connection, database connection library - var query = nodeQuery('mysql', mysql, 'mysql2'); + var query = nodeQuery('mysql', connection, 'mysql2'); query.select('foo') .from('bar') diff --git a/docs/driver.js.html b/docs/driver.js.html index e97621b..c3a280f 100644 --- a/docs/driver.js.html +++ b/docs/driver.js.html @@ -177,6 +177,7 @@ var d = { */ quoteIdentifiers: function(str) { var hiers, raw; + var pattern = new RegExp(d.identifierChar + '(' + '([a-zA-Z0-9_]+)' + '(\((.*?)\))' + ')' + d.identifierChar, 'ig'); // Recurse for arrays of identifiiers if (Array.isArray(str)) @@ -191,7 +192,19 @@ var d = { hiers = str.split('.').map(d._quote); raw = hiers.join('.'); - // TODO: fix functions + // Fix functions + if (raw.contains('(') && raw.contains(')')) + { + var funcs = pattern.exec(raw); + console.log(funcs); + + // Unquote the function + raw = raw.replace(funcs[0], funcs[1]); + + // Quote the identifiers inside of the parens + var inParens = funcs[3].substring(1, funcs[3].length -1); + raw = raw.replace(inParens, d.quoteIdentifiers(inParens)); + } return raw; } diff --git a/docs/index.html b/docs/index.html index cad7eaa..fa4d97d 100644 --- a/docs/index.html +++ b/docs/index.html @@ -91,10 +91,10 @@

Node-query

A node query builder for various SQL databases, based on CodeIgniter's query builder.

Basic use

var nodeQuery = require('node-query');
 
-var mysql = ... // Database module connection 
+var connection = ... // Database module connection 
 
 // Three arguments: database type, database connection, database connection library
-var query = nodeQuery('mysql', mysql, 'mysql2');
+var query = nodeQuery('mysql', connection, 'mysql2');
 
 query.select('foo')
     .from('bar')
diff --git a/lib/driver.js b/lib/driver.js
index 4ac7749..27b23f5 100755
--- a/lib/driver.js
+++ b/lib/driver.js
@@ -106,6 +106,7 @@ var d = {
 	 */
 	quoteIdentifiers: function(str) {
 		var hiers, raw;
+		var pattern = new RegExp(d.identifierChar + '(' + '([a-zA-Z0-9_]+)' + '(\((.*?)\))' + ')' + d.identifierChar, 'ig');
 
 		// Recurse for arrays of identifiiers
 		if (Array.isArray(str))
@@ -120,7 +121,19 @@ var d = {
 		hiers = str.split('.').map(d._quote);
 		raw = hiers.join('.');
 
-		// TODO: fix functions
+		// Fix functions
+		if (raw.contains('(') && raw.contains(')'))
+		{
+			var funcs = pattern.exec(raw);
+			console.log(funcs);
+
+			// Unquote the function
+			raw = raw.replace(funcs[0], funcs[1]);
+
+			// Quote the identifiers inside of the parens
+			var inParens = funcs[3].substring(1, funcs[3].length -1);
+			raw = raw.replace(inParens, d.quoteIdentifiers(inParens));
+		}
 
 		return raw;
 	}
diff --git a/tests/query-builder-base.js b/tests/query-builder-base.js
index a941118..895a997 100644
--- a/tests/query-builder-base.js
+++ b/tests/query-builder-base.js
@@ -20,6 +20,14 @@ module.exports = (function()  {
 	 */
 	base.tests = {
 		'Get tests' : {
+			'Get with function': function(test) {
+				base.qb.select('id, COUNT(id) as count')
+					.from('create_test')
+					.groupBy('id')
+					.get(base.testCallback.bind(test, test));
+
+				test.done();
+			},
 			'Basic select all get': function(test) {
 				base.qb.get('create_test', base.testCallback.bind(test, test));
 				test.done();