neo4j-driver 1.1.1 → 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +97 -35
- package/gulpfile.babel.js +15 -52
- package/lib/browser/neo4j-web.js +3882 -1919
- package/lib/browser/neo4j-web.min.js +16 -15
- package/lib/v1/driver.js +93 -93
- package/lib/v1/error.js +9 -0
- package/lib/v1/graph-types.js +12 -12
- package/lib/v1/index.js +53 -31
- package/lib/v1/internal/ch-config.js +87 -0
- package/lib/v1/internal/ch-dummy.js +6 -1
- package/lib/v1/internal/ch-node.js +50 -44
- package/lib/v1/internal/ch-websocket.js +9 -10
- package/lib/v1/internal/connection-holder.js +204 -0
- package/lib/v1/internal/connection-providers.js +378 -0
- package/lib/v1/internal/connector.js +177 -55
- package/lib/v1/internal/features.js +11 -0
- package/lib/v1/internal/get-servers-util.js +10 -10
- package/lib/v1/internal/host-name-resolvers.js +131 -0
- package/lib/v1/internal/rediscovery.js +49 -38
- package/lib/v1/internal/round-robin-array.js +9 -0
- package/lib/v1/internal/routing-table.js +49 -35
- package/lib/v1/internal/routing-util.js +168 -0
- package/lib/v1/internal/server-version.js +123 -0
- package/lib/v1/internal/stream-observer.js +4 -2
- package/lib/v1/internal/transaction-executor.js +204 -0
- package/lib/v1/internal/util.js +66 -6
- package/lib/v1/record.js +2 -2
- package/lib/v1/result-summary.js +1 -1
- package/lib/v1/result.js +53 -31
- package/lib/v1/routing-driver.js +49 -152
- package/lib/v1/session.js +196 -74
- package/lib/v1/transaction.js +147 -75
- package/lib/version.js +1 -1
- package/package.json +1 -1
- package/.gitmodules +0 -3
- package/neokit/README.md +0 -89
- package/neokit/neoctl.py +0 -131
- package/neokit/neoget.py +0 -185
- package/neokit/neorun.py +0 -180
package/README.md
CHANGED
|
@@ -63,39 +63,45 @@ driver.close();
|
|
|
63
63
|
|
|
64
64
|
## Usage examples
|
|
65
65
|
|
|
66
|
+
Driver creation:
|
|
66
67
|
```javascript
|
|
67
|
-
|
|
68
68
|
// Create a driver instance, for the user neo4j with password neo4j.
|
|
69
69
|
// It should be enough to have a single driver per database per application.
|
|
70
70
|
var driver = neo4j.driver("bolt://localhost", neo4j.auth.basic("neo4j", "neo4j"));
|
|
71
71
|
|
|
72
72
|
// Register a callback to know if driver creation was successful:
|
|
73
|
-
driver.onCompleted = function() {
|
|
73
|
+
driver.onCompleted = function () {
|
|
74
74
|
// proceed with using the driver, it was successfully instantiated
|
|
75
75
|
};
|
|
76
76
|
|
|
77
77
|
// Register a callback to know if driver creation failed.
|
|
78
78
|
// This could happen due to wrong credentials or database unavailability:
|
|
79
|
-
driver.onError = function(error) {
|
|
79
|
+
driver.onError = function (error) {
|
|
80
80
|
console.log('Driver instantiation failed', error);
|
|
81
81
|
};
|
|
82
82
|
|
|
83
|
+
// Close the driver when application exits.
|
|
84
|
+
// This closes all used network connections.
|
|
85
|
+
driver.close();
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
Session API:
|
|
89
|
+
```javascript
|
|
83
90
|
// Create a session to run Cypher statements in.
|
|
84
91
|
// Note: Always make sure to close sessions when you are done using them!
|
|
85
92
|
var session = driver.session();
|
|
86
93
|
|
|
87
94
|
// Run a Cypher statement, reading the result in a streaming manner as records arrive:
|
|
88
95
|
session
|
|
89
|
-
.run(
|
|
96
|
+
.run('MERGE (alice:Person {name : {nameParam} }) RETURN alice.name AS name', {nameParam: 'Alice'})
|
|
90
97
|
.subscribe({
|
|
91
|
-
onNext: function(record) {
|
|
92
|
-
|
|
98
|
+
onNext: function (record) {
|
|
99
|
+
console.log(record.get('name'));
|
|
93
100
|
},
|
|
94
|
-
onCompleted: function() {
|
|
95
|
-
// Completed!
|
|
101
|
+
onCompleted: function () {
|
|
96
102
|
session.close();
|
|
97
103
|
},
|
|
98
|
-
onError: function(error) {
|
|
104
|
+
onError: function (error) {
|
|
99
105
|
console.log(error);
|
|
100
106
|
}
|
|
101
107
|
});
|
|
@@ -103,55 +109,102 @@ session
|
|
|
103
109
|
// or
|
|
104
110
|
// the Promise way, where the complete result is collected before we act on it:
|
|
105
111
|
session
|
|
106
|
-
.run(
|
|
107
|
-
.then(function(result){
|
|
108
|
-
result.records.forEach(function(record) {
|
|
109
|
-
console.log(record.
|
|
112
|
+
.run('MERGE (james:Person {name : {nameParam} }) RETURN james.name AS name', {nameParam: 'James'})
|
|
113
|
+
.then(function (result) {
|
|
114
|
+
result.records.forEach(function (record) {
|
|
115
|
+
console.log(record.get('name'));
|
|
110
116
|
});
|
|
111
|
-
// Completed!
|
|
112
117
|
session.close();
|
|
113
118
|
})
|
|
114
|
-
.catch(function(error) {
|
|
119
|
+
.catch(function (error) {
|
|
115
120
|
console.log(error);
|
|
116
121
|
});
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
Transaction functions API:
|
|
125
|
+
```javascript
|
|
126
|
+
// Transaction functions provide a convenient API with minimal boilerplate and
|
|
127
|
+
// retries on network fluctuations and transient errors. Maximum retry time is
|
|
128
|
+
// configured on the driver level and is 30 seconds by default:
|
|
129
|
+
neo4j.driver("bolt://localhost", neo4j.auth.basic("neo4j", "neo4j"), {maxTransactionRetryTime: 30000});
|
|
130
|
+
|
|
131
|
+
// It is possible to execute read transactions that will benefit from automatic
|
|
132
|
+
// retries on both single instance ('bolt' URI scheme) and Causal Cluster
|
|
133
|
+
// ('bolt+routing' URI scheme) and will get automatic load balancing in cluster deployments
|
|
134
|
+
var readTxResultPromise = session.readTransaction(function (transaction) {
|
|
135
|
+
// used transaction will be committed automatically, no need for explicit commit/rollback
|
|
136
|
+
|
|
137
|
+
var result = transaction.run('MATCH (person:Person) RETURN person.name AS name');
|
|
138
|
+
// at this point it is possible to either return the result or process it and return the
|
|
139
|
+
// result of processing it is also possible to run more statements in the same transaction
|
|
140
|
+
return result;
|
|
141
|
+
});
|
|
142
|
+
|
|
143
|
+
// returned Promise can be later consumed like this:
|
|
144
|
+
readTxResultPromise.then(function (result) {
|
|
145
|
+
session.close();
|
|
146
|
+
console.log(result.records);
|
|
147
|
+
}).catch(function (error) {
|
|
148
|
+
console.log(error);
|
|
149
|
+
});
|
|
150
|
+
|
|
151
|
+
// It is possible to execute write transactions that will benefit from automatic retries
|
|
152
|
+
// on both single instance ('bolt' URI scheme) and Causal Cluster ('bolt+routing' URI scheme)
|
|
153
|
+
var writeTxResultPromise = session.writeTransaction(function (transaction) {
|
|
154
|
+
// used transaction will be committed automatically, no need for explicit commit/rollback
|
|
155
|
+
|
|
156
|
+
var result = transaction.run('MERGE (alice:Person {name : \'Alice\' }) RETURN alice.name AS name');
|
|
157
|
+
// at this point it is possible to either return the result or process it and return the
|
|
158
|
+
// result of processing it is also possible to run more statements in the same transaction
|
|
159
|
+
return result.records.map(function (record) {
|
|
160
|
+
return record.get('name');
|
|
161
|
+
});
|
|
162
|
+
});
|
|
163
|
+
|
|
164
|
+
// returned Promise can be later consumed like this:
|
|
165
|
+
writeTxResultPromise.then(function (namesArray) {
|
|
166
|
+
session.close();
|
|
167
|
+
console.log(namesArray);
|
|
168
|
+
}).catch(function (error) {
|
|
169
|
+
console.log(error);
|
|
170
|
+
});
|
|
171
|
+
```
|
|
117
172
|
|
|
118
|
-
|
|
173
|
+
Explicit transactions API:
|
|
174
|
+
```javascript
|
|
175
|
+
// run statement in a transaction
|
|
119
176
|
var tx = session.beginTransaction();
|
|
120
|
-
tx.run("MERGE (bob:Person {name : {nameParam} }) RETURN bob.name", {
|
|
177
|
+
tx.run("MERGE (bob:Person {name : {nameParam} }) RETURN bob.name AS name", {nameParam: 'Bob'})
|
|
121
178
|
.subscribe({
|
|
122
|
-
onNext: function(record) {
|
|
123
|
-
console.log(record.
|
|
124
|
-
|
|
125
|
-
onCompleted: function() {
|
|
126
|
-
// Completed!
|
|
179
|
+
onNext: function (record) {
|
|
180
|
+
console.log(record.get('name'));
|
|
181
|
+
},
|
|
182
|
+
onCompleted: function () {
|
|
127
183
|
session.close();
|
|
128
184
|
},
|
|
129
|
-
onError: function(error) {
|
|
185
|
+
onError: function (error) {
|
|
130
186
|
console.log(error);
|
|
131
187
|
}
|
|
132
188
|
});
|
|
133
|
-
|
|
189
|
+
|
|
134
190
|
//decide if the transaction should be committed or rolled back
|
|
135
191
|
var success = false;
|
|
136
192
|
|
|
137
193
|
if (success) {
|
|
138
194
|
tx.commit()
|
|
139
195
|
.subscribe({
|
|
140
|
-
onCompleted: function() {
|
|
141
|
-
//
|
|
196
|
+
onCompleted: function () {
|
|
197
|
+
// this transaction is now committed
|
|
142
198
|
},
|
|
143
|
-
onError: function(error) {
|
|
199
|
+
onError: function (error) {
|
|
144
200
|
console.log(error);
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
201
|
+
}
|
|
202
|
+
});
|
|
203
|
+
} else {
|
|
148
204
|
//transaction is rolled black and nothing is created in the database
|
|
149
205
|
console.log('rolled back');
|
|
150
206
|
tx.rollback();
|
|
151
207
|
}
|
|
152
|
-
|
|
153
|
-
// Close the driver when application exits
|
|
154
|
-
driver.close();
|
|
155
208
|
```
|
|
156
209
|
|
|
157
210
|
Subscriber API allows following combinations of `onNext`, `onCompleted` and `onError` callback invocations:
|
|
@@ -171,10 +224,19 @@ See files under `examples/` on how to use.
|
|
|
171
224
|
|
|
172
225
|
## Testing
|
|
173
226
|
|
|
227
|
+
Tests **require** latest [Boltkit](https://github.com/neo4j-contrib/boltkit) to be installed in the system. It is needed to start, stop and configure local test database. Boltkit can be installed with the following command:
|
|
228
|
+
|
|
229
|
+
pip install --upgrade boltkit
|
|
230
|
+
|
|
231
|
+
To run tests against "default" Neo4j version:
|
|
232
|
+
|
|
174
233
|
./runTests.sh
|
|
234
|
+
|
|
235
|
+
To run tests against specified Neo4j version:
|
|
236
|
+
|
|
237
|
+
./runTests.sh '-e 3.1.3'
|
|
175
238
|
|
|
176
|
-
|
|
177
|
-
Or `npm test` if you already have a running version of a compatible Neo4j server.
|
|
239
|
+
Simple `npm test` can also be used if you already have a running version of a compatible Neo4j server.
|
|
178
240
|
|
|
179
241
|
For development, you can have the build tool rerun the tests each time you change
|
|
180
242
|
the source code:
|
package/gulpfile.babel.js
CHANGED
|
@@ -22,7 +22,6 @@ var source = require('vinyl-source-stream');
|
|
|
22
22
|
var buffer = require('vinyl-buffer');
|
|
23
23
|
var gulp = require('gulp');
|
|
24
24
|
var through = require('through2');
|
|
25
|
-
var gulpif = require('gulp-if');
|
|
26
25
|
var uglify = require('gulp-uglify');
|
|
27
26
|
var concat = require('gulp-concat');
|
|
28
27
|
var gutil = require('gulp-util');
|
|
@@ -40,7 +39,6 @@ var decompress = require('gulp-decompress');
|
|
|
40
39
|
var fs = require("fs-extra");
|
|
41
40
|
var runSequence = require('run-sequence');
|
|
42
41
|
var path = require('path');
|
|
43
|
-
var childProcess = require("child_process");
|
|
44
42
|
var minimist = require('minimist');
|
|
45
43
|
var cucumber = require('gulp-cucumber');
|
|
46
44
|
var merge = require('merge-stream');
|
|
@@ -48,6 +46,7 @@ var install = require("gulp-install");
|
|
|
48
46
|
var os = require('os');
|
|
49
47
|
var file = require('gulp-file');
|
|
50
48
|
var semver = require('semver');
|
|
49
|
+
var sharedNeo4j = require('./test/internal/shared-neo4j').default;
|
|
51
50
|
|
|
52
51
|
gulp.task('default', ["test"]);
|
|
53
52
|
|
|
@@ -56,8 +55,7 @@ gulp.task('browser', function(cb){
|
|
|
56
55
|
});
|
|
57
56
|
|
|
58
57
|
/** Build all-in-one files for use in the browser */
|
|
59
|
-
gulp.task('
|
|
60
|
-
'ild-browser', function () {
|
|
58
|
+
gulp.task('build-browser', function () {
|
|
61
59
|
var browserOutput = 'lib/browser';
|
|
62
60
|
// Our app bundler
|
|
63
61
|
var appBundler = browserify({
|
|
@@ -164,23 +162,17 @@ gulp.task('test', function(cb){
|
|
|
164
162
|
|
|
165
163
|
gulp.task('test-nodejs', ['install-driver-into-sandbox'], function () {
|
|
166
164
|
return gulp.src('test/**/*.test.js')
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
// }),
|
|
172
|
-
includeStackTrace: true
|
|
173
|
-
}));
|
|
165
|
+
.pipe(jasmine({
|
|
166
|
+
includeStackTrace: true,
|
|
167
|
+
verbose: true
|
|
168
|
+
}));
|
|
174
169
|
});
|
|
175
170
|
|
|
176
171
|
gulp.task('test-boltkit', ['nodejs'], function () {
|
|
177
172
|
return gulp.src('test/**/*.boltkit.it.js')
|
|
178
173
|
.pipe(jasmine({
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
// consolidateAll: false
|
|
182
|
-
// }),
|
|
183
|
-
includeStackTrace: true
|
|
174
|
+
includeStackTrace: true,
|
|
175
|
+
verbose: true
|
|
184
176
|
}));
|
|
185
177
|
});
|
|
186
178
|
|
|
@@ -239,43 +231,14 @@ gulp.task('set', function() {
|
|
|
239
231
|
});
|
|
240
232
|
|
|
241
233
|
|
|
242
|
-
var neo4jHome
|
|
243
|
-
var neorunPath = path.resolve('./neokit/neorun.py');
|
|
244
|
-
var neorunStartArgsName = "--neorun.start.args"; // use this args to provide additional args for running neorun.start
|
|
245
|
-
|
|
246
|
-
gulp.task('start-neo4j', function() {
|
|
247
|
-
|
|
248
|
-
var neorunStartArgs = '-p neo4j'; // default args to neorun.start: change the default password to neo4j
|
|
249
|
-
process.argv.slice(2).forEach(function (val) {
|
|
250
|
-
if(val.startsWith(neorunStartArgsName))
|
|
251
|
-
{
|
|
252
|
-
neorunStartArgs = val.split("=")[1];
|
|
253
|
-
}
|
|
254
|
-
});
|
|
234
|
+
var neo4jHome = path.resolve('./build/neo4j');
|
|
255
235
|
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
neorunPath, '--start=' + neo4jHome
|
|
260
|
-
].concat( neorunStartArgs ) );
|
|
236
|
+
gulp.task('start-neo4j', function (done) {
|
|
237
|
+
sharedNeo4j.start(neo4jHome, process.env.NEOCTRL_ARGS);
|
|
238
|
+
done();
|
|
261
239
|
});
|
|
262
240
|
|
|
263
|
-
gulp.task('stop-neo4j', function() {
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
]);
|
|
241
|
+
gulp.task('stop-neo4j', function (done) {
|
|
242
|
+
sharedNeo4j.stop(neo4jHome);
|
|
243
|
+
done();
|
|
267
244
|
});
|
|
268
|
-
|
|
269
|
-
var runScript = function(cmd) {
|
|
270
|
-
var spawnSync = childProcess.spawnSync, child, code;
|
|
271
|
-
child = spawnSync('python', cmd);
|
|
272
|
-
console.log("Script Outputs:\n" + child.stdout.toString());
|
|
273
|
-
var error = child.stderr.toString();
|
|
274
|
-
if (error.trim() !== "")
|
|
275
|
-
console.log("Script Errors:\n"+ error);
|
|
276
|
-
code = child.status;
|
|
277
|
-
if( code !==0 )
|
|
278
|
-
{
|
|
279
|
-
throw "Script finished with code " + code
|
|
280
|
-
}
|
|
281
|
-
};
|