Skip to content

Commit b22d66f

Browse files
SeregPiedougwilson
authored andcommitted
Add raw method to wrap raw strings for escape overriding
closes mysqljs#13 closes mysqljs#21
1 parent 971f4f0 commit b22d66f

File tree

4 files changed

+54
-0
lines changed

4 files changed

+54
-0
lines changed

HISTORY.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ unreleased
22
==========
33

44
* Add `.toSqlString()` escape overriding
5+
* Add `raw` method to wrap raw strings for escape overriding
56
* Small performance improvement on `escapeId`
67

78
2.2.0 / 2016-11-01

README.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,19 @@ var sql = SqlString.format('UPDATE posts SET modified = ? WHERE id = ?', [CURREN
101101
console.log(sql); // UPDATE posts SET modified = CURRENT_TIMESTAMP() WHERE id = 42
102102
```
103103

104+
To generate objects with a `toSqlString` method, the `SqlString.raw()` method can
105+
be used. This creates an object that will be left un-touched when using in a `?`
106+
placeholder, useful for using functions as dynamic values:
107+
108+
**Caution** The string provided to `SqlString.raw()` will skip all escaping
109+
functions when used, so be careful when passing in unvalidated input.
110+
111+
```js
112+
var CURRENT_TIMESTAMP = SqlString.raw('CURRENT_TIMESTAMP()');
113+
var sql = SqlString.format('UPDATE posts SET modified = ? WHERE id = ?', [CURRENT_TIMESTAMP, 42]);
114+
console.log(sql); // UPDATE posts SET modified = CURRENT_TIMESTAMP() WHERE id = 42
115+
```
116+
104117
If you feel the need to escape queries by yourself, you can also use the escaping
105118
function directly:
106119

lib/SqlString.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,16 @@ SqlString.objectToValues = function objectToValues(object, timeZone) {
177177
return sql;
178178
};
179179

180+
SqlString.raw = function raw(sql) {
181+
if (typeof sql !== 'string') {
182+
throw new TypeError('argument sql must be a string');
183+
}
184+
185+
return {
186+
toSqlString: function toSqlString() { return sql; }
187+
};
188+
};
189+
180190
function escapeString(val) {
181191
var chunkIndex = CHARS_GLOBAL_REGEXP.lastIndex = 0;
182192
var escapedVal = '';

test/unit/test-SqlString.js

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,10 @@ test('SqlString.escape', {
6666
assert.equal(SqlString.escape(5), '5');
6767
},
6868

69+
'raw not escaped': function () {
70+
assert.equal(SqlString.escape(SqlString.raw('NOW()')), 'NOW()');
71+
},
72+
6973
'objects are turned into key value pairs': function() {
7074
assert.equal(SqlString.escape({a: 'b', c: 'd'}), "`a` = 'b', `c` = 'd'");
7175
},
@@ -299,3 +303,29 @@ test('SqlString.format', {
299303
assert.equal(sql, 'SELECT COUNT(*) FROM table');
300304
}
301305
});
306+
307+
test('SqlString.raw', {
308+
'creates object': function() {
309+
assert.equal(typeof SqlString.raw('NOW()'), 'object');
310+
},
311+
312+
'rejects number': function() {
313+
assert.throws(function () {
314+
SqlString.raw(42);
315+
});
316+
},
317+
318+
'rejects undefined': function() {
319+
assert.throws(function () {
320+
SqlString.raw();
321+
});
322+
},
323+
324+
'object has toSqlString': function() {
325+
assert.equal(typeof SqlString.raw('NOW()').toSqlString, 'function');
326+
},
327+
328+
'toSqlString returns sql as-is': function() {
329+
assert.equal(SqlString.raw("NOW() AS 'current_time'").toSqlString(), "NOW() AS 'current_time'");
330+
}
331+
});

0 commit comments

Comments
 (0)