geoff 0.1.2 → 0.2.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.
- data/Gemfile.lock +21 -17
- data/README.md +16 -10
- data/geoff.gemspec +1 -0
- data/lib/geoff/indexer.rb +55 -0
- data/lib/geoff/version.rb +1 -1
- data/lib/geoff.rb +37 -2
- metadata +19 -3
- data/lib/geoff/importer.rb +0 -149
data/Gemfile.lock
CHANGED
@@ -1,36 +1,39 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
geoff (0.
|
4
|
+
geoff (0.2.0)
|
5
5
|
activesupport (~> 3.2.3)
|
6
|
+
geoff-importer (>= 0.0.2)
|
6
7
|
json
|
7
8
|
neo4j
|
8
9
|
|
9
10
|
GEM
|
10
11
|
remote: https://rubygems.org/
|
11
12
|
specs:
|
12
|
-
actionpack (3.2.
|
13
|
-
activemodel (= 3.2.
|
14
|
-
activesupport (= 3.2.
|
13
|
+
actionpack (3.2.9)
|
14
|
+
activemodel (= 3.2.9)
|
15
|
+
activesupport (= 3.2.9)
|
15
16
|
builder (~> 3.0.0)
|
16
17
|
erubis (~> 2.7.0)
|
17
18
|
journey (~> 1.0.4)
|
18
19
|
rack (~> 1.4.0)
|
19
20
|
rack-cache (~> 1.2)
|
20
21
|
rack-test (~> 0.6.1)
|
21
|
-
sprockets (~> 2.1
|
22
|
-
activemodel (3.2.
|
23
|
-
activesupport (= 3.2.
|
22
|
+
sprockets (~> 2.2.1)
|
23
|
+
activemodel (3.2.9)
|
24
|
+
activesupport (= 3.2.9)
|
24
25
|
builder (~> 3.0.0)
|
25
|
-
activesupport (3.2.
|
26
|
+
activesupport (3.2.9)
|
26
27
|
i18n (~> 0.6)
|
27
28
|
multi_json (~> 1.0)
|
28
29
|
bouncy-castle-java (1.5.0146.1)
|
29
|
-
builder (3.0.
|
30
|
+
builder (3.0.4)
|
30
31
|
coderay (1.0.7)
|
31
32
|
columnize (0.3.6)
|
32
33
|
diff-lcs (1.1.3)
|
33
34
|
erubis (2.7.0)
|
35
|
+
geoff-importer (0.0.2)
|
36
|
+
neo4j-community (>= 1.8.M05, < 1.9)
|
34
37
|
hike (1.2.1)
|
35
38
|
i18n (0.6.1)
|
36
39
|
journey (1.0.4)
|
@@ -40,13 +43,13 @@ GEM
|
|
40
43
|
linecache (0.46)
|
41
44
|
rbx-require-relative (> 0.0.4)
|
42
45
|
method_source (0.8)
|
43
|
-
multi_json (1.
|
46
|
+
multi_json (1.4.0)
|
44
47
|
neo4j (2.2.0-java)
|
45
48
|
activemodel (>= 3.0.0, < 3.3)
|
46
49
|
neo4j-wrapper (= 2.2.0)
|
47
50
|
orm_adapter (>= 0.0.3)
|
48
51
|
railties (>= 3.0.0, < 3.3)
|
49
|
-
neo4j-community (1.8
|
52
|
+
neo4j-community (1.8-java)
|
50
53
|
neo4j-core (2.2.0-java)
|
51
54
|
neo4j-community (>= 1.8.M05, < 1.9)
|
52
55
|
neo4j-cypher (~> 1.0.0)
|
@@ -68,16 +71,16 @@ GEM
|
|
68
71
|
rack (>= 0.4)
|
69
72
|
rack-ssl (1.3.2)
|
70
73
|
rack
|
71
|
-
rack-test (0.6.
|
74
|
+
rack-test (0.6.2)
|
72
75
|
rack (>= 1.0)
|
73
|
-
railties (3.2.
|
74
|
-
actionpack (= 3.2.
|
75
|
-
activesupport (= 3.2.
|
76
|
+
railties (3.2.9)
|
77
|
+
actionpack (= 3.2.9)
|
78
|
+
activesupport (= 3.2.9)
|
76
79
|
rack-ssl (~> 1.3.2)
|
77
80
|
rake (>= 0.8.7)
|
78
81
|
rdoc (~> 3.4)
|
79
82
|
thor (>= 0.14.6, < 2.0)
|
80
|
-
rake (0.
|
83
|
+
rake (10.0.2)
|
81
84
|
rbx-require-relative (0.0.9)
|
82
85
|
rdoc (3.12)
|
83
86
|
json (~> 1.4)
|
@@ -97,8 +100,9 @@ GEM
|
|
97
100
|
ruby-debug-base (0.10.4-java)
|
98
101
|
slop (3.3.2)
|
99
102
|
spoon (0.0.1)
|
100
|
-
sprockets (2.
|
103
|
+
sprockets (2.2.2)
|
101
104
|
hike (~> 1.2)
|
105
|
+
multi_json (~> 1.0)
|
102
106
|
rack (~> 1.0)
|
103
107
|
tilt (~> 1.1, != 1.3.0)
|
104
108
|
thor (0.16.0)
|
data/README.md
CHANGED
@@ -41,7 +41,7 @@ Geoff(Company, Person) do
|
|
41
41
|
company 'Acme' do
|
42
42
|
address "13 Something Road"
|
43
43
|
|
44
|
-
|
44
|
+
outgoing :employees do
|
45
45
|
person 'Geoff'
|
46
46
|
|
47
47
|
person 'Nigel' do
|
@@ -51,12 +51,18 @@ Geoff(Company, Person) do
|
|
51
51
|
end
|
52
52
|
|
53
53
|
company 'Github' do
|
54
|
-
|
54
|
+
outgoing :customers do
|
55
55
|
person 'Tom'
|
56
56
|
person 'Dick'
|
57
57
|
person 'Harry'
|
58
58
|
end
|
59
59
|
end
|
60
|
+
|
61
|
+
person 'Harry' do
|
62
|
+
incoming :customers do
|
63
|
+
company 'NeoTech'
|
64
|
+
end
|
65
|
+
end
|
60
66
|
end
|
61
67
|
|
62
68
|
```
|
@@ -112,7 +118,7 @@ end
|
|
112
118
|
```ruby
|
113
119
|
Geoff(Company, Person) do
|
114
120
|
company 'Amazon' do
|
115
|
-
|
121
|
+
outgoing do
|
116
122
|
person 'Tom', type: :customers
|
117
123
|
person 'Tom', type: :supplier
|
118
124
|
end
|
@@ -140,13 +146,13 @@ end
|
|
140
146
|
```ruby
|
141
147
|
Geoff(Company, Person) do
|
142
148
|
company 'Amazon' do
|
143
|
-
|
149
|
+
outgoing 'employees' do
|
144
150
|
b.judas = person 'Judas'
|
145
151
|
end
|
146
152
|
end
|
147
153
|
|
148
154
|
company 'Moonlighters' do
|
149
|
-
|
155
|
+
outgoing do
|
150
156
|
b.judas type: 'employees'
|
151
157
|
end
|
152
158
|
end
|
@@ -186,14 +192,14 @@ end
|
|
186
192
|
#Injecting builders
|
187
193
|
```ruby
|
188
194
|
coffee_machines_builder = Geoff do
|
189
|
-
b.large_coffee_machines =
|
195
|
+
b.large_coffee_machines = outgoing do
|
190
196
|
coffee_machine('large_machine') { power 2300 }
|
191
197
|
coffee_machine('xxl_machine' ) { power 2600 }
|
192
198
|
end
|
193
199
|
end
|
194
200
|
|
195
201
|
tables_builder = Geoff do
|
196
|
-
b.tables =
|
202
|
+
b.tables = outgoing do
|
197
203
|
table('round_table' ) { capacity 3 }
|
198
204
|
table('square_table') { capacity 4 }
|
199
205
|
end
|
@@ -203,7 +209,7 @@ Geoff(coffee_machines_builder, tables_builder) do
|
|
203
209
|
branch 'acme_coffee_luton_branch' do
|
204
210
|
number_of_employees 15
|
205
211
|
|
206
|
-
|
212
|
+
outgoing do
|
207
213
|
b.small_coffee_machines type: 'uses', lease: '3 years'
|
208
214
|
b.tables type: 'has'
|
209
215
|
end
|
@@ -232,11 +238,11 @@ Geoff do
|
|
232
238
|
b.grinder = grinder 'fine_grinder'
|
233
239
|
|
234
240
|
branch 'acme_coffee_luton_branch' do
|
235
|
-
|
241
|
+
outgoing 'uses' do
|
236
242
|
b.machine = coffee_machine('large_machine') do
|
237
243
|
power 2300
|
238
244
|
|
239
|
-
|
245
|
+
outgoing 'connected_to' do
|
240
246
|
b.grinder clone: false
|
241
247
|
end
|
242
248
|
end
|
data/geoff.gemspec
CHANGED
@@ -0,0 +1,55 @@
|
|
1
|
+
class Geoff
|
2
|
+
class Error < StandardError ; end
|
3
|
+
class MissingIndexedProperty < Geoff::Error ; end
|
4
|
+
|
5
|
+
module Indexer
|
6
|
+
class << self
|
7
|
+
|
8
|
+
def rebuild_indices db
|
9
|
+
@db = db
|
10
|
+
|
11
|
+
Geoff.log 're-building indexes'
|
12
|
+
Neo4j::Transaction.run do
|
13
|
+
node_types.each do |type|
|
14
|
+
re_index(type)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
def node_types
|
22
|
+
root_node.relationships.map { |r| Kernel.const_get(r.get_type.to_s) rescue nil }.compact
|
23
|
+
end
|
24
|
+
|
25
|
+
def re_index(type)
|
26
|
+
Geoff.log "-> re-indexing #{type}"
|
27
|
+
props = type.instance_variable_get(:@_decl_props)
|
28
|
+
indexed_props = props.find_all { |_, p| p.has_key?(:index) }
|
29
|
+
|
30
|
+
indexed_props.each do |index|
|
31
|
+
all = type.all
|
32
|
+
|
33
|
+
all.each do |node|
|
34
|
+
@current_node = node
|
35
|
+
@current_index = index.first
|
36
|
+
node.add_index index.first
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
rescue NativeException => e
|
41
|
+
Geoff.log "-" * 80
|
42
|
+
message = "#{type} missing indexed attribute #{@current_index}, on node: #{@current_node.attributes}"
|
43
|
+
Geoff.log message
|
44
|
+
Geoff.log "-" * 80
|
45
|
+
Geoff.log e.message
|
46
|
+
Geoff.log "-" * 80
|
47
|
+
raise Geoff::MissingIndexedProperty, message
|
48
|
+
end
|
49
|
+
|
50
|
+
def root_node
|
51
|
+
@db.reference_node
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
data/lib/geoff/version.rb
CHANGED
data/lib/geoff.rb
CHANGED
@@ -2,6 +2,7 @@ require "json"
|
|
2
2
|
require "geoff/version"
|
3
3
|
require 'geoff/node_dsl'
|
4
4
|
require 'geoff/children_dsl'
|
5
|
+
require 'geoff-importer'
|
5
6
|
|
6
7
|
def java_present?
|
7
8
|
require 'java'
|
@@ -11,7 +12,7 @@ rescue LoadError
|
|
11
12
|
end
|
12
13
|
|
13
14
|
if java_present?
|
14
|
-
require 'geoff/
|
15
|
+
require 'geoff/indexer'
|
15
16
|
else
|
16
17
|
$stderr.puts "In order to use the Geoff::Importer class and Geoff.import you must
|
17
18
|
be running under jruby"
|
@@ -24,6 +25,40 @@ class Geoff::DslSyntaxError < Geoff::Error; end
|
|
24
25
|
|
25
26
|
|
26
27
|
class Geoff
|
28
|
+
class << self
|
29
|
+
|
30
|
+
def import *args
|
31
|
+
@options = args[1]
|
32
|
+
Geoff.log @options
|
33
|
+
db = options.delete(:db) || Neo4j.db.graph
|
34
|
+
node_map = build_node_map db
|
35
|
+
Importer.import args[0], db, node_map
|
36
|
+
Indexer.rebuild_indices(Neo4j.db.graph) unless options[:skip_index]
|
37
|
+
true
|
38
|
+
end
|
39
|
+
|
40
|
+
def build_node_map db
|
41
|
+
return {} if db.is_a?(String)
|
42
|
+
ref_node = db.reference_node
|
43
|
+
ref_node.rels(:outgoing).inject({}) do |h, r|
|
44
|
+
h[r.rel_type.to_s] = r.end_node
|
45
|
+
h
|
46
|
+
end.merge("ROOT" => ref_node)
|
47
|
+
end
|
48
|
+
|
49
|
+
def log(message)
|
50
|
+
$stdout.puts message unless silent?
|
51
|
+
end
|
52
|
+
|
53
|
+
def silent?
|
54
|
+
options.has_key?(:silent) ? options[:silent] : false
|
55
|
+
end
|
56
|
+
|
57
|
+
def options
|
58
|
+
@options || {}
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
27
62
|
attr_reader :children_dsl, :container
|
28
63
|
|
29
64
|
def initialize *classes_and_builders, &block
|
@@ -45,7 +80,7 @@ class Geoff
|
|
45
80
|
parent_node_dsl: nil,
|
46
81
|
type: nil,
|
47
82
|
container: @container
|
48
|
-
|
83
|
+
})
|
49
84
|
|
50
85
|
@children_dsl = ChildrenDsl.new(options, &block) if block_given?
|
51
86
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: geoff
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -13,7 +13,7 @@ authors:
|
|
13
13
|
autorequire:
|
14
14
|
bindir: bin
|
15
15
|
cert_chain: []
|
16
|
-
date: 2012-
|
16
|
+
date: 2012-12-07 00:00:00.000000000 Z
|
17
17
|
dependencies:
|
18
18
|
- !ruby/object:Gem::Dependency
|
19
19
|
name: neo4j
|
@@ -33,6 +33,22 @@ dependencies:
|
|
33
33
|
none: false
|
34
34
|
prerelease: false
|
35
35
|
type: :runtime
|
36
|
+
- !ruby/object:Gem::Dependency
|
37
|
+
name: geoff-importer
|
38
|
+
version_requirements: !ruby/object:Gem::Requirement
|
39
|
+
requirements:
|
40
|
+
- - ! '>='
|
41
|
+
- !ruby/object:Gem::Version
|
42
|
+
version: 0.0.2
|
43
|
+
none: false
|
44
|
+
requirement: !ruby/object:Gem::Requirement
|
45
|
+
requirements:
|
46
|
+
- - ! '>='
|
47
|
+
- !ruby/object:Gem::Version
|
48
|
+
version: 0.0.2
|
49
|
+
none: false
|
50
|
+
prerelease: false
|
51
|
+
type: :runtime
|
36
52
|
- !ruby/object:Gem::Dependency
|
37
53
|
name: jruby-openssl
|
38
54
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -180,7 +196,7 @@ files:
|
|
180
196
|
- lib/geoff/children_dsl.rb
|
181
197
|
- lib/geoff/container.rb
|
182
198
|
- lib/geoff/dsl_exception_handling.rb
|
183
|
-
- lib/geoff/
|
199
|
+
- lib/geoff/indexer.rb
|
184
200
|
- lib/geoff/node_dsl.rb
|
185
201
|
- lib/geoff/version.rb
|
186
202
|
- spec/integration/children_dsl_spec.rb
|
data/lib/geoff/importer.rb
DELETED
@@ -1,149 +0,0 @@
|
|
1
|
-
require 'fileutils'
|
2
|
-
Dir["lib/jars/*"].each {|file| require file }
|
3
|
-
|
4
|
-
class Geoff
|
5
|
-
class Error < StandardError ; end
|
6
|
-
class MissingIndexedProperty < Geoff::Error ; end
|
7
|
-
class InvalidRules < Geoff::Error ; end
|
8
|
-
|
9
|
-
def self.import *args
|
10
|
-
Importer.import *args
|
11
|
-
end
|
12
|
-
|
13
|
-
class Importer
|
14
|
-
Subgraph = org.neo4j.geoff.Subgraph
|
15
|
-
|
16
|
-
class << self
|
17
|
-
def import_files(*files, options)
|
18
|
-
concatenated = files.map{|f|File.read f}.join "\n"
|
19
|
-
|
20
|
-
import concatenated, options
|
21
|
-
end
|
22
|
-
|
23
|
-
def import_file(file, options = {})
|
24
|
-
rules = File.read(file)
|
25
|
-
import(rules, options)
|
26
|
-
end
|
27
|
-
|
28
|
-
def import(geoff, options = {})
|
29
|
-
geoff = geoff.to_geoff unless geoff.is_a? String
|
30
|
-
|
31
|
-
geoff = geoff.split "\n" if geoff.is_a? String
|
32
|
-
|
33
|
-
new(geoff, options).go
|
34
|
-
end
|
35
|
-
end
|
36
|
-
|
37
|
-
def initialize(rules, options)
|
38
|
-
@rules = rules
|
39
|
-
@options = options
|
40
|
-
log @options.inspect
|
41
|
-
end
|
42
|
-
|
43
|
-
def go
|
44
|
-
raise Geoff::InvalidRules.new('Invalid rules') unless validate_rules(@rules)
|
45
|
-
|
46
|
-
log 'importing the database'
|
47
|
-
|
48
|
-
import_geoff_rules @rules
|
49
|
-
rebuild_indexes
|
50
|
-
|
51
|
-
true
|
52
|
-
end
|
53
|
-
|
54
|
-
private
|
55
|
-
|
56
|
-
def import_geoff_rules(rules)
|
57
|
-
sub_graph = Subgraph.new(rules)
|
58
|
-
node_map = build_node_map
|
59
|
-
org.neo4j.geoff.Geoff.mergeIntoNeo4j(sub_graph, Neo4j.db.graph, node_map );
|
60
|
-
end
|
61
|
-
|
62
|
-
def build_node_map
|
63
|
-
root_node.rels(:outgoing).inject({}) do |h, r|
|
64
|
-
h[r.rel_type.to_s] = r.end_node
|
65
|
-
h
|
66
|
-
end.merge("ROOT" => root_node)
|
67
|
-
end
|
68
|
-
|
69
|
-
def rebuild_indexes
|
70
|
-
log 're-building indexes'
|
71
|
-
Neo4j::Transaction.run do
|
72
|
-
node_types.each do |type|
|
73
|
-
re_index(type)
|
74
|
-
end
|
75
|
-
end
|
76
|
-
end
|
77
|
-
|
78
|
-
def node_types
|
79
|
-
root_node.relationships.map { |r| Kernel.const_get(r.get_type.to_s) rescue nil }.compact
|
80
|
-
end
|
81
|
-
|
82
|
-
def re_index(type)
|
83
|
-
log "-> re-indexing #{type}"
|
84
|
-
props = type.instance_variable_get(:@_decl_props)
|
85
|
-
indexed_props = props.find_all { |_, p| p.has_key?(:index) }
|
86
|
-
|
87
|
-
indexed_props.each do |index|
|
88
|
-
all = type.all
|
89
|
-
|
90
|
-
all.each do |node|
|
91
|
-
@current_node = node
|
92
|
-
@current_index = index.first
|
93
|
-
node.add_index index.first
|
94
|
-
end
|
95
|
-
end
|
96
|
-
|
97
|
-
rescue NativeException => e
|
98
|
-
log "-" * 80
|
99
|
-
message = "#{type} missing indexed attribute #{@current_index}, on node: #{@current_node.attributes}"
|
100
|
-
log message
|
101
|
-
log "-" * 80
|
102
|
-
log e.message
|
103
|
-
log "-" * 80
|
104
|
-
raise Geoff::MissingIndexedProperty, message
|
105
|
-
end
|
106
|
-
|
107
|
-
def tx
|
108
|
-
Neo4j::Transaction.run { yield if block_given? }
|
109
|
-
end
|
110
|
-
|
111
|
-
def root_node
|
112
|
-
Neo4j.ref_node
|
113
|
-
end
|
114
|
-
|
115
|
-
def log(message)
|
116
|
-
$stdout.puts message unless silent?
|
117
|
-
end
|
118
|
-
|
119
|
-
def silent?
|
120
|
-
option_value? :silent
|
121
|
-
end
|
122
|
-
|
123
|
-
def testmode?
|
124
|
-
option_value? :test
|
125
|
-
end
|
126
|
-
|
127
|
-
def option_value?(key, default = false)
|
128
|
-
@options[key].nil? ? default : @options[key]
|
129
|
-
end
|
130
|
-
|
131
|
-
def validate_rules(rules)
|
132
|
-
@invalid = Array(rules).map do |r|
|
133
|
-
validate_rule(r)
|
134
|
-
end.compact
|
135
|
-
|
136
|
-
@invalid.each { |r, message| log "Rule '#{r}' is invalid: #{message}" }
|
137
|
-
@invalid.empty?
|
138
|
-
end
|
139
|
-
|
140
|
-
def validate_rule(rule)
|
141
|
-
Subgraph.new(Array(rule))
|
142
|
-
nil
|
143
|
-
rescue Exception => e
|
144
|
-
return [rule, e.message]
|
145
|
-
end
|
146
|
-
|
147
|
-
end
|
148
|
-
|
149
|
-
end
|