activegraph 10.0.0.pre.alpha.6

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 (142) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +1989 -0
  3. data/CONTRIBUTORS +12 -0
  4. data/Gemfile +24 -0
  5. data/README.md +107 -0
  6. data/bin/rake +17 -0
  7. data/config/locales/en.yml +5 -0
  8. data/config/neo4j/add_classnames.yml +1 -0
  9. data/config/neo4j/config.yml +38 -0
  10. data/lib/neo4j.rb +116 -0
  11. data/lib/neo4j/active_base.rb +89 -0
  12. data/lib/neo4j/active_node.rb +108 -0
  13. data/lib/neo4j/active_node/callbacks.rb +8 -0
  14. data/lib/neo4j/active_node/dependent.rb +11 -0
  15. data/lib/neo4j/active_node/dependent/association_methods.rb +49 -0
  16. data/lib/neo4j/active_node/dependent/query_proxy_methods.rb +51 -0
  17. data/lib/neo4j/active_node/enum.rb +26 -0
  18. data/lib/neo4j/active_node/has_n.rb +612 -0
  19. data/lib/neo4j/active_node/has_n/association.rb +278 -0
  20. data/lib/neo4j/active_node/has_n/association/rel_factory.rb +61 -0
  21. data/lib/neo4j/active_node/has_n/association/rel_wrapper.rb +23 -0
  22. data/lib/neo4j/active_node/has_n/association_cypher_methods.rb +108 -0
  23. data/lib/neo4j/active_node/id_property.rb +224 -0
  24. data/lib/neo4j/active_node/id_property/accessor.rb +62 -0
  25. data/lib/neo4j/active_node/initialize.rb +21 -0
  26. data/lib/neo4j/active_node/labels.rb +207 -0
  27. data/lib/neo4j/active_node/labels/index.rb +37 -0
  28. data/lib/neo4j/active_node/labels/reloading.rb +21 -0
  29. data/lib/neo4j/active_node/node_list_formatter.rb +13 -0
  30. data/lib/neo4j/active_node/node_wrapper.rb +54 -0
  31. data/lib/neo4j/active_node/orm_adapter.rb +82 -0
  32. data/lib/neo4j/active_node/persistence.rb +187 -0
  33. data/lib/neo4j/active_node/property.rb +60 -0
  34. data/lib/neo4j/active_node/query.rb +76 -0
  35. data/lib/neo4j/active_node/query/query_proxy.rb +374 -0
  36. data/lib/neo4j/active_node/query/query_proxy_eager_loading.rb +177 -0
  37. data/lib/neo4j/active_node/query/query_proxy_eager_loading/association_tree.rb +75 -0
  38. data/lib/neo4j/active_node/query/query_proxy_enumerable.rb +110 -0
  39. data/lib/neo4j/active_node/query/query_proxy_find_in_batches.rb +19 -0
  40. data/lib/neo4j/active_node/query/query_proxy_link.rb +139 -0
  41. data/lib/neo4j/active_node/query/query_proxy_methods.rb +302 -0
  42. data/lib/neo4j/active_node/query/query_proxy_methods_of_mass_updating.rb +86 -0
  43. data/lib/neo4j/active_node/query_methods.rb +68 -0
  44. data/lib/neo4j/active_node/reflection.rb +86 -0
  45. data/lib/neo4j/active_node/rels.rb +11 -0
  46. data/lib/neo4j/active_node/scope.rb +166 -0
  47. data/lib/neo4j/active_node/unpersisted.rb +48 -0
  48. data/lib/neo4j/active_node/validations.rb +59 -0
  49. data/lib/neo4j/active_rel.rb +67 -0
  50. data/lib/neo4j/active_rel/callbacks.rb +15 -0
  51. data/lib/neo4j/active_rel/initialize.rb +28 -0
  52. data/lib/neo4j/active_rel/persistence.rb +134 -0
  53. data/lib/neo4j/active_rel/persistence/query_factory.rb +95 -0
  54. data/lib/neo4j/active_rel/property.rb +95 -0
  55. data/lib/neo4j/active_rel/query.rb +101 -0
  56. data/lib/neo4j/active_rel/rel_wrapper.rb +31 -0
  57. data/lib/neo4j/active_rel/related_node.rb +87 -0
  58. data/lib/neo4j/active_rel/types.rb +82 -0
  59. data/lib/neo4j/active_rel/validations.rb +8 -0
  60. data/lib/neo4j/ansi.rb +14 -0
  61. data/lib/neo4j/class_arguments.rb +39 -0
  62. data/lib/neo4j/config.rb +135 -0
  63. data/lib/neo4j/core.rb +14 -0
  64. data/lib/neo4j/core/connection_failed_error.rb +6 -0
  65. data/lib/neo4j/core/cypher_error.rb +37 -0
  66. data/lib/neo4j/core/driver.rb +66 -0
  67. data/lib/neo4j/core/has_uri.rb +63 -0
  68. data/lib/neo4j/core/instrumentable.rb +36 -0
  69. data/lib/neo4j/core/label.rb +158 -0
  70. data/lib/neo4j/core/logging.rb +44 -0
  71. data/lib/neo4j/core/node.rb +23 -0
  72. data/lib/neo4j/core/querable.rb +88 -0
  73. data/lib/neo4j/core/query.rb +487 -0
  74. data/lib/neo4j/core/query_builder.rb +32 -0
  75. data/lib/neo4j/core/query_clauses.rb +727 -0
  76. data/lib/neo4j/core/query_ext.rb +24 -0
  77. data/lib/neo4j/core/query_find_in_batches.rb +49 -0
  78. data/lib/neo4j/core/relationship.rb +13 -0
  79. data/lib/neo4j/core/responses.rb +50 -0
  80. data/lib/neo4j/core/result.rb +33 -0
  81. data/lib/neo4j/core/schema.rb +30 -0
  82. data/lib/neo4j/core/schema_errors.rb +12 -0
  83. data/lib/neo4j/core/wrappable.rb +30 -0
  84. data/lib/neo4j/errors.rb +57 -0
  85. data/lib/neo4j/migration.rb +148 -0
  86. data/lib/neo4j/migrations.rb +27 -0
  87. data/lib/neo4j/migrations/base.rb +77 -0
  88. data/lib/neo4j/migrations/check_pending.rb +20 -0
  89. data/lib/neo4j/migrations/helpers.rb +105 -0
  90. data/lib/neo4j/migrations/helpers/id_property.rb +75 -0
  91. data/lib/neo4j/migrations/helpers/relationships.rb +66 -0
  92. data/lib/neo4j/migrations/helpers/schema.rb +51 -0
  93. data/lib/neo4j/migrations/migration_file.rb +24 -0
  94. data/lib/neo4j/migrations/runner.rb +195 -0
  95. data/lib/neo4j/migrations/schema.rb +44 -0
  96. data/lib/neo4j/migrations/schema_migration.rb +14 -0
  97. data/lib/neo4j/model_schema.rb +139 -0
  98. data/lib/neo4j/paginated.rb +27 -0
  99. data/lib/neo4j/railtie.rb +105 -0
  100. data/lib/neo4j/schema/operation.rb +102 -0
  101. data/lib/neo4j/shared.rb +60 -0
  102. data/lib/neo4j/shared/attributes.rb +216 -0
  103. data/lib/neo4j/shared/callbacks.rb +68 -0
  104. data/lib/neo4j/shared/cypher.rb +37 -0
  105. data/lib/neo4j/shared/declared_properties.rb +204 -0
  106. data/lib/neo4j/shared/declared_property.rb +109 -0
  107. data/lib/neo4j/shared/declared_property/index.rb +37 -0
  108. data/lib/neo4j/shared/enum.rb +167 -0
  109. data/lib/neo4j/shared/filtered_hash.rb +79 -0
  110. data/lib/neo4j/shared/identity.rb +34 -0
  111. data/lib/neo4j/shared/initialize.rb +64 -0
  112. data/lib/neo4j/shared/marshal.rb +23 -0
  113. data/lib/neo4j/shared/mass_assignment.rb +64 -0
  114. data/lib/neo4j/shared/permitted_attributes.rb +28 -0
  115. data/lib/neo4j/shared/persistence.rb +282 -0
  116. data/lib/neo4j/shared/property.rb +240 -0
  117. data/lib/neo4j/shared/query_factory.rb +102 -0
  118. data/lib/neo4j/shared/rel_type_converters.rb +43 -0
  119. data/lib/neo4j/shared/serialized_properties.rb +30 -0
  120. data/lib/neo4j/shared/type_converters.rb +433 -0
  121. data/lib/neo4j/shared/typecasted_attributes.rb +98 -0
  122. data/lib/neo4j/shared/typecaster.rb +53 -0
  123. data/lib/neo4j/shared/validations.rb +44 -0
  124. data/lib/neo4j/tasks/migration.rake +202 -0
  125. data/lib/neo4j/timestamps.rb +11 -0
  126. data/lib/neo4j/timestamps/created.rb +9 -0
  127. data/lib/neo4j/timestamps/updated.rb +9 -0
  128. data/lib/neo4j/transaction.rb +139 -0
  129. data/lib/neo4j/type_converters.rb +7 -0
  130. data/lib/neo4j/undeclared_properties.rb +53 -0
  131. data/lib/neo4j/version.rb +3 -0
  132. data/lib/neo4j/wrapper.rb +4 -0
  133. data/lib/rails/generators/neo4j/migration/migration_generator.rb +14 -0
  134. data/lib/rails/generators/neo4j/migration/templates/migration.erb +9 -0
  135. data/lib/rails/generators/neo4j/model/model_generator.rb +88 -0
  136. data/lib/rails/generators/neo4j/model/templates/migration.erb +9 -0
  137. data/lib/rails/generators/neo4j/model/templates/model.erb +15 -0
  138. data/lib/rails/generators/neo4j/upgrade_v8/templates/migration.erb +17 -0
  139. data/lib/rails/generators/neo4j/upgrade_v8/upgrade_v8_generator.rb +32 -0
  140. data/lib/rails/generators/neo4j_generator.rb +119 -0
  141. data/neo4j.gemspec +51 -0
  142. metadata +421 -0
