Class: LMDB::Database

Inherits:
Object
  • Object
show all
Includes:
Enumerable
Defined in:
ext/lmdb_ext/lmdb_ext.c,
lib/lmdb/database.rb,
ext/lmdb_ext/lmdb_ext.c

Overview

An LMDB Database is a table of key-value pairs. It is stored as part of the Environment.

By default, each key in a Database maps to one value. However, a Database can be configured at creation to allow duplicate keys, in which case one key will map to multiple values.

A Database stores the keys in a sorted order. The order can also be set with options when the database is created.

The basic operations on a database are to #put, #get, and #delete records. One can also iterate through the records in a database using a Cursor.

Examples:

Typical usage

env = LMDB.new "databasedir"
db = env.database "databasename"
db.put "key1", "value1"
db.put "key2", "value2"
db.get "key1"              #=> "value1"
env.close

Instance Method Summary collapse

Instance Method Details

#[](key) ⇒ Object

Retrieve the value of a record from a database

Parameters:

  • key

    the record key to retrieve

Returns:

  • value of the record for that key, or nil if there is no record with that key

See Also:

  • #get(key)


26
27
28
# File 'lib/lmdb/database.rb', line 26

def [](key)
  get(key)
end

#[]=(key, value) ⇒ Object

Set (write or update) a record in a database.

Examples:

db['a'] = 'b'     #=> 'b'
db['b'] = 1234    #=> 1234
db['a']           #=> 'b'

Parameters:

  • key

    key for the record

  • value

    the value of the record

Returns:

  • returns the value of the record

See Also:

  • value)


39
40
41
42
# File 'lib/lmdb/database.rb', line 39

def []=(key, value)
  put(key, value)
  value
end

#clearObject

Note:

The clear happens transactionally.

Empty out the database

Returns:

  • nil



806
807
808
809
810
811
812
# File 'ext/lmdb_ext/lmdb_ext.c', line 806

static VALUE database_clear(VALUE self) {
        DATABASE(self, database);
        if (!active_txn(database->env))
                return call_with_transaction(database->env, self, "clear", 0, 0, 0);
        check(mdb_drop(need_txn(database->env), database->dbi, 0));
        return Qnil;
}

#cursor {|cursor| ... } ⇒ Object

Create a cursor to iterate through a database. Uses current transaction, if any. Otherwise, if called with a block, creates a new transaction for the scope of the block. Otherwise, fails.

Examples:

db = env.database "abc"
db.cursor do |c|
  key, value = c.next
  puts "#{key}: #{value}"
end

Yields:

  • (cursor)

    A block to be executed with the cursor.

Yield Parameters:

  • cursor (Cursor)

    The cursor to be used to iterate

See Also:



986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
# File 'ext/lmdb_ext/lmdb_ext.c', line 986

static VALUE database_cursor(VALUE self) {
        DATABASE(self, database);
        if (!active_txn(database->env)) {
                if (!rb_block_given_p()) {
                        rb_raise(cError, "Must call with block or active transaction.");
                }
                return call_with_transaction(database->env, self, "cursor", 0, 0, 0);
        }

        MDB_cursor* cur;
        check(mdb_cursor_open(need_txn(database->env), database->dbi, &cur));

        Cursor* cursor;
        VALUE vcur = Data_Make_Struct(cCursor, Cursor, cursor_mark, cursor_free, cursor);
        cursor->cur = cur;
        cursor->db = self;

        if (rb_block_given_p()) {
                int exception;
                VALUE ret = rb_protect(rb_yield, vcur, &exception);
                if (exception) {
                        cursor_close(vcur);
                        rb_jump_tag(exception);
                }
                cursor_close(vcur);
                return ret;
        }
        else {
                VALUE vtxn = environment_active_txn(database->env);
                if (NIL_P(vtxn)) {
                        rb_fatal("Internal error: transaction finished unexpectedly.");
                }
                else {
                        TRANSACTION(vtxn, txn);
                        rb_ary_push(txn->cursors, vcur);
                }
        }

        return vcur;
}

#delete(key, value = nil) ⇒ Object

Deletes records from the database. This function removes key/data pairs from the database. If the database does not support sorted duplicate data items (:dupsort) the value parameter is ignored. If the database supports sorted duplicates and the value parameter is nil, all of the duplicate data items for the key will be deleted. Otherwise, if the data parameter is non-nil only the matching data item will be deleted.

Parameters:

  • key

    The key of the record to delete.

  • value

    The optional value of the record to delete.

Raises:

  • (Error)

    if the specified key/value pair is not in the database.



913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
# File 'ext/lmdb_ext/lmdb_ext.c', line 913

static VALUE database_delete(int argc, VALUE *argv, VALUE self) {
        DATABASE(self, database);
        if (!active_txn(database->env))
                return call_with_transaction(database->env, self, "delete", argc, argv, 0);

        VALUE vkey, vval;
        rb_scan_args(argc, argv, "11", &vkey, &vval);

        vkey = StringValue(vkey);

        MDB_val key;
        key.mv_size = RSTRING_LEN(vkey);
        key.mv_data = RSTRING_PTR(vkey);

        if (NIL_P(vval)) {
                check(mdb_del(need_txn(database->env), database->dbi, &key, 0));
        } else {
                vval = StringValue(vval);
                MDB_val value;
                value.mv_size = RSTRING_LEN(vval);
                value.mv_data = RSTRING_PTR(vval);
                check(mdb_del(need_txn(database->env), database->dbi, &key, &value));
        }

        return Qnil;
}

