@@ -76,6 +76,110 @@ export function mapResultRow<TResult>(
7676 return result as TResult ;
7777}
7878
79+ /** @internal */
80+ function makeJitQueryMapperInner (
81+ columns : SelectedFieldsOrdered < AnyColumn > ,
82+ joinsNotNullableMap : Record < string , boolean > | undefined ,
83+ ) : string {
84+ let fn = [ ] ;
85+ if ( joinsNotNullableMap ) fn . push ( `const nullifyMap = {};` ) ;
86+
87+ const initializedPaths = new Set < string > ( ) ;
88+
89+ for ( const [ idx , { path : pathArr , field, codec } ] of columns . entries ( ) ) {
90+ const pathPrefix = pathArr . slice ( 0 , - 1 ) ;
91+ const path = pathArr . map ( ( e ) => `[${ JSON . stringify ( e ) } ]` ) . join ( '' ) ;
92+
93+ let processedPath ;
94+ for ( const p of pathPrefix ) {
95+ processedPath = processedPath ? `${ p } [${ JSON . stringify ( p ) } ]` : JSON . stringify ( p ) ;
96+ if ( initializedPaths . has ( processedPath ) ) continue ;
97+ fn . push ( `res[${ processedPath } ] = {};` ) ;
98+ initializedPaths . add ( processedPath ) ;
99+ }
100+
101+ let decoder : DriverValueDecoder < unknown , unknown > ;
102+ let decoderStr : string ;
103+ if ( is ( field , Column ) ) {
104+ decoder = field ;
105+ decoderStr = `columns[${ idx } ].field.mapFromDriverValue` ;
106+ } else if ( is ( field , SQL ) ) {
107+ decoder = field . decoder ;
108+ decoderStr = `columns[${ idx } ].field.decoder.mapFromDriverValue` ;
109+ } else if ( is ( field , Subquery ) ) {
110+ decoder = field . _ . sql . decoder ;
111+ decoderStr = `columns[${ idx } ].field._.sql.decoder.mapFromDriverValue` ;
112+ } else {
113+ decoder = field . sql . decoder ;
114+ decoderStr = `columns[${ idx } ].field.sql.decoder.mapFromDriverValue` ;
115+ }
116+ if ( decoder . mapFromDriverValue . isNoop ) decoderStr = '' ;
117+ const rowStr = `rows[i][${ idx } ]` ;
118+
119+ fn . push (
120+ ` res${ path } = ${ rowStr } === null ? ${ rowStr } : ${
121+ decoderStr
122+ ? `${ decoderStr } (${ codec ? `columns[${ idx } ].codec(${ rowStr } , columns[${ idx } ].arrayDimensions)` : rowStr } )`
123+ : codec
124+ ? `columns[${ idx } ].codec(${ rowStr } , columns[${ idx } ].arrayDimensions)`
125+ : rowStr
126+ } ;`,
127+ ) ;
128+
129+ if ( joinsNotNullableMap && is ( field , Column ) && pathArr . length === 2 ) {
130+ const objectName = JSON . stringify ( pathArr [ 0 ] ! ) ;
131+ fn . push (
132+ `if (!(${ objectName } in nullifyMap)) {` ,
133+ ` nullifyMap[${ objectName } ] = res${ path } === null ? this.getTableName(columns[${ idx } ].field.table) : false;` ,
134+ `} else if (typeof nullifyMap[${ objectName } ] === 'string' && nullifyMap[${ objectName } ] !== this.getTableName(columns[${ idx } ].field.table)) {` ,
135+ ` nullifyMap[${ objectName } ] = false;` ,
136+ `}` ,
137+ ) ;
138+ }
139+ }
140+
141+ if ( joinsNotNullableMap ) {
142+ fn . push (
143+ `if(Object.keys(nullifyMap).length) {` ,
144+ ` for (const [objectName, tableName] of Object.entries(nullifyMap)) {` ,
145+ ` if (typeof tableName === 'string' && !joinsNotNullableMap[tableName]) {` ,
146+ ` res[objectName] = null;` ,
147+ ` }` ,
148+ ` }` ,
149+ `}` ,
150+ ) ;
151+ }
152+
153+ return fn . join ( '\n' ) ;
154+ }
155+
156+ export type JitMapper < TResult = Record < string , unknown > [ ] > = (
157+ rows : unknown [ ] [ ] ,
158+ columns : SelectedFieldsOrdered < AnyColumn > ,
159+ joinsNotNullableMap : Record < string , boolean > | undefined ,
160+ ) => TResult ;
161+
162+ /** @internal */
163+ export function makeJitQueryMapper < TResult > (
164+ columns : SelectedFieldsOrdered < AnyColumn > ,
165+ joinsNotNullableMap : Record < string , boolean > | undefined ,
166+ ) : JitMapper < TResult > {
167+ return new Function (
168+ 'rows' ,
169+ 'columns' ,
170+ 'joinsNotNullableMap' ,
171+ `const mapped = [];
172+ for (let i = 0; i < rows.length; ++i) {
173+ const res = {};
174+ ${ makeJitQueryMapperInner ( columns , joinsNotNullableMap ) }
175+ mapped[i] = res;
176+ }
177+ return mapped;` ,
178+ ) . bind ( {
179+ getTableName,
180+ } ) as any ;
181+ }
182+
79183/** @internal */
80184export function orderSelectedFields < TColumn extends AnyColumn > (
81185 fields : Record < string , unknown > ,
0 commit comments