33//
44
55import { SQLiteCloudRowset } from './rowset'
6- import { SAFE_INTEGER_MODE , SQLiteCloudCommand , SQLiteCloudError , type SQLCloudRowsetMetadata , type SQLiteCloudDataTypes } from './types'
6+ import {
7+ SAFE_INTEGER_MODE ,
8+ SQLiteCloudCommand ,
9+ SQLiteCloudError ,
10+ type SQLCloudRowsetMetadata ,
11+ type SQLiteCloudDataTypes ,
12+ type SQLiteCloudSafeIntegerMode
13+ } from './types'
714import { getSafeBuffer } from './safe-imports'
815
916// explicitly importing buffer library to allow cross-platform support by replacing it
@@ -125,15 +132,15 @@ export function parseError(buffer: Buffer, spaceIndex: number): never {
125132}
126133
127134/** Parse an array of items (each of which will be parsed by type separately) */
128- export function parseArray ( buffer : Buffer , spaceIndex : number ) : SQLiteCloudDataTypes [ ] {
135+ export function parseArray ( buffer : Buffer , spaceIndex : number , safeIntegerMode : SQLiteCloudSafeIntegerMode = SAFE_INTEGER_MODE ) : SQLiteCloudDataTypes [ ] {
129136 const parsedData = [ ]
130137
131138 const array = buffer . subarray ( spaceIndex + 1 , buffer . length )
132139 const numberOfItems = parseInt ( array . subarray ( 0 , spaceIndex - 2 ) . toString ( 'utf8' ) )
133140 let arrayItems = array . subarray ( array . indexOf ( ' ' ) + 1 , array . length )
134141
135142 for ( let i = 0 ; i < numberOfItems ; i ++ ) {
136- const { data, fwdBuffer : buffer } = popData ( arrayItems )
143+ const { data, fwdBuffer : buffer } = popData ( arrayItems , safeIntegerMode )
137144 parsedData . push ( data )
138145 arrayItems = buffer
139146 }
@@ -165,9 +172,9 @@ export function parseRowsetHeader(buffer: Buffer): { index: number; metadata: SQ
165172}
166173
167174/** Extract column names and, optionally, more metadata out of a rowset's header */
168- function parseRowsetColumnsMetadata ( buffer : Buffer , metadata : SQLCloudRowsetMetadata ) : Buffer {
175+ function parseRowsetColumnsMetadata ( buffer : Buffer , metadata : SQLCloudRowsetMetadata , safeIntegerMode : SQLiteCloudSafeIntegerMode ) : Buffer {
169176 function popForward ( ) {
170- const { data, fwdBuffer : fwdBuffer } = popData ( buffer ) // buffer in parent scope
177+ const { data, fwdBuffer : fwdBuffer } = popData ( buffer , safeIntegerMode ) // buffer in parent scope
171178 buffer = fwdBuffer
172179 return data
173180 }
@@ -192,16 +199,16 @@ function parseRowsetColumnsMetadata(buffer: Buffer, metadata: SQLCloudRowsetMeta
192199}
193200
194201/** Parse a regular rowset (no chunks) */
195- function parseRowset ( buffer : Buffer , spaceIndex : number ) : SQLiteCloudRowset {
202+ function parseRowset ( buffer : Buffer , spaceIndex : number , safeIntegerMode : SQLiteCloudSafeIntegerMode ) : SQLiteCloudRowset {
196203 buffer = buffer . subarray ( spaceIndex + 1 , buffer . length )
197204
198205 const { metadata, fwdBuffer } = parseRowsetHeader ( buffer )
199- buffer = parseRowsetColumnsMetadata ( fwdBuffer , metadata )
206+ buffer = parseRowsetColumnsMetadata ( fwdBuffer , metadata , safeIntegerMode )
200207
201208 // decode each rowset item
202209 const data = [ ]
203210 for ( let j = 0 ; j < metadata . numberOfRows * metadata . numberOfColumns ; j ++ ) {
204- const { data : rowData , fwdBuffer } = popData ( buffer )
211+ const { data : rowData , fwdBuffer } = popData ( buffer , safeIntegerMode )
205212 data . push ( rowData )
206213 buffer = fwdBuffer
207214 }
@@ -223,7 +230,7 @@ export function bufferEndsWith(buffer: Buffer, suffix: string): boolean {
223230 * *LEN 0:VERS NROWS NCOLS DATA
224231 * @see https://github.com/sqlitecloud/sdk/blob/master/PROTOCOL.md#scsp-rowset-chunk
225232 */
226- export function parseRowsetChunks ( buffers : Buffer [ ] ) : SQLiteCloudRowset {
233+ export function parseRowsetChunks ( buffers : Buffer [ ] , safeIntegerMode : SQLiteCloudSafeIntegerMode = SAFE_INTEGER_MODE ) : SQLiteCloudRowset {
227234 let buffer = Buffer . concat ( buffers )
228235 if ( ! bufferStartsWith ( buffer , CMD_ROWSET_CHUNK ) || ! bufferEndsWith ( buffer , ROWSET_CHUNKS_END ) ) {
229236 throw new Error ( 'SQLiteCloudConnection.parseRowsetChunks - invalid chunks buffer' )
@@ -245,14 +252,14 @@ export function parseRowsetChunks(buffers: Buffer[]): SQLiteCloudRowset {
245252 // first chunk? extract columns metadata
246253 if ( chunkIndex === 1 ) {
247254 metadata = chunkMetadata
248- buffer = parseRowsetColumnsMetadata ( buffer , metadata )
255+ buffer = parseRowsetColumnsMetadata ( buffer , metadata , safeIntegerMode )
249256 } else {
250257 metadata . numberOfRows += chunkMetadata . numberOfRows
251258 }
252259
253260 // extract single rowset row
254261 for ( let k = 0 ; k < chunkMetadata . numberOfRows * metadata . numberOfColumns ; k ++ ) {
255- const { data : itemData , fwdBuffer } = popData ( buffer )
262+ const { data : itemData , fwdBuffer } = popData ( buffer , safeIntegerMode )
256263 data . push ( itemData )
257264 buffer = fwdBuffer
258265 }
@@ -276,7 +283,10 @@ function popIntegers(buffer: Buffer, numberOfIntegers = 1): { data: number[]; fw
276283}
277284
278285/** Parse command, extract its data, return the data and the buffer moved to the first byte after the command */
279- export function popData ( buffer : Buffer ) : { data : SQLiteCloudDataTypes | SQLiteCloudRowset ; fwdBuffer : Buffer } {
286+ export function popData (
287+ buffer : Buffer ,
288+ safeIntegerMode : SQLiteCloudSafeIntegerMode = SAFE_INTEGER_MODE
289+ ) : { data : SQLiteCloudDataTypes | SQLiteCloudRowset ; fwdBuffer : Buffer } {
280290 function popResults ( data : any ) {
281291 const fwdBuffer = buffer . subarray ( commandEnd )
282292 return { data, fwdBuffer }
@@ -307,10 +317,10 @@ export function popData(buffer: Buffer): { data: SQLiteCloudDataTypes | SQLiteCl
307317 case CMD_INT :
308318 // SQLite uses 64-bit INTEGER, but JS uses 53-bit Number
309319 const value = BigInt ( buffer . subarray ( 1 , spaceIndex ) . toString ( ) )
310- if ( SAFE_INTEGER_MODE === 'bigint' ) {
320+ if ( safeIntegerMode === 'bigint' ) {
311321 return popResults ( value )
312322 }
313- if ( SAFE_INTEGER_MODE === 'mixed' ) {
323+ if ( safeIntegerMode === 'mixed' ) {
314324 if ( value <= BigInt ( Number . MIN_SAFE_INTEGER ) || BigInt ( Number . MAX_SAFE_INTEGER ) <= value ) {
315325 return popResults ( value )
316326 }
@@ -333,9 +343,9 @@ export function popData(buffer: Buffer): { data: SQLiteCloudDataTypes | SQLiteCl
333343 case CMD_BLOB :
334344 return popResults ( buffer . subarray ( spaceIndex + 1 , commandEnd ) )
335345 case CMD_ARRAY :
336- return popResults ( parseArray ( buffer , spaceIndex ) )
346+ return popResults ( parseArray ( buffer , spaceIndex , safeIntegerMode ) )
337347 case CMD_ROWSET :
338- return popResults ( parseRowset ( buffer , spaceIndex ) )
348+ return popResults ( parseRowset ( buffer , spaceIndex , safeIntegerMode ) )
339349 case CMD_ERROR :
340350 parseError ( buffer , spaceIndex ) // throws custom error
341351 break
0 commit comments