activegraph 10.0.0.pre.beta.3 → 10.0.0.pre.beta.4

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5bf12b2e24dd9557ad7d5a232f653e150241910a48293d4aeba5f5e16f160a42
4
- data.tar.gz: 36adc4653772d9132ea19f086b361f4d14fe61704ad1c75214ff441bac0652c9
3
+ metadata.gz: ef0444b21eb9130b0047fa423911cff404686bb29a7af0e63b66dd093d822f2b
4
+ data.tar.gz: d359a53fbe4ecfec871b596ecd3aeae4293f9369059090cec06f78e2d8a6c77c
5
5
  SHA512:
6
- metadata.gz: e0b15269740380e2bf9bf274f0d3cf89c0bc1394d3469c92919ce0fa172a0b7b22abeec2f7484440c2ff1dd38be275fbb6307aebcf1f8b5174cca8a8568aab70
7
- data.tar.gz: fa92fc22ff87ae268a8ef951adb7dc2b838d3673db36ec34cbbf204be1584814a1c48d9c97fa2b87ae8ea09261ffb0a7a72e4c8be2f7dd4ac081c730b3be3b53
6
+ metadata.gz: 736e716587d1b7cb30f44263ac05108793b1819765c4e362240421022a3581b96bbbd186ca132846ade50a643f59edb422e2cb9c492c31d6c517556fb96e2c08
7
+ data.tar.gz: e985e8b8223a56a02c581f50e180851fee59b3fcbad402560f59746df6e64c3bfa8d4ccbf813571235ff5e5af1585b28939c51d835e13b8fd6b516dbe121b66c
data/Gemfile CHANGED
@@ -2,7 +2,7 @@ source 'http://rubygems.org'
2
2
 
3
3
  gemspec
4
4
 
5
- # gem 'neo4j-ruby-driver', path: '../neo4j-ruby-driver'
5
+ #gem "neo4j-#{ENV['driver'] == 'java' ? 'java' : 'ruby'}-driver", path: '../neo4j-ruby-driver'
6
6
 
7
7
  gem 'listen', '< 3.1'
8
8
 
data/activegraph.gemspec CHANGED
@@ -38,12 +38,12 @@ DESCRIPTION
38
38
  s.add_development_dependency('guard-rspec')
39
39
  s.add_development_dependency('guard-rubocop')
40
40
  s.add_development_dependency('neo4j-rake_tasks', '>= 0.3.0')
41
- s.add_development_dependency("neo4j-#{ENV['driver'] == 'java' ? 'java' : 'ruby'}-driver", '>= 0.3.0')
41
+ s.add_development_dependency("neo4j-#{ENV['driver'] == 'java' ? 'java' : 'ruby'}-driver", '>= 0.3.5')
42
42
  s.add_development_dependency('os')
43
43
  s.add_development_dependency('pry')
44
44
  s.add_development_dependency('railties', '>= 4.0')
45
45
  s.add_development_dependency('rake')
46
- s.add_development_dependency('rubocop', '~> 0.56.0')
46
+ s.add_development_dependency('rubocop', '>= 0.56.0')
47
47
  s.add_development_dependency('yard')
48
48
  s.add_development_dependency('dryspec')
49
49
  end
@@ -1,8 +1,13 @@
1
+ require 'active_graph/core/querable'
2
+ require 'active_graph/core/schema'
3
+
1
4
  module ActiveGraph
2
5
  # To contain any base login for Node/Relationship which
3
6
  # is external to the main classes
4
7
  module Base
5
8
  include ActiveGraph::Transactions
9
+ include ActiveGraph::Core::Querable
10
+ extend ActiveGraph::Core::Schema
6
11
 
7
12
  at_exit do
8
13
  @driver&.close
@@ -10,16 +15,12 @@ module ActiveGraph
10
15
 
11
16
  class << self
12
17
  # private?
13
- def current_driver
18
+ def driver
14
19
  (@driver ||= establish_driver).tap do |driver|
15
20
  fail 'No driver defined!' if driver.nil?
16
21
  end
17
22
  end
18
23
 
19
- def driver
20
- current_driver.driver
21
- end
22
-
23
24
  def on_establish_driver(&block)
24
25
  @establish_driver_block = block
25
26
  end
@@ -28,18 +29,10 @@ module ActiveGraph
28
29
  @establish_driver_block.call if @establish_driver_block
29
30
  end
30
31
 
31
- def new_driver(url, auth_token, options = {})
32
- verbose_query_logs = ActiveGraph::Config.fetch(:verbose_query_logs, false)
33
- ActiveGraph::Core::Driver
34
- .new(url, auth_token, options, verbose_query_logs: verbose_query_logs)
35
- end
36
-
37
- def transaction
38
- current_transaction || Transaction
39
- end
40
-
41
32
  def query(*args)
42
- transaction.query(*args)
33
+ transaction do
34
+ super(*args)
35
+ end
43
36
  end
44
37
 
45
38
  # Should support setting driver via config options
@@ -48,35 +41,24 @@ module ActiveGraph
48
41
  @driver = driver
49
42
  end
50
43
 
51
- def run_transaction(run_in_tx = true)
52
- Transaction.run(current_driver, run_in_tx) do |tx|
53
- yield tx
54
- end
55
- end
56
-
57
- def new_transaction
44
+ def validating_transaction(&block)
58
45
  validate_model_schema!
59
- ActiveGraph::Transaction.new
46
+ transaction(&block)
60
47
  end
61
48
 
62
49
  def new_query(options = {})
63
50
  validate_model_schema!
