Skip to content

Commit

Permalink
Native driver, session, transaction
Browse files Browse the repository at this point in the history
  • Loading branch information
klobuczek committed Apr 1, 2020
1 parent e387298 commit 1267174
Show file tree
Hide file tree
Showing 51 changed files with 383 additions and 561 deletions.
2 changes: 1 addition & 1 deletion Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ source 'http://rubygems.org'

gemspec

# gem 'neo4j-ruby-driver', path: '../neo4j-ruby-driver'
#gem "neo4j-#{ENV['driver'] == 'java' ? 'java' : 'ruby'}-driver", path: '../neo4j-ruby-driver'

gem 'listen', '< 3.1'

Expand Down
4 changes: 2 additions & 2 deletions activegraph.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -38,12 +38,12 @@ DESCRIPTION
s.add_development_dependency('guard-rspec')
s.add_development_dependency('guard-rubocop')
s.add_development_dependency('neo4j-rake_tasks', '>= 0.3.0')
s.add_development_dependency("neo4j-#{ENV['driver'] == 'java' ? 'java' : 'ruby'}-driver", '>= 0.3.0')
s.add_development_dependency("neo4j-#{ENV['driver'] == 'java' ? 'java' : 'ruby'}-driver", '>= 0.3.5')
s.add_development_dependency('os')
s.add_development_dependency('pry')
s.add_development_dependency('railties', '>= 4.0')
s.add_development_dependency('rake')
s.add_development_dependency('rubocop', '~> 0.56.0')
s.add_development_dependency('rubocop', '>= 0.56.0')
s.add_development_dependency('yard')
s.add_development_dependency('dryspec')
end
3 changes: 3 additions & 0 deletions lib/active_graph.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
require 'active_graph/core'
require 'active_graph/core/query_ext' # From this gem

require 'active_support/core_ext/module/attribute_accessors_per_thread'
require 'active_graph/transactions'
require 'active_graph/base'
require 'active_graph/model_schema'
Expand Down Expand Up @@ -118,3 +119,5 @@ module ActiveGraph
require 'rails/generators'
require 'rails/generators/neo4j_generator'
end

Neo4j::Driver::Transaction.prepend ActiveGraph::Transaction
46 changes: 14 additions & 32 deletions lib/active_graph/base.rb
Original file line number Diff line number Diff line change
@@ -1,25 +1,26 @@
require 'active_graph/core/querable'
require 'active_graph/core/schema'

module ActiveGraph
# To contain any base login for Node/Relationship which
# is external to the main classes
module Base
include ActiveGraph::Transactions
include ActiveGraph::Core::Querable
extend ActiveGraph::Core::Schema

at_exit do
@driver&.close
end

class << self
# private?
def current_driver
def driver
(@driver ||= establish_driver).tap do |driver|
fail 'No driver defined!' if driver.nil?
end
end

def driver
current_driver.driver
end

def on_establish_driver(&block)
@establish_driver_block = block
end
Expand All @@ -28,18 +29,10 @@ def establish_driver
@establish_driver_block.call if @establish_driver_block
end

def new_driver(url, auth_token, options = {})
verbose_query_logs = ActiveGraph::Config.fetch(:verbose_query_logs, false)
ActiveGraph::Core::Driver
.new(url, auth_token, options, verbose_query_logs: verbose_query_logs)
end

def transaction
current_transaction || Transaction
end

def query(*args)
transaction.query(*args)
transaction do
super(*args)
end
end

# Should support setting driver via config options
Expand All @@ -48,35 +41,24 @@ def driver=(driver)
@driver = driver
end

def run_transaction(run_in_tx = true)
Transaction.run(current_driver, run_in_tx) do |tx|
yield tx
end
end

def new_transaction
def validating_transaction(&block)
validate_model_schema!
ActiveGraph::Transaction.new
transaction(&block)
end

def new_query(options = {})
validate_model_schema!
ActiveGraph::Core::Query.new({driver: current_driver}.merge(options))
ActiveGraph::Core::Query.new(options)
end

