ruby-tokyotyrant 0.3.0
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.
- data/COPYING +504 -0
- data/README.rdoc +204 -0
- data/Rakefile +68 -0
- data/benchmarks/bulk_db.rb +74 -0
- data/benchmarks/bulk_table.rb +87 -0
- data/benchmarks/db.rb +114 -0
- data/benchmarks/table.rb +161 -0
- data/ext/extconf.rb +39 -0
- data/ext/tokyo_tyrant.c +147 -0
- data/ext/tokyo_tyrant.h +48 -0
- data/ext/tokyo_tyrant_db.c +227 -0
- data/ext/tokyo_tyrant_db.h +8 -0
- data/ext/tokyo_tyrant_module.c +453 -0
- data/ext/tokyo_tyrant_module.h +10 -0
- data/ext/tokyo_tyrant_query.c +226 -0
- data/ext/tokyo_tyrant_query.h +9 -0
- data/ext/tokyo_tyrant_table.c +319 -0
- data/ext/tokyo_tyrant_table.h +8 -0
- data/spec/ext.lua +4 -0
- data/spec/plu_db.rb +538 -0
- data/spec/spec.rb +1 -0
- data/spec/spec_base.rb +16 -0
- data/spec/start_tyrants.sh +36 -0
- data/spec/stop_tyrants.sh +9 -0
- data/spec/tokyo_tyrant_query_spec.rb +159 -0
- data/spec/tokyo_tyrant_spec.rb +254 -0
- data/spec/tokyo_tyrant_table_spec.rb +301 -0
- metadata +80 -0
data/ext/extconf.rb
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# ENV["RC_ARCHS"] = `uname -m`.chomp if `uname -sr` =~ /^Darwin/
|
|
2
|
+
#
|
|
3
|
+
# require 'mkmf'
|
|
4
|
+
#
|
|
5
|
+
|
|
6
|
+
if RUBY_PLATFORM =~ /darwin/
|
|
7
|
+
ENV["RC_ARCHS"] = `uname -m`.chomp if `uname -sr` =~ /^Darwin/
|
|
8
|
+
|
|
9
|
+
# On PowerPC the defaults are fine
|
|
10
|
+
ENV["RC_ARCHS"] = '' if `uname -m` =~ /^Power Macintosh/
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
# Loads mkmf which is used to make makefiles for Ruby extensions
|
|
14
|
+
require 'mkmf'
|
|
15
|
+
|
|
16
|
+
# Give it a name
|
|
17
|
+
extension_name = 'tokyo_tyrant'
|
|
18
|
+
|
|
19
|
+
dir_config("tokyo_tyrant")
|
|
20
|
+
|
|
21
|
+
# NOTE: use GCC flags unless Visual C compiler is used
|
|
22
|
+
$CFLAGS << ' -Wall ' unless RUBY_PLATFORM =~ /mswin/
|
|
23
|
+
|
|
24
|
+
if RUBY_VERSION < '1.8.6'
|
|
25
|
+
$CFLAGS << ' -DRUBY_LESS_THAN_186'
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
# Do the work
|
|
29
|
+
|
|
30
|
+
find_library(*['tokyotyrant', "tcrdbnew", dir_config('libtokyotyrant').last].compact) or
|
|
31
|
+
raise "shared library 'libtokyotyrant' not found"
|
|
32
|
+
|
|
33
|
+
['tctdb.h',
|
|
34
|
+
'tcrdb.h'].each do |header|
|
|
35
|
+
find_header(*[header, dir_config('libtokyotyrant').first].compact) or
|
|
36
|
+
raise "header file '#{header}' not found"
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
create_makefile 'tokyo_tyrant'
|
data/ext/tokyo_tyrant.c
ADDED
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
#include <tokyo_tyrant.h>
|
|
2
|
+
|
|
3
|
+
extern VALUE StringRaw(const char *buf, int bsiz){
|
|
4
|
+
VALUE vval;
|
|
5
|
+
int i;
|
|
6
|
+
vval = rb_str_buf_new2("");
|
|
7
|
+
char s[5];
|
|
8
|
+
|
|
9
|
+
for(i=0;i<bsiz;i++){
|
|
10
|
+
char c = *buf++;
|
|
11
|
+
s[0] = c;
|
|
12
|
+
rb_str_buf_cat(vval, s, 1);
|
|
13
|
+
}
|
|
14
|
+
// buf -= bsiz;
|
|
15
|
+
// rb_str_buf_cat2(vval, "");
|
|
16
|
+
return vval;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
extern VALUE StringValueEx(VALUE vobj){
|
|
20
|
+
if (rb_respond_to(vobj, rb_intern("to_tokyo_tyrant"))) {
|
|
21
|
+
return rb_convert_type(vobj, T_STRING, "String", "to_tokyo_tyrant");
|
|
22
|
+
} else if (rb_respond_to(vobj, rb_intern("to_s"))) {
|
|
23
|
+
return rb_convert_type(vobj, T_STRING, "String", "to_s");
|
|
24
|
+
} else {
|
|
25
|
+
rb_raise(rb_eArgError, "can't stringify object");
|
|
26
|
+
}
|
|
27
|
+
return StringValue(vobj);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
extern TCLIST *varytolist(VALUE vary){
|
|
31
|
+
VALUE vval;
|
|
32
|
+
TCLIST *list;
|
|
33
|
+
int i, num;
|
|
34
|
+
num = RARRAY_LEN(vary);
|
|
35
|
+
list = tclistnew2(num);
|
|
36
|
+
for(i = 0; i < num; i++){
|
|
37
|
+
vval = rb_ary_entry(vary, i);
|
|
38
|
+
vval = StringValueEx(vval);
|
|
39
|
+
tclistpush(list, RSTRING_PTR(vval), RSTRING_LEN(vval));
|
|
40
|
+
}
|
|
41
|
+
return list;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
extern VALUE listtovary(TCLIST *list){
|
|
45
|
+
VALUE vary;
|
|
46
|
+
const char *vbuf;
|
|
47
|
+
int i, num, vsiz;
|
|
48
|
+
num = tclistnum(list);
|
|
49
|
+
vary = rb_ary_new2(num);
|
|
50
|
+
for(i = 0; i < num; i++){
|
|
51
|
+
vbuf = tclistval(list, i, &vsiz);
|
|
52
|
+
rb_ary_push(vary, rb_str_new(vbuf, vsiz));
|
|
53
|
+
}
|
|
54
|
+
return vary;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
extern TCMAP *vhashtomap(VALUE vhash){
|
|
58
|
+
VALUE vkeys, vkey, vval;
|
|
59
|
+
TCMAP *map;
|
|
60
|
+
int i, num;
|
|
61
|
+
map = tcmapnew2(31);
|
|
62
|
+
vkeys = rb_funcall(vhash, rb_intern("keys"), 0);
|
|
63
|
+
num = RARRAY_LEN(vkeys);
|
|
64
|
+
for(i = 0; i < num; i++){
|
|
65
|
+
vkey = rb_ary_entry(vkeys, i);
|
|
66
|
+
vval = rb_hash_aref(vhash, vkey);
|
|
67
|
+
vkey = StringValueEx(vkey);
|
|
68
|
+
vval = StringValueEx(vval);
|
|
69
|
+
tcmapput(map, RSTRING_PTR(vkey), RSTRING_LEN(vkey), RSTRING_PTR(vval), RSTRING_LEN(vval));
|
|
70
|
+
}
|
|
71
|
+
return map;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
extern VALUE maptovhash(TCMAP *map){
|
|
75
|
+
const char *kbuf;
|
|
76
|
+
int ksiz, vsiz;
|
|
77
|
+
VALUE vhash;
|
|
78
|
+
vhash = rb_hash_new();
|
|
79
|
+
tcmapiterinit(map);
|
|
80
|
+
while((kbuf = tcmapiternext(map, &ksiz)) != NULL){
|
|
81
|
+
const char *vbuf = tcmapiterval(kbuf, &vsiz);
|
|
82
|
+
rb_hash_aset(vhash, rb_str_new(kbuf, ksiz), StringRaw(vbuf, vsiz));
|
|
83
|
+
}
|
|
84
|
+
return vhash;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
extern TCMAP *varytomap(VALUE vary){
|
|
88
|
+
int i;
|
|
89
|
+
TCLIST *keys;
|
|
90
|
+
TCMAP *recs = tcmapnew();
|
|
91
|
+
keys = varytolist(vary);
|
|
92
|
+
for(i = 0; i < tclistnum(keys); i++){
|
|
93
|
+
int ksiz;
|
|
94
|
+
const char *kbuf = tclistval(keys, i, &ksiz);
|
|
95
|
+
tcmapput(recs, kbuf, ksiz, "", 0);
|
|
96
|
+
}
|
|
97
|
+
tclistdel(keys);
|
|
98
|
+
return recs;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
extern TCLIST *vhashtolist(VALUE vhash){
|
|
102
|
+
/*
|
|
103
|
+
Seems like something like this might work just as well
|
|
104
|
+
vary = rb_hash_to_a(vhash);
|
|
105
|
+
vary = rb_ary_flatten(vary);
|
|
106
|
+
args = varytolist(vary);
|
|
107
|
+
*/
|
|
108
|
+
|
|
109
|
+
VALUE vkeys, vkey, vval;
|
|
110
|
+
TCLIST *list;
|
|
111
|
+
int i, num;
|
|
112
|
+
vkeys = rb_funcall(vhash, rb_intern("keys"), 0);
|
|
113
|
+
num = RARRAY_LEN(vkeys);
|
|
114
|
+
list = tclistnew2(num);
|
|
115
|
+
for(i = 0; i < num; i++){
|
|
116
|
+
vkey = rb_ary_entry(vkeys, i);
|
|
117
|
+
vval = rb_hash_aref(vhash, vkey);
|
|
118
|
+
vkey = StringValueEx(vkey);
|
|
119
|
+
vval = StringValueEx(vval);
|
|
120
|
+
tclistpush(list, RSTRING_PTR(vkey), RSTRING_LEN(vkey));
|
|
121
|
+
tclistpush(list, RSTRING_PTR(vval), RSTRING_LEN(vval));
|
|
122
|
+
}
|
|
123
|
+
return list;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
VALUE mTokyoTyrant;
|
|
127
|
+
VALUE eTokyoTyrantError;
|
|
128
|
+
VALUE cDB;
|
|
129
|
+
VALUE cTable;
|
|
130
|
+
VALUE cQuery;
|
|
131
|
+
|
|
132
|
+
void Init_tokyo_tyrant(){
|
|
133
|
+
mTokyoTyrant = rb_define_module("TokyoTyrant");
|
|
134
|
+
eTokyoTyrantError = rb_define_class("TokyoTyrantError", rb_eStandardError);
|
|
135
|
+
init_mod();
|
|
136
|
+
|
|
137
|
+
cDB = rb_define_class_under(mTokyoTyrant, "DB", rb_cObject);
|
|
138
|
+
rb_include_module(cDB, mTokyoTyrant);
|
|
139
|
+
init_db();
|
|
140
|
+
|
|
141
|
+
cTable = rb_define_class_under(mTokyoTyrant, "Table", rb_cObject);
|
|
142
|
+
rb_include_module(cTable, mTokyoTyrant);
|
|
143
|
+
init_table();
|
|
144
|
+
|
|
145
|
+
cQuery = rb_define_class_under(mTokyoTyrant, "Query", rb_cObject);
|
|
146
|
+
init_query();
|
|
147
|
+
}
|
data/ext/tokyo_tyrant.h
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
#ifndef RUBY_TOKYOTYRANT
|
|
2
|
+
#define RUBY_TOKYOTYRANT
|
|
3
|
+
|
|
4
|
+
#include <ruby.h>
|
|
5
|
+
#include <string.h>
|
|
6
|
+
#include <math.h>
|
|
7
|
+
#include <time.h>
|
|
8
|
+
#include <locale.h>
|
|
9
|
+
#include <tcrdb.h>
|
|
10
|
+
#include <tokyo_tyrant_module.h>
|
|
11
|
+
#include <tokyo_tyrant_db.h>
|
|
12
|
+
#include <tokyo_tyrant_table.h>
|
|
13
|
+
#include <tokyo_tyrant_query.h>
|
|
14
|
+
|
|
15
|
+
#define RDBVNDATA "@rdb"
|
|
16
|
+
#define RDBQRYVNDATA "@rdbquery"
|
|
17
|
+
#define NUMBUFSIZ 32
|
|
18
|
+
#define TTPUT 0
|
|
19
|
+
#define TTPUTKEEP 1
|
|
20
|
+
#define TTPUTCAT 2
|
|
21
|
+
#define TTPUTNR 3
|
|
22
|
+
|
|
23
|
+
#if !defined(RSTRING_PTR)
|
|
24
|
+
#define RSTRING_PTR(TC_s) (RSTRING(TC_s)->ptr)
|
|
25
|
+
#endif
|
|
26
|
+
#if !defined(RSTRING_LEN)
|
|
27
|
+
#define RSTRING_LEN(TC_s) (RSTRING(TC_s)->len)
|
|
28
|
+
#endif
|
|
29
|
+
#if !defined(RARRAY_LEN)
|
|
30
|
+
#define RARRAY_LEN(TC_a) (RARRAY(TC_a)->len)
|
|
31
|
+
#endif
|
|
32
|
+
|
|
33
|
+
extern VALUE mTokyoTyrant;
|
|
34
|
+
extern VALUE eTokyoTyrantError;
|
|
35
|
+
extern VALUE cDB;
|
|
36
|
+
extern VALUE cTable;
|
|
37
|
+
extern VALUE cQuery;
|
|
38
|
+
|
|
39
|
+
extern VALUE StringRaw(const char *buf, int bsiz);
|
|
40
|
+
extern VALUE StringValueEx(VALUE vobj);
|
|
41
|
+
extern TCLIST *varytolist(VALUE vary);
|
|
42
|
+
extern VALUE listtovary(TCLIST *list);
|
|
43
|
+
extern TCMAP *vhashtomap(VALUE vhash);
|
|
44
|
+
extern VALUE maptovhash(TCMAP *map);
|
|
45
|
+
extern TCMAP *varytomap(VALUE vhash);
|
|
46
|
+
extern TCLIST *vhashtolist(VALUE vhash);
|
|
47
|
+
|
|
48
|
+
#endif
|
|
@@ -0,0 +1,227 @@
|
|
|
1
|
+
#include <tokyo_tyrant_db.h>
|
|
2
|
+
|
|
3
|
+
static VALUE cDB_put_method(VALUE vself, VALUE vkey, VALUE vstr, int method){
|
|
4
|
+
bool res;
|
|
5
|
+
TCRDB *db = mTokyoTyrant_getdb(vself);
|
|
6
|
+
|
|
7
|
+
vkey = StringValueEx(vkey);
|
|
8
|
+
vstr = StringValueEx(vstr);
|
|
9
|
+
|
|
10
|
+
switch(method){
|
|
11
|
+
case TTPUT:
|
|
12
|
+
res = tcrdbput(db, RSTRING_PTR(vkey), RSTRING_LEN(vkey), RSTRING_PTR(vstr), RSTRING_LEN(vstr));
|
|
13
|
+
break;
|
|
14
|
+
case TTPUTKEEP:
|
|
15
|
+
res = tcrdbputkeep(db, RSTRING_PTR(vkey), RSTRING_LEN(vkey), RSTRING_PTR(vstr), RSTRING_LEN(vstr));
|
|
16
|
+
break;
|
|
17
|
+
case TTPUTCAT:
|
|
18
|
+
res = tcrdbputcat(db, RSTRING_PTR(vkey), RSTRING_LEN(vkey), RSTRING_PTR(vstr), RSTRING_LEN(vstr));
|
|
19
|
+
break;
|
|
20
|
+
case TTPUTNR:
|
|
21
|
+
res = tcrdbputnr(db, RSTRING_PTR(vkey), RSTRING_LEN(vkey), RSTRING_PTR(vstr), RSTRING_LEN(vstr));
|
|
22
|
+
break;
|
|
23
|
+
default:
|
|
24
|
+
res = false;
|
|
25
|
+
break;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
if(!res) mTokyoTyrant_exception(vself);
|
|
29
|
+
|
|
30
|
+
return Qtrue;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
static VALUE cDB_put(VALUE vself, VALUE vkey, VALUE vstr){
|
|
34
|
+
return cDB_put_method(vself, vkey, vstr, TTPUT);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
static VALUE cDB_mput(VALUE vself, VALUE vhash){
|
|
38
|
+
VALUE vary;
|
|
39
|
+
TCLIST *list, *args;
|
|
40
|
+
TCRDB *db = mTokyoTyrant_getdb(vself);
|
|
41
|
+
|
|
42
|
+
args = vhashtolist(vhash);
|
|
43
|
+
list = tcrdbmisc(db, "putlist", 0, args);
|
|
44
|
+
vary = listtovary(list);
|
|
45
|
+
tclistdel(args);
|
|
46
|
+
tclistdel(list);
|
|
47
|
+
return vary;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
static VALUE cDB_putkeep(VALUE vself, VALUE vkey, VALUE vstr){
|
|
51
|
+
return cDB_put_method(vself, vkey, vstr, TTPUTKEEP);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
static VALUE cDB_putcat(VALUE vself, VALUE vkey, VALUE vstr){
|
|
55
|
+
return cDB_put_method(vself, vkey, vstr, TTPUTCAT);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
static VALUE cDB_putnr(VALUE vself, VALUE vkey, VALUE vstr){
|
|
59
|
+
return cDB_put_method(vself, vkey, vstr, TTPUTNR);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
static VALUE cDB_putshl(VALUE vself, VALUE vkey, VALUE vstr, VALUE vwidth){
|
|
63
|
+
bool res;
|
|
64
|
+
TCRDB *db = mTokyoTyrant_getdb(vself);
|
|
65
|
+
|
|
66
|
+
vkey = StringValueEx(vkey);
|
|
67
|
+
vstr = StringValueEx(vstr);
|
|
68
|
+
|
|
69
|
+
res = tcrdbputshl(db, RSTRING_PTR(vkey), RSTRING_LEN(vkey), RSTRING_PTR(vstr), RSTRING_LEN(vstr), FIXNUM_P(vwidth));
|
|
70
|
+
|
|
71
|
+
if(!res) mTokyoTyrant_exception(vself);
|
|
72
|
+
|
|
73
|
+
return Qtrue;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
static VALUE cDB_get(VALUE vself, VALUE vkey){
|
|
77
|
+
VALUE vval;
|
|
78
|
+
char *buf;
|
|
79
|
+
int bsiz, ecode;
|
|
80
|
+
TCRDB *db = mTokyoTyrant_getdb(vself);
|
|
81
|
+
|
|
82
|
+
// this is ugly
|
|
83
|
+
vkey = StringValueEx(vkey);
|
|
84
|
+
if(!(buf = tcrdbget(db, RSTRING_PTR(vkey), RSTRING_LEN(vkey), &bsiz))){
|
|
85
|
+
if ((ecode = tcrdbecode(db))) {
|
|
86
|
+
if (ecode != TTENOREC) mTokyoTyrant_exception(vself);
|
|
87
|
+
}
|
|
88
|
+
return Qnil;
|
|
89
|
+
} else {
|
|
90
|
+
vval = StringRaw(buf, bsiz);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
tcfree(buf);
|
|
94
|
+
return vval;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
static VALUE cDB_mget(int argc, VALUE *argv, VALUE vself){
|
|
98
|
+
VALUE vkeys, vhash, vvalue;
|
|
99
|
+
TCMAP *recs;
|
|
100
|
+
TCRDB *db = mTokyoTyrant_getdb(vself);
|
|
101
|
+
rb_scan_args(argc, argv, "*", &vkeys);
|
|
102
|
+
|
|
103
|
+
// I really hope there is a better way to do this
|
|
104
|
+
if (RARRAY_LEN(vkeys) == 1) {
|
|
105
|
+
vvalue = rb_ary_entry(vkeys, 0);
|
|
106
|
+
switch (TYPE(vvalue)){
|
|
107
|
+
case T_STRING:
|
|
108
|
+
case T_FIXNUM:
|
|
109
|
+
break;
|
|
110
|
+
case T_ARRAY:
|
|
111
|
+
vkeys = vvalue;
|
|
112
|
+
break;
|
|
113
|
+
case T_STRUCT: // range is not a T_STRUCT instead of a T_OBJECT in ruby1.9?
|
|
114
|
+
case T_OBJECT:
|
|
115
|
+
vkeys = rb_convert_type(vvalue, T_ARRAY, "Array", "to_a");
|
|
116
|
+
break;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
Check_Type(vkeys, T_ARRAY);
|
|
121
|
+
|
|
122
|
+
recs = varytomap(vkeys);
|
|
123
|
+
if(!tcrdbget3(db, recs)) return Qnil;
|
|
124
|
+
vhash = maptovhash(recs);
|
|
125
|
+
tcmapdel(recs);
|
|
126
|
+
return vhash;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
static VALUE cDB_vsiz(VALUE vself, VALUE vkey){
|
|
130
|
+
TCRDB *db = mTokyoTyrant_getdb(vself);
|
|
131
|
+
|
|
132
|
+
vkey = StringValueEx(vkey);
|
|
133
|
+
return INT2NUM(tcrdbvsiz(db, RSTRING_PTR(vkey), RSTRING_LEN(vkey)));
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
static VALUE cDB_fetch(int argc, VALUE *argv, VALUE vself){
|
|
137
|
+
VALUE vkey, vrv, vforce;
|
|
138
|
+
rb_scan_args(argc, argv, "11", &vkey, &vforce);
|
|
139
|
+
if(rb_block_given_p() != Qtrue) rb_raise(rb_eArgError, "no block given");
|
|
140
|
+
if(vforce == Qnil) vforce = Qfalse;
|
|
141
|
+
|
|
142
|
+
if(vforce != Qfalse || (vrv = cDB_get(vself, vkey)) == Qnil){
|
|
143
|
+
vrv = rb_yield(vkey);
|
|
144
|
+
cDB_put(vself, vkey, vrv);
|
|
145
|
+
}
|
|
146
|
+
return vrv;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
static VALUE cDB_each(VALUE vself){
|
|
150
|
+
VALUE vrv;
|
|
151
|
+
if(rb_block_given_p() != Qtrue) rb_raise(rb_eArgError, "no block given");
|
|
152
|
+
TCRDB *db = mTokyoTyrant_getdb(vself);
|
|
153
|
+
vrv = Qnil;
|
|
154
|
+
tcrdbiterinit(db);
|
|
155
|
+
int ksiz;
|
|
156
|
+
char *kbuf;
|
|
157
|
+
while((kbuf = tcrdbiternext(db, &ksiz)) != NULL){
|
|
158
|
+
int vsiz;
|
|
159
|
+
char *vbuf = tcrdbget(db, kbuf, ksiz, &vsiz);
|
|
160
|
+
vrv = rb_yield_values(2, rb_str_new2(kbuf), StringRaw(vbuf, vsiz));
|
|
161
|
+
tcfree(vbuf);
|
|
162
|
+
tcfree(kbuf);
|
|
163
|
+
}
|
|
164
|
+
return vrv;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
static VALUE cDB_each_value(VALUE vself){
|
|
168
|
+
VALUE vrv;
|
|
169
|
+
if(rb_block_given_p() != Qtrue) rb_raise(rb_eArgError, "no block given");
|
|
170
|
+
TCRDB *db = mTokyoTyrant_getdb(vself);
|
|
171
|
+
vrv = Qnil;
|
|
172
|
+
tcrdbiterinit(db);
|
|
173
|
+
int ksiz;
|
|
174
|
+
char *kbuf;
|
|
175
|
+
while((kbuf = tcrdbiternext(db, &ksiz)) != NULL){
|
|
176
|
+
int vsiz;
|
|
177
|
+
char *vbuf = tcrdbget(db, kbuf, ksiz, &vsiz);
|
|
178
|
+
vrv = rb_yield_values(1, StringRaw(vbuf, vsiz));
|
|
179
|
+
tcfree(vbuf);
|
|
180
|
+
tcfree(kbuf);
|
|
181
|
+
}
|
|
182
|
+
return vrv;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
static VALUE cDB_values(VALUE vself){
|
|
186
|
+
VALUE vary;
|
|
187
|
+
TCRDB *db = mTokyoTyrant_getdb(vself);
|
|
188
|
+
vary = rb_ary_new2(tcrdbrnum(db));
|
|
189
|
+
tcrdbiterinit(db);
|
|
190
|
+
int ksiz;
|
|
191
|
+
char *kbuf;
|
|
192
|
+
while((kbuf = tcrdbiternext(db, &ksiz)) != NULL){
|
|
193
|
+
int vsiz;
|
|
194
|
+
char *vbuf = tcrdbget(db, kbuf, ksiz, &vsiz);
|
|
195
|
+
rb_ary_push(vary, StringRaw(vbuf, vsiz));
|
|
196
|
+
tcfree(vbuf);
|
|
197
|
+
tcfree(kbuf);
|
|
198
|
+
}
|
|
199
|
+
return vary;
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
void init_db(){
|
|
203
|
+
rb_define_method(cDB, "mput", cDB_mput, 1);
|
|
204
|
+
rb_define_alias(cDB, "lput", "mput"); // Rufus Compat
|
|
205
|
+
rb_define_method(cDB, "put", cDB_put, 2);
|
|
206
|
+
rb_define_alias(cDB, "[]=", "put");
|
|
207
|
+
rb_define_method(cDB, "putkeep", cDB_putkeep, 2);
|
|
208
|
+
rb_define_method(cDB, "putcat", cDB_putcat, 2);
|
|
209
|
+
rb_define_method(cDB, "putshl", cDB_putshl, 3);
|
|
210
|
+
rb_define_method(cDB, "putnr", cDB_putnr, 2);
|
|
211
|
+
rb_define_method(cDB, "get", cDB_get, 1);
|
|
212
|
+
rb_define_alias(cDB, "[]", "get");
|
|
213
|
+
rb_define_method(cDB, "mget", cDB_mget, -1);
|
|
214
|
+
rb_define_alias(cDB, "lget", "mget"); // Rufus Compat
|
|
215
|
+
rb_define_method(cDB, "vsiz", cDB_vsiz, 1);
|
|
216
|
+
/*
|
|
217
|
+
rb_define_method(cDB, "check_value", cDB_check_value, 1);
|
|
218
|
+
rb_define_alias(cDB, "has_value?", "check_value");
|
|
219
|
+
rb_define_alias(cDB, "value?", "check_value");
|
|
220
|
+
*/
|
|
221
|
+
|
|
222
|
+
rb_define_method(cDB, "fetch", cDB_fetch, -1);
|
|
223
|
+
rb_define_method(cDB, "each", cDB_each, 0);
|
|
224
|
+
rb_define_alias(cDB, "each_pair", "each");
|
|
225
|
+
rb_define_method(cDB, "each_value", cDB_each_value, 0);
|
|
226
|
+
rb_define_method(cDB, "values", cDB_values, 0);
|
|
227
|
+
}
|