Skip to content

Commit a78ef60

Browse files
allow queries to use either the normalized value placeholder or questions marks generated by sql builder
1 parent bf9006a commit a78ef60

File tree

2 files changed

+41
-18
lines changed

2 files changed

+41
-18
lines changed

machines/compile-statement.js

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,8 @@ module.exports = {
4848
outputDescription: 'The `nativeQuery` property is the compiled native query for the database. The `meta` property is reserved for custom driver-specific extensions.',
4949
example: '==='
5050
// example: {
51-
// nativeQuery: '*',
51+
// nativeQuery: 'SELECT * FROM foo',
52+
// valuesToEscape: ['foo']
5253
// meta: '==='
5354
// }
5455
},
@@ -105,9 +106,16 @@ module.exports = {
105106
return exits.error(err);
106107
}
107108

109+
110+
// Attach a flag to the meta object to denote that the query was generated
111+
// with Knex and that it's valuesToEscape don't need to be processed any further.
112+
var meta = inputs.meta || {};
113+
meta.isUsingQuestionMarks = true;
114+
108115
return exits.success({
109-
nativeQuery: compiledNativeQuery,
110-
meta: inputs.meta
116+
nativeQuery: compiledNativeQuery.sql,
117+
valuesToEscape: compiledNativeQuery.bindings || [],
118+
meta: meta
111119
});
112120
}
113121

machines/send-native-query.js

Lines changed: 30 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -104,34 +104,49 @@ module.exports = {
104104
// Validate provided native query.
105105
var sql = inputs.nativeQuery;
106106
var bindings = inputs.valuesToEscape || [];
107+
var queryInfo;
107108

108109

109110
debug('Running SQL Query:');
110111
debug('SQL: ' + sql);
111112
debug('Bindings: ' + bindings);
112113
debug('Connection Id: ' + inputs.connection.id);
113114

114-
// Process SQL template, escaping bindings.
115-
// This converts `$1`, `$2`, etc. into the escaped binding.
116-
sql = sql.replace(/\$[1-9][0-9]*/g, function (substr){
117-
118-
// e.g. `'$3'` => `'3'` => `3` => `2`
119-
var idx = +( substr.slice(1) ) - 1;
115+
// If the meta flag is defined and it has a flag titled `isUsingQuestionMarks`
116+
// then the query was generated by Knex in compileStatement and the query
117+
// string is using `?` in place of values rather than the Waterline standardized
118+
// $1, $2, etc.
119+
if (!inputs.meta || !inputs.meta.isUsingQuestionMarks) {
120+
// Process SQL template, escaping bindings.
121+
// This converts `$1`, `$2`, etc. into the escaped binding.
122+
sql = sql.replace(/\$[1-9][0-9]*/g, function (substr){
123+
124+
// e.g. `'$3'` => `'3'` => `3` => `2`
125+
var idx = +( substr.slice(1) ) - 1;
126+
127+
// If no such binding exists, then just leave the original
128+
// template string (e.g. "$3") alone.
129+
if (idx >= bindings.length) {
130+
return substr;
131+
}
120132

121-
// If no such binding exists, then just leave the original
122-
// template string (e.g. "$3") alone.
123-
if (idx >= bindings.length) {
124-
return substr;
125-
}
133+
// But otherwise, replace it with the escaped binding.
134+
return inputs.connection.escape(bindings[idx]);
135+
});
126136

127-
// But otherwise, replace it with the escaped binding.
128-
return inputs.connection.escape(bindings[idx]);
129-
});
137+
// In this case the query has the values inline.
138+
queryInfo = sql;
139+
} else {
140+
queryInfo = {
141+
sql: sql,
142+
values: bindings
143+
};
144+
}
130145

131146
debug('Compiled (final) SQL: ' + sql);
132147

133148
// Send native query to the database using node-mysql.
134-
inputs.connection.query(sql, function query() {
149+
inputs.connection.query(queryInfo, function query() {
135150
// The exact format of the arguments for this callback are not part of
136151
// the officially documented behavior of node-mysql (at least not as
137152
// of March 2016 when this comment is being written).

0 commit comments

Comments
 (0)