neo4j-wrapper 0.0.1-java
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 +10 -0
- data/README.rdoc +64 -0
- data/lib/db/active_tx_log +1 -0
- data/lib/db/index/lucene/node/Person_exact/_0.fdt +0 -0
- data/lib/db/index/lucene/node/Person_exact/_0.fdx +0 -0
- data/lib/db/index/lucene/node/Person_exact/_0.fnm +1 -0
- data/lib/db/index/lucene/node/Person_exact/_0.frq +0 -0
- data/lib/db/index/lucene/node/Person_exact/_0.nrm +1 -0
- data/lib/db/index/lucene/node/Person_exact/_0.prx +0 -0
- data/lib/db/index/lucene/node/Person_exact/_0.tii +0 -0
- data/lib/db/index/lucene/node/Person_exact/_0.tis +0 -0
- data/lib/db/index/lucene/node/Person_exact/_1.fdt +0 -0
- data/lib/db/index/lucene/node/Person_exact/_1.fdx +0 -0
- data/lib/db/index/lucene/node/Person_exact/_1.fnm +1 -0
- data/lib/db/index/lucene/node/Person_exact/_1.frq +0 -0
- data/lib/db/index/lucene/node/Person_exact/_1.nrm +1 -0
- data/lib/db/index/lucene/node/Person_exact/_1.prx +0 -0
- data/lib/db/index/lucene/node/Person_exact/_1.tii +0 -0
- data/lib/db/index/lucene/node/Person_exact/_1.tis +0 -0
- data/lib/db/index/lucene/node/Person_exact/_2.fdt +0 -0
- data/lib/db/index/lucene/node/Person_exact/_2.fdx +0 -0
- data/lib/db/index/lucene/node/Person_exact/_2.fnm +1 -0
- data/lib/db/index/lucene/node/Person_exact/_2.frq +0 -0
- data/lib/db/index/lucene/node/Person_exact/_2.nrm +1 -0
- data/lib/db/index/lucene/node/Person_exact/_2.prx +0 -0
- data/lib/db/index/lucene/node/Person_exact/_2.tii +0 -0
- data/lib/db/index/lucene/node/Person_exact/_2.tis +0 -0
- data/lib/db/index/lucene/node/Person_exact/segments.gen +0 -0
- data/lib/db/index/lucene/node/Person_exact/segments_3 +0 -0
- data/lib/db/index/lucene-store.db +0 -0
- data/lib/db/index/lucene.log.active +0 -0
- data/lib/db/index.db +0 -0
- data/lib/db/messages.log +826 -0
- data/lib/db/neostore +0 -0
- data/lib/db/neostore.id +0 -0
- data/lib/db/neostore.nodestore.db +0 -0
- data/lib/db/neostore.nodestore.db.id +0 -0
- data/lib/db/neostore.propertystore.db +0 -0
- data/lib/db/neostore.propertystore.db.arrays +0 -0
- data/lib/db/neostore.propertystore.db.arrays.id +0 -0
- data/lib/db/neostore.propertystore.db.id +0 -0
- data/lib/db/neostore.propertystore.db.index +0 -0
- data/lib/db/neostore.propertystore.db.index.id +0 -0
- data/lib/db/neostore.propertystore.db.index.keys +0 -0
- data/lib/db/neostore.propertystore.db.index.keys.id +0 -0
- data/lib/db/neostore.propertystore.db.strings +0 -0
- data/lib/db/neostore.propertystore.db.strings.id +0 -0
- data/lib/db/neostore.relationshipstore.db +0 -0
- data/lib/db/neostore.relationshipstore.db.id +0 -0
- data/lib/db/neostore.relationshiptypestore.db +0 -0
- data/lib/db/neostore.relationshiptypestore.db.id +0 -0
- data/lib/db/neostore.relationshiptypestore.db.names +0 -0
- data/lib/db/neostore.relationshiptypestore.db.names.id +0 -0
- data/lib/db/nioneo_logical.log.active +0 -0
- data/lib/db/tm_tx_log.1 +0 -0
- data/lib/example.rb +34 -0
- data/lib/neo4j/identity_map.rb +109 -0
- data/lib/neo4j/node_mixin.rb +74 -0
- data/lib/neo4j/relationship_mixin.rb +62 -0
- data/lib/neo4j/type_converters/type_converters.rb +333 -0
- data/lib/neo4j-wrapper/class_methods.rb +27 -0
- data/lib/neo4j-wrapper/find.rb +65 -0
- data/lib/neo4j-wrapper/has_n/class_methods.rb +131 -0
- data/lib/neo4j-wrapper/has_n/decl_rel.rb +261 -0
- data/lib/neo4j-wrapper/has_n/instance_methods.rb +12 -0
- data/lib/neo4j-wrapper/has_n/nodes.rb +83 -0
- data/lib/neo4j-wrapper/node_mixin/class_methods.rb +53 -0
- data/lib/neo4j-wrapper/node_mixin/delegates.rb +140 -0
- data/lib/neo4j-wrapper/node_mixin/initialize.rb +43 -0
- data/lib/neo4j-wrapper/properties/class_methods.rb +150 -0
- data/lib/neo4j-wrapper/relationship_mixin/class_methods.rb +30 -0
- data/lib/neo4j-wrapper/relationship_mixin/delegates.rb +110 -0
- data/lib/neo4j-wrapper/relationship_mixin/initialize.rb +35 -0
- data/lib/neo4j-wrapper/rule/class_methods.rb +204 -0
- data/lib/neo4j-wrapper/rule/event_listener.rb +66 -0
- data/lib/neo4j-wrapper/rule/functions/count.rb +45 -0
- data/lib/neo4j-wrapper/rule/functions/function.rb +76 -0
- data/lib/neo4j-wrapper/rule/functions/sum.rb +31 -0
- data/lib/neo4j-wrapper/rule/instance_methods.rb +16 -0
- data/lib/neo4j-wrapper/rule/neo4j_core_ext/traverser.rb +29 -0
- data/lib/neo4j-wrapper/rule/rule.rb +134 -0
- data/lib/neo4j-wrapper/rule/rule_node.rb +205 -0
- data/lib/neo4j-wrapper/version.rb +5 -0
- data/lib/neo4j-wrapper/wrapper.rb +38 -0
- data/lib/neo4j-wrapper.rb +35 -0
- data/lib/test.rb +61 -0
- data/neo4j-wrapper.gemspec +31 -0
- metadata +162 -0
data/lib/db/neostore
ADDED
|
Binary file
|
data/lib/db/neostore.id
ADDED
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
data/lib/db/tm_tx_log.1
ADDED
|
Binary file
|
data/lib/example.rb
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
require 'rubygems'
|
|
2
|
+
require 'neo4j-wrapper'
|
|
3
|
+
|
|
4
|
+
class Company
|
|
5
|
+
include Neo4j::NodeMixin
|
|
6
|
+
has_n(:employees)
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
class Person
|
|
10
|
+
include Neo4j::NodeMixin
|
|
11
|
+
property :name
|
|
12
|
+
property :age, :size, :type => Fixnum, :index => :exact
|
|
13
|
+
property :description, :index => :fulltext
|
|
14
|
+
|
|
15
|
+
has_one(:best_friend)
|
|
16
|
+
has_n(:employed_by).from(:employees)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
Neo4j::Transaction.run do
|
|
20
|
+
Person.new(:name => 'jimmy', :age => 35)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
person = Person.find(:age => (10..42)).first
|
|
24
|
+
|
|
25
|
+
Neo4j::Transaction.run do
|
|
26
|
+
person.best_friend = Person.new
|
|
27
|
+
person.employed_by << Company.new(:name => "Foo ab")
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
company = person.employed_by.find { |p| p[:name] == 'Foo ab' }
|
|
31
|
+
puts "Person #{person.name} employed by #{company[:name]}"
|
|
32
|
+
|
|
33
|
+
company.employees.each {|x| puts x.name}
|
|
34
|
+
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
module Neo4j
|
|
2
|
+
|
|
3
|
+
# = Neo4j Identity Map
|
|
4
|
+
#
|
|
5
|
+
# Ensures that each object gets loaded only once by keeping every loaded
|
|
6
|
+
# object in a map. Looks up objects using the map when referring to them.
|
|
7
|
+
#
|
|
8
|
+
# More information on Identity Map pattern:
|
|
9
|
+
# http://www.martinfowler.com/eaaCatalog/identityMap.html
|
|
10
|
+
#
|
|
11
|
+
# == Configuration
|
|
12
|
+
#
|
|
13
|
+
# In order to enable IdentityMap, set <tt>config.neo4j.identity_map = true</tt>
|
|
14
|
+
# in your <tt>config/application.rb</tt> file. If used outside rails, set Neo4j::Config[:identity_map] = true.
|
|
15
|
+
#
|
|
16
|
+
# IdentityMap is disabled by default and still in development (i.e. use it with care).
|
|
17
|
+
#
|
|
18
|
+
module IdentityMap
|
|
19
|
+
|
|
20
|
+
class << self
|
|
21
|
+
def enabled=(flag)
|
|
22
|
+
Thread.current[:neo4j_identity_map] = flag
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def enabled
|
|
26
|
+
Thread.current[:neo4j_identity_map] == true
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
alias enabled? enabled
|
|
30
|
+
|
|
31
|
+
def node_repository
|
|
32
|
+
Thread.current[:node_identity_map] ||= java.util.HashMap.new
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def rel_repository
|
|
36
|
+
Thread.current[:rel_identity_map] ||= java.util.HashMap.new
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def repository_for(neo_entity)
|
|
40
|
+
return nil unless enabled?
|
|
41
|
+
if neo_entity.class == Neo4j::Node
|
|
42
|
+
node_repository
|
|
43
|
+
elsif neo_entity.class == Neo4j::Relationship
|
|
44
|
+
rel_repository
|
|
45
|
+
else
|
|
46
|
+
nil
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def use
|
|
51
|
+
old, self.enabled = enabled, true
|
|
52
|
+
yield if block_given?
|
|
53
|
+
ensure
|
|
54
|
+
self.enabled = old
|
|
55
|
+
clear
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def without
|
|
59
|
+
old, self.enabled = enabled, false
|
|
60
|
+
yield if block_given?
|
|
61
|
+
ensure
|
|
62
|
+
self.enabled = old
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def get(neo_entity)
|
|
66
|
+
r = repository_for(neo_entity)
|
|
67
|
+
r && r.get(neo_entity.neo_id)
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
def add(neo_entity, wrapped_entity)
|
|
71
|
+
r = repository_for(neo_entity)
|
|
72
|
+
r && r.put(neo_entity.neo_id, wrapped_entity)
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
def remove(neo_entity)
|
|
76
|
+
r = repository_for(neo_entity)
|
|
77
|
+
r && r.remove(neo_entity.neo_id)
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
def remove_node_by_id(node_id)
|
|
81
|
+
node_repository.remove(node_id)
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
def remove_rel_by_id(rel_id)
|
|
85
|
+
rel_repository.remove(rel_id)
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
def clear
|
|
89
|
+
node_repository.clear
|
|
90
|
+
rel_repository.clear
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
def on_after_commit(*)
|
|
94
|
+
clear
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
def on_neo4j_started(db)
|
|
98
|
+
if !Neo4j::Config[:identity_map] && !enabled
|
|
99
|
+
db.event_handler.remove(self)
|
|
100
|
+
end
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
end
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
Neo4j.unstarted_db.event_handler.add(Neo4j::IdentityMap)
|
|
109
|
+
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
module Neo4j
|
|
2
|
+
|
|
3
|
+
# This mixin is used to wrap Neo4j Java Nodes in Ruby objects.
|
|
4
|
+
#
|
|
5
|
+
# @example Declare and Use a Lucene Index
|
|
6
|
+
#
|
|
7
|
+
# class Contact
|
|
8
|
+
# include Neo4j::NodeMixin
|
|
9
|
+
# property :phone, :index => :exact
|
|
10
|
+
# end
|
|
11
|
+
#
|
|
12
|
+
# # Find an contact with a phone number
|
|
13
|
+
# Contact.find('phone: 12345').first #=> a phone object !
|
|
14
|
+
#
|
|
15
|
+
#
|
|
16
|
+
# = Class Method Modules
|
|
17
|
+
# * {Neo4j::Wrapper::ClassMethods}
|
|
18
|
+
# * {Neo4j::Wrapper::NodeMixin::ClassMethods}
|
|
19
|
+
# * {Neo4j::Wrapper::Property::ClassMethods}
|
|
20
|
+
# * {Neo4j::Wrapper::HasN::ClassMethods}
|
|
21
|
+
# * {Neo4j::Wrapper::Find}
|
|
22
|
+
# * {Neo4j::Wrapper::Rule::ClassMethods}
|
|
23
|
+
# * {http://rdoc.info/github/andreasronge/neo4j-core/master/Neo4j/Core/Index/ClassMethods Neo4j::Core::Index::ClassMethods}
|
|
24
|
+
#
|
|
25
|
+
# = Instance Method Modules
|
|
26
|
+
# * {http://rdoc.info/github/andreasronge/neo4j-core/master/Neo4j/Core/Index Neo4j::Core::Index}
|
|
27
|
+
module NodeMixin
|
|
28
|
+
include Neo4j::Wrapper::NodeMixin::Delegates
|
|
29
|
+
include Neo4j::Wrapper::NodeMixin::Initialize
|
|
30
|
+
include Neo4j::Wrapper::HasN::InstanceMethods
|
|
31
|
+
include Neo4j::Wrapper::Rule::InstanceMethods
|
|
32
|
+
include Neo4j::Core::Index
|
|
33
|
+
|
|
34
|
+
# @private
|
|
35
|
+
def self.included(klass)
|
|
36
|
+
klass.extend Neo4j::Wrapper::ClassMethods
|
|
37
|
+
klass.extend Neo4j::Wrapper::NodeMixin::ClassMethods
|
|
38
|
+
klass.extend Neo4j::Wrapper::Property::ClassMethods
|
|
39
|
+
klass.extend Neo4j::Wrapper::HasN::ClassMethods
|
|
40
|
+
klass.extend Neo4j::Core::Index::ClassMethods
|
|
41
|
+
klass.extend Neo4j::Wrapper::Find
|
|
42
|
+
klass.extend Neo4j::Wrapper::Rule::ClassMethods
|
|
43
|
+
|
|
44
|
+
klass.send(:include, Neo4j::Wrapper::Rule::Functions)
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
klass.node_indexer do
|
|
48
|
+
index_names :exact => "#{klass._index_name}_exact", :fulltext => "#{klass._index_name}_fulltext"
|
|
49
|
+
trigger_on :_classname => klass.to_s
|
|
50
|
+
prefix_index_name &klass.method(:index_prefix)
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def klass.inherited(sub_klass)
|
|
54
|
+
return super if sub_klass.to_s == self.to_s
|
|
55
|
+
base_class = self
|
|
56
|
+
|
|
57
|
+
# make the base class trigger on the sub class nodes
|
|
58
|
+
base_class._indexer.config.trigger_on :_classname => sub_klass.to_s
|
|
59
|
+
|
|
60
|
+
sub_klass.inherit_rules_from self
|
|
61
|
+
|
|
62
|
+
sub_klass.node_indexer do
|
|
63
|
+
inherit_from base_class
|
|
64
|
+
index_names :exact => "#{sub_klass._index_name}_exact", :fulltext => "#{sub_klass._index_name}_fulltext"
|
|
65
|
+
trigger_on :_classname => sub_klass.to_s
|
|
66
|
+
prefix_index_name &sub_klass.method(:index_prefix)
|
|
67
|
+
end
|
|
68
|
+
super
|
|
69
|
+
end
|
|
70
|
+
super
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
end
|
|
74
|
+
end
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
module Neo4j
|
|
2
|
+
# Use this mixin to wrap Neo4j Relationship Java object.
|
|
3
|
+
# This mixin is similar to Neo4j::NodeMixin which wraps Neo4j::Node Java objects.
|
|
4
|
+
#
|
|
5
|
+
# @example
|
|
6
|
+
# class Friend
|
|
7
|
+
# include Neo4j::RelationshipMixin
|
|
8
|
+
# property :since, :type => Fixnum, :index => :exact
|
|
9
|
+
# property :strength, :type => Float
|
|
10
|
+
# property :location
|
|
11
|
+
# end
|
|
12
|
+
#
|
|
13
|
+
# Friend.new(:knows, node_a, node_b, :strength => 3.14)
|
|
14
|
+
# Friend.find(:strength => (2..5)).first
|
|
15
|
+
#
|
|
16
|
+
# = Class Method Modules
|
|
17
|
+
# * {Neo4j::Wrapper::RelationshipMixin::ClassMethods}
|
|
18
|
+
# * {Neo4j::Wrapper::Property::ClassMethods}
|
|
19
|
+
# * {Neo4j::Core::Index::ClassMethods}
|
|
20
|
+
# * {Neo4j::Wrapper::Find}
|
|
21
|
+
module RelationshipMixin
|
|
22
|
+
|
|
23
|
+
include Neo4j::Wrapper::RelationshipMixin::Initialize
|
|
24
|
+
include Neo4j::Wrapper::RelationshipMixin::Delegates
|
|
25
|
+
|
|
26
|
+
# @private
|
|
27
|
+
def self.included(klass)
|
|
28
|
+
klass.extend Neo4j::Wrapper::ClassMethods
|
|
29
|
+
klass.extend Neo4j::Wrapper::RelationshipMixin::ClassMethods
|
|
30
|
+
klass.extend Neo4j::Wrapper::Property::ClassMethods
|
|
31
|
+
klass.extend Neo4j::Core::Index::ClassMethods
|
|
32
|
+
klass.extend Neo4j::Wrapper::Find
|
|
33
|
+
|
|
34
|
+
index_name = klass.to_s.gsub("::", '_')
|
|
35
|
+
|
|
36
|
+
klass.rel_indexer do
|
|
37
|
+
index_names :exact => "#{index_name}_exact", :fulltext => "#{index_name}_fulltext"
|
|
38
|
+
trigger_on :_classname => klass.to_s
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def klass.inherited(sub_klass)
|
|
42
|
+
return super if sub_klass.to_s == self.to_s
|
|
43
|
+
index_name = sub_klass.to_s.gsub("::", '_')
|
|
44
|
+
base_class = self
|
|
45
|
+
|
|
46
|
+
# make the base class trigger on the sub class nodes
|
|
47
|
+
base_class._indexer.config.trigger_on :_classname => sub_klass.to_s
|
|
48
|
+
|
|
49
|
+
sub_klass.rel_indexer do
|
|
50
|
+
inherit_from base_class
|
|
51
|
+
index_names :exact => "#{index_name}_exact", :fulltext => "#{index_name}_fulltext"
|
|
52
|
+
trigger_on :_classname => sub_klass.to_s
|
|
53
|
+
end
|
|
54
|
+
super
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
super
|
|
58
|
+
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
end
|
|
62
|
+
end
|
|
@@ -0,0 +1,333 @@
|
|
|
1
|
+
module Neo4j
|
|
2
|
+
|
|
3
|
+
# Responsible for converting values from and to Java Neo4j and Lucene.
|
|
4
|
+
# You can implement your own converter by implementing the method <tt>convert?</tt>, <tt>index_as</tt>
|
|
5
|
+
# <tt>to_java</tt> and <tt>to_ruby</tt> in this module.
|
|
6
|
+
#
|
|
7
|
+
# There are currently three default converters that are triggered when a Time, Date or a DateTime is read or written
|
|
8
|
+
# if there is a type declared for the property.
|
|
9
|
+
#
|
|
10
|
+
# @example writing your own marshalling converter:
|
|
11
|
+
#
|
|
12
|
+
# class Foo
|
|
13
|
+
# include Neo4j::NodeMixin
|
|
14
|
+
# property :thing, :type => MyType
|
|
15
|
+
# end
|
|
16
|
+
#
|
|
17
|
+
# module Neo4j::TypeConverters
|
|
18
|
+
# class MyTypeConverter
|
|
19
|
+
# class << self
|
|
20
|
+
# def convert?(type)
|
|
21
|
+
# type == MyType
|
|
22
|
+
# end
|
|
23
|
+
#
|
|
24
|
+
# def to_java(val)
|
|
25
|
+
# "silly:#{val}"
|
|
26
|
+
# end
|
|
27
|
+
#
|
|
28
|
+
# def to_ruby(val)
|
|
29
|
+
# val.sub(/silly:/, '')
|
|
30
|
+
# end
|
|
31
|
+
#
|
|
32
|
+
# def index_as
|
|
33
|
+
# String
|
|
34
|
+
# end
|
|
35
|
+
# end
|
|
36
|
+
# end
|
|
37
|
+
# end
|
|
38
|
+
#
|
|
39
|
+
module TypeConverters
|
|
40
|
+
|
|
41
|
+
# The default converter to use if there isn't a specific converter for the type
|
|
42
|
+
class DefaultConverter
|
|
43
|
+
class << self
|
|
44
|
+
|
|
45
|
+
def to_java(value)
|
|
46
|
+
value
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def to_ruby(value)
|
|
50
|
+
value
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def index_as
|
|
54
|
+
String
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
class BooleanConverter
|
|
61
|
+
class << self
|
|
62
|
+
|
|
63
|
+
def convert?(class_or_symbol)
|
|
64
|
+
:boolean == class_or_symbol
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def to_java(value)
|
|
68
|
+
return nil if value.nil?
|
|
69
|
+
!!value && value != '0'
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def to_ruby(value)
|
|
73
|
+
return nil if value.nil?
|
|
74
|
+
!!value && value != '0'
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
def index_as
|
|
78
|
+
String
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
class SymbolConverter
|
|
85
|
+
class << self
|
|
86
|
+
|
|
87
|
+
def convert?(class_or_symbol)
|
|
88
|
+
:symbol == class_or_symbol || Symbol == class_or_symbol
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
def to_java(value)
|
|
92
|
+
return nil if value.nil?
|
|
93
|
+
value.to_s
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
def to_ruby(value)
|
|
97
|
+
return nil if value.nil?
|
|
98
|
+
value.to_sym
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
def index_as
|
|
102
|
+
String
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
end
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
class StringConverter
|
|
110
|
+
class << self
|
|
111
|
+
|
|
112
|
+
def convert?(class_or_symbol)
|
|
113
|
+
[String, :string, :text].include? class_or_symbol
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
def to_java(value)
|
|
117
|
+
return nil if value.nil?
|
|
118
|
+
value.to_s
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
def to_ruby(value)
|
|
122
|
+
return nil if value.nil?
|
|
123
|
+
value.to_s
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
def index_as
|
|
127
|
+
String
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
end
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
|
|
134
|
+
|
|
135
|
+
class FixnumConverter
|
|
136
|
+
class << self
|
|
137
|
+
|
|
138
|
+
def convert?(class_or_symbol)
|
|
139
|
+
Fixnum == class_or_symbol || :fixnum == class_or_symbol || :numeric == class_or_symbol
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
def to_java(value)
|
|
143
|
+
return nil if value.nil?
|
|
144
|
+
value.to_i
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
def to_ruby(value)
|
|
148
|
+
return nil if value.nil?
|
|
149
|
+
value.to_i
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
def index_as
|
|
153
|
+
Fixnum
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
end
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
class FloatConverter
|
|
160
|
+
class << self
|
|
161
|
+
|
|
162
|
+
def convert?(clazz_or_symbol)
|
|
163
|
+
Float == clazz_or_symbol || :float == clazz_or_symbol
|
|
164
|
+
end
|
|
165
|
+
|
|
166
|
+
def to_java(value)
|
|
167
|
+
return nil if value.nil?
|
|
168
|
+
value.to_f
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
def to_ruby(value)
|
|
172
|
+
return nil if value.nil?
|
|
173
|
+
value.to_f
|
|
174
|
+
end
|
|
175
|
+
|
|
176
|
+
def index_as
|
|
177
|
+
Float
|
|
178
|
+
end
|
|
179
|
+
|
|
180
|
+
end
|
|
181
|
+
end
|
|
182
|
+
|
|
183
|
+
# Converts Date objects to Java long types. Must be timezone UTC.
|
|
184
|
+
class DateConverter
|
|
185
|
+
class << self
|
|
186
|
+
|
|
187
|
+
def convert?(clazz_or_symbol)
|
|
188
|
+
Date == clazz_or_symbol || :date == clazz_or_symbol
|
|
189
|
+
end
|
|
190
|
+
|
|
191
|
+
def to_java(value)
|
|
192
|
+
return nil if value.nil?
|
|
193
|
+
Time.utc(value.year, value.month, value.day).to_i
|
|
194
|
+
end
|
|
195
|
+
|
|
196
|
+
def to_ruby(value)
|
|
197
|
+
return nil if value.nil?
|
|
198
|
+
Time.at(value).utc.to_date
|
|
199
|
+
end
|
|
200
|
+
|
|
201
|
+
def index_as
|
|
202
|
+
Fixnum
|
|
203
|
+
end
|
|
204
|
+
|
|
205
|
+
end
|
|
206
|
+
end
|
|
207
|
+
|
|
208
|
+
# Converts DateTime objects to and from Java long types. Must be timezone UTC.
|
|
209
|
+
class DateTimeConverter
|
|
210
|
+
class << self
|
|
211
|
+
|
|
212
|
+
def convert?(clazz_or_symbol)
|
|
213
|
+
DateTime == clazz_or_symbol || :datetime == clazz_or_symbol
|
|
214
|
+
end
|
|
215
|
+
|
|
216
|
+
# Converts the given DateTime (UTC) value to an Fixnum.
|
|
217
|
+
# Only utc times are supported !
|
|
218
|
+
def to_java(value)
|
|
219
|
+
return nil if value.nil?
|
|
220
|
+
if value.class == Date
|
|
221
|
+
Time.utc(value.year, value.month, value.day, 0, 0, 0).to_i
|
|
222
|
+
else
|
|
223
|
+
Time.utc(value.year, value.month, value.day, value.hour, value.min, value.sec).to_i
|
|
224
|
+
end
|
|
225
|
+
end
|
|
226
|
+
|
|
227
|
+
def to_ruby(value)
|
|
228
|
+
return nil if value.nil?
|
|
229
|
+
t = Time.at(value).utc
|
|
230
|
+
DateTime.civil(t.year, t.month, t.day, t.hour, t.min, t.sec)
|
|
231
|
+
end
|
|
232
|
+
|
|
233
|
+
def index_as
|
|
234
|
+
Fixnum
|
|
235
|
+
end
|
|
236
|
+
|
|
237
|
+
end
|
|
238
|
+
end
|
|
239
|
+
|
|
240
|
+
class TimeConverter
|
|
241
|
+
class << self
|
|
242
|
+
|
|
243
|
+
def convert?(clazz_or_symbol)
|
|
244
|
+
Time == clazz_or_symbol || :time == clazz_or_symbol
|
|
245
|
+
end
|
|
246
|
+
|
|
247
|
+
# Converts the given DateTime (UTC) value to an Fixnum.
|
|
248
|
+
# Only utc times are supported !
|
|
249
|
+
def to_java(value)
|
|
250
|
+
return nil if value.nil?
|
|
251
|
+
if value.class == Date
|
|
252
|
+
Time.utc(value.year, value.month, value.day, 0, 0, 0).to_i
|
|
253
|
+
else
|
|
254
|
+
value.utc.to_i
|
|
255
|
+
end
|
|
256
|
+
end
|
|
257
|
+
|
|
258
|
+
def to_ruby(value)
|
|
259
|
+
return nil if value.nil?
|
|
260
|
+
Time.at(value).utc
|
|
261
|
+
end
|
|
262
|
+
|
|
263
|
+
def index_as
|
|
264
|
+
Fixnum
|
|
265
|
+
end
|
|
266
|
+
|
|
267
|
+
end
|
|
268
|
+
end
|
|
269
|
+
|
|
270
|
+
class << self
|
|
271
|
+
|
|
272
|
+
# Mostly for testing purpose, You can use this method in order to
|
|
273
|
+
# add a converter while the neo4j has already started.
|
|
274
|
+
def converters=(converters)
|
|
275
|
+
@converters = converters
|
|
276
|
+
end
|
|
277
|
+
|
|
278
|
+
# Always returns a converter that handles to_ruby or to_java
|
|
279
|
+
# if +enforce_type+ is set to false then it will raise in case of unknown type
|
|
280
|
+
# otherwise it will return the DefaultConverter.
|
|
281
|
+
def converter(type = nil, enforce_type = true)
|
|
282
|
+
return DefaultConverter unless type
|
|
283
|
+
@converters ||= begin
|
|
284
|
+
Neo4j::TypeConverters.constants.find_all do |c|
|
|
285
|
+
Neo4j::TypeConverters.const_get(c).respond_to?(:convert?)
|
|
286
|
+
end.map do |c|
|
|
287
|
+
Neo4j::TypeConverters.const_get(c)
|
|
288
|
+
end
|
|
289
|
+
end
|
|
290
|
+
found = @converters.find {|c| c.convert?(type) }
|
|
291
|
+
raise "The type #{type.inspect} is unknown. Use one of #{@converters.map{|c| c.name }.join(", ")} or create a custom type converter." if !found && enforce_type
|
|
292
|
+
found or DefaultConverter
|
|
293
|
+
end
|
|
294
|
+
|
|
295
|
+
# Converts the given value to a Java type by using the registered converters.
|
|
296
|
+
# It just looks at the class of the given value unless an attribute name is given.
|
|
297
|
+
def convert(value, attribute = nil, klass = nil, enforce_type = true)
|
|
298
|
+
converter(attribute_type(value, attribute, klass), enforce_type).to_java(value)
|
|
299
|
+
end
|
|
300
|
+
|
|
301
|
+
# Converts the given property (key, value) to Java if there is a type converter for given type.
|
|
302
|
+
# The type must also be declared using Neo4j::NodeMixin#property property_name, :type => clazz
|
|
303
|
+
# If no Converter is defined for this value then it simply returns the given value.
|
|
304
|
+
def to_java(clazz, key, value)
|
|
305
|
+
type = clazz._decl_props[key.to_sym] && clazz._decl_props[key.to_sym][:type]
|
|
306
|
+
converter(type).to_java(value)
|
|
307
|
+
end
|
|
308
|
+
|
|
309
|
+
# Converts the given property (key, value) to Ruby if there is a type converter for given type.
|
|
310
|
+
# If no Converter is defined for this value then it simply returns the given value.
|
|
311
|
+
def to_ruby(clazz, key, value)
|
|
312
|
+
type = clazz._decl_props[key.to_sym] && clazz._decl_props[key.to_sym][:type]
|
|
313
|
+
converter(type).to_ruby(value)
|
|
314
|
+
end
|
|
315
|
+
|
|
316
|
+
private
|
|
317
|
+
def attribute_type(value, attribute = nil, klass = nil)
|
|
318
|
+
type = (attribute && klass) ? attribute_type_from_attribute_and_klass(value, attribute, klass) : nil
|
|
319
|
+
type || attribute_type_from_value(value)
|
|
320
|
+
end
|
|
321
|
+
|
|
322
|
+
def attribute_type_from_attribute_and_klass(value, attribute, klass)
|
|
323
|
+
if klass.respond_to?(:_decl_props)
|
|
324
|
+
(klass._decl_props.has_key?(attribute) && klass._decl_props[attribute][:type]) ? klass._decl_props[attribute][:type] : nil
|
|
325
|
+
end
|
|
326
|
+
end
|
|
327
|
+
|
|
328
|
+
def attribute_type_from_value(value)
|
|
329
|
+
value.class
|
|
330
|
+
end
|
|
331
|
+
end
|
|
332
|
+
end
|
|
333
|
+
end
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
module Neo4j
|
|
2
|
+
# Responsible for loading the correct Ruby wrapper class for the Neo4j Entity
|
|
3
|
+
module Wrapper
|
|
4
|
+
module ClassMethods
|
|
5
|
+
# Loads the wrapper by using the original new method and initialize it
|
|
6
|
+
# @private
|
|
7
|
+
def _load_wrapper(node)
|
|
8
|
+
wrapped_node = self.orig_new
|
|
9
|
+
wrapped_node.init_on_load(node)
|
|
10
|
+
wrapped_node
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
# Creates an alias to the original new method: <tt>orig_new</t>
|
|
14
|
+
# @private
|
|
15
|
+
def self.extended(klass)
|
|
16
|
+
klass.instance_eval do
|
|
17
|
+
class << self
|
|
18
|
+
alias_method :orig_new, :new
|
|
19
|
+
end
|
|
20
|
+
end unless klass.respond_to?(:orig_new)
|
|
21
|
+
super
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
|