Skip to content

Commit 2c75581

Browse files
committed
Add driver.supportsTransactionConfig
1 parent 580d33d commit 2c75581

12 files changed

+175
-9
lines changed

src/driver.js

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,19 @@ class Driver {
123123
return connectionProvider.supportsMultiDb()
124124
}
125125

126+
/**
127+
* Returns whether the server supports transaction config capabilities based on the protocol
128+
* version negotiated via handshake.
129+
*
130+
* Note that this function call _always_ causes a round-trip to the server.
131+
*
132+
* @returns {Promise<boolean>} promise resolved with a boolean or rejected with error.
133+
*/
134+
supportsTransactionConfig () {
135+
const connectionProvider = this._getOrCreateConnectionProvider()
136+
return connectionProvider.supportsTransactionConfig()
137+
}
138+
126139
/**
127140
* Acquire a session to communicate with the database. The session will
128141
* borrow connections from the underlying connection pool as required and

src/internal/connection-provider-direct.js

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
import PooledConnectionProvider from './connection-provider-pooled'
2121
import DelegateConnection from './connection-delegate'
2222
import ChannelConnection from './connection-channel'
23-
import { BOLT_PROTOCOL_V4 } from './constants'
23+
import { BOLT_PROTOCOL_V4, BOLT_PROTOCOL_V3 } from './constants'
2424

2525
export default class DirectConnectionProvider extends PooledConnectionProvider {
2626
constructor ({ id, config, log, address, userAgent, authToken }) {
@@ -39,7 +39,7 @@ export default class DirectConnectionProvider extends PooledConnectionProvider {
3939
.then(connection => new DelegateConnection(connection, null))
4040
}
4141

42-
async supportsMultiDb () {
42+
async _hasProtocolVersion (versionPredicate) {
4343
const connection = ChannelConnection.create(
4444
this._address,
4545
this._config,
@@ -52,12 +52,24 @@ export default class DirectConnectionProvider extends PooledConnectionProvider {
5252

5353
const protocol = connection.protocol()
5454
if (protocol) {
55-
return protocol.version >= BOLT_PROTOCOL_V4
55+
return versionPredicate(protocol.version)
5656
}
5757

5858
return false
5959
} finally {
6060
await connection.close()
6161
}
6262
}
63+
64+
async supportsMultiDb () {
65+
return await this._hasProtocolVersion(
66+
version => version >= BOLT_PROTOCOL_V4
67+
)
68+
}
69+
70+
async supportsTransactionConfig () {
71+
return await this._hasProtocolVersion(
72+
version => version >= BOLT_PROTOCOL_V3
73+
)
74+
}
6375
}

src/internal/connection-provider-routing.js

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ import LeastConnectedLoadBalancingStrategy from './least-connected-load-balancin
3333
import Bookmark from './bookmark'
3434
import ChannelConnection from './connection-channel'
3535
import { int } from '../integer'
36-
import { BOLT_PROTOCOL_V4 } from './constants'
36+
import { BOLT_PROTOCOL_V4, BOLT_PROTOCOL_V3 } from './constants'
3737

3838
const UNAUTHORIZED_ERROR_CODE = 'Neo.ClientError.Security.Unauthorized'
3939
const DATABASE_NOT_FOUND_ERROR_CODE =
@@ -152,7 +152,7 @@ export default class RoutingConnectionProvider extends PooledConnectionProvider
152152
}
153153
}
154154

155-
async supportsMultiDb () {
155+
async _hasProtocolVersion (versionPredicate) {
156156
const addresses = await this._resolveSeedRouter(this._seedRouter)
157157

158158
let lastError
@@ -169,7 +169,7 @@ export default class RoutingConnectionProvider extends PooledConnectionProvider
169169

170170
const protocol = connection.protocol()
171171
if (protocol) {
172-
return protocol.version >= BOLT_PROTOCOL_V4
172+
return versionPredicate(protocol.version)
173173
}
174174

175175
return false
@@ -187,6 +187,18 @@ export default class RoutingConnectionProvider extends PooledConnectionProvider
187187
return false
188188
}
189189

190+
async supportsMultiDb () {
191+
return await this._hasProtocolVersion(
192+
version => version >= BOLT_PROTOCOL_V4
193+
)
194+
}
195+
196+
async supportsTransactionConfig () {
197+
return await this._hasProtocolVersion(
198+
version => version >= BOLT_PROTOCOL_V3
199+
)
200+
}
201+
190202
forget (address, database) {
191203
if (database || database === '') {
192204
this._routingTables[database].forget(address)

src/internal/connection-provider.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,16 @@ export default class ConnectionProvider {
4848
throw new Error('not implemented')
4949
}
5050

51+
/**
52+
* This method checks whether the backend database supports transaction config functionality
53+
* by checking protocol handshake result.
54+
*
55+
* @returns {Promise<boolean>}
56+
*/
57+
supportsTransactionConfig () {
58+
throw new Error('not implemented')
59+
}
60+
5161
/**
5262
* Closes this connection provider along with its internals (connections, pools, etc.)
5363
*

test/internal/node/direct.driver.boltkit.test.js

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -418,7 +418,7 @@ describe('#stub-direct direct driver with stub server', () => {
418418
}
419419

420420
const server = await boltStub.start(
421-
`./test/resources/boltstub/${version}/supports_multi_db.script`,
421+
`./test/resources/boltstub/${version}/supports_protocol_version.script`,
422422
9001
423423
)
424424

@@ -447,6 +447,44 @@ describe('#stub-direct direct driver with stub server', () => {
447447
})
448448
})
449449

450+
describe('should report whether transaction config is supported', () => {
451+
async function verifySupportsTransactionConfig (version, expected) {
452+
if (!boltStub.supported) {
453+
return
454+
}
455+
456+
const server = await boltStub.start(
457+
`./test/resources/boltstub/${version}/supports_protocol_version.script`,
458+
9001
459+
)
460+
461+
const driver = boltStub.newDriver('bolt://127.0.0.1:9001')
462+
463+
await expectAsync(driver.supportsTransactionConfig()).toBeResolvedTo(
464+
expected
465+
)
466+
467+
await driver.close()
468+
await server.exit()
469+
}
470+
471+
it('v1', () => verifySupportsTransactionConfig('v1', false))
472+
it('v2', () => verifySupportsTransactionConfig('v2', false))
473+
it('v3', () => verifySupportsTransactionConfig('v3', true))
474+
it('v4', () => verifySupportsTransactionConfig('v4', true))
475+
it('on error', async () => {
476+
const driver = boltStub.newDriver('bolt://127.0.0.1:9001')
477+
478+
await expectAsync(driver.supportsTransactionConfig()).toBeRejectedWith(
479+
jasmine.objectContaining({
480+
code: SERVICE_UNAVAILABLE
481+
})
482+
)
483+
484+
await driver.close()
485+
})
486+
})
487+
450488
describe('should allow to change fetch size', () => {
451489
async function verifyFailureOnCommit (version) {
452490
if (!boltStub.supported) {

test/internal/node/routing.driver.boltkit.test.js

Lines changed: 77 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2339,7 +2339,7 @@ describe('#stub-routing routing driver with stub server', () => {
23392339
}
23402340

23412341
const server = await boltStub.start(
2342-
`./test/resources/boltstub/${version}/supports_multi_db.script`,
2342+
`./test/resources/boltstub/${version}/supports_protocol_version.script`,
23432343
9001
23442344
)
23452345

@@ -2357,7 +2357,7 @@ describe('#stub-routing routing driver with stub server', () => {
23572357
}
23582358

23592359
const server = await boltStub.start(
2360-
`./test/resources/boltstub/${version}/supports_multi_db.script`,
2360+
`./test/resources/boltstub/${version}/supports_protocol_version.script`,
23612361
9001
23622362
)
23632363

@@ -2396,6 +2396,81 @@ describe('#stub-routing routing driver with stub server', () => {
23962396
})
23972397
})
23982398

2399+
describe('should report whether transaction config is supported', () => {
2400+
async function verifySupportsTransactionConfig (version, expected) {
2401+
if (!boltStub.supported) {
2402+
return
2403+
}
2404+
2405+
const server = await boltStub.start(
2406+
`./test/resources/boltstub/${version}/supports_protocol_version.script`,
2407+
9001
2408+
)
2409+
2410+
const driver = boltStub.newDriver('neo4j://127.0.0.1:9001')
2411+
2412+
await expectAsync(driver.supportsTransactionConfig()).toBeResolvedTo(
2413+
expected
2414+
)
2415+
2416+
await driver.close()
2417+
await server.exit()
2418+
}
2419+
2420+
async function verifySupportsTransactionConfigWithResolver (
2421+
version,
2422+
expected
2423+
) {
2424+
if (!boltStub.supported) {
2425+
return
2426+
}
2427+
2428+
const server = await boltStub.start(
2429+
`./test/resources/boltstub/${version}/supports_protocol_version.script`,
2430+
9001
2431+
)
2432+
2433+
const driver = boltStub.newDriver('neo4j://127.0.0.1:8000', {
2434+
resolver: address => [
2435+
'neo4j://127.0.0.1:9010',
2436+
'neo4j://127.0.0.1:9005',
2437+
'neo4j://127.0.0.1:9001'
2438+
]
2439+
})
2440+
2441+
await expectAsync(driver.supportsTransactionConfig()).toBeResolvedTo(
2442+
expected
2443+
)
2444+
2445+
await driver.close()
2446+
await server.exit()
2447+
}
2448+
2449+
it('v1', () => verifySupportsTransactionConfig('v1', false))
2450+
it('v2', () => verifySupportsTransactionConfig('v2', false))
2451+
it('v3', () => verifySupportsTransactionConfig('v3', true))
2452+
it('v4', () => verifySupportsTransactionConfig('v4', true))
2453+
it('v1 with resolver', () =>
2454+
verifySupportsTransactionConfigWithResolver('v1', false))
2455+
it('v2 with resolver', () =>
2456+
verifySupportsTransactionConfigWithResolver('v2', false))
2457+
it('v3 with resolver', () =>
2458+
verifySupportsTransactionConfigWithResolver('v3', true))
2459+
it('v4 with resolver', () =>
2460+
verifySupportsTransactionConfigWithResolver('v4', true))
2461+
it('on error', async () => {
2462+
const driver = boltStub.newDriver('neo4j://127.0.0.1:9001')
2463+
2464+
await expectAsync(driver.supportsTransactionConfig()).toBeRejectedWith(
2465+
jasmine.objectContaining({
2466+
code: SESSION_EXPIRED
2467+
})
2468+
)
2469+
2470+
await driver.close()
2471+
})
2472+
})
2473+
23992474
async function testAddressPurgeOnDatabaseError (script, query, accessMode) {
24002475
if (!boltStub.supported) {
24012476
return

test/types/driver.test.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,10 @@ driver.supportsMultiDb().then((supported: boolean) => {
111111
console.log(`multi database is supported? => ${supported}`)
112112
})
113113

114+
driver.supportsTransactionConfig().then((supported: boolean) => {
115+
console.log(`transaction config is supported? => ${supported}`)
116+
})
117+
114118
const rxSession1: RxSession = driver.rxSession()
115119
const rxSession2: RxSession = driver.rxSession({ defaultAccessMode: READ })
116120
const rxSession3: RxSession = driver.rxSession({ defaultAccessMode: 'READ' })

types/driver.d.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,8 @@ declare interface Driver {
9595
verifyConnectivity(): Promise<ServerInfo>
9696

9797
supportsMultiDb(): Promise<boolean>
98+
99+
supportsTransactionConfig(): Promise<boolean>
98100
}
99101

100102
export {

0 commit comments

Comments
 (0)