activegraph 11.5.0.beta.1 → 12.0.0.beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (38) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +8 -0
  3. data/activegraph.gemspec +1 -1
  4. data/lib/active_graph/base.rb +4 -0
  5. data/lib/active_graph/core/element.rb +142 -0
  6. data/lib/active_graph/core/entity.rb +4 -0
  7. data/lib/active_graph/core/label.rb +5 -166
  8. data/lib/active_graph/core/node.rb +0 -4
  9. data/lib/active_graph/core/query_clauses.rb +4 -4
  10. data/lib/active_graph/core/schema.rb +23 -28
  11. data/lib/active_graph/core/type.rb +13 -0
  12. data/lib/active_graph/migrations/helpers/schema.rb +10 -13
  13. data/lib/active_graph/model_schema.rb +1 -1
  14. data/lib/active_graph/node/has_n.rb +1 -1
  15. data/lib/active_graph/node/labels.rb +15 -12
  16. data/lib/active_graph/node/persistence.rb +0 -11
  17. data/lib/active_graph/node/query/query_proxy/link.rb +15 -4
  18. data/lib/active_graph/node/query/query_proxy.rb +3 -3
  19. data/lib/active_graph/node/query/query_proxy_eager_loading.rb +1 -1
  20. data/lib/active_graph/node/query/query_proxy_enumerable.rb +4 -4
  21. data/lib/active_graph/node/query/query_proxy_methods.rb +14 -16
  22. data/lib/active_graph/node/query/query_proxy_methods_of_mass_updating.rb +1 -5
  23. data/lib/active_graph/node/query.rb +1 -1
  24. data/lib/active_graph/node/query_methods.rb +9 -12
  25. data/lib/active_graph/relationship/initialize.rb +2 -2
  26. data/lib/active_graph/relationship/persistence.rb +3 -1
  27. data/lib/active_graph/relationship/property.rb +1 -5
  28. data/lib/active_graph/relationship/query.rb +14 -9
  29. data/lib/active_graph/relationship/related_node.rb +4 -8
  30. data/lib/active_graph/relationship/types.rb +8 -0
  31. data/lib/active_graph/relationship/wrapping.rb +1 -1
  32. data/lib/active_graph/relationship.rb +4 -1
  33. data/lib/active_graph/shared/identity.rb +6 -3
  34. data/lib/active_graph/shared/persistence.rb +12 -1
  35. data/lib/active_graph/shared/query_factory.rb +1 -1
  36. data/lib/active_graph/shared/type_converters.rb +3 -2
  37. data/lib/active_graph/version.rb +1 -1
  38. metadata +21 -25
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c217d68abf8f640ef01f10e2d7a5b96c6fe7b6f3c4499d24da58718a90646acc
4
- data.tar.gz: d8bcda3316fd7cdc1422eb47b186f6eb7d853752d138f014e53a0e425c2f3e4f
3
+ metadata.gz: 5980a6fcd4bee8de9d49abdc805f45292b507d76b6d4299eb3424b57fd33dd98
4
+ data.tar.gz: 16a8d463cf9b8cf88d814b4a9fd33db8f83e92b3ab4cd2e903377e420b4acd24
5
5
  SHA512:
