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 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.5'
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, *vbuf;
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), rb_str_new(vbuf, vsiz));
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, *vbuf;
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)), rb_str_new(vbuf, vsiz));
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
@@ -36,6 +36,7 @@ extern VALUE cDB;
36
36
  extern VALUE cTable;
37
37
  extern VALUE cQuery;
38
38
 
39
+ extern VALUE StringRaw(const char *buf, int bsiz);
39
40
  extern VALUE StringValueEx(VALUE vobj);
40
41
  extern TCLIST *varytolist(VALUE vary);
41
42
  extern VALUE listtovary(TCLIST *list);
@@ -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 vself, VALUE vkey){
85
- VALUE vval;
86
- char *vbuf;
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(!(vbuf = tcrdbget2(db, RSTRING_PTR(vkey)))) return Qnil;
92
- vval = rb_str_new2(vbuf);
93
- tcfree(vbuf);
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 = rb_str_new(vbuf, vsiz);
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
- while((kxstr = tcrdbiternext2(db)) != NULL){
183
- vxstr = tcrdbget2(db, kxstr);
184
- vrv = rb_yield_values(2, rb_str_new2(kxstr), rb_str_new2(vxstr));
185
- tcfree(vxstr);
186
- tcfree(kxstr);
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
- while((kxstr = tcrdbiternext2(db)) != NULL){
200
- vxstr = tcrdbget2(db, kxstr);
201
- vrv = rb_yield_values(1, rb_str_new2(vxstr));
202
- tcfree(vxstr);
203
- tcfree(kxstr);
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
- while((kxstr = tcrdbiternext2(db)) != NULL){
216
- vxstr = tcrdbget2(db, kxstr);
217
- rb_ary_push(vary, rb_str_new2(vxstr));
218
- tcfree(vxstr);
219
- tcfree(kxstr);
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);
@@ -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
- // TODO: Give this more attention, it's untested and needs defaults for scan_args
142
- static VALUE mTokyoTyrant_ext(int argc, VALUE *argv, VALUE vself){
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
- rb_scan_args(argc, argv, "14", &vname, &vkey, &vvalue, &vopts);
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
- vvalue = StringValueEx(vvalue);
153
- res = tcrdbext2(db, RSTRING_PTR(vname), FIXNUM_P(vopts), RSTRING_PTR(vkey), RSTRING_PTR(vvalue));
154
- return rb_str_new2(res);
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 path, uint64_t ts){
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(path, T_STRING);
184
- return tcrdbrestore(db, RSTRING_PTR(path), ts) ? Qtrue : Qfalse;
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 host, VALUE port){
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
- return tcrdbsetmst(db, StringValuePtr(host), FIX2INT(port)) ? Qtrue : Qfalse;
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, "ext", mTokyoTyrant_ext, -1);
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
- rb_define_method(mTokyoTyrant, "size", mTokyoTyrant_size, 0);
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);
@@ -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 = "__id";
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
  }
@@ -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, *vbuf;
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, rb_str_new(kbuf, ksiz), vcols);
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
- Check_Type(vname, T_STRING);
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, "setindex", cTable_setindex, 2);
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
@@ -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.size.should == 528736
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.size.should == 528768
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.5
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-04-11 00:00:00 -07:00
12
+ date: 2009-05-21 00:00:00 -07:00
13
13
  default_executable:
14
14
  dependencies: []
15
15