64
- ActiveGraph::Core::Query.new({driver: current_driver}.merge(options))
51
+ ActiveGraph::Core::Query.new(options)
65
52
  end
66
53
 
67
54
  def magic_query(*args)
68
55
  if args.empty? || args.map(&:class) == [Hash]
69
- Base.new_query(*args)
56
+ new_query(*args)
70
57
  else
71
- Base.current_driver.query(*args)
58
+ query(*args)
72
59
  end
73
60
  end
74
61
 
75
- def current_transaction
76
- validate_model_schema!
77
- Transaction.root
78
- end
79
-
80
62
  def label_object(label_name)
81
63
  ActiveGraph::Core::Label.new(label_name)
82
64
  end
@@ -1,6 +1,7 @@
1
1
  require 'active_support/concern'
2
2
  require 'active_support/notifications'
3
3
  require 'active_graph/ansi'
4
+ require 'active_graph/core/logging'
4
5
 
5
6
  module ActiveGraph
6
7
  module Core
@@ -14,7 +15,7 @@ module ActiveGraph
14
15
  def subscribe_to_request
15
16
  ActiveSupport::Notifications.subscribe('neo4j.core.bolt.request') do |_, start, finish, _id, _payload|
16
17
  ms = (finish - start) * 1000
17
- yield " #{ANSI::BLUE}BOLT:#{ANSI::CLEAR} #{ANSI::YELLOW}#{ms.round}ms#{ANSI::CLEAR} #{Base.current_driver.url}"
18
+ yield " #{ANSI::BLUE}BOLT:#{ANSI::CLEAR} #{ANSI::YELLOW}#{ms.round}ms#{ANSI::CLEAR}"
18
19
  end
19
20
  end
20
21
 
@@ -27,7 +28,7 @@ module ActiveGraph
27
28
  source_line, line_number = Logging.first_external_path_and_line(caller_locations)
28
29
 
29
30
  yield " #{ANSI::CYAN}#{query.context || 'CYPHER'}#{ANSI::CLEAR} #{cypher} #{params_string}" +
30
- ("\n ↳ #{source_line}:#{line_number}" if Base.current_driver.options[:verbose_query_logs] && source_line).to_s
31
+ ("\n ↳ #{source_line}:#{line_number}" if ActiveGraph::Config.fetch(:verbose_query_logs, false) && source_line).to_s
31
32
  end
32
33
  end
33
34
  end
@@ -76,7 +76,7 @@ module ActiveGraph
76
76
  end
77
77
 
78
78
  def constraints(_options = {})
79
- ActiveGraph::Transaction.constraints.select do |definition|
79
+ ActiveGraph::Base.constraints.select do |definition|
80
80
  definition[:label] == @name.to_sym
81
81
  end
82
82
  end
@@ -109,13 +109,13 @@ module ActiveGraph
109
109
 
110
110
  class << self
111
111
  def indexes
112
- ActiveGraph::Transaction.indexes
112
+ ActiveGraph::Base.indexes
113
113
  end
114
114
 
115
115
  def drop_indexes
116
116
  indexes.each do |definition|
117
117
  begin
118
- ActiveGraph::Transaction.query("DROP INDEX ON :`#{definition[:label]}`(#{definition[:properties][0]})")
118
+ ActiveGraph::Base.query("DROP INDEX ON :`#{definition[:label]}`(#{definition[:properties][0]})")
119
119
  rescue Neo4j::Driver::Exceptions::DatabaseException
120
120
  # This will error on each constraint. Ignore and continue.
121
121
  next
@@ -124,11 +124,10 @@ module ActiveGraph
124
124
  end
125
125
 
126
126
  def drop_constraints
