Skip to content

Commit b4ee8f5

Browse files
committed
Merge branch 'nodejs'
2 parents 57f625a + ea79689 commit b4ee8f5

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

41 files changed

+6665
-810
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,4 @@ pids
77
.lock-wscript
88
build
99
node_modules
10+
.idea

README.md

Lines changed: 52 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,54 +1,72 @@
11
# Neo4j Bolt Driver for JavaScript
22

3-
The JavaScript driver for Bolt uses the websocket interface and is currently available for use within a browser context only.
4-
To use the driver, simply include the `neo4j.js` file within a page.
53

64
## Example
75

86
```javascript
9-
// Create a Session object to contain all Cypher activity.
10-
var session = new Session();
7+
var neo4j = require('build/node/neo4j');
118

12-
var statement = "MERGE (a:Person {name:'Alice'}) " +
13-
"MERGE (a)-[:KNOWS]->(b:Person {name:'Bob'}) " +
14-
"RETURN id(a), id(b)",
15-
parameters = {};
9+
var statement = ['MERGE (alice:Person {name:{name_a},age:{age_a}})',
10+
'MERGE (bob:Person {name:{name_b},age:{age_b}})',
11+
'CREATE UNIQUE (alice)-[alice_knows_bob:KNOWS]->(bob)',
12+
'RETURN alice AS, bob, alice_knows_bob'
13+
];
1614

17-
// Run a Cypher statement within an implicit transaction
18-
session.run(statement, parameters,
15+
var params = {
16+
name_a: 'Alice',
17+
age_a: 33,
18+
name_b: 'Bob',
19+
age_b: 44
20+
};
1921

20-
// Called on receipt of each RECORD
21-
function(record) {
22-
console.log("Values: " + record.join());
23-
},
2422

25-
// Called on receipt of header summary message
26-
function(success, metadata) {
27-
if (success) {
28-
console.log("Fields: " + metadata["fields"].join());
29-
}
30-
else {
31-
console.log("FAILURE");
23+
// Create a Session object to contain all Cypher activity.
24+
var driver = neo4j.driver("neo4j://localhost");
25+
var session = driver.session();
26+
27+
// Run a Cypher statement within an implicit transaction
28+
// The streaming way:
29+
session.run(statement.join(' '), params).subscribe({
30+
onNext: function(record) {
31+
// On receipt of RECORD
32+
for(var i in record) {
33+
console.log(i);
34+
console.log(record[i]);
3235
}
33-
36+
}, onCompleted: function(metadata) {
37+
console.log(metadata);
38+
}, onError: function(error) {
39+
console.log(error);
3440
}
41+
});
3542

36-
);
43+
// or
44+
// the collect way, with Javascript promises:
45+
session.run(statement.join(' '), params)
46+
.then(function(records){
47+
records.forEach(function(record) {
48+
for(var i in record) {
49+
console.log(i);
50+
console.log(record[i]);
51+
}
52+
})
53+
})
54+
.catch(function(error) {
55+
console.log(error);
56+
});
3757
```
3858

39-
## Building & testing
40-
41-
npm install
42-
npm test
59+
## Building
4360

44-
This runs the test suite and produces browser-compatible standalone files under `build/`.
61+
npm install
62+
gulp
4563

46-
## TODO
64+
This produces browser-compatible standalone files under `build/browser` and a nodejs module version under `build/node`.
65+
See files under `examples/` on how to use.
4766

48-
The JavaScript driver is still missing at least the following:
67+
## Testing
4968

50-
- Integration with *node.js*
51-
- `GraphDatabase` and `Driver` classes from the Session API used by other drivers
52-
- Ability to specify the remote database URL (currently hard-coded to `bolt:localhost`)
53-
- A `Transaction` class
69+
./runTests.sh
5470

71+
This runs the test suite against a fresh download of Neo4j.
72+
Or `gulp test` if you already have a running version of a compatible Neo4j server running.

examples/neo4j.html

Lines changed: 12 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@
9393
padding: 0 2px;
9494
}
9595
</style>
96-
<script src="neo4j.js"></script>
96+
<script src="../build/browser/neo4j-web.min.js"></script>
9797
</head>
9898
<body>
9999

@@ -131,38 +131,27 @@ <h1>Cypher Runner for New Remoting</h1>
131131
</div>
132132

133133
<script>
134-
135-
var session = new Session();
134+
var driver = neo4j.driver("neo4j://localhost");
135+
var session = driver.session();
136136

