class BDB::Cursor

Public Instance Methods

c_clone(p1 = v1) click to toggle source
static VALUE
bdb_cursor_dup(int argc, VALUE *argv, VALUE obj)
{
    int flags = 0;
    VALUE a, b;
    bdb_DBC *dbcst, *dbcstdup;
    bdb_DB *dbst;
    DBC *dbcdup;
    
    if (rb_scan_args(argc, argv, "01", &a))
        flags = NUM2INT(a);
    GetCursorDB(obj, dbcst, dbst);
    bdb_test_error(dbcst->dbc->c_dup(dbcst->dbc, &dbcdup, flags));
    b = Data_Make_Struct(bdb_cCursor, bdb_DBC, 0, bdb_cursor_free, dbcstdup);
    dbcstdup->dbc = dbcdup;
    dbcstdup->db = dbcst->db;
    return b;
}
c_close() click to toggle source
static VALUE
bdb_cursor_close(VALUE obj)
{
    bdb_DBC *dbcst;
    bdb_DB *dbst;
    
    if (!OBJ_TAINTED(obj) && rb_safe_level() >= 4)
        rb_raise(rb_eSecurityError, "Insecure: can't close the cursor");
    GetCursorDB(obj, dbcst, dbst);
    bdb_test_error(dbcst->dbc->c_close(dbcst->dbc));
    dbcst->dbc = NULL;
    return Qtrue;
}
c_count() click to toggle source
static VALUE
bdb_cursor_count(VALUE obj)
{
#if !HAVE_CONST_DB_NEXT_DUP
    rb_raise(bdb_eFatal, "DB_NEXT_DUP needs Berkeley DB 2.6 or later");
#else
#if !HAVE_ST_DBC_C_COUNT
    DBT key, data;
    DBT key_o, data_o;
    int ret;
#endif
    bdb_DBC *dbcst;
    bdb_DB *dbst;
    db_recno_t count;

    GetCursorDB(obj, dbcst, dbst);
#if HAVE_ST_DBC_C_COUNT
    bdb_test_error(dbcst->dbc->c_count(dbcst->dbc, &count, 0));
    return INT2NUM(count);
#else
    MEMZERO(&key, DBT, 1);
    key.flags |= DB_DBT_MALLOC;
    MEMZERO(&data, DBT, 1);
    data.flags |= DB_DBT_MALLOC;
    MEMZERO(&key_o, DBT, 1);
    key_o.flags |= DB_DBT_MALLOC;
    MEMZERO(&data_o, DBT, 1);
    data_o.flags |= DB_DBT_MALLOC;
    SET_PARTIAL(dbst, data);
    ret = bdb_test_error(dbcst->dbc->c_get(dbcst->dbc, &key_o, &data_o, DB_CURRENT));
    if (ret == DB_NOTFOUND || ret == DB_KEYEMPTY)
        return INT2NUM(0);
    count = 1;
    while (1) {
        MEMZERO(&key, DBT, 1);
        key.flags |= DB_DBT_MALLOC;
        MEMZERO(&data, DBT, 1);
        data.flags |= DB_DBT_MALLOC;
        SET_PARTIAL(dbst, data);
        ret = bdb_test_error(dbcst->dbc->c_get(dbcst->dbc, &key, &data, DB_NEXT_DUP));
        if (ret == DB_NOTFOUND) {
            MEMZERO(&key_o, DBT, 1);
            key_o.flags |= DB_DBT_MALLOC;
            MEMZERO(&data_o, DBT, 1);
            data_o.flags |= DB_DBT_MALLOC;
            bdb_test_error(dbcst->dbc->c_get(dbcst->dbc, &key_o, &data_o, DB_SET));

            FREE_KEY(dbst, key_o);
            free(data_o.data);
            return INT2NUM(count);
        }
        if (ret == DB_KEYEMPTY) continue;
        FREE_KEY(dbst, key);
        free(data.data);
        count++;
    }
    return INT2NUM(-1);
#endif
#endif
}
c_current() click to toggle source
static VALUE
bdb_cursor_current(VALUE obj)
{
    return bdb_cursor_xxx(obj, DB_CURRENT);
}
c_del() click to toggle source
static VALUE
bdb_cursor_del(VALUE obj)
{
    int flags = 0;
    bdb_DBC *dbcst;
    bdb_DB *dbst;
    
    rb_secure(4);
    GetCursorDB(obj, dbcst, dbst);
    bdb_test_error(dbcst->dbc->c_del(dbcst->dbc, flags));
    return Qtrue;
}
c_dup(p1 = v1) click to toggle source
static VALUE
bdb_cursor_dup(int argc, VALUE *argv, VALUE obj)
{
    int flags = 0;
    VALUE a, b;
    bdb_DBC *dbcst, *dbcstdup;
    bdb_DB *dbst;
    DBC *dbcdup;
    
    if (rb_scan_args(argc, argv, "01", &a))
        flags = NUM2INT(a);
    GetCursorDB(obj, dbcst, dbst);
    bdb_test_error(dbcst->dbc->c_dup(dbcst->dbc, &dbcdup, flags));
    b = Data_Make_Struct(bdb_cCursor, bdb_DBC, 0, bdb_cursor_free, dbcstdup);
    dbcstdup->dbc = dbcdup;
    dbcstdup->db = dbcst->db;
    return b;
}
c_first() click to toggle source
static VALUE
bdb_cursor_first(VALUE obj)
{
    return bdb_cursor_xxx(obj, DB_FIRST);
}
c_get(*args) click to toggle source
static VALUE
bdb_cursor_get(int argc, VALUE *argv, VALUE obj)
{
    return bdb_cursor_get_common(argc, argv, obj, 0);
}
c_last() click to toggle source
static VALUE
bdb_cursor_last(VALUE obj)
{
    return bdb_cursor_xxx(obj, DB_LAST);
}
c_next() click to toggle source
static VALUE
bdb_cursor_next(VALUE obj)
{
    return bdb_cursor_xxx(obj, DB_NEXT);
}
c_next_dup() click to toggle source
static VALUE
bdb_cursor_next_dup(VALUE obj)
{
    return bdb_cursor_xxx(obj, DB_NEXT_DUP);
}
c_pget(*args) click to toggle source
static VALUE
bdb_cursor_pget(int argc, VALUE *argv, VALUE obj)
{
    return bdb_cursor_get_common(argc, argv, obj, 1);
}
c_prev() click to toggle source
static VALUE
bdb_cursor_prev(VALUE obj)
{
    return bdb_cursor_xxx(obj, DB_PREV);
}
c_put(p1, p2, p3 = v3) click to toggle source
static VALUE
bdb_cursor_put(int argc, VALUE *argv, VALUE obj)
{
    int flags, cnt;
    DBT key, data;
    bdb_DBC *dbcst;
    bdb_DB *dbst;
    VALUE a, b, c, f;
    volatile VALUE d = Qnil;
    volatile VALUE e = Qnil;
    db_recno_t recno;
    int ret;

    rb_secure(4);
    MEMZERO(&key, DBT, 1);
    MEMZERO(&data, DBT, 1);
    cnt = rb_scan_args(argc, argv, "21", &a, &b, &c);
    GetCursorDB(obj, dbcst, dbst);
    flags = NUM2INT(a);
    if (flags == DB_KEYFIRST || flags == DB_KEYLAST) {
        if (cnt != 3)
            rb_raise(bdb_eFatal, "invalid number of arguments");
        d = bdb_test_recno(dbcst->db, &key, &recno, b);
        e = bdb_test_dump(dbcst->db, &data, c, FILTER_VALUE);
        f = c;
    }
    else {
        e = bdb_test_dump(dbcst->db, &data, b, FILTER_VALUE);
        f = b;
    }
    SET_PARTIAL(dbst, data);
    ret = bdb_test_error(dbcst->dbc->c_put(dbcst->dbc, &key, &data, flags));
    if (cnt == 3) {
        FREE_KEY(dbst, key);
    }
    if (data.flags & DB_DBT_MALLOC)
        free(data.data);
    if (ret == DB_KEYEXIST) {
        return Qfalse;
    }
    else {
        if (dbst->partial) {
            return bdb_cursor_current(obj);
        }
        else {
            return bdb_test_ret(obj, e, f, FILTER_VALUE);
        }
    }
}
c_set(p1) click to toggle source
static VALUE 
bdb_cursor_set(VALUE obj, VALUE a)
{ 
    return bdb_cursor_set_xxx(obj, a, DB_SET);
}
c_set_range(p1) click to toggle source
static VALUE 
bdb_cursor_set_range(VALUE obj, VALUE a)
{ 
    return bdb_cursor_set_xxx(obj, a, DB_SET_RANGE);
}
c_set_recno(p1) click to toggle source
static VALUE 
bdb_cursor_set_recno(VALUE obj, VALUE a)
{ 
    return bdb_cursor_set_xxx(obj, a, DB_SET_RECNO);
}
clone(p1 = v1) click to toggle source
static VALUE
bdb_cursor_dup(int argc, VALUE *argv, VALUE obj)
{
    int flags = 0;
    VALUE a, b;
    bdb_DBC *dbcst, *dbcstdup;
    bdb_DB *dbst;
    DBC *dbcdup;
    
    if (rb_scan_args(argc, argv, "01", &a))
        flags = NUM2INT(a);
    GetCursorDB(obj, dbcst, dbst);
    bdb_test_error(dbcst->dbc->c_dup(dbcst->dbc, &dbcdup, flags));
    b = Data_Make_Struct(bdb_cCursor, bdb_DBC, 0, bdb_cursor_free, dbcstdup);
    dbcstdup->dbc = dbcdup;
    dbcstdup->db = dbcst->db;
    return b;
}
close() click to toggle source
static VALUE
bdb_cursor_close(VALUE obj)
{
    bdb_DBC *dbcst;
    bdb_DB *dbst;
    
    if (!OBJ_TAINTED(obj) && rb_safe_level() >= 4)
        rb_raise(rb_eSecurityError, "Insecure: can't close the cursor");
    GetCursorDB(obj, dbcst, dbst);
    bdb_test_error(dbcst->dbc->c_close(dbcst->dbc));
    dbcst->dbc = NULL;
    return Qtrue;
}
count() click to toggle source
static VALUE
bdb_cursor_count(VALUE obj)
{
#if !HAVE_CONST_DB_NEXT_DUP
    rb_raise(bdb_eFatal, "DB_NEXT_DUP needs Berkeley DB 2.6 or later");
#else
#if !HAVE_ST_DBC_C_COUNT
    DBT key, data;
    DBT key_o, data_o;
    int ret;
#endif
    bdb_DBC *dbcst;
    bdb_DB *dbst;
    db_recno_t count;

    GetCursorDB(obj, dbcst, dbst);
#if HAVE_ST_DBC_C_COUNT
    bdb_test_error(dbcst->dbc->c_count(dbcst->dbc, &count, 0));
    return INT2NUM(count);
#else
    MEMZERO(&key, DBT, 1);
    key.flags |= DB_DBT_MALLOC;
    MEMZERO(&data, DBT, 1);
    data.flags |= DB_DBT_MALLOC;
    MEMZERO(&key_o, DBT, 1);
    key_o.flags |= DB_DBT_MALLOC;
    MEMZERO(&data_o, DBT, 1);
    data_o.flags |= DB_DBT_MALLOC;
    SET_PARTIAL(dbst, data);
    ret = bdb_test_error(dbcst->dbc->c_get(dbcst->dbc, &key_o, &data_o, DB_CURRENT));
    if (ret == DB_NOTFOUND || ret == DB_KEYEMPTY)
        return INT2NUM(0);
    count = 1;
    while (1) {
        MEMZERO(&key, DBT, 1);
        key.flags |= DB_DBT_MALLOC;
        MEMZERO(&data, DBT, 1);
        data.flags |= DB_DBT_MALLOC;
        SET_PARTIAL(dbst, data);
        ret = bdb_test_error(dbcst->dbc->c_get(dbcst->dbc, &key, &data, DB_NEXT_DUP));
        if (ret == DB_NOTFOUND) {
            MEMZERO(&key_o, DBT, 1);
            key_o.flags |= DB_DBT_MALLOC;
            MEMZERO(&data_o, DBT, 1);
            data_o.flags |= DB_DBT_MALLOC;
            bdb_test_error(dbcst->dbc->c_get(dbcst->dbc, &key_o, &data_o, DB_SET));

            FREE_KEY(dbst, key_o);
            free(data_o.data);
            return INT2NUM(count);
        }
        if (ret == DB_KEYEMPTY) continue;
        FREE_KEY(dbst, key);
        free(data.data);
        count++;
    }
    return INT2NUM(-1);
#endif
#endif
}
current() click to toggle source
static VALUE
bdb_cursor_current(VALUE obj)
{
    return bdb_cursor_xxx(obj, DB_CURRENT);
}
del() click to toggle source
static VALUE
bdb_cursor_del(VALUE obj)
{
    int flags = 0;
    bdb_DBC *dbcst;
    bdb_DB *dbst;
    
    rb_secure(4);
    GetCursorDB(obj, dbcst, dbst);
    bdb_test_error(dbcst->dbc->c_del(dbcst->dbc, flags));
    return Qtrue;
}
delete() click to toggle source
static VALUE
bdb_cursor_del(VALUE obj)
{
    int flags = 0;
    bdb_DBC *dbcst;
    bdb_DB *dbst;
    
    rb_secure(4);
    GetCursorDB(obj, dbcst, dbst);
    bdb_test_error(dbcst->dbc->c_del(dbcst->dbc, flags));
    return Qtrue;
}
dup(p1 = v1) click to toggle source
static VALUE
bdb_cursor_dup(int argc, VALUE *argv, VALUE obj)
{
    int flags = 0;
    VALUE a, b;
    bdb_DBC *dbcst, *dbcstdup;
    bdb_DB *dbst;
    DBC *dbcdup;
    
    if (rb_scan_args(argc, argv, "01", &a))
        flags = NUM2INT(a);
    GetCursorDB(obj, dbcst, dbst);
    bdb_test_error(dbcst->dbc->c_dup(dbcst->dbc, &dbcdup, flags));
    b = Data_Make_Struct(bdb_cCursor, bdb_DBC, 0, bdb_cursor_free, dbcstdup);
    dbcstdup->dbc = dbcdup;
    dbcstdup->db = dbcst->db;
    return b;
}
first() click to toggle source
static VALUE
bdb_cursor_first(VALUE obj)
{
    return bdb_cursor_xxx(obj, DB_FIRST);
}
get(*args) click to toggle source
static VALUE
bdb_cursor_get(int argc, VALUE *argv, VALUE obj)
{
    return bdb_cursor_get_common(argc, argv, obj, 0);
}
last() click to toggle source
static VALUE
bdb_cursor_last(VALUE obj)
{
    return bdb_cursor_xxx(obj, DB_LAST);
}
next() click to toggle source
static VALUE
bdb_cursor_next(VALUE obj)
{
    return bdb_cursor_xxx(obj, DB_NEXT);
}
next_dup() click to toggle source
static VALUE
bdb_cursor_next_dup(VALUE obj)
{
    return bdb_cursor_xxx(obj, DB_NEXT_DUP);
}
pget(*args) click to toggle source
static VALUE
bdb_cursor_pget(int argc, VALUE *argv, VALUE obj)
{
    return bdb_cursor_get_common(argc, argv, obj, 1);
}
prev() click to toggle source
static VALUE
bdb_cursor_prev(VALUE obj)
{
    return bdb_cursor_xxx(obj, DB_PREV);
}
priority() click to toggle source
static VALUE
bdb_cursor_priority(VALUE obj)
{
    bdb_DBC *dbcst;
    bdb_DB *dbst;

    DB_CACHE_PRIORITY prio = 0;

    GetCursorDB(obj, dbcst, dbst);
    if (dbcst->dbc->get_priority(dbcst->dbc, &prio)) {
        rb_raise(rb_eArgError, "invalid argument");
    }
    return INT2FIX(prio);
}
priority=(p1) click to toggle source
static VALUE
bdb_cursor_set_priority(VALUE obj, VALUE a)
{
    bdb_DBC *dbcst;
    bdb_DB *dbst;

    GetCursorDB(obj, dbcst, dbst);
    if (dbcst->dbc->set_priority(dbcst->dbc, NUM2INT(a))) {
        rb_raise(rb_eArgError, "invalid argument");
    }
    return a;
}
put(p1, p2, p3 = v3) click to toggle source
static VALUE
bdb_cursor_put(int argc, VALUE *argv, VALUE obj)
{
    int flags, cnt;
    DBT key, data;
    bdb_DBC *dbcst;
    bdb_DB *dbst;
    VALUE a, b, c, f;
    volatile VALUE d = Qnil;
    volatile VALUE e = Qnil;
    db_recno_t recno;
    int ret;

    rb_secure(4);
    MEMZERO(&key, DBT, 1);
    MEMZERO(&data, DBT, 1);
    cnt = rb_scan_args(argc, argv, "21", &a, &b, &c);
    GetCursorDB(obj, dbcst, dbst);
    flags = NUM2INT(a);
    if (flags == DB_KEYFIRST || flags == DB_KEYLAST) {
        if (cnt != 3)
            rb_raise(bdb_eFatal, "invalid number of arguments");
        d = bdb_test_recno(dbcst->db, &key, &recno, b);
        e = bdb_test_dump(dbcst->db, &data, c, FILTER_VALUE);
        f = c;
    }
    else {
        e = bdb_test_dump(dbcst->db, &data, b, FILTER_VALUE);
        f = b;
    }
    SET_PARTIAL(dbst, data);
    ret = bdb_test_error(dbcst->dbc->c_put(dbcst->dbc, &key, &data, flags));
    if (cnt == 3) {
        FREE_KEY(dbst, key);
    }
    if (data.flags & DB_DBT_MALLOC)
        free(data.data);
    if (ret == DB_KEYEXIST) {
        return Qfalse;
    }
    else {
        if (dbst->partial) {
            return bdb_cursor_current(obj);
        }
        else {
            return bdb_test_ret(obj, e, f, FILTER_VALUE);
        }
    }
}
set(p1) click to toggle source
static VALUE 
bdb_cursor_set(VALUE obj, VALUE a)
{ 
    return bdb_cursor_set_xxx(obj, a, DB_SET);
}
set_range(p1) click to toggle source
static VALUE 
bdb_cursor_set_range(VALUE obj, VALUE a)
{ 
    return bdb_cursor_set_xxx(obj, a, DB_SET_RANGE);
}
set_recno(p1) click to toggle source
static VALUE 
bdb_cursor_set_recno(VALUE obj, VALUE a)
{ 
    return bdb_cursor_set_xxx(obj, a, DB_SET_RECNO);
}