Skip to content
This repository has been archived by the owner on Nov 9, 2021. It is now read-only.

Commit

Permalink
Allow param query inside where, JOIN condition, and expr
Browse files Browse the repository at this point in the history
Added toParam support for expr() block when used in JOIN ON condition, or a where clause
Added new tests for JOIN on Condition using expr()
Added new tests for Expression block
Fixed updated build script.  After changing the build script, the select.test.coffee file was not running due to a typo in the grunt file.

There were some limitations with nesting a query, or expr() with a query, inside a where clause, or a JOIN condition and the use of toParam.  The nested queries were being converted to a string rather than doing a toParam, the string result was being added as the value for the parameter.  This is a potential sql injection risk.

Now the nested/inline query when provided as a parameter will be in a where clause will replace the parameter '?' with the textual component of the nested query, and add any parameters from the nested query to the parent query.

Example,

subqry = squel.select().field('col3').from('table2').where('col5 = ?', 'test1')
query = squel.select().field('col1').from('table1').where('col2 in ?', subqry)

query.toParam() gives:

{ text: "SELECT col1 FROM table1 WHERE (col2 IN (SELECT col3 FROM table2 WHERE (col5 = ?)))",
values: ['test1']
}

Previously it gave:

{ text: "SELECT col1 FROM table1 WHERE (col2 IN (?))",
values: ['SELECT col3 FROM table2 WHERE (col5 = 'test1')']
}
  • Loading branch information
waterytowers authored and hiddentao committed Oct 28, 2014
1 parent d95e55d commit 913b0e4
Show file tree
Hide file tree
Showing 12 changed files with 313 additions and 75 deletions.
2 changes: 1 addition & 1 deletion Gruntfile.js
Expand Up @@ -70,7 +70,7 @@ module.exports = function (grunt) {
'test/expressions.test.coffee',
'test/insert.test.coffee',
'test/mocha.test.coffee',
'test/selet.test.coffee',
'test/select.test.coffee',
'test/testbase.test.coffee',
'test/update.test.coffee'
]
Expand Down
96 changes: 78 additions & 18 deletions squel-basic.js
Expand Up @@ -285,14 +285,20 @@ OTHER DEALINGS IN THE SOFTWARE.
};

