Class: LMDB::Cursor
- Inherits:
-
Object
- Object
- LMDB::Cursor
- Defined in:
- ext/lmdb_ext/lmdb_ext.c,
ext/lmdb_ext/lmdb_ext.c
Overview
A Cursor points to records in a database, and is used to iterate through the records in the database.
Cursors are created in the context of a transaction, and should only be used as long as that transaction is active. In other words, after you Transaction#commit or Transaction#abort a transaction, the cursors created while that transaction was active are no longer usable.
To create a cursor, call Database#cursor and pass it a block for that should be performed using the cursor.
Instance Method Summary collapse
-
#close ⇒ Object
Close a cursor.
-
#count ⇒ Number
Return count of duplicates for current key.
- #cursor_db ⇒ Database
-
#delete(options) ⇒ Object
Delete current key/data pair.
-
#first ⇒ Array?
Position the cursor to the first record in the database, and return its value.
-
#get ⇒ Array
Return the value of the record to which the cursor points.
-
#last ⇒ Array?
Position the cursor to the last record in the database, and return its value.
-
#next(nodup = nil) ⇒ Array?
Position the cursor to the next record in the database, and return its value.
-
#next_range ⇒ Array?
Position the cursor to the next record in the database, and return its value if the record’s key is less than or equal to the specified key, or nil otherwise.
-
#prev ⇒ Array?
Position the cursor to the previous record in the database, and return its value.
-
#put(key, value, options) ⇒ Object
Store by cursor.
-
#set(key, value = nil) ⇒ Array
Set the cursor to a specified key, optionally at the specified value if the database was opened with
:dupsort. -
#set_range(key) ⇒ Array
Set the cursor at the first key greater than or equal to a specified key.
Instance Method Details
#close ⇒ Object
1718 1719 1720 1721 1722 1723 1724 1725 |
# File 'ext/lmdb_ext/lmdb_ext.c', line 1718
static VALUE cursor_close(VALUE self) {
CURSOR_NOCHECK(self, &lmdb_cursor_type, cursor);
if (cursor->cur) {
mdb_cursor_close(cursor->cur);
cursor->cur = 0;
}
return Qnil;
}
|
#count ⇒ Number
2110 2111 2112 2113 2114 2115 |
# File 'ext/lmdb_ext/lmdb_ext.c', line 2110
static VALUE cursor_count(VALUE self) {
CURSOR(self, &lmdb_cursor_type, cursor);
size_t count;
check(mdb_cursor_count(cursor->cur, &count));
return SIZET2NUM(count);
}
|
#cursor_db ⇒ Database
2098 2099 2100 2101 |
# File 'ext/lmdb_ext/lmdb_ext.c', line 2098
static VALUE cursor_db(VALUE self) {
CURSOR(self, &lmdb_cursor_type, cursor);
return cursor->db;
}
|
#delete(options) ⇒ Object
2074 2075 2076 2077 2078 2079 2080 2081 2082 2083 2084 2085 2086 2087 2088 2089 2090 2091 2092 |
# File 'ext/lmdb_ext/lmdb_ext.c', line 2074
static VALUE cursor_delete(int argc, VALUE *argv, VALUE self) {
CURSOR(self, &lmdb_cursor_type, cursor);
VALUE option_hash;
#ifdef RB_SCAN_ARGS_KEYWORDS
rb_scan_args_kw(RB_SCAN_ARGS_LAST_HASH_KEYWORDS,
argc, argv, ":", &option_hash);
#else
rb_scan_args(argc, argv, ":", &option_hash);
#endif
int flags = 0;
if (!NIL_P(option_hash))
rb_hash_foreach(option_hash, (int (*)(ANYARGS))cursor_delete_flags,
(VALUE)&flags);
check(mdb_cursor_del(cursor->cur, flags));
return Qnil;
}
|
#first ⇒ Array?
1802 1803 1804 1805 1806 1807 1808 |
# File 'ext/lmdb_ext/lmdb_ext.c', line 1802
static VALUE cursor_first(VALUE self) {
CURSOR(self, &lmdb_cursor_type, cursor);
MDB_val key, value;
check(mdb_cursor_get(cursor->cur, &key, &value, MDB_FIRST));
return rb_assoc_new(rb_str_new(key.mv_data, key.mv_size), rb_str_new(value.mv_data, value.mv_size));
}
|
#get ⇒ Array
1983 1984 1985 1986 1987 1988 1989 1990 1991 1992 |
# File 'ext/lmdb_ext/lmdb_ext.c', line 1983
static VALUE cursor_get(VALUE self) {
CURSOR(self, &lmdb_cursor_type, cursor);
MDB_val key, value;
int ret = mdb_cursor_get(cursor->cur, &key, &value, MDB_GET_CURRENT);
if (ret == MDB_NOTFOUND)
return Qnil;
check(ret);
return rb_assoc_new(rb_str_new(key.mv_data, key.mv_size), rb_str_new(value.mv_data, value.mv_size));
}
|
#last ⇒ Array?
1817 1818 1819 1820 1821 1822 1823 |
# File 'ext/lmdb_ext/lmdb_ext.c', line 1817
static VALUE cursor_last(VALUE self) {
CURSOR(self, &lmdb_cursor_type, cursor);
MDB_val key, value;
check(mdb_cursor_get(cursor->cur, &key, &value, MDB_LAST));
return rb_assoc_new(rb_str_new(key.mv_data, key.mv_size), rb_str_new(value.mv_data, value.mv_size));
}
|
#next(nodup = nil) ⇒ Array?
1851 1852 1853 1854 1855 1856 1857 1858 1859 1860 1861 1862 1863 1864 1865 1866 1867 1868 |
# File 'ext/lmdb_ext/lmdb_ext.c', line 1851
static VALUE cursor_next(int argc, VALUE* argv, VALUE self) {
CURSOR(self, &lmdb_cursor_type, cursor);
VALUE nodup;
MDB_val key, value;
MDB_cursor_op op = MDB_NEXT;
rb_scan_args(argc, argv, "01", &nodup);
if (RTEST(nodup))
op = MDB_NEXT_NODUP;
int ret = mdb_cursor_get(cursor->cur, &key, &value, op);
if (ret == MDB_NOTFOUND)
return Qnil;
check(ret);
return rb_assoc_new(rb_str_new(key.mv_data, key.mv_size),
rb_str_new(value.mv_data, value.mv_size));
}
|
#next_range ⇒ Array?
1879 1880 1881 1882 1883 1884 1885 1886 1887 1888 1889 1890 1891 1892 1893 1894 1895 1896 1897 1898 1899 1900 |
# File 'ext/lmdb_ext/lmdb_ext.c', line 1879
static VALUE cursor_next_range(VALUE self, VALUE upper_bound_key) {
CURSOR(self, &lmdb_cursor_type, cursor);
MDB_val key, value, ub_key;
int ret = mdb_cursor_get(cursor->cur, &key, &value, MDB_NEXT);
if (ret == MDB_NOTFOUND)
return Qnil;
check(ret);
ub_key.mv_size = RSTRING_LEN(upper_bound_key);
ub_key.mv_data = StringValuePtr(upper_bound_key);
MDB_txn* txn = mdb_cursor_txn(cursor->cur);
MDB_dbi dbi = mdb_cursor_dbi(cursor->cur);
if (mdb_cmp(txn, dbi, &key, &ub_key) <= 0) {
return rb_assoc_new(rb_str_new(key.mv_data, key.mv_size),
rb_str_new(value.mv_data, value.mv_size));
} else {
return Qnil;
}
}
|
#prev ⇒ Array?
1832 1833 1834 1835 1836 1837 1838 1839 1840 1841 |
# File 'ext/lmdb_ext/lmdb_ext.c', line 1832
static VALUE cursor_prev(VALUE self) {
CURSOR(self, &lmdb_cursor_type, cursor);
MDB_val key, value;
int ret = mdb_cursor_get(cursor->cur, &key, &value, MDB_PREV);
if (ret == MDB_NOTFOUND)
return Qnil;
check(ret);
return rb_assoc_new(rb_str_new(key.mv_data, key.mv_size), rb_str_new(value.mv_data, value.mv_size));
}
|
#put(key, value, options) ⇒ Object
2031 2032 2033 2034 2035 2036 2037 2038 2039 2040 2041 2042 2043 2044 2045 2046 2047 2048 2049 2050 2051 2052 2053 2054 2055 2056 2057 2058 |
# File 'ext/lmdb_ext/lmdb_ext.c', line 2031
static VALUE cursor_put(int argc, VALUE* argv, VALUE self) {
CURSOR(self, &lmdb_cursor_type, cursor);
VALUE vkey, vval, option_hash;
#ifdef RB_SCAN_ARGS_KEYWORDS
rb_scan_args_kw(RB_SCAN_ARGS_LAST_HASH_KEYWORDS,
argc, argv, "2:", &vkey, &vval, &option_hash);
#else
rb_scan_args(argc, argv, "2:", &vkey, &vval, &option_hash);
#endif
int flags = 0;
if (!NIL_P(option_hash))
rb_hash_foreach(option_hash, (int (*)(ANYARGS))cursor_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_cursor_put(cursor->cur, &key, &value, flags));
return Qnil;
}
|
#set(key, value = nil) ⇒ Array
1910 1911 1912 1913 1914 1915 1916 1917 1918 1919 1920 1921 1922 1923 1924 1925 1926 1927 1928 1929 1930 1931 1932 1933 1934 1935 1936 1937 1938 1939 1940 1941 1942 1943 1944 1945 1946 1947 1948 1949 1950 |
# File 'ext/lmdb_ext/lmdb_ext.c', line 1910
static VALUE cursor_set(int argc, VALUE* argv, VALUE self) {
CURSOR(self, &lmdb_cursor_type, cursor);
VALUE vkey, vval;
MDB_val key, value;
MDB_cursor_op op = MDB_SET_KEY;
int ret;
rb_scan_args(argc, argv, "11", &vkey, &vval);
/*
XXX TODO: this was a nasty segfault: the key (and any
non-nil value) should be asserted to be strings, but then
if the database is `integerkeys` then perhaps we should
coerce?
*/
if (TYPE(vkey) != T_STRING)
rb_raise(rb_eArgError, "key must be a string");
key.mv_size = RSTRING_LEN(vkey);
key.mv_data = StringValuePtr(vkey);
if (!NIL_P(vval)) {
if (TYPE(vval) != T_STRING)
rb_raise(rb_eArgError, "non-nil value must be a string");
op = MDB_GET_BOTH;
value.mv_size = RSTRING_LEN(vval);
value.mv_data = StringValuePtr(vval);
}
ret = mdb_cursor_get(cursor->cur, &key, &value, op);
if (!NIL_P(vval) && ret == MDB_NOTFOUND)
return Qnil;
check(ret);
return rb_assoc_new(rb_str_new(key.mv_data, key.mv_size),
rb_str_new(value.mv_data, value.mv_size));
}
|
#set_range(key) ⇒ Array
1958 1959 1960 1961 1962 1963 1964 1965 1966 1967 1968 1969 1970 1971 1972 1973 1974 1975 |
# File 'ext/lmdb_ext/lmdb_ext.c', line 1958
static VALUE cursor_set_range(VALUE self, VALUE vkey) {
CURSOR(self, &lmdb_cursor_type, cursor);
MDB_val key, value;
int ret;
key.mv_size = RSTRING_LEN(vkey);
key.mv_data = StringValuePtr(vkey);
ret = mdb_cursor_get(cursor->cur, &key, &value, MDB_SET_RANGE);
/* not sure why we were letting this throw an exception */
if (ret == MDB_NOTFOUND) return Qnil;
check(ret);
return rb_assoc_new(rb_str_new(key.mv_data, key.mv_size),
rb_str_new(value.mv_data, value.mv_size));
}
|