@@ -110,63 +110,68 @@ function getFirstSplitOffset(buffer: Buffer, split = '\n'): number {
110110 return - 1 ;
111111}
112112
113- function parseNumberNext < T = number > (
113+ function parseNumber < T = number > (
114114 formatFn : ( string : string ) => T ,
115115 buffer : Buffer ,
116- ) : Column [ ] {
116+ ) : [ T , Buffer ] {
117117 const offset = getFirstSplitOffset ( buffer ) ;
118118 const val = formatFn ( buffer . subarray ( 0 , offset ) . toString ( 'utf-8' ) ) ;
119119
120- return parseNext ( val , buffer . subarray ( offset + 1 ) ) ;
120+ return [ val , buffer . subarray ( offset + 1 ) ] ;
121121}
122122
123- function parseNext ( val : any , buffer : Buffer ) : Column [ ] {
124- return [ val , ... parseSkytableData ( buffer ) ] ;
125- }
123+ function parseNextBySize ( size : number , buffer : Buffer ) : [ Column [ ] , Buffer ] {
124+ let values = [ ] ;
125+ let nextBuffer = buffer ;
126126
127- function parseSkytableData ( buffer : Buffer ) : Column [ ] {
128- if ( ! buffer . length ) {
129- return [ ] ;
127+ for ( let i = 0 ; i < size ; i ++ ) {
128+ const [ value , remainingBuffer ] = parseSingleVal ( nextBuffer ) ;
129+ values . push ( value ) ;
130+ nextBuffer = remainingBuffer ;
130131 }
131132
133+ return [ values , nextBuffer ] ;
134+ }
135+
136+ function parseSingleVal ( buffer : Buffer ) : [ Column , Buffer ] {
132137 const type = buffer . readUInt8 ( 0 ) ;
133138 buffer = buffer . subarray ( 1 ) ;
134139
135140 switch ( type ) {
136141 case RESPONSES_RESULT . NULL : // Null
137- return parseNext ( null , buffer . subarray ( 0 ) ) ;
142+ return [ null , buffer . subarray ( 0 ) ] ;
138143 case RESPONSES_RESULT . BOOL : // Bool
139- return parseNext ( Boolean ( buffer . readUInt8 ( 0 ) ) , buffer . subarray ( 1 ) ) ;
144+ return [ Boolean ( buffer . readUInt8 ( 0 ) ) , buffer . subarray ( 1 ) ] ;
140145 case RESPONSES_RESULT . U8INT : // 8-bit Unsigned Integer
141- return parseNumberNext ( Number , buffer ) ;
146+ return parseNumber ( Number , buffer ) ;
142147 case RESPONSES_RESULT . U16INT : // 16-bit Unsigned Integer
143- return parseNumberNext ( Number , buffer ) ;
148+ return parseNumber ( Number , buffer ) ;
144149 case RESPONSES_RESULT . U32INT : // 32-bit Unsigned Integer
145- return parseNumberNext ( Number , buffer ) ;
150+ return parseNumber ( Number , buffer ) ;
146151 case RESPONSES_RESULT . U64INT : // 64-bit Unsigned Integer
147- return parseNumberNext < bigint > ( BigInt , buffer ) ;
152+ return parseNumber < bigint > ( BigInt , buffer ) ;
148153 case RESPONSES_RESULT . S8INT : // 8-bit Signed Integer
149- return parseNumberNext ( Number , buffer ) ;
154+ return parseNumber ( Number , buffer ) ;
150155 case RESPONSES_RESULT . S16INT : // 16-bit Signed Integer
151- return parseNumberNext ( Number , buffer ) ;
156+ return parseNumber ( Number , buffer ) ;
152157 case RESPONSES_RESULT . S32INT : // 32-bit Signed Integer
153- return parseNumberNext ( Number , buffer ) ;
158+ return parseNumber ( Number , buffer ) ;
154159 case RESPONSES_RESULT . S64INT : // 64-bit Signed Integer
155- return parseNumberNext < bigint > ( BigInt , buffer ) ;
160+ return parseNumber < bigint > ( BigInt , buffer ) ;
156161 case RESPONSES_RESULT . FLOAT32 : // f32
157- return parseNumberNext ( Number . parseFloat , buffer ) ;
162+ return parseNumber ( Number . parseFloat , buffer ) ;
158163 case RESPONSES_RESULT . FLOAT64 : // f64
159- return parseNumberNext ( Number . parseFloat , buffer ) ;
164+ return parseNumber ( Number . parseFloat , buffer ) ;
160165 case RESPONSES_RESULT . BINARY : {
161166 // Binary <size>\n<payload>,
162167 const sizeOffset = getFirstSplitOffset ( buffer ) ;
163168 const size = Number ( buffer . subarray ( 0 , sizeOffset ) . toString ( 'utf-8' ) ) ;
164169 if ( size === 0 ) {
165- return parseNext ( Buffer . from ( [ ] ) , buffer . subarray ( sizeOffset + 1 ) ) ;
170+ return [ Buffer . from ( [ ] ) , buffer . subarray ( sizeOffset + 1 ) ] ;
166171 }
167172 const [ start , end ] = [ sizeOffset + 1 , sizeOffset + 1 + Number ( size ) ] ;
168173
169- return parseNext ( buffer . subarray ( start , end ) , buffer . subarray ( end ) ) ;
174+ return [ buffer . subarray ( start , end ) , buffer . subarray ( end ) ] ;
170175 }
171176 case RESPONSES_RESULT . STRING : {
172177 // String <size>\n<body>
@@ -175,16 +180,20 @@ function parseSkytableData(buffer: Buffer): Column[] {
175180 const [ start , end ] = [ sizeOffset + 1 , sizeOffset + 1 + Number ( size ) ] ;
176181 const str = buffer . subarray ( start , end ) . toString ( 'utf-8' ) ;
177182
178- return parseNext ( str , buffer . subarray ( end ) ) ;
183+ return [ str , buffer . subarray ( end ) ] ;
179184 }
180185 case RESPONSES_RESULT . LIST : {
181186 // List <size>\n<body>
182187 const sizeOffset = getFirstSplitOffset ( buffer ) ;
183188 const size = Number ( buffer . subarray ( 0 , sizeOffset ) . toString ( 'utf-8' ) ) ;
184189 if ( size === 0 ) {
185- return parseNext ( [ ] , buffer . subarray ( sizeOffset + 1 ) ) ;
190+ return [ [ ] , buffer . subarray ( sizeOffset + 1 ) ] ;
186191 }
187- return [ parseSkytableData ( buffer . subarray ( sizeOffset + 1 ) ) as Column ] ;
192+
193+ return parseNextBySize ( size , buffer . subarray ( sizeOffset + 1 ) ) as [
194+ Column ,
195+ Buffer ,
196+ ] ;
188197 }
189198 default :
190199 throw new Error ( `Unknown data type: ${ type } ` ) ;
@@ -193,10 +202,12 @@ function parseSkytableData(buffer: Buffer): Column[] {
193202
194203export function formatRow ( buffer : Buffer ) : Row {
195204 const offset = getFirstSplitOffset ( buffer ) ;
196- // const columnCount = Number(buffer.subarray(0, offset).toString(" utf-8"))
205+ const columnCount = Number ( buffer . subarray ( 0 , offset ) . toString ( ' utf-8' ) ) ;
197206 const dataType = buffer . subarray ( offset + 1 ) ;
198207
199- return parseSkytableData ( dataType ) ;
208+ const [ row ] = parseNextBySize ( columnCount , dataType ) ;
209+
210+ return row ;
200211}
201212
202213export function formatRows ( buffer : Buffer ) : Rows {
@@ -209,15 +220,17 @@ export function formatRows(buffer: Buffer): Rows {
209220 const columnCount = Number (
210221 buffer . subarray ( 0 , columnOffset ) . toString ( 'utf-8' ) ,
211222 ) ;
212- const tableData : Column [ ] = parseSkytableData ( buffer . subarray ( offset + 1 ) ) ;
223+
224+ buffer = buffer . subarray ( columnOffset + 1 ) ;
213225
214226 const result : Rows = [ ] ;
227+ let nextBuffer = buffer ;
215228
216229 for ( let i = 0 ; i < rowCount ; i ++ ) {
217- result [ i ] = [ ] ;
218- for ( let j = 0 ; j < columnCount ; j ++ ) {
219- result [ i ] [ j ] = tableData [ i * columnCount + j ] ;
220- }
230+ const [ row , remainingBuffer ] = parseNextBySize ( columnCount , nextBuffer ) ;
231+
232+ result [ i ] = row ;
233+ nextBuffer = remainingBuffer ;
221234 }
222235
223236 return result ;
@@ -239,9 +252,9 @@ export function formatResponse(buffer: Buffer): QueryResult {
239252 ) ;
240253 default :
241254 if ( isResponsesResult ( type ) ) {
242- const result = parseSkytableData ( buffer ) ;
243- // FIXME to be better
244- return result ?. [ 0 ] ;
255+ const [ val ] = parseSingleVal ( buffer ) ;
256+
257+ return val ;
245258 }
246259 throw new TypeError ( 'unknown response type' ) ;
247260 }
0 commit comments