Open
Description
An official, core driver near to the Neo4j driver specification sounds great, but the proposal doesn't feel Ruby-like. I also think Rails developers will prefer the abstraction built over the driver (neo4j.rb)
Here is an in-discussion revision to the proposal which keeps all the structure of the driver specification while utilizing what makes Ruby great.
# Java loves factory and builder patterns, ok. Creating the driver:
include Neo4j::Driver
driver = GraphDatabase.driver('bolt://localhost:7687',
AuthTokens.basic('neo4j', 'password'),
...config)
# Ruby is flexible so we can give some different ways to use this.
# First, Neo4j docs say sessions are lightweight, disposable, and usually scoped in a
# context block when the language supports it, so let's do that.
# Ruby blocks and instance_eval (with proper care for delegating method calls
# back to the original context via `method_missing`) give us clean DSL with automatically
# closing the session.
# Default session-level access mode is :write
driver.session do
run('MATCH (a:Person) RETURN a.name AS name').to_a
end
# Session-level access mode with auto-commit transaction
driver.session :read do
run('MATCH (a:Person) RETURN a.name AS name').to_a
end
# Transaction-level access mode (multiple transactions per session)
driver.session do
transaction :read do
run('MATCH (a:Person) RETURN a.name AS name').to_a
end
end
# Note that while the blocks are executed in the scope of the session or transaction,
# the objects can be explicitly used through parameters:
driver.session do |session|
session.transaction { |tx| create_person_node(tx, "Lee") }
end
def create_person_node(tx, name)
tx.run 'CREATE (a:Person {name: $name})', name: name
end
# Further, using a method symbol and variable arguments can create a clean, readable solution.
# Default write access mode
driver.session do
transaction :create_person_node, "Lee"
end
# Bookmarks are sent from the server after each transaction is commit.
# transaction is called on the session object, meaning we can make the last available.
bookmarks = []
driver.session do
transaction :write { run ... }
bookmarks << last_bookmark
end
# OR
bookmarks << driver.session do
transaction :write { run ... }
transaction :write { run ... }
transaction :write { run ... }
last_bookmark
end
# Then let's use them for a next session
driver.session :read, bookmarks do
run('MATCH (a:Person) RETURN a.name AS name').to_a
end
# So, if I may rewrite the last method in the 3.4 example, line 223:
def add_employ_and_make_friends
bookmarks = []
driver.session do
transaction :add_company, "Wayne Enterprises"
transaction :add_person "Alice"
transaction :employ, "Alice", "Wayne Enterprises"
bookmarks << last_bookmark
end
driver.session do
transaction :add_company, "LexCorp"
transaction :add_person, "Bob"
transaction :employ, "Bob", "LexCorp"
bookmarks << last_bookmark
end
driver.session bookmarks do
transaction :make_friends, "Alice", "Bob"
transaction :read, :print_friends
end
end
driver.close
Metadata
Metadata
Assignees
Labels
No labels