1717'use strict' ;
1818
1919var codec = require ( './codec.js' ) ;
20+ var commonGrpc = require ( '@google-cloud/common-grpc' ) ;
2021var is = require ( 'is' ) ;
2122
2223/*!
@@ -25,11 +26,9 @@ var is = require('is');
2526 * @private
2627 * @class
2728 */
28- function RowBuilder ( metadata , chunks ) {
29- this . metadata = metadata ;
30- this . fields = this . metadata . rowType . fields ;
31- this . chunks = chunks ;
32-
29+ function RowBuilder ( fields ) {
30+ this . fields = fields ;
31+ this . chunks = [ ] ;
3332 this . rows = [ [ ] ] ;
3433
3534 Object . defineProperty ( this , 'currentRow' , {
@@ -46,7 +45,7 @@ RowBuilder.getValue = function(obj) {
4645 var value = obj ;
4746
4847 if ( obj && obj . kind ) {
49- value = obj [ obj . kind ] ;
48+ value = commonGrpc . Service . decodeValue_ ( obj ) ;
5049 }
5150
5251 if ( value && value . values ) {
@@ -72,11 +71,11 @@ RowBuilder.formatValue = function(field, value) {
7271 }
7372
7473 if ( field . code !== 'STRUCT' ) {
75- return value ;
74+ return codec . decode ( value , field ) ;
7675 }
7776
7877 return field . structType . fields . reduce ( function ( struct , field , index ) {
79- struct [ field . name ] = RowBuilder . formatValue ( field . type , value [ index ] ) ;
78+ struct [ field . name ] = RowBuilder . formatValue ( field , value [ index ] ) ;
8079 return struct ;
8180 } , { } ) ;
8281} ;
@@ -116,14 +115,20 @@ RowBuilder.merge = function(type, head, tail) {
116115 } ) ;
117116} ;
118117
118+ /**
119+ * Add a PartialResultSet response object to the pending rows.
120+ */
121+ RowBuilder . prototype . addRow = function ( row ) {
122+ this . chunks = this . chunks . concat ( row ) ;
123+ } ;
124+
119125/**
120126 * Appends element to row.
121127 */
122128RowBuilder . prototype . append = function ( value ) {
123129 if ( this . currentRow . length === this . fields . length ) {
124130 this . rows . push ( [ ] ) ;
125131 }
126-
127132 this . currentRow . push ( value ) ;
128133} ;
129134
@@ -132,35 +137,59 @@ RowBuilder.prototype.append = function(value) {
132137 */
133138RowBuilder . prototype . build = function ( ) {
134139 var self = this ;
135- var previousChunk ;
136140
137141 this . chunks . forEach ( function ( chunk ) {
138- if ( previousChunk && previousChunk . chunkedValue ) {
139- var type = self . fields [ self . currentRow . length - 1 ] . type ;
142+ // If we have a chunk to merge, merge the values now.
143+ if ( self . pendingChunk ) {
144+ var currentColumn = self . currentRow . length % self . fields . length ;
140145 var merged = RowBuilder . merge (
141- type ,
142- self . currentRow . pop ( ) ,
146+ self . fields [ currentColumn ] . type ,
147+ self . pendingChunk ,
143148 chunk . values . shift ( )
144149 ) ;
150+ chunk . values = merged . concat ( chunk . values ) ;
151+ delete self . pendingChunk ;
152+ }
145153
146- merged . forEach ( self . append . bind ( self ) ) ;
154+ // If the chunk is chunked, store the last value for merging with the next
155+ // chunk to be processed.
156+ if ( chunk . chunkedValue ) {
157+ self . pendingChunk = chunk . values . pop ( ) ;
147158 }
148159
149160 chunk . values . map ( RowBuilder . getValue ) . forEach ( self . append . bind ( self ) ) ;
150-
151- previousChunk = chunk ;
152161 } ) ;
162+
163+ // As chunks are now in rows, remove them.
164+ this . chunks . length = 0 ;
153165} ;
154166
155167/**
156- * Transforms values into JSON format .
168+ * Flush already complete rows .
157169 */
158- RowBuilder . prototype . toJSON = function ( ) {
159- this . build ( ) ;
170+ RowBuilder . prototype . flush = function ( ) {
171+ var rowsToReturn = this . rows ;
172+
173+ if (
174+ ! is . empty ( this . rows [ 0 ] ) &&
175+ this . currentRow . length !== this . fields . length
176+ ) {
177+ // Don't return the partial row. Hold onto it for the next iteration.
178+ this . rows = this . rows . splice ( - 1 ) ;
179+ } else {
180+ this . rows = [ [ ] ] ;
181+ }
182+
183+ return rowsToReturn ;
184+ } ;
160185
186+ /**
187+ * Transforms values into JSON format.
188+ */
189+ RowBuilder . prototype . toJSON = function ( rows ) {
161190 var fields = this . fields ;
162191
163- return this . rows . map ( function ( values ) {
192+ return rows . map ( function ( values ) {
164193 var formattedRow = [ ] ;
165194 var serializedRow = { } ;
166195
@@ -169,7 +198,7 @@ RowBuilder.prototype.toJSON = function() {
169198
170199 var column = {
171200 name : field . name ,
172- value : RowBuilder . formatValue ( field . type , value ) ,
201+ value : RowBuilder . formatValue ( field , value ) ,
173202 } ;
174203
175204 formattedRow . push ( column ) ;
0 commit comments