cadet 0.0.9-java → 0.1.0-java
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/README.md +34 -5
- data/circle.yml +3 -0
- data/lib/cadet/batch_inserter/cadet_index/index.rb +38 -0
- data/lib/cadet/batch_inserter/cadet_index/index_provider.rb +19 -0
- data/lib/cadet/batch_inserter/session.rb +9 -4
- data/lib/cadet/node.rb +10 -7
- data/lib/cadet/node_traverser.rb +4 -0
- data/lib/cadet/path_traverser.rb +2 -12
- data/lib/cadet/relationship.rb +31 -0
- data/lib/cadet/session.rb +32 -7
- data/lib/cadet/transaction.rb +0 -10
- data/lib/cadet/version.rb +1 -1
- data/lib/cadet.rb +2 -6
- data/spec/spec_helper.rb +0 -51
- data/spec/unit/batch_insert_spec.rb +16 -128
- data/spec/unit/cadet_spec.rb +159 -37
- metadata +5 -7
- data/Gemfile.lock +0 -26
- data/lib/cadet/cadet_index/index.rb +0 -33
- data/lib/cadet/cadet_index/index_provider.rb +0 -20
- data/lib/cadet/dsl.rb +0 -28
- data/lib/cadet/test/session.rb +0 -11
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 44c6bd53bbc5065234be58f9851fb93fb8b35030
|
4
|
+
data.tar.gz: e07f2a4322395961deea2586f5dcb18f3bdddd35
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e213c75cca7e02ed89f2369b6c63e60c56a8d976601239b8963d8faf80ec741c6da071d293f0573e339ca6ab2dfb9797f4f7949e6409ac20756de0fdb9339974
|
7
|
+
data.tar.gz: 9053afd936989c658a6bc230f71c81864585312b9c1453e4dfb41e5f7263fc7e241d4806d2983d17a48a3451dd410a0e1e69618d11efc1fb28353a389d840ecd
|
data/.gitignore
CHANGED
data/README.md
CHANGED
@@ -12,18 +12,47 @@ super simple. you dont even need to download neo4j.
|
|
12
12
|
|
13
13
|
require 'cadet'
|
14
14
|
|
15
|
-
|
16
|
-
db = Cadet::Session.open("neo4j-community-2.0.0/data/graph.db").dsl do
|
17
|
-
#begin a transaction. the transaction will automatically finish at the end of the provided block
|
15
|
+
Cadet::Session.open "path/to/graph.db/" do
|
18
16
|
transaction do
|
19
17
|
Person_by_name("Javad").lives_in_to City_by_name("Chicago")
|
20
18
|
end
|
21
19
|
end
|
22
20
|
|
23
|
-
#close the database
|
24
|
-
db.close
|
25
21
|
|
26
22
|
```
|
27
23
|
|
24
|
+
## Getting/creating a node, using label-property-value
|
25
|
+
A node can be retrieved (and implicitly created if it does not exist) via the following syntax:
|
26
|
+
```ruby
|
27
|
+
javad = Person_by_name("Javad")
|
28
|
+
```
|
29
|
+
This will search for a node with the label "Person", and with the a "name" property set to "Javad".
|
30
|
+
If a "Person" node with "name" "Javad" is not found, it will create the node, add the label "Person", and set the "name" to "javad".
|
31
|
+
|
32
|
+
## Setting / retrieving a nodes properties
|
33
|
+
A node's properties can be accessed and modified just as if the node was a hash:
|
34
|
+
```ruby
|
35
|
+
javad[:age] = 25
|
36
|
+
puts javad[:age] # 25
|
37
|
+
```
|
38
|
+
|
39
|
+
## Creating a relationship between 2 nodes
|
40
|
+
A relationship can be added between 2 nodes via the following syntax:
|
41
|
+
```ruby
|
42
|
+
javad.lives_in_to City_by_name("Chicago")
|
43
|
+
```
|
44
|
+
This returns a Cadet#Relationship object, which can then have its properties set just like a hash:
|
45
|
+
```ruby
|
46
|
+
new_relationship = javad.lives_in_to City_by_name("Chicago")
|
47
|
+
new_relationship[:from] = "2012"
|
48
|
+
new_relationship[:to] = "ongoing"
|
49
|
+
```
|
50
|
+
|
51
|
+
Relationship creation can also be chained:
|
52
|
+
```ruby
|
53
|
+
Person_by_name("Javad").lives_in_to(City_by_name("Chicago")).city_of_to(State_by_name("Illinois")).state_of_to(Country_by_name("United States"))
|
54
|
+
```
|
55
|
+
|
56
|
+
|
28
57
|
Batch insert mode can be used by simply using Cadet::BatchInserter::Session instead of Cadet::Session!
|
29
58
|
None of your code needs to change.
|
data/circle.yml
ADDED
@@ -0,0 +1,38 @@
|
|
1
|
+
module Cadet
|
2
|
+
module BatchInserter
|
3
|
+
module CadetIndex
|
4
|
+
class Index
|
5
|
+
def initialize(lucene_index, name, type)
|
6
|
+
@name = name.to_sym
|
7
|
+
@type = type
|
8
|
+
@property_index = {}
|
9
|
+
@lucene_index = lucene_index
|
10
|
+
end
|
11
|
+
|
12
|
+
def add(node, property, value)
|
13
|
+
@property_index[property.to_sym] ||= {}
|
14
|
+
@property_index[property.to_sym][value] ||= []
|
15
|
+
@property_index[property.to_sym][value] << node
|
16
|
+
end
|
17
|
+
|
18
|
+
def get(property, value)
|
19
|
+
@property_index[property.to_sym] ||= {}
|
20
|
+
@property_index[property.to_sym][value] || []
|
21
|
+
end
|
22
|
+
|
23
|
+
def flush
|
24
|
+
lucene_node_index = @lucene_index.nodeIndex(@name, @type)
|
25
|
+
|
26
|
+
@property_index.each do |property, propval_to_node_mappings|
|
27
|
+
propval_to_node_mappings.each do |value, nodes|
|
28
|
+
nodes.each do |node|
|
29
|
+
lucene_node_index.add(node, {property.to_java_string => value})
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Cadet
|
2
|
+
module BatchInserter
|
3
|
+
module CadetIndex
|
4
|
+
class IndexProvider
|
5
|
+
|
6
|
+
def initialize(db)
|
7
|
+
@indexes = {}
|
8
|
+
@lucene_index = org.neo4j.index.impl.lucene.LuceneBatchInserterIndexProviderNewImpl.new(db)
|
9
|
+
end
|
10
|
+
def nodeIndex(label, type = {"type" => "exact"})
|
11
|
+
@indexes[label.to_sym] ||= CadetIndex::Index.new(@lucene_index, label.to_sym, type)
|
12
|
+
end
|
13
|
+
def shutdown
|
14
|
+
@indexes.each { |label, index| index.flush }
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -4,7 +4,7 @@ module Cadet
|
|
4
4
|
|
5
5
|
def initialize(db)
|
6
6
|
@index_provider = CadetIndex::IndexProvider.new(db)
|
7
|
-
|
7
|
+
@db = db
|
8
8
|
end
|
9
9
|
|
10
10
|
def close
|
@@ -12,8 +12,13 @@ module Cadet
|
|
12
12
|
super
|
13
13
|
end
|
14
14
|
|
15
|
-
def self.open(location,
|
16
|
-
new
|
15
|
+
def self.open(location, &block)
|
16
|
+
new(org.neo4j.unsafe.batchinsert.BatchInserters.inserter(location)).tap do |session|
|
17
|
+
if block_given?
|
18
|
+
session.instance_exec(session, &block)
|
19
|
+
session.close
|
20
|
+
end
|
21
|
+
end
|
17
22
|
end
|
18
23
|
|
19
24
|
def constraint(label, property)
|
@@ -36,7 +41,7 @@ module Cadet
|
|
36
41
|
end
|
37
42
|
|
38
43
|
def get_transaction
|
39
|
-
|
44
|
+
Transaction.new(self)
|
40
45
|
end
|
41
46
|
|
42
47
|
end
|
data/lib/cadet/node.rb
CHANGED
@@ -51,13 +51,16 @@ module Cadet
|
|
51
51
|
end
|
52
52
|
|
53
53
|
def method_missing(name, *args, &block)
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
54
|
+
case name
|
55
|
+
when /([A-z_]*)_to$/
|
56
|
+
self.class.class_eval "
|
57
|
+
def #{name}(value)
|
58
|
+
create_outgoing(value, :#{$1})
|
59
|
+
end
|
60
|
+
"
|
61
|
+
self.send(name, *args, &block)
|
62
|
+
else
|
63
|
+
raise NotImplementedError
|
61
64
|
end
|
62
65
|
end
|
63
66
|
|
data/lib/cadet/node_traverser.rb
CHANGED
data/lib/cadet/path_traverser.rb
CHANGED
@@ -9,18 +9,8 @@ module Cadet
|
|
9
9
|
end
|
10
10
|
|
11
11
|
def each
|
12
|
-
|
13
|
-
@
|
14
|
-
n.outgoing(@type).each do |o|
|
15
|
-
yield o
|
16
|
-
end
|
17
|
-
end
|
18
|
-
else
|
19
|
-
@nodes.each do |n|
|
20
|
-
n.incoming(@type).each do |o|
|
21
|
-
yield o
|
22
|
-
end
|
23
|
-
end
|
12
|
+
@nodes.each do |n|
|
13
|
+
n.send(@direction, @type).each { |o| yield o }
|
24
14
|
end
|
25
15
|
end
|
26
16
|
|
data/lib/cadet/relationship.rb
CHANGED
@@ -10,8 +10,39 @@ module Cadet
|
|
10
10
|
@underlying.getId == other_rel.underlying.getId
|
11
11
|
end
|
12
12
|
|
13
|
+
def []= (property, value)
|
14
|
+
@underlying.setProperty(property.to_java_string, value)
|
15
|
+
end
|
16
|
+
|
17
|
+
def [] (property)
|
18
|
+
@underlying.getProperty(property.to_java_string)
|
19
|
+
end
|
20
|
+
|
13
21
|
def get_other_node(node)
|
14
22
|
Node.new @underlying.getOtherNode(node.underlying)
|
15
23
|
end
|
24
|
+
|
25
|
+
def start_node
|
26
|
+
Node.new @underlying.getStartNode
|
27
|
+
end
|
28
|
+
|
29
|
+
def end_node
|
30
|
+
Node.new @underlying.getEndNode
|
31
|
+
end
|
32
|
+
|
33
|
+
def method_missing(name, *args, &block)
|
34
|
+
case name
|
35
|
+
when /([A-z_]*)_to$/
|
36
|
+
self.class.class_eval "
|
37
|
+
def #{name}(value)
|
38
|
+
end_node.create_outgoing(value, :#{$1})
|
39
|
+
end
|
40
|
+
"
|
41
|
+
self.send(name, *args, &block)
|
42
|
+
else
|
43
|
+
raise NotImplementedError
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
16
47
|
end
|
17
48
|
end
|
data/lib/cadet/session.rb
CHANGED
@@ -4,9 +4,18 @@ module Cadet
|
|
4
4
|
@db = db
|
5
5
|
end
|
6
6
|
|
7
|
-
def self.open(location)
|
8
|
-
|
7
|
+
def self.open(location = nil, &block)
|
8
|
+
(location ?
|
9
|
+
new(org.neo4j.graphdb.factory.GraphDatabaseFactory.new.newEmbeddedDatabase(location)) :
|
10
|
+
new(org.neo4j.test.TestGraphDatabaseFactory.new.newImpermanentDatabase))
|
11
|
+
.tap do |session|
|
12
|
+
if block_given?
|
13
|
+
session.instance_exec(session, &block)
|
14
|
+
session.close
|
15
|
+
end
|
16
|
+
end
|
9
17
|
end
|
18
|
+
|
10
19
|
def close
|
11
20
|
@db.shutdown
|
12
21
|
end
|
@@ -31,11 +40,6 @@ module Cadet
|
|
31
40
|
Transaction.new(self)
|
32
41
|
end
|
33
42
|
|
34
|
-
def dsl(&block)
|
35
|
-
DSL.new(self).instance_exec(self, &block)
|
36
|
-
self
|
37
|
-
end
|
38
|
-
|
39
43
|
def transaction
|
40
44
|
tx = get_transaction
|
41
45
|
begin
|
@@ -56,5 +60,26 @@ module Cadet
|
|
56
60
|
def begin_tx
|
57
61
|
@db.beginTx
|
58
62
|
end
|
63
|
+
|
64
|
+
def method_missing(name, *args, &block)
|
65
|
+
case name
|
66
|
+
when /^([A-z_]*)_by_([A-z_]*)$/
|
67
|
+
self.class.class_eval "
|
68
|
+
def #{name}(value)
|
69
|
+
get_node :#{$1}, :#{$2}, value
|
70
|
+
end"
|
71
|
+
return self.send(name, *args, &block)
|
72
|
+
|
73
|
+
when /^create_([A-z_]*)$/
|
74
|
+
self.class.class_eval "
|
75
|
+
def #{name}(value, indexing_property = nil)
|
76
|
+
create_node :#{$1}, value, indexing_property
|
77
|
+
end"
|
78
|
+
return self.send(name, *args, &block)
|
79
|
+
else
|
80
|
+
raise NotImplementedError
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
59
84
|
end
|
60
85
|
end
|
data/lib/cadet/transaction.rb
CHANGED
@@ -7,21 +7,11 @@ module Cadet
|
|
7
7
|
@underlying = @session.begin_tx
|
8
8
|
end
|
9
9
|
|
10
|
-
def method_missing(name, *args, &block)
|
11
|
-
# for the "dsl".
|
12
|
-
# the transaction block is instance_eval'd by this class,
|
13
|
-
# so any missing methods are then sent to the session
|
14
|
-
# essentially means that session.blah can then be writen blah
|
15
|
-
@session.send(name, *args, &block)
|
16
|
-
|
17
|
-
end
|
18
|
-
|
19
10
|
def success
|
20
11
|
@underlying.success
|
21
12
|
end
|
22
13
|
def close
|
23
14
|
@underlying.close
|
24
15
|
end
|
25
|
-
|
26
16
|
end
|
27
17
|
end
|
data/lib/cadet/version.rb
CHANGED
data/lib/cadet.rb
CHANGED
@@ -14,16 +14,12 @@ require 'cadet/path_traverser'
|
|
14
14
|
require 'cadet/node_relationships'
|
15
15
|
require 'cadet/transaction'
|
16
16
|
|
17
|
-
require 'cadet/dsl'
|
18
|
-
|
19
17
|
require 'cadet/batch_inserter/session'
|
20
18
|
require 'cadet/batch_inserter/node'
|
21
19
|
require 'cadet/batch_inserter/transaction'
|
22
20
|
|
23
|
-
require 'cadet/
|
24
|
-
|
25
|
-
require 'cadet/cadet_index/index_provider'
|
26
|
-
require 'cadet/cadet_index/index'
|
21
|
+
require 'cadet/batch_inserter/cadet_index/index_provider'
|
22
|
+
require 'cadet/batch_inserter/cadet_index/index'
|
27
23
|
|
28
24
|
require 'cadet/dynamic_relationshiptype'
|
29
25
|
require 'cadet/dynamic_label'
|
data/spec/spec_helper.rb
CHANGED
@@ -1,52 +1 @@
|
|
1
1
|
require 'cadet'
|
2
|
-
require 'tmpdir'
|
3
|
-
|
4
|
-
def quick_test_neo4j
|
5
|
-
test_neo4j do |db|
|
6
|
-
db.transaction do |tx|
|
7
|
-
yield db, tx
|
8
|
-
end
|
9
|
-
end
|
10
|
-
end
|
11
|
-
|
12
|
-
def test_neo4j
|
13
|
-
db = Cadet::Test::Session.open
|
14
|
-
yield db
|
15
|
-
db.close
|
16
|
-
end
|
17
|
-
|
18
|
-
def quick_normal_neo4j(at = nil)
|
19
|
-
at ||= Dir.mktmpdir
|
20
|
-
|
21
|
-
normal_neo4j(at) do |db|
|
22
|
-
db.transaction do
|
23
|
-
yield db
|
24
|
-
end
|
25
|
-
end
|
26
|
-
at
|
27
|
-
end
|
28
|
-
|
29
|
-
def normal_neo4j(at)
|
30
|
-
db = Cadet::Session.open(at)
|
31
|
-
yield db
|
32
|
-
db.close
|
33
|
-
end
|
34
|
-
|
35
|
-
def quick_batch_neo4j(at = nil)
|
36
|
-
at ||= Dir.mktmpdir
|
37
|
-
|
38
|
-
batch_neo4j(at) do |db|
|
39
|
-
yield db
|
40
|
-
end
|
41
|
-
at
|
42
|
-
end
|
43
|
-
|
44
|
-
def batch_neo4j(at)
|
45
|
-
db = Cadet::BatchInserter::Session.open(at)
|
46
|
-
yield db
|
47
|
-
db.close
|
48
|
-
end
|
49
|
-
|
50
|
-
def quick_batch_dsl_neo4j
|
51
|
-
yield quick_batch_neo4j.dsl
|
52
|
-
end
|
@@ -2,143 +2,31 @@ require 'spec_helper'
|
|
2
2
|
require 'tmpdir'
|
3
3
|
|
4
4
|
describe Cadet::BatchInserter do
|
5
|
-
it "should set a nodes property" do
|
6
|
-
tmpdir = quick_batch_neo4j do |db|
|
7
|
-
javad = db.get_node(:Person, :name, "Javad")
|
8
|
-
javad[:age] = 25
|
9
|
-
end
|
10
|
-
|
11
|
-
quick_normal_neo4j(tmpdir) do |db|
|
12
|
-
javad = db.get_node(:Person, :name, "Javad")
|
13
|
-
javad[:age].should == 25
|
14
|
-
end
|
15
|
-
end
|
16
|
-
|
17
|
-
it "should create a relationship" do
|
18
|
-
tmpdir = quick_batch_neo4j do |db|
|
19
|
-
javad = db.get_node(:Person, :name, "Javad")
|
20
|
-
ellen = db.get_node(:Person, :name, "Ellen")
|
21
|
-
|
22
|
-
javad.outgoing(:knows) << ellen
|
23
|
-
end
|
24
|
-
|
25
|
-
quick_normal_neo4j(tmpdir) do |db|
|
26
|
-
javad = db.get_node(:Person, :name, "Javad")
|
27
|
-
ellen = db.get_node(:Person, :name, "Ellen")
|
28
5
|
|
29
|
-
|
30
|
-
|
6
|
+
it "should create an instance of cadet session, for test and normal sessions" do
|
7
|
+
Cadet::BatchInserter::Session.open(Dir.mktmpdir).class.should == Cadet::BatchInserter::Session
|
31
8
|
end
|
32
9
|
|
33
|
-
it "should
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
quick_normal_neo4j(tmpdir) do |db|
|
39
|
-
javad = db.get_node(:Person, :name, "Javad")
|
10
|
+
it "it should accept multiple relationships" do
|
11
|
+
at = Dir.mktmpdir
|
12
|
+
Cadet::BatchInserter::Session.open(at) do
|
13
|
+
self.class.should == Cadet::BatchInserter::Session
|
40
14
|
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
it "should retrieve the same node, for the same label-key-value" do
|
47
|
-
tmpdir = quick_batch_neo4j do |db|
|
48
|
-
javad = db.get_node(:Person, :name, "Javad")
|
49
|
-
ellen = db.get_node(:Person, :name, "Ellen")
|
50
|
-
|
51
|
-
javad.outgoing(:lives_in) << db.get_node(:City, :name, "Chicago")
|
52
|
-
ellen.outgoing(:lives_in) << db.get_node(:City, :name, "Chicago")
|
53
|
-
end
|
54
|
-
|
55
|
-
quick_normal_neo4j(tmpdir) do |db|
|
56
|
-
javad = db.get_node(:Person, :name, "Javad")
|
57
|
-
ellen = db.get_node(:Person, :name, "Ellen")
|
58
|
-
|
59
|
-
javad.outgoing(:lives_in).should == ellen.outgoing(:lives_in)
|
60
|
-
end
|
61
|
-
end
|
62
|
-
|
63
|
-
it "should work" do
|
64
|
-
tmpdir = quick_batch_neo4j do |db|
|
65
|
-
javad = db.get_node :Person, :name, "Javad"
|
66
|
-
ellen = db.get_node :Person, :name, "Ellen"
|
67
|
-
trunkclub = db.get_node :Company, :name, "Trunkclub"
|
68
|
-
chicago = db.get_node :City, :name, "Chicago"
|
69
|
-
us = db.get_node :Country, :name, "United States"
|
70
|
-
|
71
|
-
javad.outgoing(:works_at) << trunkclub
|
72
|
-
trunkclub.outgoing(:located_in) << chicago
|
73
|
-
ellen.outgoing(:lives_in) << chicago
|
74
|
-
chicago.outgoing(:country) << us
|
75
|
-
end
|
76
|
-
|
77
|
-
quick_normal_neo4j(tmpdir) do |db|
|
78
|
-
javad = db.get_node :Person, :name, "Javad"
|
79
|
-
ellen = db.get_node :Person, :name, "Ellen"
|
80
|
-
trunkclub = db.get_node :Company, :name, "Trunkclub"
|
81
|
-
chicago = db.get_node :City, :name, "Chicago"
|
82
|
-
us = db.get_node :Country, :name, "United States"
|
83
|
-
|
84
|
-
javad.outgoing(:works_at).should == [trunkclub]
|
85
|
-
end
|
86
|
-
|
87
|
-
end
|
88
|
-
|
89
|
-
it "should work" do
|
90
|
-
tmpdir = quick_batch_neo4j do |db|
|
91
|
-
javad = db.get_node :Person, :name, "Javad"
|
92
|
-
ellen = db.get_node :Person, :name, "Ellen"
|
93
|
-
trunkclub = db.get_node :Company, :name, "Trunkclub"
|
94
|
-
chicago = db.get_node :City, :name, "Chicago"
|
95
|
-
us = db.get_node :Country, :name, "United States"
|
96
|
-
|
97
|
-
javad.outgoing(:lives_in) << chicago
|
98
|
-
ellen.outgoing(:lives_in) << chicago
|
99
|
-
end
|
100
|
-
|
101
|
-
quick_normal_neo4j(tmpdir) do |db|
|
102
|
-
javad = db.get_node :Person, :name, "Javad"
|
103
|
-
ellen = db.get_node :Person, :name, "Ellen"
|
104
|
-
trunkclub = db.get_node :Company, :name, "Trunkclub"
|
105
|
-
chicago = db.get_node :City, :name, "Chicago"
|
106
|
-
us = db.get_node :Country, :name, "United States"
|
107
|
-
|
108
|
-
javad.outgoing(:lives_in).should == [chicago]
|
109
|
-
ellen.outgoing(:lives_in).should == [chicago]
|
110
|
-
end
|
111
|
-
end
|
112
|
-
|
113
|
-
it "should not allow for get_relationships" do
|
114
|
-
tmpdir = quick_batch_neo4j do |db|
|
115
|
-
javad = db.get_node :Person, :name, "Javad"
|
116
|
-
ellen = db.get_node :Person, :name, "Ellen"
|
117
|
-
trunkclub = db.get_node :Company, :name, "Trunkclub"
|
118
|
-
chicago = db.get_node :City, :name, "Chicago"
|
119
|
-
us = db.get_node :Country, :name, "United States"
|
120
|
-
|
121
|
-
javad.outgoing(:lives_in) << chicago
|
122
|
-
chicago.outgoing(:country) << us
|
15
|
+
transaction do
|
16
|
+
javad = Person_by_name("Javad")
|
17
|
+
chicago = City_by_name("Chicago")
|
18
|
+
houston = City_by_name("Houston")
|
123
19
|
|
124
|
-
|
20
|
+
javad.lives_in_to chicago
|
21
|
+
javad.lives_in_to houston
|
22
|
+
end
|
125
23
|
end
|
126
|
-
end
|
127
24
|
|
128
|
-
|
129
|
-
db = Cadet::BatchInserter::Session.open(Dir.mktmpdir, {"use_memory_mapped_buffers" => "true"})
|
130
|
-
db.close
|
131
|
-
end
|
132
|
-
|
133
|
-
xit "should not allow for get_relationships" do
|
134
|
-
quick_batch_dsl_neo4j do
|
25
|
+
Cadet::Session.open(at) do
|
135
26
|
transaction do
|
136
|
-
Person_by_name("Javad").
|
137
|
-
|
138
|
-
Person_by_name("Javad").outgoing(:lives_in).should == [City_by_name("Chicago")]
|
27
|
+
Person_by_name("Javad").outgoing(:lives_in).should =~ [City_by_name("Houston"), City_by_name("Chicago")]
|
28
|
+
Person_by_name("Javad").outgoing(:lives_in).should =~ [City_by_name("Chicago"), City_by_name("Houston")]
|
139
29
|
end
|
140
30
|
end
|
141
31
|
end
|
142
|
-
|
143
|
-
|
144
32
|
end
|
data/spec/unit/cadet_spec.rb
CHANGED
@@ -1,45 +1,103 @@
|
|
1
1
|
require 'spec_helper'
|
2
|
+
require 'tmpdir'
|
2
3
|
|
3
4
|
describe Cadet do
|
4
5
|
|
5
|
-
it "should
|
6
|
-
|
7
|
-
|
8
|
-
|
6
|
+
it "should create an instance of cadet session, for test and normal sessions" do
|
7
|
+
Cadet::Session.open(Dir.mktmpdir).class.should == Cadet::Session
|
8
|
+
Cadet::Session.open.class.should == Cadet::Session #test session
|
9
|
+
end
|
10
|
+
|
11
|
+
it "should create an instance of cadet session, for test and normal sessions" do
|
12
|
+
Cadet::Session.open do |session|
|
13
|
+
self.should == session
|
14
|
+
self.class.should == Cadet::Session
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
it "should yield to transactions" do
|
19
|
+
has_block_ran = false
|
20
|
+
Cadet::Session.open do
|
21
|
+
transaction do
|
22
|
+
has_block_ran = true
|
23
|
+
end
|
24
|
+
end
|
25
|
+
has_block_ran.should == true
|
26
|
+
end
|
27
|
+
|
28
|
+
it "should return the same result between get_node and Label_by_prop" do
|
29
|
+
Cadet::Session.open do
|
30
|
+
transaction do
|
31
|
+
get_node(:Person, :name, "Javad").should == Person_by_name("Javad")
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
it "should set a node's label" do
|
37
|
+
Cadet::Session.open do
|
38
|
+
transaction do
|
39
|
+
javad = Person_by_name("Javad")
|
40
|
+
javad[:age] = 25
|
41
|
+
|
42
|
+
javad[:age].should == 25
|
43
|
+
end
|
9
44
|
end
|
10
45
|
end
|
11
46
|
|
12
47
|
it "should set a node's label" do
|
13
|
-
|
14
|
-
|
48
|
+
Cadet::Session.open do
|
49
|
+
transaction do
|
50
|
+
javad = Person_by_name("Javad")
|
15
51
|
javad.add_label :Member
|
52
|
+
|
16
53
|
javad.labels.should == ["Person", "Member"]
|
54
|
+
end
|
17
55
|
end
|
18
56
|
end
|
19
57
|
|
20
58
|
it "should add outgoing relationship's to a node" do
|
21
|
-
|
22
|
-
|
23
|
-
|
59
|
+
Cadet::Session.open do
|
60
|
+
transaction do
|
61
|
+
javad = Person_by_name("Javad")
|
62
|
+
ellen = Person_by_name("Ellen")
|
24
63
|
|
25
64
|
javad.outgoing(:knows) << ellen
|
26
65
|
|
27
66
|
javad.outgoing(:knows).should == [ellen]
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
it "should add outgoing relationship's to a node" do
|
72
|
+
Cadet::Session.open do
|
73
|
+
transaction do
|
74
|
+
javad = Person_by_name("Javad")
|
75
|
+
ellen = Person_by_name("Ellen")
|
76
|
+
|
77
|
+
javad.knows_to ellen
|
78
|
+
|
79
|
+
javad.outgoing(:knows).should == [ellen]
|
80
|
+
end
|
28
81
|
end
|
29
82
|
end
|
30
83
|
|
31
84
|
it "it should accept multiple relationships" do
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
85
|
+
Cadet::Session.open do
|
86
|
+
transaction do
|
87
|
+
javad = Person_by_name("Javad")
|
88
|
+
chicago = City_by_name("Chicago")
|
89
|
+
houston = City_by_name("Houston")
|
90
|
+
|
91
|
+
javad.lives_in_to chicago
|
92
|
+
javad.lives_in_to houston
|
93
|
+
javad.outgoing(:lives_in).should == [chicago, houston]
|
94
|
+
end
|
37
95
|
end
|
38
96
|
end
|
39
97
|
|
40
98
|
it "should allow for outgoing to be chained" do
|
41
|
-
|
42
|
-
|
99
|
+
Cadet::Session.open do
|
100
|
+
transaction do
|
43
101
|
javad = Person_by_name "Javad"
|
44
102
|
ellen = Person_by_name "Ellen"
|
45
103
|
trunkclub = Company_by_name "Trunkclub"
|
@@ -48,11 +106,11 @@ describe Cadet do
|
|
48
106
|
springfield = City_by_name "Springfield"
|
49
107
|
|
50
108
|
|
51
|
-
javad.
|
52
|
-
trunkclub.
|
53
|
-
javad.
|
54
|
-
ellen.
|
55
|
-
chicago.
|
109
|
+
javad.works_at_to trunkclub
|
110
|
+
trunkclub.located_in_to chicago
|
111
|
+
javad.lives_in_to chicago
|
112
|
+
ellen.lives_in_to chicago
|
113
|
+
chicago.country_to us
|
56
114
|
|
57
115
|
javad.outgoing(:works_at).outgoing(:located_in).outgoing(:country).should == [us]
|
58
116
|
chicago.incoming(:located_in).incoming(:works_at).should == [javad]
|
@@ -62,12 +120,12 @@ describe Cadet do
|
|
62
120
|
end
|
63
121
|
|
64
122
|
it "should allow for node relationship's to be accessed" do
|
65
|
-
|
66
|
-
|
123
|
+
Cadet::Session.open do
|
124
|
+
transaction do
|
67
125
|
javad = Person_by_name "Javad"
|
68
126
|
ellen = Person_by_name "Ellen"
|
69
|
-
javad.
|
70
|
-
|
127
|
+
javad.knows_to ellen
|
128
|
+
ellen.also_knows_to javad
|
71
129
|
|
72
130
|
javad.outgoing_rels(:knows).map{ |rel| rel.get_other_node(javad)}.should == [ellen]
|
73
131
|
javad.incoming_rels(:also_knows).map{ |rel| rel.get_other_node(javad)}.should == [ellen]
|
@@ -75,28 +133,92 @@ describe Cadet do
|
|
75
133
|
end
|
76
134
|
end
|
77
135
|
|
136
|
+
# when using an impermanent database, neo4j is writing to disk in this test (it shouldnt).
|
137
|
+
# so using a tmp dir instead
|
138
|
+
it "should enforce unique constraints" do
|
139
|
+
expect {
|
140
|
+
Cadet::Session.open(Dir.mktmpdir) do
|
141
|
+
transaction do
|
142
|
+
constraint :Person, :name
|
143
|
+
end
|
144
|
+
transaction do
|
145
|
+
create_node(:Person, {name: "Javad"})
|
146
|
+
create_node(:Person, {name: "Javad"})
|
147
|
+
end
|
148
|
+
end
|
149
|
+
}.to raise_error(org.neo4j.graphdb.ConstraintViolationException)
|
150
|
+
end
|
151
|
+
|
152
|
+
it "it should allow =~ to compare a set of nodes to a NodeRelationships, indifferent to order" do
|
153
|
+
Cadet::Session.open do
|
154
|
+
transaction do
|
155
|
+
javad = Person_by_name "Javad"
|
156
|
+
chicago = City_by_name "Chicago"
|
157
|
+
houston = City_by_name "Houston"
|
158
|
+
memphis = City_by_name "Memphis"
|
159
|
+
|
160
|
+
javad.lives_in_to chicago
|
161
|
+
javad.lives_in_to houston
|
162
|
+
|
163
|
+
javad.outgoing(:lives_in).send("=~", [houston, chicago]).should == true
|
164
|
+
javad.outgoing(:lives_in).send("=~", [chicago, houston]).should == true
|
165
|
+
javad.outgoing(:lives_in).send("=~", [chicago, houston, memphis]).should_not == true
|
166
|
+
|
167
|
+
javad.outgoing(:lives_in).should =~ [chicago, houston]
|
168
|
+
javad.outgoing(:lives_in).should =~ [houston, chicago]
|
169
|
+
javad.outgoing(:lives_in).should_not =~ [houston, chicago, memphis]
|
170
|
+
|
171
|
+
javad.outgoing(:lives_in).should == [chicago, houston]
|
172
|
+
javad.outgoing(:lives_in).should_not == [houston, chicago]
|
173
|
+
end
|
174
|
+
end
|
175
|
+
end
|
176
|
+
|
177
|
+
it "should return the relationship created when ..._to is called on a node" do
|
178
|
+
Cadet::Session.open do
|
179
|
+
transaction do
|
180
|
+
javad = Person_by_name "Javad"
|
181
|
+
houston = City_by_name "Houston"
|
182
|
+
|
183
|
+
rel = javad.home_city_to(houston)
|
184
|
+
|
185
|
+
rel.class.should == Cadet::Relationship
|
78
186
|
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
187
|
+
rel.start_node.should == javad
|
188
|
+
rel.end_node.should == houston
|
189
|
+
|
190
|
+
javad.outgoing(:home_city).should == [houston]
|
83
191
|
end
|
84
|
-
|
85
|
-
|
192
|
+
end
|
193
|
+
end
|
86
194
|
|
87
|
-
|
195
|
+
it "should allow chaining of relationship creation" do
|
196
|
+
Cadet::Session.open do
|
197
|
+
transaction do
|
198
|
+
javad = Person_by_name "Javad"
|
199
|
+
houston = City_by_name "Houston"
|
200
|
+
texas = State_by_name "Texas"
|
201
|
+
|
202
|
+
javad.home_city_to(houston).city_of_to(texas)
|
203
|
+
|
204
|
+
javad.outgoing(:home_city).should == [houston]
|
205
|
+
houston.outgoing(:city_of).should == [texas]
|
88
206
|
end
|
89
207
|
end
|
90
208
|
end
|
91
209
|
|
92
|
-
it
|
93
|
-
|
94
|
-
transaction do
|
95
|
-
Person_by_name
|
210
|
+
it "should return the relationship created when ..._to is called on a node" do
|
211
|
+
Cadet::Session.open do
|
212
|
+
transaction do
|
213
|
+
javad = Person_by_name "Javad"
|
214
|
+
houston = City_by_name "Houston"
|
96
215
|
|
97
|
-
|
216
|
+
rel = javad.home_city_to(houston)
|
217
|
+
rel[:birth_year] = 1988
|
218
|
+
rel[:birth_year].should == 1988
|
98
219
|
end
|
99
220
|
end
|
100
221
|
end
|
101
222
|
|
223
|
+
|
102
224
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: cadet
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 0.1.0
|
5
5
|
platform: java
|
6
6
|
authors:
|
7
7
|
- Javad Karabi
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-03-
|
11
|
+
date: 2014-03-12 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake
|
@@ -47,18 +47,17 @@ files:
|
|
47
47
|
- .gitignore
|
48
48
|
- .travis.yml
|
49
49
|
- Gemfile
|
50
|
-
- Gemfile.lock
|
51
50
|
- README.md
|
52
51
|
- Rakefile
|
53
52
|
- cadet.gemspec
|
53
|
+
- circle.yml
|
54
54
|
- lib/cadet.rb
|
55
|
+
- lib/cadet/batch_inserter/cadet_index/index.rb
|
56
|
+
- lib/cadet/batch_inserter/cadet_index/index_provider.rb
|
55
57
|
- lib/cadet/batch_inserter/node.rb
|
56
58
|
- lib/cadet/batch_inserter/session.rb
|
57
59
|
- lib/cadet/batch_inserter/transaction.rb
|
58
|
-
- lib/cadet/cadet_index/index.rb
|
59
|
-
- lib/cadet/cadet_index/index_provider.rb
|
60
60
|
- lib/cadet/direction.rb
|
61
|
-
- lib/cadet/dsl.rb
|
62
61
|
- lib/cadet/dynamic_label.rb
|
63
62
|
- lib/cadet/dynamic_relationshiptype.rb
|
64
63
|
- lib/cadet/helpers.rb
|
@@ -68,7 +67,6 @@ files:
|
|
68
67
|
- lib/cadet/path_traverser.rb
|
69
68
|
- lib/cadet/relationship.rb
|
70
69
|
- lib/cadet/session.rb
|
71
|
-
- lib/cadet/test/session.rb
|
72
70
|
- lib/cadet/transaction.rb
|
73
71
|
- lib/cadet/version.rb
|
74
72
|
- lib/neo4j/README.txt
|
data/Gemfile.lock
DELETED
@@ -1,26 +0,0 @@
|
|
1
|
-
PATH
|
2
|
-
remote: .
|
3
|
-
specs:
|
4
|
-
cadet (0.0.8-java)
|
5
|
-
|
6
|
-
GEM
|
7
|
-
remote: http://rubygems.org/
|
8
|
-
specs:
|
9
|
-
diff-lcs (1.2.5)
|
10
|
-
rake (10.1.1)
|
11
|
-
rspec (2.14.1)
|
12
|
-
rspec-core (~> 2.14.0)
|
13
|
-
rspec-expectations (~> 2.14.0)
|
14
|
-
rspec-mocks (~> 2.14.0)
|
15
|
-
rspec-core (2.14.7)
|
16
|
-
rspec-expectations (2.14.5)
|
17
|
-
diff-lcs (>= 1.1.3, < 2.0)
|
18
|
-
rspec-mocks (2.14.6)
|
19
|
-
|
20
|
-
PLATFORMS
|
21
|
-
java
|
22
|
-
|
23
|
-
DEPENDENCIES
|
24
|
-
cadet!
|
25
|
-
rake
|
26
|
-
rspec
|
@@ -1,33 +0,0 @@
|
|
1
|
-
module Cadet
|
2
|
-
module CadetIndex
|
3
|
-
class Index
|
4
|
-
def initialize(lucene_index, name, type)
|
5
|
-
@name = name
|
6
|
-
@type = type
|
7
|
-
@index = {}
|
8
|
-
@lucene_index = lucene_index
|
9
|
-
end
|
10
|
-
|
11
|
-
def add(node, property, value)
|
12
|
-
@index[property] ||= {}
|
13
|
-
@index[property][value] = node
|
14
|
-
end
|
15
|
-
|
16
|
-
def get(property, value)
|
17
|
-
@index[property] ||= {}
|
18
|
-
[@index[property][value]]
|
19
|
-
end
|
20
|
-
|
21
|
-
def flush
|
22
|
-
index = @lucene_index.nodeIndex(@name, @type)
|
23
|
-
|
24
|
-
@index.each do |property, mappings|
|
25
|
-
mappings.each do |value, node|
|
26
|
-
index.add(node, {property.to_java_string => value})
|
27
|
-
end
|
28
|
-
end
|
29
|
-
end
|
30
|
-
|
31
|
-
end
|
32
|
-
end
|
33
|
-
end
|
@@ -1,20 +0,0 @@
|
|
1
|
-
module Cadet
|
2
|
-
module CadetIndex
|
3
|
-
class IndexProvider
|
4
|
-
|
5
|
-
def initialize(db)
|
6
|
-
@db = db
|
7
|
-
@indexes = {}
|
8
|
-
@lucene_index = org.neo4j.index.impl.lucene.LuceneBatchInserterIndexProviderNewImpl.new(db)
|
9
|
-
end
|
10
|
-
def nodeIndex(name, type = {"type" => "exact"})
|
11
|
-
@indexes[name.to_sym] ||= CadetIndex::Index.new(@lucene_index, name.to_sym, type)
|
12
|
-
end
|
13
|
-
def shutdown
|
14
|
-
@indexes.each do |name, index|
|
15
|
-
index.flush
|
16
|
-
end
|
17
|
-
end
|
18
|
-
end
|
19
|
-
end
|
20
|
-
end
|
data/lib/cadet/dsl.rb
DELETED
@@ -1,28 +0,0 @@
|
|
1
|
-
module Cadet
|
2
|
-
class DSL
|
3
|
-
def initialize(db)
|
4
|
-
@db = db
|
5
|
-
end
|
6
|
-
|
7
|
-
def method_missing(name, *args, &block)
|
8
|
-
case name
|
9
|
-
when /^([A-z_]*)_by_([A-z_]*)$/
|
10
|
-
self.class.class_eval "
|
11
|
-
def #{name}(value)
|
12
|
-
@db.get_node :#{$1}, :#{$2}, value
|
13
|
-
end"
|
14
|
-
return self.send(name, *args, &block)
|
15
|
-
|
16
|
-
when /^create_([A-z_]*)$/
|
17
|
-
self.class.class_eval "
|
18
|
-
def #{name}(value, indexing_property = nil)
|
19
|
-
@db.create_node :#{$1}, value, indexing_property
|
20
|
-
end"
|
21
|
-
return self.send(name, *args, &block)
|
22
|
-
else
|
23
|
-
return @db.send(name, *args, &block)
|
24
|
-
end
|
25
|
-
end
|
26
|
-
|
27
|
-
end
|
28
|
-
end
|