lmdb 0.6.6 → 0.7.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: fcfc5ce25df41f83029918b757006f4f34b674f41c2c2691cc40128a7e63a46e
4
- data.tar.gz: 9cf681ab6dc945eac9b8225717248f42cf27940a704e951aed3dbd59f151df23
3
+ metadata.gz: c098384d91381d0f7c66a4794f88ea55c1c8a1e54d60480a75a379704407252d
4
+ data.tar.gz: 11c4e5b74f9b552ad9f89d5a189bf812340ab409b43b54361cb84f7d47dfd906
5
5
  SHA512:
6
- metadata.gz: 888eb18fa7e8be017e950f1b8893fc9c4f3c4cc1fa616312438b23be86344cfdeb37d2cc7edc477a528292776ae45e95c0f65c8cd49cd417a4be387f1dd3a28f
7
- data.tar.gz: 07740710e001f491d22b902d27c1e446d2bab1b93e42d41951e47fdd084b5d5f982dadc551f13764146e8725b8dda4b7a7084c2781454bac2d9f332e16fd666e
6
+ metadata.gz: da3b52d345951ad527b67ce32998c749b17267b7b0d075f695e841d1b2a0891df4e0064e021e7db9ac21f41c0b81a4fb590ff88a98250675e15ad14baf185680
7
+ data.tar.gz: 12ae851f60db43dec61730f8497a06bf952e56242bff2e8fe64153a852c34582441556320cb1627fa65b7c29dfe417ba312c929d242511c0ab9c3888b12075b4
data/CHANGES CHANGED
@@ -1,3 +1,12 @@
1
+ 0.7.0
2
+
3
+ * Nesting read-only transactions finally works, by making it a noop
4
+ and using the parent transaction (djt)
5
+
6
+ 0.6.6
7
+
8
+ * added `put?` and `delete?` (djt)
9
+
1
10
  0.5.1
2
11
 
3
12
  * Move read-only operations to read-only transactions (djt)
@@ -285,69 +285,87 @@ static void stop_txn_begin(void *arg)
285
285
  */
286
286
 
