odba 1.1.8 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.github/workflows/devenv.yml +30 -0
- data/.github/workflows/ruby.yml +8 -7
- data/.gitignore +11 -0
- data/{History.txt → History.md} +43 -19
- data/README.md +79 -2
- data/Rakefile +3 -15
- data/devenv.lock +171 -0
- data/devenv.nix +53 -0
- data/devenv.yaml +8 -0
- data/lib/odba/cache.rb +401 -344
- data/lib/odba/cache_entry.rb +42 -31
- data/lib/odba/connection_pool.rb +99 -72
- data/lib/odba/drbwrapper.rb +26 -18
- data/lib/odba/id_server.rb +20 -20
- data/lib/odba/index.rb +249 -215
- data/lib/odba/index_definition.rb +17 -17
- data/lib/odba/marshal.rb +15 -14
- data/lib/odba/odba.rb +40 -32
- data/lib/odba/odba_error.rb +4 -2
- data/lib/odba/persistable.rb +460 -414
- data/lib/odba/storage.rb +328 -277
- data/lib/odba/stub.rb +166 -153
- data/lib/odba/version.rb +1 -1
- data/lib/odba.rb +9 -9
- data/odba.gemspec +8 -3
- data/test/example.rb +47 -0
- data/test/helper.rb +6 -0
- data/test/suite.rb +7 -0
- data/test/test_array.rb +38 -33
- data/test/test_cache.rb +657 -622
- data/test/test_cache_entry.rb +51 -71
- data/test/test_connection_pool.rb +70 -25
- data/test/test_drbwrapper.rb +24 -19
- data/test/test_hash.rb +98 -89
- data/test/test_id_server.rb +30 -32
- data/test/test_index.rb +191 -158
- data/test/test_marshal.rb +15 -25
- data/test/test_persistable.rb +378 -369
- data/test/test_storage.rb +510 -471
- data/test/test_stub.rb +147 -135
- metadata +63 -20
- data/Guide.txt +0 -36
- data/Manifest.txt +0 -38
- data/install.rb +0 -1098
- data/lib/odba/18_19_loading_compatibility.rb +0 -77
data/lib/odba/index.rb
CHANGED
|
@@ -1,110 +1,117 @@
|
|
|
1
1
|
#!/usr/bin/env ruby
|
|
2
2
|
#-- Index -- odba -- 13.05.2004 -- rwaltert@ywesee.com
|
|
3
3
|
|
|
4
|
-
require
|
|
4
|
+
require "odba/persistable"
|
|
5
5
|
|
|
6
6
|
module ODBA
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
7
|
+
# Indices in ODBA are defined by origin and target (which may be identical)
|
|
8
|
+
# Any time a Persistable of class _target_klass_ or _origin_klass_ is stored,
|
|
9
|
+
# all corresponding indices are updated. To make this possible, we have to tell
|
|
10
|
+
# Index, how to navigate from _origin_ to _target_ and vice versa.
|
|
11
|
+
# This entails the Limitation that these paths must not change without
|
|
12
|
+
# _origin_ and/or _target_ being stored.
|
|
13
|
+
# Further, _search_term_ must be resolved in relation to _origin_.
|
|
14
|
+
class IndexCommon # :nodoc: all
|
|
15
|
+
include Persistable
|
|
16
|
+
ODBA_EXCLUDE_VARS
|
|
17
|
+
[
|
|
18
18
|
:@proc_origin, :@proc_target, :@proc_resolve_search_term
|
|
19
19
|
]
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
@target_klass = origin_module.instance_eval(index_definition.target_klass.to_s)
|
|
30
|
-
@resolve_origin = index_definition.resolve_origin
|
|
31
|
-
@resolve_target = index_definition.resolve_target
|
|
32
|
-
@index_name = index_definition.index_name
|
|
33
|
-
@resolve_search_term = index_definition.resolve_search_term
|
|
20
|
+
attr_accessor :origin_klass, :target_klass, :resolve_origin, :resolve_target,
|
|
21
|
+
:resolve_search_term, :index_name, :class_filter
|
|
22
|
+
def initialize(index_definition, origin_module)
|
|
23
|
+
@origin_klass = origin_module.instance_eval(index_definition.origin_klass.to_s)
|
|
24
|
+
@target_klass = origin_module.instance_eval(index_definition.target_klass.to_s)
|
|
25
|
+
@resolve_origin = index_definition.resolve_origin
|
|
26
|
+
@resolve_target = index_definition.resolve_target
|
|
27
|
+
@index_name = index_definition.index_name
|
|
28
|
+
@resolve_search_term = index_definition.resolve_search_term
|
|
34
29
|
@class_filter = index_definition.class_filter
|
|
35
|
-
|
|
30
|
+
end
|
|
31
|
+
|
|
36
32
|
def current_origin_ids(target_id) # :nodoc:
|
|
37
33
|
ODBA.storage.index_origin_ids(@index_name, target_id)
|
|
38
34
|
end
|
|
35
|
+
|
|
39
36
|
def current_target_ids(origin_id) # :nodoc:
|
|
40
37
|
ODBA.storage.index_target_ids(@index_name, origin_id)
|
|
41
38
|
end
|
|
39
|
+
|
|
42
40
|
def delete(object) # :nodoc:
|
|
43
|
-
if
|
|
44
|
-
ODBA.storage.delete_index_element(@index_name, object.odba_id,
|
|
45
|
-
|
|
41
|
+
if object.is_a?(@origin_klass)
|
|
42
|
+
ODBA.storage.delete_index_element(@index_name, object.odba_id,
|
|
43
|
+
"origin_id")
|
|
46
44
|
end
|
|
47
|
-
if
|
|
48
|
-
ODBA.storage.delete_index_element(@index_name, object.odba_id,
|
|
49
|
-
|
|
45
|
+
if object.is_a?(@target_klass)
|
|
46
|
+
ODBA.storage.delete_index_element(@index_name, object.odba_id,
|
|
47
|
+
"target_id")
|
|
50
48
|
end
|
|
51
49
|
end
|
|
50
|
+
|
|
52
51
|
def delete_origin(origin_id, term) # :nodoc:
|
|
53
52
|
ODBA.storage.index_delete_origin(@index_name, origin_id, term)
|
|
54
53
|
end
|
|
54
|
+
|
|
55
55
|
def delete_target(origin_id, old_term, target_id) # :nodoc:
|
|
56
56
|
ODBA.storage.index_delete_target(@index_name, origin_id,
|
|
57
|
-
|
|
57
|
+
old_term, target_id)
|
|
58
58
|
end
|
|
59
|
-
|
|
59
|
+
|
|
60
|
+
def do_update_index(origin_id, term, target_id = nil) # :nodoc:
|
|
60
61
|
ODBA.storage.update_index(@index_name, origin_id, term, target_id)
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def fill(targets)
|
|
65
|
+
@proc_origin = nil
|
|
66
|
+
targets.flatten.each { |target|
|
|
67
|
+
target_id = target.odba_id
|
|
68
|
+
origins = proc_instance_origin.call(target)
|
|
69
|
+
origins.each { |origin|
|
|
69
70
|
search_terms(origin).each { |term|
|
|
70
|
-
do_update_index(
|
|
71
|
+
do_update_index(origin.odba_id, term, target_id)
|
|
71
72
|
}
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
def keys(length = nil)
|
|
78
|
+
ODBA.storage.index_fetch_keys(@index_name, length).delete_if { |k|
|
|
79
|
+
k.empty?
|
|
80
|
+
}
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
def matches(substring, limit = nil, offset = 0)
|
|
80
84
|
ODBA.storage.index_matches @index_name, substring, limit, offset
|
|
81
85
|
end
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
86
|
+
|
|
87
|
+
def origin_class?(klass)
|
|
88
|
+
(@origin_klass == klass)
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
def proc_instance_origin # :nodoc:
|
|
92
|
+
if @proc_origin.nil?
|
|
93
|
+
if @resolve_origin.to_s.empty?
|
|
94
|
+
@proc_origin = proc { |odba_item| [odba_item] }
|
|
95
|
+
else
|
|
96
|
+
src = <<-EOS
|
|
91
97
|
Proc.new { |odba_item|
|
|
92
98
|
res = [odba_item.#{@resolve_origin}]
|
|
93
99
|
res.flatten!
|
|
94
100
|
res.compact!
|
|
95
101
|
res
|
|
96
102
|
}
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
+
EOS
|
|
104
|
+
@proc_origin = eval(src)
|
|
105
|
+
end
|
|
106
|
+
end
|
|
107
|
+
@proc_origin
|
|
108
|
+
end
|
|
109
|
+
|
|
103
110
|
def proc_instance_target # :nodoc:
|
|
104
|
-
if
|
|
105
|
-
if
|
|
106
|
-
@proc_target =
|
|
107
|
-
#elsif(@resolve_target == :odba_skip)
|
|
111
|
+
if @proc_target.nil?
|
|
112
|
+
if @resolve_target.to_s.empty?
|
|
113
|
+
@proc_target = proc { |odba_item| [odba_item] }
|
|
114
|
+
# elsif(@resolve_target == :odba_skip)
|
|
108
115
|
# @proc_target = Proc.new { [] }
|
|
109
116
|
else
|
|
110
117
|
src = <<-EOS
|
|
@@ -120,14 +127,15 @@ module ODBA
|
|
|
120
127
|
end
|
|
121
128
|
@proc_target
|
|
122
129
|
end
|
|
130
|
+
|
|
123
131
|
def proc_resolve_search_term # :nodoc:
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
132
|
+
if @proc_resolve_search_term.nil?
|
|
133
|
+
if @resolve_search_term.to_s.empty?
|
|
134
|
+
@proc_resolve_search_term = proc { |origin|
|
|
127
135
|
origin.to_s.downcase
|
|
128
136
|
}
|
|
129
|
-
|
|
130
|
-
|
|
137
|
+
else
|
|
138
|
+
src = <<-EOS
|
|
131
139
|
Proc.new { |origin|
|
|
132
140
|
begin
|
|
133
141
|
origin.#{@resolve_search_term}
|
|
@@ -135,42 +143,47 @@ module ODBA
|
|
|
135
143
|
nil
|
|
136
144
|
end
|
|
137
145
|
}
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
146
|
+
EOS
|
|
147
|
+
@proc_resolve_search_term = eval(src)
|
|
148
|
+
end
|
|
149
|
+
end
|
|
150
|
+
@proc_resolve_search_term
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
def search_term(origin) # :nodoc:
|
|
154
|
+
proc_resolve_search_term.call(origin)
|
|
155
|
+
end
|
|
156
|
+
|
|
147
157
|
def search_terms(origin)
|
|
148
158
|
[search_term(origin)].flatten.compact.uniq
|
|
149
159
|
end
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
160
|
+
|
|
161
|
+
def set_relevance(meta, rows) # :nodoc:
|
|
162
|
+
if meta.respond_to?(:set_relevance)
|
|
163
|
+
rows.each { |row|
|
|
164
|
+
meta.set_relevance(row.at(0), row.at(1))
|
|
165
|
+
}
|
|
166
|
+
end
|
|
167
|
+
end
|
|
168
|
+
|
|
169
|
+
def update(object)
|
|
158
170
|
@class_filter ||= :is_a?
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
rescue
|
|
165
|
-
warn
|
|
166
|
-
#{err.class}: #{err.message} when updating index '#{@index_name}' with a #{object.class}
|
|
167
|
-
#{err.backtrace[0,4]}
|
|
168
|
-
[...]
|
|
171
|
+
if object.send(@class_filter, @target_klass)
|
|
172
|
+
update_target(object)
|
|
173
|
+
elsif object.send(@class_filter, @origin_klass)
|
|
174
|
+
update_origin(object)
|
|
175
|
+
end
|
|
176
|
+
rescue => err
|
|
177
|
+
warn <<~EOS
|
|
178
|
+
#{err.class}: #{err.message} when updating index '#{@index_name}' with a #{object.class}
|
|
179
|
+
#{err.backtrace[0, 4]}
|
|
180
|
+
[...]
|
|
169
181
|
EOS
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
182
|
+
end
|
|
183
|
+
|
|
184
|
+
def update_origin(object) # :nodoc:
|
|
185
|
+
origin_id = object.odba_id
|
|
186
|
+
search_terms = search_terms(object)
|
|
174
187
|
current = current_target_ids(origin_id)
|
|
175
188
|
target_ids = []
|
|
176
189
|
current_terms = []
|
|
@@ -184,15 +197,16 @@ module ODBA
|
|
|
184
197
|
delete_origin(origin_id, term)
|
|
185
198
|
}
|
|
186
199
|
new_terms = search_terms - current_terms
|
|
187
|
-
unless
|
|
200
|
+
unless new_terms.empty?
|
|
188
201
|
target_ids.each { |target_id|
|
|
189
202
|
new_terms.each { |term|
|
|
190
203
|
do_update_index(origin_id, term, target_id)
|
|
191
204
|
}
|
|
192
205
|
}
|
|
193
206
|
end
|
|
194
|
-
|
|
195
|
-
|
|
207
|
+
end
|
|
208
|
+
|
|
209
|
+
def update_target(target) # :nodoc:
|
|
196
210
|
target_id = target.odba_id
|
|
197
211
|
current = current_origin_ids(target_id)
|
|
198
212
|
old_terms = current.collect { |row|
|
|
@@ -212,42 +226,46 @@ module ODBA
|
|
|
212
226
|
(new_terms - old_terms).each { |origin_id, terms|
|
|
213
227
|
do_update_index(origin_id, terms, target_id)
|
|
214
228
|
}
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
229
|
+
end
|
|
230
|
+
end
|
|
231
|
+
|
|
232
|
+
# Currently there are 3 predefined Index-classes
|
|
233
|
+
# For Sample Code see
|
|
234
|
+
# http://dev.ywesee.com/wiki.php/ODBA/SimpleIndex
|
|
235
|
+
# http://dev.ywesee.com/wiki.php/ODBA/ConditionIndex
|
|
236
|
+
# http://dev.ywesee.com/wiki.php/ODBA/FulltextIndex
|
|
237
|
+
class Index < IndexCommon # :nodoc: all
|
|
238
|
+
def initialize(index_definition, origin_module) # :nodoc:
|
|
239
|
+
super
|
|
240
|
+
ODBA.storage.create_index(index_definition.index_name)
|
|
241
|
+
end
|
|
242
|
+
|
|
243
|
+
def fetch_ids(search_term, meta = nil) # :nodoc:
|
|
244
|
+
exact = meta.respond_to?(:exact) && meta.exact
|
|
245
|
+
limit = meta.respond_to?(:limit) && meta.limit
|
|
246
|
+
rows = ODBA.storage.retrieve_from_index(@index_name,
|
|
247
|
+
search_term.to_s.downcase,
|
|
248
|
+
exact, limit)
|
|
249
|
+
set_relevance(meta, rows)
|
|
250
|
+
rows.collect { |row| row.at(0) }
|
|
251
|
+
end
|
|
252
|
+
|
|
253
|
+
def update_origin(object) # :nodoc:
|
|
237
254
|
# Possible changes:
|
|
238
255
|
# - search_terms of origin have changed
|
|
239
256
|
# - targets have changed, except if @resolve_target == :none
|
|
240
257
|
# => we need a matrix of all current [term, target_id]
|
|
241
258
|
# and of all new [term, target_id]
|
|
242
|
-
|
|
243
|
-
|
|
259
|
+
origin_id = object.odba_id
|
|
260
|
+
search_terms = search_terms(object)
|
|
244
261
|
current = current_target_ids(origin_id)
|
|
245
262
|
target_ids = if @resolve_target == :none
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
263
|
+
current.dup
|
|
264
|
+
else
|
|
265
|
+
proc_instance_target.call(object).collect { |obj|
|
|
266
|
+
obj.odba_id
|
|
267
|
+
}
|
|
268
|
+
end
|
|
251
269
|
target_ids.compact!
|
|
252
270
|
target_ids.uniq!
|
|
253
271
|
current_ids = []
|
|
@@ -258,13 +276,11 @@ module ODBA
|
|
|
258
276
|
}
|
|
259
277
|
current_ids.uniq!
|
|
260
278
|
current_terms.uniq!
|
|
261
|
-
current_combinations = current_ids.
|
|
279
|
+
current_combinations = current_ids.each_with_object([]) { |id, memo|
|
|
262
280
|
current_terms.each { |term| memo.push [term, id] }
|
|
263
|
-
memo
|
|
264
281
|
}
|
|
265
|
-
combinations = target_ids.
|
|
282
|
+
combinations = target_ids.each_with_object([]) { |id, memo|
|
|
266
283
|
search_terms.each { |term| memo.push [term, id] }
|
|
267
|
-
memo
|
|
268
284
|
}
|
|
269
285
|
(current_combinations - combinations).each { |pair|
|
|
270
286
|
delete_target(origin_id, *pair)
|
|
@@ -272,119 +288,137 @@ module ODBA
|
|
|
272
288
|
(combinations - current_combinations).each { |pair|
|
|
273
289
|
do_update_index(origin_id, *pair)
|
|
274
290
|
}
|
|
275
|
-
|
|
291
|
+
end
|
|
292
|
+
|
|
276
293
|
def search_terms(origin)
|
|
277
294
|
super.collect { |term| term.to_s.downcase }.uniq
|
|
278
295
|
end
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
296
|
+
end
|
|
297
|
+
|
|
298
|
+
class ConditionIndex < IndexCommon # :nodoc: all
|
|
299
|
+
def initialize(index_definition, origin_module) # :nodoc:
|
|
300
|
+
super
|
|
301
|
+
definition = {}
|
|
302
|
+
@resolve_search_term = {}
|
|
303
|
+
index_definition.resolve_search_term.each { |name, info|
|
|
304
|
+
if info.is_a?(String)
|
|
305
|
+
info = {"resolve" => info}
|
|
306
|
+
end
|
|
307
|
+
if info["type"].nil?
|
|
308
|
+
info["type"] = "text"
|
|
309
|
+
end
|
|
310
|
+
@resolve_search_term.store(name, info)
|
|
311
|
+
definition.store(name, info["type"])
|
|
312
|
+
}
|
|
313
|
+
ODBA.storage.create_condition_index(@index_name, definition)
|
|
314
|
+
end
|
|
315
|
+
|
|
297
316
|
def current_ids(rows, id_name)
|
|
298
|
-
rows.collect { |row|
|
|
317
|
+
rows.collect { |row|
|
|
299
318
|
[
|
|
300
|
-
row[id_name],
|
|
319
|
+
row[id_name],
|
|
301
320
|
@resolve_search_term.keys.collect { |key|
|
|
302
|
-
[key.to_s, row[key]]
|
|
321
|
+
[key.to_s, row[key]]
|
|
322
|
+
}.sort
|
|
303
323
|
]
|
|
304
324
|
}
|
|
305
325
|
end
|
|
326
|
+
|
|
306
327
|
def current_origin_ids(target_id)
|
|
307
328
|
current_ids(ODBA.storage.condition_index_ids(@index_name,
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
329
|
+
target_id,
|
|
330
|
+
"target_id"),
|
|
331
|
+
"origin_id")
|
|
311
332
|
end
|
|
333
|
+
|
|
312
334
|
def current_target_ids(origin_id)
|
|
313
335
|
current_ids(ODBA.storage.condition_index_ids(@index_name,
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
336
|
+
origin_id,
|
|
337
|
+
"origin_id"),
|
|
338
|
+
"target_id")
|
|
317
339
|
end
|
|
340
|
+
|
|
318
341
|
def delete_origin(origin_id, search_terms)
|
|
319
342
|
ODBA.storage.condition_index_delete(@index_name, origin_id,
|
|
320
|
-
|
|
343
|
+
search_terms)
|
|
321
344
|
end
|
|
345
|
+
|
|
322
346
|
def delete_target(origin_id, search_terms, target_id)
|
|
323
347
|
ODBA.storage.condition_index_delete(@index_name, origin_id,
|
|
324
|
-
|
|
325
|
-
end
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
348
|
+
search_terms, target_id)
|
|
349
|
+
end
|
|
350
|
+
|
|
351
|
+
def do_update_index(origin_id, search_terms, target_id = nil) # :nodoc:
|
|
352
|
+
ODBA.storage.update_condition_index(@index_name, origin_id,
|
|
353
|
+
search_terms, target_id)
|
|
354
|
+
end
|
|
355
|
+
|
|
356
|
+
def fetch_ids(conditions, meta = nil) # :nodoc:
|
|
357
|
+
limit = meta.respond_to?(:limit) && meta.limit
|
|
358
|
+
rows = ODBA.storage.retrieve_from_condition_index(@index_name,
|
|
359
|
+
conditions,
|
|
360
|
+
limit)
|
|
361
|
+
set_relevance(meta, rows)
|
|
336
362
|
rows.collect { |row| row.at(0) }
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
363
|
+
end
|
|
364
|
+
|
|
365
|
+
def proc_resolve_search_term # :nodoc:
|
|
366
|
+
if @proc_resolve_search_term.nil?
|
|
367
|
+
src = <<-EOS
|
|
341
368
|
Proc.new { |origin|
|
|
342
369
|
values = {}
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
370
|
+
EOS
|
|
371
|
+
@resolve_search_term.each { |name, info|
|
|
372
|
+
src << <<-EOS
|
|
346
373
|
begin
|
|
347
|
-
values.store('#{name}', origin.#{info[
|
|
374
|
+
values.store('#{name}', origin.#{info["resolve"]})
|
|
348
375
|
rescue NameError
|
|
349
376
|
end
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
377
|
+
EOS
|
|
378
|
+
}
|
|
379
|
+
src << <<-EOS
|
|
353
380
|
values
|
|
354
381
|
}
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
382
|
+
EOS
|
|
383
|
+
@proc_resolve_search_term = eval(src)
|
|
384
|
+
end
|
|
385
|
+
@proc_resolve_search_term
|
|
386
|
+
end
|
|
387
|
+
|
|
360
388
|
def search_terms(origin)
|
|
361
389
|
super.collect { |data| data.to_a.sort }
|
|
362
390
|
end
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
391
|
+
end
|
|
392
|
+
|
|
393
|
+
class FulltextIndex < IndexCommon # :nodoc: all
|
|
394
|
+
def initialize(index_definition, origin_module) # :nodoc:
|
|
395
|
+
super
|
|
396
|
+
ODBA.storage.create_fulltext_index(@index_name)
|
|
397
|
+
end
|
|
398
|
+
|
|
369
399
|
def current_origin_ids(target_id)
|
|
370
400
|
ODBA.storage.fulltext_index_delete(@index_name, target_id,
|
|
371
|
-
|
|
401
|
+
"target_id")
|
|
372
402
|
[]
|
|
373
403
|
end
|
|
404
|
+
|
|
374
405
|
def current_target_ids(origin_id)
|
|
375
406
|
ODBA.storage.fulltext_index_target_ids(@index_name, origin_id)
|
|
376
407
|
end
|
|
408
|
+
|
|
377
409
|
def delete_origin(origin_id, term)
|
|
378
|
-
ODBA.storage.fulltext_index_delete(@index_name, origin_id,
|
|
379
|
-
|
|
410
|
+
ODBA.storage.fulltext_index_delete(@index_name, origin_id,
|
|
411
|
+
"origin_id")
|
|
380
412
|
end
|
|
381
|
-
|
|
413
|
+
|
|
414
|
+
def fetch_ids(search_term, meta = nil) # :nodoc:
|
|
382
415
|
limit = meta.respond_to?(:limit) && meta.limit
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
416
|
+
rows = ODBA.storage.retrieve_from_fulltext_index(@index_name, search_term, limit)
|
|
417
|
+
set_relevance(meta, rows)
|
|
418
|
+
rows.collect { |row| row.at(0) }
|
|
419
|
+
end
|
|
420
|
+
|
|
421
|
+
def do_update_index(origin_id, search_text, target_id = nil) # :nodoc:
|
|
388
422
|
ODBA.storage.update_fulltext_index(@index_name, origin_id, search_text, target_id)
|
|
389
423
|
end
|
|
390
424
|
end
|
|
@@ -2,22 +2,22 @@
|
|
|
2
2
|
#-- IndexDefinition -- odba -- 20.09.2004 -- hwyss@ywesee.com
|
|
3
3
|
|
|
4
4
|
module ODBA
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
5
|
+
# IndexDefinition is a convenience class. Load a yaml-dump of this and pass it
|
|
6
|
+
# to Cache#create_index to introduce new indices
|
|
7
|
+
class IndexDefinition
|
|
8
|
+
attr_accessor :index_name, :origin_klass,
|
|
9
|
+
:target_klass, :resolve_search_term, :resolve_target,
|
|
10
|
+
:resolve_origin, :fulltext, :init_source, :class_filter
|
|
11
|
+
def initialize
|
|
12
|
+
@index_name = ""
|
|
13
|
+
@origin_klass = ""
|
|
14
|
+
@target_klass = ""
|
|
15
|
+
@resolve_search_term = ""
|
|
16
|
+
@resolve_target = ""
|
|
17
|
+
@resolve_origin = ""
|
|
18
|
+
@init_source = ""
|
|
19
|
+
@fulltext = false
|
|
20
20
|
@class_filter = :is_a?
|
|
21
|
-
|
|
22
|
-
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
23
|
end
|