def magic_query(*args)
if args.empty? || args.map(&:class) == [Hash]
Base.new_query(*args)
new_query(*args)
else
Base.current_driver.query(*args)
query(*args)
end
end

def current_transaction
validate_model_schema!
Transaction.root
end

def label_object(label_name)
ActiveGraph::Core::Label.new(label_name)
end
Expand Down
1 change: 0 additions & 1 deletion lib/active_graph/core.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
require 'active_graph/transaction'
require 'active_graph/core/instrumentable'
require 'active_graph/core/query'
require 'active_graph/core/driver'
require 'active_graph/core/responses'

require 'neo4j_ruby_driver'
Expand Down
49 changes: 0 additions & 49 deletions lib/active_graph/core/driver.rb

This file was deleted.

5 changes: 3 additions & 2 deletions lib/active_graph/core/instrumentable.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
require 'active_support/concern'
require 'active_support/notifications'
require 'active_graph/ansi'
require 'active_graph/core/logging'

module ActiveGraph
module Core
Expand All @@ -14,7 +15,7 @@ module Instrumentable
def subscribe_to_request
ActiveSupport::Notifications.subscribe('neo4j.core.bolt.request') do |_, start, finish, _id, _payload|
ms = (finish - start) * 1000
yield " #{ANSI::BLUE}BOLT:#{ANSI::CLEAR} #{ANSI::YELLOW}#{ms.round}ms#{ANSI::CLEAR} #{Base.current_driver.url}"
yield " #{ANSI::BLUE}BOLT:#{ANSI::CLEAR} #{ANSI::YELLOW}#{ms.round}ms#{ANSI::CLEAR}"
end
end

Expand All @@ -27,7 +28,7 @@ def subscribe_to_query
source_line, line_number = Logging.first_external_path_and_line(caller_locations)

yield " #{ANSI::CYAN}#{query.context || 'CYPHER'}#{ANSI::CLEAR} #{cypher} #{params_string}" +
("\n#{source_line}:#{line_number}" if Base.current_driver.options[:verbose_query_logs] && source_line).to_s
("\n#{source_line}:#{line_number}" if ActiveGraph::Config.fetch(:verbose_query_logs, false) && source_line).to_s
end
end
end
Expand Down
17 changes: 8 additions & 9 deletions lib/active_graph/core/label.rb
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ def index?(property)
end

def constraints(_options = {})
ActiveGraph::Transaction.constraints.select do |definition|
ActiveGraph::Base.constraints.select do |definition|
definition[:label] == @name.to_sym
end
end
Expand Down Expand Up @@ -109,13 +109,13 @@ def schema_threads=(array)

class << self
def indexes
ActiveGraph::Transaction.indexes
ActiveGraph::Base.indexes
end

def drop_indexes
indexes.each do |definition|
begin
ActiveGraph::Transaction.query("DROP INDEX ON :`#{definition[:label]}`(#{definition[:properties][0]})")
ActiveGraph::Base.query("DROP INDEX ON :`#{definition[:label]}`(#{definition[:properties][0]})")
rescue Neo4j::Driver::Exceptions::DatabaseException
# This will error on each constraint. Ignore and continue.
next
Expand All @@ -124,11 +124,10 @@ def drop_indexes
end

