odba 1.0.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.
- data/History.txt +5 -0
- data/LICENSE +459 -0
- data/Manifest.txt +38 -0
- data/README.txt +32 -0
- data/Rakefile +28 -0
- data/install.rb +1098 -0
- data/lib/odba.rb +72 -0
- data/lib/odba/18_19_loading_compatibility.rb +71 -0
- data/lib/odba/cache.rb +603 -0
- data/lib/odba/cache_entry.rb +122 -0
- data/lib/odba/connection_pool.rb +87 -0
- data/lib/odba/drbwrapper.rb +88 -0
- data/lib/odba/id_server.rb +26 -0
- data/lib/odba/index.rb +395 -0
- data/lib/odba/index_definition.rb +24 -0
- data/lib/odba/marshal.rb +18 -0
- data/lib/odba/odba.rb +45 -0
- data/lib/odba/odba_error.rb +12 -0
- data/lib/odba/persistable.rb +621 -0
- data/lib/odba/storage.rb +628 -0
- data/lib/odba/stub.rb +187 -0
- data/sql/collection.sql +6 -0
- data/sql/create_tables.sql +6 -0
- data/sql/object.sql +8 -0
- data/sql/object_connection.sql +7 -0
- data/test/suite.rb +8 -0
- data/test/test_array.rb +108 -0
- data/test/test_cache.rb +725 -0
- data/test/test_cache_entry.rb +109 -0
- data/test/test_connection_pool.rb +77 -0
- data/test/test_drbwrapper.rb +102 -0
- data/test/test_hash.rb +144 -0
- data/test/test_id_server.rb +43 -0
- data/test/test_index.rb +371 -0
- data/test/test_marshal.rb +28 -0
- data/test/test_persistable.rb +625 -0
- data/test/test_storage.rb +829 -0
- data/test/test_stub.rb +226 -0
- metadata +134 -0
@@ -0,0 +1,829 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# encoding: ISO-8859-1
|
3
|
+
# TestStorage -- odba -- 10.05.2004 -- hwyss@ywesee.com rwaltert@ywesee.com mwalder@ywesee.com
|
4
|
+
|
5
|
+
$: << File.dirname(__FILE__)
|
6
|
+
$: << File.expand_path('../lib/', File.dirname(__FILE__))
|
7
|
+
|
8
|
+
require 'odba/storage'
|
9
|
+
require 'test/unit'
|
10
|
+
require 'flexmock'
|
11
|
+
|
12
|
+
module ODBA
|
13
|
+
class Storage
|
14
|
+
public :restore_max_id
|
15
|
+
attr_writer :next_id
|
16
|
+
end
|
17
|
+
class TestStorage < Test::Unit::TestCase
|
18
|
+
include FlexMock::TestCase
|
19
|
+
def setup
|
20
|
+
@storage = ODBA::Storage.instance
|
21
|
+
@dbi = flexmock('DBI')
|
22
|
+
@storage.dbi = @dbi
|
23
|
+
end
|
24
|
+
def test_bulk_restore
|
25
|
+
dbi = flexmock("dbi")
|
26
|
+
array = [1, 23, 4]
|
27
|
+
@storage.dbi = dbi
|
28
|
+
dbi.should_receive(:select_all).times(1).and_return { |query|
|
29
|
+
assert_not_nil(query.index('IN (1,23,4)'))
|
30
|
+
[]
|
31
|
+
}
|
32
|
+
@storage.bulk_restore(array)
|
33
|
+
end
|
34
|
+
def test_delete_persistable
|
35
|
+
dbi = flexmock("dbi")
|
36
|
+
@storage.dbi = dbi
|
37
|
+
expected1 = <<-SQL
|
38
|
+
DELETE FROM object_connection WHERE origin_id = ?
|
39
|
+
SQL
|
40
|
+
dbi.should_receive(:do).with(expected1, 2).times(1).and_return do
|
41
|
+
assert true
|
42
|
+
end
|
43
|
+
expected2 = <<-SQL
|
44
|
+
DELETE FROM object_connection WHERE target_id = ?
|
45
|
+
SQL
|
46
|
+
dbi.should_receive(:do).with(expected2, 2).times(1).and_return do
|
47
|
+
assert true
|
48
|
+
end
|
49
|
+
expected3 = <<-SQL
|
50
|
+
DELETE FROM collection WHERE odba_id = ?
|
51
|
+
SQL
|
52
|
+
dbi.should_receive(:do).with(expected3, 2).times(1).and_return do
|
53
|
+
assert true
|
54
|
+
end
|
55
|
+
expected4 = <<-SQL
|
56
|
+
DELETE FROM object WHERE odba_id = ?
|
57
|
+
SQL
|
58
|
+
dbi.should_receive(:do).with(expected4, 2).times(1).and_return do
|
59
|
+
assert true
|
60
|
+
end
|
61
|
+
@storage.delete_persistable(2)
|
62
|
+
end
|
63
|
+
def test_restore_prefetchable
|
64
|
+
dbi = flexmock("dbi")
|
65
|
+
rows = flexmock("row")
|
66
|
+
@storage.dbi = dbi
|
67
|
+
dbi.should_receive(:select_all).times(1).and_return{ |sql|
|
68
|
+
assert_equal("\t\t\t\tSELECT odba_id, content FROM object WHERE prefetchable = true\n", sql)
|
69
|
+
rows
|
70
|
+
}
|
71
|
+
@storage.restore_prefetchable
|
72
|
+
end
|
73
|
+
def test_bulk_restore_empty
|
74
|
+
dbi = flexmock("dbi")
|
75
|
+
array = []
|
76
|
+
@storage.dbi = dbi
|
77
|
+
assert_nothing_raised {
|
78
|
+
@storage.bulk_restore(array)
|
79
|
+
}
|
80
|
+
end
|
81
|
+
def test_create_index
|
82
|
+
dbi = flexmock('dbi')
|
83
|
+
@storage.dbi = dbi
|
84
|
+
sql = <<-SQL
|
85
|
+
CREATE TABLE index_name (
|
86
|
+
origin_id INTEGER,
|
87
|
+
search_term TEXT,
|
88
|
+
target_id INTEGER
|
89
|
+
);
|
90
|
+
SQL
|
91
|
+
dbi.should_receive(:do).times(1).with(sql).and_return do
|
92
|
+
assert true
|
93
|
+
end
|
94
|
+
sql = <<-SQL
|
95
|
+
CREATE INDEX origin_id_index_name
|
96
|
+
ON index_name(origin_id)
|
97
|
+
SQL
|
98
|
+
dbi.should_receive(:do).times(1).with(sql).and_return do
|
99
|
+
assert true
|
100
|
+
end
|
101
|
+
sql = <<-SQL
|
102
|
+
CREATE INDEX search_term_index_name
|
103
|
+
ON index_name(search_term)
|
104
|
+
SQL
|
105
|
+
dbi.should_receive(:do).times(1).with(sql).and_return do
|
106
|
+
assert true
|
107
|
+
end
|
108
|
+
sql = <<-SQL
|
109
|
+
CREATE INDEX target_id_index_name
|
110
|
+
ON index_name(target_id)
|
111
|
+
SQL
|
112
|
+
dbi.should_receive(:do).times(1).with(sql).and_return do
|
113
|
+
assert true
|
114
|
+
end
|
115
|
+
@storage.create_index("index_name")
|
116
|
+
end
|
117
|
+
def test_next_id
|
118
|
+
@storage.next_id = 1
|
119
|
+
assert_equal(2, @storage.next_id)
|
120
|
+
assert_equal(3, @storage.next_id)
|
121
|
+
end
|
122
|
+
def test_store__1
|
123
|
+
dbi = flexmock("dbi")
|
124
|
+
@storage.dbi = dbi
|
125
|
+
dbi.should_receive(:select_one).times(1).and_return { |query, id|
|
126
|
+
assert_equal('SELECT name FROM object WHERE odba_id = ?',
|
127
|
+
query)
|
128
|
+
assert_equal(1, id)
|
129
|
+
nil
|
130
|
+
}
|
131
|
+
dbi.should_receive(:do).times(1).and_return { |query, id, dump, name, prefetch, klass|
|
132
|
+
expected= <<-SQL
|
133
|
+
INSERT INTO object (odba_id, content, name, prefetchable, extent)
|
134
|
+
VALUES (?, ?, ?, ?, ?)
|
135
|
+
SQL
|
136
|
+
assert_equal(expected, query)
|
137
|
+
assert_equal(1, id)
|
138
|
+
assert_equal("foodump", dump)
|
139
|
+
assert_equal("foo", name)
|
140
|
+
assert_equal(true, prefetch)
|
141
|
+
assert_equal("FlexMock", klass)
|
142
|
+
}
|
143
|
+
@storage.store(1,"foodump", "foo", true, FlexMock)
|
144
|
+
end
|
145
|
+
def test_store__2
|
146
|
+
dbi = flexmock("dbi")
|
147
|
+
@storage.dbi = dbi
|
148
|
+
dbi.should_receive(:select_one).times(1).and_return { |query, id|
|
149
|
+
assert_equal('SELECT name FROM object WHERE odba_id = ?',
|
150
|
+
query)
|
151
|
+
assert_equal(1, id)
|
152
|
+
['name']
|
153
|
+
}
|
154
|
+
dbi.should_receive(:do).times(1).and_return { |query, dump, name, prefetch, klass, id|
|
155
|
+
expected= <<-SQL
|
156
|
+
UPDATE object SET
|
157
|
+
content = ?,
|
158
|
+
name = ?,
|
159
|
+
prefetchable = ?,
|
160
|
+
extent = ?
|
161
|
+
WHERE odba_id = ?
|
162
|
+
SQL
|
163
|
+
assert_equal(expected, query)
|
164
|
+
assert_equal(1, id)
|
165
|
+
assert_equal("foodump", dump)
|
166
|
+
assert_equal("foo", name)
|
167
|
+
assert_equal(true, prefetch)
|
168
|
+
assert_equal("FlexMock", klass)
|
169
|
+
}
|
170
|
+
@storage.store(1,"foodump", "foo", true, FlexMock)
|
171
|
+
end
|
172
|
+
def test_store__3__name_only_set_in_db
|
173
|
+
dbi = flexmock("dbi")
|
174
|
+
@storage.dbi = dbi
|
175
|
+
dbi.should_receive(:select_one).times(1).and_return { |query, id|
|
176
|
+
assert_equal('SELECT name FROM object WHERE odba_id = ?',
|
177
|
+
query)
|
178
|
+
assert_equal(1, id)
|
179
|
+
{'name' => 'name_in_db'}
|
180
|
+
}
|
181
|
+
dbi.should_receive(:do).times(1).and_return { |query, dump, name, prefetch, klass, id|
|
182
|
+
expected= <<-SQL
|
183
|
+
UPDATE object SET
|
184
|
+
content = ?,
|
185
|
+
name = ?,
|
186
|
+
prefetchable = ?,
|
187
|
+
extent = ?
|
188
|
+
WHERE odba_id = ?
|
189
|
+
SQL
|
190
|
+
assert_equal(expected, query)
|
191
|
+
assert_equal(1, id)
|
192
|
+
assert_equal("foodump", dump)
|
193
|
+
assert_equal("name_in_db", name)
|
194
|
+
assert_equal(true, prefetch)
|
195
|
+
assert_equal("FlexMock", klass)
|
196
|
+
}
|
197
|
+
@storage.store(1,"foodump", nil, true, FlexMock)
|
198
|
+
end
|
199
|
+
def test_restore
|
200
|
+
dbi = flexmock
|
201
|
+
@storage.dbi = dbi
|
202
|
+
dbi.should_receive(:select_one).times(1).and_return{ |arg, name| ['dump'] }
|
203
|
+
assert_equal('dump', @storage.restore(1))
|
204
|
+
end
|
205
|
+
def test_restore_named
|
206
|
+
dbi = flexmock
|
207
|
+
@storage.dbi = dbi
|
208
|
+
dbi.should_receive(:select_one).times(1).and_return{ |arg, name| ['dump'] }
|
209
|
+
assert_equal('dump', @storage.restore_named('foo'))
|
210
|
+
end
|
211
|
+
def test_max_id
|
212
|
+
dbi = flexmock
|
213
|
+
row = flexmock
|
214
|
+
@storage.dbi = dbi
|
215
|
+
dbi.should_receive(:select_one).and_return{|var|
|
216
|
+
row
|
217
|
+
}
|
218
|
+
row.should_receive(:first).times(1).and_return { 23 }
|
219
|
+
row.should_receive(:first).times(1).and_return { 23 }
|
220
|
+
assert_equal(23, @storage.max_id)
|
221
|
+
end
|
222
|
+
def test_restore_max_id__nil
|
223
|
+
dbi = flexmock
|
224
|
+
row = flexmock
|
225
|
+
@storage.dbi = dbi
|
226
|
+
dbi.should_receive(:select_one).times(1).and_return{|var|
|
227
|
+
row
|
228
|
+
}
|
229
|
+
row.should_receive(:first).times(1).and_return{ || }
|
230
|
+
id = nil
|
231
|
+
assert_nothing_raised {
|
232
|
+
id = @storage.restore_max_id
|
233
|
+
}
|
234
|
+
assert_equal(0, id)
|
235
|
+
end
|
236
|
+
def test_retrieve
|
237
|
+
dbi = flexmock("dbi")
|
238
|
+
sth = flexmock
|
239
|
+
@storage.dbi = dbi
|
240
|
+
sql = <<-SQL
|
241
|
+
SELECT target_id, COUNT(target_id) AS relevance
|
242
|
+
FROM index
|
243
|
+
WHERE search_term LIKE ?
|
244
|
+
GROUP BY target_id
|
245
|
+
SQL
|
246
|
+
dbi.should_receive(:select_all).with(sql, 'foo%')\
|
247
|
+
.and_return { assert(true) }
|
248
|
+
@storage.retrieve_from_index("index","foo")
|
249
|
+
end
|
250
|
+
def test_retrieve_exact
|
251
|
+
dbi = flexmock("dbi")
|
252
|
+
sth = flexmock
|
253
|
+
@storage.dbi = dbi
|
254
|
+
sql = <<-SQL
|
255
|
+
SELECT target_id, COUNT(target_id) AS relevance
|
256
|
+
FROM index
|
257
|
+
WHERE search_term LIKE ?
|
258
|
+
GROUP BY target_id
|
259
|
+
SQL
|
260
|
+
dbi.should_receive(:select_all).with(sql, 'foo')\
|
261
|
+
.and_return { assert(true) }
|
262
|
+
@storage.retrieve_from_index("index","foo", true)
|
263
|
+
end
|
264
|
+
def test_retrieve_one
|
265
|
+
dbi = flexmock("dbi")
|
266
|
+
sth = flexmock
|
267
|
+
@storage.dbi = dbi
|
268
|
+
sql = <<-SQL << " LIMIT 1"
|
269
|
+
SELECT target_id, COUNT(target_id) AS relevance
|
270
|
+
FROM index
|
271
|
+
WHERE search_term LIKE ?
|
272
|
+
GROUP BY target_id
|
273
|
+
SQL
|
274
|
+
dbi.should_receive(:select_all).with(sql, 'foo%')\
|
275
|
+
.and_return { assert(true) }
|
276
|
+
@storage.retrieve_from_index("index","foo", false, 1)
|
277
|
+
end
|
278
|
+
def test_update_index
|
279
|
+
dbi = flexmock("dbi")
|
280
|
+
rows = [3]
|
281
|
+
@storage.dbi = dbi
|
282
|
+
|
283
|
+
#insert query
|
284
|
+
dbi.should_receive(:do).times(1).and_return{ |sql, id, term, target_id|
|
285
|
+
assert_not_nil(sql.index("INSERT INTO"))
|
286
|
+
}
|
287
|
+
|
288
|
+
@storage.update_index("foo", 2,"baz", 3)
|
289
|
+
end
|
290
|
+
def test_update_index__without_target_id
|
291
|
+
sql = <<-'SQL'
|
292
|
+
UPDATE index SET search_term=?
|
293
|
+
WHERE origin_id=?
|
294
|
+
SQL
|
295
|
+
handle = flexmock('StatementHandle')
|
296
|
+
@dbi.should_receive(:do).with(sql, 'term', 2).times(1).and_return do
|
297
|
+
assert true
|
298
|
+
end
|
299
|
+
@storage.update_index("index", 2, "term", nil)
|
300
|
+
end
|
301
|
+
def test_delete_index_origin
|
302
|
+
dbi = flexmock("dbi")
|
303
|
+
@storage.dbi = dbi
|
304
|
+
expected = <<-SQL
|
305
|
+
DELETE FROM foo
|
306
|
+
WHERE origin_id = ?
|
307
|
+
AND search_term = ?
|
308
|
+
SQL
|
309
|
+
dbi.should_receive(:do).and_return { |sql, id, term|
|
310
|
+
assert_equal(expected, sql)
|
311
|
+
assert_equal(2, id)
|
312
|
+
assert_equal('search-term', term)
|
313
|
+
}
|
314
|
+
@storage.index_delete_origin("foo", 2, 'search-term')
|
315
|
+
end
|
316
|
+
def test_retrieve_connected_objects
|
317
|
+
dbi = flexmock("dbi")
|
318
|
+
@storage.dbi = dbi
|
319
|
+
dbi.should_receive(:select_all).and_return{|sql, target_id|
|
320
|
+
assert_not_nil(sql.index('SELECT origin_id FROM object_connection'))
|
321
|
+
assert_equal(target_id, 1)
|
322
|
+
}
|
323
|
+
@storage.retrieve_connected_objects(1)
|
324
|
+
end
|
325
|
+
def test_index_delete_target
|
326
|
+
dbi = flexmock("dbi")
|
327
|
+
sth = flexmock("sth")
|
328
|
+
@storage.dbi = dbi
|
329
|
+
sql = <<-SQL
|
330
|
+
DELETE FROM foo_index
|
331
|
+
WHERE origin_id = ?
|
332
|
+
AND search_term = ?
|
333
|
+
AND target_id = ?
|
334
|
+
SQL
|
335
|
+
dbi.should_receive(:do).with(sql, 6, 'search-term', 5).times(1).and_return do
|
336
|
+
assert true
|
337
|
+
end
|
338
|
+
@storage.index_delete_target("foo_index", 6, 'search-term', 5)
|
339
|
+
end
|
340
|
+
def test_drop_index
|
341
|
+
dbi = flexmock("dbi")
|
342
|
+
@storage.dbi = dbi
|
343
|
+
sql = "DROP TABLE foo_index"
|
344
|
+
dbi.should_receive(:do).with(sql).and_return do
|
345
|
+
assert true
|
346
|
+
end
|
347
|
+
@storage.drop_index("foo_index")
|
348
|
+
end
|
349
|
+
def test_retrieve_from_fulltext_index
|
350
|
+
dbi = flexmock("dbi")
|
351
|
+
@storage.dbi = dbi
|
352
|
+
dbi.should_receive(:select_all).and_return { |sql, d1, t1, d2, t2|
|
353
|
+
assert_equal('\(+\)-cloprostenolum&natricum', t1)
|
354
|
+
[]
|
355
|
+
}
|
356
|
+
@storage.retrieve_from_fulltext_index('index_name',
|
357
|
+
'(+)-cloprostenolum natricum', 'default_german')
|
358
|
+
end
|
359
|
+
def test_retrieve_from_fulltext_index__2
|
360
|
+
dbi = flexmock("dbi")
|
361
|
+
@storage.dbi = dbi
|
362
|
+
dbi.should_receive(:select_all).and_return { |sql, d1, t1, d2, t2|
|
363
|
+
assert_equal('phenylbutazonum&calcicum&\(2\:1\)', t1)
|
364
|
+
[]
|
365
|
+
}
|
366
|
+
@storage.retrieve_from_fulltext_index('index_name',
|
367
|
+
'phenylbutazonum&calcicum&(2:1)', 'default_german')
|
368
|
+
end
|
369
|
+
def test_retrieve_from_fulltext_index__umlaut
|
370
|
+
dbi = flexmock("dbi")
|
371
|
+
@storage.dbi = dbi
|
372
|
+
dbi.should_receive(:select_all).and_return { |sql, d1, t1, d2, t2|
|
373
|
+
assert_equal('dr�g�es&�hnl�ch&k�mpr�ss�n&�t�', t1)
|
374
|
+
[]
|
375
|
+
}
|
376
|
+
@storage.retrieve_from_fulltext_index('index_name',
|
377
|
+
'dr�g�es �hnl�ch k�mpr�ss�n �t�', 'default_german')
|
378
|
+
end
|
379
|
+
def test_ensure_object_connections
|
380
|
+
dbi = flexmock("dbi")
|
381
|
+
@storage.dbi = dbi
|
382
|
+
sql = <<-SQL
|
383
|
+
SELECT target_id FROM object_connection
|
384
|
+
WHERE origin_id = ?
|
385
|
+
SQL
|
386
|
+
dbi.should_receive(:select_all).with(sql, 123).and_return {
|
387
|
+
assert(true)
|
388
|
+
[[1], [3], [5], [7], [9]]
|
389
|
+
}
|
390
|
+
sql = <<-SQL
|
391
|
+
DELETE FROM object_connection
|
392
|
+
WHERE origin_id = ? AND target_id IN (7,9)
|
393
|
+
SQL
|
394
|
+
dbi.should_receive(:do).with(sql, 123).and_return {
|
395
|
+
assert(true)
|
396
|
+
}
|
397
|
+
sql = <<-SQL
|
398
|
+
INSERT INTO object_connection (origin_id, target_id)
|
399
|
+
VALUES (?, ?)
|
400
|
+
SQL
|
401
|
+
sth = flexmock('sth')
|
402
|
+
dbi.should_receive(:prepare).with(sql).and_return(sth)
|
403
|
+
sth.should_receive(:execute).with(123, 2).times(1).and_return {
|
404
|
+
assert(true)
|
405
|
+
}
|
406
|
+
sth.should_receive(:execute).with(123, 4).times(1).and_return {
|
407
|
+
assert(true)
|
408
|
+
}
|
409
|
+
sth.should_receive(:execute).with(123, 6).times(1).and_return {
|
410
|
+
assert(true)
|
411
|
+
}
|
412
|
+
sth.should_receive(:finish).times(1)
|
413
|
+
@storage.ensure_object_connections(123, [1,2,2,3,4,4,5,6,6])
|
414
|
+
end
|
415
|
+
def test_transaction_returns_blockval_even_if_dbi_does_not
|
416
|
+
@dbi.should_receive(:transaction).and_return { |block|
|
417
|
+
block.call({})
|
418
|
+
false
|
419
|
+
}
|
420
|
+
res = @storage.transaction { "foo" }
|
421
|
+
assert_equal("foo", res)
|
422
|
+
end
|
423
|
+
def test_create_condition_index
|
424
|
+
definition = [
|
425
|
+
[:foo, 'Integer'],
|
426
|
+
[:bar, 'Date'],
|
427
|
+
]
|
428
|
+
sql = <<-'SQL'
|
429
|
+
CREATE TABLE conditions (
|
430
|
+
origin_id INTEGER,
|
431
|
+
foo Integer,
|
432
|
+
bar Date,
|
433
|
+
target_id INTEGER
|
434
|
+
);
|
435
|
+
SQL
|
436
|
+
@dbi.should_receive(:do).with(sql).and_return do
|
437
|
+
assert true
|
438
|
+
end
|
439
|
+
sql = <<-'SQL'
|
440
|
+
CREATE INDEX origin_id_conditions ON conditions(origin_id);
|
441
|
+
SQL
|
442
|
+
@dbi.should_receive(:do).with(sql).and_return do
|
443
|
+
assert true
|
444
|
+
end
|
445
|
+
sql = <<-'SQL'
|
446
|
+
CREATE INDEX foo_conditions ON conditions(foo);
|
447
|
+
SQL
|
448
|
+
@dbi.should_receive(:do).with(sql).and_return do
|
449
|
+
assert true
|
450
|
+
end
|
451
|
+
sql = <<-'SQL'
|
452
|
+
CREATE INDEX bar_conditions ON conditions(bar);
|
453
|
+
SQL
|
454
|
+
@dbi.should_receive(:do).with(sql).and_return do
|
455
|
+
assert true
|
456
|
+
end
|
457
|
+
sql = <<-'SQL'
|
458
|
+
CREATE INDEX target_id_conditions ON conditions(target_id);
|
459
|
+
SQL
|
460
|
+
@dbi.should_receive(:do).with(sql).and_return do
|
461
|
+
assert true
|
462
|
+
end
|
463
|
+
@storage.create_condition_index('conditions', definition)
|
464
|
+
end
|
465
|
+
def test_create_fulltext_index
|
466
|
+
sql = <<-'SQL'
|
467
|
+
CREATE TABLE fulltext (
|
468
|
+
origin_id INTEGER,
|
469
|
+
search_term tsvector,
|
470
|
+
target_id INTEGER
|
471
|
+
);
|
472
|
+
SQL
|
473
|
+
statement = flexmock('StatementHandle')
|
474
|
+
@dbi.should_receive(:do).with(sql).and_return do
|
475
|
+
assert true
|
476
|
+
end
|
477
|
+
sql = <<-'SQL'
|
478
|
+
CREATE INDEX origin_id_fulltext ON fulltext(origin_id);
|
479
|
+
SQL
|
480
|
+
@dbi.should_receive(:do).with(sql).and_return do
|
481
|
+
assert true
|
482
|
+
end
|
483
|
+
sql = <<-'SQL'
|
484
|
+
CREATE INDEX search_term_fulltext
|
485
|
+
ON fulltext USING gist(search_term);
|
486
|
+
SQL
|
487
|
+
@dbi.should_receive(:do).with(sql).and_return do
|
488
|
+
assert true
|
489
|
+
end
|
490
|
+
sql = <<-'SQL'
|
491
|
+
CREATE INDEX target_id_fulltext ON fulltext(target_id);
|
492
|
+
SQL
|
493
|
+
@dbi.should_receive(:do).with(sql).and_return do
|
494
|
+
assert true
|
495
|
+
end
|
496
|
+
@storage.create_fulltext_index('fulltext')
|
497
|
+
end
|
498
|
+
def test_extent_ids
|
499
|
+
sql = <<-'SQL'
|
500
|
+
SELECT odba_id FROM object WHERE extent = ?
|
501
|
+
SQL
|
502
|
+
@dbi.should_receive(:select_all).with(sql, 'Object').and_return {
|
503
|
+
[[1], [2], [3], [4], [5]]
|
504
|
+
}
|
505
|
+
expected = [1,2,3,4,5]
|
506
|
+
assert_equal(expected, @storage.extent_ids(Object))
|
507
|
+
end
|
508
|
+
def test_collection_fetch
|
509
|
+
sql = <<-'SQL'
|
510
|
+
SELECT value FROM collection
|
511
|
+
WHERE odba_id = ? AND key = ?
|
512
|
+
SQL
|
513
|
+
@dbi.should_receive(:select_one).with(sql, 34, 'key_dump').and_return {
|
514
|
+
["dump"]
|
515
|
+
}
|
516
|
+
assert_equal("dump", @storage.collection_fetch(34, "key_dump"))
|
517
|
+
end
|
518
|
+
def test_collection_remove
|
519
|
+
sql = <<-'SQL'
|
520
|
+
DELETE FROM collection
|
521
|
+
WHERE odba_id = ? AND key = ?
|
522
|
+
SQL
|
523
|
+
statement = flexmock('StatementHandle')
|
524
|
+
@dbi.should_receive(:do).with(sql, 34, 'key_dump').and_return do
|
525
|
+
assert true
|
526
|
+
end
|
527
|
+
@storage.collection_remove(34, "key_dump")
|
528
|
+
end
|
529
|
+
def test_collection_store
|
530
|
+
sql = <<-'SQL'
|
531
|
+
INSERT INTO collection (odba_id, key, value)
|
532
|
+
VALUES (?, ?, ?)
|
533
|
+
SQL
|
534
|
+
statement = flexmock('StatementHandle')
|
535
|
+
@dbi.should_receive(:do).with(sql, 34, 'key_dump', 'dump').and_return do
|
536
|
+
assert true
|
537
|
+
end
|
538
|
+
@storage.collection_store(34, "key_dump", 'dump')
|
539
|
+
end
|
540
|
+
def test_index_fetch_keys
|
541
|
+
sql = <<-'SQL'
|
542
|
+
SELECT DISTINCT search_term AS key
|
543
|
+
FROM index
|
544
|
+
ORDER BY key
|
545
|
+
SQL
|
546
|
+
@dbi.should_receive(:select_all).with(sql).and_return {
|
547
|
+
[['key1'], ['key2'], ['key3']]
|
548
|
+
}
|
549
|
+
assert_equal(%w{key1 key2 key3},
|
550
|
+
@storage.index_fetch_keys('index'))
|
551
|
+
sql = <<-'SQL'
|
552
|
+
SELECT DISTINCT substr(search_term, 1, 2) AS key
|
553
|
+
FROM index
|
554
|
+
ORDER BY key
|
555
|
+
SQL
|
556
|
+
@dbi.should_receive(:select_all).with(sql).and_return {
|
557
|
+
[['k1'], ['k2'], ['k3']]
|
558
|
+
}
|
559
|
+
assert_equal(%w{k1 k2 k3},
|
560
|
+
@storage.index_fetch_keys('index', 2))
|
561
|
+
end
|
562
|
+
def test_index_target_ids
|
563
|
+
sql = <<-'SQL'
|
564
|
+
SELECT DISTINCT target_id, search_term
|
565
|
+
FROM index
|
566
|
+
WHERE origin_id=?
|
567
|
+
SQL
|
568
|
+
@dbi.should_receive(:select_all).with(sql, 5).and_return {
|
569
|
+
[[1, 'search-term'], [2, 'search-term'], [3, 'search-term']]
|
570
|
+
}
|
571
|
+
expected = [[1, 'search-term'], [2, 'search-term'], [3, 'search-term']]
|
572
|
+
assert_equal(expected, @storage.index_target_ids('index', 5))
|
573
|
+
end
|
574
|
+
def test_retrieve_from_condition_index
|
575
|
+
sql = <<-'SQL'
|
576
|
+
SELECT target_id, COUNT(target_id) AS relevance
|
577
|
+
FROM index
|
578
|
+
WHERE TRUE
|
579
|
+
AND cond1 = ?
|
580
|
+
AND cond2 IS NULL
|
581
|
+
AND cond3 LIKE ?
|
582
|
+
AND cond4 > ?
|
583
|
+
GROUP BY target_id
|
584
|
+
SQL
|
585
|
+
@dbi.should_receive(:select_all)\
|
586
|
+
.with(sql, 'foo', 'bar%', '5').and_return {
|
587
|
+
assert(true)
|
588
|
+
}
|
589
|
+
conds = [
|
590
|
+
['cond1', 'foo'],
|
591
|
+
['cond2', nil],
|
592
|
+
['cond3', {'condition' => 'LIKE', 'value' => 'bar'}],
|
593
|
+
['cond4', {'condition' => '>', 'value' => 5}],
|
594
|
+
]
|
595
|
+
@storage.retrieve_from_condition_index('index', conds)
|
596
|
+
sql << ' LIMIT 1'
|
597
|
+
@dbi.should_receive(:select_all)\
|
598
|
+
.with(sql, 'foo', 'bar%', 5).and_return {
|
599
|
+
assert(true)
|
600
|
+
}
|
601
|
+
@storage.retrieve_from_condition_index('index', conds, 1)
|
602
|
+
end
|
603
|
+
def test_setup__object
|
604
|
+
tables = %w{object_connection collection}
|
605
|
+
@dbi.should_receive(:tables).and_return(tables)
|
606
|
+
sql = <<-'SQL'
|
607
|
+
CREATE TABLE object (
|
608
|
+
odba_id INTEGER NOT NULL, content TEXT,
|
609
|
+
name TEXT, prefetchable BOOLEAN, extent TEXT,
|
610
|
+
PRIMARY KEY(odba_id), UNIQUE(name)
|
611
|
+
);
|
612
|
+
CREATE INDEX prefetchable_index ON object(prefetchable);
|
613
|
+
CREATE INDEX extent_index ON object(extent);
|
614
|
+
SQL
|
615
|
+
@dbi.should_receive(:execute).with(sql).and_return {
|
616
|
+
assert(true) }
|
617
|
+
col = flexmock('Column')
|
618
|
+
col.should_receive(:name).and_return('extent')
|
619
|
+
@dbi.should_receive(:columns).and_return([col])
|
620
|
+
@storage.setup
|
621
|
+
end
|
622
|
+
def test_setup__object_connection
|
623
|
+
tables = %w{object collection}
|
624
|
+
@dbi.should_receive(:tables).and_return(tables)
|
625
|
+
sql = <<-'SQL'
|
626
|
+
CREATE TABLE object_connection (
|
627
|
+
origin_id integer, target_id integer,
|
628
|
+
PRIMARY KEY(origin_id, target_id)
|
629
|
+
);
|
630
|
+
CREATE INDEX target_id_index ON object_connection(target_id);
|
631
|
+
SQL
|
632
|
+
@dbi.should_receive(:execute).with(sql).and_return {
|
633
|
+
assert(true) }
|
634
|
+
col = flexmock('Column')
|
635
|
+
col.should_receive(:name).and_return('extent')
|
636
|
+
@dbi.should_receive(:columns).and_return([col])
|
637
|
+
@storage.setup
|
638
|
+
end
|
639
|
+
def test_setup__collection
|
640
|
+
tables = %w{object object_connection}
|
641
|
+
@dbi.should_receive(:tables).and_return(tables)
|
642
|
+
sql = <<-'SQL'
|
643
|
+
CREATE TABLE collection (
|
644
|
+
odba_id integer NOT NULL, key text, value text,
|
645
|
+
PRIMARY KEY(odba_id, key)
|
646
|
+
);
|
647
|
+
SQL
|
648
|
+
@dbi.should_receive(:execute).with(sql).and_return {
|
649
|
+
assert(true) }
|
650
|
+
col = flexmock('Column')
|
651
|
+
col.should_receive(:name).and_return('extent')
|
652
|
+
@dbi.should_receive(:columns).and_return([col])
|
653
|
+
@storage.setup
|
654
|
+
end
|
655
|
+
def test_setup__extent
|
656
|
+
tables = %w{object object_connection collection}
|
657
|
+
@dbi.should_receive(:tables).and_return(tables)
|
658
|
+
sql = <<-'SQL'
|
659
|
+
ALTER TABLE object ADD COLUMN extent TEXT;
|
660
|
+
CREATE INDEX extent_index ON object(extent);
|
661
|
+
SQL
|
662
|
+
@dbi.should_receive(:do).with(sql).and_return {
|
663
|
+
assert(true) }
|
664
|
+
@dbi.should_receive(:columns).and_return([])
|
665
|
+
@storage.setup
|
666
|
+
end
|
667
|
+
def test_update_condition_index__with_target_id
|
668
|
+
handle = flexmock('StatementHandle')
|
669
|
+
sql = <<-'SQL'
|
670
|
+
INSERT INTO index (origin_id, target_id, foo, bar)
|
671
|
+
VALUES (?, ?, ?, ?)
|
672
|
+
SQL
|
673
|
+
@dbi.should_receive(:do).with(sql, 12, 15, 14, 'blur').times(1).and_return {
|
674
|
+
assert(true)
|
675
|
+
}
|
676
|
+
terms = [
|
677
|
+
['foo', 14],
|
678
|
+
['bar', 'blur'],
|
679
|
+
]
|
680
|
+
@storage.update_condition_index('index', 12, terms, 15)
|
681
|
+
end
|
682
|
+
def test_update_condition_index__without_target_id
|
683
|
+
handle = flexmock('StatementHandle')
|
684
|
+
sql = <<-'SQL'
|
685
|
+
UPDATE index SET foo=?, bar=?
|
686
|
+
WHERE origin_id = ?
|
687
|
+
SQL
|
688
|
+
@dbi.should_receive(:do).with(sql, 14, 'blur', 12).times(1).and_return {
|
689
|
+
assert(true)
|
690
|
+
}
|
691
|
+
terms = [
|
692
|
+
['foo', 14],
|
693
|
+
['bar', 'blur'],
|
694
|
+
]
|
695
|
+
@storage.update_condition_index('index', 12, terms, nil)
|
696
|
+
end
|
697
|
+
def test_update_fulltext_index__with_target_id
|
698
|
+
handle = flexmock('StatementHandle')
|
699
|
+
sql = <<-'SQL'
|
700
|
+
INSERT INTO index (origin_id, search_term, target_id)
|
701
|
+
VALUES (?, to_tsvector(?, ?), ?)
|
702
|
+
SQL
|
703
|
+
@dbi.should_receive(:do).with(sql, 12, "german", "some text",
|
704
|
+
15).and_return {
|
705
|
+
assert(true)
|
706
|
+
}
|
707
|
+
@storage.update_fulltext_index('index', 12, "some text", 15,
|
708
|
+
'german')
|
709
|
+
end
|
710
|
+
def test_update_fulltext_index__without_target_id
|
711
|
+
handle = flexmock('StatementHandle')
|
712
|
+
sql = <<-'SQL'
|
713
|
+
UPDATE index SET search_term=to_tsvector(?, ?)
|
714
|
+
WHERE origin_id=?
|
715
|
+
SQL
|
716
|
+
@dbi.should_receive(:do).with(sql, "german", "some text",
|
717
|
+
12).and_return {
|
718
|
+
assert(true)
|
719
|
+
}
|
720
|
+
@storage.update_fulltext_index('index', 12, "some text", nil,
|
721
|
+
'german')
|
722
|
+
end
|
723
|
+
def test_condition_index_delete
|
724
|
+
sql = <<-SQL
|
725
|
+
DELETE FROM index WHERE origin_id = ? AND c1 = ? AND c2 = ?
|
726
|
+
SQL
|
727
|
+
handle = flexmock('DBHandle')
|
728
|
+
@dbi.should_receive(:do).with(sql.chomp, 3, 'f', 7)\
|
729
|
+
.times(1).and_return { assert(true) }
|
730
|
+
@storage.condition_index_delete('index', 3, {'c1' => 'f','c2' => 7})
|
731
|
+
end
|
732
|
+
def test_condition_index_delete__with_target_id
|
733
|
+
sql = <<-SQL
|
734
|
+
DELETE FROM index WHERE origin_id = ? AND c1 = ? AND c2 = ? AND target_id = ?
|
735
|
+
SQL
|
736
|
+
handle = flexmock('DBHandle')
|
737
|
+
@dbi.should_receive(:do).with(sql.chomp, 3, 'f', 7, 4)\
|
738
|
+
.times(1).and_return { assert(true) }
|
739
|
+
@storage.condition_index_delete('index', 3, {'c1' => 'f','c2' => 7}, 4)
|
740
|
+
end
|
741
|
+
def test_condition_index_ids__origin_id
|
742
|
+
sql = <<-SQL
|
743
|
+
SELECT DISTINCT *
|
744
|
+
FROM index
|
745
|
+
WHERE origin_id=?
|
746
|
+
SQL
|
747
|
+
@dbi.should_receive(:select_all).with(sql, 5)\
|
748
|
+
.times(1).and_return { assert(true) }
|
749
|
+
@storage.condition_index_ids('index', 5, 'origin_id')
|
750
|
+
end
|
751
|
+
def test_condition_index_ids__target_id
|
752
|
+
sql = <<-SQL
|
753
|
+
SELECT DISTINCT *
|
754
|
+
FROM index
|
755
|
+
WHERE target_id=?
|
756
|
+
SQL
|
757
|
+
@dbi.should_receive(:select_all).with(sql, 5)\
|
758
|
+
.times(1).and_return { assert(true) }
|
759
|
+
@storage.condition_index_ids('index', 5, 'target_id')
|
760
|
+
end
|
761
|
+
def test_ensure_target_id_index
|
762
|
+
sql = <<-SQL
|
763
|
+
CREATE INDEX target_id_index
|
764
|
+
ON index(target_id)
|
765
|
+
SQL
|
766
|
+
@dbi.should_receive(:execute).with(sql).and_return {
|
767
|
+
raise DBI::Error }
|
768
|
+
assert_nothing_raised {
|
769
|
+
@storage.ensure_target_id_index('index')
|
770
|
+
}
|
771
|
+
end
|
772
|
+
def test_fulltext_index_delete__origin
|
773
|
+
sql = <<-SQL
|
774
|
+
DELETE FROM index
|
775
|
+
WHERE origin_id = ?
|
776
|
+
SQL
|
777
|
+
@dbi.should_receive(:do).with(sql, 4)\
|
778
|
+
.times(1).and_return { assert(true) }
|
779
|
+
@storage.fulltext_index_delete('index', 4, 'origin_id')
|
780
|
+
end
|
781
|
+
def test_fulltext_index_delete__target
|
782
|
+
sql = <<-SQL
|
783
|
+
DELETE FROM index
|
784
|
+
WHERE target_id = ?
|
785
|
+
SQL
|
786
|
+
@dbi.should_receive(:do).with(sql, 4)\
|
787
|
+
.times(1).and_return { assert(true) }
|
788
|
+
@storage.fulltext_index_delete('index', 4, 'target_id')
|
789
|
+
end
|
790
|
+
def test_fulltext_index_target_ids
|
791
|
+
sql = <<-SQL
|
792
|
+
SELECT DISTINCT target_id
|
793
|
+
FROM index
|
794
|
+
WHERE origin_id=?
|
795
|
+
SQL
|
796
|
+
@dbi.should_receive(:select_all).with(sql, 4)\
|
797
|
+
.times(1).and_return { assert(true) }
|
798
|
+
@storage.fulltext_index_target_ids('index', 4)
|
799
|
+
end
|
800
|
+
def test_index_origin_ids
|
801
|
+
sql = <<-SQL
|
802
|
+
SELECT DISTINCT origin_id, search_term
|
803
|
+
FROM index
|
804
|
+
WHERE target_id=?
|
805
|
+
SQL
|
806
|
+
@dbi.should_receive(:select_all).with(sql, 4)\
|
807
|
+
.times(1).and_return { assert(true) }
|
808
|
+
@storage.index_origin_ids('index', 4)
|
809
|
+
end
|
810
|
+
def test_delete_index_element__origin
|
811
|
+
handle = flexmock('DB-Handle')
|
812
|
+
@dbi.should_receive(:do).with(<<-SQL, 15).times(1).and_return {
|
813
|
+
DELETE FROM index WHERE origin_id = ?
|
814
|
+
SQL
|
815
|
+
assert(true)
|
816
|
+
}
|
817
|
+
@storage.delete_index_element('index', 15, 'origin_id')
|
818
|
+
end
|
819
|
+
def test_delete_index_element__target
|
820
|
+
handle = flexmock('DB-Handle')
|
821
|
+
@dbi.should_receive(:do).with(<<-SQL, 15).times(1).and_return {
|
822
|
+
DELETE FROM index WHERE target_id = ?
|
823
|
+
SQL
|
824
|
+
assert(true)
|
825
|
+
}
|
826
|
+
@storage.delete_index_element('index', 15, 'target_id')
|
827
|
+
end
|
828
|
+
end
|
829
|
+
end
|