1
1
'use strict'
2
2
3
+ const lsp = str => ( / ^ [ \s \n \r ] / . test ( str ) ? str : ' ' + str )
4
+ const push = ( str , val , statement , spaced ) => {
5
+ const { strings } = statement
6
+ str [ str . length - 1 ] += spaced ? lsp ( strings [ 0 ] ) : strings [ 0 ]
7
+ str . push ( ...strings . slice ( 1 ) )
8
+ val . push ( ...( statement . values || statement . bind ) )
9
+ }
10
+
3
11
class SQLStatement {
4
12
/**
5
13
* @param {string[] } strings
@@ -25,20 +33,19 @@ class SQLStatement {
25
33
* @returns {this }
26
34
*/
27
35
append ( statement ) {
36
+ const { strings } = this
28
37
if ( statement instanceof SQLStatement ) {
29
- this . strings [ this . strings . length - 1 ] += statement . strings [ 0 ]
30
- this . strings . push . apply ( this . strings , statement . strings . slice ( 1 ) )
31
- const list = this . values || this . bind
32
- list . push . apply ( list , statement . values )
38
+ push ( strings , this . values || this . bind , statement , true )
33
39
} else {
34
- this . strings [ this . strings . length - 1 ] += statement
40
+ strings [ strings . length - 1 ] += lsp ( statement )
35
41
}
36
42
return this
37
43
}
38
44
39
45
/**
40
46
* Use a prepared statement with Sequelize.
41
- * Makes `query` return a query with `$n` syntax instead of `?` and switches the `values` key name to `bind`
47
+ * Makes `query` return a query with `$n` syntax instead of `?`
48
+ * and switches the `values` key name to `bind`
42
49
* @param {boolean } [value=true] value If omitted, defaults to `true`
43
50
* @returns this
44
51
*/
@@ -79,8 +86,27 @@ Object.defineProperty(SQLStatement.prototype, 'sql', {
79
86
* @param {...any } values
80
87
* @returns {SQLStatement }
81
88
*/
82
- function SQL ( strings ) {
83
- return new SQLStatement ( strings . slice ( 0 ) , Array . from ( arguments ) . slice ( 1 ) )
89
+ function SQL ( tpl , ...val ) {
90
+ const strings = [ tpl [ 0 ] ]
91
+ const values = [ ]
92
+ for ( let { length } = tpl , prev = tpl [ 0 ] , j = 0 , i = 1 ; i < length ; i ++ ) {
93
+ const current = tpl [ i ]
94
+ const value = val [ i - 1 ]
95
+ if ( / ^ ( ' | " ) / . test ( current ) && RegExp . $1 === prev . slice ( - 1 ) ) {
96
+ strings [ j ] = [ strings [ j ] . slice ( 0 , - 1 ) , value , current . slice ( 1 ) ] . join ( '`' )
97
+ } else {
98
+ if ( value instanceof SQLStatement ) {
99
+ push ( strings , values , value , false )
100
+ j = strings . length - 1
101
+ strings [ j ] += current
102
+ } else {
103
+ values . push ( value )
104
+ j = strings . push ( current ) - 1
105
+ }
106
+ prev = strings [ j ]
107
+ }
108
+ }
109
+ return new SQLStatement ( strings , values )
84
110
}
85
111
86
112
module . exports = SQL
0 commit comments