@@ -102,12 +102,16 @@ console.log(sql); // UPDATE posts SET modified = CURRENT_TIMESTAMP() WHERE id =
102102```
103103
104104To 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 ` ? `
105+ be used. This creates an object that will be left un-touched when used in a ` ? `
106106placeholder, useful for using functions as dynamic values:
107107
108108** Caution** The string provided to ` SqlString.raw() ` will skip all escaping
109109functions when used, so be careful when passing in unvalidated input.
110110
111+ Similarly, ` SqlString.identifier(id, forbidQualified) ` creates an object with a
112+ ` toSqlString ` method that returns ` SqlString.escapeId(id, forbidQualified) ` .
113+ Its result is not re-escaped when used in a ` ? ` or ` ?? ` placeholder.
114+
111115``` js
112116var CURRENT_TIMESTAMP = SqlString .raw (' CURRENT_TIMESTAMP()' );
113117var sql = SqlString .format (' UPDATE posts SET modified = ? WHERE id = ?' , [CURRENT_TIMESTAMP , 42 ]);
@@ -150,6 +154,15 @@ var sql = 'SELECT * FROM posts ORDER BY ' + SqlString.escapeId(sorter, true);
150154console .log (sql); // SELECT * FROM posts ORDER BY `date.2`
151155```
152156
157+ If ` escapeId ` receives an object with a ` toSqlString ` method, then ` escapeId ` uses
158+ that method's result after coercing it to a string.
159+
160+ ``` js
161+ var sorter = SqlString .identifier (' date' ); // ({ toSqlString: () => '`date`' })
162+ var sql = ' SELECT * FROM posts ORDER BY ' + sqlString .escapeId (sorter);
163+ console .log (sql); // SELECT * FROM posts ORDER BY `date`
164+ ```
165+
153166Alternatively, you can use ` ?? ` characters as placeholders for identifiers you would
154167like to have escaped like this:
155168
@@ -161,7 +174,8 @@ console.log(sql); // SELECT `username`, `email` FROM `users` WHERE id = 1
161174```
162175** Please note that this last character sequence is experimental and syntax might change**
163176
164- When you pass an Object to ` .escape() ` or ` .format() ` , ` .escapeId() ` is used to avoid SQL injection in object keys.
177+ When you pass an Object to ` .escape() ` or ` .format() ` , ` .escapeId() `
178+ is used to avoid SQL injection in object keys.
165179
166180### Formatting queries
167181
@@ -191,6 +205,78 @@ var sql = SqlString.format('UPDATE ?? SET ? WHERE `id` = ?', ['users', data,
191205console .log (sql); // UPDATE `users` SET `email` = 'foobar@example.com', `modified` = NOW() WHERE `id` = 1
192206```
193207
208+ ### ES6 Template Tag Support
209+
210+ ` SqlString.sql ` works as a template tag in Node versions that support ES6 features
211+ (node runtime versions 6 and later).
212+
213+ ``` es6
214+ var column = ' users' ;
215+ var userId = 1 ;
216+ var data = { email: ' foobar@example.com' , modified: SqlString .raw (' NOW()' ) };
217+ var fromFormat = SqlString .format (' UPDATE ?? SET ? WHERE `id` = ?' , [column, data, userId]);
218+ var fromTag = SqlString .sql ` UPDATE \` ${ column} \` SET ${ data} WHERE \` id\` = ${ userId} ` ;
219+
220+ console .log (fromFormat);
221+ console .log (fromTag .toSqlString ());
222+ // Both emit:
223+ // UPDATE `users` SET `email` = 'foobar@example.com', `modified` = NOW() WHERE `id` = 1
224+ ```
225+
226+
227+ There are some differences between ` SqlString.format ` and ` SqlString.raw ` :
228+
229+ * The ` SqlString.sql ` tag returns a raw chunk SQL as if by ` SqlString.raw ` ,
230+ whereas ` SqlString.format ` returns a string.
231+ This allows chaining:
232+ ``` es6
233+ let data = { a: 1 };
234+ let whereClause = SqlString .sql ` WHERE ${ data} ` ;
235+ SqlString .sql ` SELECT * FROM TABLE ${ whereClause} ` .toSqlString ();
236+ // SELECT * FROM TABLE WHERE `a` = 1
237+ ```
238+ * An interpolation in a quoted string will not insert excess quotes:
239+ ``` es6
240+ SqlString .sql ` SELECT '${ ' foo' } ' ` .toSqlString () === ` SELECT 'foo' ` ;
241+ SqlString .sql ` SELECT ${ ' foo' } ` .toSqlString () === ` SELECT 'foo' ` ;
242+ SqlString .format (" SELECT '?' " , [' foo' ]) === ` SELECT ''foo'' ` ;
243+ ```
244+ This means that you can interpolate a string into an ID thus:
245+ ``` es6
246+ SqlString .sql ` SELECT * FROM \` ${ ' table' } \` ` .toSqlString () === ' SELECT * FROM `table`'
247+ SqlString .format (' SELECT * FROM ??' , [' table' ]) === ' SELECT * FROM `table`'
248+ ```
249+ * Backticks end a template tag, so you need to escape backticks.
250+ ``` es6
251+ SqlString .sql ` SELECT \` ${ ' id' } \` FROM \` TABLE\` ` .toSqlString ()
252+ === ' SELECT `id` FROM `TABLE`'
253+ ```
254+ * Other escape sequences are raw.
255+ ``` es6
256+ SqlString .sql ` SELECT "\n "` .toSqlString () === ' SELECT "\\ n"'
257+ SqlString .format (' SELECT "\n "' , []) === ' SELECT "\n "'
258+ SqlString .format (String .raw ` SELECT "\n "` , []) === ' SELECT "\\ n"'
259+ ```
260+ * ` SqlString.format ` takes options at the end, but ` SqlString.sql `
261+ takes an options object in a separate call.
262+ ``` es6
263+ let timeZone = ' GMT' ;
264+ let date = new Date (Date .UTC (2000 , 0 , 1 ));
265+ SqlString .sql ({ timeZone })` SELECT ${ date} ` .toSqlString () ===
266+ ' SELECT \' 2000-01-01 00:00:00.000\' ' ;
267+ SqlString .format (' SELECT ?' , [date], false , timezone) ===
268+ ' SELECT \' 2000-01-01 00:00:00.000\' ' ;
269+ ```
270+ The options object can contain any of
271+ ` { stringifyObjects, timeZone, forbidQualified } ` which have the
272+ same meaning as when used with other ` SqlString ` APIs.
273+
274+ ` SqlString.sql ` handles ` ${...} ` inside quoted strings as if the tag
275+ matched the following grammar:
276+
277+ [ ![ Railroad Diagram] ( docs/sql-railroad.svg )] ( docs/sql-railroad.svg )
278+
279+
194280## License
195281
196282[ MIT] ( LICENSE )
0 commit comments