#dropObject

Note:

The drop happens transactionally.

Remove a database from the environment.

Returns:

  • nil



792
793
794
795
796
797
798
# File 'ext/lmdb_ext/lmdb_ext.c', line 792

static VALUE database_drop(VALUE self) {
        DATABASE(self, database);
        if (!active_txn(database->env))
                return call_with_transaction(database->env, self, "drop", 0, 0, 0);
        check(mdb_drop(need_txn(database->env), database->dbi, 1));
        return Qnil;
}

#each {|i| ... } ⇒ Object

Iterate through the records in a database

Examples:

db.each do |record|
  key, value = record
  puts "at #{key}: #{value}"
end

Yields:

  • (i)

    Gives a record [key, value] to the block

Yield Parameters:

  • i (Array)

    The key, value pair for each record



13
14
15
16
17
18
19
# File 'lib/lmdb/database.rb', line 13

def each
  cursor do |c|
    while i = c.next
      yield(i)
    end
  end
end

#database_envEnvironment

Returns the environment to which this database belongs.

Returns:

  • (Environment)

    the environment to which this database belongs.



1031
1032
1033
1034
# File 'ext/lmdb_ext/lmdb_ext.c', line 1031

static VALUE database_env(VALUE self) {
        DATABASE(self, database);
        return database->env;
}

#get(key) ⇒ Object

Retrieves one value associated with this key. This function retrieves key/data pairs from the database. If the database supports duplicate keys (:dupsort) then the first data item for the key will be returned. Retrieval of other items requires the use of #cursor.

Parameters:

  • key

    The key of the record to retrieve.



823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
# File 'ext/lmdb_ext/lmdb_ext.c', line 823

static VALUE database_get(VALUE self, VALUE vkey) {
        DATABASE(self, database);
        if (!active_txn(database->env))
                return call_with_transaction(database->env, self, "get", 1, &vkey, MDB_RDONLY);

        vkey = StringValue(vkey);
        MDB_val key, value;
        key.mv_size = RSTRING_LEN(vkey);
        key.mv_data = RSTRING_PTR(vkey);

        int ret = mdb_get(need_txn(database->env), database->dbi, &key, &value);
        if (ret == MDB_NOTFOUND)
                return Qnil;
        check(ret);
        return rb_str_new(value.mv_data, value.mv_size);
}

#put(key, value, options) ⇒ Object

Stores items into a database. This function stores key/value pairs in the database. The default behavior is to enter the new key/value pair, replacing any previously existing key if duplicates are disallowed, or adding a duplicate data item if duplicates are allowed (:dupsort).

Parameters:

  • key

    The key of the record to set

  • value

    The value to insert for this key

Options Hash (options):

  • :nodupdata (Boolean)

    Enter the new key/value pair only if it does not already appear in the database. This flag may only be specified if the database was opened with :dupsort. The function will raise an Error if the key/data pair already appears in the database.

  • :nooverwrite (Boolean)

    Enter the new key/value pair only if the key does not already appear in the database. The function will raise an {Error] if the key already appears in the database, even if the database supports duplicates (:dupsort).

  • :append (Boolean)

    Append the given key/data pair to the end of the database. No key comparisons are performed. This option allows fast bulk loading when keys are already known to be in the correct order. Loading unsorted keys with this flag will cause data corruption.

  • :appenddup (Boolean)

    As above, but for sorted dup data.



873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
# File 'ext/lmdb_ext/lmdb_ext.c', line 873

static VALUE database_put(int argc, VALUE *argv, VALUE self) {
        DATABASE(self, database);
        if (!active_txn(database->env))
                return call_with_transaction(database->env, self, "put", argc, argv, 0);

        VALUE vkey, vval, option_hash;
        rb_scan_args(argc, argv, "2:", &vkey, &vval, &option_hash);

        int flags = 0;
        if (!NIL_P(option_hash))
                rb_hash_foreach(option_hash, database_put_flags, (VALUE)&flags);

        vkey = StringValue(vkey);
        vval = StringValue(vval);

        MDB_val key, value;
        key.mv_size = RSTRING_LEN(vkey);
        key.mv_data = RSTRING_PTR(vkey);
        value.mv_size = RSTRING_LEN(vval);
        value.mv_data = RSTRING_PTR(vval);

        check(mdb_put(need_txn(database->env), database->dbi, &key, &value, flags));
        return Qnil;
}

#sizeObject

Returns the number of records in this database.

Returns:

  • the number of records in this database



45
46
47
# File 'lib/lmdb/database.rb', line 45

def size
  stat[:entries]
end

#statHash

Return useful statistics about a database.

  • :psize Size of a database page

  • :depth Depth (height) of the B-tree

  • :branch_pages Number of internal (non-leaf) pages

  • :leaf_pages Number of leaf pages

  • :overflow_pages Number of overflow pages

  • :entries Number of data items

Returns:

  • (Hash)

    the statistics



776
777
778
779
780
781
782
783
784
# File 'ext/lmdb_ext/lmdb_ext.c', line 776

static VALUE database_stat(VALUE self) {
        DATABASE(self, database);
        if (!active_txn(database->env))
                return call_with_transaction(database->env, self, "stat", 0, 0, MDB_RDONLY);

        MDB_stat stat;
        check(mdb_stat(need_txn(database->env), database->dbi, &stat));
        return stat2hash(&stat);
}