lmdb 0.7.3 → 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/README.md +12 -4
- data/Rakefile +48 -0
- data/ext/lmdb_ext/extconf.rb +29 -10
- data/ext/lmdb_ext/lmdb_ext.c +1389 -908
- data/ext/lmdb_ext/lmdb_ext.h +36 -19
- data/lib/lmdb/database.rb +2 -1
- data/lib/lmdb/version.rb +1 -1
- data/lmdb.gemspec +4 -1
- data/spec/gc_torture_spec.rb +162 -0
- data/spec/helper.rb +3 -3
- data/spec/lmdb_spec.rb +152 -136
- data/spec/pseudo_transactions_spec.rb +237 -0
- data/vendor/liblmdb/VERSION +1 -0
- data/vendor/{libraries/liblmdb → liblmdb}/lmdb.h +18 -63
- data/vendor/{libraries/liblmdb → liblmdb}/mdb.c +583 -1480
- data/vendor/{libraries/liblmdb → liblmdb}/midl.c +0 -62
- data/vendor/{libraries/liblmdb → liblmdb}/midl.h +4 -16
- metadata +11 -34
- data/CONTRIBUTORS +0 -8
- data/behaviour.org +0 -35
- data/ext/lmdb_ext/prototypes.sh +0 -4
- data/vendor/libraries/liblmdb/.gitignore +0 -24
- data/vendor/libraries/liblmdb/COPYRIGHT +0 -20
- data/vendor/libraries/liblmdb/Doxyfile +0 -1631
- data/vendor/libraries/liblmdb/LICENSE +0 -47
- data/vendor/libraries/liblmdb/Makefile +0 -118
- data/vendor/libraries/liblmdb/intro.doc +0 -192
- data/vendor/libraries/liblmdb/mdb_copy.1 +0 -61
- data/vendor/libraries/liblmdb/mdb_copy.c +0 -84
- data/vendor/libraries/liblmdb/mdb_drop.1 +0 -40
- data/vendor/libraries/liblmdb/mdb_drop.c +0 -135
- data/vendor/libraries/liblmdb/mdb_dump.1 +0 -81
- data/vendor/libraries/liblmdb/mdb_dump.c +0 -319
- data/vendor/libraries/liblmdb/mdb_load.1 +0 -84
- data/vendor/libraries/liblmdb/mdb_load.c +0 -492
- data/vendor/libraries/liblmdb/mdb_stat.1 +0 -70
- data/vendor/libraries/liblmdb/mdb_stat.c +0 -264
- data/vendor/libraries/liblmdb/mtest.c +0 -177
- data/vendor/libraries/liblmdb/mtest2.c +0 -124
- data/vendor/libraries/liblmdb/mtest3.c +0 -133
- data/vendor/libraries/liblmdb/mtest4.c +0 -168
- data/vendor/libraries/liblmdb/mtest5.c +0 -135
- data/vendor/libraries/liblmdb/mtest6.c +0 -141
- data/vendor/libraries/liblmdb/sample-bdb.txt +0 -73
- data/vendor/libraries/liblmdb/sample-mdb.txt +0 -62
- data/vendor/libraries/liblmdb/tooltag +0 -27
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,88 +219,103 @@ 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
|
|
281
288
|
|
|
289
|
+
it 'should not complain when you break out of a transaction' do
|
|
290
|
+
env.transaction do |txn|
|
|
291
|
+
db.put 'key4', 'value4'
|
|
292
|
+
break
|
|
293
|
+
end
|
|
294
|
+
|
|
295
|
+
expect(db.get 'key4').to eq('value4')
|
|
296
|
+
end
|
|
297
|
+
|
|
282
298
|
it 'should return stat' do
|
|
283
|
-
db.stat.
|
|
299
|
+
expect(db.stat).to be_instance_of(Hash)
|
|
284
300
|
end
|
|
285
301
|
|
|
286
302
|
it 'should return size' do
|
|
287
|
-
db.size.
|
|
303
|
+
expect(db.size).to eq(0)
|
|
288
304
|
db.put('key', 'value')
|
|
289
|
-
db.size.
|
|
305
|
+
expect(db.size).to eq(1)
|
|
290
306
|
db.put('key2', 'value2')
|
|
291
|
-
db.size.
|
|
307
|
+
expect(db.size).to eq(2)
|
|
292
308
|
end
|
|
293
309
|
|
|
294
310
|
it 'should be enumerable' do
|
|
295
311
|
db['k1'] = 'v1'
|
|
296
312
|
db['k2'] = 'v2'
|
|
297
|
-
db.to_a.
|
|
313
|
+
expect(db.to_a).to eq([['k1', 'v1'], ['k2', 'v2']])
|
|
298
314
|
end
|
|
299
315
|
|
|
300
316
|
it 'should have shortcuts' do
|
|
301
317
|
db['key'] = 'value'
|
|
302
|
-
db['key'].
|
|
318
|
+
expect(db['key']).to eq('value')
|
|
303
319
|
end
|
|
304
320
|
|
|
305
321
|
it 'should store binary' do
|
|
@@ -307,21 +323,21 @@ describe LMDB do
|
|
|
307
323
|
bin2 = "\xAAx\BB\xCC2"
|
|
308
324
|
db[bin1] = bin2
|
|
309
325
|
db['key'] = bin2
|
|
310
|
-
db[bin1].
|
|
311
|
-
db['key'].
|
|
326
|
+
expect(db[bin1]).to eq(bin2)
|
|
327
|
+
expect(db['key']).to eq(bin2)
|
|
312
328
|
end
|
|
313
329
|
|
|
314
330
|
it 'should get environment' do
|
|
315
331
|
main = env.database
|
|
316
332
|
db1 = env.database('db1', create: true)
|
|
317
|
-
main.env.
|
|
318
|
-
db1.env.
|
|
333
|
+
expect(main.env).to eq(env)
|
|
334
|
+
expect(db1.env).to eq(env)
|
|
319
335
|
end
|
|
320
336
|
|
|
321
337
|
it 'should iterate over/list keys' do
|
|
322
338
|
db['k1'] = 'v1'
|
|
323
339
|
db['k2'] = 'v2'
|
|
324
|
-
db.keys.sort.
|
|
340
|
+
expect(db.keys.sort).to eq(%w[k1 k2])
|
|
325
341
|
end
|
|
326
342
|
end
|
|
327
343
|
|
|
@@ -333,38 +349,38 @@ describe LMDB do
|
|
|
333
349
|
|
|
334
350
|
it 'should get first key/value' do
|
|
335
351
|
db.cursor do |c|
|
|
336
|
-
c.first.
|
|
352
|
+
expect(c.first).to eq(['key1', 'value1'])
|
|
337
353
|
end
|
|
338
354
|
end
|
|
339
355
|
|
|
340
356
|
it 'should get last key/value' do
|
|
341
357
|
db.cursor do |c|
|
|
342
|
-
c.last.
|
|
358
|
+
expect(c.last).to eq(['key2', 'value2'])
|
|
343
359
|
end
|
|
344
360
|
end
|
|
345
361
|
|
|
346
362
|
it 'should get next key/value' do
|
|
347
363
|
db.cursor do |c|
|
|
348
364
|
c.first
|
|
349
|
-
c.next.
|
|
365
|
+
expect(c.next).to eq(['key2', 'value2'])
|
|
350
366
|
end
|
|
351
367
|
end
|
|
352
368
|
|
|
353
369
|
it 'should seek to key' do
|
|
354
370
|
db.cursor do |c|
|
|
355
|
-
c.set
|
|
371
|
+
expect(c.set 'key1').to eq(['key1', 'value1'])
|
|
356
372
|
end
|
|
357
373
|
end
|
|
358
374
|
|
|
359
375
|
it 'should seek to closest key' do
|
|
360
376
|
db.cursor do |c|
|
|
361
|
-
c.set_range
|
|
377
|
+
expect(c.set_range 'key0').to eq(['key1', 'value1'])
|
|
362
378
|
end
|
|
363
379
|
end
|
|
364
380
|
|
|
365
381
|
it 'should seek to key with nuls' do
|
|
366
382
|
db.cursor do |c|
|
|
367
|
-
c.set_range
|
|
383
|
+
expect(c.set_range '\x00').to eq(['key1', 'value1'])
|
|
368
384
|
end
|
|
369
385
|
end
|
|
370
386
|
|
|
@@ -372,8 +388,8 @@ describe LMDB do
|
|
|
372
388
|
db.cursor do |c|
|
|
373
389
|
db.put('key0', 'value0')
|
|
374
390
|
c.first
|
|
375
|
-
c.next_range
|
|
376
|
-
c.next_range
|
|
391
|
+
expect(c.next_range 'key1').to eq(['key1', 'value1'])
|
|
392
|
+
expect(c.next_range 'key1').to be_nil
|
|
377
393
|
end
|
|
378
394
|
end
|
|
379
395
|
|
|
@@ -381,35 +397,35 @@ describe LMDB do
|
|
|
381
397
|
dupdb = env.database 'dupsort', create: true, dupsort: true
|
|
382
398
|
|
|
383
399
|
# check flag while we're at it
|
|
384
|
-
dupdb.flags[:dupsort].
|
|
385
|
-
dupdb.dupsort
|
|
386
|
-
dupdb.dupfixed
|
|
400
|
+
expect(dupdb.flags[:dupsort]).to be_truthy
|
|
401
|
+
expect(dupdb.dupsort?).to be_truthy
|
|
402
|
+
expect(dupdb.dupfixed?).to be_falsy
|
|
387
403
|
|
|
388
404
|
# add the no-op keyword to trigger a complaint from ruby 2.7
|
|
389
405
|
dupdb.put 'key1', 'value1', nodupdata: false
|
|
390
406
|
dupdb.put 'key1', 'value2'
|
|
391
407
|
dupdb.put 'key2', 'value3'
|
|
392
408
|
dupdb.cursor do |c|
|
|
393
|
-
c.set
|
|
394
|
-
c.set
|
|
395
|
-
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
|
|
396
412
|
end
|
|
397
413
|
|
|
398
414
|
# this should do nothing
|
|
399
|
-
dupdb.put?
|
|
415
|
+
expect(dupdb.put? 'key1', 'value1', nodupdata: true).to be_nil
|
|
400
416
|
|
|
401
417
|
# this is basically an extended test of `cursor.set key, val`
|
|
402
|
-
dupdb.has?
|
|
403
|
-
dupdb.has?
|
|
404
|
-
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
|
|
405
421
|
|
|
406
422
|
# match the contents of key1
|
|
407
|
-
dupdb.each_value('key1').to_a.sort.
|
|
423
|
+
expect(dupdb.each_value('key1').to_a.sort).to eq(['value1', 'value2'])
|
|
408
424
|
|
|
409
425
|
# we should have two entries for key1
|
|
410
|
-
dupdb.cardinality
|
|
426
|
+
expect(dupdb.cardinality 'key1').to eq(2)
|
|
411
427
|
|
|
412
|
-
dupdb.each_key.to_a.sort.
|
|
428
|
+
expect(dupdb.each_key.to_a.sort).to eq(['key1', 'key2'])
|
|
413
429
|
|
|
414
430
|
# XXX move this or whatever
|
|
415
431
|
env.transaction do |t|
|
|
@@ -419,24 +435,24 @@ describe LMDB do
|
|
|
419
435
|
|
|
420
436
|
it 'should complain setting a key-value pair without dupsort' do
|
|
421
437
|
db.cursor do |c|
|
|
422
|
-
|
|
438
|
+
expect { c.set('key1', 'value1') }.to raise_error(LMDB::Error)
|
|
423
439
|
end
|
|
424
440
|
end
|
|
425
441
|
|
|
426
442
|
it 'should raise without block or txn' do
|
|
427
|
-
|
|
443
|
+
expect { db.cursor.next }.to raise_error(LMDB::Error)
|
|
428
444
|
end
|
|
429
445
|
|
|
430
446
|
it 'should raise outside txn' do
|
|
431
447
|
c = nil
|
|
432
448
|
env.transaction { c = db.cursor }
|
|
433
|
-
|
|
449
|
+
expect { c.next }.to raise_error(LMDB::Error)
|
|
434
450
|
end
|
|
435
451
|
|
|
436
452
|
it 'should get database' do
|
|
437
453
|
db2 = nil
|
|
438
454
|
env.transaction { c = db.cursor; db2 = c.database }
|
|
439
|
-
db2.
|
|
455
|
+
expect(db2).to eq(db)
|
|
440
456
|
end
|
|
441
457
|
|
|
442
458
|
it 'should nest a read-only txn in a read-write' do
|
|
@@ -447,19 +463,19 @@ describe LMDB do
|
|
|
447
463
|
end
|
|
448
464
|
|
|
449
465
|
it 'should croak when cursor key is not given a string' do
|
|
450
|
-
|
|
466
|
+
expect do
|
|
451
467
|
db.cursor do |c|
|
|
452
468
|
c.set 1
|
|
453
469
|
end
|
|
454
|
-
end.
|
|
470
|
+
end.to raise_error(ArgumentError)
|
|
455
471
|
end
|
|
456
472
|
|
|
457
473
|
it 'should croak when cursor value is not given a string' do
|
|
458
|
-
|
|
474
|
+
expect do
|
|
459
475
|
db.cursor do |c|
|
|
460
476
|
c.set 'hi', 1
|
|
461
477
|
end
|
|
462
|
-
end.
|
|
478
|
+
end.to raise_error(ArgumentError)
|
|
463
479
|
end
|
|
464
480
|
end
|
|
465
481
|
end
|