neo4j 3.0.0.rc.5 → 3.0.0
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.
- checksums.yaml +4 -4
- data/CHANGELOG +3 -0
- data/lib/neo4j/active_node.rb +1 -1
- data/lib/neo4j/active_node/id_property.rb +1 -5
- data/lib/neo4j/active_node/labels.rb +1 -1
- data/lib/neo4j/active_node/query/query_proxy_methods.rb +1 -1
- data/lib/neo4j/active_node/query_methods.rb +3 -3
- data/lib/neo4j/active_node/scope.rb +1 -1
- data/lib/neo4j/active_node/validations.rb +2 -9
- data/lib/neo4j/active_rel/persistence.rb +7 -13
- data/lib/neo4j/active_rel/query.rb +8 -9
- data/lib/neo4j/active_rel/rel_wrapper.rb +1 -1
- data/lib/neo4j/migration.rb +34 -21
- data/lib/neo4j/shared/property.rb +9 -5
- data/lib/neo4j/shared/validations.rb +4 -4
- data/lib/neo4j/version.rb +1 -1
- data/neo4j.gemspec +1 -1
- metadata +6 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8c7dc4797f55611d07474d42b4618485691dc613
|
4
|
+
data.tar.gz: 8b8dd2f9eee185c7a157eeba14afcbe8cfbf043c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 97484101ffda9dc168e5f1ce39bde7fc28f019231dc9cfa82ae74dbc49fc75942279882023da33329453644d3734ea072415d9996fdeb6089f404e952f2aa262
|
7
|
+
data.tar.gz: 2770dacf06cbb2816acf892c0e162e3049ff18af305013b358ab5b850cf20462a556b3197760ed128aad870d57f362302296b00c32906325b23b963ece0419a7
|
data/CHANGELOG
CHANGED
data/lib/neo4j/active_node.rb
CHANGED
@@ -42,12 +42,8 @@ module Neo4j::ActiveNode
|
|
42
42
|
|
43
43
|
def validate_conf(conf)
|
44
44
|
return if conf.empty?
|
45
|
-
|
46
45
|
raise "Expected a Hash, got #{conf.class} (#{conf.to_s}) for id_property" unless conf.is_a?(Hash)
|
47
|
-
|
48
|
-
unless conf.include?(:auto) || conf.include?(:on)
|
49
|
-
raise "Illegal value #{conf.inspect} for id_property, expected :on or :auto"
|
50
|
-
end
|
46
|
+
raise "Illegal value #{conf.inspect} for id_property, expected :on or :auto" unless conf.include?(:auto) || conf.include?(:on)
|
51
47
|
end
|
52
48
|
|
53
49
|
def define_property_method(clazz, name)
|
@@ -86,7 +86,7 @@ module Neo4j
|
|
86
86
|
self.query_as(:n).where(n: eval(args.join)).limit(1).pluck(:n).first
|
87
87
|
end
|
88
88
|
|
89
|
-
# Like find_by, except that if no record is found, raises a RecordNotFound error.
|
89
|
+
# Like find_by, except that if no record is found, raises a RecordNotFound error.
|
90
90
|
def find_by!(*args)
|
91
91
|
a = eval(args.join)
|
92
92
|
find_by(args) or raise RecordNotFound, "#{self.query_as(:n).where(n: a).limit(1).to_cypher} returned no results"
|
@@ -37,7 +37,7 @@ module Neo4j
|
|
37
37
|
def include?(other, target=nil)
|
38
38
|
raise(InvalidParameterError, ':include? only accepts nodes') unless other.respond_to?(:neo_id)
|
39
39
|
query_with_target(target) do |target|
|
40
|
-
self.
|
40
|
+
self.where("#{target}.#{other.class.primary_key} = {other_node_id}").params(other_node_id: other.id).query.return("count(#{target}) as count").first.count > 0
|
41
41
|
end
|
42
42
|
end
|
43
43
|
|
@@ -44,10 +44,10 @@ module Neo4j
|
|
44
44
|
private
|
45
45
|
|
46
46
|
def exists_query_start(node_condition)
|
47
|
-
case
|
48
|
-
when
|
47
|
+
case node_condition
|
48
|
+
when Fixnum
|
49
49
|
self.query_as(:n).where("ID(n) = #{node_condition}")
|
50
|
-
when
|
50
|
+
when Hash
|
51
51
|
self.where(node_condition.keys.first => node_condition.values.first)
|
52
52
|
else
|
53
53
|
self.query_as(:n)
|
@@ -61,7 +61,7 @@ module Neo4j::ActiveNode
|
|
61
61
|
|
62
62
|
def _call_scope_context(eval_context, query_params, proc)
|
63
63
|
if proc.arity == 1
|
64
|
-
eval_context.instance_exec(query_params
|
64
|
+
eval_context.instance_exec(query_params, &proc)
|
65
65
|
else
|
66
66
|
eval_context.instance_exec(&proc)
|
67
67
|
end
|
@@ -31,19 +31,12 @@ module Neo4j
|
|
31
31
|
# TODO: Added as find(:name => nil) throws error
|
32
32
|
value = "" if value == nil
|
33
33
|
|
34
|
-
|
35
|
-
conditions[attribute] = value
|
36
|
-
else
|
37
|
-
conditions[attribute] = /^#{Regexp.escape(value.to_s)}$/i
|
38
|
-
end
|
34
|
+
conditions[attribute] = options[:case_sensitive] ? value : /^#{Regexp.escape(value.to_s)}$/i
|
39
35
|
|
40
36
|
# prevent that same object is returned
|
41
37
|
# TODO: add negative condtion to not return current record
|
42
38
|
found = record.class.where(conditions).to_a.select{|f| f.neo_id != record.neo_id}
|
43
|
-
|
44
|
-
if found.count > 0
|
45
|
-
record.errors.add(attribute, :taken, options.except(:case_sensitive, :scope).merge(:value => value))
|
46
|
-
end
|
39
|
+
record.errors.add(attribute, :taken, options.except(:case_sensitive, :scope).merge(:value => value)) if found.count > 0
|
47
40
|
end
|
48
41
|
|
49
42
|
def message(instance)
|
@@ -13,9 +13,7 @@ module Neo4j::ActiveRel
|
|
13
13
|
end
|
14
14
|
|
15
15
|
def save!(*args)
|
16
|
-
unless save(*args)
|
17
|
-
raise RelInvalidError.new(self)
|
18
|
-
end
|
16
|
+
raise RelInvalidError.new(self) unless save(*args)
|
19
17
|
end
|
20
18
|
|
21
19
|
def create_model(*)
|
@@ -44,21 +42,17 @@ module Neo4j::ActiveRel
|
|
44
42
|
|
45
43
|
# Same as #create, but raises an error if there is a problem during save.
|
46
44
|
def create!(*args)
|
47
|
-
unless create(*args)
|
48
|
-
raise RelInvalidError.new(self)
|
49
|
-
end
|
45
|
+
raise RelInvalidError.new(self) unless create(*args)
|
50
46
|
end
|
51
47
|
end
|
52
48
|
|
53
|
-
private
|
49
|
+
private
|
54
50
|
|
55
51
|
def confirm_node_classes
|
56
52
|
[from_node, to_node].each do |node|
|
57
53
|
type = from_node == node ? :_from_class : :_to_class
|
58
54
|
next if allows_any_class?(type)
|
59
|
-
unless class_as_constant(type) == node.class
|
60
|
-
raise ModelClassInvalidError, "Node class was #{node.class}, expected #{self.class.send(type)}"
|
61
|
-
end
|
55
|
+
raise ModelClassInvalidError, "Node class was #{node.class}, expected #{self.class.send(type)}" unless class_as_constant(type) == node.class
|
62
56
|
end
|
63
57
|
end
|
64
58
|
|
@@ -71,10 +65,10 @@ module Neo4j::ActiveRel
|
|
71
65
|
|
72
66
|
def class_as_constant(type)
|
73
67
|
given_class = self.class.send(type)
|
74
|
-
case
|
75
|
-
when
|
68
|
+
case given_class
|
69
|
+
when String
|
76
70
|
given_class.constantize
|
77
|
-
when
|
71
|
+
when Symbol
|
78
72
|
given_class.to_s.constantize
|
79
73
|
else
|
80
74
|
given_class
|
@@ -54,7 +54,7 @@ module Neo4j::ActiveRel
|
|
54
54
|
when :inbound
|
55
55
|
identifier = '(n2'
|
56
56
|
identifier + (_to_class == :any ? ')' : cypher_label(:inbound))
|
57
|
-
end
|
57
|
+
end
|
58
58
|
end
|
59
59
|
|
60
60
|
def cypher_label(dir = :outbound)
|
@@ -63,10 +63,10 @@ module Neo4j::ActiveRel
|
|
63
63
|
end
|
64
64
|
|
65
65
|
def as_constant(given_class)
|
66
|
-
case
|
67
|
-
when
|
66
|
+
case given_class
|
67
|
+
when String
|
68
68
|
given_class.constantize
|
69
|
-
when
|
69
|
+
when Symbol
|
70
70
|
given_class.to_s.constantize
|
71
71
|
else
|
72
72
|
given_class
|
@@ -74,11 +74,10 @@ module Neo4j::ActiveRel
|
|
74
74
|
end
|
75
75
|
|
76
76
|
def where_string(args)
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
else
|
77
|
+
case args
|
78
|
+
when Hash
|
79
|
+
args.map { |k, v| v.is_a?(Integer) ? "r1.#{k} = #{v}" : "r1.#{k} = '#{v}'" }.join(', ')
|
80
|
+
else
|
82
81
|
args
|
83
82
|
end
|
84
83
|
end
|
@@ -5,7 +5,7 @@ class Neo4j::Relationship
|
|
5
5
|
props.symbolize_keys!
|
6
6
|
return self unless props.is_a?(Hash) && props.has_key?(Neo4j::Config.class_name_property)
|
7
7
|
begin
|
8
|
-
|
8
|
+
found_class = props[Neo4j::Config.class_name_property].constantize
|
9
9
|
rescue NameError
|
10
10
|
return self
|
11
11
|
end
|
data/lib/neo4j/migration.rb
CHANGED
@@ -1,5 +1,18 @@
|
|
1
1
|
module Neo4j
|
2
2
|
class Migration
|
3
|
+
|
4
|
+
def migrate
|
5
|
+
raise 'not implemented'
|
6
|
+
end
|
7
|
+
|
8
|
+
def output(string = '')
|
9
|
+
puts string unless !!ENV['silenced']
|
10
|
+
end
|
11
|
+
|
12
|
+
def print_output(string)
|
13
|
+
print string unless !!ENV['silenced']
|
14
|
+
end
|
15
|
+
|
3
16
|
class AddIdProperty < Neo4j::Migration
|
4
17
|
attr_reader :models_filename
|
5
18
|
|
@@ -9,12 +22,12 @@ module Neo4j
|
|
9
22
|
|
10
23
|
def migrate
|
11
24
|
models = ActiveSupport::HashWithIndifferentAccess.new(YAML.load_file(models_filename))[:models]
|
12
|
-
|
13
|
-
|
25
|
+
output "This task will add an ID Property every node in the given file."
|
26
|
+
output "It may take a significant amount of time, please be patient."
|
14
27
|
models.each do |model|
|
15
|
-
|
16
|
-
|
17
|
-
|
28
|
+
output
|
29
|
+
output
|
30
|
+
output "Adding IDs to #{model}"
|
18
31
|
add_ids_to model.constantize
|
19
32
|
end
|
20
33
|
end
|
@@ -44,10 +57,10 @@ module Neo4j
|
|
44
57
|
nodes_left = Neo4j::Session.query.match(n: label).where("NOT has(n.#{property})").return("COUNT(n) AS ids").first.ids
|
45
58
|
|
46
59
|
time_per_node = last_time_taken / max_per_batch if last_time_taken
|
47
|
-
|
60
|
+
print_output "Running first batch...\r"
|
48
61
|
if time_per_node
|
49
62
|
eta_seconds = (nodes_left * time_per_node).round
|
50
|
-
|
63
|
+
print_output "#{nodes_left} nodes left. Last batch: #{(time_per_node * 1000.0).round(1)}ms / node (ETA: #{eta_seconds / 60} minutes)\r"
|
51
64
|
end
|
52
65
|
|
53
66
|
return if nodes_left == 0
|
@@ -58,7 +71,7 @@ module Neo4j
|
|
58
71
|
last_time_taken = id_batch_set(label, property, new_ids, to_set)
|
59
72
|
rescue Neo4j::Server::CypherResponse::ResponseError, Faraday::TimeoutError
|
60
73
|
new_max_per_batch = (max_per_batch * 0.8).round
|
61
|
-
|
74
|
+
output "Error querying #{max_per_batch} nodes. Trying #{new_max_per_batch}"
|
62
75
|
max_per_batch = new_max_per_batch
|
63
76
|
end
|
64
77
|
end
|
@@ -92,7 +105,6 @@ module Neo4j
|
|
92
105
|
end
|
93
106
|
|
94
107
|
class AddClassnames < Neo4j::Migration
|
95
|
-
attr_reader :classnames_filename, :classnames_filepath
|
96
108
|
|
97
109
|
def initialize
|
98
110
|
@classnames_filename = 'add_classnames.yml'
|
@@ -100,33 +112,34 @@ module Neo4j
|
|
100
112
|
end
|
101
113
|
|
102
114
|
def migrate
|
103
|
-
|
115
|
+
output "Adding classnames. This make take some time."
|
104
116
|
execute(true)
|
105
117
|
end
|
106
118
|
|
107
119
|
def test
|
108
|
-
|
120
|
+
output "TESTING! No queries will be executed."
|
109
121
|
execute(false)
|
110
122
|
end
|
111
123
|
|
112
124
|
def setup
|
113
|
-
|
125
|
+
output "Creating file #{classnames_filepath}. Please use this as the migration guide."
|
114
126
|
FileUtils.mkdir_p("db/neo4j-migrate")
|
115
|
-
unless File.file?(
|
127
|
+
unless File.file?(classnames_filepath)
|
116
128
|
source = File.join(File.dirname(__FILE__), "..", "..", "config", "neo4j", classnames_filename)
|
117
129
|
FileUtils.copy_file(source, classnames_filepath)
|
118
130
|
end
|
119
131
|
end
|
120
132
|
|
121
133
|
private
|
134
|
+
attr_reader :classnames_filename, :classnames_filepath, :model_map
|
122
135
|
|
123
136
|
def execute(migrate = false)
|
124
137
|
file_init
|
125
138
|
map = []
|
126
|
-
map.push :nodes if
|
127
|
-
map.push :relationships if
|
139
|
+
map.push :nodes if model_map[:nodes]
|
140
|
+
map.push :relationships if model_map[:relationships]
|
128
141
|
map.each do |type|
|
129
|
-
|
142
|
+
model_map[type].each do |action, labels|
|
130
143
|
do_classnames(action, labels, type, migrate)
|
131
144
|
end
|
132
145
|
end
|
@@ -135,7 +148,7 @@ module Neo4j
|
|
135
148
|
def do_classnames(action, labels, type, migrate = false)
|
136
149
|
method = type == :nodes ? :node_cypher : :rel_cypher
|
137
150
|
labels.each do |label|
|
138
|
-
|
151
|
+
output cypher = self.send(method, label, action)
|
139
152
|
execute_cypher(cypher) if migrate
|
140
153
|
end
|
141
154
|
end
|
@@ -146,7 +159,7 @@ module Neo4j
|
|
146
159
|
|
147
160
|
def node_cypher(label, action)
|
148
161
|
where, phrase_start = action_variables(action, 'n')
|
149
|
-
|
162
|
+
output "#{phrase_start} _classname '#{label}' on nodes with matching label:"
|
150
163
|
"MATCH (n:`#{label}`) #{where} SET n._classname = '#{label}' RETURN COUNT(n) as modified"
|
151
164
|
end
|
152
165
|
|
@@ -161,13 +174,13 @@ module Neo4j
|
|
161
174
|
to_cypher = to ? "(to:`#{to}`)" : "(to)"
|
162
175
|
type = "[r:`#{value[:type]}`]"
|
163
176
|
where, phrase_start = action_variables(action, 'r')
|
164
|
-
|
177
|
+
output "#{phrase_start} _classname '#{label}' where type is '#{value[:type]}' using cypher:"
|
165
178
|
"MATCH #{from_cypher}-#{type}->#{to_cypher} #{where} SET r._classname = '#{label}' return COUNT(r) as modified"
|
166
179
|
end
|
167
180
|
|
168
181
|
def execute_cypher(query_string)
|
169
|
-
|
170
|
-
|
182
|
+
output "Modified #{Neo4j::Session.query(query_string).first.modified} records"
|
183
|
+
output ""
|
171
184
|
end
|
172
185
|
|
173
186
|
def action_variables(action, identifier)
|
@@ -108,11 +108,7 @@ module Neo4j::Shared
|
|
108
108
|
return nil if values_with_empty_parameters.all? { |v| v.nil? }
|
109
109
|
values = values_with_empty_parameters.collect { |v| v.nil? ? 1 : v }
|
110
110
|
klass = field[:type]
|
111
|
-
|
112
|
-
klass.new(*values)
|
113
|
-
else
|
114
|
-
values
|
115
|
-
end
|
111
|
+
klass ? klass.new(*values) : values
|
116
112
|
end
|
117
113
|
|
118
114
|
module ClassMethods
|
@@ -163,6 +159,7 @@ module Neo4j::Shared
|
|
163
159
|
end
|
164
160
|
|
165
161
|
def default_property(name, &block)
|
162
|
+
reset_default_properties(name) if default_properties.respond_to?(:size)
|
166
163
|
default_properties[name] = block
|
167
164
|
end
|
168
165
|
|
@@ -171,6 +168,13 @@ module Neo4j::Shared
|
|
171
168
|
@default_property ||= {}
|
172
169
|
end
|
173
170
|
|
171
|
+
def reset_default_properties(name_to_keep)
|
172
|
+
default_properties.each_key do |property|
|
173
|
+
undef_method(property) unless property == name_to_keep
|
174
|
+
end
|
175
|
+
@default_property = {}
|
176
|
+
end
|
177
|
+
|
174
178
|
def default_property_values(instance)
|
175
179
|
default_properties.each_with_object({}) do |(key, block),result|
|
176
180
|
result[key] = block.call(instance)
|
@@ -28,13 +28,13 @@ module Neo4j
|
|
28
28
|
super(context)
|
29
29
|
errors.empty?
|
30
30
|
end
|
31
|
-
|
31
|
+
|
32
32
|
private
|
33
|
-
|
33
|
+
|
34
34
|
def perform_validations(options={})
|
35
35
|
perform_validation = case options
|
36
|
-
|
37
|
-
|
36
|
+
when Hash
|
37
|
+
options[:validate] != false
|
38
38
|
end
|
39
39
|
|
40
40
|
if perform_validation
|
data/lib/neo4j/version.rb
CHANGED
data/neo4j.gemspec
CHANGED
@@ -31,7 +31,7 @@ A Neo4j OGM for use in Ruby on Rails and Rack frameworks, intended as a complete
|
|
31
31
|
s.add_dependency("activesupport", "~> 4")
|
32
32
|
s.add_dependency("railties", "~> 4")
|
33
33
|
s.add_dependency('active_attr', "~> 0.8")
|
34
|
-
s.add_dependency("neo4j-core", "= 3.0.0
|
34
|
+
s.add_dependency("neo4j-core", "= 3.0.0")
|
35
35
|
|
36
36
|
if RUBY_PLATFORM =~ /java/
|
37
37
|
s.add_dependency("neo4j-community", '~> 2.0')
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: neo4j
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.0.0
|
4
|
+
version: 3.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Andreas Ronge
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-09-
|
11
|
+
date: 2014-09-26 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: orm_adapter
|
@@ -86,14 +86,14 @@ dependencies:
|
|
86
86
|
requirements:
|
87
87
|
- - '='
|
88
88
|
- !ruby/object:Gem::Version
|
89
|
-
version: 3.0.0
|
89
|
+
version: 3.0.0
|
90
90
|
type: :runtime
|
91
91
|
prerelease: false
|
92
92
|
version_requirements: !ruby/object:Gem::Requirement
|
93
93
|
requirements:
|
94
94
|
- - '='
|
95
95
|
- !ruby/object:Gem::Version
|
96
|
-
version: 3.0.0
|
96
|
+
version: 3.0.0
|
97
97
|
description: |
|
98
98
|
A Neo4j OGM for use in Ruby on Rails and Rack frameworks, intended as a complete replacement for ActiveRecord.
|
99
99
|
email: andreas.ronge@gmail.com
|
@@ -182,9 +182,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
182
182
|
version: 1.9.1
|
183
183
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
184
184
|
requirements:
|
185
|
-
- - "
|
185
|
+
- - ">="
|
186
186
|
- !ruby/object:Gem::Version
|
187
|
-
version:
|
187
|
+
version: '0'
|
188
188
|
requirements: []
|
189
189
|
rubyforge_project: neo4j
|
190
190
|
rubygems_version: 2.2.2
|