fixing insert column ordering, fixes #31

This commit is contained in:
Tim Griesser 2013-08-07 10:22:46 -04:00
parent 339ab8df4c
commit bb21643539
2 changed files with 19 additions and 22 deletions

View File

@ -128,25 +128,23 @@ Sqlite3Client.grammar = {
return require('../knex').Grammar.compileInsert.call(this, qb);
}
var keys = _.keys(values[0]).sort();
var names = this.columnize(keys);
var columns = [];
var columns = _.pluck(values[0], 0);
var blocks = [];
// SQLite requires us to build the multi-row insert as a listing of select with
// unions joining them together. So we'll build out this list of columns and
// then join them all together with select unions to complete the queries.
for (var i = 0, l = keys.length; i < l; i++) {
var column = keys[i];
columns.push('? as ' + this.wrap(column));
for (var i = 0, l = columns.length; i < l; i++) {
blocks.push('? as ' + this.wrap(columns[i]));
}
var joinedColumns = columns.join(', ');
columns = [];
var joinedColumns = blocks.join(', ');
blocks = [];
for (i = 0, l = values.length; i < l; i++) {
columns.push(joinedColumns);
blocks.push(joinedColumns);
}
return "insert into " + table + " (" + names + ") select " + columns.join(' union all select ');
return "insert into " + table + " (" + this.columnize(columns) + ") select " + blocks.join(' union all select ');
},
// Compile a truncate table statement into SQL.

23
knex.js
View File

@ -103,7 +103,7 @@
if (!(bindings[i] instanceof Raw)) {
cleaned.push(bindings[i]);
} else {
cleaned.push(bindings[i].bindings);
push.apply(cleaned, bindings[i].bindings);
}
}
return cleaned;
@ -322,10 +322,9 @@
// Compiles an `insert` query, allowing for multiple
// inserts using a single query statement.
compileInsert: function(qb) {
var values = qb.values;
var table = this.wrapTable(qb.table);
var columns = this.columnize(_.keys(values[0]).sort());
var parameters = this.parameterize(_.values(values[0]));
var values = qb.values;
var table = this.wrapTable(qb.table);
var columns = _.pluck(values[0], 0);
var paramBlocks = [];
// If there are any "where" clauses, we need to omit
@ -333,10 +332,10 @@
if (qb.wheres.length > 0) this._clearWhereBindings(qb);
for (var i = 0, l = values.length; i < l; ++i) {
paramBlocks.push("(" + parameters + ")");
paramBlocks.push("(" + this.parameterize(_.pluck(values[i], 1)) + ")");
}
return "insert into " + table + " (" + columns + ") values " + paramBlocks.join(', ');
return "insert into " + table + " (" + this.columnize(columns) + ") values " + paramBlocks.join(', ');
},
// Depending on the type of `where` clause, this will appropriately
@ -804,7 +803,7 @@
bindings[i] = obj[i][1];
}
this.bindings = bindings.concat(this.bindings || []);
this.values = obj;
this.values = obj;
return this._setType('update');
},
@ -842,7 +841,7 @@
_prepValues: function(values) {
if (!_.isArray(values)) values = values ? [values] : [];
for (var i = 0, l = values.length; i<l; i++) {
var obj = sortObject(values[i]);
var obj = values[i] = sortObject(values[i]);
for (var i2 = 0, l2 = obj.length; i2 < l2; i2++) {
this.bindings.push(obj[i2][1]);
}
@ -1657,8 +1656,8 @@
};
// Executes a Raw query.
Target.Raw = function(value, bindings) {
var raw = new Raw(value, bindings);
Target.Raw = function(sql, bindings) {
var raw = new Raw(sql, bindings);
raw.client = client;
return raw;
};
@ -1685,4 +1684,4 @@
// Export the Knex module
module.exports = Knex;
}).call(this);
}).call(this);