6
- metadata.gz: fa79ae2d367a183fb0a5a26363f352d15767540288ae080558fc876854100ecf01815fb76be5460d1f638c3c1a8799a5b44f09e7ce5d0efc8faa8a74baf9c187
7
- data.tar.gz: e39a318db8e56067cffbd7ba216d3951184124cb36b48da420334475472d63d17bff7d70027d4d7a9e495d7cb4cb7d4dd8b27b9a4c3bf44e265b24503802b2fd
6
+ metadata.gz: 02bb5a53486be92a3a8724a42525b02148065fb0461fe9400d31c95d3bf7cbe351028cd955fea96dd22ec587baae8abe6c4e9498d131a7019bbee0bb2c78d093
7
+ data.tar.gz: a98acca7075481e24e9926bfcbb8cb6fadefc9e11cef963fa146fc7c543e8682d7fcb8639e681c3fb5971738d01568623f59456cb93ce36de7c0eaf7a6500abf
data/CHANGELOG.md CHANGED
@@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file.
3
3
  This file should follow the standards specified on [http://keepachangelog.com/]
4
4
  This project adheres to [Semantic Versioning](http://semver.org/).
5
5
 
6
+ ## [12.0.0.beta.1] 2024-01-01
7
+
8
+ ## Added
9
+
10
+ - removed deprecated usage of id (neo_id), replaced with element_id, requires neo4j-ruby-driver 5
11
+ - removed the possibility of using neo_id as id_property
12
+ - added id_property to relationships
13
+
6
14
  ## [11.5.0.beta.1] 2023-12-29
7
15
 
8
16
  ## Added
data/activegraph.gemspec CHANGED
@@ -32,7 +32,7 @@ DESCRIPTION
32
32
 
33
33
  s.add_dependency('activemodel', '>= 7')
34
34
  s.add_dependency('i18n', '!= 1.8.8') # https://github.com/jruby/jruby/issues/6547
35
- s.add_dependency('neo4j-ruby-driver', '>= 4.4.1', '< 5')
35
+ s.add_dependency('neo4j-ruby-driver', '>= 5')
36
36
  s.add_dependency('orm_adapter', '>= 0.5.0')
37
37
  s.add_dependency('sorted_set')
38
38
  s.add_development_dependency('guard')
@@ -60,6 +60,10 @@ module ActiveGraph
60
60
  ActiveGraph::Core::Label.new(label_name)
61
61
  end
62
62
 
63
+ def element(name, relationship: false)
64
+ (relationship ? Core::Type : Core::Label).new(name)
65
+ end
66
+
63
67
  def logger
64
68
  @logger ||= (ActiveGraph::Config[:logger] || ActiveSupport::Logger.new(STDOUT))
65
69
  end
@@ -0,0 +1,142 @@
1
+ module ActiveGraph
2
+ module Core
3
+ class Element
4
+ attr_reader :name
5
+ delegate :version?, to: ActiveGraph::Base
6
+
7
+ def initialize(name)
8
+ @name = name
9
+ end
10
+
11
+ def create_index(*properties, **options)
12
+ validate_index_options!(options)
13
+ properties = properties.map { |p| "l.#{p}" }
14
+ schema_query("CREATE INDEX FOR (l:`#{@name}`) ON (#{properties.join('.')})")
15
+ end
16
+
17
+ def drop_index(property, options = {})
18
+ validate_index_options!(options)
19
+ schema_query("SHOW INDEXES YIELD * WHERE labelsOrTypes = $labels AND properties = $properties",
20
+ labels: [@name], properties: [property]).each do |record|
21
+ schema_query("DROP INDEX #{record[:name]}")
22
+ end
23
+ end
24
+
25
+ # Creates a neo4j constraint on a property
26
+ # See http://docs.neo4j.org/chunked/stable/query-constraints.html
27
+ # @example
28
+ # label = ActiveGraph::Label.create(:person)
29
+ # label.create_constraint(:name, {type: :unique})
30
+ #
31
+ def create_constraint(property, type: :key)
32
+ schema_query(
33
+ "CREATE CONSTRAINT #{constraint_name(property, type:)} FOR #{pattern("n:`#{name}`")} REQUIRE n.`#{property}` IS #{constraint_type(type:)}"
34
+ )
35
+ end
36
+
37
+ # Drops a neo4j constraint on a property
38
+ # See http://docs.neo4j.org/chunked/stable/query-constraints.html
39
+ # @example
40
+ # label = ActiveGraph::Label.create(:person)
41
+ # label.create_constraint(:name, {type: :unique})
42
+ # label.drop_constraint(:name, {type: :unique})
43
+ #
44
+ def drop_constraint(property, type: :key)
45
+ schema_query("DROP CONSTRAINT #{constraint_name(property, type:)} IF EXISTS")
46
+ end
47
+
48
+ def drop_uniqueness_constraint(property, options = {})
49
+ drop_constraint(property, type: :unique)
50
+ end
51
+
52
+ def indexes
53
+ self.class.indexes.select do |definition|
54
+ definition[:label] == @name.to_sym
55
+ end
56
+ end
57
+
58
+ def drop_indexes
59
+ self.class.drop_indexes
60
+ end
61
+
62
+ def index?(property)
63
+ indexes.any? { |definition| definition[:properties] == [property.to_sym] }
64
+ end
65
+
66
+ def constraints(_options = {})
67
+ ActiveGraph::Base.constraints.select do |definition|
68
+ definition[:label] == @name.to_sym
69
+ end
70
+ end
71
+
72
+ def uniqueness_constraints(_options = {})
73
+ constraints.select do |definition|
74
+ definition[:type] == :uniqueness
75
+ end
76
+ end
77
+
78
+ def constraint?(property)
79
+ constraints.any? { |definition| definition[:properties] == [property.to_sym] }
80
+ end
81
+
82
+ def uniqueness_constraint?(property)
83
+ uniqueness_constraints.include?([property])
84
+ end
85
+
86
+ private
87
+
88
+ class << self
89
+ def indexes
90
+ ActiveGraph::Base.indexes
91
+ end
92
+
93
+ def drop_indexes
94
+ indexes.each do |definition|
95
+ ActiveGraph::Base.query("DROP INDEX #{definition[:name]}") unless definition[:owningConstraint]
96
+ end
97
+ end
98
+
99
+ def drop_constraints
100
+ result = ActiveGraph::Base.read_transaction do |tx|
101
+ tx.run('SHOW CONSTRAINTS YIELD *').to_a
102
+ end
103
+ ActiveGraph::Base.write_transaction do |tx|
104
+ result.each do |record|
105
+ tx.run("DROP CONSTRAINT `#{record[:name]}`")
106
+ end
107
+ end
108
+ end
109
+ end
110
+
111
+ def schema_query(cypher, **params)
112
+ ActiveGraph::Base.query(cypher, params)
113
+ end
114
+
115
+ def validate_index_options!(options)
116
+ return unless options[:type] && options[:type] != :exact
117
+ fail "Type #{options[:type]} is not supported"
118
+ end
119
+
120
+ def constraint_type(type:)
121
+ case symnolic_type(type:)
122
+ when :key
123
+ "#{element_type} KEY"
124
+ when :unique
125
+ "UNIQUE"
126
+ when :not_null
127
+ "UNIQUE"
128
+ else
129
+ ":: #{type.to_s.upcase}"
130
+ end
131
+ end
132
+
133
+ def symnolic_type(type:)
134
+ type == :key && !ActiveGraph::Base.enterprise? ? :unique : type
135
+ end
136
+
137
+ def constraint_name(property, type:)
138
+ "`#{element_type}_#{name}##{property}_#{symnolic_type(type:)}`"
139
+ end
140
+ end
141
+ end
142
+ end
@@ -3,6 +3,10 @@
3
3
  module ActiveGraph
4
4
  module Core
5
5
  module Entity
6
+ def neo_id
7
+ element_id
8
+ end
9
+
6
10
  def properties
7
11
  @properties ||= super
8
12
  end
@@ -1,173 +1,12 @@
1
1
  module ActiveGraph
2
2
  module Core
3
- class Label
4
- attr_reader :name
5
- delegate :version?, to: ActiveGraph::Base
6
-
7
- def initialize(name)
8
- @name = name
9
- end
10
-
11
- def create_index(*properties, **options)
12
- validate_index_options!(options)
13
- if version?('>=4.4')
14
- properties = properties.map { |p| "l.#{p}" }
15
- fragment = "FOR (l:`#{@name}`) ON"
16
- else
17
- fragment = "ON :`#{@name}`"
18
- end
19
- schema_query("CREATE INDEX #{fragment} (#{properties.join('.')})")
20
- end
21
-
22
- def drop_index(property, options = {})
23
- validate_index_options!(options)
24
- if version?('<4.3')
25
- schema_query("DROP INDEX ON :`#{@name}`(#{property})")
26
- else
27
- schema_query("SHOW INDEXES YIELD * WHERE labelsOrTypes = $labels AND properties = $properties",
28
- labels: [@name], properties: [property]).each do |record|
29
- schema_query("DROP INDEX #{record[:name]}")
30
- end
31
- end
32
- end
33
-
34
- # Creates a neo4j constraint on a property
35
- # See http://docs.neo4j.org/chunked/stable/query-constraints.html
36
- # @example
37
- # label = ActiveGraph::Label.create(:person)
38
- # label.create_constraint(:name, {type: :unique})
39
- #
40
- def create_constraint(property, constraints)
41
- cypher = case constraints[:type]
42
- when :unique, :uniqueness
43
- _for, _require = version?('>=4.4') ? %w[FOR REQUIRE] : %w[ON ASSERT]
44
- "CREATE CONSTRAINT #{_for} (n:`#{name}`) #{_require} n.`#{property}` IS UNIQUE"
45
- else
46
- fail "Not supported constraint #{constraints.inspect} for property #{property} (expected :type => :unique)"
47
- end
48
- schema_query(cypher)
49
- end
50
-
51
- def create_uniqueness_constraint(property, options = {})
52
- create_constraint(property, options.merge(type: :unique))
53
- end
54
-
55
- # Drops a neo4j constraint on a property
56
- # See http://docs.neo4j.org/chunked/stable/query-constraints.html
57
- # @example
58
- # label = ActiveGraph::Label.create(:person)
59
- # label.create_constraint(:name, {type: :unique})
60
- # label.drop_constraint(:name, {type: :unique})
61
- #
62
- def drop_constraint(property, constraint)
63
- return drop_constraint42(property, constraint) if version?('<4.3')
64
- type = case constraint[:type]
65
- when :unique, :uniqueness
66
- 'UNIQUENESS'
67
- when :exists
68
- 'NODE_PROPERTY_EXISTENCE'
69
- else
70
- fail "Not supported constraint #{constraint.inspect}"
71
- end
72
- schema_query(
73
- 'SHOW CONSTRAINTS YIELD * WHERE type = $type AND labelsOrTypes = $labels AND properties = $properties',
74
- type: type, labels: [name], properties: [property]).first[:name].tap do |constraint_name|
75
- schema_query("DROP CONSTRAINT #{constraint_name}")
76
- end
77
- end
78
-
79
- def drop_uniqueness_constraint(property, options = {})
80
- drop_constraint(property, options.merge(type: :unique))
81
- end
82
-
83
- def indexes
84
- self.class.indexes.select do |definition|
85
- definition[:label] == @name.to_sym
86
- end
87
- end
88
-
89
- def drop_indexes
90
- self.class.drop_indexes
91
- end
92
-
93
- def index?(property)
94
- indexes.any? { |definition| definition[:properties] == [property.to_sym] }
95
- end
96
-
97
- def constraints(_options = {})
98
- ActiveGraph::Base.constraints.select do |definition|
99
- definition[:label] == @name.to_sym
100
- end
101
- end
102
-
103
- def uniqueness_constraints(_options = {})
104
- constraints.select do |definition|
105
- definition[:type] == :uniqueness
106
- end
107
- end
108
-
109
- def constraint?(property)
110
- constraints.any? { |definition| definition[:properties] == [property.to_sym] }
111
- end
112
-
113
- def uniqueness_constraint?(property)
114
- uniqueness_constraints.include?([property])
115
- end
116
-
117
- private
118
-
119
- class << self
120
- def indexes
121
- ActiveGraph::Base.indexes
122
- end
123
-
124
- def drop_indexes
125
- indexes.each do |definition|
126
- begin
127
- ActiveGraph::Base.query(
128
- if definition[:name]
129
- "DROP INDEX #{definition[:name]}"
130
- else
131
- "DROP INDEX ON :`#{definition[:label]}`(#{definition[:properties][0]})"
132
- end)
133
- rescue Neo4j::Driver::Exceptions::DatabaseException
134
- # This will error on each constraint. Ignore and continue.
135
- next
136
- end
137
- end
138
- end
139
-
140
- def drop_constraints
141
- result = ActiveGraph::Base.read_transaction do |tx|
142
- tx.run(ActiveGraph::Base.version?('<4.3') ? 'CALL db.constraints' : 'SHOW CONSTRAINTS YIELD *').to_a
143
- end
144
- ActiveGraph::Base.write_transaction do |tx|
145
- result.each do |record|
146
- tx.run("DROP #{record.keys.include?(:name) ? "CONSTRAINT #{record[:name]}" : record[:description]}")
147
- end
148
- end
149
- end
150
- end
151
-
152
- def schema_query(cypher, **params)
153
- ActiveGraph::Base.query(cypher, params)
154
- end
155
-
156
- def validate_index_options!(options)
157
- return unless options[:type] && options[:type] != :exact
158
- fail "Type #{options[:type]} is not supported"
3
+ class Label < Element
4
+ def pattern(spec)
5
+ "(#{spec})"
159
6
  end
160
7
 
161
- def drop_constraint42(property, constraint)
162
- cypher = case constraint[:type]
163
- when :unique, :uniqueness
164
- "n.`#{property}` IS UNIQUE"
165
- when :exists
166
- "exists(n.`#{property}`)"
167
- else
168
- fail "Not supported constraint #{constraint.inspect}"
169
- end
170
- schema_query("DROP CONSTRAINT ON (n:`#{name}`) ASSERT #{cypher}")
8
+ def element_type
9
+ 'NODE'
171
10
  end
172
11
  end
173
12
  end
@@ -3,10 +3,6 @@
3
3
  module ActiveGraph
4
4
  module Core
5
5
  module Node
6
- def neo_id
7
- id
8
- end
9
-
10
6
  def labels
11
7
  @labels ||= super
12
8
  end
@@ -158,7 +158,7 @@ module ActiveGraph
158
158
  end
159
159
 
160
160
  def from_key_and_single_value(key, value)
161
- value.to_sym == :neo_id ? "ID(#{key})" : "#{key}.#{value}"
161
+ value.to_sym == :neo_id ? "elementId(#{key})" : "#{key}.#{value}"
162
162
  end
163
163
  end
164
164
 
@@ -200,7 +200,7 @@ module ActiveGraph
200
200
  end
201
201
 
202
202
  def array_value?(value, is_set)
203
- value.is_a?(Array) && !is_set
203
+ value.is_a?(Enumerable) && !is_set
204
204
  end
205
205
 
206
206
  def format_label(label_arg)
@@ -316,8 +316,8 @@ module ActiveGraph
316
316
  def hash_key_value_string(key, value, previous_keys)
317
317
  value.map do |k, v|
318
318
  if k.to_sym == :neo_id
319
- v = Array(v).map { |item| (item.respond_to?(:neo_id) ? item.neo_id : item).to_i }
320
- key_value_string("ID(#{key})", v)
319
+ v = Array(v).map { |item| item.respond_to?(:neo_id) ? item.neo_id : item }
320
+ key_value_string("elementId(#{key})", v)
321
321
  else
322
322
  "#{key}.#{from_key_and_value(k, v, previous_keys + [key])}"
323
323
  end
@@ -1,21 +1,20 @@
1
1
  module ActiveGraph
2
2
  module Core
3
3
  module Schema
4
- FILTER = {
5
- 3 => [:type, 'node_unique_property'],
6
- 4 => [:uniqueness, 'UNIQUE'],
7
- }
8
-
9
4
  def version
10
- @version ||= read_transaction do
11
- # BTW: community / enterprise could be retrieved via `result.first.edition`
12
- query('CALL dbms.components()', {}, skip_instrumentation: true).first[:versions][0]
13
- .then(&Gem::Version.method(:new))
14
- end
5
+ Gem::Version.new(component[:versions][0])
6
+ end
7
+
8
+ def edition
9
+ component[:edition]
10
+ end
11
+
12
+ def enterprise?
13
+ edition == 'enterprise'
15
14
  end
16
15
 
17
16
  def version?(requirement)
18
- Gem::Requirement.create(requirement).satisfied_by?(Gem::Version.new(version))
17
+ Gem::Requirement.create(requirement).satisfied_by?(version)
19
18
  end
20
19
 
21
20
  def indexes
@@ -24,17 +23,12 @@ module ActiveGraph
24
23
 
25
24
  def normalize(result, *extra)
26
25
  result.map do |row|
27
- definition(row, version?('<4') ? :index_cypher_v3 : :index_cypher)
28
- .merge(extra.to_h { |key| [key, row[key].to_sym] })
26
+ definition(row, :index_cypher).merge(extra.to_h { |key| [key, row[key].to_sym] })
29
27
  end
30
28
  end
31
29
 
32
30
  def constraints
33
- if version?('<4.3')
34
- raw_indexes.select(&method(:constraint_owned?))
35
- else
36
- raw_constraints.select(&method(:constraint_filter))
37
- end.map { |row| definition(row, :constraint_cypher).merge(type: :uniqueness) }
31
+ raw_constraints.select(&method(:constraint_filter)).map { |row| definition(row, :constraint_cypher).merge(type: :uniqueness) }
38
32
  end
39
33
 
40
34
  private def raw_constraints
@@ -45,27 +39,28 @@ module ActiveGraph
45
39
 
46
40
  def raw_indexes
47
41
  read_transaction do
48
- query(version?('<4.3') ? 'CALL db.indexes()' : 'SHOW INDEXES YIELD *', {}, skip_instrumentation: true)
49
- .reject { |row| row[:type] == 'LOOKUP' }
42
+ query('SHOW INDEXES YIELD *', {}, skip_instrumentation: true).reject { |row| row[:type] == 'LOOKUP' }
50
43
  end
51
44
  end
52
45
 
53
46
  def constraint_owned?(record)
54
- FILTER[major]&.then { |(key, value)| record[key] == value } || record[:owningConstraint]
47
+ record[:owningConstraint]
55
48
  end
56
49
 
57
50
  private
58
51
 
52
+ def component
53
+ @component ||= read_transaction do
54
+ query('CALL dbms.components()', {}, skip_instrumentation: true).first
55
+ end
56
+ end
57
+
59
58
  def major
60
59
  @major ||= version.segments.first
61
60
  end
62
61
 
63
62
  def constraint_filter(record)
64
- %w[UNIQUENESS RELATIONSHIP_PROPERTY_EXISTENCE NODE_PROPERTY_EXISTENCE NODE_KEY].include?(record[:type])
65
- end
66
-
67
- def index_cypher_v3(label, properties)
68
- "INDEX ON :#{label}#{com_sep(properties, nil)}"
63
+ %w[UNIQUENESS RELATIONSHIP_UNIQUENESS RELATIONSHIP_PROPERTY_EXISTENCE NODE_PROPERTY_EXISTENCE NODE_KEY RELATIONSHIP_KEY].include?(record[:type])
69
64
  end
70
65
 
71
66
  def index_cypher(label, properties)
@@ -82,11 +77,11 @@ module ActiveGraph
82
77
 
83
78
  def definition(row, template)
84
79
  { label: label(row), properties: properties(row), name: row[:name],
85
- create_statement: row[:createStatement] || send(template,label(row), row[:properties]) }
80
+ create_statement: row[:createStatement] || send(template, label(row), row[:properties]) }
86
81
  end
87
82
 
88
83
  def label(row)
89
- row[version?('>=4') ? :labelsOrTypes : :tokenNames].first.to_sym
84
+ row[:labelsOrTypes].first.to_sym
90
85
  end
91
86
 
92
87
  def properties(row)
@@ -0,0 +1,13 @@
1
+ module ActiveGraph
2
+ module Core
3
+ class Type < Element
4
+ def pattern(spec)
5
+ "()-[#{spec}]-()"
6
+ end
7
+
8
+ def element_type
9
+ 'RELATIONSHIP'
10
+ end
11
+ end
12
+ end
13
+ end
@@ -6,18 +6,16 @@ module ActiveGraph
6
6
  MISSING_CONSTRAINT_OR_INDEX = 'No such %{type} for %{label}#%{property}'.freeze
7
7
  DUPLICATE_CONSTRAINT_OR_INDEX = 'Duplicate %{type} for %{label}#%{property}'.freeze
8
8
 
9
- def add_constraint(label, property, options = {})
10
- force = options[:force] || false
11
- type = options[:type] || :uniqueness
12
- label_object = ActiveGraph::Base.label_object(label)
13
- if label_object.constraint?(property)
9
+ def add_constraint(name, property, relationship: false, type: :key, force: false)
10
+ element = ActiveGraph::Base.element(name, relationship:)
11
+ if element.constraint?(property)
14
12
  if force
15
- label_object.drop_constraint(property, type: type)
13
+ element.drop_constraint(property, type:)
16
14
  else
17
- fail_duplicate_constraint_or_index!(:constraint, label, property)
15
+ fail_duplicate_constraint_or_index!(:constraint, name, property)
18
16
  end
19
17
  end
20
- label_object.create_constraint(property, type: type)
18
+ element.create_constraint(property, type:)
21
19
  end
22
20
 
23
21
  def add_index(label, property, options = {})
@@ -33,11 +31,10 @@ module ActiveGraph
33
31
  label_object.create_index(property)
34
32
  end
35
33
 
36
- def drop_constraint(label, property, options = {})
37
- type = options[:type] || :uniqueness
38
- label_object = ActiveGraph::Base.label_object(label)
39
- fail_missing_constraint_or_index!(:constraint, label, property) if !options[:force] && !label_object.constraint?(property)
40
- label_object.drop_constraint(property, type: type)
34
+ def drop_constraint(name, property, type: :key, relationship: false, force: false)
35
+ element = ActiveGraph::Base.element(name, relationship:)
36
+ fail_missing_constraint_or_index!(:constraint, name, property) unless force || element.constraint?(property)
37
+ element.drop_constraint(property, type:)
41
38
  end
42
39
 
43
40
  def drop_index(label, property, options = {})
@@ -55,7 +55,7 @@ module ActiveGraph
55
55
  # should be private
56
56
  def schema_elements_list(by_model, db_results)
57
57
  by_model.flat_map do |model, property_names|
58
- label = model.mapped_label_name.to_sym
58
+ label = model.mapped_element_name.to_sym
59
59
  property_names.map do |property_name|
60
60
  exists = db_results[label] && db_results[label].include?([property_name])
61
61
  [model, label, property_name, exists]
@@ -286,7 +286,7 @@ module ActiveGraph::Node
286
286
  query_proxy = self.class.as(:previous).where(neo_id: result_cache.map(&:neo_id))
287
287
  query_proxy = self.class.send(:association_query_proxy, association_name, previous_query_proxy: query_proxy, node: :next, optional: true)
288
288
 
289
- Hash[*query_proxy.pluck('ID(previous)', 'collect(next)').flatten(1)].each_value do |records|
289
+ Hash[*query_proxy.pluck('elementId(previous)', 'collect(next)').flatten(1)].each_value do |records|
290
290
  records.each do |record|
291
291
  record.instance_variable_set('@source_proxy_result_cache', records)
292
292
  end
@@ -108,7 +108,7 @@ module ActiveGraph
108
108
 
109
109
  # Deletes all nodes and connected relationships from Cypher.
110
110
  def delete_all
111
- neo4j_query("MATCH (n:`#{mapped_label_name}`) OPTIONAL MATCH (n)-[r]-() DELETE n,r")
111
+ neo4j_query("MATCH (n:`#{mapped_label_name}`) DETACH DELETE n")
112
112
  end
113
113
 
114
114
  # Returns each node to Ruby and calls `destroy`. Be careful, as this can be a very slow operation if you have many nodes. It will generate at least
@@ -127,11 +127,15 @@ module ActiveGraph
127
127
  @mapped_label_name || label_for_model
128
128
  end
129
129
 
130
+ alias mapped_element_name mapped_label_name
131
+
130
132
  # @return [ActiveGraph::Label] the label for this class
131
133
  def mapped_label
132
134
  ActiveGraph::Core::Label.new(mapped_label_name)
133
135
  end
134
136
 
137
+ alias mapped_element mapped_label
138
+
135
139
  def base_class
136
140
  unless self < ActiveGraph::Node
137
141
  fail "#{name} doesn't belong in a hierarchy descending from Node"
@@ -160,6 +164,7 @@ module ActiveGraph
160
164
 
161
165
  self.mapped_label_name = name
162
166
  end
167
+
163
168
  # rubocop:enable Naming/AccessorMethodName
164
169
 
165
170
  private
@@ -184,20 +189,18 @@ module ActiveGraph
184
189
  end
185
190
 
186
191
  def label_for_model
187
- (self.name.nil? ? object_id.to_s.to_sym : decorated_label_name)
192
+ name.nil? ? object_id.to_s.to_sym : decorated_label_name
188
193
  end
189
194
 
190
195
  def decorated_label_name
191
- name = case ActiveGraph::Config[:module_handling]
192
- when :demodulize
193
- self.name.demodulize
194
- when Proc
195
- ActiveGraph::Config[:module_handling].call self.name
196
- else
197
- self.name
198
- end
199
-
200
- name.to_sym
196
+ case ActiveGraph::Config[:module_handling]
197
+ when :demodulize
198
+ name.demodulize
199
+ when Proc
200
+ ActiveGraph::Config[:module_handling].call name
201
+ else
202
+ name
203
+ end.to_sym
201
204
  end
202
205
  end
203
206
  end