Permalink
Browse files

Minor code cleanup for Gremlin feature (#47).

  • Loading branch information...
1 parent 318d68e commit e505430ca515e69be263a7e061cd571b448d030d @aseemk aseemk committed Sep 21, 2012
Showing with 71 additions and 68 deletions.
  1. +26 −27 lib/GraphDatabase._coffee
  2. +1 −2 package.json
  3. +2 −2 test/cypher._coffee
  4. +42 −37 test/gremlin._coffee
@@ -241,16 +241,35 @@ module.exports = class GraphDatabase
catch error
throw adjustError error
- # wrapper around the Gremlin plugin to execute scripts bundled with
- # Neo4j. Pass in the Gremlin script as a string, and optionally script
+ # XXX temporary backwards compatibility shim for query() argument order,
+ # and also to support overloaded method signature:
+ do (actual = @::query) =>
+ @::query = (query, params, callback) ->
+ if typeof query is 'function' and typeof params is 'string'
+ # instantiate a new error to derive the current stack, and
+ # show the relevant source line in a warning:
+ console.warn 'neo4j.GraphDatabase::query()’s signature is ' +
+ 'now (query, params, callback). Please update your code!\n' +
+ new Error().stack.split('\n')[2] # includes indentation
+ callback = query
+ query = params
+ params = null
+ else if typeof params is 'function'
+ callback = params
+ params = null
+
+ actual.call @, query, params, callback
+
+ # wrapper around the Gremlin plugin, which comes bundled with Neo4j.
+ # pass in the Gremlin script as a string, and optionally script
# parameters as a map -- recommended for both perf and security!
# http://docs.neo4j.org/chunked/snapshot/gremlin-plugin.html
- # returns...
+ # returns whatever your script returns, but any values that represent
+ # nodes, relationships or paths are transformed to instances.
execute: (script, params, _) ->
try
services = @getServices _
- endpoint = services.gremlin or
- services.extensions?.GremlinPlugin?['execute_script']
+ endpoint = services.extensions?.GremlinPlugin?['execute_script']
if not endpoint
throw new Error 'Gremlin plugin not installed'
@@ -274,32 +293,12 @@ module.exports = class GraphDatabase
throw response
# Success: transform nodes/relationships
- results = util.transform response.body, this
- return results
+ return util.transform response.body, this
catch error
throw adjustError error
- # XXX temporary backwards compatibility shim for query() argument order:
- do (actual = @::query) =>
- @::query = (query, params, callback) ->
- if typeof query is 'function' and typeof params is 'string'
- # instantiate a new error to derive the current stack, and
- # show the relevant source line in a warning:
- console.warn 'neo4j.GraphDatabase::query()’s signature is ' +
- 'now (query, params, callback). Please update your code!\n' +
- new Error().stack.split('\n')[2] # includes indentation
- callback = query
- query = params
- params = null
- else if typeof params is 'function'
- callback = params
- params = null
-
- actual.call @, query, params, callback
-
-
- #
+ # helper for overloaded execute() method:
do (actual = @::execute) =>
@::execute = (script, params, callback) ->
if typeof params is 'function'
View
@@ -24,8 +24,7 @@
"clean": "rm lib/*.js",
"postinstall": "npm run build",
"profile": "_coffee test/profile",
- "test": "_coffee test",
- "gremlin": "_coffee test/gremlin"
+ "test": "_coffee test"
},
"keywords": [
"neo4j", "graph", "database", "driver", "rest", "api", "client"
View
@@ -68,8 +68,8 @@ createFollowRelationships = (i, _) ->
i2 = (i + 2) % users.length
i3 = (i + 3) % users.length
# create three relationships in parallel
- # WARNING: don't freaking use a variable called futures!
- # coffeescript's variable shadowing will FUCK. YOU. UP.
+ # WARNING: don't use a variable named futures here!
+ # coffeescript variable shadowing will kick in unexpectedly. =(
f1 = user.createRelationshipTo users[i1], 'follows', {}
f2 = user.createRelationshipTo users[i2], 'follows', {}
f3 = user.createRelationshipTo users[i3], 'follows', {}
View
@@ -8,14 +8,14 @@ db = new neo4j.GraphDatabase 'http://localhost:7474'
# convenience wrapper
createNode = (name) ->
- node = db.createNode {name}
- node.name = name
- node.toString = -> name
- node
+ node = db.createNode {name}
+ node.name = name
+ node.toString = -> name
+ node
-#create some nodes
+# create some nodes
users = for i in [0..6]
- createNode "gremlinTest#{i}"
+ createNode "gremlinTest#{i}"
# save in parallel
futures = (user.save() for user in users)
@@ -30,42 +30,47 @@ user4 = users[4]
user5 = users[5]
user6 = users[6]
-# test: can query a single user
-results = db.execute """
- g.v(#{user0.id})
-""", {}, _
+# test: can query a single user, using param
+result = db.execute """
+ g.v(userId)
+""", {userId: user0.id}, _
-assert.ok typeof results, 'object'
-assert.ok typeof results.data.name, 'string' # dislike this because it will throw for the wrong reasons possibly
-assert.equal results.data.name, user0.name
+assert.ok result
+assert.equal typeof result, 'object'
+assert.equal typeof result.data, 'object'
+assert.equal result.data.name, user0.name
# test: create relationships between users (same as cypher tests), then query by relationships
createFollowRelationships = (i, _) ->
- user = users[i]
- i1 = (i + 1) % users.length
- i2 = (i + 2) % users.length
- i3 = (i + 3) % users.length
- f1 = user.createRelationshipTo users[i1], 'gremlin_follows', {}
- f2 = user.createRelationshipTo users[i2], 'gremlin_follows', {}
- f3 = user.createRelationshipTo users[i3], 'gremlin_follows', {}
- f1 _
- f2 _
- f3 _
+ user = users[i]
+ i1 = (i + 1) % users.length
+ i2 = (i + 2) % users.length
+ i3 = (i + 3) % users.length
+ f1 = user.createRelationshipTo users[i1], 'gremlin_follows', {}
+ f2 = user.createRelationshipTo users[i2], 'gremlin_follows', {}
+ f3 = user.createRelationshipTo users[i3], 'gremlin_follows', {}
+ f1 _
+ f2 _
+ f3 _
# create follow relationships for each user in parallel
futures = (createFollowRelationships(i) for user, i in users)
future _ for future in futures
-relationships = db.execute """
- g.v(#{user0.id}).in('gremlin_follows')
+rels = db.execute """
+ g.v(#{user0.id}).in('gremlin_follows')
""", {} , _
-# above is working, but lib should support returning instances of Node and Relationship if possible
-
+assert.ok rels instanceof Array
+assert.equal rels.length, 3
+assert.ok rels[1]
+assert.equal typeof rels[1], 'object'
+# order isn't specified/guaranteed:
+assert.ok rels[1].id in [user4.id, user5.id, user6.id]
# handle multiple types of data return
traversals = db.execute """
- g.v(#{user0.id}).transform{ [it, it.out.toList(), it.in.count()] }
+ g.v(#{user0.id}).transform{ [it, it.out.toList(), it.in.count()] }
""", {}, _
assert.ok traversals instanceof Array
@@ -74,20 +79,20 @@ assert.equal traversals.length, 1
assert.ok traversals[0] instanceof Array
assert.equal traversals[0].length, 3
-assert.ok typeof traversals[0][0], 'object'
+assert.equal typeof traversals[0][0], 'object'
+assert.equal traversals[0][0].id, user0.id
assert.ok traversals[0][1] instanceof Array
-assert.ok typeof traversals[0][2], 'number'
-
-console.log 'Multiple data types appear to have worked with .execute() and util.transform()'
+assert.equal traversals[0][1].length, 3
+assert.ok traversals[0][1][1].id in [user1.id, user2.id, user3.id]
+assert.equal traversals[0][2], 3
# ensure you can call without params
-
params_test = db.execute """
- g.v(#{user0.id})
+ g.v(#{user0.id})
""", _
-assert.ok typeof params_test, 'object'
+assert.equal typeof params_test, 'object'
assert.equal params_test.data.name, user0.name
-# Should be relatively clear at this point the .execute() function is working with gremlin on some level
-console.log 'Passed initial Gremlin tests'
+# give some confidence that these tests actually passed ;)
+console.log 'passed gremlin tests'

0 comments on commit e505430

Please sign in to comment.