@@ -34,6 +34,12 @@ class BufferReader {
3434 return result ;
3535 }
3636
37+ public byte ( ) {
38+ const result = this . buffer [ this . offset ] ;
39+ this . offset ++ ;
40+ return result ;
41+ }
42+
3743 public int32 ( ) {
3844 const result = this . buffer . readInt32BE ( this . offset ) ;
3945 this . offset += 4 ;
@@ -102,6 +108,11 @@ const emptyQuery = {
102108 length : 4 ,
103109}
104110
111+ const copyDone = {
112+ name : 'copyDone' ,
113+ length : 4 ,
114+ }
115+
105116enum MessageCodes {
106117 DataRow = 0x44 , // D
107118 ParseComplete = 0x31 , // 1
@@ -120,6 +131,10 @@ enum MessageCodes {
120131 PortalSuspended = 0x73 , // s
121132 ReplicationStart = 0x57 , // W
122133 EmptyQuery = 0x49 , // I
134+ CopyIn = 0x47 , // G
135+ CopyOut = 0x48 , // H
136+ CopyDone = 0x63 , // c
137+ CopyData = 0x64 , // d
123138}
124139
125140export class PgPacketStream extends Transform {
@@ -187,6 +202,9 @@ export class PgPacketStream extends Transform {
187202 case MessageCodes . PortalSuspended :
188203 this . emit ( 'message' , portalSuspended ) ;
189204 break ;
205+ case MessageCodes . CopyDone :
206+ this . emit ( 'message' , copyDone ) ;
207+ break ;
190208 case MessageCodes . CommandComplete :
191209 this . parseCommandCompleteMessage ( offset , length , bytes ) ;
192210 break ;
@@ -220,6 +238,15 @@ export class PgPacketStream extends Transform {
220238 case MessageCodes . RowDescriptionMessage :
221239 this . parseRowDescriptionMessage ( offset , length , bytes ) ;
222240 break ;
241+ case MessageCodes . CopyIn :
242+ this . parseCopyInMessage ( offset , length , bytes ) ;
243+ break ;
244+ case MessageCodes . CopyOut :
245+ this . parseCopyOutMessage ( offset , length , bytes ) ;
246+ break ;
247+ case MessageCodes . CopyData :
248+ this . parseCopyData ( offset , length , bytes ) ;
249+ break ;
223250 default :
224251 throw new Error ( 'unhanled code: ' + code . toString ( 16 ) )
225252 const packet = bytes . slice ( offset , CODE_LENGTH + length + offset )
@@ -244,6 +271,31 @@ export class PgPacketStream extends Transform {
244271 this . emit ( 'message' , message )
245272 }
246273
274+ private parseCopyData ( offset : number , length : number , bytes : Buffer ) {
275+ const chunk = bytes . slice ( offset , offset + ( length - 4 ) ) ;
276+ const message = new CopyDataMessage ( length , chunk ) ;
277+ this . emit ( 'message' , message )
278+ }
279+
280+ private parseCopyInMessage ( offset : number , length : number , bytes : Buffer ) {
281+ this . parseCopyMessage ( offset , length , bytes , 'copyInResponse' )
282+ }
283+
284+ private parseCopyOutMessage ( offset : number , length : number , bytes : Buffer ) {
285+ this . parseCopyMessage ( offset , length , bytes , 'copyOutResponse' )
286+ }
287+
288+ private parseCopyMessage ( offset : number , length : number , bytes : Buffer , messageName : string ) {
289+ this . reader . setBuffer ( offset , bytes ) ;
290+ const isBinary = this . reader . byte ( ) !== 0 ;
291+ const columnCount = this . reader . int16 ( )
292+ const message = new CopyResponse ( length , messageName , isBinary , columnCount ) ;
293+ for ( let i = 0 ; i < columnCount ; i ++ ) {
294+ message . columnTypes [ i ] = this . reader . int16 ( ) ;
295+ }
296+ this . emit ( 'message' , message ) ;
297+ }
298+
247299 private parseNotificationMessage ( offset : number , length : number , bytes : Buffer ) {
248300 this . reader . setBuffer ( offset , bytes ) ;
249301 const processId = this . reader . int32 ( ) ;
@@ -411,6 +463,20 @@ class DatabaseError extends Error {
411463 }
412464}
413465
466+ class CopyDataMessage {
467+ public readonly name = 'copyData' ;
468+ constructor ( public readonly length : number , public readonly chunk : Buffer ) {
469+
470+ }
471+ }
472+
473+ class CopyResponse {
474+ public readonly columnTypes : number [ ] ;
475+ constructor ( public readonly length : number , public readonly name : string , public readonly binary : boolean , columnCount : number ) {
476+ this . columnTypes = new Array ( columnCount ) ;
477+ }
478+ }
479+
414480class Field {
415481 constructor ( public readonly name : string , public readonly tableID : number , public readonly columnID : number , public readonly dataTypeID : number , public readonly dataTypeSize : number , public readonly dataTypeModifier : number , public readonly format : FieldFormat ) {
416482 }
0 commit comments