mdbx 0.2.1 → 0.3.1
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
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +0 -0
- data/History.md +23 -0
- data/ext/mdbx_ext/database.c +203 -95
- data/lib/mdbx.rb +1 -1
- data/lib/mdbx/database.rb +32 -5
- metadata +2 -2
- metadata.gz.sig +0 -0
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 97a83bdd83e99ab3b58cf823a914c8a7b75b5b63e33e13cd00f135aa2c8988b4
|
|
4
|
+
data.tar.gz: aa6687110e91dfe083332fc93299c492ce5628ad41fe26cb36d9ee33531e1039
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 732ecf85ef600ae8edb433b18d67ecf26fbc1332fc673e7e01b20637dbcffff94735a8c1d79cc43c9d293cdda7b7532670f9a0c9f101234367b19aaac03149a9
|
|
7
|
+
data.tar.gz: 1623ff8c9d4b6e7752ef9faaf4075961119d812c7dfd78bb619fa74eaacb3e7fd1042b66b630e5638010478f61a0f3f232fa6cf2e1a37e40ef3d010a5c3257f6
|
checksums.yaml.gz.sig
CHANGED
|
Binary file
|
data.tar.gz.sig
CHANGED
|
Binary file
|
data/History.md
CHANGED
|
@@ -1,6 +1,29 @@
|
|
|
1
1
|
# Release History for MDBX
|
|
2
2
|
|
|
3
3
|
---
|
|
4
|
+
## v0.3.0 [2021-04-09] Mahlon E. Smith <mahlon@martini.nu>
|
|
5
|
+
|
|
6
|
+
Enhancements:
|
|
7
|
+
|
|
8
|
+
- Alter the behavior of #clear, so it doesn't destroy collection
|
|
9
|
+
environments, but just empties them.
|
|
10
|
+
|
|
11
|
+
- Add #drop, which explictly -does- destroy a collection environment.
|
|
12
|
+
|
|
13
|
+
- Switching to a collection now automatically creates its environment.
|
|
14
|
+
|
|
15
|
+
- Add include? and has_key?, for presence checks without allocating
|
|
16
|
+
value memory or requiring deserialization.
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
Bugfixes:
|
|
20
|
+
|
|
21
|
+
- Run all cursor methods through rb_protect, to ensure proper
|
|
22
|
+
cursor cleanup in the event of an exception mid iteration.
|
|
23
|
+
|
|
24
|
+
- Fix the block form of collections to support multiple scopes.
|
|
25
|
+
|
|
26
|
+
|
|
4
27
|
## v0.2.1 [2021-04-06] Mahlon E. Smith <mahlon@martini.nu>
|
|
5
28
|
|
|
6
29
|
Enhancement:
|
data/ext/mdbx_ext/database.c
CHANGED
|
@@ -6,7 +6,10 @@
|
|
|
6
6
|
*/
|
|
7
7
|
#define UNWRAP_DB( val, db ) \
|
|
8
8
|
rmdbx_db_t *db; \
|
|
9
|
-
TypedData_Get_Struct( val, rmdbx_db_t, &rmdbx_db_data, db )
|
|
9
|
+
TypedData_Get_Struct( val, rmdbx_db_t, &rmdbx_db_data, db )
|
|
10
|
+
|
|
11
|
+
#define CHECK_HANDLE \
|
|
12
|
+
if ( ! db->state.open ) rb_raise( rmdbx_eDatabaseError, "Closed database." )
|
|
10
13
|
|
|
11
14
|
|
|
12
15
|
VALUE rmdbx_cDatabase;
|
|
@@ -160,7 +163,7 @@ rmdbx_open_env( VALUE self )
|
|
|
160
163
|
void
|
|
161
164
|
rmdbx_open_cursor( rmdbx_db_t *db )
|
|
162
165
|
{
|
|
163
|
-
|
|
166
|
+
CHECK_HANDLE;
|
|
164
167
|
if ( ! db->txn ) rb_raise( rmdbx_eDatabaseError, "No snapshot or transaction currently open." );
|
|
165
168
|
|
|
166
169
|
int rc = mdbx_cursor_open( db->txn, db->dbi, &db->cursor );
|
|
@@ -215,11 +218,11 @@ rmdbx_close_txn( rmdbx_db_t *db, int txnflag )
|
|
|
215
218
|
{
|
|
216
219
|
if ( ! db->txn || db->state.retain_txn > -1 ) return;
|
|
217
220
|
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
221
|
+
if ( txnflag == RMDBX_TXN_COMMIT ) {
|
|
222
|
+
mdbx_txn_commit( db->txn );
|
|
223
|
+
}
|
|
224
|
+
else {
|
|
225
|
+
mdbx_txn_abort( db->txn );
|
|
223
226
|
}
|
|
224
227
|
|
|
225
228
|
db->txn = 0;
|
|
@@ -239,6 +242,7 @@ VALUE
|
|
|
239
242
|
rmdbx_rb_opentxn( VALUE self, VALUE mode )
|
|
240
243
|
{
|
|
241
244
|
UNWRAP_DB( self, db );
|
|
245
|
+
CHECK_HANDLE;
|
|
242
246
|
|
|
243
247
|
rmdbx_open_txn( db, RTEST(mode) ? MDBX_TXN_READWRITE : MDBX_TXN_RDONLY );
|
|
244
248
|
db->state.retain_txn = RTEST(mode) ? 1 : 0;
|
|
@@ -273,13 +277,53 @@ rmdbx_rb_closetxn( VALUE self, VALUE write )
|
|
|
273
277
|
*
|
|
274
278
|
* Empty the current collection on disk. If collections are not enabled
|
|
275
279
|
* or the database handle is set to the top-level (main) db - this
|
|
276
|
-
* deletes *all records* from the database.
|
|
280
|
+
* deletes *all records* from the database.
|
|
277
281
|
*/
|
|
278
282
|
VALUE
|
|
279
283
|
rmdbx_clear( VALUE self )
|
|
280
284
|
{
|
|
281
285
|
UNWRAP_DB( self, db );
|
|
282
286
|
|
|
287
|
+
rmdbx_open_txn( db, MDBX_TXN_READWRITE );
|
|
288
|
+
int rc = mdbx_drop( db->txn, db->dbi, false );
|
|
289
|
+
|
|
290
|
+
if ( rc != MDBX_SUCCESS )
|
|
291
|
+
rb_raise( rmdbx_eDatabaseError, "mdbx_drop: (%d) %s", rc, mdbx_strerror(rc) );
|
|
292
|
+
|
|
293
|
+
rmdbx_close_txn( db, RMDBX_TXN_COMMIT );
|
|
294
|
+
|
|
295
|
+
return Qnil;
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
|
|
299
|
+
/*
|
|
300
|
+
* call-seq:
|
|
301
|
+
* db.drop( collection ) -> db
|
|
302
|
+
*
|
|
303
|
+
* Destroy a collection. You must be in the top level database to call
|
|
304
|
+
* this method.
|
|
305
|
+
*/
|
|
306
|
+
VALUE
|
|
307
|
+
rmdbx_drop( VALUE self, VALUE name )
|
|
308
|
+
{
|
|
309
|
+
UNWRAP_DB( self, db );
|
|
310
|
+
|
|
311
|
+
/* Provide a friendlier error message if max_collections is 0. */
|
|
312
|
+
if ( db->settings.max_collections == 0 )
|
|
313
|
+
rb_raise( rmdbx_eDatabaseError, "Unable to drop collection: collections are not enabled." );
|
|
314
|
+
|
|
315
|
+
/* All transactions must be closed when dropping a database. */
|
|
316
|
+
if ( db->txn )
|
|
317
|
+
rb_raise( rmdbx_eDatabaseError, "Unable to drop collection: transaction open" );
|
|
318
|
+
|
|
319
|
+
/* A drop can only be performed from the top-level database. */
|
|
320
|
+
if ( db->subdb != NULL )
|
|
321
|
+
rb_raise( rmdbx_eDatabaseError, "Unable to drop collection: switch to top-level db first" );
|
|
322
|
+
|
|
323
|
+
name = rb_funcall( name, rb_intern("to_s"), 0 );
|
|
324
|
+
db->subdb = StringValueCStr( name );
|
|
325
|
+
|
|
326
|
+
rmdbx_close_dbi( db ); /* ensure we're reopening within the new subdb */
|
|
283
327
|
rmdbx_open_txn( db, MDBX_TXN_READWRITE );
|
|
284
328
|
int rc = mdbx_drop( db->txn, db->dbi, true );
|
|
285
329
|
|
|
@@ -288,10 +332,11 @@ rmdbx_clear( VALUE self )
|
|
|
288
332
|
|
|
289
333
|
rmdbx_close_txn( db, RMDBX_TXN_COMMIT );
|
|
290
334
|
|
|
291
|
-
/*
|
|
292
|
-
|
|
335
|
+
/* Reset the current collection to the top level. */
|
|
336
|
+
db->subdb = NULL;
|
|
337
|
+
rmdbx_close_dbi( db ); /* ensure next access is not in the defunct subdb */
|
|
293
338
|
|
|
294
|
-
return
|
|
339
|
+
return self;
|
|
295
340
|
}
|
|
296
341
|
|
|
297
342
|
|
|
@@ -348,21 +393,15 @@ rmdbx_deserialize( VALUE self, VALUE val )
|
|
|
348
393
|
}
|
|
349
394
|
|
|
350
395
|
|
|
351
|
-
/*
|
|
352
|
-
*
|
|
353
|
-
*
|
|
354
|
-
* Calls the block once for each key, returning self.
|
|
355
|
-
* A transaction must be opened prior to use.
|
|
396
|
+
/*
|
|
397
|
+
* Enumerate over keys for the current collection.
|
|
356
398
|
*/
|
|
357
399
|
VALUE
|
|
358
|
-
|
|
400
|
+
rmdbx_each_key_i( VALUE self )
|
|
359
401
|
{
|
|
360
402
|
UNWRAP_DB( self, db );
|
|
361
403
|
MDBX_val key, data;
|
|
362
404
|
|
|
363
|
-
rmdbx_open_cursor( db );
|
|
364
|
-
RETURN_ENUMERATOR( self, 0, 0 );
|
|
365
|
-
|
|
366
405
|
if ( mdbx_cursor_get( db->cursor, &key, &data, MDBX_FIRST ) == MDBX_SUCCESS ) {
|
|
367
406
|
rb_yield( rb_str_new( key.iov_base, key.iov_len ) );
|
|
368
407
|
while ( mdbx_cursor_get( db->cursor, &key, &data, MDBX_NEXT ) == MDBX_SUCCESS ) {
|
|
@@ -370,27 +409,45 @@ rmdbx_each_key( VALUE self )
|
|
|
370
409
|
}
|
|
371
410
|
}
|
|
372
411
|
|
|
373
|
-
mdbx_cursor_close( db->cursor );
|
|
374
|
-
db->cursor = NULL;
|
|
375
412
|
return self;
|
|
376
413
|
}
|
|
377
414
|
|
|
378
415
|
|
|
379
416
|
/* call-seq:
|
|
380
|
-
* db.
|
|
417
|
+
* db.each_key {|key| block } => self
|
|
381
418
|
*
|
|
382
|
-
* Calls the block once for each
|
|
419
|
+
* Calls the block once for each key, returning self.
|
|
383
420
|
* A transaction must be opened prior to use.
|
|
384
421
|
*/
|
|
385
422
|
VALUE
|
|
386
|
-
|
|
423
|
+
rmdbx_each_key( VALUE self )
|
|
387
424
|
{
|
|
388
425
|
UNWRAP_DB( self, db );
|
|
389
|
-
|
|
426
|
+
int state;
|
|
390
427
|
|
|
428
|
+
CHECK_HANDLE;
|
|
391
429
|
rmdbx_open_cursor( db );
|
|
392
430
|
RETURN_ENUMERATOR( self, 0, 0 );
|
|
393
431
|
|
|
432
|
+
rb_protect( rmdbx_each_key_i, self, &state );
|
|
433
|
+
|
|
434
|
+
mdbx_cursor_close( db->cursor );
|
|
435
|
+
db->cursor = NULL;
|
|
436
|
+
|
|
437
|
+
if ( state ) rb_jump_tag( state );
|
|
438
|
+
|
|
439
|
+
return self;
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
|
|
443
|
+
/* Enumerate over values for the current collection.
|
|
444
|
+
*/
|
|
445
|
+
VALUE
|
|
446
|
+
rmdbx_each_value_i( VALUE self )
|
|
447
|
+
{
|
|
448
|
+
UNWRAP_DB( self, db );
|
|
449
|
+
MDBX_val key, data;
|
|
450
|
+
|
|
394
451
|
if ( mdbx_cursor_get( db->cursor, &key, &data, MDBX_FIRST ) == MDBX_SUCCESS ) {
|
|
395
452
|
VALUE rv = rb_str_new( data.iov_base, data.iov_len );
|
|
396
453
|
rb_yield( rmdbx_deserialize( self, rv ) );
|
|
@@ -401,27 +458,45 @@ rmdbx_each_value( VALUE self )
|
|
|
401
458
|
}
|
|
402
459
|
}
|
|
403
460
|
|
|
404
|
-
mdbx_cursor_close( db->cursor );
|
|
405
|
-
db->cursor = NULL;
|
|
406
461
|
return self;
|
|
407
462
|
}
|
|
408
463
|
|
|
409
464
|
|
|
410
465
|
/* call-seq:
|
|
411
|
-
* db.
|
|
466
|
+
* db.each_value {|value| block } => self
|
|
412
467
|
*
|
|
413
|
-
* Calls the block once for each
|
|
468
|
+
* Calls the block once for each value, returning self.
|
|
414
469
|
* A transaction must be opened prior to use.
|
|
415
470
|
*/
|
|
416
471
|
VALUE
|
|
417
|
-
|
|
472
|
+
rmdbx_each_value( VALUE self )
|
|
418
473
|
{
|
|
419
474
|
UNWRAP_DB( self, db );
|
|
420
|
-
|
|
475
|
+
int state;
|
|
421
476
|
|
|
477
|
+
CHECK_HANDLE;
|
|
422
478
|
rmdbx_open_cursor( db );
|
|
423
479
|
RETURN_ENUMERATOR( self, 0, 0 );
|
|
424
480
|
|
|
481
|
+
rb_protect( rmdbx_each_value_i, self, &state );
|
|
482
|
+
|
|
483
|
+
mdbx_cursor_close( db->cursor );
|
|
484
|
+
db->cursor = NULL;
|
|
485
|
+
|
|
486
|
+
if ( state ) rb_jump_tag( state );
|
|
487
|
+
|
|
488
|
+
return self;
|
|
489
|
+
}
|
|
490
|
+
|
|
491
|
+
|
|
492
|
+
/* Enumerate over key and value pairs for the current collection.
|
|
493
|
+
*/
|
|
494
|
+
VALUE
|
|
495
|
+
rmdbx_each_pair_i( VALUE self )
|
|
496
|
+
{
|
|
497
|
+
UNWRAP_DB( self, db );
|
|
498
|
+
MDBX_val key, data;
|
|
499
|
+
|
|
425
500
|
if ( mdbx_cursor_get( db->cursor, &key, &data, MDBX_FIRST ) == MDBX_SUCCESS ) {
|
|
426
501
|
VALUE rkey = rb_str_new( key.iov_base, key.iov_len );
|
|
427
502
|
VALUE rval = rb_str_new( data.iov_base, data.iov_len );
|
|
@@ -434,12 +509,38 @@ rmdbx_each_pair( VALUE self )
|
|
|
434
509
|
}
|
|
435
510
|
}
|
|
436
511
|
|
|
512
|
+
return self;
|
|
513
|
+
}
|
|
514
|
+
|
|
515
|
+
|
|
516
|
+
/* call-seq:
|
|
517
|
+
* db.each_pair {|key, value| block } => self
|
|
518
|
+
*
|
|
519
|
+
* Calls the block once for each key and value, returning self.
|
|
520
|
+
* A transaction must be opened prior to use.
|
|
521
|
+
*/
|
|
522
|
+
VALUE
|
|
523
|
+
rmdbx_each_pair( VALUE self )
|
|
524
|
+
{
|
|
525
|
+
UNWRAP_DB( self, db );
|
|
526
|
+
int state;
|
|
527
|
+
|
|
528
|
+
CHECK_HANDLE;
|
|
529
|
+
rmdbx_open_cursor( db );
|
|
530
|
+
RETURN_ENUMERATOR( self, 0, 0 );
|
|
531
|
+
|
|
532
|
+
rb_protect( rmdbx_each_pair_i, self, &state );
|
|
533
|
+
|
|
437
534
|
mdbx_cursor_close( db->cursor );
|
|
438
535
|
db->cursor = NULL;
|
|
536
|
+
|
|
537
|
+
if ( state ) rb_jump_tag( state );
|
|
538
|
+
|
|
439
539
|
return self;
|
|
440
540
|
}
|
|
441
541
|
|
|
442
542
|
|
|
543
|
+
|
|
443
544
|
/* call-seq:
|
|
444
545
|
* db.length -> Integer
|
|
445
546
|
*
|
|
@@ -451,7 +552,7 @@ rmdbx_length( VALUE self )
|
|
|
451
552
|
UNWRAP_DB( self, db );
|
|
452
553
|
MDBX_stat mstat;
|
|
453
554
|
|
|
454
|
-
|
|
555
|
+
CHECK_HANDLE;
|
|
455
556
|
rmdbx_open_txn( db, MDBX_TXN_RDONLY );
|
|
456
557
|
|
|
457
558
|
int rc = mdbx_dbi_stat( db->txn, db->dbi, &mstat, sizeof(mstat) );
|
|
@@ -465,6 +566,39 @@ rmdbx_length( VALUE self )
|
|
|
465
566
|
}
|
|
466
567
|
|
|
467
568
|
|
|
569
|
+
/* call-seq:
|
|
570
|
+
* db.include?( 'key' ) => bool
|
|
571
|
+
*
|
|
572
|
+
* Returns true if the current collection contains +key+.
|
|
573
|
+
*/
|
|
574
|
+
VALUE
|
|
575
|
+
rmdbx_include( VALUE self, VALUE key )
|
|
576
|
+
{
|
|
577
|
+
int rc;
|
|
578
|
+
UNWRAP_DB( self, db );
|
|
579
|
+
|
|
580
|
+
CHECK_HANDLE;
|
|
581
|
+
rmdbx_open_txn( db, MDBX_TXN_RDONLY );
|
|
582
|
+
|
|
583
|
+
MDBX_val ckey = rmdbx_key_for( key );
|
|
584
|
+
MDBX_val data;
|
|
585
|
+
rc = mdbx_get( db->txn, db->dbi, &ckey, &data );
|
|
586
|
+
rmdbx_close_txn( db, RMDBX_TXN_ROLLBACK );
|
|
587
|
+
|
|
588
|
+
switch ( rc ) {
|
|
589
|
+
case MDBX_SUCCESS:
|
|
590
|
+
return Qtrue;
|
|
591
|
+
|
|
592
|
+
case MDBX_NOTFOUND:
|
|
593
|
+
return Qfalse;
|
|
594
|
+
|
|
595
|
+
default:
|
|
596
|
+
rmdbx_close( self );
|
|
597
|
+
rb_raise( rmdbx_eDatabaseError, "Unable to fetch key: (%d) %s", rc, mdbx_strerror(rc) );
|
|
598
|
+
}
|
|
599
|
+
}
|
|
600
|
+
|
|
601
|
+
|
|
468
602
|
/* call-seq:
|
|
469
603
|
* db[ 'key' ] => value
|
|
470
604
|
*
|
|
@@ -476,7 +610,7 @@ rmdbx_get_val( VALUE self, VALUE key )
|
|
|
476
610
|
int rc;
|
|
477
611
|
UNWRAP_DB( self, db );
|
|
478
612
|
|
|
479
|
-
|
|
613
|
+
CHECK_HANDLE;
|
|
480
614
|
rmdbx_open_txn( db, MDBX_TXN_RDONLY );
|
|
481
615
|
|
|
482
616
|
MDBX_val ckey = rmdbx_key_for( key );
|
|
@@ -503,7 +637,8 @@ rmdbx_get_val( VALUE self, VALUE key )
|
|
|
503
637
|
/* call-seq:
|
|
504
638
|
* db[ 'key' ] = value
|
|
505
639
|
*
|
|
506
|
-
* Set a single value for +key+.
|
|
640
|
+
* Set a single value for +key+. If the value is +nil+, the
|
|
641
|
+
* key is removed.
|
|
507
642
|
*/
|
|
508
643
|
VALUE
|
|
509
644
|
rmdbx_put_val( VALUE self, VALUE key, VALUE val )
|
|
@@ -511,7 +646,7 @@ rmdbx_put_val( VALUE self, VALUE key, VALUE val )
|
|
|
511
646
|
int rc;
|
|
512
647
|
UNWRAP_DB( self, db );
|
|
513
648
|
|
|
514
|
-
|
|
649
|
+
CHECK_HANDLE;
|
|
515
650
|
rmdbx_open_txn( db, MDBX_TXN_READWRITE );
|
|
516
651
|
|
|
517
652
|
MDBX_val ckey = rmdbx_key_for( key );
|
|
@@ -552,41 +687,32 @@ VALUE
|
|
|
552
687
|
rmdbx_stats( VALUE self )
|
|
553
688
|
{
|
|
554
689
|
UNWRAP_DB( self, db );
|
|
555
|
-
|
|
690
|
+
CHECK_HANDLE;
|
|
556
691
|
|
|
557
692
|
return rmdbx_gather_stats( db );
|
|
558
693
|
}
|
|
559
694
|
|
|
560
695
|
|
|
561
696
|
/*
|
|
562
|
-
*
|
|
563
|
-
*
|
|
564
|
-
* db.collection( 'collection_name' ) -> db
|
|
565
|
-
* db.collection( nil ) -> db (main)
|
|
566
|
-
*
|
|
567
|
-
* Gets or sets the sub-database "collection" that read/write
|
|
568
|
-
* operations apply to.
|
|
569
|
-
* Passing +nil+ sets the database to the main, top-level namespace.
|
|
570
|
-
* If a block is passed, the collection automatically reverts to the
|
|
571
|
-
* prior collection when it exits.
|
|
572
|
-
*
|
|
573
|
-
* db.collection( 'collection_name' ) do
|
|
574
|
-
* [ ... ]
|
|
575
|
-
* end # reverts to the previous collection name
|
|
576
|
-
*
|
|
697
|
+
* Return the currently selected collection, or +nil+ if at the
|
|
698
|
+
* top-level.
|
|
577
699
|
*/
|
|
578
700
|
VALUE
|
|
579
|
-
|
|
701
|
+
rmdbx_get_subdb( VALUE self )
|
|
580
702
|
{
|
|
581
703
|
UNWRAP_DB( self, db );
|
|
582
|
-
|
|
583
|
-
|
|
704
|
+
return ( db->subdb == NULL ) ? Qnil : rb_str_new_cstr( db->subdb );
|
|
705
|
+
}
|
|
584
706
|
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
707
|
+
|
|
708
|
+
/*
|
|
709
|
+
* Sets the current collection name for read/write operations.
|
|
710
|
+
*
|
|
711
|
+
*/
|
|
712
|
+
VALUE
|
|
713
|
+
rmdbx_set_subdb( VALUE self, VALUE name )
|
|
714
|
+
{
|
|
715
|
+
UNWRAP_DB( self, db );
|
|
590
716
|
|
|
591
717
|
/* Provide a friendlier error message if max_collections is 0. */
|
|
592
718
|
if ( db->settings.max_collections == 0 )
|
|
@@ -596,38 +722,14 @@ rmdbx_set_subdb( int argc, VALUE *argv, VALUE self )
|
|
|
596
722
|
if ( db->txn )
|
|
597
723
|
rb_raise( rmdbx_eDatabaseError, "Unable to change collection: transaction open" );
|
|
598
724
|
|
|
599
|
-
|
|
600
|
-
*/
|
|
601
|
-
if ( rb_block_given_p() && db->subdb != NULL ) {
|
|
602
|
-
prev_db = (char *) malloc( strlen(db->subdb) + 1 );
|
|
603
|
-
strcpy( prev_db, db->subdb );
|
|
604
|
-
}
|
|
725
|
+
db->subdb = NIL_P( name ) ? NULL : StringValueCStr( name );
|
|
605
726
|
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
else {
|
|
610
|
-
subdb = rb_funcall( subdb, rb_intern("to_s"), 0 );
|
|
611
|
-
db->subdb = StringValueCStr( subdb );
|
|
612
|
-
}
|
|
727
|
+
/* Reset the db handle and issue a single transaction to reify
|
|
728
|
+
the collection.
|
|
729
|
+
*/
|
|
613
730
|
rmdbx_close_dbi( db );
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
FIXME: Immediate transaction write to auto-create new env?
|
|
617
|
-
Fetching from here at the moment causes an error if you
|
|
618
|
-
haven't written anything to the new collection yet.
|
|
619
|
-
*/
|
|
620
|
-
|
|
621
|
-
/* Revert to the previous collection after the block is done.
|
|
622
|
-
*/
|
|
623
|
-
if ( rb_block_given_p() ) {
|
|
624
|
-
rb_yield( self );
|
|
625
|
-
if ( db->subdb != prev_db ) {
|
|
626
|
-
db->subdb = prev_db;
|
|
627
|
-
rmdbx_close_dbi( db );
|
|
628
|
-
}
|
|
629
|
-
xfree( prev_db );
|
|
630
|
-
}
|
|
731
|
+
rmdbx_open_txn( db, MDBX_TXN_READWRITE );
|
|
732
|
+
rmdbx_close_txn( db, RMDBX_TXN_COMMIT );
|
|
631
733
|
|
|
632
734
|
return self;
|
|
633
735
|
}
|
|
@@ -767,16 +869,18 @@ rmdbx_init_database()
|
|
|
767
869
|
|
|
768
870
|
rb_define_protected_method( rmdbx_cDatabase, "initialize", rmdbx_database_initialize, -1 );
|
|
769
871
|
rb_define_protected_method( rmdbx_cDatabase, "initialize_copy", rmdbx_init_copy, 1 );
|
|
770
|
-
|
|
872
|
+
|
|
873
|
+
rb_define_method( rmdbx_cDatabase, "clear", rmdbx_clear, 0 );
|
|
771
874
|
rb_define_method( rmdbx_cDatabase, "close", rmdbx_close, 0 );
|
|
772
|
-
rb_define_method( rmdbx_cDatabase, "reopen", rmdbx_open_env, 0 );
|
|
773
875
|
rb_define_method( rmdbx_cDatabase, "closed?", rmdbx_closed_p, 0 );
|
|
774
|
-
rb_define_method( rmdbx_cDatabase, "
|
|
775
|
-
rb_define_method( rmdbx_cDatabase, "clear", rmdbx_clear, 0 );
|
|
876
|
+
rb_define_method( rmdbx_cDatabase, "drop", rmdbx_drop, 1 );
|
|
776
877
|
rb_define_method( rmdbx_cDatabase, "each_key", rmdbx_each_key, 0 );
|
|
777
|
-
rb_define_method( rmdbx_cDatabase, "each_value", rmdbx_each_value, 0 );
|
|
778
878
|
rb_define_method( rmdbx_cDatabase, "each_pair", rmdbx_each_pair, 0 );
|
|
879
|
+
rb_define_method( rmdbx_cDatabase, "each_value", rmdbx_each_value, 0 );
|
|
880
|
+
rb_define_method( rmdbx_cDatabase, "in_transaction?", rmdbx_in_transaction_p, 0 );
|
|
881
|
+
rb_define_method( rmdbx_cDatabase, "include?", rmdbx_include, 1 );
|
|
779
882
|
rb_define_method( rmdbx_cDatabase, "length", rmdbx_length, 0 );
|
|
883
|
+
rb_define_method( rmdbx_cDatabase, "reopen", rmdbx_open_env, 0 );
|
|
780
884
|
rb_define_method( rmdbx_cDatabase, "[]", rmdbx_get_val, 1 );
|
|
781
885
|
rb_define_method( rmdbx_cDatabase, "[]=", rmdbx_put_val, 2 );
|
|
782
886
|
|
|
@@ -784,6 +888,10 @@ rmdbx_init_database()
|
|
|
784
888
|
rb_define_protected_method( rmdbx_cDatabase, "open_transaction", rmdbx_rb_opentxn, 1 );
|
|
785
889
|
rb_define_protected_method( rmdbx_cDatabase, "close_transaction", rmdbx_rb_closetxn, 1 );
|
|
786
890
|
|
|
891
|
+
/* Collection functions */
|
|
892
|
+
rb_define_protected_method( rmdbx_cDatabase, "get_subdb", rmdbx_get_subdb, 0 );
|
|
893
|
+
rb_define_protected_method( rmdbx_cDatabase, "set_subdb", rmdbx_set_subdb, 1 );
|
|
894
|
+
|
|
787
895
|
rb_define_protected_method( rmdbx_cDatabase, "raw_stats", rmdbx_stats, 0 );
|
|
788
896
|
|
|
789
897
|
rb_require( "mdbx/database" );
|
data/lib/mdbx.rb
CHANGED
data/lib/mdbx/database.rb
CHANGED
|
@@ -128,16 +128,43 @@ class MDBX::Database
|
|
|
128
128
|
attr_accessor :deserializer
|
|
129
129
|
|
|
130
130
|
|
|
131
|
+
alias_method :size, :length
|
|
132
|
+
alias_method :each, :each_pair
|
|
133
|
+
alias_method :has_key?, :include?
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
### Gets or sets the sub-database "collection" that read/write
|
|
137
|
+
### operations apply to. If a block is passed, the collection
|
|
138
|
+
### automatically reverts to the prior collection when it exits.
|
|
139
|
+
###
|
|
140
|
+
### db.collection #=> (collection name, or nil if in main)
|
|
141
|
+
### db.collection( 'collection_name' ) #=> db
|
|
142
|
+
###
|
|
143
|
+
### db.collection( 'collection_name' ) do
|
|
144
|
+
### [ ... ]
|
|
145
|
+
### end # reverts to the previous collection name
|
|
146
|
+
###
|
|
147
|
+
def collection( name=nil )
|
|
148
|
+
current = self.get_subdb
|
|
149
|
+
return current unless name
|
|
150
|
+
|
|
151
|
+
self.set_subdb( name.to_s )
|
|
152
|
+
yield( self ) if block_given?
|
|
153
|
+
|
|
154
|
+
return self
|
|
155
|
+
|
|
156
|
+
ensure
|
|
157
|
+
self.set_subdb( current ) if name && block_given?
|
|
158
|
+
end
|
|
159
|
+
alias_method :namespace, :collection
|
|
160
|
+
|
|
161
|
+
|
|
131
162
|
### Switch to the top-level collection.
|
|
132
163
|
###
|
|
133
164
|
def main
|
|
134
|
-
return self.
|
|
165
|
+
return self.set_subdb( nil )
|
|
135
166
|
end
|
|
136
167
|
|
|
137
|
-
alias_method :namespace, :collection
|
|
138
|
-
alias_method :size, :length
|
|
139
|
-
alias_method :each, :each_pair
|
|
140
|
-
|
|
141
168
|
|
|
142
169
|
#
|
|
143
170
|
# Transaction methods
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: mdbx
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.3.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Mahlon E. Smith
|
|
@@ -34,7 +34,7 @@ cert_chain:
|
|
|
34
34
|
49pOzX5KHZLTS9DKeaP/xcGPz6C8MiwQdYrZarr2SHRASX1zFa79rkItO8kE6RDr
|
|
35
35
|
b6WDF79UvZ55ajtE00TiwqjQL/ZPEtbd
|
|
36
36
|
-----END CERTIFICATE-----
|
|
37
|
-
date: 2021-
|
|
37
|
+
date: 2021-05-16 00:00:00.000000000 Z
|
|
38
38
|
dependencies:
|
|
39
39
|
- !ruby/object:Gem::Dependency
|
|
40
40
|
name: pry
|
metadata.gz.sig
CHANGED
|
Binary file
|