BaseBuilder.prototype._formatValueAsParam = function(value) {
var _this = this;
var p,
_this = this;
if (Array.isArray(value)) {
return value.map(function(v) {
return _this._formatValueAsParam(v);
});
} else {
if (value instanceof cls.QueryBuilder && value.isNestable()) {
return "" + value;
value.updateOptions({
"nestedBuilder": true
});
return p = value.toParam();
} else if (value instanceof cls.Expression) {
return p = value.toParam();
} else {
return this._formatCustomValue(value);
}
Expand All @@ -317,6 +323,8 @@ OTHER DEALINGS IN THE SOFTWARE.
value = value ? "TRUE" : "FALSE";
} else if (value instanceof cls.QueryBuilder) {
value = "(" + value + ")";
} else if (value instanceof cls.Expression) {
value = "(" + value + ")";
} else if ("number" !== typeof value) {
value = this._escapeValue(value);
value = formattingOptions.dontQuote ? "" + value : "'" + value + "'";
Expand Down Expand Up @@ -412,7 +420,7 @@ OTHER DEALINGS IN THE SOFTWARE.
};

Expression.prototype._toString = function(node, paramMode) {
var child, inStr, nodeStr, params, str, _i, _len, _ref;
var child, cv, inStr, nodeStr, params, str, _i, _len, _ref;
if (paramMode == null) {
paramMode = false;
}
Expand All @@ -427,7 +435,13 @@ OTHER DEALINGS IN THE SOFTWARE.
if (!paramMode) {
nodeStr = nodeStr.replace('?', this._formatValue(child.para));
} else {
params = params.concat(this._formatValueAsParam(child.para));
cv = this._formatValueAsParam(child.para);
if ((cv.text != null)) {
params = params.concat(cv.values);
nodeStr = nodeStr.replace('?', "(" + cv.text + ")");
} else {
params = params.concat(cv);
}
if (Array.isArray(child.para)) {
inStr = Array.apply(null, new Array(child.para.length)).map(function() {
return '?';
Expand Down Expand Up @@ -953,7 +967,7 @@ OTHER DEALINGS IN THE SOFTWARE.
};

SetFieldBlock.prototype.buildParam = function(queryBuilder) {
var field, i, str, vals, value, _i, _ref4;
var field, i, p, str, v, vals, value, _i, _j, _len, _ref4, _ref5;
if (0 >= this.fields.length) {
throw new Error("set() needs to be called");
}
Expand All @@ -968,8 +982,18 @@ OTHER DEALINGS IN THE SOFTWARE.
if (typeof value === 'undefined') {
str += field;
} else {
str += "" + field + " = ?";
vals.push(this._formatValueAsParam(value));
p = this._formatValueAsParam(value);
if (p.text != null) {
str += "" + field + " = (" + p.text + ")";
_ref5 = p.values;
for (_j = 0, _len = _ref5.length; _j < _len; _j++) {
v = _ref5[_j];
vals.push(v);
}
} else {
str += "" + field + " = ?";
vals.push(p);
}
}
}
return {
Expand Down Expand Up @@ -1022,16 +1046,27 @@ OTHER DEALINGS IN THE SOFTWARE.
};

InsertFieldValueBlock.prototype._buildValParams = function() {
var i, j, params, vals, _i, _j, _ref5, _ref6;
var i, j, p, params, str, v, vals, _i, _j, _k, _len, _ref5, _ref6, _ref7;
vals = [];
params = [];
for (i = _i = 0, _ref5 = this.values.length; 0 <= _ref5 ? _i < _ref5 : _i > _ref5; i = 0 <= _ref5 ? ++_i : --_i) {
for (j = _j = 0, _ref6 = this.values[i].length; 0 <= _ref6 ? _j < _ref6 : _j > _ref6; j = 0 <= _ref6 ? ++_j : --_j) {
params.push(this._formatValueAsParam(this.values[i][j]));
p = this._formatValueAsParam(this.values[i][j]);
if (p.text != null) {
str = p.text;
_ref7 = p.values;
for (_k = 0, _len = _ref7.length; _k < _len; _k++) {
v = _ref7[_k];
params.push(v);
}
} else {
str = '?';
params.push(p);
}
if ('string' === typeof vals[i]) {
vals[i] += ', ?';
vals[i] += ", " + str;
} else {
vals[i] = '?';
vals[i] = "" + str;
}
}
}
Expand Down Expand Up @@ -1240,7 +1275,7 @@ OTHER DEALINGS IN THE SOFTWARE.
};

WhereBlock.prototype.buildParam = function(queryBuilder) {
var ret, v, value, where, whereStr, _i, _j, _len, _len1, _ref5, _ref6;
var i, p, qv, ret, str, v, where, whereStr, _i, _j, _k, _len, _len1, _len2, _ref5, _ref6, _ref7;
ret = {
text: "",
values: []
Expand All @@ -1255,12 +1290,30 @@ OTHER DEALINGS IN THE SOFTWARE.
if ("" !== whereStr) {
whereStr += ") AND (";
}
whereStr += where.text;
str = where.text.split('?');
i = 0;
_ref6 = where.values;
for (_j = 0, _len1 = _ref6.length; _j < _len1; _j++) {
v = _ref6[_j];
ret.values.push(this._formatValueAsParam(v));
value = this._formatValueAsParam(value);
p = this._formatValueAsParam(v);
if (str[i] != null) {
whereStr += "" + str[i];
}
if ((p.text != null)) {
whereStr += "(" + p.text + ")";
_ref7 = p.values;
for (_k = 0, _len2 = _ref7.length; _k < _len2; _k++) {
qv = _ref7[_k];
ret.values.push(qv);
}
} else {
whereStr += "?";
ret.values.push(p);
}
i = i + 1;
}
if (str[i] != null) {
whereStr += "" + str[i];
}
}
ret.text = "WHERE (" + whereStr + ")";
Expand Down Expand Up @@ -1482,7 +1535,7 @@ OTHER DEALINGS IN THE SOFTWARE.
};

JoinBlock.prototype.buildParam = function(queryBuilder) {
var blk, joinStr, p, params, ret, v, _i, _j, _k, _len, _len1, _len2, _ref5, _ref6;
var blk, cp, joinStr, p, params, ret, v, _i, _j, _k, _len, _len1, _len2, _ref5, _ref6;
ret = {
text: "",
values: []
Expand Down Expand Up @@ -1511,6 +1564,13 @@ OTHER DEALINGS IN THE SOFTWARE.
});
p = blk.buildParam(queryBuilder);
}
if (blk.condition instanceof cls.Expression) {
cp = blk.condition.toParam();
p.condition = cp.text;
p.values = p.values.concat(cp.values);
} else {
p.condition = blk.condition;
}
p.join = blk;
params.push(p);
}
Expand All @@ -1528,8 +1588,8 @@ OTHER DEALINGS IN THE SOFTWARE.
if (p.join.alias) {
joinStr += " " + p.join.alias;
}
if (p.join.condition) {
joinStr += " ON (" + p.join.condition + ")";
if (p.condition) {
joinStr += " ON (" + p.condition + ")";
}
_ref6 = p.values;
for (_k = 0, _len2 = _ref6.length; _k < _len2; _k++) {
Expand Down
2 changes: 1 addition & 1 deletion squel-basic.min.js

Large diffs are not rendered by default.

96 changes: 78 additions & 18 deletions squel.js
Expand Up @@ -286,14 +286,20 @@ OTHER DEALINGS IN THE SOFTWARE.
};

BaseBuilder.prototype._formatValueAsParam = function(value) {
var _this = this;
var p,
_this = this;
if (Array.isArray(value)) {
return value.map(function(v) {
return _this._formatValueAsParam(v);
});
} else {
if (value instanceof cls.QueryBuilder && value.isNestable()) {
return "" + value;
value.updateOptions({
"nestedBuilder": true
});
return p = value.toParam();
} else if (value instanceof cls.Expression) {
return p = value.toParam();
} else {
return this._formatCustomValue(value);
}
Expand All @@ -318,6 +324,8 @@ OTHER DEALINGS IN THE SOFTWARE.
value = value ? "TRUE" : "FALSE";
} else if (value instanceof cls.QueryBuilder) {
value = "(" + value + ")";
} else if (value instanceof cls.Expression) {
value = "(" + value + ")";
} else if ("number" !== typeof value) {
value = this._escapeValue(value);
value = formattingOptions.dontQuote ? "" + value : "'" + value + "'";
Expand Down Expand Up @@ -413,7 +421,7 @@ OTHER DEALINGS IN THE SOFTWARE.
};

Expression.prototype._toString = function(node, paramMode) {
var child, inStr, nodeStr, params, str, _i, _len, _ref;
var child, cv, inStr, nodeStr, params, str, _i, _len, _ref;
if (paramMode == null) {
paramMode = false;
}
Expand All @@ -428,7 +436,13 @@ OTHER DEALINGS IN THE SOFTWARE.
if (!paramMode) {
nodeStr = nodeStr.replace('?', this._formatValue(child.para));
} else {
params = params.concat(this._formatValueAsParam(child.para));
cv = this._formatValueAsParam(child.para);
if ((cv.text != null)) {
params = params.concat(cv.values);
nodeStr = nodeStr.replace('?', "(" + cv.text + ")");
} else {
params = params.concat(cv);
}
if (Array.isArray(child.para)) {
inStr = Array.apply(null, new Array(child.para.length)).map(function() {
return '?';
Expand Down Expand Up @@ -954,7 +968,7 @@ OTHER DEALINGS IN THE SOFTWARE.
};

SetFieldBlock.prototype.buildParam = function(queryBuilder) {
var field, i, str, vals, value, _i, _ref4;
var field, i, p, str, v, vals, value, _i, _j, _len, _ref4, _ref5;
if (0 >= this.fields.length) {
throw new Error("set() needs to be called");
}
Expand All @@ -969,8 +983,18 @@ OTHER DEALINGS IN THE SOFTWARE.
if (typeof value === 'undefined') {
str += field;
} else {
str += "" + field + " = ?";
vals.push(this._formatValueAsParam(value));
p = this._formatValueAsParam(value);
if (p.text != null) {
str += "" + field + " = (" + p.text + ")";
_ref5 = p.values;
for (_j = 0, _len = _ref5.length; _j < _len; _j++) {
v = _ref5[_j];
vals.push(v);
}
} else {
str += "" + field + " = ?";
vals.push(p);
}
}
}
return {
Expand Down Expand Up @@ -1023,16 +1047,27 @@ OTHER DEALINGS IN THE SOFTWARE.
};

InsertFieldValueBlock.prototype._buildValParams = function() {
var i, j, params, vals, _i, _j, _ref5, _ref6;
var i, j, p, params, str, v, vals, _i, _j, _k, _len, _ref5, _ref6, _ref7;
vals = [];
params = [];
for (i = _i = 0, _ref5 = this.values.length; 0 <= _ref5 ? _i < _ref5 : _i > _ref5; i = 0 <= _ref5 ? ++_i : --_i) {
for (j = _j = 0, _ref6 = this.values[i].length; 0 <= _ref6 ? _j < _ref6 : _j > _ref6; j = 0 <= _ref6 ? ++_j : --_j) {
params.push(this._formatValueAsParam(this.values[i][j]));
p = this._formatValueAsParam(this.values[i][j]);
if (p.text != null) {
str = p.text;
_ref7 = p.values;
for (_k = 0, _len = _ref7.length; _k < _len; _k++) {
v = _ref7[_k];
params.push(v);
}
} else {
str = '?';
params.push(p);
}
if ('string' === typeof vals[i]) {
vals[i] += ', ?';
vals[i] += ", " + str;
} else {
vals[i] = '?';
vals[i] = "" + str;
}
}
}
Expand Down Expand Up @@ -1241,7 +1276,7 @@ OTHER DEALINGS IN THE SOFTWARE.
};

WhereBlock.prototype.buildParam = function(queryBuilder) {
var ret, v, value, where, whereStr, _i, _j, _len, _len1, _ref5, _ref6;
var i, p, qv, ret, str, v, where, whereStr, _i, _j, _k, _len, _len1, _len2, _ref5, _ref6, _ref7;
ret = {
text: "",
values: []
Expand All @@ -1256,12 +1291,30 @@ OTHER DEALINGS IN THE SOFTWARE.
if ("" !== whereStr) {
whereStr += ") AND (";
}
whereStr += where.text;
str = where.text.split('?');
i = 0;
_ref6 = where.values;
for (_j = 0, _len1 = _ref6.length; _j < _len1; _j++) {
v = _ref6[_j];
ret.values.push(this._formatValueAsParam(v));
value = this._formatValueAsParam(value);
p = this._formatValueAsParam(v);
if (str[i] != null) {
whereStr += "" + str[i];
}
if ((p.text != null)) {
whereStr += "(" + p.text + ")";
_ref7 = p.values;
for (_k = 0, _len2 = _ref7.length; _k < _len2; _k++) {
qv = _ref7[_k];
ret.values.push(qv);
}
} else {
whereStr += "?";
ret.values.push(p);
}
i = i + 1;
}
if (str[i] != null) {
whereStr += "" + str[i];
}
}
ret.text = "WHERE (" + whereStr + ")";
Expand Down Expand Up @@ -1483,7 +1536,7 @@ OTHER DEALINGS IN THE SOFTWARE.
};

JoinBlock.prototype.buildParam = function(queryBuilder) {
var blk, joinStr, p, params, ret, v, _i, _j, _k, _len, _len1, _len2, _ref5, _ref6;
var blk, cp, joinStr, p, params, ret, v, _i, _j, _k, _len, _len1, _len2, _ref5, _ref6;
ret = {
text: "",
values: []
Expand Down Expand Up @@ -1512,6 +1565,13 @@ OTHER DEALINGS IN THE SOFTWARE.
});
p = blk.buildParam(queryBuilder);
}
if (blk.condition instanceof cls.Expression) {
cp = blk.condition.toParam();
p.condition = cp.text;
p.values = p.values.concat(cp.values);
} else {
p.condition = blk.condition;
}
p.join = blk;
params.push(p);
}
Expand All @@ -1529,8 +1589,8 @@ OTHER DEALINGS IN THE SOFTWARE.
if (p.join.alias) {
joinStr += " " + p.join.alias;
}
if (p.join.condition) {
joinStr += " ON (" + p.join.condition + ")";
if (p.condition) {
joinStr += " ON (" + p.condition + ")";
}
_ref6 = p.values;
for (_k = 0, _len2 = _ref6.length; _k < _len2; _k++) {
Expand Down
4 changes: 2 additions & 2 deletions squel.min.js

Large diffs are not rendered by default.

0 comments on commit 913b0e4

Please sign in to comment.