geoff 0.1.2 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|