neo4j-core 2.0.0.alpha.1-java → 2.0.0-java
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile +2 -2
- data/README.rdoc +161 -13
- data/config/neo4j/config.yml +1 -1
- data/lib/db/active_tx_log +1 -0
- data/lib/db/index/lucene-store.db +0 -0
- data/lib/db/index/lucene.log.active +0 -0
- data/lib/db/messages.log +2299 -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/neo4j-core.rb +20 -3
- data/lib/neo4j-core/cypher/cypher.rb +1033 -0
- data/lib/neo4j-core/cypher/result_wrapper.rb +48 -0
- data/lib/neo4j-core/database.rb +4 -5
- data/lib/neo4j-core/event_handler.rb +1 -1
- data/lib/neo4j-core/hash_with_indifferent_access.rb +165 -0
- data/lib/neo4j-core/index/class_methods.rb +27 -41
- data/lib/neo4j-core/index/index.rb +3 -4
- data/lib/neo4j-core/index/index_config.rb +30 -23
- data/lib/neo4j-core/index/indexer.rb +65 -53
- data/lib/neo4j-core/index/indexer_registry.rb +2 -2
- data/lib/neo4j-core/index/lucene_query.rb +53 -42
- data/lib/neo4j-core/index/unique_factory.rb +54 -0
- data/lib/neo4j-core/node/class_methods.rb +4 -4
- data/lib/neo4j-core/node/node.rb +1 -8
- data/lib/neo4j-core/property/java.rb +59 -0
- data/lib/neo4j-core/property/property.rb +1 -3
- data/lib/neo4j-core/relationship/relationship.rb +8 -10
- data/lib/neo4j-core/rels/rels.rb +9 -4
- data/lib/neo4j-core/rels/traverser.rb +13 -27
- data/lib/neo4j-core/traversal/prune_evaluator.rb +2 -2
- data/lib/neo4j-core/traversal/traverser.rb +122 -27
- data/lib/neo4j-core/version.rb +1 -1
- data/lib/neo4j-core/wrapper/class_methods.rb +22 -0
- data/lib/neo4j-core/wrapper/wrapper.rb +20 -0
- data/lib/neo4j/algo.rb +300 -0
- data/lib/neo4j/config.rb +3 -6
- data/lib/neo4j/cypher.rb +180 -0
- data/lib/neo4j/neo4j.rb +51 -23
- data/lib/neo4j/node.rb +27 -0
- data/lib/neo4j/relationship.rb +25 -0
- data/lib/test.rb~ +27 -0
- data/neo4j-core.gemspec +2 -2
- metadata +44 -11
- data/lib/neo4j-core/type_converters/type_converters.rb +0 -287
- data/lib/neo4j-core/version.rb~ +0 -3
- data/lib/test.rb +0 -27
@@ -0,0 +1,48 @@
|
|
1
|
+
module Neo4j
|
2
|
+
module Core
|
3
|
+
module Cypher
|
4
|
+
# Wraps the Cypher query result.
|
5
|
+
# Loads the node and relationships wrapper if possible and use symbol as column keys.
|
6
|
+
# @notice The result is a once forward read only Enumerable, work if you need to read the result twice - use #to_a
|
7
|
+
#
|
8
|
+
# @example
|
9
|
+
# result = Neo4j.query(@a, @b){|a,b| node(a,b).as(:n)}
|
10
|
+
# r = @query_result.to_a # can only loop once
|
11
|
+
# r.size.should == 2
|
12
|
+
# r.first.should include(:n)
|
13
|
+
# r[0][:n].neo_id.should == @a.neo_id
|
14
|
+
# r[1][:n].neo_id.should == @b.neo_id
|
15
|
+
class ResultWrapper
|
16
|
+
include Enumerable
|
17
|
+
|
18
|
+
# @return the original result from the Neo4j Cypher Engine, once forward read only !
|
19
|
+
attr_reader :source
|
20
|
+
|
21
|
+
def initialize(source)
|
22
|
+
@source = source
|
23
|
+
end
|
24
|
+
|
25
|
+
# @return [Array<Symbol>] the columns in the query result
|
26
|
+
def columns
|
27
|
+
@source.columns.map{|x| x.to_sym}
|
28
|
+
end
|
29
|
+
|
30
|
+
# for the Enumerable contract
|
31
|
+
def each
|
32
|
+
@source.each { |row| yield map(row) }
|
33
|
+
end
|
34
|
+
|
35
|
+
# Maps each row so that we can use symbols for column names.
|
36
|
+
# @private
|
37
|
+
def map(row)
|
38
|
+
out = {} # move to a real hash!
|
39
|
+
row.each do |key, value|
|
40
|
+
out[key.to_sym] = value.respond_to?(:wrapper) ? value.wrapper : value
|
41
|
+
end
|
42
|
+
out
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
data/lib/neo4j-core/database.rb
CHANGED
@@ -53,10 +53,10 @@ module Neo4j
|
|
53
53
|
start_readonly_graph_db
|
54
54
|
elsif Neo4j::Config['ha.db']
|
55
55
|
start_ha_graph_db
|
56
|
-
Neo4j.migrate!
|
56
|
+
Neo4j.migrate! if Neo4j.respond_to?(:migrate!)
|
57
57
|
else
|
58
58
|
start_local_graph_db
|
59
|
-
Neo4j.migrate!
|
59
|
+
Neo4j.migrate! if Neo4j.respond_to?(:migrate!)
|
60
60
|
end
|
61
61
|
rescue
|
62
62
|
@running = false
|
@@ -67,7 +67,8 @@ module Neo4j
|
|
67
67
|
end
|
68
68
|
|
69
69
|
|
70
|
-
|
70
|
+
# true if the database has started
|
71
|
+
def running?
|
71
72
|
@running
|
72
73
|
end
|
73
74
|
|
@@ -163,8 +164,6 @@ module Neo4j
|
|
163
164
|
Neo4j.logger.info "starting Neo4j in HA mode, machine id: #{Neo4j.config['ha.server_id']} at #{Neo4j.config['ha.server']} db #{@storage_path}"
|
164
165
|
# Modify the public base classes for the HA Node and Relationships
|
165
166
|
# (instead of private Java::OrgNeo4jKernel::HighlyAvailableGraphDatabase::LookupNode)
|
166
|
-
Neo4j::Node.extend_java_class(Java::OrgNeo4jToolingWrap::WrappedNode)
|
167
|
-
Neo4j::Relationship.extend_java_class(Java::OrgNeo4jToolingWrap::WrappedRelationship)
|
168
167
|
@graph = Java::OrgNeo4jKernel::HighlyAvailableGraphDatabase.new(@storage_path, Neo4j.config.to_java_map)
|
169
168
|
@graph.register_transaction_event_handler(@event_handler)
|
170
169
|
@lucene = @graph.index
|
@@ -88,7 +88,7 @@ module Neo4j
|
|
88
88
|
# You only need to implement the methods that you need.
|
89
89
|
#
|
90
90
|
class EventHandler
|
91
|
-
include
|
91
|
+
include Java::OrgNeo4jGraphdbEvent::TransactionEventHandler
|
92
92
|
|
93
93
|
def initialize
|
94
94
|
@listeners = []
|
@@ -0,0 +1,165 @@
|
|
1
|
+
module Neo4j
|
2
|
+
module Core
|
3
|
+
# Stolen from http://as.rubyonrails.org/classes/HashWithIndifferentAccess.html
|
4
|
+
# We don't want to depend on active support
|
5
|
+
class HashWithIndifferentAccess < Hash
|
6
|
+
|
7
|
+
# Always returns true, so that <tt>Array#extract_options!</tt> finds members of this class.
|
8
|
+
def extractable_options?
|
9
|
+
true
|
10
|
+
end
|
11
|
+
|
12
|
+
def with_indifferent_access
|
13
|
+
dup
|
14
|
+
end
|
15
|
+
|
16
|
+
def nested_under_indifferent_access
|
17
|
+
self
|
18
|
+
end
|
19
|
+
|
20
|
+
def initialize(constructor = {})
|
21
|
+
if constructor.is_a?(Hash)
|
22
|
+
super()
|
23
|
+
update(constructor)
|
24
|
+
else
|
25
|
+
super(constructor)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def default(key = nil)
|
30
|
+
if key.is_a?(Symbol) && include?(key = key.to_s)
|
31
|
+
self[key]
|
32
|
+
else
|
33
|
+
super
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def self.new_from_hash_copying_default(hash)
|
38
|
+
new(hash).tap do |new_hash|
|
39
|
+
new_hash.default = hash.default
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
alias_method :regular_writer, :[]= unless method_defined?(:regular_writer)
|
44
|
+
alias_method :regular_update, :update unless method_defined?(:regular_update)
|
45
|
+
|
46
|
+
# Assigns a new value to the hash:
|
47
|
+
#
|
48
|
+
# hash = HashWithIndifferentAccess.new
|
49
|
+
# hash[:key] = "value"
|
50
|
+
#
|
51
|
+
def []=(key, value)
|
52
|
+
regular_writer(convert_key(key), convert_value(value))
|
53
|
+
end
|
54
|
+
|
55
|
+
alias_method :store, :[]=
|
56
|
+
|
57
|
+
# Updates the instantized hash with values from the second:
|
58
|
+
#
|
59
|
+
# hash_1 = HashWithIndifferentAccess.new
|
60
|
+
# hash_1[:key] = "value"
|
61
|
+
#
|
62
|
+
# hash_2 = HashWithIndifferentAccess.new
|
63
|
+
# hash_2[:key] = "New Value!"
|
64
|
+
#
|
65
|
+
# hash_1.update(hash_2) # => {"key"=>"New Value!"}
|
66
|
+
#
|
67
|
+
def update(other_hash)
|
68
|
+
if other_hash.is_a? HashWithIndifferentAccess
|
69
|
+
super(other_hash)
|
70
|
+
else
|
71
|
+
other_hash.each_pair { |key, value| regular_writer(convert_key(key), convert_value(value)) }
|
72
|
+
self
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
alias_method :merge!, :update
|
77
|
+
|
78
|
+
# Checks the hash for a key matching the argument passed in:
|
79
|
+
#
|
80
|
+
# hash = HashWithIndifferentAccess.new
|
81
|
+
# hash["key"] = "value"
|
82
|
+
# hash.key? :key # => true
|
83
|
+
# hash.key? "key" # => true
|
84
|
+
#
|
85
|
+
def key?(key)
|
86
|
+
super(convert_key(key))
|
87
|
+
end
|
88
|
+
|
89
|
+
alias_method :include?, :key?
|
90
|
+
alias_method :has_key?, :key?
|
91
|
+
alias_method :member?, :key?
|
92
|
+
|
93
|
+
# Fetches the value for the specified key, same as doing hash[key]
|
94
|
+
def fetch(key, *extras)
|
95
|
+
super(convert_key(key), *extras)
|
96
|
+
end
|
97
|
+
|
98
|
+
# Returns an array of the values at the specified indices:
|
99
|
+
#
|
100
|
+
# hash = HashWithIndifferentAccess.new
|
101
|
+
# hash[:a] = "x"
|
102
|
+
# hash[:b] = "y"
|
103
|
+
# hash.values_at("a", "b") # => ["x", "y"]
|
104
|
+
#
|
105
|
+
def values_at(*indices)
|
106
|
+
indices.collect {|key| self[convert_key(key)]}
|
107
|
+
end
|
108
|
+
|
109
|
+
# Returns an exact copy of the hash.
|
110
|
+
def dup
|
111
|
+
self.class.new(self).tap do |new_hash|
|
112
|
+
new_hash.default = default
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
# Merges the instantized and the specified hashes together, giving precedence to the values from the second hash.
|
117
|
+
# Does not overwrite the existing hash.
|
118
|
+
def merge(hash)
|
119
|
+
self.dup.update(hash)
|
120
|
+
end
|
121
|
+
|
122
|
+
# Performs the opposite of merge, with the keys and values from the first hash taking precedence over the second.
|
123
|
+
# This overloaded definition prevents returning a regular hash, if reverse_merge is called on a <tt>HashWithDifferentAccess</tt>.
|
124
|
+
def reverse_merge(other_hash)
|
125
|
+
super self.class.new_from_hash_copying_default(other_hash)
|
126
|
+
end
|
127
|
+
|
128
|
+
def reverse_merge!(other_hash)
|
129
|
+
replace(reverse_merge( other_hash ))
|
130
|
+
end
|
131
|
+
|
132
|
+
# Removes a specified key from the hash.
|
133
|
+
def delete(key)
|
134
|
+
super(convert_key(key))
|
135
|
+
end
|
136
|
+
|
137
|
+
def stringify_keys!; self end
|
138
|
+
def stringify_keys; dup end
|
139
|
+
# undef :symbolize_keys!
|
140
|
+
def symbolize_keys; to_hash.symbolize_keys end
|
141
|
+
def to_options!; self end
|
142
|
+
|
143
|
+
# Convert to a Hash with String keys.
|
144
|
+
def to_hash
|
145
|
+
Hash.new(default).merge!(self)
|
146
|
+
end
|
147
|
+
|
148
|
+
protected
|
149
|
+
def convert_key(key)
|
150
|
+
key.kind_of?(Symbol) ? key.to_s : key
|
151
|
+
end
|
152
|
+
|
153
|
+
def convert_value(value)
|
154
|
+
if value.is_a? Hash
|
155
|
+
value #.nested_under_indifferent_access
|
156
|
+
elsif value.is_a?(Array)
|
157
|
+
value.dup.replace(value.map { |e| convert_value(e) })
|
158
|
+
else
|
159
|
+
value
|
160
|
+
end
|
161
|
+
end
|
162
|
+
end
|
163
|
+
|
164
|
+
end
|
165
|
+
end
|
@@ -7,7 +7,6 @@ module Neo4j
|
|
7
7
|
attr_reader :_indexer
|
8
8
|
|
9
9
|
|
10
|
-
# TODO fix YARD docs update using DSL
|
11
10
|
# Sets which indexer should be used for the given node class.
|
12
11
|
# You can share an indexer between several different classes.
|
13
12
|
#
|
@@ -20,49 +19,18 @@ module Neo4j
|
|
20
19
|
# node_indexer do
|
21
20
|
# index_names :exact => 'myindex_exact', :fulltext => 'myindex_fulltext'
|
22
21
|
# trigger_on :ntype => 'foo', :name => ['bar', 'foobar']
|
23
|
-
# # TODO multitenancy support
|
24
|
-
# prefix_index_name do
|
25
|
-
# return "" unless Neo4j.running?
|
26
|
-
# return "" unless @indexer_for.respond_to?(:ref_node_for_class)
|
27
|
-
# ref_node = @indexer_for.ref_node_for_class.wrapper
|
28
|
-
# prefix = ref_node.send(:_index_prefix) if ref_node.respond_to?(:_index_prefix)
|
29
|
-
# prefix ||= ref_node[:name] # To maintain backward compatiblity
|
30
|
-
# prefix.blank? ? "" : prefix + "_"
|
31
|
-
# end
|
32
|
-
#
|
33
22
|
#
|
34
|
-
#
|
35
|
-
#
|
36
|
-
# type = decl_props && decl_props[field.to_sym] && decl_props[field.to_sym][:type]
|
37
|
-
# type && !type.is_a?(String)
|
23
|
+
# prefix_index_name do
|
24
|
+
# "Foo" # this is used for example in multitenancy to let each domain have there own index files
|
38
25
|
# end
|
39
26
|
# end
|
40
27
|
# end
|
41
28
|
#
|
42
|
-
# @
|
43
|
-
#
|
44
|
-
# class Contact
|
45
|
-
# include Neo4j::NodeMixin
|
46
|
-
# index :name
|
47
|
-
# has_one :phone
|
48
|
-
# end
|
49
|
-
#
|
50
|
-
# class Phone
|
51
|
-
# include Neo4j::NodeMixin
|
52
|
-
# property :phone
|
53
|
-
# node_indexer Contact # put index on the Contact class instead
|
54
|
-
# index :phone
|
55
|
-
# end
|
56
|
-
#
|
57
|
-
# # Find an contact with a phone number, this works since they share the same index
|
58
|
-
# Contact.find('phone: 12345').first #=> a phone object !
|
59
|
-
#
|
29
|
+
# @param [Neo4j::Core::Index::IndexConfig] config the configuration used as context for the config_dsl
|
60
30
|
# @return [Neo4j::Core::Index::Indexer] The indexer that should be used to index the given class
|
61
31
|
# @see Neo4j::Core::Index::IndexConfig for possible configuration values in the +config_dsl+ block
|
62
32
|
# @yield evaluated in the a Neo4j::Core::Index::IndexConfig object to configure it.
|
63
|
-
def node_indexer(&config_dsl)
|
64
|
-
# TODO reuse an existing index config
|
65
|
-
config = IndexConfig.new(:node)
|
33
|
+
def node_indexer(config = _config || IndexConfig.new(:node), &config_dsl)
|
66
34
|
config.instance_eval(&config_dsl)
|
67
35
|
indexer(config)
|
68
36
|
end
|
@@ -70,17 +38,32 @@ module Neo4j
|
|
70
38
|
# Sets which indexer should be used for the given relationship class
|
71
39
|
# Same as #node_indexer except that it indexes relationships instead of nodes.
|
72
40
|
#
|
73
|
-
# @see #node_indexer
|
74
|
-
# @return
|
75
|
-
def rel_indexer(
|
76
|
-
|
41
|
+
# @param (see #node_indexer)
|
42
|
+
# @return (see #node_indexer)
|
43
|
+
def rel_indexer(config = _config || IndexConfig.new(:rel), &config_dsl)
|
44
|
+
config.instance_eval(&config_dsl)
|
45
|
+
indexer(config)
|
77
46
|
end
|
78
47
|
|
48
|
+
def _config
|
49
|
+
@_indexer && @_indexer.config
|
50
|
+
end
|
79
51
|
|
80
52
|
def indexer(index_config)
|
81
53
|
@_indexer ||= IndexerRegistry.instance.register(Indexer.new(index_config))
|
82
54
|
end
|
83
55
|
|
56
|
+
# You can specify which nodes should be triggered.
|
57
|
+
# The index can be triggered by one or more properties having one or more values.
|
58
|
+
# This can also be done using the #node_indexer or #rel_indexer methods.
|
59
|
+
#
|
60
|
+
# @example trigger on property :type being 'MyType1'
|
61
|
+
# Neo4j::NodeIndex.trigger_on(:type => 'MyType1')
|
62
|
+
#
|
63
|
+
def trigger_on(hash)
|
64
|
+
_config.trigger_on(hash)
|
65
|
+
end
|
66
|
+
|
84
67
|
|
85
68
|
class << self
|
86
69
|
private
|
@@ -93,7 +76,7 @@ module Neo4j
|
|
93
76
|
def delegate(method_name)
|
94
77
|
class_eval(<<-EOM, __FILE__, __LINE__)
|
95
78
|
def #{method_name}(*args, &block)
|
96
|
-
|
79
|
+
_indexer.send(:#{method_name}, *args, &block)
|
97
80
|
end
|
98
81
|
EOM
|
99
82
|
end
|
@@ -109,6 +92,9 @@ module Neo4j
|
|
109
92
|
delegate :add_index
|
110
93
|
delegate :rm_index
|
111
94
|
delegate :index_type
|
95
|
+
delegate :index_name_for_type
|
96
|
+
delegate :index_for_type
|
97
|
+
delegate :put_if_absent
|
112
98
|
end
|
113
99
|
|
114
100
|
|
@@ -2,7 +2,7 @@ module Neo4j
|
|
2
2
|
module Core
|
3
3
|
|
4
4
|
# A mixin which adds indexing behaviour to your own Ruby class
|
5
|
-
# You are expected to implement the method `
|
5
|
+
# You are expected to implement the method `_java_entity` returning the underlying Neo4j Node or Relationship.
|
6
6
|
module Index
|
7
7
|
|
8
8
|
# Adds an index on the given property
|
@@ -16,8 +16,7 @@ module Neo4j
|
|
16
16
|
# @see Neo4j::Core::Index::ClassMethods#add_index
|
17
17
|
#
|
18
18
|
def add_index(field, value=self[field])
|
19
|
-
|
20
|
-
self.class.add_index(wrapped_entity, field.to_s, converted_value)
|
19
|
+
self.class.add_index(_java_entity, field.to_s, value)
|
21
20
|
end
|
22
21
|
|
23
22
|
# Removes an index on the given property.
|
@@ -27,7 +26,7 @@ module Neo4j
|
|
27
26
|
# @see Neo4j::Core::Index::ClassMethods#rm_index
|
28
27
|
#
|
29
28
|
def rm_index(field, value=self[field])
|
30
|
-
self.class.rm_index(
|
29
|
+
self.class.rm_index(_java_entity, field.to_s, value)
|
31
30
|
end
|
32
31
|
|
33
32
|
end
|
@@ -5,14 +5,25 @@ module Neo4j
|
|
5
5
|
# Responsible for holding the configuration for one index
|
6
6
|
# Is used in a DSL to configure the index.
|
7
7
|
class IndexConfig
|
8
|
-
attr_reader :_trigger_on, :_index_names, :entity_type
|
8
|
+
attr_reader :_trigger_on, :_index_names, :entity_type, :_index_type, :_field_types
|
9
9
|
|
10
|
+
# @param [:rel, :node] entity_type the type of index
|
10
11
|
def initialize(entity_type)
|
11
12
|
@entity_type = entity_type
|
12
|
-
@
|
13
|
-
@
|
13
|
+
@_index_type = {}
|
14
|
+
@_field_types = {}
|
14
15
|
@_trigger_on = {}
|
15
|
-
|
16
|
+
end
|
17
|
+
|
18
|
+
def to_s
|
19
|
+
"IndexConfig [#@entity_type, _index_type: #{@_index_type.inspect}, _field_types: #{@_field_types.inspect}, _trigger_on: #{@_trigger_on.inspect}]"
|
20
|
+
end
|
21
|
+
|
22
|
+
def inherit_from(clazz)
|
23
|
+
c = clazz._indexer.config
|
24
|
+
raise "Can't inherit from different index type #{@entity_type} != #{c.entity_type}" if @entity_type != c.entity_type
|
25
|
+
@_index_type.merge!(c._index_type)
|
26
|
+
@_field_types.merge!(c._field_types)
|
16
27
|
end
|
17
28
|
|
18
29
|
# Specifies which property and values the index should be triggered on.
|
@@ -22,11 +33,8 @@ module Neo4j
|
|
22
33
|
merge_and_to_string(@_trigger_on, hash)
|
23
34
|
end
|
24
35
|
|
25
|
-
|
26
|
-
|
27
|
-
# @see Neo4j::Core::Index::ClassMethods#node_indexer
|
28
|
-
def decl_type(prop_and_type_hash)
|
29
|
-
merge_and_to_string(@decl_type, prop_and_type_hash)
|
36
|
+
def field_type(key)
|
37
|
+
@_field_types[key.to_s]
|
30
38
|
end
|
31
39
|
|
32
40
|
# Specifies an index with configuration
|
@@ -37,15 +45,15 @@ module Neo4j
|
|
37
45
|
conf = args.last.kind_of?(Hash) ? args.pop : {}
|
38
46
|
|
39
47
|
args.uniq.each do |field|
|
40
|
-
@
|
41
|
-
@
|
48
|
+
@_index_type[field.to_s] = conf[:type] || :exact
|
49
|
+
@_field_types[field.to_s] = conf[:field_type] || String
|
42
50
|
end
|
43
51
|
end
|
44
52
|
|
45
|
-
# @return [Class] the specified type of the property or
|
53
|
+
# @return [Class,nil] the specified type of the property or nil
|
46
54
|
# @see #decl_type
|
47
55
|
def decl_type_on(prop)
|
48
|
-
@
|
56
|
+
@_field_types[prop]
|
49
57
|
end
|
50
58
|
|
51
59
|
# @return [true, false] if the props can/should trigger an index operation
|
@@ -71,31 +79,30 @@ module Neo4j
|
|
71
79
|
@_index_names = hash
|
72
80
|
end
|
73
81
|
|
74
|
-
|
75
82
|
def rm_index_config
|
76
|
-
@
|
77
|
-
@
|
83
|
+
@_index_type = {}
|
84
|
+
@_field_types = {}
|
78
85
|
end
|
79
86
|
|
80
87
|
def index_type(field)
|
81
|
-
@
|
88
|
+
@_index_type[field.to_s]
|
82
89
|
end
|
83
90
|
|
84
91
|
def has_index_type?(type)
|
85
|
-
@
|
92
|
+
@_index_type.values.include?(type)
|
86
93
|
end
|
87
94
|
|
88
95
|
def fields
|
89
|
-
@
|
96
|
+
@_index_type.keys
|
90
97
|
end
|
91
98
|
|
92
99
|
def index?(field)
|
93
|
-
@
|
100
|
+
@_index_type.include?(field.to_s)
|
94
101
|
end
|
95
102
|
|
96
103
|
def numeric?(field)
|
97
|
-
|
98
|
-
|
104
|
+
raise "No index on #{field.inspect}, has fields: #{@field_types.inspect}" unless @_field_types[field]
|
105
|
+
@_field_types[field] != String
|
99
106
|
end
|
100
107
|
|
101
108
|
private
|
@@ -103,7 +110,7 @@ module Neo4j
|
|
103
110
|
def merge_and_to_string(existing_hash, new_hash)
|
104
111
|
new_hash.each_pair do |k, v|
|
105
112
|
existing_hash[k.to_s] ||= Set.new
|
106
|
-
existing_hash[k.to_s].merge(v.is_a?(Array)? v : [v])
|
113
|
+
existing_hash[k.to_s].merge(v.is_a?(Array) ? v : [v])
|
107
114
|
end
|
108
115
|
end
|
109
116
|
end
|