kyotocabinet 1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/extconf.rb +30 -0
- data/kyotocabinet.cc +1266 -0
- metadata +67 -0
data/extconf.rb
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
require "mkmf"
|
|
2
|
+
|
|
3
|
+
File::unlink("Makefile") if (File::exist?("Makefile"))
|
|
4
|
+
dir_config('kyotocabinet')
|
|
5
|
+
|
|
6
|
+
home = ENV["HOME"]
|
|
7
|
+
ENV["PATH"] = ENV["PATH"] + ":/usr/local/bin:$home/bin:."
|
|
8
|
+
kccflags = `kcutilcodec conf -i 2>/dev/null`.chomp
|
|
9
|
+
kcldflags = `kcutilcodec conf -l 2>/dev/null`.chomp
|
|
10
|
+
kcldflags = kcldflags.gsub(/-l[\S]+/, "").strip
|
|
11
|
+
kclibs = `kcutilcodec conf -l 2>/dev/null`.chomp
|
|
12
|
+
kclibs = kclibs.gsub(/-L[\S]+/, "").strip
|
|
13
|
+
|
|
14
|
+
kccflags = "-I/usr/local/include" if(kccflags.length < 1)
|
|
15
|
+
kcldflags = "-L/usr/local/lib" if(kcldflags.length < 1)
|
|
16
|
+
kclibs = "-lkyotocabinet -lz -lstdc++ -lrt -lpthread -lm -lc" if(kclibs.length < 1)
|
|
17
|
+
|
|
18
|
+
Config::CONFIG["CPP"] = "g++ -E"
|
|
19
|
+
$CFLAGS = "-I. #{kccflags} -Wall #{$CFLAGS} -O2"
|
|
20
|
+
$LDFLAGS = "#{$LDFLAGS} -L. #{kcldflags}"
|
|
21
|
+
$libs = "#{$libs} #{kclibs}"
|
|
22
|
+
|
|
23
|
+
printf("setting variables ...\n")
|
|
24
|
+
printf(" \$CFLAGS = %s\n", $CFLAGS)
|
|
25
|
+
printf(" \$LDFLAGS = %s\n", $LDFLAGS)
|
|
26
|
+
printf(" \$libs = %s\n", $libs)
|
|
27
|
+
|
|
28
|
+
if have_header('kccommon.h')
|
|
29
|
+
create_makefile('kyotocabinet')
|
|
30
|
+
end
|
data/kyotocabinet.cc
ADDED
|
@@ -0,0 +1,1266 @@
|
|
|
1
|
+
/*************************************************************************************************
|
|
2
|
+
* Ruby binding
|
|
3
|
+
* Copyright (C) 2009-2010 Mikio Hirabayashi
|
|
4
|
+
* This file is part of Kyoto Cabinet.
|
|
5
|
+
* This program is free software: you can redistribute it and/or modify it under the terms of
|
|
6
|
+
* the GNU General Public License as published by the Free Software Foundation, either version
|
|
7
|
+
* 3 of the License, or any later version.
|
|
8
|
+
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
|
9
|
+
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
10
|
+
* See the GNU General Public License for more details.
|
|
11
|
+
* You should have received a copy of the GNU General Public License along with this program.
|
|
12
|
+
* If not, see <http://www.gnu.org/licenses/>.
|
|
13
|
+
*************************************************************************************************/
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
#include <kcpolydb.h>
|
|
17
|
+
|
|
18
|
+
namespace kc = kyotocabinet;
|
|
19
|
+
|
|
20
|
+
extern "C" {
|
|
21
|
+
|
|
22
|
+
#include <ruby.h>
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
typedef std::map<std::string, std::string> StringMap;
|
|
26
|
+
typedef VALUE (*METHOD)(...);
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
const int32_t VISMAGICNOP = INT32_MAX / 4 + 0;
|
|
30
|
+
const int32_t VISMAGICREMOVE = INT32_MAX / 4 + 1;
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
VALUE mod_kc;
|
|
34
|
+
VALUE cls_th;
|
|
35
|
+
VALUE cls_mtx;
|
|
36
|
+
VALUE cls_ex_arg;
|
|
37
|
+
VALUE cls_err;
|
|
38
|
+
VALUE cls_vis;
|
|
39
|
+
VALUE cls_vis_magic;
|
|
40
|
+
VALUE cls_fproc;
|
|
41
|
+
VALUE cls_cur;
|
|
42
|
+
VALUE cls_db;
|
|
43
|
+
ID id_th_pass;
|
|
44
|
+
ID id_mtx_lock;
|
|
45
|
+
ID id_mtx_unlock;
|
|
46
|
+
ID id_err_to_s;
|
|
47
|
+
ID id_vis_magic;
|
|
48
|
+
ID id_vis_nop;
|
|
49
|
+
ID id_vis_remove;
|
|
50
|
+
ID id_vis_visit_full;
|
|
51
|
+
ID id_vis_visit_empty;
|
|
52
|
+
ID id_fproc_process;
|
|
53
|
+
ID id_cur_db;
|
|
54
|
+
ID id_db_error;
|
|
55
|
+
ID id_db_open;
|
|
56
|
+
ID id_db_close;
|
|
57
|
+
ID id_db_mutex;
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
void Init_kyotocabinet();
|
|
61
|
+
static volatile VALUE StringValueEx(VALUE vobj);
|
|
62
|
+
static VALUE maptovhash(const StringMap* map);
|
|
63
|
+
static void init_env();
|
|
64
|
+
static void th_pass();
|
|
65
|
+
static void init_err();
|
|
66
|
+
static VALUE err_new(VALUE cls);
|
|
67
|
+
static void err_del(void* ptr);
|
|
68
|
+
static VALUE err_initialize(int argc, VALUE* argv, VALUE vself);
|
|
69
|
+
static VALUE err_set(VALUE vself, VALUE vcode, VALUE vmsg);
|
|
70
|
+
static VALUE err_code(VALUE vself);
|
|
71
|
+
static VALUE err_name(VALUE vself);
|
|
72
|
+
static VALUE err_message(VALUE vself);
|
|
73
|
+
static VALUE err_to_s(VALUE vself);
|
|
74
|
+
static void init_vis();
|
|
75
|
+
static VALUE vis_magic_initialize(VALUE vself, VALUE vnum);
|
|
76
|
+
static VALUE vis_visit_full(VALUE vself, VALUE vkey, VALUE vvalue);
|
|
77
|
+
static VALUE vis_visit_empty(VALUE vself, VALUE vkey);
|
|
78
|
+
static void init_fproc();
|
|
79
|
+
static VALUE fproc_process(VALUE vself, VALUE vpath);
|
|
80
|
+
static void init_cur();
|
|
81
|
+
static VALUE cur_new(VALUE cls);
|
|
82
|
+
static void cur_del(void* ptr);
|
|
83
|
+
static VALUE cur_initialize(VALUE vself, VALUE vdb);
|
|
84
|
+
static VALUE cur_disable(VALUE vself);
|
|
85
|
+
static VALUE cur_accept(int argc, VALUE* argv, VALUE vself);
|
|
86
|
+
static VALUE cur_get_key(VALUE vself);
|
|
87
|
+
static VALUE cur_get_value(VALUE vself);
|
|
88
|
+
static VALUE cur_get(VALUE vself);
|
|
89
|
+
static VALUE cur_remove(VALUE vself);
|
|
90
|
+
static VALUE cur_jump(int argc, VALUE* argv, VALUE vself);
|
|
91
|
+
static VALUE cur_step(VALUE vself);
|
|
92
|
+
static VALUE cur_db(VALUE vself);
|
|
93
|
+
static VALUE cur_error(VALUE vself);
|
|
94
|
+
static VALUE cur_to_s(VALUE vself);
|
|
95
|
+
static void init_db();
|
|
96
|
+
static VALUE db_new(VALUE cls);
|
|
97
|
+
static void db_del(void* ptr);
|
|
98
|
+
static void db_lock(VALUE vdb);
|
|
99
|
+
static void db_unlock(VALUE vdb);
|
|
100
|
+
static VALUE db_initialize(VALUE vself);
|
|
101
|
+
static VALUE db_error(VALUE vself);
|
|
102
|
+
static VALUE db_open(int argc, VALUE* argv, VALUE vself);
|
|
103
|
+
static VALUE db_close(VALUE vself);
|
|
104
|
+
static VALUE db_accept(int argc, VALUE* argv, VALUE vself);
|
|
105
|
+
static VALUE db_iterate(int argc, VALUE* argv, VALUE vself);
|
|
106
|
+
static VALUE db_set(VALUE vself, VALUE vkey, VALUE vvalue);
|
|
107
|
+
static VALUE db_add(VALUE vself, VALUE vkey, VALUE vvalue);
|
|
108
|
+
static VALUE db_append(VALUE vself, VALUE vkey, VALUE vvalue);
|
|
109
|
+
static VALUE db_increment(int argc, VALUE* argv, VALUE vself);
|
|
110
|
+
static VALUE db_cas(VALUE vself, VALUE vkey, VALUE voval, VALUE vnval);
|
|
111
|
+
static VALUE db_remove(VALUE vself, VALUE vkey);
|
|
112
|
+
static VALUE db_get(VALUE vself, VALUE vkey);
|
|
113
|
+
static VALUE db_clear(VALUE vself);
|
|
114
|
+
static VALUE db_synchronize(int argc, VALUE* argv, VALUE vself);
|
|
115
|
+
static VALUE db_begin_transaction(int argc, VALUE* argv, VALUE vself);
|
|
116
|
+
static VALUE db_end_transaction(int argc, VALUE* argv, VALUE vself);
|
|
117
|
+
static VALUE db_count(VALUE vself);
|
|
118
|
+
static VALUE db_size(VALUE vself);
|
|
119
|
+
static VALUE db_path(VALUE vself);
|
|
120
|
+
static VALUE db_status(VALUE vself);
|
|
121
|
+
static VALUE db_cursor(VALUE vself);
|
|
122
|
+
static VALUE db_to_s(VALUE vself);
|
|
123
|
+
static VALUE db_each(VALUE vself);
|
|
124
|
+
static VALUE db_each_key(VALUE vself);
|
|
125
|
+
static VALUE db_each_value(VALUE vself);
|
|
126
|
+
static VALUE db_process(int argc, VALUE* argv, VALUE vself);
|
|
127
|
+
static VALUE db_process_body(VALUE args);
|
|
128
|
+
static VALUE db_process_ensure(VALUE args);
|
|
129
|
+
|
|
130
|
+
|
|
131
|
+
class CursorBurrow {
|
|
132
|
+
private:
|
|
133
|
+
typedef std::vector<kc::PolyDB::Cursor*> CursorList;
|
|
134
|
+
public:
|
|
135
|
+
CursorBurrow() : dcurs_() {}
|
|
136
|
+
~CursorBurrow() {
|
|
137
|
+
sweap();
|
|
138
|
+
}
|
|
139
|
+
void sweap() {
|
|
140
|
+
if (dcurs_.size() > 0) {
|
|
141
|
+
CursorList::iterator dit = dcurs_.begin();
|
|
142
|
+
CursorList::iterator ditend = dcurs_.end();
|
|
143
|
+
while (dit != ditend) {
|
|
144
|
+
kc::PolyDB::Cursor* cur = *dit;
|
|
145
|
+
delete cur;
|
|
146
|
+
dit++;
|
|
147
|
+
}
|
|
148
|
+
dcurs_.clear();
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
void deposit(kc::PolyDB::Cursor* cur) {
|
|
152
|
+
dcurs_.push_back(cur);
|
|
153
|
+
}
|
|
154
|
+
private:
|
|
155
|
+
CursorList dcurs_;
|
|
156
|
+
} g_curbur;
|
|
157
|
+
|
|
158
|
+
|
|
159
|
+
struct SoftCursor {
|
|
160
|
+
kc::PolyDB::Cursor* cur_;
|
|
161
|
+
SoftCursor() : cur_(NULL) {}
|
|
162
|
+
~SoftCursor() {
|
|
163
|
+
if (cur_) g_curbur.deposit(cur_);
|
|
164
|
+
}
|
|
165
|
+
};
|
|
166
|
+
|
|
167
|
+
|
|
168
|
+
class SoftVisitor : public kc::PolyDB::Visitor {
|
|
169
|
+
public:
|
|
170
|
+
SoftVisitor(VALUE vvisitor) : vvisitor_(vvisitor) {}
|
|
171
|
+
private:
|
|
172
|
+
const char* visit_full(const char* kbuf, size_t ksiz,
|
|
173
|
+
const char* vbuf, size_t vsiz, size_t* sp) {
|
|
174
|
+
VALUE vkey = rb_str_new(kbuf, ksiz);
|
|
175
|
+
VALUE vvalue = rb_str_new(vbuf, vsiz);
|
|
176
|
+
VALUE args = rb_ary_new3(3, vvisitor_, vkey, vvalue);
|
|
177
|
+
int result = 0;
|
|
178
|
+
VALUE vrv = rb_protect(visit_full_impl, args, &result);
|
|
179
|
+
const char* rv;
|
|
180
|
+
if (result) {
|
|
181
|
+
rv = NOP;
|
|
182
|
+
} else if (rb_obj_is_kind_of(vrv, cls_vis_magic)) {
|
|
183
|
+
VALUE vmagic = rb_ivar_get(vrv, id_vis_magic);
|
|
184
|
+
int32_t num = NUM2INT(vmagic);
|
|
185
|
+
if (num == VISMAGICREMOVE) {
|
|
186
|
+
rv = kc::PolyDB::Visitor::REMOVE;
|
|
187
|
+
} else {
|
|
188
|
+
rv = kc::PolyDB::Visitor::NOP;
|
|
189
|
+
}
|
|
190
|
+
} else if (vrv == Qnil || vrv == Qfalse) {
|
|
191
|
+
rv = NOP;
|
|
192
|
+
} else {
|
|
193
|
+
vrv = StringValueEx(vrv);
|
|
194
|
+
rv = RSTRING_PTR(vrv);
|
|
195
|
+
*sp = RSTRING_LEN(vrv);
|
|
196
|
+
}
|
|
197
|
+
return rv;
|
|
198
|
+
}
|
|
199
|
+
const char* visit_empty(const char* kbuf, size_t ksiz, size_t* sp) {
|
|
200
|
+
VALUE vkey = rb_str_new(kbuf, ksiz);
|
|
201
|
+
VALUE args = rb_ary_new3(2, vvisitor_, vkey);
|
|
202
|
+
int result = 0;
|
|
203
|
+
VALUE vrv = rb_protect(visit_empty_impl, args, &result);
|
|
204
|
+
const char* rv;
|
|
205
|
+
if (result) {
|
|
206
|
+
rv = NOP;
|
|
207
|
+
} else if (rb_obj_is_instance_of(vrv, cls_vis_magic)) {
|
|
208
|
+
VALUE vmagic = rb_ivar_get(vrv, id_vis_magic);
|
|
209
|
+
int32_t num = NUM2INT(vmagic);
|
|
210
|
+
if (num == VISMAGICREMOVE) {
|
|
211
|
+
rv = kc::PolyDB::Visitor::REMOVE;
|
|
212
|
+
} else {
|
|
213
|
+
rv = kc::PolyDB::Visitor::NOP;
|
|
214
|
+
}
|
|
215
|
+
} else if (vrv == Qnil || vrv == Qfalse) {
|
|
216
|
+
rv = NOP;
|
|
217
|
+
} else {
|
|
218
|
+
vrv = StringValueEx(vrv);
|
|
219
|
+
rv = RSTRING_PTR(vrv);
|
|
220
|
+
*sp = RSTRING_LEN(vrv);
|
|
221
|
+
}
|
|
222
|
+
return rv;
|
|
223
|
+
}
|
|
224
|
+
static VALUE visit_full_impl(VALUE args) {
|
|
225
|
+
VALUE vvisitor = rb_ary_shift(args);
|
|
226
|
+
VALUE vkey = rb_ary_shift(args);
|
|
227
|
+
VALUE vvalue = rb_ary_shift(args);
|
|
228
|
+
return rb_funcall(vvisitor, id_vis_visit_full, 2, vkey, vvalue);
|
|
229
|
+
}
|
|
230
|
+
static VALUE visit_empty_impl(VALUE args) {
|
|
231
|
+
VALUE vvisitor = rb_ary_shift(args);
|
|
232
|
+
VALUE vkey = rb_ary_shift(args);
|
|
233
|
+
return rb_funcall(vvisitor, id_vis_visit_empty, 1, vkey);
|
|
234
|
+
}
|
|
235
|
+
VALUE vvisitor_;
|
|
236
|
+
};
|
|
237
|
+
|
|
238
|
+
|
|
239
|
+
class SoftEachVisitor : public kc::PolyDB::Visitor {
|
|
240
|
+
private:
|
|
241
|
+
const char* visit_full(const char* kbuf, size_t ksiz,
|
|
242
|
+
const char* vbuf, size_t vsiz, size_t* sp) {
|
|
243
|
+
VALUE vkey = rb_str_new(kbuf, ksiz);
|
|
244
|
+
VALUE vvalue = rb_str_new(vbuf, vsiz);
|
|
245
|
+
VALUE args = rb_ary_new3(2, vkey, vvalue);
|
|
246
|
+
int result = 0;
|
|
247
|
+
rb_protect(visit_full_impl, args, &result);
|
|
248
|
+
return NOP;
|
|
249
|
+
}
|
|
250
|
+
static VALUE visit_full_impl(VALUE args) {
|
|
251
|
+
return rb_yield(args);
|
|
252
|
+
}
|
|
253
|
+
};
|
|
254
|
+
|
|
255
|
+
|
|
256
|
+
class SoftEachKeyVisitor : public kc::PolyDB::Visitor {
|
|
257
|
+
private:
|
|
258
|
+
const char* visit_full(const char* kbuf, size_t ksiz,
|
|
259
|
+
const char* vbuf, size_t vsiz, size_t* sp) {
|
|
260
|
+
VALUE vkey = rb_str_new(kbuf, ksiz);
|
|
261
|
+
VALUE args = rb_ary_new3(1, vkey);
|
|
262
|
+
int result = 0;
|
|
263
|
+
rb_protect(visit_full_impl, args, &result);
|
|
264
|
+
return NOP;
|
|
265
|
+
}
|
|
266
|
+
static VALUE visit_full_impl(VALUE args) {
|
|
267
|
+
return rb_yield(args);
|
|
268
|
+
}
|
|
269
|
+
};
|
|
270
|
+
|
|
271
|
+
|
|
272
|
+
class SoftEachValueVisitor : public kc::PolyDB::Visitor {
|
|
273
|
+
private:
|
|
274
|
+
const char* visit_full(const char* kbuf, size_t ksiz,
|
|
275
|
+
const char* vbuf, size_t vsiz, size_t* sp) {
|
|
276
|
+
VALUE vvalue = rb_str_new(vbuf, vsiz);
|
|
277
|
+
VALUE args = rb_ary_new3(1, vvalue);
|
|
278
|
+
int result = 0;
|
|
279
|
+
rb_protect(visit_full_impl, args, &result);
|
|
280
|
+
return NOP;
|
|
281
|
+
}
|
|
282
|
+
static VALUE visit_full_impl(VALUE args) {
|
|
283
|
+
return rb_yield(args);
|
|
284
|
+
}
|
|
285
|
+
};
|
|
286
|
+
|
|
287
|
+
|
|
288
|
+
class SoftFileProcessor : public kc::PolyDB::FileProcessor {
|
|
289
|
+
public:
|
|
290
|
+
SoftFileProcessor(VALUE vproc) : vproc_(vproc) {}
|
|
291
|
+
private:
|
|
292
|
+
bool process(const std::string& path) {
|
|
293
|
+
VALUE vpath = rb_str_new2(path.c_str());
|
|
294
|
+
VALUE args = rb_ary_new3(2, vproc_, vpath);
|
|
295
|
+
int result = 0;
|
|
296
|
+
VALUE vrv = rb_protect(process_impl, args, &result);
|
|
297
|
+
return !result && vrv != Qnil && vrv != Qfalse;
|
|
298
|
+
}
|
|
299
|
+
static VALUE process_impl(VALUE args) {
|
|
300
|
+
VALUE vproc = rb_ary_shift(args);
|
|
301
|
+
VALUE vpath = rb_ary_shift(args);
|
|
302
|
+
return rb_funcall(vproc, id_fproc_process, 1, vpath);
|
|
303
|
+
}
|
|
304
|
+
VALUE vproc_;
|
|
305
|
+
};
|
|
306
|
+
|
|
307
|
+
|
|
308
|
+
void Init_kyotocabinet() {
|
|
309
|
+
mod_kc = rb_define_module("KyotoCabinet");
|
|
310
|
+
rb_define_const(mod_kc, "VERSION", rb_str_new2(kc::VERSION));
|
|
311
|
+
init_env();
|
|
312
|
+
init_err();
|
|
313
|
+
init_vis();
|
|
314
|
+
init_fproc();
|
|
315
|
+
init_cur();
|
|
316
|
+
init_db();
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
|
|
320
|
+
static volatile VALUE StringValueEx(VALUE vobj) {
|
|
321
|
+
char kbuf[kc::NUMBUFSIZ];
|
|
322
|
+
switch (TYPE(vobj)) {
|
|
323
|
+
case T_FIXNUM: {
|
|
324
|
+
size_t ksiz = std::sprintf(kbuf, "%d", (int)FIX2INT(vobj));
|
|
325
|
+
return rb_str_new(kbuf, ksiz);
|
|
326
|
+
}
|
|
327
|
+
case T_BIGNUM: {
|
|
328
|
+
size_t ksiz = std::sprintf(kbuf, "%lld", (long long)NUM2LL(vobj));
|
|
329
|
+
return rb_str_new(kbuf, ksiz);
|
|
330
|
+
}
|
|
331
|
+
case T_TRUE: {
|
|
332
|
+
size_t ksiz = std::sprintf(kbuf, "true");
|
|
333
|
+
return rb_str_new(kbuf, ksiz);
|
|
334
|
+
}
|
|
335
|
+
case T_FALSE: {
|
|
336
|
+
size_t ksiz = std::sprintf(kbuf, "false");
|
|
337
|
+
return rb_str_new(kbuf, ksiz);
|
|
338
|
+
}
|
|
339
|
+
case T_NIL: {
|
|
340
|
+
size_t ksiz = std::sprintf(kbuf, "nil");
|
|
341
|
+
return rb_str_new(kbuf, ksiz);
|
|
342
|
+
}
|
|
343
|
+
case T_SYMBOL: {
|
|
344
|
+
return rb_str_new2(rb_id2name(SYM2ID(vobj)));
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
return StringValue(vobj);
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
|
|
351
|
+
static VALUE maptovhash(const StringMap* map) {
|
|
352
|
+
VALUE vhash = rb_hash_new();
|
|
353
|
+
StringMap::const_iterator it = map->begin();
|
|
354
|
+
StringMap::const_iterator itend = map->end();
|
|
355
|
+
while (it != itend) {
|
|
356
|
+
VALUE vkey = rb_str_new(it->first.c_str(), it->first.size());
|
|
357
|
+
VALUE vvalue = rb_str_new(it->second.c_str(), it->second.size());
|
|
358
|
+
rb_hash_aset(vhash, vkey, vvalue);
|
|
359
|
+
it++;
|
|
360
|
+
}
|
|
361
|
+
return vhash;
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
|
|
365
|
+
static void init_env() {
|
|
366
|
+
rb_require("thread");
|
|
367
|
+
cls_th = rb_path2class("Thread");
|
|
368
|
+
id_th_pass = rb_intern("pass");
|
|
369
|
+
cls_mtx = rb_path2class("Mutex");
|
|
370
|
+
id_mtx_lock = rb_intern("lock");
|
|
371
|
+
id_mtx_unlock = rb_intern("unlock");
|
|
372
|
+
cls_ex_arg = rb_path2class("ArgumentError");
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
|
|
376
|
+
static void th_pass() {
|
|
377
|
+
rb_funcall(cls_th, id_th_pass, 0);
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
|
|
381
|
+
static void init_err() {
|
|
382
|
+
cls_err = rb_define_class_under(mod_kc, "Error", rb_cObject);
|
|
383
|
+
rb_define_alloc_func(cls_err, err_new);
|
|
384
|
+
rb_define_const(cls_err, "SUCCESS", INT2FIX(kc::PolyDB::Error::SUCCESS));
|
|
385
|
+
rb_define_const(cls_err, "NOIMPL", INT2FIX(kc::PolyDB::Error::NOIMPL));
|
|
386
|
+
rb_define_const(cls_err, "INVALID", INT2FIX(kc::PolyDB::Error::INVALID));
|
|
387
|
+
rb_define_const(cls_err, "NOFILE", INT2FIX(kc::PolyDB::Error::NOFILE));
|
|
388
|
+
rb_define_const(cls_err, "NOPERM", INT2FIX(kc::PolyDB::Error::NOPERM));
|
|
389
|
+
rb_define_const(cls_err, "BROKEN", INT2FIX(kc::PolyDB::Error::BROKEN));
|
|
390
|
+
rb_define_const(cls_err, "DUPREC", INT2FIX(kc::PolyDB::Error::DUPREC));
|
|
391
|
+
rb_define_const(cls_err, "NOREC", INT2FIX(kc::PolyDB::Error::NOREC));
|
|
392
|
+
rb_define_const(cls_err, "LOGIC", INT2FIX(kc::PolyDB::Error::LOGIC));
|
|
393
|
+
rb_define_const(cls_err, "SYSTEM", INT2FIX(kc::PolyDB::Error::SYSTEM));
|
|
394
|
+
rb_define_const(cls_err, "MISC", INT2FIX(kc::PolyDB::Error::MISC));
|
|
395
|
+
rb_define_private_method(cls_err, "initialize", (METHOD)err_initialize, -1);
|
|
396
|
+
rb_define_method(cls_err, "set", (METHOD)err_set, 2);
|
|
397
|
+
rb_define_method(cls_err, "code", (METHOD)err_code, 0);
|
|
398
|
+
rb_define_method(cls_err, "name", (METHOD)err_name, 0);
|
|
399
|
+
rb_define_method(cls_err, "message", (METHOD)err_message, 0);
|
|
400
|
+
rb_define_method(cls_err, "to_i", (METHOD)err_code, 0);
|
|
401
|
+
rb_define_method(cls_err, "to_s", (METHOD)err_to_s, 0);
|
|
402
|
+
id_err_to_s = rb_intern("to_s");
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
|
|
406
|
+
static VALUE err_new(VALUE cls) {
|
|
407
|
+
kc::PolyDB::Error* err = new kc::PolyDB::Error();
|
|
408
|
+
return Data_Wrap_Struct(cls_err, 0, err_del, err);
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
|
|
412
|
+
static void err_del(void* ptr) {
|
|
413
|
+
delete (kc::PolyDB::Error*)ptr;
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
|
|
417
|
+
static VALUE err_initialize(int argc, VALUE* argv, VALUE vself) {
|
|
418
|
+
kc::PolyDB::Error* err;
|
|
419
|
+
Data_Get_Struct(vself, kc::PolyDB::Error, err);
|
|
420
|
+
VALUE vcode, vmsg;
|
|
421
|
+
rb_scan_args(argc, argv, "02", &vcode, &vmsg);
|
|
422
|
+
int32_t code = vcode == Qnil ? kc::PolyDB::Error::SUCCESS : NUM2INT(vcode);
|
|
423
|
+
const char* msg;
|
|
424
|
+
if (vmsg == Qnil) {
|
|
425
|
+
msg = "error";
|
|
426
|
+
} else {
|
|
427
|
+
vmsg = StringValueEx(vmsg);
|
|
428
|
+
msg = RSTRING_PTR(vmsg);
|
|
429
|
+
}
|
|
430
|
+
err->set((kc::PolyDB::Error::Code)code, msg);
|
|
431
|
+
return Qnil;
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
|
|
435
|
+
static VALUE err_set(VALUE vself, VALUE vcode, VALUE vmsg) {
|
|
436
|
+
kc::PolyDB::Error* err;
|
|
437
|
+
Data_Get_Struct(vself, kc::PolyDB::Error, err);
|
|
438
|
+
int32_t code = NUM2INT(vcode);
|
|
439
|
+
vmsg = StringValueEx(vmsg);
|
|
440
|
+
const char* msg = RSTRING_PTR(vmsg);
|
|
441
|
+
err->set((kc::PolyDB::Error::Code)code, msg);
|
|
442
|
+
return Qnil;
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
|
|
446
|
+
static VALUE err_code(VALUE vself) {
|
|
447
|
+
kc::PolyDB::Error* err;
|
|
448
|
+
Data_Get_Struct(vself, kc::PolyDB::Error, err);
|
|
449
|
+
return INT2FIX(err->code());
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
|
|
453
|
+
static VALUE err_name(VALUE vself) {
|
|
454
|
+
kc::PolyDB::Error* err;
|
|
455
|
+
Data_Get_Struct(vself, kc::PolyDB::Error, err);
|
|
456
|
+
return rb_str_new2(err->name());
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
|
|
460
|
+
static VALUE err_message(VALUE vself) {
|
|
461
|
+
kc::PolyDB::Error* err;
|
|
462
|
+
Data_Get_Struct(vself, kc::PolyDB::Error, err);
|
|
463
|
+
return rb_str_new2(err->message());
|
|
464
|
+
}
|
|
465
|
+
|
|
466
|
+
|
|
467
|
+
static VALUE err_to_s(VALUE vself) {
|
|
468
|
+
kc::PolyDB::Error* err;
|
|
469
|
+
Data_Get_Struct(vself, kc::PolyDB::Error, err);
|
|
470
|
+
std::string str;
|
|
471
|
+
kc::strprintf(&str, "%s: %s", err->name(), err->message());
|
|
472
|
+
return rb_str_new2(str.c_str());
|
|
473
|
+
}
|
|
474
|
+
|
|
475
|
+
|
|
476
|
+
static void init_vis() {
|
|
477
|
+
cls_vis = rb_define_class_under(mod_kc, "Visitor", rb_cObject);
|
|
478
|
+
cls_vis_magic = rb_define_class_under(mod_kc, "VisitorMagic", rb_cObject);
|
|
479
|
+
rb_define_private_method(cls_vis_magic, "initialize", (METHOD)vis_magic_initialize, 1);
|
|
480
|
+
id_vis_magic = rb_intern("@magic_");
|
|
481
|
+
VALUE vnopnum = INT2FIX(VISMAGICNOP);
|
|
482
|
+
VALUE vnop = rb_class_new_instance(1, &vnopnum, cls_vis_magic);
|
|
483
|
+
rb_define_const(cls_vis, "NOP", vnop);
|
|
484
|
+
VALUE vremovenum = INT2FIX(VISMAGICREMOVE);
|
|
485
|
+
VALUE vremove = rb_class_new_instance(1, &vremovenum, cls_vis_magic);
|
|
486
|
+
rb_define_const(cls_vis, "REMOVE", vremove);
|
|
487
|
+
rb_define_method(cls_vis, "visit_full", (METHOD)vis_visit_full, 2);
|
|
488
|
+
rb_define_method(cls_vis, "visit_empty", (METHOD)vis_visit_empty, 1);
|
|
489
|
+
id_vis_nop = rb_intern("NOP");
|
|
490
|
+
id_vis_remove = rb_intern("REMOVE");
|
|
491
|
+
id_vis_visit_full = rb_intern("visit_full");
|
|
492
|
+
id_vis_visit_empty = rb_intern("visit_empty");
|
|
493
|
+
}
|
|
494
|
+
|
|
495
|
+
|
|
496
|
+
static VALUE vis_magic_initialize(VALUE vself, VALUE vnum) {
|
|
497
|
+
rb_ivar_set(vself, id_vis_magic, vnum);
|
|
498
|
+
return Qnil;
|
|
499
|
+
}
|
|
500
|
+
|
|
501
|
+
|
|
502
|
+
static VALUE vis_visit_full(VALUE vself, VALUE vkey, VALUE vvalue) {
|
|
503
|
+
return rb_const_get(cls_vis, id_vis_nop);
|
|
504
|
+
}
|
|
505
|
+
|
|
506
|
+
|
|
507
|
+
static VALUE vis_visit_empty(VALUE vself, VALUE vkey) {
|
|
508
|
+
return rb_const_get(cls_vis, id_vis_nop);
|
|
509
|
+
}
|
|
510
|
+
|
|
511
|
+
|
|
512
|
+
static void init_fproc() {
|
|
513
|
+
cls_fproc = rb_define_class_under(mod_kc, "FileProcessor", rb_cObject);
|
|
514
|
+
rb_define_method(cls_fproc, "process", (METHOD)fproc_process, 1);
|
|
515
|
+
id_fproc_process = rb_intern("process");
|
|
516
|
+
}
|
|
517
|
+
|
|
518
|
+
|
|
519
|
+
static VALUE fproc_process(VALUE vself, VALUE vpath) {
|
|
520
|
+
return Qtrue;
|
|
521
|
+
}
|
|
522
|
+
|
|
523
|
+
|
|
524
|
+
static void init_cur() {
|
|
525
|
+
cls_cur = rb_define_class_under(mod_kc, "Cursor", rb_cObject);
|
|
526
|
+
rb_define_alloc_func(cls_cur, cur_new);
|
|
527
|
+
rb_define_private_method(cls_cur, "initialize", (METHOD)cur_initialize, 1);
|
|
528
|
+
rb_define_method(cls_cur, "disable", (METHOD)cur_disable, 0);
|
|
529
|
+
rb_define_method(cls_cur, "accept", (METHOD)cur_accept, -1);
|
|
530
|
+
rb_define_method(cls_cur, "get_key", (METHOD)cur_get_key, 0);
|
|
531
|
+
rb_define_method(cls_cur, "get_value", (METHOD)cur_get_value, 0);
|
|
532
|
+
rb_define_method(cls_cur, "get", (METHOD)cur_get, 0);
|
|
533
|
+
rb_define_method(cls_cur, "remove", (METHOD)cur_remove, 0);
|
|
534
|
+
rb_define_method(cls_cur, "jump", (METHOD)cur_jump, -1);
|
|
535
|
+
rb_define_method(cls_cur, "step", (METHOD)cur_step, 0);
|
|
536
|
+
rb_define_method(cls_cur, "db", (METHOD)cur_db, 0);
|
|
537
|
+
rb_define_method(cls_cur, "error", (METHOD)cur_error, 0);
|
|
538
|
+
rb_define_method(cls_cur, "to_s", (METHOD)cur_to_s, 0);
|
|
539
|
+
id_cur_db = rb_intern("@db_");
|
|
540
|
+
}
|
|
541
|
+
|
|
542
|
+
|
|
543
|
+
static VALUE cur_new(VALUE cls) {
|
|
544
|
+
SoftCursor* cur = new SoftCursor;
|
|
545
|
+
return Data_Wrap_Struct(cls_cur, 0, cur_del, cur);
|
|
546
|
+
}
|
|
547
|
+
|
|
548
|
+
|
|
549
|
+
static void cur_del(void* ptr) {
|
|
550
|
+
delete (SoftCursor*)ptr;
|
|
551
|
+
}
|
|
552
|
+
|
|
553
|
+
|
|
554
|
+
static VALUE cur_initialize(VALUE vself, VALUE vdb) {
|
|
555
|
+
SoftCursor* cur;
|
|
556
|
+
Data_Get_Struct(vself, SoftCursor, cur);
|
|
557
|
+
kc::PolyDB* db;
|
|
558
|
+
Data_Get_Struct(vdb, kc::PolyDB, db);
|
|
559
|
+
db_lock(vdb);
|
|
560
|
+
g_curbur.sweap();
|
|
561
|
+
cur->cur_ = db->cursor();
|
|
562
|
+
db_unlock(vdb);
|
|
563
|
+
rb_ivar_set(vself, id_cur_db, vdb);
|
|
564
|
+
return Qnil;
|
|
565
|
+
}
|
|
566
|
+
|
|
567
|
+
|
|
568
|
+
static VALUE cur_disable(VALUE vself) {
|
|
569
|
+
VALUE vdb = rb_ivar_get(vself, id_cur_db);
|
|
570
|
+
if (vdb == Qnil) rb_raise(cls_ex_arg, "disabled cursor");
|
|
571
|
+
SoftCursor* cur;
|
|
572
|
+
Data_Get_Struct(vself, SoftCursor, cur);
|
|
573
|
+
db_lock(vdb);
|
|
574
|
+
delete cur->cur_;
|
|
575
|
+
cur->cur_ = NULL;
|
|
576
|
+
db_unlock(vdb);
|
|
577
|
+
rb_ivar_set(vself, id_cur_db, Qnil);
|
|
578
|
+
return Qnil;
|
|
579
|
+
}
|
|
580
|
+
|
|
581
|
+
|
|
582
|
+
static VALUE cur_accept(int argc, VALUE* argv, VALUE vself) {
|
|
583
|
+
VALUE vdb = rb_ivar_get(vself, id_cur_db);
|
|
584
|
+
if (vdb == Qnil) rb_raise(cls_ex_arg, "disabled cursor");
|
|
585
|
+
SoftCursor* cur;
|
|
586
|
+
Data_Get_Struct(vself, SoftCursor, cur);
|
|
587
|
+
VALUE vvisitor, vwritable, vstep;
|
|
588
|
+
rb_scan_args(argc, argv, "12", &vvisitor, &vwritable, &vstep);
|
|
589
|
+
SoftVisitor visitor(vvisitor);
|
|
590
|
+
bool writable = vwritable != Qfalse;
|
|
591
|
+
bool step = vstep != Qnil && vstep != Qfalse;
|
|
592
|
+
db_lock(vdb);
|
|
593
|
+
bool rv = cur->cur_->accept(&visitor, writable, step);
|
|
594
|
+
db_unlock(vdb);
|
|
595
|
+
return rv ? Qtrue : Qfalse;
|
|
596
|
+
}
|
|
597
|
+
|
|
598
|
+
|
|
599
|
+
static VALUE cur_get_key(VALUE vself) {
|
|
600
|
+
VALUE vdb = rb_ivar_get(vself, id_cur_db);
|
|
601
|
+
if (vdb == Qnil) rb_raise(cls_ex_arg, "disabled cursor");
|
|
602
|
+
SoftCursor* cur;
|
|
603
|
+
Data_Get_Struct(vself, SoftCursor, cur);
|
|
604
|
+
db_lock(vdb);
|
|
605
|
+
size_t ksiz;
|
|
606
|
+
char* kbuf = cur->cur_->get_key(&ksiz);
|
|
607
|
+
db_unlock(vdb);
|
|
608
|
+
VALUE vrv;
|
|
609
|
+
if (kbuf) {
|
|
610
|
+
vrv = rb_str_new(kbuf, ksiz);
|
|
611
|
+
delete[] kbuf;
|
|
612
|
+
} else {
|
|
613
|
+
vrv = Qnil;
|
|
614
|
+
}
|
|
615
|
+
return vrv;
|
|
616
|
+
}
|
|
617
|
+
|
|
618
|
+
|
|
619
|
+
static VALUE cur_get_value(VALUE vself) {
|
|
620
|
+
VALUE vdb = rb_ivar_get(vself, id_cur_db);
|
|
621
|
+
if (vdb == Qnil) rb_raise(cls_ex_arg, "disabled cursor");
|
|
622
|
+
SoftCursor* cur;
|
|
623
|
+
Data_Get_Struct(vself, SoftCursor, cur);
|
|
624
|
+
db_lock(vdb);
|
|
625
|
+
size_t vsiz;
|
|
626
|
+
char* vbuf = cur->cur_->get_value(&vsiz);
|
|
627
|
+
db_unlock(vdb);
|
|
628
|
+
VALUE vrv;
|
|
629
|
+
if (vbuf) {
|
|
630
|
+
vrv = rb_str_new(vbuf, vsiz);
|
|
631
|
+
delete[] vbuf;
|
|
632
|
+
} else {
|
|
633
|
+
vrv = Qnil;
|
|
634
|
+
}
|
|
635
|
+
return vrv;
|
|
636
|
+
}
|
|
637
|
+
|
|
638
|
+
|
|
639
|
+
static VALUE cur_get(VALUE vself) {
|
|
640
|
+
VALUE vdb = rb_ivar_get(vself, id_cur_db);
|
|
641
|
+
if (vdb == Qnil) rb_raise(cls_ex_arg, "disabled cursor");
|
|
642
|
+
SoftCursor* cur;
|
|
643
|
+
Data_Get_Struct(vself, SoftCursor, cur);
|
|
644
|
+
db_lock(vdb);
|
|
645
|
+
size_t ksiz, vsiz;
|
|
646
|
+
const char* vbuf;
|
|
647
|
+
char* kbuf = cur->cur_->get(&ksiz, &vbuf, &vsiz);
|
|
648
|
+
db_unlock(vdb);
|
|
649
|
+
VALUE vrv;
|
|
650
|
+
if (kbuf) {
|
|
651
|
+
VALUE vkey = rb_str_new(kbuf, ksiz);
|
|
652
|
+
VALUE vvalue = rb_str_new(vbuf, vsiz);
|
|
653
|
+
vrv = rb_ary_new3(2, vkey, vvalue);
|
|
654
|
+
delete[] kbuf;
|
|
655
|
+
} else {
|
|
656
|
+
vrv = Qnil;
|
|
657
|
+
}
|
|
658
|
+
return vrv;
|
|
659
|
+
}
|
|
660
|
+
|
|
661
|
+
|
|
662
|
+
static VALUE cur_remove(VALUE vself) {
|
|
663
|
+
VALUE vdb = rb_ivar_get(vself, id_cur_db);
|
|
664
|
+
if (vdb == Qnil) rb_raise(cls_ex_arg, "disabled cursor");
|
|
665
|
+
SoftCursor* cur;
|
|
666
|
+
Data_Get_Struct(vself, SoftCursor, cur);
|
|
667
|
+
db_lock(vdb);
|
|
668
|
+
bool rv = cur->cur_->remove();
|
|
669
|
+
db_unlock(vdb);
|
|
670
|
+
return rv ? Qtrue : Qfalse;
|
|
671
|
+
}
|
|
672
|
+
|
|
673
|
+
|
|
674
|
+
static VALUE cur_jump(int argc, VALUE* argv, VALUE vself) {
|
|
675
|
+
VALUE vdb = rb_ivar_get(vself, id_cur_db);
|
|
676
|
+
if (vdb == Qnil) rb_raise(cls_ex_arg, "disabled cursor");
|
|
677
|
+
SoftCursor* cur;
|
|
678
|
+
Data_Get_Struct(vself, SoftCursor, cur);
|
|
679
|
+
VALUE vkey;
|
|
680
|
+
rb_scan_args(argc, argv, "01", &vkey);
|
|
681
|
+
VALUE vrv;
|
|
682
|
+
if (vkey == Qnil) {
|
|
683
|
+
db_lock(vdb);
|
|
684
|
+
bool rv = cur->cur_->jump();
|
|
685
|
+
db_unlock(vdb);
|
|
686
|
+
vrv = rv ? Qtrue : Qfalse;
|
|
687
|
+
} else {
|
|
688
|
+
vkey = StringValueEx(vkey);
|
|
689
|
+
const char* kbuf = RSTRING_PTR(vkey);
|
|
690
|
+
size_t ksiz = RSTRING_LEN(vkey);
|
|
691
|
+
db_lock(vdb);
|
|
692
|
+
bool rv = cur->cur_->jump(kbuf, ksiz);
|
|
693
|
+
db_unlock(vdb);
|
|
694
|
+
vrv = rv ? Qtrue : Qfalse;
|
|
695
|
+
}
|
|
696
|
+
return vrv;
|
|
697
|
+
}
|
|
698
|
+
|
|
699
|
+
|
|
700
|
+
static VALUE cur_step(VALUE vself) {
|
|
701
|
+
VALUE vdb = rb_ivar_get(vself, id_cur_db);
|
|
702
|
+
if (vdb == Qnil) rb_raise(cls_ex_arg, "disabled cursor");
|
|
703
|
+
SoftCursor* cur;
|
|
704
|
+
Data_Get_Struct(vself, SoftCursor, cur);
|
|
705
|
+
db_lock(vdb);
|
|
706
|
+
bool rv = cur->cur_->step();
|
|
707
|
+
db_unlock(vdb);
|
|
708
|
+
return rv ? Qtrue : Qfalse;
|
|
709
|
+
}
|
|
710
|
+
|
|
711
|
+
|
|
712
|
+
static VALUE cur_db(VALUE vself) {
|
|
713
|
+
VALUE vdb = rb_ivar_get(vself, id_cur_db);
|
|
714
|
+
if (vdb == Qnil) rb_raise(cls_ex_arg, "disabled cursor");
|
|
715
|
+
return vdb;
|
|
716
|
+
}
|
|
717
|
+
|
|
718
|
+
|
|
719
|
+
static VALUE cur_error(VALUE vself) {
|
|
720
|
+
VALUE vdb = rb_ivar_get(vself, id_cur_db);
|
|
721
|
+
if (vdb == Qnil) rb_raise(cls_ex_arg, "disabled cursor");
|
|
722
|
+
SoftCursor* cur;
|
|
723
|
+
Data_Get_Struct(vself, SoftCursor, cur);
|
|
724
|
+
db_lock(vdb);
|
|
725
|
+
kc::PolyDB::Error err = cur->cur_->error();
|
|
726
|
+
db_unlock(vdb);
|
|
727
|
+
VALUE args[2];
|
|
728
|
+
args[0] = INT2FIX(err.code());
|
|
729
|
+
args[1] = rb_str_new2(err.message());
|
|
730
|
+
return rb_class_new_instance(2, args, cls_err);
|
|
731
|
+
}
|
|
732
|
+
|
|
733
|
+
|
|
734
|
+
static VALUE cur_to_s(VALUE vself) {
|
|
735
|
+
VALUE vdb = rb_ivar_get(vself, id_cur_db);
|
|
736
|
+
if (vdb == Qnil) rb_raise(cls_ex_arg, "disabled cursor");
|
|
737
|
+
SoftCursor* cur;
|
|
738
|
+
Data_Get_Struct(vself, SoftCursor, cur);
|
|
739
|
+
db_lock(vdb);
|
|
740
|
+
kc::PolyDB* db = cur->cur_->db();
|
|
741
|
+
std::string path = db->path();
|
|
742
|
+
std::string str;
|
|
743
|
+
kc::strprintf(&str, "#<KyotoCabinet::Cursor:%p: %s", cur, path.c_str());
|
|
744
|
+
size_t ksiz;
|
|
745
|
+
char* kbuf = cur->cur_->get_key(&ksiz);
|
|
746
|
+
if (kbuf) {
|
|
747
|
+
kc::strprintf(&str, ":");
|
|
748
|
+
str.append(kbuf, ksiz);
|
|
749
|
+
delete[] kbuf;
|
|
750
|
+
}
|
|
751
|
+
kc::strprintf(&str, ">");
|
|
752
|
+
db_unlock(vdb);
|
|
753
|
+
return rb_str_new2(str.c_str());
|
|
754
|
+
}
|
|
755
|
+
|
|
756
|
+
|
|
757
|
+
static void init_db() {
|
|
758
|
+
cls_db = rb_define_class_under(mod_kc, "DB", rb_cObject);
|
|
759
|
+
rb_define_alloc_func(cls_db, db_new);
|
|
760
|
+
rb_define_const(cls_db, "OREADER", INT2FIX(kc::PolyDB::OREADER));
|
|
761
|
+
rb_define_const(cls_db, "OWRITER", INT2FIX(kc::PolyDB::OWRITER));
|
|
762
|
+
rb_define_const(cls_db, "OCREATE", INT2FIX(kc::PolyDB::OCREATE));
|
|
763
|
+
rb_define_const(cls_db, "OTRUNCATE", INT2FIX(kc::PolyDB::OTRUNCATE));
|
|
764
|
+
rb_define_const(cls_db, "OAUTOTRAN", INT2FIX(kc::PolyDB::OAUTOTRAN));
|
|
765
|
+
rb_define_const(cls_db, "OAUTOSYNC", INT2FIX(kc::PolyDB::OAUTOSYNC));
|
|
766
|
+
rb_define_const(cls_db, "ONOLOCK", INT2FIX(kc::PolyDB::ONOLOCK));
|
|
767
|
+
rb_define_const(cls_db, "OTRYLOCK", INT2FIX(kc::PolyDB::OTRYLOCK));
|
|
768
|
+
rb_define_const(cls_db, "ONOREPAIR", INT2FIX(kc::PolyDB::ONOREPAIR));
|
|
769
|
+
rb_define_private_method(cls_db, "initialize", (METHOD)db_initialize, 0);
|
|
770
|
+
rb_define_method(cls_db, "error", (METHOD)db_error, 0);
|
|
771
|
+
rb_define_method(cls_db, "open", (METHOD)db_open, -1);
|
|
772
|
+
rb_define_method(cls_db, "close", (METHOD)db_close, 0);
|
|
773
|
+
rb_define_method(cls_db, "accept", (METHOD)db_accept, -1);
|
|
774
|
+
rb_define_method(cls_db, "iterate", (METHOD)db_iterate, -1);
|
|
775
|
+
rb_define_method(cls_db, "set", (METHOD)db_set, 2);
|
|
776
|
+
rb_define_method(cls_db, "add", (METHOD)db_add, 2);
|
|
777
|
+
rb_define_method(cls_db, "append", (METHOD)db_append, 2);
|
|
778
|
+
rb_define_method(cls_db, "increment", (METHOD)db_increment, -1);
|
|
779
|
+
rb_define_method(cls_db, "cas", (METHOD)db_cas, 3);
|
|
780
|
+
rb_define_method(cls_db, "remove", (METHOD)db_remove, 1);
|
|
781
|
+
rb_define_method(cls_db, "get", (METHOD)db_get, 1);
|
|
782
|
+
rb_define_method(cls_db, "clear", (METHOD)db_clear, 0);
|
|
783
|
+
rb_define_method(cls_db, "synchronize", (METHOD)db_synchronize, -1);
|
|
784
|
+
rb_define_method(cls_db, "begin_transaction", (METHOD)db_begin_transaction, -1);
|
|
785
|
+
rb_define_method(cls_db, "end_transaction", (METHOD)db_end_transaction, -1);
|
|
786
|
+
rb_define_method(cls_db, "count", (METHOD)db_count, 0);
|
|
787
|
+
rb_define_method(cls_db, "size", (METHOD)db_size, 0);
|
|
788
|
+
rb_define_method(cls_db, "path", (METHOD)db_path, 0);
|
|
789
|
+
rb_define_method(cls_db, "status", (METHOD)db_status, 0);
|
|
790
|
+
rb_define_method(cls_db, "cursor", (METHOD)db_cursor, 0);
|
|
791
|
+
rb_define_method(cls_db, "to_s", (METHOD)db_to_s, 0);
|
|
792
|
+
rb_define_method(cls_db, "[]", (METHOD)db_get, 1);
|
|
793
|
+
rb_define_method(cls_db, "[]=", (METHOD)db_set, 2);
|
|
794
|
+
rb_define_method(cls_db, "store", (METHOD)db_set, 2);
|
|
795
|
+
rb_define_method(cls_db, "delete", (METHOD)db_set, 1);
|
|
796
|
+
rb_define_method(cls_db, "fetch", (METHOD)db_set, 1);
|
|
797
|
+
rb_define_method(cls_db, "length", (METHOD)db_count, 0);
|
|
798
|
+
rb_define_method(cls_db, "each", (METHOD)db_each, 0);
|
|
799
|
+
rb_define_method(cls_db, "each_pair", (METHOD)db_each, 0);
|
|
800
|
+
rb_define_method(cls_db, "each_key", (METHOD)db_each_key, 0);
|
|
801
|
+
rb_define_method(cls_db, "each_value", (METHOD)db_each_value, 0);
|
|
802
|
+
id_db_error = rb_intern("error");
|
|
803
|
+
id_db_open = rb_intern("open");
|
|
804
|
+
id_db_close = rb_intern("close");
|
|
805
|
+
id_db_mutex = rb_intern("@mutex_");
|
|
806
|
+
rb_define_singleton_method(cls_db, "process", (METHOD)db_process, -1);
|
|
807
|
+
}
|
|
808
|
+
|
|
809
|
+
|
|
810
|
+
static VALUE db_new(VALUE cls) {
|
|
811
|
+
kc::PolyDB* db = new kc::PolyDB();
|
|
812
|
+
return Data_Wrap_Struct(cls_db, 0, db_del, db);
|
|
813
|
+
}
|
|
814
|
+
|
|
815
|
+
|
|
816
|
+
static void db_del(void* ptr) {
|
|
817
|
+
g_curbur.sweap();
|
|
818
|
+
delete (kc::PolyDB*)ptr;
|
|
819
|
+
}
|
|
820
|
+
|
|
821
|
+
|
|
822
|
+
static void db_lock(VALUE vdb) {
|
|
823
|
+
VALUE vmutex = rb_ivar_get(vdb, id_db_mutex);
|
|
824
|
+
rb_funcall(vmutex, id_mtx_lock, 0);
|
|
825
|
+
}
|
|
826
|
+
|
|
827
|
+
|
|
828
|
+
static void db_unlock(VALUE vdb) {
|
|
829
|
+
VALUE vmutex = rb_ivar_get(vdb, id_db_mutex);
|
|
830
|
+
rb_funcall(vmutex, id_mtx_unlock, 0);
|
|
831
|
+
}
|
|
832
|
+
|
|
833
|
+
|
|
834
|
+
static VALUE db_initialize(VALUE vself) {
|
|
835
|
+
VALUE vmutex = rb_class_new_instance(0, NULL, cls_mtx);
|
|
836
|
+
rb_ivar_set(vself, id_db_mutex, vmutex);
|
|
837
|
+
return Qnil;
|
|
838
|
+
}
|
|
839
|
+
|
|
840
|
+
|
|
841
|
+
static VALUE db_error(VALUE vself) {
|
|
842
|
+
kc::PolyDB* db;
|
|
843
|
+
Data_Get_Struct(vself, kc::PolyDB, db);
|
|
844
|
+
db_lock(vself);
|
|
845
|
+
kc::PolyDB::Error err = db->error();
|
|
846
|
+
db_unlock(vself);
|
|
847
|
+
VALUE args[2];
|
|
848
|
+
args[0] = INT2FIX(err.code());
|
|
849
|
+
args[1] = rb_str_new2(err.message());
|
|
850
|
+
return rb_class_new_instance(2, args, cls_err);
|
|
851
|
+
}
|
|
852
|
+
|
|
853
|
+
|
|
854
|
+
static VALUE db_open(int argc, VALUE* argv, VALUE vself) {
|
|
855
|
+
kc::PolyDB* db;
|
|
856
|
+
Data_Get_Struct(vself, kc::PolyDB, db);
|
|
857
|
+
VALUE vpath, vmode;
|
|
858
|
+
rb_scan_args(argc, argv, "02", &vpath, &vmode);
|
|
859
|
+
if (vpath == Qnil) vpath = rb_str_new2("*");
|
|
860
|
+
vpath = StringValueEx(vpath);
|
|
861
|
+
const char* path = RSTRING_PTR(vpath);
|
|
862
|
+
uint32_t mode = vmode == Qnil ? kc::PolyDB::OREADER : NUM2INT(vmode);
|
|
863
|
+
db_lock(vself);
|
|
864
|
+
bool rv = db->open(path, mode);
|
|
865
|
+
db_unlock(vself);
|
|
866
|
+
return rv ? Qtrue : Qfalse;
|
|
867
|
+
}
|
|
868
|
+
|
|
869
|
+
|
|
870
|
+
static VALUE db_close(VALUE vself) {
|
|
871
|
+
kc::PolyDB* db;
|
|
872
|
+
Data_Get_Struct(vself, kc::PolyDB, db);
|
|
873
|
+
db_lock(vself);
|
|
874
|
+
bool rv = db->close();
|
|
875
|
+
db_unlock(vself);
|
|
876
|
+
return rv ? Qtrue : Qfalse;
|
|
877
|
+
}
|
|
878
|
+
|
|
879
|
+
|
|
880
|
+
static VALUE db_accept(int argc, VALUE* argv, VALUE vself) {
|
|
881
|
+
kc::PolyDB* db;
|
|
882
|
+
Data_Get_Struct(vself, kc::PolyDB, db);
|
|
883
|
+
VALUE vkey, vvisitor, vwritable;
|
|
884
|
+
rb_scan_args(argc, argv, "21", &vkey, &vvisitor, &vwritable);
|
|
885
|
+
vkey = StringValueEx(vkey);
|
|
886
|
+
const char* kbuf = RSTRING_PTR(vkey);
|
|
887
|
+
size_t ksiz = RSTRING_LEN(vkey);
|
|
888
|
+
SoftVisitor visitor(vvisitor);
|
|
889
|
+
bool writable = vwritable != Qfalse;
|
|
890
|
+
db_lock(vself);
|
|
891
|
+
bool rv = db->accept(kbuf, ksiz, &visitor, writable);
|
|
892
|
+
db_unlock(vself);
|
|
893
|
+
return rv ? Qtrue : Qfalse;
|
|
894
|
+
}
|
|
895
|
+
|
|
896
|
+
|
|
897
|
+
static VALUE db_iterate(int argc, VALUE* argv, VALUE vself) {
|
|
898
|
+
kc::PolyDB* db;
|
|
899
|
+
Data_Get_Struct(vself, kc::PolyDB, db);
|
|
900
|
+
VALUE vvisitor, vwritable;
|
|
901
|
+
rb_scan_args(argc, argv, "11", &vvisitor, &vwritable);
|
|
902
|
+
SoftVisitor visitor(vvisitor);
|
|
903
|
+
bool writable = vwritable != Qfalse;
|
|
904
|
+
db_lock(vself);
|
|
905
|
+
bool rv = db->iterate(&visitor, writable);
|
|
906
|
+
db_unlock(vself);
|
|
907
|
+
return rv ? Qtrue : Qfalse;
|
|
908
|
+
}
|
|
909
|
+
|
|
910
|
+
|
|
911
|
+
static VALUE db_set(VALUE vself, VALUE vkey, VALUE vvalue) {
|
|
912
|
+
kc::PolyDB* db;
|
|
913
|
+
Data_Get_Struct(vself, kc::PolyDB, db);
|
|
914
|
+
vkey = StringValueEx(vkey);
|
|
915
|
+
const char* kbuf = RSTRING_PTR(vkey);
|
|
916
|
+
size_t ksiz = RSTRING_LEN(vkey);
|
|
917
|
+
vvalue = StringValueEx(vvalue);
|
|
918
|
+
const char* vbuf = RSTRING_PTR(vvalue);
|
|
919
|
+
size_t vsiz = RSTRING_LEN(vvalue);
|
|
920
|
+
db_lock(vself);
|
|
921
|
+
bool rv = db->set(kbuf, ksiz, vbuf, vsiz);
|
|
922
|
+
db_unlock(vself);
|
|
923
|
+
return rv ? Qtrue : Qfalse;
|
|
924
|
+
}
|
|
925
|
+
|
|
926
|
+
|
|
927
|
+
static VALUE db_add(VALUE vself, VALUE vkey, VALUE vvalue) {
|
|
928
|
+
kc::PolyDB* db;
|
|
929
|
+
Data_Get_Struct(vself, kc::PolyDB, db);
|
|
930
|
+
vkey = StringValueEx(vkey);
|
|
931
|
+
const char* kbuf = RSTRING_PTR(vkey);
|
|
932
|
+
size_t ksiz = RSTRING_LEN(vkey);
|
|
933
|
+
vvalue = StringValueEx(vvalue);
|
|
934
|
+
const char* vbuf = RSTRING_PTR(vvalue);
|
|
935
|
+
size_t vsiz = RSTRING_LEN(vvalue);
|
|
936
|
+
db_lock(vself);
|
|
937
|
+
bool rv = db->add(kbuf, ksiz, vbuf, vsiz);
|
|
938
|
+
db_unlock(vself);
|
|
939
|
+
return rv ? Qtrue : Qfalse;
|
|
940
|
+
}
|
|
941
|
+
|
|
942
|
+
|
|
943
|
+
static VALUE db_append(VALUE vself, VALUE vkey, VALUE vvalue) {
|
|
944
|
+
kc::PolyDB* db;
|
|
945
|
+
Data_Get_Struct(vself, kc::PolyDB, db);
|
|
946
|
+
vkey = StringValueEx(vkey);
|
|
947
|
+
const char* kbuf = RSTRING_PTR(vkey);
|
|
948
|
+
size_t ksiz = RSTRING_LEN(vkey);
|
|
949
|
+
vvalue = StringValueEx(vvalue);
|
|
950
|
+
const char* vbuf = RSTRING_PTR(vvalue);
|
|
951
|
+
size_t vsiz = RSTRING_LEN(vvalue);
|
|
952
|
+
db_lock(vself);
|
|
953
|
+
bool rv = db->append(kbuf, ksiz, vbuf, vsiz);
|
|
954
|
+
db_unlock(vself);
|
|
955
|
+
return rv ? Qtrue : Qfalse;
|
|
956
|
+
}
|
|
957
|
+
|
|
958
|
+
|
|
959
|
+
static VALUE db_increment(int argc, VALUE* argv, VALUE vself) {
|
|
960
|
+
kc::PolyDB* db;
|
|
961
|
+
Data_Get_Struct(vself, kc::PolyDB, db);
|
|
962
|
+
VALUE vkey, vnum;
|
|
963
|
+
rb_scan_args(argc, argv, "11", &vkey, &vnum);
|
|
964
|
+
vkey = StringValueEx(vkey);
|
|
965
|
+
const char* kbuf = RSTRING_PTR(vkey);
|
|
966
|
+
size_t ksiz = RSTRING_LEN(vkey);
|
|
967
|
+
bool dmode = false;
|
|
968
|
+
int64_t inum = 0;
|
|
969
|
+
double dnum = NAN;
|
|
970
|
+
switch (TYPE(vnum)) {
|
|
971
|
+
case T_FIXNUM: {
|
|
972
|
+
inum = FIX2INT(vnum);
|
|
973
|
+
break;
|
|
974
|
+
}
|
|
975
|
+
case T_BIGNUM: {
|
|
976
|
+
inum = NUM2LL(vnum);
|
|
977
|
+
break;
|
|
978
|
+
}
|
|
979
|
+
case T_FLOAT: {
|
|
980
|
+
dnum = NUM2DBL(vnum);
|
|
981
|
+
dmode = true;
|
|
982
|
+
break;
|
|
983
|
+
}
|
|
984
|
+
case T_TRUE: {
|
|
985
|
+
inum = 1;
|
|
986
|
+
break;
|
|
987
|
+
}
|
|
988
|
+
case T_STRING: {
|
|
989
|
+
const char* str = RSTRING_PTR(vnum);
|
|
990
|
+
if (std::strchr(str, '.')) {
|
|
991
|
+
dnum = kc::atof(str);
|
|
992
|
+
dmode = true;
|
|
993
|
+
} else {
|
|
994
|
+
inum = kc::atoi(str);
|
|
995
|
+
}
|
|
996
|
+
break;
|
|
997
|
+
}
|
|
998
|
+
}
|
|
999
|
+
VALUE vrv;
|
|
1000
|
+
if (dmode) {
|
|
1001
|
+
db_lock(vself);
|
|
1002
|
+
double num = db->increment(kbuf, ksiz, dnum);
|
|
1003
|
+
db_unlock(vself);
|
|
1004
|
+
vrv = num == num ? rb_float_new(num) : Qnil;
|
|
1005
|
+
} else {
|
|
1006
|
+
db_lock(vself);
|
|
1007
|
+
int64_t num = db->increment(kbuf, ksiz, inum);
|
|
1008
|
+
db_unlock(vself);
|
|
1009
|
+
vrv = num == INT64_MIN ? Qnil : LL2NUM(num);
|
|
1010
|
+
}
|
|
1011
|
+
return vrv;
|
|
1012
|
+
}
|
|
1013
|
+
|
|
1014
|
+
|
|
1015
|
+
static VALUE db_cas(VALUE vself, VALUE vkey, VALUE voval, VALUE vnval) {
|
|
1016
|
+
kc::PolyDB* db;
|
|
1017
|
+
Data_Get_Struct(vself, kc::PolyDB, db);
|
|
1018
|
+
vkey = StringValueEx(vkey);
|
|
1019
|
+
const char* kbuf = RSTRING_PTR(vkey);
|
|
1020
|
+
size_t ksiz = RSTRING_LEN(vkey);
|
|
1021
|
+
const char* ovbuf = NULL;
|
|
1022
|
+
size_t ovsiz = 0;
|
|
1023
|
+
if (voval != Qnil) {
|
|
1024
|
+
voval = StringValueEx(voval);
|
|
1025
|
+
ovbuf = RSTRING_PTR(voval);
|
|
1026
|
+
ovsiz = RSTRING_LEN(voval);
|
|
1027
|
+
}
|
|
1028
|
+
const char* nvbuf = NULL;
|
|
1029
|
+
size_t nvsiz = 0;
|
|
1030
|
+
if (vnval != Qnil) {
|
|
1031
|
+
vnval = StringValueEx(vnval);
|
|
1032
|
+
nvbuf = RSTRING_PTR(vnval);
|
|
1033
|
+
nvsiz = RSTRING_LEN(vnval);
|
|
1034
|
+
}
|
|
1035
|
+
db_lock(vself);
|
|
1036
|
+
bool rv = db->cas(kbuf, ksiz, ovbuf, ovsiz, nvbuf, nvsiz);
|
|
1037
|
+
db_unlock(vself);
|
|
1038
|
+
return rv ? Qtrue : Qfalse;
|
|
1039
|
+
}
|
|
1040
|
+
|
|
1041
|
+
|
|
1042
|
+
static VALUE db_remove(VALUE vself, VALUE vkey) {
|
|
1043
|
+
kc::PolyDB* db;
|
|
1044
|
+
Data_Get_Struct(vself, kc::PolyDB, db);
|
|
1045
|
+
vkey = StringValueEx(vkey);
|
|
1046
|
+
const char* kbuf = RSTRING_PTR(vkey);
|
|
1047
|
+
size_t ksiz = RSTRING_LEN(vkey);
|
|
1048
|
+
db_lock(vself);
|
|
1049
|
+
bool rv = db->remove(kbuf, ksiz);
|
|
1050
|
+
db_unlock(vself);
|
|
1051
|
+
return rv ? Qtrue : Qfalse;
|
|
1052
|
+
}
|
|
1053
|
+
|
|
1054
|
+
|
|
1055
|
+
static VALUE db_get(VALUE vself, VALUE vkey) {
|
|
1056
|
+
kc::PolyDB* db;
|
|
1057
|
+
Data_Get_Struct(vself, kc::PolyDB, db);
|
|
1058
|
+
vkey = StringValueEx(vkey);
|
|
1059
|
+
const char* kbuf = RSTRING_PTR(vkey);
|
|
1060
|
+
size_t ksiz = RSTRING_LEN(vkey);
|
|
1061
|
+
db_lock(vself);
|
|
1062
|
+
size_t vsiz;
|
|
1063
|
+
char* vbuf = db->get(kbuf, ksiz, &vsiz);
|
|
1064
|
+
db_unlock(vself);
|
|
1065
|
+
VALUE vrv;
|
|
1066
|
+
if (vbuf) {
|
|
1067
|
+
vrv = rb_str_new(vbuf, vsiz);
|
|
1068
|
+
delete[] vbuf;
|
|
1069
|
+
} else {
|
|
1070
|
+
vrv = Qnil;
|
|
1071
|
+
}
|
|
1072
|
+
return vrv;
|
|
1073
|
+
}
|
|
1074
|
+
|
|
1075
|
+
|
|
1076
|
+
static VALUE db_clear(VALUE vself) {
|
|
1077
|
+
kc::PolyDB* db;
|
|
1078
|
+
Data_Get_Struct(vself, kc::PolyDB, db);
|
|
1079
|
+
db_lock(vself);
|
|
1080
|
+
bool rv = db->clear();
|
|
1081
|
+
db_unlock(vself);
|
|
1082
|
+
return rv ? Qtrue : Qfalse;
|
|
1083
|
+
}
|
|
1084
|
+
|
|
1085
|
+
|
|
1086
|
+
static VALUE db_synchronize(int argc, VALUE* argv, VALUE vself) {
|
|
1087
|
+
kc::PolyDB* db;
|
|
1088
|
+
Data_Get_Struct(vself, kc::PolyDB, db);
|
|
1089
|
+
VALUE vhard, vproc;
|
|
1090
|
+
rb_scan_args(argc, argv, "02", &vhard, &vproc);
|
|
1091
|
+
bool hard = vhard != Qnil && vhard != Qfalse;
|
|
1092
|
+
VALUE vrv;
|
|
1093
|
+
if (rb_respond_to(vproc, id_fproc_process)) {
|
|
1094
|
+
SoftFileProcessor proc(vproc);
|
|
1095
|
+
db_lock(vself);
|
|
1096
|
+
bool rv = db->synchronize(hard, &proc);
|
|
1097
|
+
db_unlock(vself);
|
|
1098
|
+
vrv = rv ? Qtrue : Qfalse;
|
|
1099
|
+
} else {
|
|
1100
|
+
db_lock(vself);
|
|
1101
|
+
bool rv = db->synchronize(hard, NULL);
|
|
1102
|
+
db_unlock(vself);
|
|
1103
|
+
vrv = rv ? Qtrue : Qfalse;
|
|
1104
|
+
}
|
|
1105
|
+
return vrv;
|
|
1106
|
+
}
|
|
1107
|
+
|
|
1108
|
+
|
|
1109
|
+
static VALUE db_begin_transaction(int argc, VALUE* argv, VALUE vself) {
|
|
1110
|
+
kc::PolyDB* db;
|
|
1111
|
+
Data_Get_Struct(vself, kc::PolyDB, db);
|
|
1112
|
+
VALUE vhard;
|
|
1113
|
+
rb_scan_args(argc, argv, "01", &vhard);
|
|
1114
|
+
bool hard = vhard != Qnil && vhard != Qfalse;
|
|
1115
|
+
bool err = false;
|
|
1116
|
+
while (true) {
|
|
1117
|
+
db_lock(vself);
|
|
1118
|
+
bool rv = db->begin_transaction_try(hard);
|
|
1119
|
+
db_unlock(vself);
|
|
1120
|
+
if (rv) break;
|
|
1121
|
+
if (db->error() != kc::PolyDB::Error::LOGIC) {
|
|
1122
|
+
err = true;
|
|
1123
|
+
break;
|
|
1124
|
+
}
|
|
1125
|
+
th_pass();
|
|
1126
|
+
}
|
|
1127
|
+
return err ? Qfalse : Qtrue;
|
|
1128
|
+
}
|
|
1129
|
+
|
|
1130
|
+
|
|
1131
|
+
static VALUE db_end_transaction(int argc, VALUE* argv, VALUE vself) {
|
|
1132
|
+
kc::PolyDB* db;
|
|
1133
|
+
Data_Get_Struct(vself, kc::PolyDB, db);
|
|
1134
|
+
VALUE vcommit;
|
|
1135
|
+
rb_scan_args(argc, argv, "01", &vcommit);
|
|
1136
|
+
bool commit = vcommit != Qfalse;
|
|
1137
|
+
db_lock(vself);
|
|
1138
|
+
bool rv = db->end_transaction(commit);
|
|
1139
|
+
db_unlock(vself);
|
|
1140
|
+
return rv ? Qtrue : Qfalse;
|
|
1141
|
+
}
|
|
1142
|
+
|
|
1143
|
+
|
|
1144
|
+
static VALUE db_count(VALUE vself) {
|
|
1145
|
+
kc::PolyDB* db;
|
|
1146
|
+
Data_Get_Struct(vself, kc::PolyDB, db);
|
|
1147
|
+
db_lock(vself);
|
|
1148
|
+
int64_t count = db->count();
|
|
1149
|
+
db_unlock(vself);
|
|
1150
|
+
return LL2NUM(count);
|
|
1151
|
+
}
|
|
1152
|
+
|
|
1153
|
+
|
|
1154
|
+
static VALUE db_size(VALUE vself) {
|
|
1155
|
+
kc::PolyDB* db;
|
|
1156
|
+
Data_Get_Struct(vself, kc::PolyDB, db);
|
|
1157
|
+
db_lock(vself);
|
|
1158
|
+
int64_t size = db->size();
|
|
1159
|
+
db_unlock(vself);
|
|
1160
|
+
return LL2NUM(size);
|
|
1161
|
+
}
|
|
1162
|
+
|
|
1163
|
+
|
|
1164
|
+
static VALUE db_path(VALUE vself) {
|
|
1165
|
+
kc::PolyDB* db;
|
|
1166
|
+
Data_Get_Struct(vself, kc::PolyDB, db);
|
|
1167
|
+
db_lock(vself);
|
|
1168
|
+
std::string path = db->path();
|
|
1169
|
+
db_unlock(vself);
|
|
1170
|
+
if (path.size() < 1) return Qnil;
|
|
1171
|
+
return rb_str_new2(path.c_str());
|
|
1172
|
+
}
|
|
1173
|
+
|
|
1174
|
+
|
|
1175
|
+
static VALUE db_status(VALUE vself) {
|
|
1176
|
+
kc::PolyDB* db;
|
|
1177
|
+
Data_Get_Struct(vself, kc::PolyDB, db);
|
|
1178
|
+
StringMap status;
|
|
1179
|
+
db_lock(vself);
|
|
1180
|
+
bool rv = db->status(&status);
|
|
1181
|
+
db_unlock(vself);
|
|
1182
|
+
return rv ? maptovhash(&status) : Qnil;
|
|
1183
|
+
}
|
|
1184
|
+
|
|
1185
|
+
|
|
1186
|
+
static VALUE db_cursor(VALUE vself) {
|
|
1187
|
+
return rb_class_new_instance(1, &vself, cls_cur);
|
|
1188
|
+
}
|
|
1189
|
+
|
|
1190
|
+
|
|
1191
|
+
static VALUE db_to_s(VALUE vself) {
|
|
1192
|
+
kc::PolyDB* db;
|
|
1193
|
+
Data_Get_Struct(vself, kc::PolyDB, db);
|
|
1194
|
+
db_lock(vself);
|
|
1195
|
+
std::string path = db->path();
|
|
1196
|
+
std::string str;
|
|
1197
|
+
kc::strprintf(&str, "#<KyotoCabinet::DB:%p: %s: %lld: %lld>",
|
|
1198
|
+
db, path.c_str(), (long long)db->count(), (long long)db->size());
|
|
1199
|
+
db_unlock(vself);
|
|
1200
|
+
return rb_str_new2(str.c_str());
|
|
1201
|
+
}
|
|
1202
|
+
|
|
1203
|
+
|
|
1204
|
+
static VALUE db_each(VALUE vself) {
|
|
1205
|
+
kc::PolyDB* db;
|
|
1206
|
+
Data_Get_Struct(vself, kc::PolyDB, db);
|
|
1207
|
+
SoftEachVisitor visitor;
|
|
1208
|
+
db_lock(vself);
|
|
1209
|
+
bool rv = db->iterate(&visitor, false);
|
|
1210
|
+
db_unlock(vself);
|
|
1211
|
+
return rv ? Qtrue : Qfalse;
|
|
1212
|
+
}
|
|
1213
|
+
|
|
1214
|
+
|
|
1215
|
+
static VALUE db_each_key(VALUE vself) {
|
|
1216
|
+
kc::PolyDB* db;
|
|
1217
|
+
Data_Get_Struct(vself, kc::PolyDB, db);
|
|
1218
|
+
SoftEachKeyVisitor visitor;
|
|
1219
|
+
db_lock(vself);
|
|
1220
|
+
bool rv = db->iterate(&visitor, false);
|
|
1221
|
+
db_unlock(vself);
|
|
1222
|
+
return rv ? Qtrue : Qfalse;
|
|
1223
|
+
}
|
|
1224
|
+
|
|
1225
|
+
|
|
1226
|
+
static VALUE db_each_value(VALUE vself) {
|
|
1227
|
+
kc::PolyDB* db;
|
|
1228
|
+
Data_Get_Struct(vself, kc::PolyDB, db);
|
|
1229
|
+
SoftEachValueVisitor visitor;
|
|
1230
|
+
db_lock(vself);
|
|
1231
|
+
bool rv = db->iterate(&visitor, false);
|
|
1232
|
+
db_unlock(vself);
|
|
1233
|
+
return rv ? Qtrue : Qfalse;
|
|
1234
|
+
}
|
|
1235
|
+
|
|
1236
|
+
|
|
1237
|
+
static VALUE db_process(int argc, VALUE* argv, VALUE vself) {
|
|
1238
|
+
VALUE vdb = rb_class_new_instance(0, NULL, cls_db);
|
|
1239
|
+
VALUE vpath, vmode;
|
|
1240
|
+
rb_scan_args(argc, argv, "02", &vpath, &vmode);
|
|
1241
|
+
VALUE vrv = rb_funcall(vdb, id_db_open, 2, vpath, vmode);
|
|
1242
|
+
if (vrv == Qnil || vrv == Qfalse) return rb_funcall(vdb, id_db_error, 0);
|
|
1243
|
+
VALUE bargs = rb_ary_new3(1, vdb);
|
|
1244
|
+
VALUE eargs = rb_ary_new3(1, vdb);
|
|
1245
|
+
return rb_ensure((METHOD)db_process_body, bargs, (METHOD)db_process_ensure, eargs);
|
|
1246
|
+
}
|
|
1247
|
+
|
|
1248
|
+
|
|
1249
|
+
static VALUE db_process_body(VALUE args) {
|
|
1250
|
+
VALUE vdb = rb_ary_shift(args);
|
|
1251
|
+
rb_yield(vdb);
|
|
1252
|
+
return Qnil;
|
|
1253
|
+
}
|
|
1254
|
+
|
|
1255
|
+
|
|
1256
|
+
static VALUE db_process_ensure(VALUE args) {
|
|
1257
|
+
VALUE vdb = rb_ary_shift(args);
|
|
1258
|
+
rb_funcall(vdb, id_db_close, 0);
|
|
1259
|
+
return Qnil;
|
|
1260
|
+
}
|
|
1261
|
+
|
|
1262
|
+
|
|
1263
|
+
}
|
|
1264
|
+
|
|
1265
|
+
|
|
1266
|
+
// END OF FILE
|
metadata
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: kyotocabinet
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
hash: 15
|
|
5
|
+
prerelease: false
|
|
6
|
+
segments:
|
|
7
|
+
- 1
|
|
8
|
+
- 0
|
|
9
|
+
version: "1.0"
|
|
10
|
+
platform: ruby
|
|
11
|
+
authors:
|
|
12
|
+
- Mikio Hirabayashi
|
|
13
|
+
autorequire:
|
|
14
|
+
bindir: bin
|
|
15
|
+
cert_chain: []
|
|
16
|
+
|
|
17
|
+
date: 2010-06-02 00:00:00 -03:00
|
|
18
|
+
default_executable:
|
|
19
|
+
dependencies: []
|
|
20
|
+
|
|
21
|
+
description: Kyoto Cabinet is a library of routines for managing a database. The database is a simple data file containing records, each is a pair of a key and a value. Every key and value is serial bytes with variable length. Both binary data and character string can be used as a key and a value. Each key must be unique within a database. There is neither concept of data tables nor data types. Records are organized in hash table or B+ tree.
|
|
22
|
+
email: hirarin@gmail.com
|
|
23
|
+
executables: []
|
|
24
|
+
|
|
25
|
+
extensions:
|
|
26
|
+
- extconf.rb
|
|
27
|
+
extra_rdoc_files: []
|
|
28
|
+
|
|
29
|
+
files:
|
|
30
|
+
- kyotocabinet.cc
|
|
31
|
+
- extconf.rb
|
|
32
|
+
has_rdoc: true
|
|
33
|
+
homepage: http://1978th.net/kyotocabinet/
|
|
34
|
+
licenses: []
|
|
35
|
+
|
|
36
|
+
post_install_message:
|
|
37
|
+
rdoc_options: []
|
|
38
|
+
|
|
39
|
+
require_paths:
|
|
40
|
+
- .
|
|
41
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
42
|
+
none: false
|
|
43
|
+
requirements:
|
|
44
|
+
- - ">="
|
|
45
|
+
- !ruby/object:Gem::Version
|
|
46
|
+
hash: 3
|
|
47
|
+
segments:
|
|
48
|
+
- 0
|
|
49
|
+
version: "0"
|
|
50
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
51
|
+
none: false
|
|
52
|
+
requirements:
|
|
53
|
+
- - ">="
|
|
54
|
+
- !ruby/object:Gem::Version
|
|
55
|
+
hash: 3
|
|
56
|
+
segments:
|
|
57
|
+
- 0
|
|
58
|
+
version: "0"
|
|
59
|
+
requirements: []
|
|
60
|
+
|
|
61
|
+
rubyforge_project:
|
|
62
|
+
rubygems_version: 1.3.7
|
|
63
|
+
signing_key:
|
|
64
|
+
specification_version: 3
|
|
65
|
+
summary: "Kyoto Cabinet: a straightforward implementation of DBM."
|
|
66
|
+
test_files: []
|
|
67
|
+
|