From 55c20da35969bb3102afea136e36e049142b506b Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Mon, 2 Oct 2017 00:01:16 -0400 Subject: [PATCH] Add mysql.raw() to generate pre-escaped values closes #877 closes #1821 --- Changes.md | 1 + Readme.md | 13 +++++++++++++ index.js | 12 ++++++++++++ test/unit/test-Mysql.js | 10 ++++++++++ 4 files changed, 36 insertions(+) diff --git a/Changes.md b/Changes.md index fe640cb31..78a30ec56 100644 --- a/Changes.md +++ b/Changes.md @@ -7,6 +7,7 @@ you spot any mistakes. ## HEAD * Add new Amazon RDS ca-central-1 certificate CA to Amazon RDS SSL profile #1809 +* Add `mysql.raw()` to generate pre-escaped values #877 #1821 * Fix "changedRows" to work on non-English servers #1819 * Fix typo in insecure auth error message * Support `mysql_native_password` auth switch request for Azure #1396 #1729 #1730 diff --git a/Readme.md b/Readme.md index f1bf7b221..81ad2b1db 100644 --- a/Readme.md +++ b/Readme.md @@ -737,6 +737,19 @@ var sql = mysql.format('UPDATE posts SET modified = ? WHERE id = ?', [CURRENT_TI console.log(sql); // UPDATE posts SET modified = CURRENT_TIMESTAMP() WHERE id = 42 ``` +To generate objects with a `toSqlString` method, the `mysql.raw()` method can +be used. This creates an object that will be left un-touched when using in a `?` +placeholder, useful for using functions as dynamic values: + +**Caution** The string provided to `mysql.raw()` will skip all escaping +functions when used, so be careful when passing in unvalidated input. + +```js +var CURRENT_TIMESTAMP = mysql.raw('CURRENT_TIMESTAMP()'); +var sql = mysql.format('UPDATE posts SET modified = ? WHERE id = ?', [CURRENT_TIMESTAMP, 42]); +console.log(sql); // UPDATE posts SET modified = CURRENT_TIMESTAMP() WHERE id = 42 +``` + If you feel the need to escape queries by yourself, you can also use the escaping function directly: diff --git a/index.js b/index.js index ed4496d56..72624076b 100644 --- a/index.js +++ b/index.js @@ -94,6 +94,18 @@ exports.format = function format(sql, values, stringifyObjects, timeZone) { return SqlString.format(sql, values, stringifyObjects, timeZone); }; +/** + * Wrap raw SQL strings from escape overriding. + * @param {string} sql The raw SQL + * @return {object} Wrapped object + * @public + */ +exports.raw = function raw(sql) { + var SqlString = loadClass('SqlString'); + + return SqlString.raw(sql); +}; + /** * The type constants. * @public diff --git a/test/unit/test-Mysql.js b/test/unit/test-Mysql.js index 8cc627c75..5bd15fe6d 100644 --- a/test/unit/test-Mysql.js +++ b/test/unit/test-Mysql.js @@ -20,6 +20,16 @@ test('Mysql.format', { } }); +test('Mysql.raw', { + 'generate object format will not escape': function() { + var now = Mysql.raw('NOW()'); + assert.equal( + Mysql.format('SELECT * FROM ?? WHERE ?? >= ?', ['table', 'property', now]), + 'SELECT * FROM `table` WHERE `property` >= NOW()' + ); + } +}); + test('Mysql.Types', { 'exported object of types': function() { assert.equal(typeof Mysql.Types, 'object');