287
287
  static VALUE with_transaction(VALUE venv, VALUE(*fn)(VALUE), VALUE arg, int flags) {
288
- ENVIRONMENT(venv, environment);
289
-
290
- MDB_txn* txn;
291
- TxnArgs txn_args;
292
-
293
- VALUE thread = rb_thread_current();
294
- VALUE vparent = environment_active_txn(venv);
295
-
296
- Transaction* tparent = NULL;
297
- if (vparent && !NIL_P(vparent))
298
- Data_Get_Struct(vparent, Transaction, tparent);
299
-
288
+ ENVIRONMENT(venv, environment);
289
+
290
+ MDB_txn* txn;
291
+ TxnArgs txn_args;
292
+
293
+ VALUE thread = rb_thread_current();
294
+ VALUE vparent = environment_active_txn(venv);
295
+
296
+ //
297
+ Transaction* tparent = NULL;
298
+ if (vparent && !NIL_P(vparent))
299
+ Data_Get_Struct(vparent, Transaction, tparent);
300
+
301
+ /*
302
+ * If the requested transaction is read-only and there is a parent
303
+ * transaction (whether read-only or not), we need to use the
304
+ * parent transaction.
305
+ *
306
+ * XXX except conceivably you could do a transaction (RO or RW)
307
+ * that spawns a thread that opens another transaction.
308
+ *
309
+ * note we do *NOT* re-begin the parent transaction, nor do we
310
+ * want to commit it
311
+ *
312
+ */
313
+
314
+ if (tparent && flags & MDB_RDONLY) {
315
+ int exception;
316
+ VALUE ret = rb_protect(fn, NIL_P(arg) ? vparent : arg, &exception);
317
+ if (exception) {
318
+ if (vparent == environment_active_txn(venv))
319
+ transaction_abort(vparent);
320
+ rb_jump_tag(exception);
321
+ }
322
+ return ret;
323
+ }
324
+ else {
300
325
  // XXX note this is a cursed goto loop that could almost certainly
301
326
  // be rewritten as a do-while
302
- retry:
327
+ retry:
303
328
  txn = NULL;
304
329
 
305
330
  txn_args.env = environment->env;
306
- txn_args.parent = active_txn(venv);
331
+ txn_args.parent = active_txn(venv); // this returns an MDB_txn
307
332
  txn_args.flags = flags;
308
333
  txn_args.htxn = &txn;
309
334
  txn_args.result = 0;
310
335
  txn_args.stop = 0;
311
336
 
312
- if (flags & MDB_RDONLY) {
313
- if (tparent && tparent->flags & MDB_RDONLY)
314
- // this is a no-op: put the same actual transaction in a
315
- // different wrapper struct
316
- txn = txn_args.parent;
317
- else
318
- // this will return an error if the parent transaction is
319
- // read-write, so we don't need to handle the case explicitly
320
- call_txn_begin(&txn_args);
321
- }
337
+ if (flags & MDB_RDONLY)
338
+ call_txn_begin(&txn_args);
322
339
  else {
323
- if (tparent) {
324
- // first we have to determine if we're on the same thread
325
- // as the parent, which in turn must be the same as the
326
- // environment's registry for which thread has the
327
- // read-write transaction
328
- if (thread != tparent->thread ||
329
- thread != environment->rw_txn_thread)
330
- rb_raise(cError,
331
- "Attempt to nest transaction on a different thread");
340
+ if (tparent) {
341
+ // first we have to determine if we're on the same thread
342
+ // as the parent, which in turn must be the same as the
343
+ // environment's registry for which thread has the
344
+ // read-write transaction
345
+ if (thread != tparent->thread ||
346
+ thread != environment->rw_txn_thread)
347
+ rb_raise(cError,
348
+ "Attempt to nest transaction on a different thread");
349
+ }
350
+
351
+ // try to acquire the new transaction
352
+ CALL_WITHOUT_GVL(call_txn_begin, &txn_args, stop_txn_begin, &txn_args);
353
+
354
+ if (txn_args.stop || !txn) {
355
+ // !txn is when rb_thread_call_without_gvl2
356
+ // returns before calling txn_begin
357
+ if (txn) {
358
+ mdb_txn_abort(txn);
359
+ txn_args.result = 0;
332
360
  }
333
361
 
334
- CALL_WITHOUT_GVL(call_txn_begin, &txn_args, stop_txn_begin, &txn_args);
362
+ //rb_warn("got here lol");
363
+ rb_thread_check_ints();
364
+ goto retry; // in what cases do we get here?
365
+ }
335
366
 
336
- if (txn_args.stop || !txn) {
337
- // !txn is when rb_thread_call_without_gvl2
338
- // returns before calling txn_begin
339
- if (txn) {
340
- mdb_txn_abort(txn);
341
- txn_args.result = 0;
342
- }
343
-
344
- //rb_warn("got here lol");
345
- rb_thread_check_ints();
346
- goto retry; // in what cases do we get here?
347
- }
348
-
349
- // set the thread
350
- environment->rw_txn_thread = thread;
367
+ // set the thread
368
+ environment->rw_txn_thread = thread;
351
369
  }
352
370
 
353
371
  // this will raise unless result is zero
@@ -373,14 +391,15 @@ static VALUE with_transaction(VALUE venv, VALUE(*fn)(VALUE), VALUE arg, int flag
373
391
  VALUE ret = rb_protect(fn, NIL_P(arg) ? vtxn : arg, &exception);
374
392
 
375
393
  if (exception) {
376
- // rb_warn("lol got exception");
377
- if (vtxn == environment_active_txn(venv))
378
- transaction_abort(vtxn);
379
- rb_jump_tag(exception);
394
+ // rb_warn("lol got exception");
395
+ if (vtxn == environment_active_txn(venv))
396
+ transaction_abort(vtxn);
397
+ rb_jump_tag(exception);
380
398
  }
381
399
  if (vtxn == environment_active_txn(venv))
382
- transaction_commit(vtxn);
400
+ transaction_commit(vtxn);
383
401
  return ret;
402
+ }
384
403
  }
385
404
 
386
405
  static void environment_check(Environment* environment) {
@@ -773,23 +792,24 @@ static void environment_set_active_txn(VALUE self, VALUE thread, VALUE txn) {
773
792
  }
774
793
  }
775
794
 
795
+ static MDB_txn* extract_txn(VALUE vtxn) {
796
+ if (NIL_P(vtxn)) return NULL;
797
+ TRANSACTION(vtxn, transaction);
798
+ if (!transaction->txn) rb_raise(cError, "Transaction is already terminated");
799
+ if (transaction->thread != rb_thread_current())
800
+ rb_raise(cError, "Transaction is from another thread");
801
+ return transaction->txn;
802
+ }
776
803
 
777
804
  static MDB_txn* active_txn(VALUE self) {
778
805
  VALUE vtxn = environment_active_txn(self);
779
- if (NIL_P(vtxn))
780
- return 0;
781
- TRANSACTION(vtxn, transaction);
782
- if (!transaction->txn)
783
- rb_raise(cError, "Transaction is already terminated");
784
- if (transaction->thread != rb_thread_current())
785
- rb_raise(cError, "Wrong thread");
786
- return transaction->txn;
806
+ return extract_txn(vtxn);
787
807
  }
788
808
 
789
809
  static MDB_txn* need_txn(VALUE self) {
790
810
  MDB_txn* txn = active_txn(self);
791
- if (!txn)
792
- rb_raise(cError, "No active transaction");
811
+
812
+ if (!txn) rb_raise(cError, "No active transaction");
793
813
  return txn;
794
814
  }
795
815
 
@@ -104,12 +104,12 @@ typedef struct {
104
104
  } EnvironmentOptions;
105
105
 
106
106
  typedef struct {
107
- MDB_env *env;
108
- MDB_txn *parent;
109
- unsigned int flags;
110
- MDB_txn **htxn;
111
- int result;
112
- int stop;
107
+ MDB_env *env;
108
+ MDB_txn *parent;
109
+ unsigned int flags;
110
+ MDB_txn **htxn; // not sure why this is a pointer to a pointer
111
+ int result;
112
+ int stop;
113
113
  } TxnArgs;
114
114
 
115
115
  static VALUE cEnvironment, cDatabase, cTransaction, cCursor, cError;
data/lib/lmdb/database.rb CHANGED
@@ -136,16 +136,18 @@ module LMDB
136
136
 
137
137
  # Conditionally put a value into the database.
138
138
  #
139
- # @param key [String] The key of the record
140
- # @param value [String] the (optional) value
139
+ # @param key [#to_s] The key of the record
140
+ # @param value [#to_s, nil] the (optional) value
141
141
  # @param options [Hash] options
142
142
  #
143
143
  # @see #put
144
144
  #
145
145
  # @return [void]
146
+ #
146
147
  def put?(key, value = nil, **options)
148
+ flags = { (dupsort? ? :nodupdata : :nooverwrite) => true }
147
149
  begin
148
- put key, value, **options
150
+ put key, value, **options.merge(flags)
149
151
  rescue LMDB::Error::KEYEXIST
150
152
  nil
151
153
  end
@@ -154,15 +156,15 @@ module LMDB
154
156
  # Delete the key (and optional value pair) if it exists; do not
155
157
  # complain about missing keys.
156
158
  # @param key [#to_s] The key of the record
157
- # @param value [#to_s] The optional value
159
+ # @param value [#to_s, nil] The optional value
158
160
  #
159
161
  # @see #delete
160
162
  #
161
163
  # @return [void]
162
164
  #
163
- def delete?(key, value = nil, **options)
165
+ def delete?(key, value = nil)
164
166
  begin
165
- delete key, value, **options
167
+ delete key, value
166
168
  rescue LMDB::Error::NOTFOUND
167
169
  nil
168
170
  end
@@ -186,6 +188,10 @@ module LMDB
186
188
  # having trouble with read-only transactions embedded in
187
189
  # read-write for some reason; can't pin it down to test it yet so
188
190
  # going to do this (djt; 2020-02-10)
191
+ #
192
+ # 2025-11-14: this miiiigght no longer be necessary?? like as of
193
+ # whenever i implemented that short-circuiting code
194
+ #
189
195
  def maybe_txn(readonly, &block)
190
196
  if t = env.active_txn
191
197
  # warn "reusing #{t.readonly? ? 'read-only ' : ''}txn #{t.inspect}"
data/lib/lmdb/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module LMDB
2
- VERSION = '0.6.6'.freeze
2
+ VERSION = '0.7.0'.freeze
3
3
  end
data/spec/lmdb_spec.rb CHANGED
@@ -40,8 +40,8 @@ describe LMDB do
40
40
  env = LMDB::Environment.new(path, nosync: true, mode: 0777,
41
41
  maxreaders: 777, mapsize: 111111, maxdbs: 666)
42
42
  env.should be_instance_of(described_class)
43
- env.info[:maxreaders].should == 777
44
- env.info[:mapsize].should == 111111
43
+ env.info[:maxreaders].should eq(777)
44
+ env.info[:mapsize].should eq(111111)
45
45
  env.flags.should include(:nosync)
46
46
  env.close
47
47
 
@@ -74,7 +74,7 @@ describe LMDB do
74
74
  it 'should set mapsize' do
75
75
  size_before = env.info[:mapsize]
76
76
  env.mapsize = size_before * 2
77
- env.info[:mapsize].should == size_before * 2
77
+ env.info[:mapsize].should eq(size_before * 2)
78
78
  end
79
79
 
80
80
  it 'should copy' do
@@ -108,7 +108,7 @@ describe LMDB do
108
108
  it 'returns list of named databases' do
109
109
  db1 = subject.database 'db1', create: true
110
110
  db2 = subject.database 'db2', create: true
111
- subject.databases.should == ['db1', 'db2']
111
+ subject.databases.should eq(['db1', 'db2'])
112
112
  end
113
113
 
114
114
  it 'returns list of named databases when there are non-database kes in the main db' do
@@ -117,7 +117,7 @@ describe LMDB do
117
117
  subject.database 'db1', create: true
118
118
  subject.database 'db2', create: true
119
119
 
120
- subject.databases.should == ['db1', 'db2']
120
+ subject.databases.should eq(['db1', 'db2'])
121
121
  end
122
122
  end
123
123
 
@@ -125,71 +125,71 @@ describe LMDB do
125
125
  subject { env }
126
126
 
127
127
  it 'should create transactions' do
128
- subject.active_txn.should == nil
128
+ subject.active_txn.should be_nil
129
129
  subject.transaction do |txn|
130
- subject.active_txn.should == txn
130
+ subject.active_txn.should eq(txn)
131
131
  txn.should be_instance_of(described_class)
132
132
  txn.abort
133
- subject.active_txn.should == nil
133
+ subject.active_txn.should be_nil
134
134
  end
135
- subject.active_txn.should == nil
135
+ subject.active_txn.should be_nil
136
136
  end
137
137
 
138
138
  it 'should create read-only transactions' do
139
- subject.active_txn.should == nil
139
+ subject.active_txn.should be_nil
140
140
  subject.transaction(true) do |txn|
141
- subject.active_txn.should == txn
141
+ subject.active_txn.should eq(txn)
142
142
  txn.should be_instance_of(described_class)
143
143
  txn.abort
144
- subject.active_txn.should == nil
144
+ subject.active_txn.should be_nil
145
145
  end
146
- subject.active_txn.should == nil
146
+ subject.active_txn.should be_nil
147
147
  end
148
148
 
149
149
  it 'can create child transactions' do
150
- subject.active_txn.should == nil
150
+ subject.active_txn.should be_nil
151
151
  env.transaction do |txn|
152
- subject.active_txn.should == txn
152
+ subject.active_txn.should eq(txn)
153
153
  env.transaction do |ctxn|
154
- subject.active_txn.should == ctxn
154
+ subject.active_txn.should eq(ctxn)
155
155
  ctxn.abort
156
- subject.active_txn.should == txn
156
+ subject.active_txn.should eq(txn)
157
157
  end
158
- subject.active_txn.should == txn
158
+ subject.active_txn.should eq(txn)
159
159
  end
160
- subject.active_txn.should == nil
160
+ subject.active_txn.should be_nil
161
161
  end
162
162
 
163
163
  it 'should support aborting parent transaction' do
164
- subject.active_txn.should == nil
164
+ subject.active_txn.should be_nil
165
165
  env.transaction do |txn|
166
- subject.active_txn.should == txn
166
+ subject.active_txn.should eq(txn)
167
167
  env.transaction do |ctxn|
168
- subject.active_txn.should == ctxn
168
+ subject.active_txn.should eq(ctxn)
169
169
  db['key'] = 'value'
170
170
  txn.abort
171
- subject.active_txn.should == nil
171
+ subject.active_txn.should be_nil
172
172
  end
173
- subject.active_txn.should == nil
173
+ subject.active_txn.should be_nil
174
174
  end
175
- db['key'].should be(nil)
176
- subject.active_txn.should == nil
175
+ db['key'].should be_nil
176
+ subject.active_txn.should be_nil
177
177
  end
178
178
 
179
179
  it 'should support comitting parent transaction' do
180
- subject.active_txn.should == nil
180
+ subject.active_txn.should be_nil
181
181
  env.transaction do |txn|
182
- subject.active_txn.should == txn
182
+ subject.active_txn.should eq(txn)
183
183
  env.transaction do |ctxn|
184
- subject.active_txn.should == ctxn
184
+ subject.active_txn.should eq(ctxn)
185
185
  db['key'] = 'value'
186
186
  txn.commit
187
- subject.active_txn.should == nil
187
+ subject.active_txn.should be_nil
188
188
  end
189
- subject.active_txn.should == nil
189
+ subject.active_txn.should be_nil
190
190
  end
191
- db['key'].should == 'value'
192
- subject.active_txn.should == nil
191
+ db['key'].should eq('value')
192
+ subject.active_txn.should be_nil
193
193
  end
194
194
 
195
195
  it 'should get environment' do
@@ -197,7 +197,7 @@ describe LMDB do
197
197
  env.transaction do |txn|
198
198
  env2 = txn.env
199
199
  end
200
- env2.should == env
200
+ env2.should eq(env)
201
201
  end
202
202
  end
203
203
  end
@@ -207,8 +207,8 @@ describe LMDB do
207
207
 
208
208
  it 'should return flags' do
209
209
  subject.flags.should be_instance_of(Hash)
210
- subject.dupsort?.should == false
211
- subject.dupfixed?.should == false
210
+ subject.dupsort?.should be_falsy
211
+ subject.dupfixed?.should be_falsy
212
212
  end
213
213
 
214
214
  it 'should support named databases' do
@@ -222,19 +222,22 @@ describe LMDB do
222
222
  db1['key'] = '2'
223
223
  db2['key'] = '3'
224
224
 
225
- main['key'].should == '1'
226
- db1['key'].should == '2'
227
- db2['key'].should == '3'
225
+ main['key'].should eq(?1)
226
+ db1['key'].should eq(?2)
227
+ db2['key'].should eq(?3)
228
228
  end
229
229
 
230
230
  it 'should get/put data' do
231
231
  subject.get('cat').should be_nil
232
232
  subject.put('cat', 'garfield').should be_nil
233
- subject.get('cat').should == 'garfield'
233
+ subject.get('cat').should eq('garfield')
234
234
 
235
235
  # check for key-value pairs on non-dupsort database
236
- subject.has?('cat', 'garfield').should == true
237
- subject.has?('cat', 'heathcliff').should == false
236
+ subject.has?('cat', 'garfield').should be_truthy
237
+ subject.has?('cat', 'heathcliff').should be_falsy
238
+
239
+ subject.put?('dog', 'odie')
240
+ subject.has?('dog', 'odie').should be_truthy
238
241
  end
239
242
 
240
243
  it 'should delete by key' do
@@ -255,7 +258,7 @@ describe LMDB do
255
258
 
256
259
  it 'stores key/values in same transaction' do
257
260
  db.put('key', 'value').should be_nil
258
- db.get('key').should == 'value'
261
+ db.get('key').should eq('value')
259
262
  end
260
263
 
261
264
  it 'stores key/values in different transactions' do
@@ -268,10 +271,10 @@ describe LMDB do
268
271
  end
269
272
 
270
273
  env.transaction do
271
- db.get('key').should == 'value'
272
- db.get('key2').should == 'value2'
274
+ db.get('key').should eq('value')
275
+ db.get('key2').should eq('value2')
273
276
  env.transaction do
274
- db.get('key3').should == 'value3'
277
+ db.get('key3').should eq('value3')
275
278
  end
276
279
  end
277
280
  end
@@ -281,22 +284,22 @@ describe LMDB do
281
284
  end
282
285
 
283
286
  it 'should return size' do
284
- db.size.should == 0
287
+ db.size.should eq(0)
285
288
  db.put('key', 'value')
286
- db.size.should == 1
289
+ db.size.should eq(1)
287
290
  db.put('key2', 'value2')
288
- db.size.should == 2
291
+ db.size.should eq(2)
289
292
  end
290
293
 
291
294
  it 'should be enumerable' do
292
295
  db['k1'] = 'v1'
293
296
  db['k2'] = 'v2'
294
- db.to_a.should == [['k1', 'v1'], ['k2', 'v2']]
297
+ db.to_a.should eq([['k1', 'v1'], ['k2', 'v2']])
295
298
  end
296
299
 
297
300
  it 'should have shortcuts' do
298
301
  db['key'] = 'value'
299
- db['key'].should == 'value'
302
+ db['key'].should eq('value')
300
303
  end
301
304
 
302
305
  it 'should store binary' do
@@ -304,15 +307,15 @@ describe LMDB do
304
307
  bin2 = "\xAAx\BB\xCC2"
305
308
  db[bin1] = bin2
306
309
  db['key'] = bin2
307
- db[bin1].should == bin2
308
- db['key'].should == bin2
310
+ db[bin1].should eq(bin2)
311
+ db['key'].should eq(bin2)
309
312
  end
310
313
 
311
314
  it 'should get environment' do
312
315
  main = env.database
313
316
  db1 = env.database('db1', create: true)
314
- main.env.should == env
315
- db1.env.should == env
317
+ main.env.should eq(env)
318
+ db1.env.should eq(env)
316
319
  end
317
320
 
318
321
  it 'should iterate over/list keys' do
@@ -330,38 +333,38 @@ describe LMDB do
330
333
 
331
334
  it 'should get first key/value' do
332
335
  db.cursor do |c|
333
- c.first.should == ['key1', 'value1']
336
+ c.first.should eq(['key1', 'value1'])
334
337
  end
335
338
  end
336
339
 
337
340
  it 'should get last key/value' do
338
341
  db.cursor do |c|
339
- c.last.should == ['key2', 'value2']
342
+ c.last.should eq(['key2', 'value2'])
340
343
  end
341
344
  end
342
345
 
343
346
  it 'should get next key/value' do
344
347
  db.cursor do |c|
345
348
  c.first
346
- c.next.should == ['key2', 'value2']
349
+ c.next.should eq(['key2', 'value2'])
347
350
  end
348
351
  end
349
352
 
350
353
  it 'should seek to key' do
351
354
  db.cursor do |c|
352
- c.set('key1').should == ['key1', 'value1']
355
+ c.set('key1').should eq(['key1', 'value1'])
353
356
  end
354
357
  end
355
358
 
356
359
  it 'should seek to closest key' do
357
360
  db.cursor do |c|
358
- c.set_range('key0').should == ['key1', 'value1']
361
+ c.set_range('key0').should eq(['key1', 'value1'])
359
362
  end
360
363
  end
361
364
 
362
365
  it 'should seek to key with nuls' do
363
366
  db.cursor do |c|
364
- c.set_range('\x00').should == ['key1', 'value1']
367
+ c.set_range('\x00').should eq(['key1', 'value1'])
365
368
  end
366
369
  end
367
370
 
@@ -369,8 +372,8 @@ describe LMDB do
369
372
  db.cursor do |c|
370
373
  db.put('key0', 'value0')
371
374
  c.first
372
- c.next_range('key1').should == ['key1', 'value1']
373
- c.next_range('key1').should == nil
375
+ c.next_range('key1').should eq(['key1', 'value1'])
376
+ c.next_range('key1').should be_nil
374
377
  end
375
378
  end
376
379
 
@@ -378,34 +381,35 @@ describe LMDB do
378
381
  dupdb = env.database 'dupsort', create: true, dupsort: true
379
382
 
380
383
  # check flag while we're at it
381
- dupdb.flags[:dupsort].should == true
382
- dupdb.dupsort?.should == true
383
- dupdb.dupfixed?.should == false
384
+ dupdb.flags[:dupsort].should be_truthy
385
+ dupdb.dupsort?.should be_truthy
386
+ dupdb.dupfixed?.should be_falsy
384
387
 
385
388
  # add the no-op keyword to trigger a complaint from ruby 2.7
386
389
  dupdb.put 'key1', 'value1', nodupdata: false
387
390
  dupdb.put 'key1', 'value2'
388
391
  dupdb.put 'key2', 'value3'
389
392
  dupdb.cursor do |c|
390
- c.set('key1', 'value2').should == ['key1', 'value2']
391
- c.set('key1', 'value1').should == ['key1', 'value1']
392
- c.set('key1', 'value3').should == nil
393
+ c.set('key1', 'value2').should eq(['key1', 'value2'])
394
+ c.set('key1', 'value1').should eq(['key1', 'value1'])
395
+ c.set('key1', 'value3').should be_nil
393
396
  end
394
397
 
398
+ # this should do nothing
395
399
  dupdb.put?('key1', 'value1', nodupdata: true).should be_nil
396
400
 
397
401
  # this is basically an extended test of `cursor.set key, val`
398
- dupdb.has?('key1', 'value1').should == true
399
- dupdb.has?('key1', 'value2').should == true
400
- dupdb.has?('key1', 'value0').should == false
402
+ dupdb.has?('key1', 'value1').should be_truthy
403
+ dupdb.has?('key1', 'value2').should be_truthy
404
+ dupdb.has?('key1', 'value0').should be_falsy
401
405
 
402
406
  # match the contents of key1
403
- dupdb.each_value('key1').to_a.sort.should == ['value1', 'value2']
407
+ dupdb.each_value('key1').to_a.sort.should eq(['value1', 'value2'])
404
408
 
405
409
  # we should have two entries for key1
406
- dupdb.cardinality('key1').should == 2
410
+ dupdb.cardinality('key1').should eq(2)
407
411
 
408
- dupdb.each_key.to_a.sort.should == ['key1', 'key2']
412
+ dupdb.each_key.to_a.sort.should eq(['key1', 'key2'])
409
413
 
410
414
  # XXX move this or whatever
411
415
  env.transaction do |t|
@@ -432,7 +436,7 @@ describe LMDB do
432
436
  it 'should get database' do
433
437
  db2 = nil
434
438
  env.transaction { c = db.cursor; db2 = c.database }
435
- db2.should == db
439
+ db2.should eq(db)
436
440
  end
437
441
 
438
442
  it 'should nest a read-only txn in a read-write' do
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: lmdb
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.6
4
+ version: 0.7.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Daniel Mendler
8
8
  - Dorian Taylor
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2025-11-13 00:00:00.000000000 Z
11
+ date: 2025-11-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake