actsasflinn-ruby-tokyotyrant 0.1.5 → 0.1.6
Sign up to get free protection for your applications and to get access to all the features.
- data/Rakefile +1 -1
- data/ext/tokyo_tyrant.c +22 -6
- data/ext/tokyo_tyrant.h +1 -0
- data/ext/tokyo_tyrant_db.c +49 -48
- data/ext/tokyo_tyrant_module.c +95 -16
- data/ext/tokyo_tyrant_query.c +25 -5
- data/ext/tokyo_tyrant_table.c +16 -5
- data/spec/tokyo_tyrant_query_spec.rb +16 -0
- data/spec/tokyo_tyrant_spec.rb +38 -1
- data/spec/tokyo_tyrant_table_spec.rb +52 -1
- metadata +2 -2
data/Rakefile
CHANGED
@@ -20,7 +20,7 @@ CLEAN.include('pkg', 'tmp')
|
|
20
20
|
|
21
21
|
gemspec = Gem::Specification.new do |s|
|
22
22
|
s.name = 'ruby-tokyotyrant'
|
23
|
-
s.version = '0.1.
|
23
|
+
s.version = '0.1.6'
|
24
24
|
s.authors = [ 'Flinn' ]
|
25
25
|
s.email = 'flinn@actsasflinn.com'
|
26
26
|
s.homepage = 'http://github.com/actsasflinn/ruby-tokyotyrant/'
|
data/ext/tokyo_tyrant.c
CHANGED
@@ -1,5 +1,21 @@
|
|
1
1
|
#include <tokyo_tyrant.h>
|
2
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
|
+
|
3
19
|
extern VALUE StringValueEx(VALUE vobj){
|
4
20
|
char kbuf[NUMBUFSIZ];
|
5
21
|
int ksiz;
|
@@ -75,27 +91,27 @@ extern TCMAP *vhashtomap(VALUE vhash){
|
|
75
91
|
}
|
76
92
|
|
77
93
|
extern VALUE maptovhash(TCMAP *map){
|
78
|
-
const char *kbuf
|
94
|
+
const char *kbuf;
|
79
95
|
int ksiz, vsiz;
|
80
96
|
VALUE vhash;
|
81
97
|
vhash = rb_hash_new();
|
82
98
|
tcmapiterinit(map);
|
83
99
|
while((kbuf = tcmapiternext(map, &ksiz)) != NULL){
|
84
|
-
vbuf = tcmapiterval(kbuf, &vsiz);
|
85
|
-
rb_hash_aset(vhash, rb_str_new(kbuf, ksiz),
|
100
|
+
const char *vbuf = tcmapiterval(kbuf, &vsiz);
|
101
|
+
rb_hash_aset(vhash, rb_str_new(kbuf, ksiz), StringRaw(vbuf, vsiz));
|
86
102
|
}
|
87
103
|
return vhash;
|
88
104
|
}
|
89
105
|
|
90
106
|
extern VALUE maptovhashsym(TCMAP *map){
|
91
|
-
const char *kbuf
|
107
|
+
const char *kbuf;
|
92
108
|
int ksiz, vsiz;
|
93
109
|
VALUE vhash;
|
94
110
|
vhash = rb_hash_new();
|
95
111
|
tcmapiterinit(map);
|
96
112
|
while((kbuf = tcmapiternext(map, &ksiz)) != NULL){
|
97
|
-
vbuf = tcmapiterval(kbuf, &vsiz);
|
98
|
-
rb_hash_aset(vhash, ID2SYM(rb_intern(kbuf)),
|
113
|
+
const char *vbuf = tcmapiterval(kbuf, &vsiz);
|
114
|
+
rb_hash_aset(vhash, ID2SYM(rb_intern(kbuf)), StringRaw(vbuf, vsiz));
|
99
115
|
}
|
100
116
|
return vhash;
|
101
117
|
}
|
data/ext/tokyo_tyrant.h
CHANGED
data/ext/tokyo_tyrant_db.c
CHANGED
@@ -81,16 +81,31 @@ static VALUE cDB_putshl(VALUE vself, VALUE vkey, VALUE vstr, VALUE vwidth){
|
|
81
81
|
return Qtrue;
|
82
82
|
}
|
83
83
|
|
84
|
-
static VALUE cDB_get(VALUE
|
85
|
-
VALUE vval;
|
86
|
-
char *
|
84
|
+
static VALUE cDB_get(int argc, VALUE *argv, VALUE vself){
|
85
|
+
VALUE vkey, vraw, vval;
|
86
|
+
char *buf;
|
87
|
+
int bsiz, ecode;
|
88
|
+
bool raw;
|
87
89
|
TCRDB *db;
|
88
90
|
Data_Get_Struct(rb_iv_get(vself, RDBVNDATA), TCRDB, db);
|
89
91
|
|
92
|
+
rb_scan_args(argc, argv, "11", &vkey, &vraw);
|
93
|
+
raw = (vraw == Qtrue);
|
94
|
+
|
95
|
+
// this is ugly
|
90
96
|
vkey = StringValueEx(vkey);
|
91
|
-
if(!(
|
92
|
-
|
93
|
-
|
97
|
+
if(!(buf = tcrdbget(db, RSTRING_PTR(vkey), RSTRING_LEN(vkey), &bsiz))){
|
98
|
+
if ((ecode = tcrdbecode(db))) {
|
99
|
+
if (ecode != TTENOREC) {
|
100
|
+
rb_raise(eTokyoTyrantError, "get error: %s", tcrdberrmsg(ecode));
|
101
|
+
}
|
102
|
+
}
|
103
|
+
return Qnil;
|
104
|
+
} else {
|
105
|
+
vval = StringRaw(buf, bsiz);
|
106
|
+
}
|
107
|
+
|
108
|
+
tcfree(buf);
|
94
109
|
return vval;
|
95
110
|
}
|
96
111
|
|
@@ -134,26 +149,6 @@ static VALUE cDB_vsiz(VALUE vself, VALUE vkey){
|
|
134
149
|
return INT2NUM(tcrdbvsiz2(db, RSTRING_PTR(vkey)));
|
135
150
|
}
|
136
151
|
|
137
|
-
static VALUE cDB_addint(VALUE vself, VALUE vkey, VALUE vnum){
|
138
|
-
int num;
|
139
|
-
TCRDB *db;
|
140
|
-
Data_Get_Struct(rb_iv_get(vself, RDBVNDATA), TCRDB, db);
|
141
|
-
vkey = StringValueEx(vkey);
|
142
|
-
|
143
|
-
num = tcrdbaddint(db, RSTRING_PTR(vkey), RSTRING_LEN(vkey), NUM2INT(vnum));
|
144
|
-
return num == INT_MIN ? Qnil : INT2NUM(num);
|
145
|
-
}
|
146
|
-
|
147
|
-
static VALUE cDB_adddouble(VALUE vself, VALUE vkey, VALUE vnum){
|
148
|
-
double num;
|
149
|
-
TCRDB *db;
|
150
|
-
Data_Get_Struct(rb_iv_get(vself, RDBVNDATA), TCRDB, db);
|
151
|
-
|
152
|
-
vkey = StringValueEx(vkey);
|
153
|
-
num = tcrdbadddouble(db, RSTRING_PTR(vkey), RSTRING_LEN(vkey), NUM2DBL(vnum));
|
154
|
-
return isnan(num) ? Qnil : rb_float_new(num);
|
155
|
-
}
|
156
|
-
|
157
152
|
static VALUE cDB_fetch(int argc, VALUE *argv, VALUE vself){
|
158
153
|
VALUE vkey, vdef, vval;
|
159
154
|
TCRDB *db;
|
@@ -163,7 +158,7 @@ static VALUE cDB_fetch(int argc, VALUE *argv, VALUE vself){
|
|
163
158
|
vkey = StringValueEx(vkey);
|
164
159
|
Data_Get_Struct(rb_iv_get(vself, RDBVNDATA), TCRDB, db);
|
165
160
|
if((vbuf = tcrdbget(db, RSTRING_PTR(vkey), RSTRING_LEN(vkey), &vsiz)) != NULL){
|
166
|
-
vval =
|
161
|
+
vval = StringRaw(vbuf, vsiz);
|
167
162
|
tcfree(vbuf);
|
168
163
|
} else {
|
169
164
|
vval = vdef;
|
@@ -174,16 +169,18 @@ static VALUE cDB_fetch(int argc, VALUE *argv, VALUE vself){
|
|
174
169
|
static VALUE cDB_each(VALUE vself){
|
175
170
|
VALUE vrv;
|
176
171
|
TCRDB *db;
|
177
|
-
char *kxstr, *vxstr;
|
178
172
|
if(rb_block_given_p() != Qtrue) rb_raise(rb_eArgError, "no block given");
|
179
173
|
Data_Get_Struct(rb_iv_get(vself, RDBVNDATA), TCRDB, db);
|
180
174
|
vrv = Qnil;
|
181
175
|
tcrdbiterinit(db);
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
176
|
+
int ksiz;
|
177
|
+
char *kbuf;
|
178
|
+
while((kbuf = tcrdbiternext(db, &ksiz)) != NULL){
|
179
|
+
int vsiz;
|
180
|
+
char *vbuf = tcrdbget(db, kbuf, ksiz, &vsiz);
|
181
|
+
vrv = rb_yield_values(2, rb_str_new2(kbuf), StringRaw(vbuf, vsiz));
|
182
|
+
tcfree(vbuf);
|
183
|
+
tcfree(kbuf);
|
187
184
|
}
|
188
185
|
return vrv;
|
189
186
|
}
|
@@ -191,16 +188,18 @@ static VALUE cDB_each(VALUE vself){
|
|
191
188
|
static VALUE cDB_each_value(VALUE vself){
|
192
189
|
VALUE vrv;
|
193
190
|
TCRDB *db;
|
194
|
-
char *kxstr, *vxstr;
|
195
191
|
if(rb_block_given_p() != Qtrue) rb_raise(rb_eArgError, "no block given");
|
196
192
|
Data_Get_Struct(rb_iv_get(vself, RDBVNDATA), TCRDB, db);
|
197
193
|
vrv = Qnil;
|
198
194
|
tcrdbiterinit(db);
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
195
|
+
int ksiz;
|
196
|
+
char *kbuf;
|
197
|
+
while((kbuf = tcrdbiternext(db, &ksiz)) != NULL){
|
198
|
+
int vsiz;
|
199
|
+
char *vbuf = tcrdbget(db, kbuf, ksiz, &vsiz);
|
200
|
+
vrv = rb_yield_values(1, StringRaw(vbuf, vsiz));
|
201
|
+
tcfree(vbuf);
|
202
|
+
tcfree(kbuf);
|
204
203
|
}
|
205
204
|
return vrv;
|
206
205
|
}
|
@@ -208,38 +207,40 @@ static VALUE cDB_each_value(VALUE vself){
|
|
208
207
|
static VALUE cDB_values(VALUE vself){
|
209
208
|
VALUE vary;
|
210
209
|
TCRDB *db;
|
211
|
-
char *kxstr, *vxstr;
|
212
210
|
Data_Get_Struct(rb_iv_get(vself, RDBVNDATA), TCRDB, db);
|
213
211
|
vary = rb_ary_new2(tcrdbrnum(db));
|
214
212
|
tcrdbiterinit(db);
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
213
|
+
int ksiz;
|
214
|
+
char *kbuf;
|
215
|
+
while((kbuf = tcrdbiternext(db, &ksiz)) != NULL){
|
216
|
+
int vsiz;
|
217
|
+
char *vbuf = tcrdbget(db, kbuf, ksiz, &vsiz);
|
218
|
+
rb_ary_push(vary, StringRaw(vbuf, vsiz));
|
219
|
+
tcfree(vbuf);
|
220
|
+
tcfree(kbuf);
|
220
221
|
}
|
221
222
|
return vary;
|
222
223
|
}
|
223
224
|
|
224
225
|
void init_db(){
|
225
226
|
rb_define_method(cDB, "mput", cDB_mput, 1);
|
227
|
+
rb_define_alias(cDB, "lput", "mput"); // Rufus Compat
|
226
228
|
rb_define_method(cDB, "put", cDB_put, 2);
|
227
229
|
rb_define_alias(cDB, "[]=", "put");
|
228
230
|
rb_define_method(cDB, "putkeep", cDB_putkeep, 2);
|
229
231
|
rb_define_method(cDB, "putcat", cDB_putcat, 2);
|
230
232
|
rb_define_method(cDB, "putshl", cDB_putshl, 2);
|
231
233
|
rb_define_method(cDB, "putnr", cDB_putnr, 2);
|
232
|
-
rb_define_method(cDB, "get", cDB_get, 1);
|
234
|
+
rb_define_method(cDB, "get", cDB_get, -1);
|
233
235
|
rb_define_alias(cDB, "[]", "get");
|
234
236
|
rb_define_method(cDB, "mget", cDB_mget, -1);
|
237
|
+
rb_define_alias(cDB, "lget", "mget"); // Rufus Compat
|
235
238
|
rb_define_method(cDB, "vsiz", cDB_vsiz, 1);
|
236
239
|
/*
|
237
240
|
rb_define_method(cDB, "check_value", cDB_check_value, 1);
|
238
241
|
rb_define_alias(cDB, "has_value?", "check_value");
|
239
242
|
rb_define_alias(cDB, "value?", "check_value");
|
240
243
|
*/
|
241
|
-
rb_define_method(cDB, "addint", cDB_addint, 2);
|
242
|
-
rb_define_method(cDB, "adddouble", cDB_adddouble, 2);
|
243
244
|
|
244
245
|
rb_define_method(cDB, "fetch", cDB_fetch, -1);
|
245
246
|
rb_define_method(cDB, "each", cDB_each, 0);
|
data/ext/tokyo_tyrant_module.c
CHANGED
@@ -67,6 +67,39 @@ static VALUE mTokyoTyrant_out(VALUE vself, VALUE vkey){
|
|
67
67
|
return tcrdbout2(db, RSTRING_PTR(vkey)) ? Qtrue : Qfalse;
|
68
68
|
}
|
69
69
|
|
70
|
+
// TODO: merge out and mout?
|
71
|
+
static VALUE mTokyoTyrant_outlist(int argc, VALUE *argv, VALUE vself){
|
72
|
+
VALUE vkeys, vary, vvalue;
|
73
|
+
TCRDB *db;
|
74
|
+
TCLIST *list, *result;
|
75
|
+
Data_Get_Struct(rb_iv_get(vself, RDBVNDATA), TCRDB, db);
|
76
|
+
rb_scan_args(argc, argv, "*", &vkeys);
|
77
|
+
|
78
|
+
// I really hope there is a better way to do this
|
79
|
+
if (RARRAY_LEN(vkeys) == 1) {
|
80
|
+
vvalue = rb_ary_entry(vkeys, 0);
|
81
|
+
switch (TYPE(vvalue)){
|
82
|
+
case T_STRING:
|
83
|
+
case T_FIXNUM:
|
84
|
+
break;
|
85
|
+
case T_ARRAY:
|
86
|
+
vkeys = vvalue;
|
87
|
+
break;
|
88
|
+
case T_OBJECT:
|
89
|
+
vkeys = rb_convert_type(vvalue, T_ARRAY, "Array", "to_a");
|
90
|
+
break;
|
91
|
+
}
|
92
|
+
}
|
93
|
+
Check_Type(vkeys, T_ARRAY);
|
94
|
+
|
95
|
+
list = varytolist(vkeys);
|
96
|
+
result = tcrdbmisc(db, "outlist", 0, list);
|
97
|
+
tclistdel(list);
|
98
|
+
vary = listtovary(result);
|
99
|
+
tclistdel(result);
|
100
|
+
return vary;
|
101
|
+
}
|
102
|
+
|
70
103
|
static VALUE mTokyoTyrant_check(VALUE vself, VALUE vkey){
|
71
104
|
TCRDB *db;
|
72
105
|
Data_Get_Struct(rb_iv_get(vself, RDBVNDATA), TCRDB, db);
|
@@ -111,6 +144,22 @@ static VALUE mTokyoTyrant_fwmkeys(int argc, VALUE *argv, VALUE vself){
|
|
111
144
|
return vary;
|
112
145
|
}
|
113
146
|
|
147
|
+
static VALUE mTokyoTyrant_delete_keys_with_prefix(int argc, VALUE *argv, VALUE vself){
|
148
|
+
VALUE vprefix, vmax;
|
149
|
+
TCLIST *keys;
|
150
|
+
int max;
|
151
|
+
TCRDB *db;
|
152
|
+
Data_Get_Struct(rb_iv_get(vself, RDBVNDATA), TCRDB, db);
|
153
|
+
rb_scan_args(argc, argv, "11", &vprefix, &vmax);
|
154
|
+
|
155
|
+
vprefix = StringValueEx(vprefix);
|
156
|
+
max = (vmax == Qnil) ? -1 : NUM2INT(vmax);
|
157
|
+
keys = tcrdbfwmkeys(db, RSTRING_PTR(vprefix), RSTRING_LEN(vprefix), max);
|
158
|
+
tcrdbmisc(db, "outlist", 0, keys);
|
159
|
+
tclistdel(keys);
|
160
|
+
return Qnil;
|
161
|
+
}
|
162
|
+
|
114
163
|
static VALUE mTokyoTyrant_keys(VALUE vself){
|
115
164
|
/*
|
116
165
|
VALUE vary;
|
@@ -138,20 +187,32 @@ static VALUE mTokyoTyrant_keys(VALUE vself){
|
|
138
187
|
return vary;
|
139
188
|
}
|
140
189
|
|
141
|
-
|
142
|
-
|
143
|
-
const char *res;
|
144
|
-
VALUE vname, vkey, vvalue, vopts;
|
190
|
+
static VALUE mTokyoTyrant_add_int(VALUE vself, VALUE vkey, VALUE vnum){
|
191
|
+
int num;
|
145
192
|
TCRDB *db;
|
146
193
|
Data_Get_Struct(rb_iv_get(vself, RDBVNDATA), TCRDB, db);
|
194
|
+
vkey = StringValueEx(vkey);
|
147
195
|
|
148
|
-
|
196
|
+
num = tcrdbaddint(db, RSTRING_PTR(vkey), RSTRING_LEN(vkey), NUM2INT(vnum));
|
197
|
+
return num == INT_MIN ? Qnil : INT2NUM(num);
|
198
|
+
}
|
199
|
+
|
200
|
+
static VALUE mTokyoTyrant_get_int(VALUE vself, VALUE vkey){
|
201
|
+
return mTokyoTyrant_add_int(vself, vkey, INT2NUM(0));
|
202
|
+
}
|
203
|
+
|
204
|
+
static VALUE mTokyoTyrant_add_double(VALUE vself, VALUE vkey, VALUE vnum){
|
205
|
+
double num;
|
206
|
+
TCRDB *db;
|
207
|
+
Data_Get_Struct(rb_iv_get(vself, RDBVNDATA), TCRDB, db);
|
149
208
|
|
150
|
-
vname = StringValueEx(vname);
|
151
209
|
vkey = StringValueEx(vkey);
|
152
|
-
|
153
|
-
|
154
|
-
|
210
|
+
num = tcrdbadddouble(db, RSTRING_PTR(vkey), RSTRING_LEN(vkey), NUM2DBL(vnum));
|
211
|
+
return isnan(num) ? Qnil : rb_float_new(num);
|
212
|
+
}
|
213
|
+
|
214
|
+
static VALUE mTokyoTyrant_get_double(VALUE vself, VALUE vkey){
|
215
|
+
return mTokyoTyrant_add_double(vself, vkey, INT2NUM(0));
|
155
216
|
}
|
156
217
|
|
157
218
|
static VALUE mTokyoTyrant_sync(VALUE vself){
|
@@ -176,19 +237,27 @@ static VALUE mTokyoTyrant_copy(VALUE vself, VALUE path){
|
|
176
237
|
return tcrdbcopy(db, RSTRING_PTR(path)) ? Qtrue : Qfalse;
|
177
238
|
}
|
178
239
|
|
179
|
-
static VALUE mTokyoTyrant_restore(VALUE vself, VALUE
|
240
|
+
static VALUE mTokyoTyrant_restore(VALUE vself, VALUE vpath, VALUE vts, VALUE vopts){
|
241
|
+
uint64_t ts;
|
242
|
+
int opts;
|
180
243
|
TCRDB *db;
|
181
244
|
Data_Get_Struct(rb_iv_get(vself, RDBVNDATA), TCRDB, db);
|
182
245
|
|
183
|
-
Check_Type(
|
184
|
-
|
246
|
+
Check_Type(vpath, T_STRING);
|
247
|
+
ts = (uint64_t) FIX2INT(vts);
|
248
|
+
opts = FIX2INT(vopts);
|
249
|
+
return tcrdbrestore(db, RSTRING_PTR(vpath), ts, opts) ? Qtrue : Qfalse;
|
185
250
|
}
|
186
251
|
|
187
|
-
static VALUE mTokyoTyrant_setmst(VALUE vself, VALUE
|
252
|
+
static VALUE mTokyoTyrant_setmst(VALUE vself, VALUE vhost, VALUE vport, VALUE vts, VALUE vopts){
|
253
|
+
uint64_t ts;
|
254
|
+
int opts;
|
188
255
|
TCRDB *db;
|
189
256
|
Data_Get_Struct(rb_iv_get(vself, RDBVNDATA), TCRDB, db);
|
190
257
|
|
191
|
-
|
258
|
+
ts = (uint64_t) FIX2INT(vts);
|
259
|
+
opts = FIX2INT(vopts);
|
260
|
+
return tcrdbsetmst(db, RSTRING_PTR(vhost), FIX2INT(vport), ts, opts) ? Qtrue : Qfalse;
|
192
261
|
}
|
193
262
|
|
194
263
|
static VALUE mTokyoTyrant_rnum(VALUE vself){
|
@@ -271,6 +340,10 @@ void init_mod(){
|
|
271
340
|
rb_define_method(mTokyoTyrant, "errmsg", mTokyoTyrant_errmsg, -1);
|
272
341
|
rb_define_method(mTokyoTyrant, "ecode", mTokyoTyrant_ecode, 0);
|
273
342
|
rb_define_method(mTokyoTyrant, "out", mTokyoTyrant_out, 1);
|
343
|
+
rb_define_alias(mTokyoTyrant, "delete", "out"); // Rufus Compat
|
344
|
+
rb_define_method(mTokyoTyrant, "outlist", mTokyoTyrant_outlist, -1);
|
345
|
+
rb_define_alias(mTokyoTyrant, "mdelete", "outlist");
|
346
|
+
rb_define_alias(mTokyoTyrant, "ldelete", "outlist"); // Rufus Compat
|
274
347
|
rb_define_method(mTokyoTyrant, "check", mTokyoTyrant_check, 1);
|
275
348
|
rb_define_alias(mTokyoTyrant, "has_key?", "check");
|
276
349
|
rb_define_alias(mTokyoTyrant, "key?", "check");
|
@@ -279,8 +352,13 @@ void init_mod(){
|
|
279
352
|
rb_define_method(mTokyoTyrant, "iterinit", mTokyoTyrant_iterinit, 0);
|
280
353
|
rb_define_method(mTokyoTyrant, "iternext", mTokyoTyrant_iternext, 0);
|
281
354
|
rb_define_method(mTokyoTyrant, "fwmkeys", mTokyoTyrant_fwmkeys, -1);
|
355
|
+
rb_define_method(mTokyoTyrant, "delete_keys_with_prefix", mTokyoTyrant_delete_keys_with_prefix, -1);// Rufus Compat
|
356
|
+
rb_define_alias(mTokyoTyrant, "dfwmkeys", "delete_keys_with_prefix");
|
282
357
|
rb_define_method(mTokyoTyrant, "keys", mTokyoTyrant_keys, 0);
|
283
|
-
rb_define_method(mTokyoTyrant, "
|
358
|
+
rb_define_method(mTokyoTyrant, "add_int", mTokyoTyrant_add_int, 2);
|
359
|
+
rb_define_method(mTokyoTyrant, "get_int", mTokyoTyrant_get_int, 1);
|
360
|
+
rb_define_method(mTokyoTyrant, "add_double", mTokyoTyrant_add_double, 2);
|
361
|
+
rb_define_method(mTokyoTyrant, "get_double", mTokyoTyrant_get_double, 1);
|
284
362
|
rb_define_method(mTokyoTyrant, "sync", mTokyoTyrant_sync, 0);
|
285
363
|
rb_define_method(mTokyoTyrant, "vanish", mTokyoTyrant_vanish, 0);
|
286
364
|
rb_define_alias(mTokyoTyrant, "clear", "vanish");
|
@@ -290,7 +368,8 @@ void init_mod(){
|
|
290
368
|
rb_define_method(mTokyoTyrant, "rnum", mTokyoTyrant_rnum, 0);
|
291
369
|
rb_define_alias(mTokyoTyrant, "count", "rnum");
|
292
370
|
rb_define_method(mTokyoTyrant, "empty?", mTokyoTyrant_empty, 0);
|
293
|
-
|
371
|
+
rb_define_alias(mTokyoTyrant, "size", "rnum"); // Rufus Compat
|
372
|
+
rb_define_method(mTokyoTyrant, "db_size", mTokyoTyrant_size, 0); // Rufus Compat
|
294
373
|
rb_define_alias(mTokyoTyrant, "length", "size");
|
295
374
|
rb_define_method(mTokyoTyrant, "stat", mTokyoTyrant_stat, 0);
|
296
375
|
rb_define_method(mTokyoTyrant, "misc", mTokyoTyrant_misc, -1);
|
data/ext/tokyo_tyrant_query.c
CHANGED
@@ -82,10 +82,18 @@ static VALUE cQuery_searchout(VALUE vself){
|
|
82
82
|
return tcrdbqrysearchout(qry) ? Qtrue : Qfalse;
|
83
83
|
}
|
84
84
|
|
85
|
+
static VALUE cQuery_searchcount(VALUE vself){
|
86
|
+
VALUE vqry;
|
87
|
+
RDBQRY *qry;
|
88
|
+
vqry = rb_iv_get(vself, RDBQRYVNDATA);
|
89
|
+
Data_Get_Struct(vqry, RDBQRY, qry);
|
90
|
+
return LL2NUM(tcrdbqrysearchcount(qry));
|
91
|
+
}
|
92
|
+
|
85
93
|
static VALUE cQuery_get(VALUE vself){
|
86
94
|
int i, num, ksiz;
|
87
|
-
const char *name, *col;
|
88
|
-
VALUE vqry, vary, vcols;
|
95
|
+
const char *name, *col, *pkey;
|
96
|
+
VALUE vqry, vary, vcols, vpkey;
|
89
97
|
RDBQRY *qry;
|
90
98
|
TCLIST *res;
|
91
99
|
TCMAP *cols;
|
@@ -95,6 +103,8 @@ static VALUE cQuery_get(VALUE vself){
|
|
95
103
|
res = tcrdbqrysearchget(qry);
|
96
104
|
num = tclistnum(res);
|
97
105
|
vary = rb_ary_new2(num);
|
106
|
+
vpkey = rb_iv_get(vself, "@pkey");
|
107
|
+
pkey = vpkey == Qnil ? "__id" : STR2CSTR(StringValueEx(vpkey));
|
98
108
|
for(i = 0; i < num; i++){
|
99
109
|
vcols = rb_hash_new();
|
100
110
|
cols = tcrdbqryrescols(res, i);
|
@@ -102,7 +112,7 @@ static VALUE cQuery_get(VALUE vself){
|
|
102
112
|
tcmapiterinit(cols);
|
103
113
|
while((name = tcmapiternext(cols, &ksiz)) != NULL){
|
104
114
|
col = tcmapget2(cols, name);
|
105
|
-
if (ksiz == 0) name =
|
115
|
+
if (ksiz == 0) name = pkey;
|
106
116
|
rb_hash_aset(vcols, ID2SYM(rb_intern(name)), rb_str_new2(col));
|
107
117
|
}
|
108
118
|
}
|
@@ -113,6 +123,10 @@ static VALUE cQuery_get(VALUE vself){
|
|
113
123
|
return vary;
|
114
124
|
}
|
115
125
|
|
126
|
+
static VALUE cQuery_set_pkey(VALUE vself, VALUE vpkey) {
|
127
|
+
return rb_iv_set(vself, "@pkey", vpkey);
|
128
|
+
}
|
129
|
+
|
116
130
|
void init_query(){
|
117
131
|
rb_define_const(cQuery, "CSTREQ", INT2NUM(RDBQCSTREQ));
|
118
132
|
rb_define_const(cQuery, "CSTRINC", INT2NUM(RDBQCSTRINC));
|
@@ -140,12 +154,18 @@ void init_query(){
|
|
140
154
|
rb_define_method(cQuery, "addcond", cQuery_addcond, 3);
|
141
155
|
rb_define_alias(cQuery, "add_condition", "addcond");
|
142
156
|
rb_define_alias(cQuery, "condition", "addcond");
|
157
|
+
rb_define_alias(cQuery, "add", "addcond"); // Rufus Compat
|
143
158
|
rb_define_method(cQuery, "setorder", cQuery_setorder, 2);
|
144
|
-
rb_define_alias(cQuery, "order_by", "setorder");
|
159
|
+
rb_define_alias(cQuery, "order_by", "setorder"); // Rufus Compat
|
145
160
|
rb_define_method(cQuery, "setmax", cQuery_setmax, 1);
|
146
|
-
rb_define_alias(cQuery, "limit", "setmax");
|
161
|
+
rb_define_alias(cQuery, "limit", "setmax"); // Rufus Compat
|
147
162
|
rb_define_method(cQuery, "search", cQuery_search, 0);
|
148
163
|
rb_define_alias(cQuery, "run", "search");
|
149
164
|
rb_define_method(cQuery, "searchout", cQuery_searchout, 0);
|
165
|
+
rb_define_alias(cQuery, "delete", "searchout"); // Rufus Compat
|
166
|
+
rb_define_method(cQuery, "searchcount", cQuery_searchcount, 0);
|
167
|
+
rb_define_alias(cQuery, "count", "searchcount"); // Rufus Compat
|
150
168
|
rb_define_method(cQuery, "get", cQuery_get, 0);
|
169
|
+
rb_define_method(cQuery, "set_pkey", cQuery_set_pkey, 1);
|
170
|
+
rb_define_alias(cQuery, "pkey=", "set_pkey");
|
151
171
|
}
|
data/ext/tokyo_tyrant_table.c
CHANGED
@@ -107,7 +107,7 @@ static VALUE cTable_get(VALUE vself, VALUE vkey){
|
|
107
107
|
}
|
108
108
|
|
109
109
|
static VALUE cTable_mget(int argc, VALUE *argv, VALUE vself){
|
110
|
-
const char *kbuf
|
110
|
+
const char *kbuf;
|
111
111
|
int ksiz, vsiz;
|
112
112
|
VALUE vkeys, vhash, vcols, vvalue;
|
113
113
|
TCRDB *db;
|
@@ -137,11 +137,11 @@ static VALUE cTable_mget(int argc, VALUE *argv, VALUE vself){
|
|
137
137
|
vhash = rb_hash_new();
|
138
138
|
tcmapiterinit(recs);
|
139
139
|
while((kbuf = tcmapiternext(recs, &ksiz)) != NULL){
|
140
|
-
vbuf = tcmapiterval(kbuf, &vsiz);
|
140
|
+
const char *vbuf = tcmapiterval(kbuf, &vsiz);
|
141
141
|
cols = tcstrsplit4(vbuf, vsiz);
|
142
142
|
vcols = maptovhashsym(cols);
|
143
143
|
tcmapdel(cols);
|
144
|
-
rb_hash_aset(vhash,
|
144
|
+
rb_hash_aset(vhash, StringRaw(kbuf, ksiz), vcols);
|
145
145
|
}
|
146
146
|
tcmapdel(recs);
|
147
147
|
return vhash;
|
@@ -150,7 +150,15 @@ static VALUE cTable_mget(int argc, VALUE *argv, VALUE vself){
|
|
150
150
|
static VALUE cTable_setindex(VALUE vself, VALUE vname, VALUE vtype){
|
151
151
|
TCRDB *db;
|
152
152
|
Data_Get_Struct(rb_iv_get(vself, RDBVNDATA), TCRDB, db);
|
153
|
-
|
153
|
+
vname = StringValueEx(vname);
|
154
|
+
if (TYPE(vtype) == T_SYMBOL) vtype = rb_str_new2(rb_id2name(SYM2ID(vtype)));
|
155
|
+
|
156
|
+
if (TYPE(vtype) == T_STRING){
|
157
|
+
vtype = StringValueEx(vtype);
|
158
|
+
vtype = tctdbstrtoindextype(RSTRING_PTR(toupper(vtype)));
|
159
|
+
vtype = INT2NUM(vtype);
|
160
|
+
}
|
161
|
+
|
154
162
|
return tcrdbtblsetindex(db, RSTRING_PTR(vname), NUM2INT(vtype)) ? Qtrue : Qfalse;
|
155
163
|
}
|
156
164
|
|
@@ -268,15 +276,18 @@ static VALUE cTable_find(VALUE vself){
|
|
268
276
|
|
269
277
|
void init_table(){
|
270
278
|
rb_define_method(cTable, "mput", cTable_mput, 1);
|
279
|
+
rb_define_alias(cTable, "lput", "mput"); // Rufus Compat
|
271
280
|
rb_define_method(cTable, "put", cTable_put, 2);
|
272
281
|
rb_define_alias(cTable, "[]=", "put");
|
273
282
|
rb_define_method(cTable, "putkeep", cTable_putkeep, 2);
|
274
283
|
rb_define_method(cTable, "putcat", cTable_putcat, 2);
|
275
284
|
rb_define_method(cTable, "out", cTable_out, 1);
|
285
|
+
rb_define_alias(cTable, "delete", "out"); // Rufus Compat
|
276
286
|
rb_define_method(cTable, "get", cTable_get, 1);
|
277
287
|
rb_define_method(cTable, "mget", cTable_mget, -1);
|
288
|
+
rb_define_alias(cTable, "lget", "mget"); // Rufus Compat
|
278
289
|
rb_define_alias(cTable, "[]", "get");
|
279
|
-
rb_define_method(cTable, "
|
290
|
+
rb_define_method(cTable, "set_index", cTable_setindex, 2); // Rufus Compat
|
280
291
|
rb_define_method(cTable, "genuid", cTable_genuid, 0);
|
281
292
|
rb_define_alias(cTable, "generate_unique_id", "genuid");
|
282
293
|
rb_define_method(cTable, "fetch", cTable_fetch, -1);
|
@@ -88,4 +88,20 @@ describe TokyoTyrant::Query, "with an open database" do
|
|
88
88
|
{:type=>"Cucumber", :variety=>"Lemon", :__id=>"4595", :code=>"4595"},
|
89
89
|
{:type=>"Cucumber", :variety=>"Japanese / White", :__id=>"4594", :code=>"4594"}]
|
90
90
|
end
|
91
|
+
|
92
|
+
it "should show query count" do
|
93
|
+
res = @db.prepare_query{ |q| q.condition(:type, :streq, 'Cucumber') }.count
|
94
|
+
res.should == 5
|
95
|
+
end
|
96
|
+
|
97
|
+
it "should allow a custom pkey for a result set" do
|
98
|
+
q = @db.query
|
99
|
+
q.condition(:type, :streq, 'Cucumber')
|
100
|
+
q.set_pkey(:pk)
|
101
|
+
q.get.should == [{:type=>"Cucumber", :code=>"4592", :pk=>"4592", :variety=>"Armenian"},
|
102
|
+
{:type=>"Cucumber", :code=>"4593", :pk=>"4593", :variety=>"English / Hot House / Long Seedless / Telegraph / Continental"},
|
103
|
+
{:type=>"Cucumber", :code=>"4594", :pk=>"4594", :variety=>"Japanese / White"},
|
104
|
+
{:type=>"Cucumber", :code=>"4595", :pk=>"4595", :variety=>"Lemon"},
|
105
|
+
{:type=>"Cucumber", :code=>"4596", :pk=>"4596", :variety=>"Pickling / Gherkin"}]
|
106
|
+
end
|
91
107
|
end
|
data/spec/tokyo_tyrant_spec.rb
CHANGED
@@ -42,6 +42,16 @@ describe TokyoTyrant::DB, "with an open database" do
|
|
42
42
|
end
|
43
43
|
end
|
44
44
|
|
45
|
+
it "should delete multiple values" do
|
46
|
+
h = { 'pizza' => 'old forge style',
|
47
|
+
'sandwich' => 'peanut butter jelly',
|
48
|
+
'yogurt' => 'greek',
|
49
|
+
'coffee' => 'black' }
|
50
|
+
@db.mput(h)
|
51
|
+
@db.outlist('coffee', 'yogurt').should.be.empty
|
52
|
+
@db.keys.sort.should == ['pizza','sandwich']
|
53
|
+
end
|
54
|
+
|
45
55
|
it "should get multiple values" do
|
46
56
|
h = { 'pizza' => 'old forge style',
|
47
57
|
'sandwich' => 'peanut butter jelly',
|
@@ -97,6 +107,17 @@ describe TokyoTyrant::DB, "with an open database" do
|
|
97
107
|
@db.fwmkeys('apples').sort.should == ["apples/grannysmith", "apples/royalgala"]
|
98
108
|
end
|
99
109
|
|
110
|
+
it "should delete forward matching keys" do
|
111
|
+
@db['apples/royalgala'] = '4173'
|
112
|
+
@db['apples/grannysmith'] = '4139'
|
113
|
+
@db['bananas/yellow'] = '4011'
|
114
|
+
@db['oranges/shamouti'] = '3027'
|
115
|
+
@db['grapefruit/deepred'] = '4288'
|
116
|
+
@db.delete_keys_with_prefix('apples').should == nil
|
117
|
+
@db.fwmkeys('apples').should.be.empty
|
118
|
+
@db.keys.sort.should == ['bananas/yellow', 'grapefruit/deepred', 'oranges/shamouti']
|
119
|
+
end
|
120
|
+
|
100
121
|
it "should get all keys" do
|
101
122
|
keys = %w[appetizers entree dessert]
|
102
123
|
values = %w[chips chicken\ caeser\ salad ice\ cream]
|
@@ -131,7 +152,7 @@ describe TokyoTyrant::DB, "with an open database" do
|
|
131
152
|
|
132
153
|
it "should report db size" do
|
133
154
|
@db['rootbeer'] = 'virgils'
|
134
|
-
@db.
|
155
|
+
@db.db_size.should == 528736
|
135
156
|
end
|
136
157
|
|
137
158
|
it "should fetch a record" do
|
@@ -177,4 +198,20 @@ describe TokyoTyrant::DB, "with an open database" do
|
|
177
198
|
i = i += 1
|
178
199
|
end
|
179
200
|
end
|
201
|
+
|
202
|
+
it "should add serialized integer values" do
|
203
|
+
key = 'counter'
|
204
|
+
@db.out(key)
|
205
|
+
@db.add_int(key, 1).should == 1
|
206
|
+
@db.add_int(key, 1).should == 2
|
207
|
+
@db.get_int(key).should == 2
|
208
|
+
end
|
209
|
+
|
210
|
+
it "should add serialized double values" do
|
211
|
+
key = 'counter'
|
212
|
+
@db.out(key)
|
213
|
+
@db.add_double(key, 1.0).should.be.close?(1.0, 0.005)
|
214
|
+
@db.add_double(key, 1.0).should.be.close?(2.0, 0.005)
|
215
|
+
@db.get_double(key).should.be.close?(2.0, 0.005)
|
216
|
+
end
|
180
217
|
end
|
@@ -45,6 +45,17 @@ describe TokyoTyrant::Table, "with an open database" do
|
|
45
45
|
end
|
46
46
|
end
|
47
47
|
|
48
|
+
it "should delete multiple values" do
|
49
|
+
h = { 'pizza' => { :best => 'old forge style', :ok => 'new york style', :worst => 'chicago style' },
|
50
|
+
'sandwich' => { :best => 'peanut butter jelly', :ok => 'turkey', :worst => 'olive loaf' },
|
51
|
+
'yogurt' => { :best => 'greek', :ok => 'organic', :worst => '+hfcs' },
|
52
|
+
'coffee' => { :best => 'black', :ok => 'espresso', :worst => 'latte' } }
|
53
|
+
|
54
|
+
@db.mput(h)
|
55
|
+
@db.outlist('coffee', 'yogurt').should.be.empty
|
56
|
+
@db.keys.sort.should == ['pizza','sandwich']
|
57
|
+
end
|
58
|
+
|
48
59
|
it "should get multiple values" do
|
49
60
|
h = { 'pizza' => { :best => 'old forge style', :ok => 'new york style', :worst => 'chicago style' },
|
50
61
|
'sandwich' => { :best => 'peanut butter jelly', :ok => 'turkey', :worst => 'olive loaf' },
|
@@ -94,6 +105,17 @@ describe TokyoTyrant::Table, "with an open database" do
|
|
94
105
|
@db.fwmkeys('apples').sort.should == ["apples/grannysmith", "apples/royalgala"]
|
95
106
|
end
|
96
107
|
|
108
|
+
it "should delete forward matching keys" do
|
109
|
+
@db['apples/royalgala'] = { :code => '4173', :color => 'red-yellow' }
|
110
|
+
@db['apples/grannysmith'] = { :code => '4139', :color => 'green' }
|
111
|
+
@db['bananas/yellow'] = { :code => '4011', :color => 'yellow' }
|
112
|
+
@db['oranges/shamouti'] = { :code => '3027', :color => 'orange' }
|
113
|
+
@db['grapefruit/deepred'] = { :code => '4288', :color => 'yellow/pink' }
|
114
|
+
@db.delete_keys_with_prefix('apples').should == nil
|
115
|
+
@db.fwmkeys('apples').should.be.empty
|
116
|
+
@db.keys.sort.should == ['bananas/yellow', 'grapefruit/deepred', 'oranges/shamouti']
|
117
|
+
end
|
118
|
+
|
97
119
|
it "should get all keys" do
|
98
120
|
keys = %w[appetizers entree dessert]
|
99
121
|
values = [{ :cheap => 'chips', :expensive => 'sample everything platter' },
|
@@ -134,7 +156,7 @@ describe TokyoTyrant::Table, "with an open database" do
|
|
134
156
|
|
135
157
|
it "should report db size" do
|
136
158
|
@db['rootbeer'] = { :gourmet => 'Virgils', :natural => 'Hansens' }
|
137
|
-
@db.
|
159
|
+
@db.db_size.should == 528768
|
138
160
|
end
|
139
161
|
|
140
162
|
it "should fetch a record" do
|
@@ -187,4 +209,33 @@ describe TokyoTyrant::Table, "with an open database" do
|
|
187
209
|
i = i += 1
|
188
210
|
end
|
189
211
|
end
|
212
|
+
|
213
|
+
it "should add serialized integer values" do
|
214
|
+
key = 'counter'
|
215
|
+
@db.out(key)
|
216
|
+
@db[key] = { :title => 'Bean Counter' }
|
217
|
+
@db.add_int(key, 1).should == 1
|
218
|
+
@db.add_int(key, 1).should == 2
|
219
|
+
@db.get_int(key).should == 2
|
220
|
+
@db[key].should == { :title => 'Bean Counter', :_num => "2" }
|
221
|
+
end
|
222
|
+
|
223
|
+
it "should add serialized double values" do
|
224
|
+
key = 'counter'
|
225
|
+
@db.out(key)
|
226
|
+
@db[key] = { :title => 'Bean Counter' }
|
227
|
+
@db.add_double(key, 1.0).should.be.close?(1.0, 0.005)
|
228
|
+
@db.add_double(key, 1.0).should.be.close?(2.0, 0.005)
|
229
|
+
@db.get_double(key).should.be.close?(2.0, 0.005)
|
230
|
+
@db[key].should == { :title => 'Bean Counter', :_num => "2" }
|
231
|
+
end
|
232
|
+
|
233
|
+
it "should set an index" do
|
234
|
+
key = 'counter'
|
235
|
+
50.times do |i|
|
236
|
+
@db["key#{i}"] = { :title => %w{rice beans corn}.sort_by{rand}.first,
|
237
|
+
:description => 'a whole protein' }
|
238
|
+
end
|
239
|
+
@db.set_index(:title, :lexical).should.be.true
|
240
|
+
end
|
190
241
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: actsasflinn-ruby-tokyotyrant
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Flinn
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-
|
12
|
+
date: 2009-05-21 00:00:00 -07:00
|
13
13
|
default_executable:
|
14
14
|
dependencies: []
|
15
15
|
|