def drop_constraints
ActiveGraph::Transaction.named_constraints.each do |constraint|
ActiveGraph::Transaction.query("DROP CONSTRAINT #{constraint.name}")
end
ActiveGraph::Transaction.constraints.each do |definition|
ActiveGraph::Transaction.query("DROP CONSTRAINT ON (n:`#{definition[:label]}`) ASSERT n.`#{definition[:properties][0]}` IS UNIQUE")
ActiveGraph::Base.transaction do |tx|
tx.run('CALL db.constraints').each do |record|
tx.run("DROP #{record.keys.include?(:name) ? "CONSTRAINT #{record[:name]}" : record[:description]}")
end
end
end

Expand All @@ -147,7 +146,7 @@ def set_schema_threads(array)
end

def schema_query(cypher)
ActiveGraph::Transaction.transaction { |tx| tx.query(cypher, {}) }
ActiveGraph::Base.query(cypher, {})
end

def validate_index_options!(options)
Expand Down
2 changes: 1 addition & 1 deletion lib/active_graph/core/logging.rb
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ def paths_to_ignore
def neo4j_gem_path
return if !defined?(::Rails.root)

@neo4j_gem_path ||= File.expand_path('../../..', ActiveGraph::Base.method(:current_driver).source_location[0])
@neo4j_gem_path ||= File.expand_path('../../..', ActiveGraph::Base.method(:driver).source_location[0])
end

def active_support_gem_path
Expand Down
43 changes: 7 additions & 36 deletions lib/active_graph/core/querable.rb
Original file line number Diff line number Diff line change
Expand Up @@ -27,29 +27,8 @@ def queries(options = {}, &block)

query_builder.instance_eval(&block)

new_or_current_transaction(options[:transaction]) do |tx|
query_set(tx, query_builder.queries, { commit: !options[:transaction] }.merge(options))
end
end

# If called without a block, returns a Transaction object
# which can be used to call query/queries/mark_failed/commit
# If called with a block, the Transaction object is yielded
# to the block and `commit` is ensured. Any uncaught exceptions
# will mark the transaction as failed first
def transaction
return Transaction.new unless block_given?

begin
tx = transaction

yield tx
rescue => e
tx.mark_failed if tx

raise e
ensure
tx.close if tx
transaction do
query_set(query_builder.queries, options)
end
end

Expand All @@ -60,28 +39,20 @@ def setup_queries!(queries, options = {})
end
end

def query_set(transaction, queries, options = {})
def query_set(queries, options = {})
setup_queries!(queries, skip_instrumentation: options[:skip_instrumentation])

ActiveSupport::Notifications.instrument('neo4j.core.bolt.request') do
self.wrap_level = options[:wrap_level]
queries.map do |query|
result_from_data(transaction.root_tx.run(query.cypher, query.parameters))
transaction do |tx|
queries.map do |query|
result_from_data(tx.run(query.cypher, query.parameters))
end
end
rescue Neo4j::Driver::Exceptions::Neo4jException => e
raise ActiveGraph::Core::CypherError.new_from(e.code, e.message) # , e.stack_track.to_a
end
end

private

def new_or_current_transaction(tx, &block)
if tx
yield(tx)
else
transaction(&block)
end
end
end
end
end
Expand Down
6 changes: 2 additions & 4 deletions lib/active_graph/core/query.rb
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,6 @@ class << self
end

def initialize(options = {})
@driver = options[:driver]

@options = options
@clauses = []
@_params = {}
Expand Down Expand Up @@ -237,7 +235,7 @@ def unwrapped?
def response
return @response if @response

@response = ActiveGraph::Transaction.query(self, transaction: Transaction.root, wrap_level: (:core_entity if unwrapped?))
@response = ActiveGraph::Base.query(self, wrap_level: (:core_entity if unwrapped?))
end

def raise_if_cypher_error!(response)
Expand Down Expand Up @@ -374,7 +372,7 @@ def union_cypher(other, options = {})
end

def &(other)
self.class.new(driver: @driver).tap do |new_query|
self.class.new.tap do |new_query|
new_query.options = options.merge(other.options)
new_query.clauses = clauses + other.clauses
end.params(other._params)
Expand Down
4 changes: 1 addition & 3 deletions lib/active_graph/core/query_builder.rb
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,7 @@ def append(*args)
end

def query
# `nil` drivers are just a workaround until
# we phase out `Query` objects containing drivers
ActiveGraph::Core::Query.new(driver: nil)
ActiveGraph::Core::Query.new
end
end
end
Expand Down
5 changes: 0 additions & 5 deletions lib/active_graph/core/schema.rb
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,6 @@ def constraints
end
end

def named_constraints
result = query('CALL db.constraints()', {}, skip_instrumentation: true)
result.columns.include?(:name) ? result : []
end

private

def v4_filter(row)
Expand Down
Loading

0 comments on commit 1267174

Please sign in to comment.