@@ -7,6 +7,7 @@ import { instanceOf } from './instance-of';
7
7
import './polyfills' ;
8
8
import { ObjectNameValidator } from './object-name.validator' ;
9
9
import { isNameReference , trimNameReference } from './name-reference' ;
10
+ import { JSONArray , JSONObject } from '@themost/json' ;
10
11
11
12
class AbstractMethodError extends Error {
12
13
constructor ( ) {
@@ -133,6 +134,9 @@ class SqlFormatter {
133
134
return SqlUtils . escape ( null ) ;
134
135
135
136
if ( typeof value === 'object' ) {
137
+ if ( value instanceof JSONArray || value instanceof JSONObject ) {
138
+ return SqlUtils . escape ( value . toString ( ) ) ;
139
+ }
136
140
//add an exception for Date object
137
141
if ( value instanceof Date )
138
142
return SqlUtils . escape ( value ) ;
@@ -747,17 +751,28 @@ class SqlFormatter {
747
751
const queryEntity = item ;
748
752
sqlSelect = this . escapeEntity ( queryEntity . name ) ;
749
753
// get alias
750
- sqlAlias = queryEntity . $alias ;
754
+ sqlAlias = queryEntity . $alias ? this . escapeName ( queryEntity . $alias ) : null ;
751
755
} else if ( typeof item === 'string' ) {
752
756
sqlSelect = this . escapeEntity ( item )
753
757
} else {
754
- /**
755
- * @type {QueryExpression }
756
- */
757
- const queryExpression = item ;
758
- // get alias
759
- sqlAlias = queryExpression . $alias ;
760
- sqlSelect = '(' + this . format ( queryExpression ) + ')' ;
758
+ // try to validate if item is a query expression with a single field
759
+ // e.g. { paymentMethods: { $jsonEach: 'paymentMethods' } }
760
+ // which is equivalent to SELECT json_each(paymentMethods) AS paymentMethods
761
+ const [ key ] = Object . keys ( item ) ;
762
+ if ( Object . prototype . hasOwnProperty . call ( item [ key ] , '$jsonEach' ) ) {
763
+ sqlSelect = $this . escape ( item ) ;
764
+ sqlAlias = this . escapeName ( key ) ;
765
+ } else if ( Object . prototype . hasOwnProperty . call ( item , '$select' ) ) {
766
+ /**
767
+ * @type {QueryExpression }
768
+ */
769
+ const queryExpression = item ;
770
+ // get alias
771
+ sqlAlias = queryExpression . $alias ? this . escapeName ( queryExpression . $alias ) : null ;
772
+ sqlSelect = '(' + this . format ( queryExpression ) + ')' ;
773
+ } else {
774
+ throw new Error ( 'Invalid additional select expression.' ) ;
775
+ }
761
776
}
762
777
if ( sqlAlias ) {
763
778
if ( aliasKeyword ) {
@@ -1009,15 +1024,15 @@ class SqlFormatter {
1009
1024
* @type {SqlFormatter }
1010
1025
*/
1011
1026
const formatter = new FormatterCtor ( ) ;
1012
- for ( var key in select ) {
1027
+ for ( let key in select ) {
1013
1028
if ( Object . prototype . hasOwnProperty . call ( select , key ) ) {
1014
- var selectFields = select [ key ] ;
1029
+ const selectFields = select [ key ] ;
1015
1030
fields = selectFields . map ( function ( selectField ) {
1016
1031
let name ;
1017
1032
if ( selectField instanceof QueryField ) {
1018
1033
name = selectField . as ( ) || selectField . getName ( ) ;
1019
1034
} else {
1020
- var field = new QueryField ( selectField ) ;
1035
+ const field = new QueryField ( selectField ) ;
1021
1036
name = field . as ( ) || field . getName ( ) ;
1022
1037
}
1023
1038
if ( name == null ) {
@@ -1191,7 +1206,7 @@ class SqlFormatter {
1191
1206
if ( isNil ( obj ) )
1192
1207
return null ;
1193
1208
//if a format is defined
1194
- if ( s !== undefined ) {
1209
+ if ( typeof s === 'string' ) {
1195
1210
if ( ( s === '%f' ) || ( s === '%ff' ) ) {
1196
1211
//field formatting
1197
1212
let field = new QueryField ( ) ;
@@ -1201,11 +1216,12 @@ class SqlFormatter {
1201
1216
else
1202
1217
field = Object . assign ( new QueryField ( ) , obj ) ;
1203
1218
return this . formatFieldEx ( field , s ) ;
1204
- }
1205
- else if ( s === '%o' ) {
1219
+ } else if ( s === '%o' ) {
1206
1220
if ( instanceOf ( obj , QueryExpression ) )
1207
1221
return this . formatOrder ( obj . $order ) ;
1208
1222
return this . formatOrder ( obj ) ;
1223
+ } else {
1224
+ throw new Error ( 'Invalid format expression.' ) ;
1209
1225
}
1210
1226
}
1211
1227
@@ -1220,27 +1236,32 @@ class SqlFormatter {
1220
1236
query = Object . assign ( new QueryExpression ( ) , obj ) ;
1221
1237
}
1222
1238
//format query
1223
- if ( isObject ( query . $select ) ) {
1239
+ const filtered = typeof query . $where === 'object' || typeof query . $prepared === 'object' ;
1240
+ if ( typeof query . $select === 'object' ) {
1224
1241
if ( isString ( query . $count ) ) {
1225
1242
return this . formatCount ( query ) ;
1226
1243
}
1227
1244
if ( ! query . hasPaging ( ) )
1228
1245
return this . formatSelect ( query ) ;
1229
-
1230
1246
else
1231
1247
return this . formatLimitSelect ( query ) ;
1232
- }
1233
- else if ( isObject ( query . $insert ) )
1248
+ } else if ( typeof query . $insert === 'object' ) {
1234
1249
return this . formatInsert ( query ) ;
1235
- else if ( isObject ( query . $update ) )
1250
+ } else if ( typeof query . $update === 'object' ) {
1251
+ if ( filtered === false ) {
1252
+ throw new Error ( 'Invalid update expression. Expected a valid where clause.' ) ;
1253
+ }
1236
1254
return this . formatUpdate ( query ) ;
1237
- else if ( query . $delete !== null )
1255
+ } else if ( typeof query . $delete === 'object' || typeof query . $delete === 'string' ) {
1256
+ if ( filtered === false ) {
1257
+ throw new Error ( 'Invalid delete expression. Expected a valid where clause.' ) ;
1258
+ }
1238
1259
return this . formatDelete ( query ) ;
1239
- else if ( query . $where !== null )
1260
+ } else if ( typeof query . $where === 'object' ) {
1240
1261
return this . formatWhere ( query . $where ) ;
1241
-
1242
- else
1243
- return null ;
1262
+ } else {
1263
+ throw new Error ( 'Invalid source expression. Expected a valid query expression.' ) ;
1264
+ }
1244
1265
1245
1266
}
1246
1267
$eq ( left , right ) {
0 commit comments