diff --git a/lib/driver.js b/lib/driver.js index 83f4c76..7b77c2c 100755 --- a/lib/driver.js +++ b/lib/driver.js @@ -112,7 +112,48 @@ var d = { sql += d.quoteTable(table); return 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} + */ + insertBatch: function(table, data) { + + // Get the data values to insert, so they can + // be parameterized + var vals = []; + data.forEach(function(obj) { + Object.keys(obj).forEach(function(key) { + vals.push(obj[key]); + }); + }); + + // Get the field names from the keys of the first + // object inserted + var fields = Object.keys(data[0]); + table = d.quoteTable(table); + + var sql = "INSERT INTO " + table + " (" + + d.quoteIdentifiers(fields).join(",") + + ") VALUES "; + + // Create placeholder groups + var params = new Array(fields.length).fill('?'); + var paramString = "(" + params.join(',') + ")"; + var paramList = new Array(data.length).fill(paramString); + + sql += paramList.join(','); + + return { + sql: sql, + values: vals + }; } + }; module.exports = d; \ No newline at end of file diff --git a/lib/query-builder.js b/lib/query-builder.js index 23c86ef..b08cc46 100755 --- a/lib/query-builder.js +++ b/lib/query-builder.js @@ -269,18 +269,21 @@ var QueryBuilder = function(driver, adapter) { _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) { vals = state.values.concat(state.whereValues); } +//console.log(sql); +//console.log(vals); +//console.log('------------------------'); + // Reset the state so another query can be built _p.resetState(); @@ -763,6 +766,7 @@ var QueryBuilder = function(driver, adapter) { */ this.insert = function(/* table, data, callback */) { var args = getArgs('table:string, [data]:object, callback:function', arguments); + args.table = driver.quoteTable(args.table); if (args.data) { this.set(args.data); } @@ -771,6 +775,23 @@ var QueryBuilder = function(driver, adapter) { _p.run('insert', args.table, args.callback); }; + /** + * Insert multiple sets of rows at a time + * + * @param {String} table - The table to insert into + * @param {Array} data - The array of objects containing data rows to insert + * @param {Function} callback - Callback for handling database response + * @example query.insertBatch('foo',[{id:1,val:'bar'},{id:2,val:'baz'}], callbackFunction);S + * @return void + */ + this.insertBatch = function(/* table, data, callback */) { + var args = getArgs('table:string, data:array, callback:function', arguments); + var batch = driver.insertBatch(args.table, args.data); + + // Run the query + _p.run('', '', args.callback, batch.sql, batch.values); + }; + /** * Run the generated update query * @@ -798,7 +819,7 @@ var QueryBuilder = function(driver, adapter) { * @return void */ this.delete = function (/*table, [where], callback*/) { - var args = getArgs('table:string, [where], callback:function', arguments); + var args = getArgs('table:string, [where]:object, callback:function', arguments); if (args.where) { diff --git a/tests/base_test.js b/tests/base_test.js index 04fac94..c5dffc7 100755 --- a/tests/base_test.js +++ b/tests/base_test.js @@ -24,9 +24,7 @@ module.exports = { test.expect(1); test.throws(function() { modules['node-query']('foo', {}, 'bar'); - }, function(err) { - if (err instanceof Error) return true; - }); + }, Error, "Bad driver throws exception"); test.done(); } }; \ No newline at end of file diff --git a/tests/query-builder-base.js b/tests/query-builder-base.js index b265d03..980dd90 100644 --- a/tests/query-builder-base.js +++ b/tests/query-builder-base.js @@ -322,6 +322,24 @@ module.exports = (function QueryBuilderTestBase() { val: 2 }, base.testCallback.bind(this, test)); }, + 'Test Insert Batch': function(test) { + test.expect(1); + var data = [{ + id: 544, + key: 3, + val: 7 + }, { + id: 89, + key: 34, + val: "10 o'clock" + }, { + id: 48, + key: 403, + val: 97 + }]; + + base.qb.insertBatch('create_test', data, base.testCallback.bind(this, test)); + }, 'Test Update': function(test) { test.expect(1); base.qb.where('id', 7) @@ -354,12 +372,12 @@ module.exports = (function QueryBuilderTestBase() { 'Test delete': function(test) { test.expect(1); base.qb.delete('create_test', {id: 5}, base.testCallback.bind(this, test)); - }/*, + }, 'delete with where': function(test) { test.expect(1); base.qb.where('id', 5) .delete('create_test', base.testCallback.bind(this, test)); - }*/ + } }, // ! Get compiled tests 'Get compiled tests' : {