lmdb 0.7.5 → 0.8.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/ext/lmdb_ext/extconf.rb +2 -0
- data/ext/lmdb_ext/lmdb_ext.c +1379 -912
- data/ext/lmdb_ext/lmdb_ext.h +36 -19
- data/lib/lmdb/version.rb +1 -1
- data/spec/gc_torture_spec.rb +162 -0
- data/spec/helper.rb +3 -3
- data/spec/lmdb_spec.rb +144 -137
- data/spec/pseudo_transactions_spec.rb +237 -0
- metadata +6 -2
data/spec/lmdb_spec.rb
CHANGED
|
@@ -8,107 +8,108 @@ describe LMDB do
|
|
|
8
8
|
let(:db) { env.database }
|
|
9
9
|
|
|
10
10
|
it 'has version constants' do
|
|
11
|
-
LMDB::LIB_VERSION_MAJOR.
|
|
12
|
-
LMDB::LIB_VERSION_MINOR.
|
|
13
|
-
LMDB::LIB_VERSION_PATCH.
|
|
14
|
-
LMDB::LIB_VERSION.
|
|
15
|
-
LMDB::VERSION.
|
|
11
|
+
expect(LMDB::LIB_VERSION_MAJOR).to be_instance_of(Integer)
|
|
12
|
+
expect(LMDB::LIB_VERSION_MINOR).to be_instance_of(Integer)
|
|
13
|
+
expect(LMDB::LIB_VERSION_PATCH).to be_instance_of(Integer)
|
|
14
|
+
expect(LMDB::LIB_VERSION).to be_instance_of(String)
|
|
15
|
+
expect(LMDB::VERSION).to be_instance_of(String)
|
|
16
16
|
end
|
|
17
17
|
|
|
18
18
|
describe LMDB::Environment do
|
|
19
19
|
subject { env }
|
|
20
20
|
|
|
21
21
|
it 'should return flags' do
|
|
22
|
-
subject.flags.
|
|
22
|
+
expect(subject.flags).to be_instance_of(Array)
|
|
23
23
|
end
|
|
24
24
|
|
|
25
25
|
describe 'new' do
|
|
26
26
|
it 'returns environment' do
|
|
27
27
|
env = LMDB::Environment.new(path)
|
|
28
|
-
env.
|
|
28
|
+
expect(env).to be_instance_of(described_class)
|
|
29
29
|
env.close
|
|
30
30
|
end
|
|
31
31
|
|
|
32
32
|
it 'accepts block' do
|
|
33
|
-
LMDB::Environment.new(path) do |env|
|
|
34
|
-
env.
|
|
33
|
+
out = LMDB::Environment.new(path) do |env|
|
|
34
|
+
expect(env).to be_instance_of(described_class)
|
|
35
35
|
42
|
|
36
|
-
end
|
|
36
|
+
end
|
|
37
|
+
expect(out).to eq(42)
|
|
37
38
|
end
|
|
38
39
|
|
|
39
40
|
it 'accepts options' do
|
|
40
41
|
env = LMDB::Environment.new(path, nosync: true, mode: 0777,
|
|
41
42
|
maxreaders: 777, mapsize: 111111, maxdbs: 666)
|
|
42
|
-
env.
|
|
43
|
-
env.info[:maxreaders].
|
|
44
|
-
env.info[:mapsize].
|
|
45
|
-
env.flags.
|
|
43
|
+
expect(env).to be_instance_of(described_class)
|
|
44
|
+
expect(env.info[:maxreaders]).to eq(777)
|
|
45
|
+
expect(env.info[:mapsize]).to eq(111111)
|
|
46
|
+
expect(env.flags.include? :nosync).to be_truthy
|
|
46
47
|
env.close
|
|
47
48
|
|
|
48
|
-
env = LMDB::Environment.new(path, :
|
|
49
|
-
env.flags.
|
|
49
|
+
env = LMDB::Environment.new(path, nosync: false)
|
|
50
|
+
expect(env.flags.include? :nosync).to be_falsy
|
|
50
51
|
env.close
|
|
51
52
|
end
|
|
52
53
|
end
|
|
53
54
|
|
|
54
55
|
it 'should return stat' do
|
|
55
56
|
stat = env.stat
|
|
56
|
-
stat[:psize].
|
|
57
|
-
stat[:depth].
|
|
58
|
-
stat[:branch_pages].
|
|
59
|
-
stat[:leaf_pages].
|
|
60
|
-
stat[:overflow_pages].
|
|
61
|
-
stat[:entries].
|
|
57
|
+
expect(stat[:psize]).to be_instance_of(Integer)
|
|
58
|
+
expect(stat[:depth]).to be_instance_of(Integer)
|
|
59
|
+
expect(stat[:branch_pages]).to be_instance_of(Integer)
|
|
60
|
+
expect(stat[:leaf_pages]).to be_instance_of(Integer)
|
|
61
|
+
expect(stat[:overflow_pages]).to be_instance_of(Integer)
|
|
62
|
+
expect(stat[:entries]).to be_instance_of(Integer)
|
|
62
63
|
end
|
|
63
64
|
|
|
64
65
|
it 'should return info' do
|
|
65
66
|
info = env.info
|
|
66
|
-
info[:mapaddr].
|
|
67
|
-
info[:mapsize].
|
|
68
|
-
info[:last_pgno].
|
|
69
|
-
info[:last_txnid].
|
|
70
|
-
info[:maxreaders].
|
|
71
|
-
info[:numreaders].
|
|
67
|
+
expect(info[:mapaddr]).to be_instance_of(Integer)
|
|
68
|
+
expect(info[:mapsize]).to be_instance_of(Integer)
|
|
69
|
+
expect(info[:last_pgno]).to be_instance_of(Integer)
|
|
70
|
+
expect(info[:last_txnid]).to be_instance_of(Integer)
|
|
71
|
+
expect(info[:maxreaders]).to be_instance_of(Integer)
|
|
72
|
+
expect(info[:numreaders]).to be_instance_of(Integer)
|
|
72
73
|
end
|
|
73
74
|
|
|
74
75
|
it 'should set mapsize' do
|
|
75
76
|
size_before = env.info[:mapsize]
|
|
76
77
|
env.mapsize = size_before * 2
|
|
77
|
-
env.info[:mapsize].
|
|
78
|
+
expect(env.info[:mapsize]).to eq(size_before * 2)
|
|
78
79
|
end
|
|
79
80
|
|
|
80
81
|
it 'should copy' do
|
|
81
82
|
target = mkpath('copy')
|
|
82
|
-
subject.copy(target).
|
|
83
|
+
expect(subject.copy(target)).to be_nil
|
|
83
84
|
end
|
|
84
85
|
|
|
85
86
|
it 'should sync' do
|
|
86
|
-
subject.sync.
|
|
87
|
+
expect(subject.sync).to be_nil
|
|
87
88
|
end
|
|
88
89
|
|
|
89
90
|
it 'should force-sync' do
|
|
90
|
-
subject.sync(true).
|
|
91
|
+
expect(subject.sync(true)).to be_nil
|
|
91
92
|
end
|
|
92
93
|
|
|
93
94
|
it 'should accept custom flags' do
|
|
94
|
-
subject.flags.
|
|
95
|
+
expect(subject.flags.include? :nosync).to be_falsy
|
|
95
96
|
|
|
96
97
|
subject.set_flags :nosync
|
|
97
|
-
subject.flags.
|
|
98
|
+
expect(subject.flags.include? :nosync).to be_truthy
|
|
98
99
|
|
|
99
100
|
subject.clear_flags :nosync
|
|
100
|
-
subject.flags.
|
|
101
|
+
expect(subject.flags.include? :nosync).to be_falsy
|
|
101
102
|
end
|
|
102
103
|
|
|
103
104
|
describe 'databases' do
|
|
104
105
|
it 'returns empty list when there are no named databases' do
|
|
105
|
-
subject.databases.
|
|
106
|
+
expect(subject.databases).to eq([])
|
|
106
107
|
end
|
|
107
108
|
|
|
108
109
|
it 'returns list of named databases' do
|
|
109
110
|
db1 = subject.database 'db1', create: true
|
|
110
111
|
db2 = subject.database 'db2', create: true
|
|
111
|
-
subject.databases.
|
|
112
|
+
expect(subject.databases).to eq(['db1', 'db2'])
|
|
112
113
|
end
|
|
113
114
|
|
|
114
115
|
it 'returns list of named databases when there are non-database kes in the main db' do
|
|
@@ -117,7 +118,7 @@ describe LMDB do
|
|
|
117
118
|
subject.database 'db1', create: true
|
|
118
119
|
subject.database 'db2', create: true
|
|
119
120
|
|
|
120
|
-
subject.databases.
|
|
121
|
+
expect(subject.databases).to eq(['db1', 'db2'])
|
|
121
122
|
end
|
|
122
123
|
end
|
|
123
124
|
|
|
@@ -125,71 +126,71 @@ describe LMDB do
|
|
|
125
126
|
subject { env }
|
|
126
127
|
|
|
127
128
|
it 'should create transactions' do
|
|
128
|
-
subject.active_txn.
|
|
129
|
+
expect(subject.active_txn).to be_nil
|
|
129
130
|
subject.transaction do |txn|
|
|
130
|
-
subject.active_txn.
|
|
131
|
-
txn.
|
|
131
|
+
expect(subject.active_txn).to eq(txn)
|
|
132
|
+
expect(txn).to be_instance_of(described_class)
|
|
132
133
|
txn.abort
|
|
133
|
-
subject.active_txn.
|
|
134
|
+
expect(subject.active_txn).to be_nil
|
|
134
135
|
end
|
|
135
|
-
subject.active_txn.
|
|
136
|
+
expect(subject.active_txn).to be_nil
|
|
136
137
|
end
|
|
137
138
|
|
|
138
139
|
it 'should create read-only transactions' do
|
|
139
|
-
subject.active_txn.
|
|
140
|
+
expect(subject.active_txn).to be_nil
|
|
140
141
|
subject.transaction(true) do |txn|
|
|
141
|
-
subject.active_txn.
|
|
142
|
-
txn.
|
|
142
|
+
expect(subject.active_txn).to eq(txn)
|
|
143
|
+
expect(txn).to be_instance_of(described_class)
|
|
143
144
|
txn.abort
|
|
144
|
-
subject.active_txn.
|
|
145
|
+
expect(subject.active_txn).to be_nil
|
|
145
146
|
end
|
|
146
|
-
subject.active_txn.
|
|
147
|
+
expect(subject.active_txn).to be_nil
|
|
147
148
|
end
|
|
148
149
|
|
|
149
150
|
it 'can create child transactions' do
|
|
150
|
-
subject.active_txn.
|
|
151
|
+
expect(subject.active_txn).to be_nil
|
|
151
152
|
env.transaction do |txn|
|
|
152
|
-
subject.active_txn.
|
|
153
|
+
expect(subject.active_txn).to eq(txn)
|
|
153
154
|
env.transaction do |ctxn|
|
|
154
|
-
subject.active_txn.
|
|
155
|
+
expect(subject.active_txn).to eq(ctxn)
|
|
155
156
|
ctxn.abort
|
|
156
|
-
subject.active_txn.
|
|
157
|
+
expect(subject.active_txn).to eq(txn)
|
|
157
158
|
end
|
|
158
|
-
subject.active_txn.
|
|
159
|
+
expect(subject.active_txn).to eq(txn)
|
|
159
160
|
end
|
|
160
|
-
subject.active_txn.
|
|
161
|
+
expect(subject.active_txn).to be_nil
|
|
161
162
|
end
|
|
162
163
|
|
|
163
164
|
it 'should support aborting parent transaction' do
|
|
164
|
-
subject.active_txn.
|
|
165
|
+
expect(subject.active_txn).to be_nil
|
|
165
166
|
env.transaction do |txn|
|
|
166
|
-
subject.active_txn.
|
|
167
|
+
expect(subject.active_txn).to eq(txn)
|
|
167
168
|
env.transaction do |ctxn|
|
|
168
|
-
subject.active_txn.
|
|
169
|
+
expect(subject.active_txn).to eq(ctxn)
|
|
169
170
|
db['key'] = 'value'
|
|
170
171
|
txn.abort
|
|
171
|
-
subject.active_txn.
|
|
172
|
+
expect(subject.active_txn).to be_nil
|
|
172
173
|
end
|
|
173
|
-
subject.active_txn.
|
|
174
|
+
expect(subject.active_txn).to be_nil
|
|
174
175
|
end
|
|
175
|
-
db['key'].
|
|
176
|
-
subject.active_txn.
|
|
176
|
+
expect(db['key']).to be_nil
|
|
177
|
+
expect(subject.active_txn).to be_nil
|
|
177
178
|
end
|
|
178
179
|
|
|
179
180
|
it 'should support comitting parent transaction' do
|
|
180
|
-
subject.active_txn.
|
|
181
|
+
expect(subject.active_txn).to be_nil
|
|
181
182
|
env.transaction do |txn|
|
|
182
|
-
subject.active_txn.
|
|
183
|
+
expect(subject.active_txn).to eq(txn)
|
|
183
184
|
env.transaction do |ctxn|
|
|
184
|
-
subject.active_txn.
|
|
185
|
+
expect(subject.active_txn).to eq(ctxn)
|
|
185
186
|
db['key'] = 'value'
|
|
186
187
|
txn.commit
|
|
187
|
-
subject.active_txn.
|
|
188
|
+
expect(subject.active_txn).to be_nil
|
|
188
189
|
end
|
|
189
|
-
subject.active_txn.
|
|
190
|
+
expect(subject.active_txn).to be_nil
|
|
190
191
|
end
|
|
191
|
-
db['key'].
|
|
192
|
-
subject.active_txn.
|
|
192
|
+
expect(db['key']).to eq('value')
|
|
193
|
+
expect(subject.active_txn).to be_nil
|
|
193
194
|
end
|
|
194
195
|
|
|
195
196
|
it 'should get environment' do
|
|
@@ -197,7 +198,7 @@ describe LMDB do
|
|
|
197
198
|
env.transaction do |txn|
|
|
198
199
|
env2 = txn.env
|
|
199
200
|
end
|
|
200
|
-
env2.
|
|
201
|
+
expect(env2).to eq(env)
|
|
201
202
|
end
|
|
202
203
|
end
|
|
203
204
|
end
|
|
@@ -206,9 +207,9 @@ describe LMDB do
|
|
|
206
207
|
subject { db }
|
|
207
208
|
|
|
208
209
|
it 'should return flags' do
|
|
209
|
-
subject.flags.
|
|
210
|
-
subject.dupsort
|
|
211
|
-
subject.dupfixed
|
|
210
|
+
expect(subject.flags).to be_instance_of(Hash)
|
|
211
|
+
expect(subject.dupsort?).to be_falsy
|
|
212
|
+
expect(subject.dupfixed?).to be_falsy
|
|
212
213
|
end
|
|
213
214
|
|
|
214
215
|
it 'should support named databases' do
|
|
@@ -218,63 +219,69 @@ describe LMDB do
|
|
|
218
219
|
db1 = env.database 'db1', create: true # actually no it doesn't wtf
|
|
219
220
|
db2 = env.database 'db2', **dbopts
|
|
220
221
|
|
|
222
|
+
# this should not crash
|
|
223
|
+
expect(env[:db1].size).to eq(0)
|
|
224
|
+
|
|
221
225
|
main['key'] = '1'
|
|
222
226
|
db1['key'] = '2'
|
|
223
227
|
db2['key'] = '3'
|
|
224
228
|
|
|
225
|
-
main['key'].
|
|
226
|
-
db1['key'].
|
|
227
|
-
db2['key'].
|
|
229
|
+
expect(main['key']).to eq(?1)
|
|
230
|
+
expect(db1['key']).to eq(?2)
|
|
231
|
+
expect(db2['key']).to eq(?3)
|
|
228
232
|
end
|
|
229
233
|
|
|
230
234
|
it 'should get/put data' do
|
|
231
|
-
subject.get
|
|
232
|
-
subject.put
|
|
233
|
-
subject.get
|
|
235
|
+
expect(subject.get 'cat').to be_nil
|
|
236
|
+
expect(subject.put 'cat', 'garfield').to be_nil
|
|
237
|
+
expect(subject.get 'cat').to eq('garfield')
|
|
234
238
|
|
|
235
239
|
# check for key-value pairs on non-dupsort database
|
|
236
|
-
subject.has?
|
|
237
|
-
subject.has?
|
|
240
|
+
expect(subject.has? 'cat', 'garfield').to be_truthy
|
|
241
|
+
expect(subject.has? 'cat', 'heathcliff').to be_falsy
|
|
238
242
|
|
|
239
243
|
subject.put?('dog', 'odie')
|
|
240
|
-
subject.has?
|
|
244
|
+
expect(subject.has? 'dog', 'odie').to be_truthy
|
|
241
245
|
end
|
|
242
246
|
|
|
243
247
|
it 'should delete by key' do
|
|
244
|
-
|
|
245
|
-
|
|
248
|
+
expect { subject.delete('cat') }.to raise_error(LMDB::Error::NOTFOUND)
|
|
249
|
+
expect {
|
|
250
|
+
subject.delete 'cat', 'garfield'
|
|
251
|
+
}.to raise_error(LMDB::Error::NOTFOUND)
|
|
246
252
|
|
|
247
253
|
subject.put('cat', 'garfield')
|
|
248
|
-
subject.delete
|
|
249
|
-
|
|
254
|
+
expect(subject.delete 'cat').to be_nil
|
|
255
|
+
expect { subject.delete 'cat' }.to raise_error(LMDB::Error::NOTFOUND)
|
|
250
256
|
|
|
251
257
|
subject.put('cat', 'garfield')
|
|
252
|
-
subject.delete
|
|
253
|
-
|
|
258
|
+
expect(subject.delete 'cat', 'garfield').to be_nil
|
|
259
|
+
expect {
|
|
260
|
+
subject.delete 'cat', 'garfield' }.to raise_error(LMDB::Error::NOTFOUND)
|
|
254
261
|
|
|
255
262
|
# soft delete
|
|
256
|
-
subject.delete?
|
|
263
|
+
expect(subject.delete? 'cat', 'heathcliff').to be_nil
|
|
257
264
|
end
|
|
258
265
|
|
|
259
266
|
it 'stores key/values in same transaction' do
|
|
260
|
-
db.put
|
|
261
|
-
db.get
|
|
267
|
+
expect(db.put 'key', 'value').to be_nil
|
|
268
|
+
expect(db.get 'key').to eq('value')
|
|
262
269
|
end
|
|
263
270
|
|
|
264
271
|
it 'stores key/values in different transactions' do
|
|
265
272
|
env.transaction do
|
|
266
|
-
db.put
|
|
267
|
-
db.put
|
|
273
|
+
expect(db.put 'key', 'value').to be_nil
|
|
274
|
+
expect(db.put 'key2', 'value2').to be_nil
|
|
268
275
|
env.transaction do
|
|
269
|
-
db.put
|
|
276
|
+
expect(db.put 'key3', 'value3').to be_nil
|
|
270
277
|
end
|
|
271
278
|
end
|
|
272
279
|
|
|
273
280
|
env.transaction do
|
|
274
|
-
db.get
|
|
275
|
-
db.get
|
|
281
|
+
expect(db.get 'key').to eq('value')
|
|
282
|
+
expect(db.get 'key2').to eq('value2')
|
|
276
283
|
env.transaction do
|
|
277
|
-
db.get
|
|
284
|
+
expect(db.get 'key3').to eq('value3')
|
|
278
285
|
end
|
|
279
286
|
end
|
|
280
287
|
end
|
|
@@ -285,30 +292,30 @@ describe LMDB do
|
|
|
285
292
|
break
|
|
286
293
|
end
|
|
287
294
|
|
|
288
|
-
db.get
|
|
295
|
+
expect(db.get 'key4').to eq('value4')
|
|
289
296
|
end
|
|
290
297
|
|
|
291
298
|
it 'should return stat' do
|
|
292
|
-
db.stat.
|
|
299
|
+
expect(db.stat).to be_instance_of(Hash)
|
|
293
300
|
end
|
|
294
301
|
|
|
295
302
|
it 'should return size' do
|
|
296
|
-
db.size.
|
|
303
|
+
expect(db.size).to eq(0)
|
|
297
304
|
db.put('key', 'value')
|
|
298
|
-
db.size.
|
|
305
|
+
expect(db.size).to eq(1)
|
|
299
306
|
db.put('key2', 'value2')
|
|
300
|
-
db.size.
|
|
307
|
+
expect(db.size).to eq(2)
|
|
301
308
|
end
|
|
302
309
|
|
|
303
310
|
it 'should be enumerable' do
|
|
304
311
|
db['k1'] = 'v1'
|
|
305
312
|
db['k2'] = 'v2'
|
|
306
|
-
db.to_a.
|
|
313
|
+
expect(db.to_a).to eq([['k1', 'v1'], ['k2', 'v2']])
|
|
307
314
|
end
|
|
308
315
|
|
|
309
316
|
it 'should have shortcuts' do
|
|
310
317
|
db['key'] = 'value'
|
|
311
|
-
db['key'].
|
|
318
|
+
expect(db['key']).to eq('value')
|
|
312
319
|
end
|
|
313
320
|
|
|
314
321
|
it 'should store binary' do
|
|
@@ -316,21 +323,21 @@ describe LMDB do
|
|
|
316
323
|
bin2 = "\xAAx\BB\xCC2"
|
|
317
324
|
db[bin1] = bin2
|
|
318
325
|
db['key'] = bin2
|
|
319
|
-
db[bin1].
|
|
320
|
-
db['key'].
|
|
326
|
+
expect(db[bin1]).to eq(bin2)
|
|
327
|
+
expect(db['key']).to eq(bin2)
|
|
321
328
|
end
|
|
322
329
|
|
|
323
330
|
it 'should get environment' do
|
|
324
331
|
main = env.database
|
|
325
332
|
db1 = env.database('db1', create: true)
|
|
326
|
-
main.env.
|
|
327
|
-
db1.env.
|
|
333
|
+
expect(main.env).to eq(env)
|
|
334
|
+
expect(db1.env).to eq(env)
|
|
328
335
|
end
|
|
329
336
|
|
|
330
337
|
it 'should iterate over/list keys' do
|
|
331
338
|
db['k1'] = 'v1'
|
|
332
339
|
db['k2'] = 'v2'
|
|
333
|
-
db.keys.sort.
|
|
340
|
+
expect(db.keys.sort).to eq(%w[k1 k2])
|
|
334
341
|
end
|
|
335
342
|
end
|
|
336
343
|
|
|
@@ -342,38 +349,38 @@ describe LMDB do
|
|
|
342
349
|
|
|
343
350
|
it 'should get first key/value' do
|
|
344
351
|
db.cursor do |c|
|
|
345
|
-
c.first.
|
|
352
|
+
expect(c.first).to eq(['key1', 'value1'])
|
|
346
353
|
end
|
|
347
354
|
end
|
|
348
355
|
|
|
349
356
|
it 'should get last key/value' do
|
|
350
357
|
db.cursor do |c|
|
|
351
|
-
c.last.
|
|
358
|
+
expect(c.last).to eq(['key2', 'value2'])
|
|
352
359
|
end
|
|
353
360
|
end
|
|
354
361
|
|
|
355
362
|
it 'should get next key/value' do
|
|
356
363
|
db.cursor do |c|
|
|
357
364
|
c.first
|
|
358
|
-
c.next.
|
|
365
|
+
expect(c.next).to eq(['key2', 'value2'])
|
|
359
366
|
end
|
|
360
367
|
end
|
|
361
368
|
|
|
362
369
|
it 'should seek to key' do
|
|
363
370
|
db.cursor do |c|
|
|
364
|
-
c.set
|
|
371
|
+
expect(c.set 'key1').to eq(['key1', 'value1'])
|
|
365
372
|
end
|
|
366
373
|
end
|
|
367
374
|
|
|
368
375
|
it 'should seek to closest key' do
|
|
369
376
|
db.cursor do |c|
|
|
370
|
-
c.set_range
|
|
377
|
+
expect(c.set_range 'key0').to eq(['key1', 'value1'])
|
|
371
378
|
end
|
|
372
379
|
end
|
|
373
380
|
|
|
374
381
|
it 'should seek to key with nuls' do
|
|
375
382
|
db.cursor do |c|
|
|
376
|
-
c.set_range
|
|
383
|
+
expect(c.set_range '\x00').to eq(['key1', 'value1'])
|
|
377
384
|
end
|
|
378
385
|
end
|
|
379
386
|
|
|
@@ -381,8 +388,8 @@ describe LMDB do
|
|
|
381
388
|
db.cursor do |c|
|
|
382
389
|
db.put('key0', 'value0')
|
|
383
390
|
c.first
|
|
384
|
-
c.next_range
|
|
385
|
-
c.next_range
|
|
391
|
+
expect(c.next_range 'key1').to eq(['key1', 'value1'])
|
|
392
|
+
expect(c.next_range 'key1').to be_nil
|
|
386
393
|
end
|
|
387
394
|
end
|
|
388
395
|
|
|
@@ -390,35 +397,35 @@ describe LMDB do
|
|
|
390
397
|
dupdb = env.database 'dupsort', create: true, dupsort: true
|
|
391
398
|
|
|
392
399
|
# check flag while we're at it
|
|
393
|
-
dupdb.flags[:dupsort].
|
|
394
|
-
dupdb.dupsort
|
|
395
|
-
dupdb.dupfixed
|
|
400
|
+
expect(dupdb.flags[:dupsort]).to be_truthy
|
|
401
|
+
expect(dupdb.dupsort?).to be_truthy
|
|
402
|
+
expect(dupdb.dupfixed?).to be_falsy
|
|
396
403
|
|
|
397
404
|
# add the no-op keyword to trigger a complaint from ruby 2.7
|
|
398
405
|
dupdb.put 'key1', 'value1', nodupdata: false
|
|
399
406
|
dupdb.put 'key1', 'value2'
|
|
400
407
|
dupdb.put 'key2', 'value3'
|
|
401
408
|
dupdb.cursor do |c|
|
|
402
|
-
c.set
|
|
403
|
-
c.set
|
|
404
|
-
c.set
|
|
409
|
+
expect(c.set 'key1', 'value2').to eq(['key1', 'value2'])
|
|
410
|
+
expect(c.set 'key1', 'value1').to eq(['key1', 'value1'])
|
|
411
|
+
expect(c.set 'key1', 'value3').to be_nil
|
|
405
412
|
end
|
|
406
413
|
|
|
407
414
|
# this should do nothing
|
|
408
|
-
dupdb.put?
|
|
415
|
+
expect(dupdb.put? 'key1', 'value1', nodupdata: true).to be_nil
|
|
409
416
|
|
|
410
417
|
# this is basically an extended test of `cursor.set key, val`
|
|
411
|
-
dupdb.has?
|
|
412
|
-
dupdb.has?
|
|
413
|
-
dupdb.has?
|
|
418
|
+
expect(dupdb.has? 'key1', 'value1').to be_truthy
|
|
419
|
+
expect(dupdb.has? 'key1', 'value2').to be_truthy
|
|
420
|
+
expect(dupdb.has? 'key1', 'value0').to be_falsy
|
|
414
421
|
|
|
415
422
|
# match the contents of key1
|
|
416
|
-
dupdb.each_value('key1').to_a.sort.
|
|
423
|
+
expect(dupdb.each_value('key1').to_a.sort).to eq(['value1', 'value2'])
|
|
417
424
|
|
|
418
425
|
# we should have two entries for key1
|
|
419
|
-
dupdb.cardinality
|
|
426
|
+
expect(dupdb.cardinality 'key1').to eq(2)
|
|
420
427
|
|
|
421
|
-
dupdb.each_key.to_a.sort.
|
|
428
|
+
expect(dupdb.each_key.to_a.sort).to eq(['key1', 'key2'])
|
|
422
429
|
|
|
423
430
|
# XXX move this or whatever
|
|
424
431
|
env.transaction do |t|
|
|
@@ -428,24 +435,24 @@ describe LMDB do
|
|
|
428
435
|
|
|
429
436
|
it 'should complain setting a key-value pair without dupsort' do
|
|
430
437
|
db.cursor do |c|
|
|
431
|
-
|
|
438
|
+
expect { c.set('key1', 'value1') }.to raise_error(LMDB::Error)
|
|
432
439
|
end
|
|
433
440
|
end
|
|
434
441
|
|
|
435
442
|
it 'should raise without block or txn' do
|
|
436
|
-
|
|
443
|
+
expect { db.cursor.next }.to raise_error(LMDB::Error)
|
|
437
444
|
end
|
|
438
445
|
|
|
439
446
|
it 'should raise outside txn' do
|
|
440
447
|
c = nil
|
|
441
448
|
env.transaction { c = db.cursor }
|
|
442
|
-
|
|
449
|
+
expect { c.next }.to raise_error(LMDB::Error)
|
|
443
450
|
end
|
|
444
451
|
|
|
445
452
|
it 'should get database' do
|
|
446
453
|
db2 = nil
|
|
447
454
|
env.transaction { c = db.cursor; db2 = c.database }
|
|
448
|
-
db2.
|
|
455
|
+
expect(db2).to eq(db)
|
|
449
456
|
end
|
|
450
457
|
|
|
451
458
|
it 'should nest a read-only txn in a read-write' do
|
|
@@ -456,19 +463,19 @@ describe LMDB do
|
|
|
456
463
|
end
|
|
457
464
|
|
|
458
465
|
it 'should croak when cursor key is not given a string' do
|
|
459
|
-
|
|
466
|
+
expect do
|
|
460
467
|
db.cursor do |c|
|
|
461
468
|
c.set 1
|
|
462
469
|
end
|
|
463
|
-
end.
|
|
470
|
+
end.to raise_error(ArgumentError)
|
|
464
471
|
end
|
|
465
472
|
|
|
466
473
|
it 'should croak when cursor value is not given a string' do
|
|
467
|
-
|
|
474
|
+
expect do
|
|
468
475
|
db.cursor do |c|
|
|
469
476
|
c.set 'hi', 1
|
|
470
477
|
end
|
|
471
|
-
end.
|
|
478
|
+
end.to raise_error(ArgumentError)
|
|
472
479
|
end
|
|
473
480
|
end
|
|
474
481
|
end
|