127
- ActiveGraph::Transaction.named_constraints.each do |constraint|
128
- ActiveGraph::Transaction.query("DROP CONSTRAINT #{constraint.name}")
129
- end
130
- ActiveGraph::Transaction.constraints.each do |definition|
131
- ActiveGraph::Transaction.query("DROP CONSTRAINT ON (n:`#{definition[:label]}`) ASSERT n.`#{definition[:properties][0]}` IS UNIQUE")
127
+ ActiveGraph::Base.transaction do |tx|
128
+ tx.run('CALL db.constraints').each do |record|
129
+ tx.run("DROP #{record.keys.include?(:name) ? "CONSTRAINT #{record[:name]}" : record[:description]}")
130
+ end
132
131
  end
133
132
  end
134
133
 
@@ -147,7 +146,7 @@ module ActiveGraph
147
146
  end
148
147
 
149
148
  def schema_query(cypher)
150
- ActiveGraph::Transaction.transaction { |tx| tx.query(cypher, {}) }
149
+ ActiveGraph::Base.query(cypher, {})
151
150
  end
152
151
 
153
152
  def validate_index_options!(options)
@@ -30,7 +30,7 @@ module ActiveGraph
30
30
  def neo4j_gem_path
31
31
  return if !defined?(::Rails.root)
32
32
 
33
- @neo4j_gem_path ||= File.expand_path('../../..', ActiveGraph::Base.method(:current_driver).source_location[0])
33
+ @neo4j_gem_path ||= File.expand_path('../../..', ActiveGraph::Base.method(:driver).source_location[0])
34
34
  end
35
35
 
36
36
  def active_support_gem_path
@@ -27,29 +27,8 @@ module ActiveGraph
27
27
 
28
28
  query_builder.instance_eval(&block)
29
29
 
30
- new_or_current_transaction(options[:transaction]) do |tx|
31
- query_set(tx, query_builder.queries, { commit: !options[:transaction] }.merge(options))
32
- end
33
- end
34
-
35
- # If called without a block, returns a Transaction object
36
- # which can be used to call query/queries/mark_failed/commit
37
- # If called with a block, the Transaction object is yielded
38
- # to the block and `commit` is ensured. Any uncaught exceptions
39
- # will mark the transaction as failed first
40
- def transaction
41
- return Transaction.new unless block_given?
42
-
43
- begin
44
- tx = transaction
45
-
46
- yield tx
47
- rescue => e
48
- tx.mark_failed if tx
49
-
50
- raise e
51
- ensure
52
- tx.close if tx
30
+ transaction do
31
+ query_set(query_builder.queries, options)
53
32
  end
54
33
  end
55
34
 
@@ -60,28 +39,20 @@ module ActiveGraph
60
39
  end
61
40
  end
62
41
 
63
- def query_set(transaction, queries, options = {})
42
+ def query_set(queries, options = {})
64
43
  setup_queries!(queries, skip_instrumentation: options[:skip_instrumentation])
65
44
 
66
45
  ActiveSupport::Notifications.instrument('neo4j.core.bolt.request') do
67
46
  self.wrap_level = options[:wrap_level]
68
- queries.map do |query|
69
- result_from_data(transaction.root_tx.run(query.cypher, query.parameters))
47
+ transaction do |tx|
48
+ queries.map do |query|
49
+ result_from_data(tx.run(query.cypher, query.parameters))
50
+ end
70
51
  end
71
52
  rescue Neo4j::Driver::Exceptions::Neo4jException => e
72
53
  raise ActiveGraph::Core::CypherError.new_from(e.code, e.message) # , e.stack_track.to_a
73
54
  end
74
55
  end
75
-
76
- private
77
-
78
- def new_or_current_transaction(tx, &block)
79
- if tx
80
- yield(tx)
81
- else
82
- transaction(&block)
83
- end
84
- end
85
56
  end
86
57
  end
87
58
  end
@@ -68,8 +68,6 @@ module ActiveGraph
68
68
  end
69
69
 
70
70
  def initialize(options = {})
71
- @driver = options[:driver]
72
-
73
71
  @options = options
74
72
  @clauses = []
75
73
  @_params = {}
@@ -237,7 +235,7 @@ module ActiveGraph
237
235
  def response
238
236
  return @response if @response
239
237
 
240
- @response = ActiveGraph::Transaction.query(self, transaction: Transaction.root, wrap_level: (:core_entity if unwrapped?))
238
+ @response = ActiveGraph::Base.query(self, wrap_level: (:core_entity if unwrapped?))
241
239
  end
242
240
 
243
241
  def raise_if_cypher_error!(response)
@@ -374,7 +372,7 @@ module ActiveGraph
374
372
  end
375
373
 
376
374
  def &(other)
377
- self.class.new(driver: @driver).tap do |new_query|
375
+ self.class.new.tap do |new_query|
378
376
  new_query.options = options.merge(other.options)
379
377
  new_query.clauses = clauses + other.clauses
380
378
  end.params(other._params)
@@ -23,9 +23,7 @@ module ActiveGraph
23
23
  end
24
24
 
25
25
  def query
26
- # `nil` drivers are just a workaround until
27
- # we phase out `Query` objects containing drivers
28
- ActiveGraph::Core::Query.new(driver: nil)
26
+ ActiveGraph::Core::Query.new
29
27
  end
30
28
  end
31
29
  end
@@ -24,11 +24,6 @@ module ActiveGraph
24
24
  end
25
25
  end
26
26
 
27
- def named_constraints
28
- result = query('CALL db.constraints()', {}, skip_instrumentation: true)
29
- result.columns.include?(:name) ? result : []
30
- end
31
-
32
27
  private
33
28
 
34
29
  def v4_filter(row)
@@ -1,7 +1,6 @@
1
1
  require 'active_graph/transaction'
2
2
  require 'active_graph/core/instrumentable'
3
3
  require 'active_graph/core/query'
4
- require 'active_graph/core/driver'
5
4
  require 'active_graph/core/responses'
6
5
 
7
6
  require 'neo4j_ruby_driver'
@@ -28,7 +28,7 @@ module ActiveGraph
28
28
  end
29
29
 
30
30
  def query(*args)
31
- ActiveGraph::Base.current_driver.query(*args)
31
+ ActiveGraph::Base.query(*args)
32
32
  end
33
33
 
34
34
  class AddIdProperty < ActiveGraph::Migration
@@ -115,7 +115,7 @@ MESSAGE
115
115
  # def id_batch_set(label, id_property, new_ids, count)
116
116
  # tx = ActiveGraph::Base.new_transaction
117
117
 
118
- # ActiveGraph::Base.current_driver.query("MATCH (n:`#{label}`) WHERE NOT EXISTS(n.#{id_property})
118
+ # ActiveGraph::Base.query("MATCH (n:`#{label}`) WHERE NOT EXISTS(n.#{id_property})
119
119
  # with COLLECT(n) as nodes, #{new_ids} as ids
120
120
  # FOREACH(i in range(0,#{count - 1})|
121
121
  # FOREACH(node in [nodes[i]]|
@@ -63,11 +63,11 @@ module ActiveGraph
63
63
  end
64
64
 
65
65
  def migration_transaction(&block)
66
- ActiveGraph::Base.run_transaction(transactions?, &block)
66
+ transactions? ? ActiveGraph::Base.transaction(&block) : block.call
67
67
  end
68
68
 
69
69
  def log_queries
70
- subscriber = ActiveGraph::Transaction.subscribe_to_query(&method(:output))
70
+ subscriber = ActiveGraph::Base.subscribe_to_query(&method(:output))
71
71
  yield
72
72
  ensure
73
73
  ActiveSupport::Notifications.unsubscribe(subscriber) if subscriber
@@ -27,23 +27,20 @@ module ActiveGraph
27
27
  end
28
28
 
29
29
  def id_batch_set(label, id_property, new_ids, count)
30
- tx = ActiveGraph::Base.new_transaction
31
-
32
- execute("MATCH (n:`#{label}`) WHERE NOT EXISTS(n.#{id_property})
30
+ ActiveGraph::Base.transaction do
31
+ execute("MATCH (n:`#{label}`) WHERE NOT EXISTS(n.#{id_property})
33
32
  with COLLECT(n) as nodes, #{new_ids} as ids
34
33
  FOREACH(i in range(0,#{count - 1})|
35
34
  FOREACH(node in [nodes[i]]|
36
35
  SET node.#{id_property} = ids[i]))
37
36
  RETURN distinct(true)
38
37
  LIMIT #{count}")
39
-
40
- count
41
- rescue ActiveGraph::Server::CypherResponse::ResponseError, Faraday::TimeoutError
38
+ count
39
+ end
40
+ rescue ActiveGraph::Server::CypherResponse::ResponseError
42
41
  new_max_per_batch = (max_per_batch * 0.8).round
43
42
  output "Error querying #{max_per_batch} nodes. Trying #{new_max_per_batch}"
44
43
  new_max_per_batch
45
- ensure
46
- tx.close
47
44
  end
48
45
 
49
46
  def print_status(last_time_taken, max_per_batch, nodes_left)
@@ -2,16 +2,16 @@ module ActiveGraph
2
2
  module Migrations
3
3
  module Schema
4
4
  class << self
5
- def fetch_schema_data(driver)
6
- {constraints: fetch_constraint_descriptions(driver).sort,
7
- indexes: fetch_index_descriptions(driver).sort}
5
+ def fetch_schema_data
6
+ {constraints: fetch_constraint_descriptions.sort,
7
+ indexes: fetch_index_descriptions.sort}
8
8
  end
9
9
 
10
- def synchronize_schema_data(driver, schema_data, remove_missing)
10
+ def synchronize_schema_data(schema_data, remove_missing)
11
11
  queries = []
12
12
  queries += drop_and_create_queries(fetch_constraint_descriptions(driver), schema_data[:constraints], remove_missing)
13
13
  queries += drop_and_create_queries(fetch_index_descriptions(driver), schema_data[:indexes], remove_missing)
14
- driver.queries do
14
+ ActiveGraph::Base.queries do
15
15
  queries.each { |query| append query }
16
16
  end
17
17
  end
@@ -19,11 +19,11 @@ module ActiveGraph
19
19
  private
20
20
 
21
21
  def fetch_constraint_descriptions(driver)
22
- driver.query('CALL db.constraints()').map(&:description)
22
+ ActiveGraph::Base.query('CALL db.constraints()').map(&:description)
23
23
  end
24
24
 
25
25
  def fetch_index_descriptions(driver)
26
- result = driver.query('CALL db.indexes()')
26
+ result = ActiveGraph::Base.query('CALL db.indexes()')
27
27
  if result.columns.include?(:description)
28
28
  v3_indexes(result)
29
29
  else
@@ -32,7 +32,7 @@ module ActiveGraph
32
32
  def model_constraints
33
33
  return @model_constraints if @model_constraints
34
34
 
35
- constraints = ActiveGraph::Transaction.constraints.each_with_object({}) do |row, result|
35
+ constraints = ActiveGraph::Base.constraints.each_with_object({}) do |row, result|
36
36
  result[row[:label]] ||= []
37
37
  result[row[:label]] << row[:properties]
38
38
  end
@@ -43,7 +43,7 @@ module ActiveGraph
43
43
  def model_indexes
44
44
  return @model_indexes if @model_indexes
45
45
 
46
- indexes = ActiveGraph::Transaction.indexes.each_with_object({}) do |row, result|
46
+ indexes = ActiveGraph::Base.indexes.each_with_object({}) do |row, result|
47
47
  result[row[:label]] ||= []
48
48
  result[row[:label]] << row[:properties]
49
49
  end
@@ -446,7 +446,7 @@ module ActiveGraph::Node
446
446
 
447
447
  clear_deferred_nodes_for_association(name)
448
448
 
449
- self.class.run_transaction { association_proxy(name).replace_with(other_nodes) }
449
+ ActiveGraph::Base.transaction { association_proxy(name).replace_with(other_nodes) }
450
450
  end
451
451
  end
452
452
 
@@ -524,7 +524,7 @@ module ActiveGraph::Node
524
524
  if persisted?
525
525
  other_node.save if other_node.respond_to?(:persisted?) && !other_node.persisted?
526
526
  association_proxy_cache.clear # TODO: Should probably just clear for this association...
527
- self.class.run_transaction { association_proxy(name).replace_with(other_node) }
527
+ ActiveGraph::Base.transaction { association_proxy(name).replace_with(other_node) }
528
528
  # handle_non_persisted_node(other_node)
529
529
  else
530
530
  defer_create(name, other_node, clear: true)
@@ -93,10 +93,9 @@ module ActiveGraph::Node
93
93
  end
94
94
 
95
95
  # The pending associations are cleared during the save process, so it's necessary to
96
- # build the processable hash before it begins. If there are nodes and associations that
97
- # need to be created after the node is saved, a new transaction is started.
96
+ # build the processable hash before it begins.
98
97
  def cascade_save
99
- self.class.run_transaction(pending_deferred_creations?) do
98
+ ActiveGraph::Base.transaction do
100
99
  yield.tap { process_unpersisted_nodes! }
101
100
  end
102
101
  end
@@ -205,7 +205,7 @@ module ActiveGraph
205
205
  fail 'Can only create relationships on associations' if !@association
206
206
  other_nodes = _nodeify!(*other_nodes)
207
207
 
208
- ActiveGraph::Base.run_transaction do
208
+ ActiveGraph::Base.transaction do
209
209
  other_nodes.each do |other_node|
210
210
  if other_node.neo_id
211
211
  other_node.try(:delete_reverse_has_one_core_rel, association)
@@ -152,10 +152,10 @@ module ActiveGraph
152
152
  fail 'Method invalid when called on Class objects' unless source_object
153
153
  result = self.where(params).first
154
154
  return result unless result.nil?
155
- ActiveGraph::Base.run_transaction do
155
+ ActiveGraph::Base.transaction do
156
156
  node = model.create(params)
157
157
  self << node
158
- return node
158
+ node
159
159
  end
160
160
  end
161
161
 
@@ -46,6 +46,7 @@ module ActiveGraph
46
46
  include ActiveGraph::Node::Enum
47
47
  include ActiveGraph::Shared::PermittedAttributes
48
48
  include ActiveGraph::Node::DependentCallbacks
49
+ include ActiveGraph::Transactions
49
50
 
50
51
  def initialize(args = nil)
51
52
  self.class.ensure_id_property_info! # So that we make sure all objects have an id_property
@@ -2,7 +2,6 @@ require 'active_support/notifications'
2
2
  require 'rails/railtie'
3
3
  # Need the action_dispatch railtie to have action_dispatch.rescue_responses initialized correctly
4
4
  require 'action_dispatch/railtie'
5
- require 'active_graph/core/driver'
6
5
 
7
6
  module ActiveGraph
8
7
  class Railtie < ::Rails::Railtie
@@ -65,7 +64,7 @@ module ActiveGraph
65
64
  auth_token ||= username ? Neo4j::Driver::AuthTokens.basic(username, password) : Neo4j::Driver::AuthTokens.none
66
65
  register_neo4j_cypher_logging
67
66
 
68
- ActiveGraph::Base.new_driver(url || path || default_driver_path_or_url, auth_token, config)
67
+ Neo4j::Driver::GraphDatabase.driver(url || path || default_driver_path_or_url, auth_token, config)
69
68
  end
70
69
 
71
70
  def final_driver_config!(neo4j_config)
@@ -99,8 +98,8 @@ module ActiveGraph
99
98
  logger_proc = ->(message) do
100
99
  (ActiveGraph::Config[:logger] ||= Rails.logger).debug message
101
100
  end
102
- ActiveGraph::Transaction.subscribe_to_query(&logger_proc)
103
- ActiveGraph::Transaction.subscribe_to_request(&logger_proc)
101
+ ActiveGraph::Base.subscribe_to_query(&logger_proc)
102
+ ActiveGraph::Base.subscribe_to_request(&logger_proc)
104
103
 
105
104
  @neo4j_cypher_logging_registered = true
106
105
  end
@@ -19,6 +19,7 @@ module ActiveGraph
19
19
  include ActiveGraph::Relationship::Types
20
20
  include ActiveGraph::Shared::Enum
21
21
  include ActiveGraph::Shared::PermittedAttributes
22
+ include ActiveGraph::Transactions
22
23
 
23
24
  class FrozenRelError < ActiveGraph::Error; end
24
25
 
@@ -20,16 +20,14 @@ module ActiveGraph
20
20
  end
21
21
 
22
22
  def destroy #:nodoc:
23
- tx = ActiveGraph::Base.new_transaction
24
- tx.root.after_commit { run_callbacks(:destroy_commit) {} }
25
- run_callbacks(:destroy) { super }
23
+ ActiveGraph::Base.validating_transaction do |tx|
24
+ tx.after_commit { run_callbacks(:destroy_commit) {} }
25
+ run_callbacks(:destroy) { super }
26
+ end
26
27
  rescue
27
28
  @_deleted = false
28
29
  @attributes = @attributes.dup
29
- tx.mark_failed if tx
30
30
  raise
31
- ensure
32
- tx.close if tx
33
31
  end
34
32
 
35
33
  def touch #:nodoc:
@@ -51,15 +49,15 @@ module ActiveGraph
51
49
  end
52
50
 
53
51
  def create_model #:nodoc:
54
- self.class.run_transaction do |tx|
55
- tx.root.after_commit { run_callbacks(:create_commit) {} }
52
+ ActiveGraph::Base.transaction do |tx|
53
+ tx.after_commit { run_callbacks(:create_commit) {} }
56
54
  run_callbacks(:create) { super }
57
55
  end
58
56
  end
59
57
 
60
58
  def update_model(*) #:nodoc:
61
- self.class.run_transaction do |tx|
62
- tx.root.after_commit { run_callbacks(:update_commit) {} }
59
+ ActiveGraph::Base.transaction do |tx|
60
+ tx.after_commit { run_callbacks(:update_commit) {} }
63
61
  run_callbacks(:update) { super }
64
62
  end
65
63
  end
@@ -89,14 +89,10 @@ module ActiveGraph::Shared
89
89
  @_create_or_updating = true
90
90
  apply_default_values
91
91
  result = _persisted_obj ? update_model : create_model
92
- current_transaction = ActiveGraph::Base.current_transaction
93
92
 
94
- current_transaction.mark_failed if result == false && current_transaction
93
+ ActiveGraph::Base.transaction(&:failure) if result == false
95
94
 
96
95
  result != false
97
- rescue => e
98
- current_transaction.mark_failed if current_transaction
99
- raise e
100
96
  ensure
101
97
  @_create_or_updating = nil
102
98
  end
@@ -180,10 +176,10 @@ module ActiveGraph::Shared
180
176
  # Updates this resource with all the attributes from the passed-in Hash and requests that the record be saved.
181
177
  # If saving fails because the resource is invalid then false will be returned.
182
178
  def update(attributes)
183
- self.class.run_transaction do |tx|
179
+ ActiveGraph::Base.transaction do |tx|
184
180
  self.attributes = process_attributes(attributes)
185
181
  saved = save
186
- tx.mark_failed unless saved
182
+ tx.failure unless saved
187
183
  saved
188
184
  end
189
185
  end
@@ -197,7 +193,7 @@ module ActiveGraph::Shared
197
193
 
198
194
  def update_db_properties(hash)
199
195
  fail ::ActiveGraph::Error, 'can not update on a new record object' unless persisted?
200
- self.class.run_transaction do
196
+ ActiveGraph::Base.transaction do
201
197
  db_values = props_for_db(hash)
202
198
  neo4j_query(query_as(:n).set(n: db_values))
203
199
  db_values.each_pair { |k, v| self.public_send(:"#{k}=", v) }
@@ -210,7 +206,7 @@ module ActiveGraph::Shared
210
206
 
211
207
  # Same as {#update_attributes}, but raises an exception if saving fails.
212
208
  def update!(attributes)
213
- self.class.run_transaction do
209
+ ActiveGraph::Base.transaction do
214
210
  self.attributes = process_attributes(attributes)
215
211
  save!
216
212
  end
@@ -227,12 +223,6 @@ module ActiveGraph::Shared
227
223
  end
228
224
  end
229
225
 
230
- module ClassMethods
231
- def run_transaction(run_in_tx = true)
232
- ActiveGraph::Base.run_transaction(run_in_tx) { |tx| yield tx }
233
- end
234
- end
235
-
236
226
  protected
237
227
 
238
228
  def increment_by_query!(match_query, attribute, by, element_name = :n)
@@ -14,7 +14,7 @@ module ActiveGraph
14
14
 
15
15
  # remove?
16
16
  def neo4j_driver
17
- ActiveGraph::Base.current_driver
17
+ ActiveGraph::Base.driver
18
18
  end
19
19
 
20
20
  # remove?
@@ -9,8 +9,8 @@ if !defined?(Rails) && !Rake::Task.task_defined?('environment')
9
9
  require 'ostruct'
10
10
  neo4j_url = ENV['NEO4J_URL'] || 'http://localhost:7474'
11
11
  $LOAD_PATH.unshift File.dirname('./')
12
- ActiveGraph::Base.on_establish_session do
13
- ActiveGraph::Base.new_driver(neo4j_url)
12
+ ActiveGraph::Base.on_establish_driver do
13
+ Neo4j::Driver::GraphDatabase.driver(neo4j_url)
14
14
  end
15
15
  end
16
16
  end
@@ -64,7 +64,7 @@ namespace :neo4j do
64
64
  COMMENT
65
65
 
66
66
  def check_neo4j_version_3
67
- if ActiveGraph::Base.transaction.version > '3.0.0'
67
+ if ActiveGraph::Base.version > '3.0.0'
68
68
  yield
69
69
  else
70
70
  puts 'WARNING: This task does not work for versions of Neo4j before 3.0.0'
@@ -76,7 +76,7 @@ COMMENT
76
76
  check_neo4j_version_3 do
77
77
  require 'active_graph/migrations/schema'
78
78
 
79
- schema_data = ActiveGraph::Migrations::Schema.fetch_schema_data(ActiveGraph::Base.transaction)
79
+ schema_data = ActiveGraph::Migrations::Schema.fetch_schema_data
80
80
 
81
81
  runner = ActiveGraph::Migrations::Runner.new
82
82
  schema_data[:versions] = runner.complete_migration_versions.sort
@@ -97,13 +97,13 @@ COMMENT
97
97
 
98
98
  schema_data = YAML.safe_load(File.read(SCHEMA_YAML_PATH), [Symbol])
99
99
 
100
- ActiveGraph::Transaction.subscribe_to_query(&method(:puts))
100
+ ActiveGraph::Base.subscribe_to_query(&method(:puts))
101
101
 
102
- ActiveGraph::Base.run_transaction do
103
- ActiveGraph::Migrations::Schema.synchronize_schema_data(ActiveGraph::Base.transaction, schema_data, args[:remove_missing])
102
+ ActiveGraph::Base.transaction do
103
+ ActiveGraph::Migrations::Schema.synchronize_schema_data(schema_data, args[:remove_missing])
104
104
  end
105
105
 
106
- ActiveGraph::Base.run_transaction do
106
+ ActiveGraph::Base.transaction do
107
107
  runner = ActiveGraph::Migrations::Runner.new
108
108
  runner.mark_versions_as_complete(schema_data[:versions]) # Run in test mode?
109
109
  end
@@ -1,139 +1,24 @@
1
- require 'active_support/core_ext/module/delegation'
2
- require 'active_support/core_ext/module/attribute_accessors_per_thread'
3
- require 'active_graph/core/querable'
4
- require 'active_graph/core/schema'
5
-
6
1
  module ActiveGraph
7
- class Transaction
8
- include ActiveGraph::Core::Querable
9
- extend ActiveGraph::Core::Schema
10
-
11
- thread_mattr_accessor :stack
12
- attr_reader :root
13
- attr_reader :driver_tx, :driver_session
14
-
15
- class << self
16
- # Runs the given block in a new transaction.
17
- # @param [Boolean] run_in_tx if true a new transaction will not be created, instead if will simply yield to the given block
18
- # @@yield [ActiveGraph::Transaction::Instance]
19
- def run(_driver, run_in_tx)
20
- return yield(nil) unless run_in_tx
21
-
22
- tx = ActiveGraph::Transaction.new
23
- yield tx
24
- rescue Exception => e # rubocop:disable Lint/RescueException
25
- tx.mark_failed unless tx.nil?
26
- raise e
27
- ensure
28
- tx.close unless tx.nil?
29
- end
30
-
31
- def root
32
- initialized_stack.first
33
- end
34
-
35
- def initialized_stack
36
- self.stack ||= []
37
- end
38
- end
39
-
40
- def initialize(_options = {})
41
- self.class.initialized_stack << self
42
- @root = stack.first
43
- return unless root?
44
- @driver_session = Base.current_driver.driver.session(Neo4j::Driver::AccessMode::WRITE)
45
- @driver_tx = @driver_session.begin_transaction
46
- rescue StandardError => e
47
- self.stack = []
48
- @driver_tx.close if @driver_tx
49
- @driver_session.close if @driver_session
50
- raise e
51
- end
52
-
53
- # Commits or marks this transaction for rollback, depending on whether #mark_failed has been previously invoked.
54
- def close
55
- fail 'Tried closing when transaction stack is empty (maybe you closed too many?)' if stack.empty?
56
- fail "Closed transaction which wasn't the most recent on the stack (maybe you forgot to close one?)" if stack.pop != self
57
-
58
- post_close! if stack.empty?
59
- end
60
-
61
- # Marks this transaction as failed,
62
- # which means that it will unconditionally be rolled back
63
- # when #close is called.
64
- # Aliased for legacy purposes.
65
- def mark_failed
66
- root.mark_failed if root && root != self
2
+ module Transaction
3
+ def failure
4
+ super
67
5
  @failure = true
68
6
  end
69
7
 
70
- alias failure mark_failed
71
-
72
- # If it has been marked as failed.
73
- # Aliased for legacy purposes.
74
- def failed?
75
- !!@failure
76
- end
77
-
78
- alias failure? failed?
79
-
80
- def root?
81
- @root == self
82
- end
83
-
84
- def query(*args)
85
- options = if args[0].is_a?(::ActiveGraph::Core::Query)
86
- args[1] ||= {}
87
- else
88
- args[1] ||= {}
89
- args[2] ||= {}
90
- end
91
- options[:transaction] ||= self
92
-
93
- self.class.query(*args)
94
- end
95
-
96
- def queries(options = {}, &block)
97
- self.class.queries({ transaction: self }.merge(options), &block)
98
- end
99
-
100
- def after_commit_registry
101
- @after_commit_registry ||= []
8
+ def close
9
+ success
10
+ super
11
+ after_commit_registry.each(&:call) unless @failure
102
12
  end
103
13
 
104
14
  def after_commit(&block)
105
15
  after_commit_registry << block
106
16
  end
107
17
 
108
- def commit
109
- return unless root?
110
- begin
111
- @driver_tx.success
112
- @driver_tx.close
113
- ensure
114
- @driver_session.close
115
- end
116
- end
117
-
118
- def delete
119
- root.driver_tx.failure
120
- root.driver_tx.close
121
- root.driver_session.close
122
- end
123
-
124
- def root_tx
125
- root.driver_tx
126
- end
127
-
128
18
  private
129
19
 
130
- def post_close!
131
- if failed?
132
- delete
133
- else
134
- commit
135
- after_commit_registry.each(&:call)
136
- end
20
+ def after_commit_registry
21
+ @after_commit_registry ||= []
137
22
  end
138
23
  end
139
24
  end
@@ -5,50 +5,53 @@ module ActiveGraph
5
5
  extend ActiveSupport::Concern
6
6
 
7
7
  included do
8
- thread_mattr_accessor :ag_session, :tx
8
+ thread_mattr_accessor :explicit_session, :tx
9
9
  end
10
10
 
11
11
  class_methods do
12
12
  def session(*args)
13
- driver.session(*args) do |session|
14
- self.ag_session = session
13
+ ActiveGraph::Base.driver.session(*args) do |session|
14
+ self.explicit_session = session
15
15
  yield session
16
16
  session.last_bookmark
17
- ensure
18
- self.ag_session = nil
19
17
  end
20
18
  end
21
19
 
22
- def write_transaction(config = nil, &block)
23
- send_transaction(:write_transaction, config, &block)
20
+ def transaction(**config, &block)
21
+ send_transaction(:begin_transaction, **config, &block)
24
22
  end
25
- alias transaction write_transaction
26
23
 
27
- def read_transaction(config = nil, &block)
28
- send_transaction(:read_transaction, config, &block)
24
+ def write_transaction(**config, &block)
25
+ send_transaction(:write_transaction, **config, &block)
29
26
  end
30
27
 
31
- def begin_transaction(config = nil, &block)
32
- send_transaction(:begin_transaction, config, &block)
28
+ def read_transaction(**config, &block)
29
+ send_transaction(:read_transaction, **config, &block)
33
30
  end
34
31
 
35
32
  private
36
33
 
37
- def send_transaction(method, config = nil, &block)
38
- return yield tx if tx
39
- return reuse(ag_session, method, config, &block) if ag_session
40
- driver.session { |session| reuse(session, method, config, &block) }
34
+ def send_transaction(method, **config, &block)
35
+ return checked_yield(tx, &block) if tx&.open?
36
+ return run_transaction_work(explicit_session, method, **config, &block) if explicit_session&.open?
37
+ driver.session do |session|
38
+ run_transaction_work(session, method, **config, &block)
39
+ end
41
40
  end
42
41
 
43
- def reuse(session, method, config)
44
- session.send(method, config) do |tx|
42
+ def run_transaction_work(session, method, **config, &block)
43
+ session.send(method, **config) do |tx|
45
44
  self.tx = tx
46
- yield tx
47
- tx.success
48
- ensure
49
- self.tx = nil
45
+ checked_yield(tx, &block)
50
46
  end
51
47
  end
48
+
49
+ def checked_yield(tx)
50
+ yield tx
51
+ rescue StandardError => e
52
+ tx.failure
53
+ raise e
54
+ end
52
55
  end
53
56
  end
54
57
  end
@@ -1,3 +1,3 @@
1
1
  module ActiveGraph
2
- VERSION = '10.0.0-beta.3'
2
+ VERSION = '10.0.0-beta.4'
3
3
  end
data/lib/active_graph.rb CHANGED
@@ -4,6 +4,7 @@ require 'active_graph/version'
4
4
  require 'active_graph/core'
5
5
  require 'active_graph/core/query_ext' # From this gem
6
6
 
7
+ require 'active_support/core_ext/module/attribute_accessors_per_thread'
7
8
  require 'active_graph/transactions'
8
9
  require 'active_graph/base'
9
10
  require 'active_graph/model_schema'
@@ -118,3 +119,5 @@ if defined?(Rails)
118
119
  require 'rails/generators'
119
120
  require 'rails/generators/neo4j_generator'
120
121
  end
122
+
123
+ Neo4j::Driver::Transaction.prepend ActiveGraph::Transaction
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: activegraph
3
3
  version: !ruby/object:Gem::Version
4
- version: 10.0.0.pre.beta.3
4
+ version: 10.0.0.pre.beta.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andreas Ronge, Brian Underwood, Chris Grigg, Heinrich Klobuczek
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-03-12 00:00:00.000000000 Z
11
+ date: 2020-04-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activemodel
@@ -128,14 +128,14 @@ dependencies:
128
128
  requirements:
129
129
  - - ">="
130
130
  - !ruby/object:Gem::Version
131
- version: 0.3.0
131
+ version: 0.3.5
132
132
  type: :development
133
133
  prerelease: false
134
134
  version_requirements: !ruby/object:Gem::Requirement
135
135
  requirements:
136
136
  - - ">="
137
137
  - !ruby/object:Gem::Version
138
- version: 0.3.0
138
+ version: 0.3.5
139
139
  - !ruby/object:Gem::Dependency
140
140
  name: os
141
141
  requirement: !ruby/object:Gem::Requirement
@@ -196,14 +196,14 @@ dependencies:
196
196
  name: rubocop
197
197
  requirement: !ruby/object:Gem::Requirement
198
198
  requirements:
199
- - - "~>"
199
+ - - ">="
200
200
  - !ruby/object:Gem::Version
201
201
  version: 0.56.0
202
202
  type: :development
203
203
  prerelease: false
204
204
  version_requirements: !ruby/object:Gem::Requirement
205
205
  requirements:
206
- - - "~>"
206
+ - - ">="
207
207
  - !ruby/object:Gem::Version
208
208
  version: 0.56.0
209
209
  - !ruby/object:Gem::Dependency
@@ -262,7 +262,6 @@ files:
262
262
  - lib/active_graph/core.rb
263
263
  - lib/active_graph/core/connection_failed_error.rb
264
264
  - lib/active_graph/core/cypher_error.rb
265
- - lib/active_graph/core/driver.rb
266
265
  - lib/active_graph/core/instrumentable.rb
267
266
  - lib/active_graph/core/label.rb
268
267
  - lib/active_graph/core/logging.rb
@@ -1,49 +0,0 @@
1
- require 'active_support/core_ext/module/attribute_accessors'
2
- require 'active_graph/core/logging'
3
- require 'active_graph/version'
4
-
5
- module ActiveGraph
6
- module Core
7
- class Driver
8
- USER_AGENT_STRING = "activegraph-gem/#{::ActiveGraph::VERSION} (https://github.com/neo4jrb/activegraph)"
9
-
10
- attr_accessor :wrap_level
11
- attr_reader :options, :driver, :url
12
- delegate :close, to: :driver
13
-
14
- class << self
15
- def new_instance(url, auth_token, options = {})
16
- Neo4j::Driver::GraphDatabase.driver(url, auth_token, options)
17
- end
18
- end
19
-
20
- def initialize(url, auth_token = Neo4j::Driver::AuthTokens.none, options = {}, extended_options = {})
21
- @url = url
22
- @driver = self.class.new_instance(url, auth_token, options)
23
- @options = extended_options
24
- end
25
-
26
- def logger
27
- return @logger if @logger
28
-
29
- @logger = if @options[:logger]
30
- @options[:logger]
31
- else
32
- Logger.new(logger_location).tap do |logger|
33
- logger.level = logger_level
34
- end
35
- end
36
- end
37
-
38
- private
39
-
40
- def logger_location
41
- @options[:logger_location] || STDOUT
42
- end
43
-
44
- def logger_level
45
- @options[:logger_level] || Logger::WARN
46
- end
47
- end
48
- end
49
- end