actsasflinn-ruby-tokyotyrant 0.1.5 → 0.1.6

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/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