@@ -27,6 +27,7 @@ import StreamObserver from './stream-observer';
27
27
import { ServerVersion , VERSION_3_2_0 } from './server-version' ;
28
28
import Logger from './logger' ;
29
29
import ProtocolHandshaker from './protocol-handshaker' ;
30
+ import RequestMessage from './request-message' ;
30
31
31
32
let Channel ;
32
33
if ( NodeChannel . available ) {
@@ -40,13 +41,7 @@ else {
40
41
}
41
42
42
43
43
- // Signature bytes for each message type
44
- const INIT = 0x01 ; // 0000 0001 // INIT <user_agent>
45
- const ACK_FAILURE = 0x0E ; // 0000 1110 // ACK_FAILURE - unused
46
- const RESET = 0x0F ; // 0000 1111 // RESET
47
- const RUN = 0x10 ; // 0001 0000 // RUN <statement> <parameters>
48
- const DISCARD_ALL = 0x2F ; // 0010 1111 // DISCARD *
49
- const PULL_ALL = 0x3F ; // 0011 1111 // PULL *
44
+ // Signature bytes for each response message type
50
45
const SUCCESS = 0x70 ; // 0111 0000 // SUCCESS <metadata>
51
46
const RECORD = 0x71 ; // 0111 0001 // RECORD <value>
52
47
const IGNORED = 0x7E ; // 0111 1110 // IGNORED <metadata>
@@ -97,11 +92,9 @@ class Connection {
97
92
this . _chunker = new Chunker ( channel ) ;
98
93
this . _log = log ;
99
94
100
- const protocolHandshaker = new ProtocolHandshaker ( this . _ch , this . _chunker , this . _disableLosslessIntegers , this . _log ) ;
101
-
95
+ const protocolHandshaker = new ProtocolHandshaker ( this , channel , this . _chunker , this . _disableLosslessIntegers , this . _log ) ;
102
96
// initially assume that database supports latest Bolt version, create latest packer and unpacker
103
- this . _packer = protocolHandshaker . createLatestPacker ( ) ;
104
- this . _unpacker = protocolHandshaker . createLatestUnpacker ( ) ;
97
+ this . _protocol = protocolHandshaker . createLatestProtocol ( ) ;
105
98
106
99
this . _currentFailure = null ;
107
100
@@ -128,7 +121,7 @@ class Connection {
128
121
}
129
122
130
123
this . _dechunker . onmessage = ( buf ) => {
131
- this . _handleMessage ( this . _unpacker . unpack ( buf ) ) ;
124
+ this . _handleMessage ( this . _protocol . unpacker ( ) . unpack ( buf ) ) ;
132
125
} ;
133
126
134
127
if ( this . _log . isDebugEnabled ( ) ) {
@@ -138,6 +131,45 @@ class Connection {
138
131
protocolHandshaker . writeHandshakeRequest ( ) ;
139
132
}
140
133
134
+ /**
135
+ * Get the Bolt protocol for the connection.
136
+ * @return {BoltProtocol } the protocol.
137
+ */
138
+ protocol ( ) {
139
+ return this . _protocol ;
140
+ }
141
+
142
+ /**
143
+ * Write a message to the network channel.
144
+ * @param {RequestMessage } message the message to write.
145
+ * @param {StreamObserver } observer the response observer.
146
+ * @param {boolean } flush <code>true</code> if flush should happen after the message is written to the buffer.
147
+ */
148
+ write ( message , observer , flush ) {
149
+ if ( message . isInitializationMessage ) {
150
+ observer = this . _state . wrap ( observer ) ;
151
+ }
152
+
153
+ const queued = this . _queueObserver ( observer ) ;
154
+
155
+ if ( queued ) {
156
+ if ( this . _log . isDebugEnabled ( ) ) {
157
+ this . _log . debug ( `${ this } C: ${ message } ` ) ;
158
+ }
159
+
160
+ this . _protocol . packer ( ) . packStruct (
161
+ message . signature ,
162
+ message . fields . map ( field => this . _packable ( field ) ) ,
163
+ err => this . _handleFatalError ( err ) ) ;
164
+
165
+ this . _chunker . messageBoundary ( ) ;
166
+
167
+ if ( flush ) {
168
+ this . _chunker . flush ( ) ;
169
+ }
170
+ }
171
+ }
172
+
141
173
/**
142
174
* Complete protocol initialization.
143
175
* @param {BaseBuffer } buffer the handshake response buffer.
@@ -146,11 +178,8 @@ class Connection {
146
178
*/
147
179
_initializeProtocol ( buffer , protocolHandshaker ) {
148
180
try {
149
- const { packer, unpacker} = protocolHandshaker . readHandshakeResponse ( buffer ) ;
150
-
151
- // re-assign packer and unpacker because version might be lower than we initially assumed
152
- this . _packer = packer ;
153
- this . _unpacker = unpacker ;
181
+ // re-assign the protocol because version might be lower than we initially assumed
182
+ this . _protocol = protocolHandshaker . readHandshakeResponse ( buffer ) ;
154
183
155
184
// Ok, protocol running. Simply forward all messages to the dechunker
156
185
this . _ch . onmessage = buf => this . _dechunker . write ( buf ) ;
@@ -247,66 +276,13 @@ class Connection {
247
276
}
248
277
}
249
278
250
- /** Queue an INIT-message to be sent to the database */
251
- initialize ( clientName , token , observer ) {
252
- if ( this . _log . isDebugEnabled ( ) ) {
253
- this . _log . debug ( `${ this } C: INIT ${ clientName } {...}` ) ;
254
- }
255
- const initObserver = this . _state . wrap ( observer ) ;
256
- const queued = this . _queueObserver ( initObserver ) ;
257
- if ( queued ) {
258
- this . _packer . packStruct ( INIT , [ this . _packable ( clientName ) , this . _packable ( token ) ] ,
259
- ( err ) => this . _handleFatalError ( err ) ) ;
260
- this . _chunker . messageBoundary ( ) ;
261
- this . flush ( ) ;
262
- }
263
- }
264
-
265
- /** Queue a RUN-message to be sent to the database */
266
- run ( statement , params , observer ) {
267
- if ( this . _log . isDebugEnabled ( ) ) {
268
- this . _log . debug ( `${ this } C: RUN ${ statement } ${ JSON . stringify ( params ) } ` ) ;
269
- }
270
- const queued = this . _queueObserver ( observer ) ;
271
- if ( queued ) {
272
- this . _packer . packStruct ( RUN , [ this . _packable ( statement ) , this . _packable ( params ) ] ,
273
- ( err ) => this . _handleFatalError ( err ) ) ;
274
- this . _chunker . messageBoundary ( ) ;
275
- }
276
- }
277
-
278
- /** Queue a PULL_ALL-message to be sent to the database */
279
- pullAll ( observer ) {
280
- if ( this . _log . isDebugEnabled ( ) ) {
281
- this . _log . debug ( `${ this } C: PULL_ALL` ) ;
282
- }
283
- const queued = this . _queueObserver ( observer ) ;
284
- if ( queued ) {
285
- this . _packer . packStruct ( PULL_ALL , [ ] , ( err ) => this . _handleFatalError ( err ) ) ;
286
- this . _chunker . messageBoundary ( ) ;
287
- }
288
- }
289
-
290
- /** Queue a DISCARD_ALL-message to be sent to the database */
291
- discardAll ( observer ) {
292
- if ( this . _log . isDebugEnabled ( ) ) {
293
- this . _log . debug ( `${ this } C: DISCARD_ALL` ) ;
294
- }
295
- const queued = this . _queueObserver ( observer ) ;
296
- if ( queued ) {
297
- this . _packer . packStruct ( DISCARD_ALL , [ ] , ( err ) => this . _handleFatalError ( err ) ) ;
298
- this . _chunker . messageBoundary ( ) ;
299
- }
300
- }
301
-
302
279
/**
303
- * Send a RESET-message to the database. Mutes failure handling.
304
- * Message is immediately flushed to the network. Separate {@link Connection#flush()} call is not required.
280
+ * Send a RESET-message to the database. Message is immediately flushed to the network.
305
281
* @return {Promise<void> } promise resolved when SUCCESS-message response arrives, or failed when other response messages arrives.
306
282
*/
307
283
resetAndFlush ( ) {
308
284
return new Promise ( ( resolve , reject ) => {
309
- this . _reset ( {
285
+ this . _protocol . reset ( {
310
286
onNext : record => {
311
287
const neo4jError = this . _handleProtocolError ( 'Received RECORD as a response for RESET: ' + JSON . stringify ( record ) ) ;
312
288
reject ( neo4jError ) ;
@@ -328,7 +304,7 @@ class Connection {
328
304
}
329
305
330
306
_resetOnFailure ( ) {
331
- this . _reset ( {
307
+ this . _protocol . reset ( {
332
308
onNext : record => {
333
309
this . _handleProtocolError ( 'Received RECORD as a response for RESET: ' + JSON . stringify ( record ) ) ;
334
310
} ,
@@ -342,19 +318,6 @@ class Connection {
342
318
} ) ;
343
319
}
344
320
345
- _reset ( observer ) {
346
- if ( this . _log . isDebugEnabled ( ) ) {
347
- this . _log . debug ( `${ this } C: RESET` ) ;
348
- }
349
-
350
- const queued = this . _queueObserver ( observer ) ;
351
- if ( queued ) {
352
- this . _packer . packStruct ( RESET , [ ] , err => this . _handleFatalError ( err ) ) ;
353
- this . _chunker . messageBoundary ( ) ;
354
- this . flush ( ) ;
355
- }
356
- }
357
-
358
321
_queueObserver ( observer ) {
359
322
if ( this . _isBroken ) {
360
323
if ( observer && observer . onError ) {
@@ -376,7 +339,7 @@ class Connection {
376
339
377
340
/**
378
341
* Get promise resolved when connection initialization succeed or rejected when it fails.
379
- * Connection is initialized using {@link initialize} function.
342
+ * Connection is initialized using {@link BoltProtocol# initialize() } function.
380
343
* @return {Promise<Connection> } the result of connection initialization.
381
344
*/
382
345
initializationCompleted ( ) {
@@ -391,13 +354,6 @@ class Connection {
391
354
this . _currentObserver = this . _pendingObservers . shift ( ) ;
392
355
}
393
356
394
- /**
395
- * Flush all queued outgoing messages.
396
- */
397
- flush ( ) {
398
- this . _chunker . flush ( ) ;
399
- }
400
-
401
357
/** Check if this connection is in working condition */
402
358
isOpen ( ) {
403
359
return ! this . _isBroken && this . _ch . _open ;
@@ -419,7 +375,7 @@ class Connection {
419
375
}
420
376
421
377
_packable ( value ) {
422
- return this . _packer . packable ( value , ( err ) => this . _handleFatalError ( err ) ) ;
378
+ return this . _protocol . packer ( ) . packable ( value , ( err ) => this . _handleFatalError ( err ) ) ;
423
379
}
424
380
425
381
/**
@@ -431,7 +387,7 @@ class Connection {
431
387
this . server . version = serverVersion ;
432
388
const version = ServerVersion . fromString ( serverVersion ) ;
433
389
if ( version . compareTo ( VERSION_3_2_0 ) < 0 ) {
434
- this . _packer . disableByteArrays ( ) ;
390
+ this . _protocol . packer ( ) . disableByteArrays ( ) ;
435
391
}
436
392
}
437
393
}
0 commit comments