# 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);
    }