11var getSessionSingleton = require ( '../../../getSessionSingleton' ) ;
2+ var newParameterized = require ( '../../../query/newParameterized' ) ;
23
3- function newSingleCommandCore ( context , table , filter , alias ) {
4+ function newSingleCommandCore ( context , table , filter , alias , concurrencyState ) {
45 var c = { } ;
6+ var quote = getSessionSingleton ( context , 'quote' ) ;
7+ var engine = getSessionSingleton ( context , 'engine' ) ;
8+ var concurrency = buildConcurrencyChecks ( concurrencyState ) ;
9+ var parameters = filter . parameters ? filter . parameters . slice ( ) : [ ] ;
10+ if ( concurrency && concurrency . parameters . length > 0 )
11+ parameters = parameters . concat ( concurrency . parameters ) ;
512
613 c . sql = function ( ) {
714 var whereSql = filter . sql ( ) ;
15+ if ( concurrency && concurrency . sql ) {
16+ if ( whereSql )
17+ whereSql += ' AND ' + concurrency . sql ;
18+ else
19+ whereSql = concurrency . sql ;
20+ }
821 if ( whereSql )
922 whereSql = ' where ' + whereSql ;
1023 var deleteFromSql = getSessionSingleton ( context , 'deleteFromSql' ) ;
1124 return deleteFromSql ( table , alias , whereSql ) ;
1225 } ;
1326
14- c . parameters = filter . parameters ;
27+ c . parameters = parameters ;
1528
1629 return c ;
30+
31+ function buildConcurrencyChecks ( state ) {
32+ const columnsState = state && state . columns ;
33+ if ( ! columnsState )
34+ return ;
35+ const parts = [ ] ;
36+ const params = [ ] ;
37+ for ( let alias in columnsState ) {
38+ const columnState = columnsState [ alias ] ;
39+ if ( ! columnState || columnState . concurrency === 'overwrite' )
40+ continue ;
41+ const column = table [ alias ] ;
42+ if ( ! column )
43+ continue ;
44+ const encoded = ( engine === 'mysql' && column . tsType === 'JSONColumn' )
45+ ? encodeJsonValue ( columnState . oldValue , column )
46+ : column . encode ( context , columnState . oldValue ) ;
47+ const comparison = buildNullSafeComparison ( column , encoded ) ;
48+ if ( comparison . sql )
49+ parts . push ( comparison . sql ( ) ) ;
50+ if ( comparison . parameters . length > 0 )
51+ params . push ( ...comparison . parameters ) ;
52+ }
53+ if ( parts . length === 0 )
54+ return ;
55+ return { sql : parts . join ( ' AND ' ) , parameters : params } ;
56+ }
57+
58+ function buildNullSafeComparison ( column , encoded ) {
59+ const columnSql = quote ( column . _dbName ) ;
60+ if ( engine === 'pg' ) {
61+ return newParameterized ( columnSql + ' IS NOT DISTINCT FROM ' + encoded . sql ( ) , encoded . parameters ) ;
62+ }
63+ if ( engine === 'mysql' ) {
64+ return newParameterized ( columnSql + ' <=> ' + encoded . sql ( ) , encoded . parameters ) ;
65+ }
66+ if ( engine === 'sqlite' ) {
67+ return newParameterized ( columnSql + ' IS ' + encoded . sql ( ) , encoded . parameters ) ;
68+ }
69+ if ( engine === 'sap' && column . tsType === 'JSONColumn' ) {
70+ if ( encoded . sql ( ) === 'null' )
71+ return newParameterized ( columnSql + ' IS NULL' ) ;
72+ const casted = newParameterized ( 'CONVERT(VARCHAR(16384), ' + encoded . sql ( ) + ')' , encoded . parameters ) ;
73+ return newParameterized ( 'CONVERT(VARCHAR(16384), ' + columnSql + ')=' + casted . sql ( ) , casted . parameters ) ;
74+ }
75+ if ( engine === 'oracle' && column . tsType === 'JSONColumn' ) {
76+ if ( encoded . sql ( ) === 'null' )
77+ return newParameterized ( columnSql + ' IS NULL' ) ;
78+ const jsonValue = newParameterized ( 'JSON(' + encoded . sql ( ) + ')' , encoded . parameters ) ;
79+ return newParameterized ( 'JSON_EQUAL(' + columnSql + ', ' + jsonValue . sql ( ) + ')' , jsonValue . parameters ) ;
80+ }
81+ if ( encoded . sql ( ) === 'null' )
82+ return newParameterized ( columnSql + ' IS NULL' ) ;
83+ return newParameterized ( columnSql + '=' + encoded . sql ( ) , encoded . parameters ) ;
84+ }
85+
86+ function encodeJsonValue ( value , column ) {
87+ if ( engine === 'oracle' ) {
88+ if ( value === null || value === undefined )
89+ return newParameterized ( 'null' ) ;
90+ if ( isJsonObject ( value ) )
91+ return column . encode ( context , value ) ;
92+ if ( typeof value === 'boolean' || typeof value === 'number' )
93+ return newParameterized ( '?' , [ String ( value ) ] ) ;
94+ return newParameterized ( '?' , [ value ] ) ;
95+ }
96+ if ( engine === 'pg' ) {
97+ const jsonValue = JSON . stringify ( value === undefined ? null : value ) ;
98+ return newParameterized ( '?::jsonb' , [ jsonValue ] ) ;
99+ }
100+ if ( engine === 'mysql' ) {
101+ const jsonValue = JSON . stringify ( value === undefined ? null : value ) ;
102+ return newParameterized ( 'CAST(? AS JSON)' , [ jsonValue ] ) ;
103+ }
104+ if ( engine === 'sqlite' ) {
105+ if ( isJsonObject ( value ) ) {
106+ const jsonValue = JSON . stringify ( value ) ;
107+ return newParameterized ( '?' , [ jsonValue ] ) ;
108+ }
109+ if ( value === null || value === undefined )
110+ return newParameterized ( 'null' ) ;
111+ return newParameterized ( '?' , [ value ] ) ;
112+ }
113+ if ( engine === 'mssql' || engine === 'mssqlNative' ) {
114+ if ( isJsonObject ( value ) )
115+ return newParameterized ( 'JSON_QUERY(?)' , [ JSON . stringify ( value ) ] ) ;
116+ if ( value === null || value === undefined )
117+ return newParameterized ( 'null' ) ;
118+ return newParameterized ( '?' , [ String ( value ) ] ) ;
119+ }
120+ return column . encode ( context , value ) ;
121+ }
122+
123+ function isJsonObject ( value ) {
124+ return value && typeof value === 'object' ;
125+ }
17126}
18127
19- module . exports = newSingleCommandCore ;
128+ module . exports = newSingleCommandCore ;
0 commit comments