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.
@@ -0,0 +1,319 @@
1
+ #include <tokyo_tyrant_table.h>
2
+
3
+ static VALUE cTable_put_method(VALUE vself, VALUE vkey, VALUE vcols, int method){
4
+ bool res;
5
+ TCMAP *cols;
6
+ TCRDB *db = mTokyoTyrant_getdb(vself);
7
+
8
+ vkey = StringValueEx(vkey);
9
+ Check_Type(vcols, T_HASH);
10
+ cols = vhashtomap(vcols);
11
+
12
+ // there's probably a more elegant way yo do this
13
+ switch(method){
14
+ case TTPUT:
15
+ res = tcrdbtblput(db, RSTRING_PTR(vkey), RSTRING_LEN(vkey), cols);
16
+ break;
17
+ case TTPUTKEEP:
18
+ res = tcrdbtblputkeep(db, RSTRING_PTR(vkey), RSTRING_LEN(vkey), cols);
19
+ break;
20
+ case TTPUTCAT:
21
+ res = tcrdbtblputcat(db, RSTRING_PTR(vkey), RSTRING_LEN(vkey), cols);
22
+ break;
23
+ default :
24
+ res = false;
25
+ break;
26
+ }
27
+
28
+ if(!res) mTokyoTyrant_exception(vself);
29
+ tcmapdel(cols);
30
+ return Qtrue;
31
+ }
32
+
33
+ static VALUE cTable_put(VALUE vself, VALUE vkey, VALUE vcols){
34
+ return cTable_put_method(vself, vkey, vcols, TTPUT);
35
+ }
36
+
37
+ static VALUE cTable_mput(VALUE vself, VALUE vhash){
38
+ int i, num, j;
39
+ VALUE vary, vkeys, vkey, vval;
40
+ TCLIST *list, *result;
41
+ TCRDB *db = mTokyoTyrant_getdb(vself);
42
+
43
+ vkeys = rb_funcall(vhash, rb_intern("keys"), 0);
44
+ num = RARRAY_LEN(vkeys);
45
+ list = tclistnew2(num * 2);
46
+ for(i = 0; i < num; i++){
47
+ vkey = rb_ary_entry(vkeys, i);
48
+ vval = rb_hash_aref(vhash, vkey);
49
+
50
+ vkey = StringValueEx(vkey);
51
+ tclistpush2(list, RSTRING_PTR(vkey));
52
+
53
+ TCLIST *cols = vhashtolist(vval);
54
+ TCXSTR *xstr = tcxstrnew();
55
+
56
+ for(j = 0; j < tclistnum(cols); j++){
57
+ int rsiz;
58
+ const char *rbuf = tclistval(cols, j, &rsiz);
59
+ if (j > 0) tcxstrcat(xstr, "\0", 1);
60
+ tcxstrcat(xstr, rbuf, rsiz);
61
+ }
62
+ tclistpush(list, tcxstrptr(xstr), tcxstrsize(xstr));
63
+ tclistdel(cols);
64
+ tcxstrdel(xstr);
65
+ }
66
+ result = tcrdbmisc(db, "putlist", 0, list);
67
+ tclistdel(list);
68
+ vary = listtovary(result);
69
+ tclistdel(result);
70
+ return vary;
71
+ }
72
+
73
+ static VALUE cTable_putkeep(VALUE vself, VALUE vkey, VALUE vcols){
74
+ return cTable_put_method(vself, vkey, vcols, TTPUTKEEP);
75
+ }
76
+
77
+ static VALUE cTable_putcat(VALUE vself, VALUE vkey, VALUE vcols){
78
+ return cTable_put_method(vself, vkey, vcols, TTPUTCAT);
79
+ }
80
+
81
+ static VALUE cTable_out(VALUE vself, VALUE vkey){
82
+ TCRDB *db = mTokyoTyrant_getdb(vself);
83
+ vkey = StringValueEx(vkey);
84
+
85
+ return tcrdbtblout(db, RSTRING_PTR(vkey), RSTRING_LEN(vkey)) ? Qtrue : Qfalse;
86
+ }
87
+
88
+ static VALUE cTable_get(VALUE vself, VALUE vkey){
89
+ VALUE vcols;
90
+ int ecode;
91
+ TCMAP *cols;
92
+ TCRDB *db = mTokyoTyrant_getdb(vself);
93
+
94
+ vkey = StringValueEx(vkey);
95
+ if(!(cols = tcrdbtblget(db, RSTRING_PTR(vkey), RSTRING_LEN(vkey)))){
96
+ if ((ecode = tcrdbecode(db))) {
97
+ if (ecode != TTENOREC) mTokyoTyrant_exception(vself);
98
+ }
99
+ return Qnil;
100
+ } else {
101
+ vcols = maptovhash(cols);
102
+ }
103
+
104
+ tcmapdel(cols);
105
+ return vcols;
106
+ }
107
+
108
+ static VALUE cTable_mget(int argc, VALUE *argv, VALUE vself){
109
+ const char *kbuf;
110
+ int ksiz, vsiz;
111
+ VALUE vkeys, vhash, vcols, vvalue;
112
+ TCMAP *recs, *cols;
113
+ TCRDB *db = mTokyoTyrant_getdb(vself);
114
+ rb_scan_args(argc, argv, "*", &vkeys);
115
+
116
+ // I really hope there is a better way to do this
117
+ if (RARRAY_LEN(vkeys) == 1) {
118
+ vvalue = rb_ary_entry(vkeys, 0);
119
+ switch (TYPE(vvalue)){
120
+ case T_STRING:
121
+ case T_FIXNUM:
122
+ break;
123
+ case T_ARRAY:
124
+ vkeys = vvalue;
125
+ break;
126
+ case T_STRUCT: // range is not a T_STRUCT instead of a T_OBJECT in ruby1.9?
127
+ case T_OBJECT:
128
+ vkeys = rb_convert_type(vvalue, T_ARRAY, "Array", "to_a");
129
+ break;
130
+ }
131
+ }
132
+ Check_Type(vkeys, T_ARRAY);
133
+
134
+ recs = varytomap(vkeys);
135
+ if(!tcrdbget3(db, recs)) return Qnil;
136
+ vhash = rb_hash_new();
137
+ tcmapiterinit(recs);
138
+ while((kbuf = tcmapiternext(recs, &ksiz)) != NULL){
139
+ const char *vbuf = tcmapiterval(kbuf, &vsiz);
140
+ cols = tcstrsplit4(vbuf, vsiz);
141
+ vcols = maptovhash(cols);
142
+ tcmapdel(cols);
143
+ rb_hash_aset(vhash, StringRaw(kbuf, ksiz), vcols);
144
+ }
145
+ tcmapdel(recs);
146
+ return vhash;
147
+ }
148
+
149
+ static VALUE cTable_setindex(VALUE vself, VALUE vname, VALUE vtype){
150
+ TCRDB *db = mTokyoTyrant_getdb(vself);
151
+ vname = StringValueEx(vname);
152
+ if (TYPE(vtype) == T_SYMBOL) vtype = rb_str_new2(rb_id2name(SYM2ID(vtype)));
153
+
154
+ if (TYPE(vtype) == T_STRING){
155
+ vtype = StringValueEx(vtype);
156
+ vtype = tctdbstrtoindextype(RSTRING_PTR(vtype));
157
+ vtype = INT2NUM(vtype);
158
+ }
159
+
160
+ return tcrdbtblsetindex(db, RSTRING_PTR(vname), NUM2INT(vtype)) ? Qtrue : Qfalse;
161
+ }
162
+
163
+ static VALUE cTable_genuid(VALUE vself){
164
+ TCRDB *db = mTokyoTyrant_getdb(vself);
165
+ return LL2NUM(tcrdbtblgenuid(db));
166
+ }
167
+
168
+ static VALUE cTable_fetch(int argc, VALUE *argv, VALUE vself){
169
+ VALUE vkey, vrv, vforce;
170
+ rb_scan_args(argc, argv, "11", &vkey, &vforce);
171
+ if(rb_block_given_p() != Qtrue) rb_raise(rb_eArgError, "no block given");
172
+ if(vforce == Qnil) vforce = Qfalse;
173
+ vkey = StringValueEx(vkey);
174
+
175
+ if(vforce != Qfalse ||
176
+ (vrv = cTable_get(vself, vkey)) == Qnil){
177
+ vrv = rb_yield(vkey);
178
+ cTable_put(vself, vkey, vrv);
179
+ }
180
+
181
+ return vrv;
182
+ }
183
+
184
+ static VALUE cTable_each(VALUE vself){
185
+ VALUE vrv;
186
+ TCMAP *cols;
187
+ char *kbuf;
188
+ int ksiz;
189
+ if(rb_block_given_p() != Qtrue) rb_raise(rb_eArgError, "no block given");
190
+ TCRDB *db = mTokyoTyrant_getdb(vself);
191
+ vrv = Qnil;
192
+ tcrdbiterinit(db);
193
+ while((kbuf = tcrdbiternext(db, &ksiz)) != NULL){
194
+ if((cols = tcrdbtblget(db, kbuf, ksiz)) != NULL){
195
+ vrv = rb_yield_values(2, rb_str_new(kbuf, ksiz), maptovhash(cols));
196
+ tcmapdel(cols);
197
+ } else {
198
+ vrv = rb_yield_values(2, rb_str_new(kbuf, ksiz), Qnil);
199
+ }
200
+ tcfree(kbuf);
201
+ }
202
+ return vrv;
203
+ }
204
+
205
+ static VALUE cTable_each_value(VALUE vself){
206
+ VALUE vrv;
207
+ TCMAP *cols;
208
+ char *kbuf;
209
+ int ksiz;
210
+ if(rb_block_given_p() != Qtrue) rb_raise(rb_eArgError, "no block given");
211
+ TCRDB *db = mTokyoTyrant_getdb(vself);
212
+ vrv = Qnil;
213
+ tcrdbiterinit(db);
214
+ while((kbuf = tcrdbiternext(db, &ksiz)) != NULL){
215
+ if((cols = tcrdbtblget(db, kbuf, ksiz)) != NULL){
216
+ vrv = rb_yield(maptovhash(cols));
217
+ tcmapdel(cols);
218
+ } else {
219
+ vrv = rb_yield(Qnil);
220
+ }
221
+ tcfree(kbuf);
222
+ }
223
+ return vrv;
224
+ }
225
+
226
+ static VALUE cTable_values(VALUE vself){
227
+ VALUE vary;
228
+ TCMAP *cols;
229
+ char *kxstr;
230
+ int ksiz;
231
+ TCRDB *db = mTokyoTyrant_getdb(vself);
232
+ vary = rb_ary_new2(tcrdbrnum(db));
233
+ tcrdbiterinit(db);
234
+ while((kxstr = tcrdbiternext(db, &ksiz)) != NULL){
235
+ cols = tcrdbtblget(db, kxstr, ksiz);
236
+ rb_ary_push(vary, maptovhash(cols));
237
+ tcmapdel(cols);
238
+ tcfree(kxstr);
239
+ }
240
+ return vary;
241
+ }
242
+
243
+ // Probably should dry these up
244
+ static VALUE cTable_prepare_query(VALUE vself){
245
+ VALUE vqry;
246
+ vqry = rb_class_new_instance(1, &vself, rb_path2class("TokyoTyrant::Query"));
247
+ if(rb_block_given_p()) rb_yield_values(1, vqry);
248
+ return vqry;
249
+ }
250
+
251
+ static VALUE cTable_query(VALUE vself){
252
+ VALUE vqry, vary;
253
+ vqry = rb_class_new_instance(1, &vself, rb_path2class("TokyoTyrant::Query"));
254
+ if(rb_block_given_p()) {
255
+ rb_yield_values(1, vqry);
256
+ vary = rb_funcall(vqry, rb_intern("run"), 0);
257
+ return vary;
258
+ } else {
259
+ return vqry;
260
+ }
261
+ }
262
+
263
+ static VALUE cTable_find(VALUE vself){
264
+ VALUE vqry, vary;
265
+ vqry = rb_class_new_instance(1, &vself, rb_path2class("TokyoTyrant::Query"));
266
+ if(rb_block_given_p()) rb_yield_values(1, vqry);
267
+ vary = rb_funcall(vqry, rb_intern("get"), 0);
268
+ return vary;
269
+ }
270
+
271
+ static VALUE cTable_search(int argc, VALUE *argv, VALUE vself){
272
+ VALUE vqrys, vkeys, vtype;
273
+ int qsiz, type, j;
274
+
275
+ rb_scan_args(argc, argv, "1*", &vtype, &vqrys);
276
+
277
+ qsiz = argc - 1;
278
+ RDBQRY *qrys[qsiz];
279
+
280
+ vtype = StringValueEx(vtype);
281
+ type = tctdbstrtometasearcytype(RSTRING_PTR(vtype));
282
+
283
+ for(j = 0; j < qsiz; j++){
284
+ VALUE vqry = rb_iv_get(rb_ary_entry(vqrys, j), RDBQRYVNDATA);
285
+ Data_Get_Struct(vqry, RDBQRY, qrys[j]);
286
+ }
287
+ TCLIST *res = tcrdbmetasearch(qrys, qsiz, type);
288
+ vkeys = listtovary(res);
289
+ tclistdel(res);
290
+
291
+ return vkeys;
292
+ }
293
+
294
+ void init_table(){
295
+ rb_define_method(cTable, "mput", cTable_mput, 1);
296
+ rb_define_alias(cTable, "lput", "mput"); // Rufus Compat
297
+ rb_define_method(cTable, "put", cTable_put, 2);
298
+ rb_define_alias(cTable, "[]=", "put");
299
+ rb_define_method(cTable, "putkeep", cTable_putkeep, 2);
300
+ rb_define_method(cTable, "putcat", cTable_putcat, 2);
301
+ rb_define_method(cTable, "out", cTable_out, 1);
302
+ rb_define_alias(cTable, "delete", "out"); // Rufus Compat
303
+ rb_define_method(cTable, "get", cTable_get, 1);
304
+ rb_define_method(cTable, "mget", cTable_mget, -1);
305
+ rb_define_alias(cTable, "lget", "mget"); // Rufus Compat
306
+ rb_define_alias(cTable, "[]", "get");
307
+ rb_define_method(cTable, "set_index", cTable_setindex, 2); // Rufus Compat
308
+ rb_define_method(cTable, "genuid", cTable_genuid, 0);
309
+ rb_define_alias(cTable, "generate_unique_id", "genuid");
310
+ rb_define_method(cTable, "fetch", cTable_fetch, -1);
311
+ rb_define_method(cTable, "each", cTable_each, 0);
312
+ rb_define_alias(cTable, "each_pair", "each");
313
+ rb_define_method(cTable, "each_value", cTable_each_value, 0);
314
+ rb_define_method(cTable, "values", cTable_values, 0);
315
+ rb_define_method(cTable, "prepare_query", cTable_prepare_query, 0);
316
+ rb_define_method(cTable, "query", cTable_query, 0);
317
+ rb_define_method(cTable, "find", cTable_find, 0);
318
+ rb_define_method(cTable, "search", cTable_search, -1);
319
+ }
@@ -0,0 +1,8 @@
1
+ #ifndef RUBY_TOKYOTYRANT_TABLE
2
+ #define RUBY_TOKYOTYRANT_TABLE
3
+
4
+ #include <tokyo_tyrant.h>
5
+
6
+ void init_table();
7
+
8
+ #endif
data/spec/ext.lua ADDED
@@ -0,0 +1,4 @@
1
+ -- echo back the key and the value
2
+ function echo(key, value)
3
+ return key .. "\t" .. value
4
+ end