137137
function run() {
138138
var statement = document.getElementById("statement").value,
139139
parameters = getParameters();
140140

141141
var table = document.createElement("table");
142-
session.run(statement, parameters, function(record) {
143-
144-
// On receipt of RECORD
145-
var tr = document.createElement("tr");
146-
for(var i = 0; i < record.length; i++) {
147-
var td = document.createElement("td");
148-
td.appendChild(document.createTextNode(record[i]));
149-
tr.appendChild(td);
150-
}
151-
table.appendChild(tr);
152-
153-
}, function(success, metadata) {
154-
155-
// On receipt of header summary message
156-
if(success) {
142+
session.run(statement, parameters).subscribe({
143+
onNext: function(record) {
144+
// On receipt of RECORD
157145
var tr = document.createElement("tr");
158-
for(var i = 0; i < metadata.fields.length; i++) {
159-
var th = document.createElement("th");
160-
th.appendChild(document.createTextNode(metadata.fields[i]));
161-
tr.appendChild(th);
146+
for(var i in record) {
147+
var td = document.createElement("td");
148+
td.appendChild(document.createTextNode(record[i]));
149+
tr.appendChild(td);
162150
}
163151
table.appendChild(tr);
152+
}, onCompleted: function(metadata) {
153+
164154
}
165-
166155
});
167156

168157
var results = document.getElementById("results");

examples/node.js

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
2+
var neo4j = require('../build/node/neo4j');
3+
4+
var statement = ['MERGE (alice:Person {name:{name_a},age:{age_a}})',
5+
'MERGE (bob:Person {name:{name_b},age:{age_b}})',
6+
'CREATE UNIQUE (alice)-[alice_knows_bob:KNOWS]->(bob)',
7+
'RETURN alice AS, bob, alice_knows_bob'
8+
];
9+
10+
var params = {
11+
name_a: 'Alice',
12+
age_a: 33,
13+
name_b: 'Bob',
14+
age_b: 44
15+
};
16+
17+
var driver = neo4j.driver("neo4j://localhost");
18+
var session = driver.session();
19+
20+
session.run(statement.join(' '), params).subscribe({
21+
onNext: function(record) {
22+
// On receipt of RECORD
23+
for(var i in record) {
24+
console.log(i);
25+
console.log(record[i]);
26+
}
27+
}, onCompleted: function(metadata) {
28+
// On receipt of header summary message
29+
console.log('');
30+
console.log(metadata);
31+
}, onError: function(error) {
32+
console.log(error);
33+
}
34+
});

gulpfile.js

Lines changed: 108 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1,77 +1,141 @@
11
var browserify = require('browserify');
2-
var source = require('vinyl-source-stream');
2+
var source = require('vinyl-source-stream');
3+
var buffer = require('vinyl-buffer');
34
var gulp = require('gulp');
5+
var through = require('through2');
46
var gulpif = require('gulp-if');
57
var uglify = require('gulp-uglify');
68
var concat = require('gulp-concat');
7-
var streamify = require('gulp-streamify');
89
var gutil = require('gulp-util');
910
var download = require("gulp-download");
1011
var gunzip = require('gulp-gunzip');
1112
var untar = require('gulp-untar2');
13+
var shell = require('gulp-shell');
1214
var jasmine = require('gulp-jasmine');
15+
var jasmineBrowser = require('gulp-jasmine-browser');
1316
var reporters = require('jasmine-reporters');
14-
var jasminePhantomJs = require('gulp-jasmine2-phantomjs');
17+
var babelify = require('babelify');
18+
var babel = require('gulp-babel');
19+
var watch = require('gulp-watch');
20+
var batch = require('gulp-batch');
21+
var fs = require("fs");
1522

23+
gulp.task('default', ["test"]);
24+
25+
/** Build all-in-one files for use in the browser */
26+
gulp.task('browser', ['nodejs'], function () {
27+
28+
var browserOutput = 'build/browser';
29+
var testFiles = [];
30+
gulp.src('./test/**/*.test.js')
31+
.pipe( through.obj( function( file, enc, cb ) {
32+
testFiles.push( file.path );
33+
cb();
34+
}, function(cb) {
35+
// At end-of-stream, push the list of files to the next step
36+
this.push( testFiles );
37+
cb();
38+
}))
39+
.pipe( through.obj( function( testFiles, enc, cb) {
40+
browserify({
41+
entries: testFiles,
42+
cache: {},
43+
debug: true
44+
}).transform(babelify.configure({
45+
ignore: /external/
46+
}))
47+
.bundle()
48+
.on('error', gutil.log)
49+
.pipe(source('neo4j-web.test.js'))
50+
.pipe(buffer())
51+
.pipe(uglify())
52+
.pipe(gulp.dest(browserOutput));
53+
}));
1654

17-
var browserifyTask = function (options) {
1855

1956
// Our app bundler
2057
var appBundler = browserify({
21-
entries: [options.src],
22-
cache: {},
58+
entries: ['lib/neo4j.js'],
59+
cache: {},
60+
standalone: 'neo4j',
2361
packageCache: {}
24-
});
62+
}).transform(babelify.configure({
63+
ignore: /external/
64+
})).bundle();
2565

2666
// Un-minified browser package
27-
appBundler.bundle()
28-
.on('error', gutil.log)
29-
.pipe(source('neo4j-web.js'))
30-
.pipe(gulp.dest(options.dest));
67+
appBundler
68+
.on('error', gutil.log)
69+
.pipe(source('neo4j-web.js'))
70+
.pipe(gulp.dest(browserOutput));
71+
72+
return appBundler
73+
.on('error', gutil.log)
74+
.pipe(source('neo4j-web.min.js'))
75+
.pipe(buffer())
76+
.pipe(uglify())
77+
.pipe(gulp.dest(browserOutput));
78+
});
3179

80+
var compress = function(source, dest, filename) {
3281

33-
appBundler.bundle()
34-
.on('error', gutil.log)
35-
.pipe(source('neo4j-web.min.js'))
36-
.pipe(gulp.dest(options.dest))
37-
.pipe(gulpif(!options.development, streamify(uglify())))
3882
}
3983

40-
gulp.task('default', ["test", "browser"]);
84+
var buildNode = function(options) {
85+
return gulp.src(options.src)
86+
.pipe(babel({ignore: ['lib/external/**/*.js']}))
87+
.pipe(gulp.dest(options.dest))
88+
}
4189

42-
gulp.task('browser', function () {
90+
gulp.task('nodejs', function(){
91+
return buildNode({
92+
src: 'lib/**/*.js',
93+
dest: 'build/node'
94+
});
95+
})
4396

44-
browserifyTask({
45-
src: 'lib/neo4j.js',
46-
dest: 'build/browser'
47-
});
97+
gulp.task('all', ['nodejs', 'browser']);
4898

49-
});
99+
gulp.task('test', ['test-nodejs', 'test-browser']);
50100

51-
gulp.task('test', ["test-nodejs", "test-browser"]);
101+
gulp.task('start-neo4j', ['download-neo4j'], shell.task([
102+
'chmod +x build/neo4j-enterprise*/bin/neo4j',
103+
'build/neo4j-enterprise*/bin/neo4j start',
104+
]));
52105

53-
gulp.task('test-nodejs', function () {
54-
return gulp.src('test/*.test.js')
106+
gulp.task('stop-neo4j', shell.task([
107+
'build/neo4j-enterprise*/bin/neo4j stop',
108+
]));
109+
110+
gulp.task('test-nodejs', ['nodejs'], function () {
111+
return gulp.src('test/**/*.test.js')
55112
.pipe(jasmine({
56-
reporter: new reporters.JUnitXmlReporter({
57-
savePath: "build/nodejs-test-reports",
58-
consolidateAll: false
59-
})
113+
// reporter: new reporters.JUnitXmlReporter({
114+
// savePath: "build/nodejs-test-reports",
115+
// consolidateAll: false
116+
// }),
117+
includeStackTrace: true
60118
}));
61119
});
62120

121+
gulp.task('test-browser', ['browser'], function () {
122+
return gulp.src('build/browser/neo4j-web.test.js')
123+
.pipe(jasmineBrowser.specRunner({console: true}))
124+
.pipe(jasmineBrowser.headless({driver: 'slimerjs'}));
125+
});
63126

64-
gulp.task('test-browser', function () {
65-
// TODO: We should not use PhantomJS directly, instead we should run this via Karma to get wide cross-browser testing
66-
gulp.src('./test/*.test.js')
67-
.pipe(concat('all.test.js'))
68-
.pipe(gulp.dest('./build/'));
69-
70-
browserify({ entries: ['build/all.test.js'] })
71-
.bundle()
72-
.on('error', gutil.log)
73-
.pipe(source('neo4j-web.test.js'))
74-
.pipe(gulp.dest('./build/browser/'));
75-
76-
return gulp.src('./test/browser/testrunner-phantomjs.html').pipe(jasminePhantomJs());
77-
});
127+
gulp.task('watch', function () {
128+
watch('lib/**/*.js', batch(function (events, done) {
129+
gulp.start('all', done);
130+
}));
131+
});
132+
133+
gulp.task('download-neo4j', function() {
134+
if( !fs.existsSync('./build/neo4j-enterprise-3.0.0-alpha') ) {
135+
// Need to download
136+
return download("http://alpha.neohq.net/dist/neo4j-enterprise-3.0.0-alpha-unix.tar.gz")
137+
.pipe(gunzip())
138+
.pipe(untar())
139+
.pipe(gulp.dest('./build'));
140+
}
141+
});

0 commit comments

Comments
 (0)