@@ -0,0 +1,24 @@
1
+ module Neo4j
2
+ module Core
3
+ class Query
4
+ # Creates a Neo4j::ActiveNode::Query::QueryProxy object that builds off of a Core::Query object.
5
+ #
6
+ # @param [Class] model An ActiveNode model to be used as the start of a new QueryuProxy chain
7
+ # @param [Symbol] var The variable to be used to refer to the object from within the new QueryProxy
8
+ # @param [Boolean] optional Indicate whether the new QueryProxy will use MATCH or OPTIONAL MATCH.
9
+ # @return [Neo4j::ActiveNode::Query::QueryProxy] A QueryProxy object.
10
+ def proxy_as(model, var, optional = false)
11
+ # TODO: Discuss whether it's necessary to call `break` on the query or if this should be left to the user.
12
+ Neo4j::ActiveNode::Query::QueryProxy.new(model, nil, node: var, optional: optional, starting_query: self, chain_level: @proxy_chain_level)
13
+ end
14
+
15
+ # Calls proxy_as with `optional` set true. This doesn't offer anything different from calling `proxy_as` directly but it may be more readable.
16
+ def proxy_as_optional(model, var)
17
+ proxy_as(model, var, true)
18
+ end
19
+
20
+ # For instances where you turn a QueryProxy into a Query and then back to a QueryProxy with `#proxy_as`
21
+ attr_accessor :proxy_chain_level
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,49 @@
1
+ module Neo4j
2
+ module Core
3
+ module QueryFindInBatches
4
+ def find_in_batches(node_var, prop_var, options = {})
5
+ validate_find_in_batches_options!(options)
6
+
7
+ batch_size = options.delete(:batch_size) || 1000
8
+
9
+ query = reorder(node_var => prop_var).limit(batch_size)
10
+
11
+ records = query.to_a
12
+
13
+ while records.any?
14
+ records_size = records.size
15
+ primary_key_offset = primary_key_offset(records.last, node_var, prop_var)
16
+
17
+ yield records
18
+
19
+ break if records_size < batch_size
20
+
21
+ primary_key_var = Neo4j::Core::QueryClauses::Clause.from_key_and_single_value(node_var, prop_var)
22
+ records = query.where("#{primary_key_var} > {primary_key_offset}")
23
+ .params(primary_key_offset: primary_key_offset).to_a
24
+ end
25
+ end
26
+
27
+ def find_each(*args, &block)
28
+ find_in_batches(*args) { |batch| batch.each(&block) }
29
+ end
30
+
31
+ private
32
+
33
+ def validate_find_in_batches_options!(options)
34
+ invalid_keys = options.keys.map(&:to_sym) - [:batch_size]
35
+ fail ArgumentError, "Invalid keys: #{invalid_keys.join(', ')}" if not invalid_keys.empty?
36
+ end
37
+
38
+ def primary_key_offset(last_record, node_var, prop_var)
39
+ last_record.send(node_var).send(prop_var)
40
+ rescue NoMethodError
41
+ begin
42
+ last_record.send(node_var).properties[prop_var.to_sym]
43
+ rescue NoMethodError
44
+ last_record.send("#{node_var}.#{prop_var}") # In case we're explicitly returning it
45
+ end
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,13 @@
1
+ require 'neo4j/core/wrappable'
2
+
3
+ module Neo4j
4
+ module Core
5
+ module Relationship
6
+ def props; properties; end
7
+ def neo_id; id; end
8
+ def start_node_neo_id; start_node_id; end
9
+ def end_node_neo_id; end_node_id; end
10
+ def rel_type; type; end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,50 @@
1
+ require 'neo4j/core/result'
2
+ require 'active_support/core_ext/module/attribute_accessors'
3
+
4
+ module Neo4j
5
+ module Core
6
+ module Responses
7
+ extend ActiveSupport::Concern
8
+
9
+ included do
10
+ mattr_accessor :wrap_level
11
+ end
12
+
13
+ class_methods do
14
+ def result_from_data(entities_data)
15
+ rows = entities_data.map do |entity_data|
16
+ wrap(entity_data.values)
17
+ end
18
+
19
+ Neo4j::Core::Result.new(entities_data.keys, rows)
20
+ end
21
+
22
+ private
23
+
24
+ def wrap(value)
25
+ case value
26
+ when Neo4j::Driver::Types::Entity
27
+ wrap_by_level(value)
28
+ when Neo4j::Driver::Types::Path
29
+ value
30
+ when Hash
31
+ value.map { |key, val| [key, wrap(val)] }.to_h
32
+ when Enumerable
33
+ value.map(&method(:wrap))
34
+ else
35
+ value
36
+ end
37
+ end
38
+
39
+ def wrap_by_level(entity)
40
+ case wrap_level
41
+ when :core_entity
42
+ entity
43
+ else
44
+ entity.wrap
45
+ end
46
+ end
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,33 @@
1
+ module Neo4j
2
+ module Core
3
+ class Result
4
+ attr_reader :columns, :rows
5
+
6
+ def initialize(columns, rows)
7
+ @columns = columns.map(&:to_sym)
8
+ @rows = rows
9
+ @struct_class = Struct.new(:index, *@columns)
10
+ end
11
+
12
+ include Enumerable
13
+
14
+ def each
15
+ structs.each do |struct|
16
+ yield struct
17
+ end
18
+ end
19
+
20
+ def structs
21
+ @structs ||= rows.each_with_index.map do |row, index|
22
+ @struct_class.new(index, *row)
23
+ end
24
+ end
25
+
26
+ def hashes
27
+ @hashes ||= rows.map do |row|
28
+ Hash[@columns.zip(row)]
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,30 @@
1
+ module Neo4j
2
+ module Core
3
+ module Schema
4
+ def version
5
+ result = query('CALL dbms.components()', {}, skip_instrumentation: true)
6
+
7
+ # BTW: community / enterprise could be retrieved via `result.first.edition`
8
+ result.first.versions[0]
9
+ end
10
+
11
+ def indexes
12
+ result = query('CALL db.indexes()', {}, skip_instrumentation: true)
13
+
14
+ result.map do |row|
15
+ label, property = row.description.match(/INDEX ON :([^\(]+)\(([^\)]+)\)/)[1, 2]
16
+ { type: row.type.to_sym, label: label.to_sym, properties: [property.to_sym], state: row.state.to_sym }
17
+ end
18
+ end
19
+
20
+ def constraints
21
+ result = query('CALL db.indexes()', {}, skip_instrumentation: true)
22
+
23
+ result.select { |row| row.type == 'node_unique_property' }.map do |row|
24
+ label, property = row.description.match(/INDEX ON :([^\(]+)\(([^\)]+)\)/)[1, 2]
25
+ { type: :uniqueness, label: label.to_sym, properties: [property.to_sym] }
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,12 @@
1
+ module Neo4j
2
+ module Core
3
+ module SchemaErrors
4
+ class ConstraintValidationFailedError < CypherError;
5
+ end
6
+ class ConstraintAlreadyExistsError < CypherError;
7
+ end
8
+ class IndexAlreadyExistsError < CypherError;
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,30 @@
1
+ module Neo4j
2
+ module Core
3
+ module Wrappable
4
+ extend ActiveSupport::Concern
5
+
6
+ def wrap
7
+ self.class.wrap(self)
8
+ end
9
+
10
+ class_methods do
11
+ def wrapper_callback(proc)
12
+ fail 'Callback already specified!' if @wrapper_callback
13
+ @wrapper_callback = proc
14
+ end
15
+
16
+ def clear_wrapper_callback
17
+ @wrapper_callback = nil
18
+ end
19
+
20
+ def wrap(node)
21
+ if @wrapper_callback
22
+ @wrapper_callback.call(node)
23
+ else
24
+ node
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,57 @@
1
+ module Neo4j
2
+ # Neo4j.rb Errors
3
+ # Generic Neo4j.rb exception class.
4
+ class Error < StandardError
5
+ end
6
+
7
+ # Raised when Neo4j.rb cannot find record by given id.
8
+ class RecordNotFound < Error
9
+ attr_reader :model, :primary_key, :id
10
+
11
+ def initialize(message = nil, model = nil, primary_key = nil, id = nil)
12
+ @primary_key = primary_key
13
+ @model = model
14
+ @id = id
15
+
16
+ super(message)
17
+ end
18
+ end
19
+
20
+ class DeprecatedSchemaDefinitionError < Error; end
21
+
22
+ class InvalidPropertyOptionsError < Error; end
23
+
24
+ class InvalidParameterError < Error; end
25
+
26
+ class UnknownTypeConverterError < Error; end
27
+
28
+ class DangerousAttributeError < ScriptError; end
29
+ class UnknownAttributeError < NoMethodError; end
30
+
31
+ class MigrationError < Error; end
32
+ class IrreversibleMigration < MigrationError; end
33
+ class UnknownMigrationVersionError < MigrationError; end
34
+
35
+ # Inspired/taken from active_record/migration.rb
36
+ class PendingMigrationError < MigrationError
37
+ def initialize(migrations)
38
+ pending_migrations = migrations.join("\n")
39
+ if rails? && defined?(Rails.env)
40
+ super("Migrations are pending:\n#{pending_migrations}\n To resolve this issue, run:\n\n #{command_name} neo4j:migrate RAILS_ENV=#{::Rails.env}")
41
+ else
42
+ super("Migrations are pending:\n#{pending_migrations}\n To resolve this issue, run:\n\n #{command_name} neo4j:migrate")
43
+ end
44
+ end
45
+
46
+ private
47
+
48
+ def command_name
49
+ return 'rake' unless rails?
50
+ Rails.version.to_f >= 5 ? 'bin/rails' : 'bin/rake'
51
+ end
52
+
53
+ def rails?
54
+ defined?(Rails)
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,148 @@
1
+ require 'benchmark'
2
+ require 'neo4j/migrations/helpers/id_property'
3
+
4
+ module Neo4j
5
+ class Migration
6
+ def migrate
7
+ fail 'not implemented'
8
+ end
9
+
10
+ def output(string = '')
11
+ puts string unless !!ENV['MIGRATIONS_SILENCED']
12
+ end
13
+
14
+ def print_output(string)
15
+ print string unless !!ENV['MIGRATIONS_SILENCED']
16
+ end
17
+
18
+ def default_path
19
+ Rails.root if defined? Rails
20
+ end
21
+
22
+ def joined_path(path)
23
+ File.join(path.to_s, 'db', 'neo4j-migrate')
24
+ end
25
+
26
+ def setup
27
+ FileUtils.mkdir_p('db/neo4j-migrate')
28
+ end
29
+
30
+ def query(*args)
31
+ Neo4j::ActiveBase.current_driver.query(*args)
32
+ end
33
+
34
+ class AddIdProperty < Neo4j::Migration
35
+ include Neo4j::Migrations::Helpers::IdProperty
36
+
37
+ attr_reader :models_filename
38
+
39
+ def initialize(path = default_path)
40
+ @models_filename = File.join(joined_path(path), 'add_id_property.yml')
41
+ end
42
+
43
+ def migrate
44
+ ActiveSupport::Deprecation.warn '`AddIdProperty` task is deprecated and may be removed from future releases. '\
45
+ 'Create a new migration and use the `populate_id_property` helper.', caller
46
+ models = ActiveSupport::HashWithIndifferentAccess.new(YAML.load_file(models_filename))[:models]
47
+ output 'This task will add an ID Property every node in the given file.'
48
+ output 'It may take a significant amount of time, please be patient.'
49
+ models.each do |model|
50
+ output
51
+ output
52
+ output "Adding IDs to #{model}"
53
+ populate_id_property model
54
+ end
55
+ end
56
+
57
+ def query(*args)
58
+ ActiveBase.magic_query(*args)
59
+ end
60
+
61
+ def execute(*args)
62
+ ActiveBase.query(*args)
63
+ end
64
+
65
+ def setup
66
+ super
67
+ return if File.file?(models_filename)
68
+
69
+ File.open(models_filename, 'w') do |file|
70
+ message = <<MESSAGE
71
+ # Provide models to which IDs should be added.
72
+ # # It will only modify nodes that do not have IDs. There is no danger of overwriting data.
73
+ # # models: [Student,Lesson,Teacher,Exam]\nmodels: []
74
+ MESSAGE
75
+ file.write(message)
76
+ end
77
+ end
78
+
79
+ # Might need some of this...
80
+ # private
81
+
82
+ # def add_ids_to(model)
83
+ # max_per_batch = (ENV['MAX_PER_BATCH'] || default_max_per_batch).to_i
84
+
85
+ # label = model.mapped_label_name
86
+ # last_time_taken = nil
87
+
88
+ # until (nodes_left = idless_count(label, model.primary_key)) == 0
89
+ # print_status(last_time_taken, max_per_batch, nodes_left)
90
+
91
+ # count = [nodes_left, max_per_batch].min
92
+ # last_time_taken = Benchmark.realtime do
93
+ # max_per_batch = id_batch_set(label, model.primary_key, Array.new(count) { new_id_for(model) }, count)
94
+ # end
95
+ # end
96
+ # end
97
+
98
+ # def idless_count(label, id_property)
99
+ # Neo4j::ActiveBase.new_query.match(n: label).where("NOT EXISTS(n.#{id_property})").pluck('COUNT(n) AS ids').first
100
+ # end
101
+
102
+ # def print_status(last_time_taken, max_per_batch, nodes_left)
103
+ # time_per_node = last_time_taken / max_per_batch if last_time_taken
104
+ # message = if time_per_node
105
+ # eta_seconds = (nodes_left * time_per_node).round
106
+ # "#{nodes_left} nodes left. Last batch: #{(time_per_node * 1000.0).round(1)}ms / node (ETA: #{eta_seconds / 60} minutes)\r"
107
+ # else
108
+ # "Running first batch...\r"
109
+ # end
110
+
111
+ # print_output message
112
+ # end
113
+
114
+
115
+ # def id_batch_set(label, id_property, new_ids, count)
116
+ # tx = Neo4j::ActiveBase.new_transaction
117
+
118
+ # Neo4j::ActiveBase.current_driver.query("MATCH (n:`#{label}`) WHERE NOT EXISTS(n.#{id_property})
119
+ # with COLLECT(n) as nodes, #{new_ids} as ids
120
+ # FOREACH(i in range(0,#{count - 1})|
121
+ # FOREACH(node in [nodes[i]]|
122
+ # SET node.#{id_property} = ids[i]))
123
+ # RETURN distinct(true)
124
+ # LIMIT #{count}")
125
+
126
+ # count
127
+ # rescue Neo4j::Server::CypherResponse::ResponseError, Faraday::TimeoutError
128
+ # new_max_per_batch = (max_per_batch * 0.8).round
129
+ # output "Error querying #{max_per_batch} nodes. Trying #{new_max_per_batch}"
130
+ # new_max_per_batch
131
+ # ensure
132
+ # tx.close
133
+ # end
134
+
135
+ # def default_max_per_batch
136
+ # 900
137
+ # end
138
+
139
+ # def new_id_for(model)
140
+ # if model.id_property_info[:type][:auto]
141
+ # SecureRandom.uuid
142
+ # else
143
+ # model.new.send(model.id_property_info[:type][:on])
144
+ # end
145
+ # end
146
+ end
147
+ end
148
+ end