sdbm 0.0.1
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.
- checksums.yaml +7 -0
- data/ext/sdbm/_sdbm.c +952 -0
- data/ext/sdbm/depend +25 -0
- data/ext/sdbm/extconf.rb +5 -0
- data/ext/sdbm/init.c +1067 -0
- data/ext/sdbm/sdbm.h +86 -0
- metadata +78 -0
data/ext/sdbm/depend
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
# AUTOGENERATED DEPENDENCIES START
|
2
|
+
_sdbm.o: $(RUBY_EXTCONF_H)
|
3
|
+
_sdbm.o: $(arch_hdrdir)/ruby/config.h
|
4
|
+
_sdbm.o: $(hdrdir)/ruby/backward.h
|
5
|
+
_sdbm.o: $(hdrdir)/ruby/defines.h
|
6
|
+
_sdbm.o: $(hdrdir)/ruby/intern.h
|
7
|
+
_sdbm.o: $(hdrdir)/ruby/missing.h
|
8
|
+
_sdbm.o: $(hdrdir)/ruby/ruby.h
|
9
|
+
_sdbm.o: $(hdrdir)/ruby/st.h
|
10
|
+
_sdbm.o: $(hdrdir)/ruby/subst.h
|
11
|
+
_sdbm.o: _sdbm.c
|
12
|
+
_sdbm.o: sdbm.h
|
13
|
+
init.o: $(RUBY_EXTCONF_H)
|
14
|
+
init.o: $(arch_hdrdir)/ruby/config.h
|
15
|
+
init.o: $(hdrdir)/ruby/backward.h
|
16
|
+
init.o: $(hdrdir)/ruby/defines.h
|
17
|
+
init.o: $(hdrdir)/ruby/intern.h
|
18
|
+
init.o: $(hdrdir)/ruby/missing.h
|
19
|
+
init.o: $(hdrdir)/ruby/ruby.h
|
20
|
+
init.o: $(hdrdir)/ruby/st.h
|
21
|
+
init.o: $(hdrdir)/ruby/subst.h
|
22
|
+
# init.o: $(top_srcdir)/include/ruby.h
|
23
|
+
init.o: init.c
|
24
|
+
init.o: sdbm.h
|
25
|
+
# AUTOGENERATED DEPENDENCIES END
|
data/ext/sdbm/extconf.rb
ADDED
data/ext/sdbm/init.c
ADDED
@@ -0,0 +1,1067 @@
|
|
1
|
+
/************************************************
|
2
|
+
|
3
|
+
sdbminit.c -
|
4
|
+
|
5
|
+
$Author$
|
6
|
+
created at: Fri May 7 08:34:24 JST 1999
|
7
|
+
|
8
|
+
Copyright (C) 1995-2001 Yukihiro Matsumoto
|
9
|
+
|
10
|
+
************************************************/
|
11
|
+
|
12
|
+
#include "ruby.h"
|
13
|
+
|
14
|
+
#include "sdbm.h"
|
15
|
+
#include <fcntl.h>
|
16
|
+
#include <errno.h>
|
17
|
+
|
18
|
+
/*
|
19
|
+
* Document-class: SDBM
|
20
|
+
*
|
21
|
+
* SDBM provides a simple file-based key-value store, which can only store
|
22
|
+
* String keys and values.
|
23
|
+
*
|
24
|
+
* Note that Ruby comes with the source code for SDBM, while the DBM and GDBM
|
25
|
+
* standard libraries rely on external libraries and headers.
|
26
|
+
*
|
27
|
+
* === Examples
|
28
|
+
*
|
29
|
+
* Insert values:
|
30
|
+
*
|
31
|
+
* require 'sdbm'
|
32
|
+
*
|
33
|
+
* SDBM.open 'my_database' do |db|
|
34
|
+
* db['apple'] = 'fruit'
|
35
|
+
* db['pear'] = 'fruit'
|
36
|
+
* db['carrot'] = 'vegetable'
|
37
|
+
* db['tomato'] = 'vegetable'
|
38
|
+
* end
|
39
|
+
*
|
40
|
+
* Bulk update:
|
41
|
+
*
|
42
|
+
* require 'sdbm'
|
43
|
+
*
|
44
|
+
* SDBM.open 'my_database' do |db|
|
45
|
+
* db.update('peach' => 'fruit', 'tomato' => 'fruit')
|
46
|
+
* end
|
47
|
+
*
|
48
|
+
* Retrieve values:
|
49
|
+
*
|
50
|
+
* require 'sdbm'
|
51
|
+
*
|
52
|
+
* SDBM.open 'my_database' do |db|
|
53
|
+
* db.each do |key, value|
|
54
|
+
* puts "Key: #{key}, Value: #{value}"
|
55
|
+
* end
|
56
|
+
* end
|
57
|
+
*
|
58
|
+
* Outputs:
|
59
|
+
*
|
60
|
+
* Key: apple, Value: fruit
|
61
|
+
* Key: pear, Value: fruit
|
62
|
+
* Key: carrot, Value: vegetable
|
63
|
+
* Key: peach, Value: fruit
|
64
|
+
* Key: tomato, Value: fruit
|
65
|
+
*/
|
66
|
+
|
67
|
+
static VALUE rb_cDBM, rb_eDBMError;
|
68
|
+
|
69
|
+
struct dbmdata {
|
70
|
+
int di_size;
|
71
|
+
DBM *di_dbm;
|
72
|
+
};
|
73
|
+
|
74
|
+
static void
|
75
|
+
closed_sdbm(void)
|
76
|
+
{
|
77
|
+
rb_raise(rb_eDBMError, "closed SDBM file");
|
78
|
+
}
|
79
|
+
|
80
|
+
#define GetDBM(obj, dbmp) do {\
|
81
|
+
TypedData_Get_Struct((obj), struct dbmdata, &sdbm_type, (dbmp));\
|
82
|
+
if ((dbmp) == 0) closed_sdbm();\
|
83
|
+
if ((dbmp)->di_dbm == 0) closed_sdbm();\
|
84
|
+
} while (0)
|
85
|
+
|
86
|
+
#define GetDBM2(obj, dbmp, dbm) do {\
|
87
|
+
GetDBM((obj), (dbmp));\
|
88
|
+
(dbm) = (dbmp)->di_dbm;\
|
89
|
+
} while (0)
|
90
|
+
|
91
|
+
static void
|
92
|
+
free_sdbm(void *ptr)
|
93
|
+
{
|
94
|
+
struct dbmdata *dbmp = ptr;
|
95
|
+
|
96
|
+
if (dbmp->di_dbm) sdbm_close(dbmp->di_dbm);
|
97
|
+
ruby_xfree(dbmp);
|
98
|
+
}
|
99
|
+
|
100
|
+
static size_t
|
101
|
+
memsize_dbm(const void *ptr)
|
102
|
+
{
|
103
|
+
size_t size = 0;
|
104
|
+
const struct dbmdata *dbmp = ptr;
|
105
|
+
if (dbmp) {
|
106
|
+
size += sizeof(*dbmp);
|
107
|
+
if (dbmp->di_dbm) size += sizeof(DBM);
|
108
|
+
}
|
109
|
+
return size;
|
110
|
+
}
|
111
|
+
|
112
|
+
static const rb_data_type_t sdbm_type = {
|
113
|
+
"sdbm",
|
114
|
+
{0, free_sdbm, memsize_dbm,},
|
115
|
+
0, 0,
|
116
|
+
RUBY_TYPED_FREE_IMMEDIATELY,
|
117
|
+
};
|
118
|
+
|
119
|
+
/*
|
120
|
+
* call-seq:
|
121
|
+
* sdbm.close -> nil
|
122
|
+
*
|
123
|
+
* Closes the database file.
|
124
|
+
*
|
125
|
+
* Raises SDBMError if the database is already closed.
|
126
|
+
*/
|
127
|
+
static VALUE
|
128
|
+
fsdbm_close(VALUE obj)
|
129
|
+
{
|
130
|
+
struct dbmdata *dbmp;
|
131
|
+
|
132
|
+
GetDBM(obj, dbmp);
|
133
|
+
sdbm_close(dbmp->di_dbm);
|
134
|
+
dbmp->di_dbm = 0;
|
135
|
+
|
136
|
+
return Qnil;
|
137
|
+
}
|
138
|
+
|
139
|
+
/*
|
140
|
+
* call-seq:
|
141
|
+
* sdbm.closed? -> true or false
|
142
|
+
*
|
143
|
+
* Returns +true+ if the database is closed.
|
144
|
+
*/
|
145
|
+
static VALUE
|
146
|
+
fsdbm_closed(VALUE obj)
|
147
|
+
{
|
148
|
+
struct dbmdata *dbmp;
|
149
|
+
|
150
|
+
TypedData_Get_Struct(obj, struct dbmdata, &sdbm_type, dbmp);
|
151
|
+
if (dbmp == 0)
|
152
|
+
return Qtrue;
|
153
|
+
if (dbmp->di_dbm == 0)
|
154
|
+
return Qtrue;
|
155
|
+
|
156
|
+
return Qfalse;
|
157
|
+
}
|
158
|
+
|
159
|
+
static VALUE
|
160
|
+
fsdbm_alloc(VALUE klass)
|
161
|
+
{
|
162
|
+
return TypedData_Wrap_Struct(klass, &sdbm_type, 0);
|
163
|
+
}
|
164
|
+
/*
|
165
|
+
* call-seq:
|
166
|
+
* SDBM.new(filename, mode = 0666)
|
167
|
+
*
|
168
|
+
* Creates a new database handle by opening the given +filename+. SDBM actually
|
169
|
+
* uses two physical files, with extensions '.dir' and '.pag'. These extensions
|
170
|
+
* will automatically be appended to the +filename+.
|
171
|
+
*
|
172
|
+
* If the file does not exist, a new file will be created using the given
|
173
|
+
* +mode+, unless +mode+ is explicitly set to nil. In the latter case, no
|
174
|
+
* database will be created.
|
175
|
+
*
|
176
|
+
* If the file exists, it will be opened in read/write mode. If this fails, it
|
177
|
+
* will be opened in read-only mode.
|
178
|
+
*/
|
179
|
+
static VALUE
|
180
|
+
fsdbm_initialize(int argc, VALUE *argv, VALUE obj)
|
181
|
+
{
|
182
|
+
VALUE file, vmode;
|
183
|
+
DBM *dbm;
|
184
|
+
struct dbmdata *dbmp;
|
185
|
+
int mode;
|
186
|
+
|
187
|
+
if (rb_scan_args(argc, argv, "11", &file, &vmode) == 1) {
|
188
|
+
mode = 0666; /* default value */
|
189
|
+
}
|
190
|
+
else if (NIL_P(vmode)) {
|
191
|
+
mode = -1; /* return nil if DB not exist */
|
192
|
+
}
|
193
|
+
else {
|
194
|
+
mode = NUM2INT(vmode);
|
195
|
+
}
|
196
|
+
FilePathValue(file);
|
197
|
+
|
198
|
+
dbm = 0;
|
199
|
+
if (mode >= 0)
|
200
|
+
dbm = sdbm_open(RSTRING_PTR(file), O_RDWR|O_CREAT, mode);
|
201
|
+
if (!dbm)
|
202
|
+
dbm = sdbm_open(RSTRING_PTR(file), O_RDWR, 0);
|
203
|
+
if (!dbm)
|
204
|
+
dbm = sdbm_open(RSTRING_PTR(file), O_RDONLY, 0);
|
205
|
+
|
206
|
+
if (!dbm) {
|
207
|
+
if (mode == -1) return Qnil;
|
208
|
+
rb_sys_fail_str(file);
|
209
|
+
}
|
210
|
+
|
211
|
+
dbmp = ALLOC(struct dbmdata);
|
212
|
+
DATA_PTR(obj) = dbmp;
|
213
|
+
dbmp->di_dbm = dbm;
|
214
|
+
dbmp->di_size = -1;
|
215
|
+
|
216
|
+
return obj;
|
217
|
+
}
|
218
|
+
|
219
|
+
/*
|
220
|
+
* call-seq:
|
221
|
+
* SDBM.open(filename, mode = 0666)
|
222
|
+
* SDBM.open(filename, mode = 0666) { |sdbm| ... }
|
223
|
+
*
|
224
|
+
* If called without a block, this is the same as SDBM.new.
|
225
|
+
*
|
226
|
+
* If a block is given, the new database will be passed to the block and
|
227
|
+
* will be safely closed after the block has executed.
|
228
|
+
*
|
229
|
+
* Example:
|
230
|
+
*
|
231
|
+
* require 'sdbm'
|
232
|
+
*
|
233
|
+
* SDBM.open('my_database') do |db|
|
234
|
+
* db['hello'] = 'world'
|
235
|
+
* end
|
236
|
+
*/
|
237
|
+
static VALUE
|
238
|
+
fsdbm_s_open(int argc, VALUE *argv, VALUE klass)
|
239
|
+
{
|
240
|
+
VALUE obj = fsdbm_alloc(klass);
|
241
|
+
|
242
|
+
if (NIL_P(fsdbm_initialize(argc, argv, obj))) {
|
243
|
+
return Qnil;
|
244
|
+
}
|
245
|
+
|
246
|
+
if (rb_block_given_p()) {
|
247
|
+
return rb_ensure(rb_yield, obj, fsdbm_close, obj);
|
248
|
+
}
|
249
|
+
|
250
|
+
return obj;
|
251
|
+
}
|
252
|
+
|
253
|
+
static VALUE
|
254
|
+
fsdbm_fetch(VALUE obj, VALUE keystr, VALUE ifnone)
|
255
|
+
{
|
256
|
+
datum key, value;
|
257
|
+
struct dbmdata *dbmp;
|
258
|
+
DBM *dbm;
|
259
|
+
|
260
|
+
ExportStringValue(keystr);
|
261
|
+
key.dptr = RSTRING_PTR(keystr);
|
262
|
+
key.dsize = RSTRING_LENINT(keystr);
|
263
|
+
|
264
|
+
GetDBM2(obj, dbmp, dbm);
|
265
|
+
value = sdbm_fetch(dbm, key);
|
266
|
+
if (value.dptr == 0) {
|
267
|
+
if (ifnone == Qnil && rb_block_given_p())
|
268
|
+
return rb_yield(rb_external_str_new(key.dptr, key.dsize));
|
269
|
+
return ifnone;
|
270
|
+
}
|
271
|
+
return rb_external_str_new(value.dptr, value.dsize);
|
272
|
+
}
|
273
|
+
|
274
|
+
/*
|
275
|
+
* call-seq:
|
276
|
+
* sdbm[key] -> value or nil
|
277
|
+
*
|
278
|
+
* Returns the +value+ in the database associated with the given +key+ string.
|
279
|
+
*
|
280
|
+
* If no value is found, returns +nil+.
|
281
|
+
*/
|
282
|
+
static VALUE
|
283
|
+
fsdbm_aref(VALUE obj, VALUE keystr)
|
284
|
+
{
|
285
|
+
return fsdbm_fetch(obj, keystr, Qnil);
|
286
|
+
}
|
287
|
+
|
288
|
+
/*
|
289
|
+
* call-seq:
|
290
|
+
* sdbm.fetch(key) -> value or nil
|
291
|
+
* sdbm.fetch(key) { |key| ... }
|
292
|
+
*
|
293
|
+
* Returns the +value+ in the database associated with the given +key+ string.
|
294
|
+
*
|
295
|
+
* If a block is provided, the block will be called when there is no
|
296
|
+
* +value+ associated with the given +key+. The +key+ will be passed in as an
|
297
|
+
* argument to the block.
|
298
|
+
*
|
299
|
+
* If no block is provided and no value is associated with the given +key+,
|
300
|
+
* then an IndexError will be raised.
|
301
|
+
*/
|
302
|
+
static VALUE
|
303
|
+
fsdbm_fetch_m(int argc, VALUE *argv, VALUE obj)
|
304
|
+
{
|
305
|
+
VALUE keystr, valstr, ifnone;
|
306
|
+
|
307
|
+
rb_scan_args(argc, argv, "11", &keystr, &ifnone);
|
308
|
+
valstr = fsdbm_fetch(obj, keystr, ifnone);
|
309
|
+
if (argc == 1 && !rb_block_given_p() && NIL_P(valstr))
|
310
|
+
rb_raise(rb_eIndexError, "key not found");
|
311
|
+
|
312
|
+
return valstr;
|
313
|
+
}
|
314
|
+
|
315
|
+
/*
|
316
|
+
* call-seq:
|
317
|
+
* sdbm.key(value) -> key
|
318
|
+
*
|
319
|
+
* Returns the +key+ associated with the given +value+. If more than one
|
320
|
+
* +key+ corresponds to the given +value+, then the first key to be found
|
321
|
+
* will be returned. If no keys are found, +nil+ will be returned.
|
322
|
+
*/
|
323
|
+
static VALUE
|
324
|
+
fsdbm_key(VALUE obj, VALUE valstr)
|
325
|
+
{
|
326
|
+
datum key, val;
|
327
|
+
struct dbmdata *dbmp;
|
328
|
+
DBM *dbm;
|
329
|
+
|
330
|
+
ExportStringValue(valstr);
|
331
|
+
val.dptr = RSTRING_PTR(valstr);
|
332
|
+
val.dsize = RSTRING_LENINT(valstr);
|
333
|
+
|
334
|
+
GetDBM2(obj, dbmp, dbm);
|
335
|
+
for (key = sdbm_firstkey(dbm); key.dptr; key = sdbm_nextkey(dbm)) {
|
336
|
+
val = sdbm_fetch(dbm, key);
|
337
|
+
if (val.dsize == RSTRING_LEN(valstr) &&
|
338
|
+
memcmp(val.dptr, RSTRING_PTR(valstr), val.dsize) == 0)
|
339
|
+
return rb_external_str_new(key.dptr, key.dsize);
|
340
|
+
}
|
341
|
+
return Qnil;
|
342
|
+
}
|
343
|
+
|
344
|
+
/*
|
345
|
+
* :nodoc:
|
346
|
+
*/
|
347
|
+
static VALUE
|
348
|
+
fsdbm_index(VALUE hash, VALUE value)
|
349
|
+
{
|
350
|
+
rb_warn("SDBM#index is deprecated; use SDBM#key");
|
351
|
+
return fsdbm_key(hash, value);
|
352
|
+
}
|
353
|
+
|
354
|
+
/* call-seq:
|
355
|
+
* sdbm.select { |key, value| ... } -> Array
|
356
|
+
*
|
357
|
+
* Returns a new Array of key-value pairs for which the block returns +true+.
|
358
|
+
*
|
359
|
+
* Example:
|
360
|
+
*
|
361
|
+
* require 'sdbm'
|
362
|
+
*
|
363
|
+
* SDBM.open 'my_database' do |db|
|
364
|
+
* db['apple'] = 'fruit'
|
365
|
+
* db['pear'] = 'fruit'
|
366
|
+
* db['spinach'] = 'vegetable'
|
367
|
+
*
|
368
|
+
* veggies = db.select do |key, value|
|
369
|
+
* value == 'vegetable'
|
370
|
+
* end #=> [["apple", "fruit"], ["pear", "fruit"]]
|
371
|
+
* end
|
372
|
+
*/
|
373
|
+
static VALUE
|
374
|
+
fsdbm_select(VALUE obj)
|
375
|
+
{
|
376
|
+
VALUE new = rb_ary_new();
|
377
|
+
datum key, val;
|
378
|
+
DBM *dbm;
|
379
|
+
struct dbmdata *dbmp;
|
380
|
+
|
381
|
+
GetDBM2(obj, dbmp, dbm);
|
382
|
+
for (key = sdbm_firstkey(dbm); key.dptr; key = sdbm_nextkey(dbm)) {
|
383
|
+
VALUE assoc, v;
|
384
|
+
val = sdbm_fetch(dbm, key);
|
385
|
+
assoc = rb_assoc_new(rb_external_str_new(key.dptr, key.dsize),
|
386
|
+
rb_external_str_new(val.dptr, val.dsize));
|
387
|
+
v = rb_yield(assoc);
|
388
|
+
if (RTEST(v)) {
|
389
|
+
rb_ary_push(new, assoc);
|
390
|
+
}
|
391
|
+
GetDBM2(obj, dbmp, dbm);
|
392
|
+
}
|
393
|
+
|
394
|
+
return new;
|
395
|
+
}
|
396
|
+
|
397
|
+
/* call-seq:
|
398
|
+
* sdbm.values_at(key, ...) -> Array
|
399
|
+
*
|
400
|
+
* Returns an Array of values corresponding to the given keys.
|
401
|
+
*/
|
402
|
+
static VALUE
|
403
|
+
fsdbm_values_at(int argc, VALUE *argv, VALUE obj)
|
404
|
+
{
|
405
|
+
VALUE new = rb_ary_new2(argc);
|
406
|
+
int i;
|
407
|
+
|
408
|
+
for (i=0; i<argc; i++) {
|
409
|
+
rb_ary_push(new, fsdbm_fetch(obj, argv[i], Qnil));
|
410
|
+
}
|
411
|
+
|
412
|
+
return new;
|
413
|
+
}
|
414
|
+
|
415
|
+
static void
|
416
|
+
fdbm_modify(VALUE obj)
|
417
|
+
{
|
418
|
+
if (OBJ_FROZEN(obj)) rb_error_frozen("SDBM");
|
419
|
+
}
|
420
|
+
|
421
|
+
/*
|
422
|
+
* call-seq:
|
423
|
+
* sdbm.delete(key) -> value or nil
|
424
|
+
* sdbm.delete(key) { |key, value| ... }
|
425
|
+
*
|
426
|
+
* Deletes the key-value pair corresponding to the given +key+. If the
|
427
|
+
* +key+ exists, the deleted value will be returned, otherwise +nil+.
|
428
|
+
*
|
429
|
+
* If a block is provided, the deleted +key+ and +value+ will be passed to
|
430
|
+
* the block as arguments. If the +key+ does not exist in the database, the
|
431
|
+
* value will be +nil+.
|
432
|
+
*/
|
433
|
+
static VALUE
|
434
|
+
fsdbm_delete(VALUE obj, VALUE keystr)
|
435
|
+
{
|
436
|
+
datum key, value;
|
437
|
+
struct dbmdata *dbmp;
|
438
|
+
DBM *dbm;
|
439
|
+
VALUE valstr;
|
440
|
+
|
441
|
+
fdbm_modify(obj);
|
442
|
+
ExportStringValue(keystr);
|
443
|
+
key.dptr = RSTRING_PTR(keystr);
|
444
|
+
key.dsize = RSTRING_LENINT(keystr);
|
445
|
+
|
446
|
+
GetDBM2(obj, dbmp, dbm);
|
447
|
+
dbmp->di_size = -1;
|
448
|
+
|
449
|
+
value = sdbm_fetch(dbm, key);
|
450
|
+
if (value.dptr == 0) {
|
451
|
+
if (rb_block_given_p()) return rb_yield(keystr);
|
452
|
+
return Qnil;
|
453
|
+
}
|
454
|
+
|
455
|
+
/* need to save value before sdbm_delete() */
|
456
|
+
valstr = rb_external_str_new(value.dptr, value.dsize);
|
457
|
+
|
458
|
+
if (sdbm_delete(dbm, key)) {
|
459
|
+
dbmp->di_size = -1;
|
460
|
+
rb_raise(rb_eDBMError, "dbm_delete failed");
|
461
|
+
}
|
462
|
+
else if (dbmp->di_size >= 0) {
|
463
|
+
dbmp->di_size--;
|
464
|
+
}
|
465
|
+
return valstr;
|
466
|
+
}
|
467
|
+
|
468
|
+
/*
|
469
|
+
* call-seq:
|
470
|
+
* sdbm.shift -> Array or nil
|
471
|
+
*
|
472
|
+
* Removes a key-value pair from the database and returns them as an
|
473
|
+
* Array. If the database is empty, returns +nil+.
|
474
|
+
*/
|
475
|
+
static VALUE
|
476
|
+
fsdbm_shift(VALUE obj)
|
477
|
+
{
|
478
|
+
datum key, val;
|
479
|
+
struct dbmdata *dbmp;
|
480
|
+
DBM *dbm;
|
481
|
+
VALUE keystr, valstr;
|
482
|
+
|
483
|
+
fdbm_modify(obj);
|
484
|
+
GetDBM2(obj, dbmp, dbm);
|
485
|
+
key = sdbm_firstkey(dbm);
|
486
|
+
if (!key.dptr) return Qnil;
|
487
|
+
val = sdbm_fetch(dbm, key);
|
488
|
+
keystr = rb_external_str_new(key.dptr, key.dsize);
|
489
|
+
valstr = rb_external_str_new(val.dptr, val.dsize);
|
490
|
+
sdbm_delete(dbm, key);
|
491
|
+
if (dbmp->di_size >= 0) {
|
492
|
+
dbmp->di_size--;
|
493
|
+
}
|
494
|
+
|
495
|
+
return rb_assoc_new(keystr, valstr);
|
496
|
+
}
|
497
|
+
|
498
|
+
/*
|
499
|
+
* call-seq:
|
500
|
+
* sdbm.delete_if { |key, value| ... } -> self
|
501
|
+
* sdbm.reject! { |key, value| ... } -> self
|
502
|
+
*
|
503
|
+
* Iterates over the key-value pairs in the database, deleting those for
|
504
|
+
* which the block returns +true+.
|
505
|
+
*/
|
506
|
+
static VALUE
|
507
|
+
fsdbm_delete_if(VALUE obj)
|
508
|
+
{
|
509
|
+
datum key, val;
|
510
|
+
struct dbmdata *dbmp;
|
511
|
+
DBM *dbm;
|
512
|
+
VALUE keystr, valstr;
|
513
|
+
VALUE ret, ary = rb_ary_new();
|
514
|
+
long i;
|
515
|
+
int status = 0, n;
|
516
|
+
|
517
|
+
fdbm_modify(obj);
|
518
|
+
GetDBM2(obj, dbmp, dbm);
|
519
|
+
n = dbmp->di_size;
|
520
|
+
dbmp->di_size = -1;
|
521
|
+
for (key = sdbm_firstkey(dbm); key.dptr; key = sdbm_nextkey(dbm)) {
|
522
|
+
val = sdbm_fetch(dbm, key);
|
523
|
+
keystr = rb_external_str_new(key.dptr, key.dsize);
|
524
|
+
valstr = rb_external_str_new(val.dptr, val.dsize);
|
525
|
+
ret = rb_protect(rb_yield, rb_assoc_new(rb_str_dup(keystr), valstr), &status);
|
526
|
+
if (status != 0) break;
|
527
|
+
if (RTEST(ret)) rb_ary_push(ary, keystr);
|
528
|
+
GetDBM2(obj, dbmp, dbm);
|
529
|
+
}
|
530
|
+
|
531
|
+
for (i = 0; i < RARRAY_LEN(ary); i++) {
|
532
|
+
keystr = RARRAY_AREF(ary, i);
|
533
|
+
ExportStringValue(keystr);
|
534
|
+
key.dptr = RSTRING_PTR(keystr);
|
535
|
+
key.dsize = RSTRING_LENINT(keystr);
|
536
|
+
if (sdbm_delete(dbm, key)) {
|
537
|
+
rb_raise(rb_eDBMError, "sdbm_delete failed");
|
538
|
+
}
|
539
|
+
}
|
540
|
+
if (status) rb_jump_tag(status);
|
541
|
+
if (n > 0) dbmp->di_size = n - RARRAY_LENINT(ary);
|
542
|
+
|
543
|
+
return obj;
|
544
|
+
}
|
545
|
+
|
546
|
+
/*
|
547
|
+
* call-seq:
|
548
|
+
* sdbm.clear -> self
|
549
|
+
*
|
550
|
+
* Deletes all data from the database.
|
551
|
+
*/
|
552
|
+
static VALUE
|
553
|
+
fsdbm_clear(VALUE obj)
|
554
|
+
{
|
555
|
+
datum key;
|
556
|
+
struct dbmdata *dbmp;
|
557
|
+
DBM *dbm;
|
558
|
+
|
559
|
+
fdbm_modify(obj);
|
560
|
+
GetDBM2(obj, dbmp, dbm);
|
561
|
+
dbmp->di_size = -1;
|
562
|
+
while (key = sdbm_firstkey(dbm), key.dptr) {
|
563
|
+
if (sdbm_delete(dbm, key)) {
|
564
|
+
rb_raise(rb_eDBMError, "sdbm_delete failed");
|
565
|
+
}
|
566
|
+
}
|
567
|
+
dbmp->di_size = 0;
|
568
|
+
|
569
|
+
return obj;
|
570
|
+
}
|
571
|
+
|
572
|
+
/*
|
573
|
+
* call-seq:
|
574
|
+
* sdbm.invert -> Hash
|
575
|
+
*
|
576
|
+
* Returns a Hash in which the key-value pairs have been inverted.
|
577
|
+
*
|
578
|
+
* Example:
|
579
|
+
*
|
580
|
+
* require 'sdbm'
|
581
|
+
*
|
582
|
+
* SDBM.open 'my_database' do |db|
|
583
|
+
* db.update('apple' => 'fruit', 'spinach' => 'vegetable')
|
584
|
+
*
|
585
|
+
* db.invert #=> {"fruit" => "apple", "vegetable" => "spinach"}
|
586
|
+
* end
|
587
|
+
*/
|
588
|
+
static VALUE
|
589
|
+
fsdbm_invert(VALUE obj)
|
590
|
+
{
|
591
|
+
datum key, val;
|
592
|
+
struct dbmdata *dbmp;
|
593
|
+
DBM *dbm;
|
594
|
+
VALUE keystr, valstr;
|
595
|
+
VALUE hash = rb_hash_new();
|
596
|
+
|
597
|
+
GetDBM2(obj, dbmp, dbm);
|
598
|
+
for (key = sdbm_firstkey(dbm); key.dptr; key = sdbm_nextkey(dbm)) {
|
599
|
+
val = sdbm_fetch(dbm, key);
|
600
|
+
keystr = rb_external_str_new(key.dptr, key.dsize);
|
601
|
+
valstr = rb_external_str_new(val.dptr, val.dsize);
|
602
|
+
rb_hash_aset(hash, valstr, keystr);
|
603
|
+
}
|
604
|
+
return hash;
|
605
|
+
}
|
606
|
+
|
607
|
+
/*
|
608
|
+
* call-seq:
|
609
|
+
* sdbm[key] = value -> value
|
610
|
+
* sdbm.store(key, value) -> value
|
611
|
+
*
|
612
|
+
* Stores a new +value+ in the database with the given +key+ as an index.
|
613
|
+
*
|
614
|
+
* If the +key+ already exists, this will update the +value+ associated with
|
615
|
+
* the +key+.
|
616
|
+
*
|
617
|
+
* Returns the given +value+.
|
618
|
+
*/
|
619
|
+
static VALUE
|
620
|
+
fsdbm_store(VALUE obj, VALUE keystr, VALUE valstr)
|
621
|
+
{
|
622
|
+
datum key, val;
|
623
|
+
struct dbmdata *dbmp;
|
624
|
+
DBM *dbm;
|
625
|
+
|
626
|
+
if (valstr == Qnil) {
|
627
|
+
fsdbm_delete(obj, keystr);
|
628
|
+
return Qnil;
|
629
|
+
}
|
630
|
+
|
631
|
+
fdbm_modify(obj);
|
632
|
+
ExportStringValue(keystr);
|
633
|
+
ExportStringValue(valstr);
|
634
|
+
|
635
|
+
key.dptr = RSTRING_PTR(keystr);
|
636
|
+
key.dsize = RSTRING_LENINT(keystr);
|
637
|
+
|
638
|
+
val.dptr = RSTRING_PTR(valstr);
|
639
|
+
val.dsize = RSTRING_LENINT(valstr);
|
640
|
+
|
641
|
+
GetDBM2(obj, dbmp, dbm);
|
642
|
+
dbmp->di_size = -1;
|
643
|
+
if (sdbm_store(dbm, key, val, DBM_REPLACE)) {
|
644
|
+
#ifdef HAVE_DBM_CLAERERR
|
645
|
+
sdbm_clearerr(dbm);
|
646
|
+
#endif
|
647
|
+
if (errno == EPERM) rb_sys_fail(0);
|
648
|
+
rb_raise(rb_eDBMError, "sdbm_store failed");
|
649
|
+
}
|
650
|
+
|
651
|
+
return valstr;
|
652
|
+
}
|
653
|
+
|
654
|
+
static VALUE
|
655
|
+
update_i(RB_BLOCK_CALL_FUNC_ARGLIST(pair, dbm))
|
656
|
+
{
|
657
|
+
const VALUE *ptr;
|
658
|
+
Check_Type(pair, T_ARRAY);
|
659
|
+
if (RARRAY_LEN(pair) < 2) {
|
660
|
+
rb_raise(rb_eArgError, "pair must be [key, value]");
|
661
|
+
}
|
662
|
+
ptr = RARRAY_CONST_PTR(pair);
|
663
|
+
fsdbm_store(dbm, ptr[0], ptr[1]);
|
664
|
+
return Qnil;
|
665
|
+
}
|
666
|
+
|
667
|
+
/*
|
668
|
+
* call-seq:
|
669
|
+
* sdbm.update(pairs) -> self
|
670
|
+
*
|
671
|
+
* Insert or update key-value pairs.
|
672
|
+
*
|
673
|
+
* This method will work with any object which implements an each_pair
|
674
|
+
* method, such as a Hash.
|
675
|
+
*/
|
676
|
+
static VALUE
|
677
|
+
fsdbm_update(VALUE obj, VALUE other)
|
678
|
+
{
|
679
|
+
rb_block_call(other, rb_intern("each_pair"), 0, 0, update_i, obj);
|
680
|
+
return obj;
|
681
|
+
}
|
682
|
+
|
683
|
+
/*
|
684
|
+
* call-seq:
|
685
|
+
* sdbm.replace(pairs) -> self
|
686
|
+
*
|
687
|
+
* Empties the database, then inserts the given key-value pairs.
|
688
|
+
*
|
689
|
+
* This method will work with any object which implements an each_pair
|
690
|
+
* method, such as a Hash.
|
691
|
+
*/
|
692
|
+
static VALUE
|
693
|
+
fsdbm_replace(VALUE obj, VALUE other)
|
694
|
+
{
|
695
|
+
fsdbm_clear(obj);
|
696
|
+
rb_block_call(other, rb_intern("each_pair"), 0, 0, update_i, obj);
|
697
|
+
return obj;
|
698
|
+
}
|
699
|
+
|
700
|
+
/*
|
701
|
+
* call-seq:
|
702
|
+
* sdbm.length -> integer
|
703
|
+
* sdbm.size -> integer
|
704
|
+
*
|
705
|
+
* Returns the number of keys in the database.
|
706
|
+
*/
|
707
|
+
static VALUE
|
708
|
+
fsdbm_length(VALUE obj)
|
709
|
+
{
|
710
|
+
datum key;
|
711
|
+
struct dbmdata *dbmp;
|
712
|
+
DBM *dbm;
|
713
|
+
int i = 0;
|
714
|
+
|
715
|
+
GetDBM2(obj, dbmp, dbm);
|
716
|
+
if (dbmp->di_size > 0) return INT2FIX(dbmp->di_size);
|
717
|
+
|
718
|
+
for (key = sdbm_firstkey(dbm); key.dptr; key = sdbm_nextkey(dbm)) {
|
719
|
+
i++;
|
720
|
+
}
|
721
|
+
dbmp->di_size = i;
|
722
|
+
|
723
|
+
return INT2FIX(i);
|
724
|
+
}
|
725
|
+
|
726
|
+
/*
|
727
|
+
* call-seq:
|
728
|
+
* sdbm.empty? -> true or false
|
729
|
+
*
|
730
|
+
* Returns +true+ if the database is empty.
|
731
|
+
*/
|
732
|
+
static VALUE
|
733
|
+
fsdbm_empty_p(VALUE obj)
|
734
|
+
{
|
735
|
+
datum key;
|
736
|
+
struct dbmdata *dbmp;
|
737
|
+
DBM *dbm;
|
738
|
+
|
739
|
+
GetDBM(obj, dbmp);
|
740
|
+
if (dbmp->di_size < 0) {
|
741
|
+
dbm = dbmp->di_dbm;
|
742
|
+
|
743
|
+
for (key = sdbm_firstkey(dbm); key.dptr; key = sdbm_nextkey(dbm)) {
|
744
|
+
return Qfalse;
|
745
|
+
}
|
746
|
+
}
|
747
|
+
else {
|
748
|
+
if (dbmp->di_size)
|
749
|
+
return Qfalse;
|
750
|
+
}
|
751
|
+
return Qtrue;
|
752
|
+
}
|
753
|
+
|
754
|
+
/*
|
755
|
+
* call-seq:
|
756
|
+
* sdbm.each_value
|
757
|
+
* sdbm.each_value { |value| ... }
|
758
|
+
*
|
759
|
+
* Iterates over each +value+ in the database.
|
760
|
+
*
|
761
|
+
* If no block is given, returns an Enumerator.
|
762
|
+
*/
|
763
|
+
static VALUE
|
764
|
+
fsdbm_each_value(VALUE obj)
|
765
|
+
{
|
766
|
+
datum key, val;
|
767
|
+
struct dbmdata *dbmp;
|
768
|
+
DBM *dbm;
|
769
|
+
|
770
|
+
RETURN_ENUMERATOR(obj, 0, 0);
|
771
|
+
|
772
|
+
GetDBM2(obj, dbmp, dbm);
|
773
|
+
for (key = sdbm_firstkey(dbm); key.dptr; key = sdbm_nextkey(dbm)) {
|
774
|
+
val = sdbm_fetch(dbm, key);
|
775
|
+
rb_yield(rb_external_str_new(val.dptr, val.dsize));
|
776
|
+
GetDBM2(obj, dbmp, dbm);
|
777
|
+
}
|
778
|
+
return obj;
|
779
|
+
}
|
780
|
+
|
781
|
+
/*
|
782
|
+
* call-seq:
|
783
|
+
* sdbm.each_key
|
784
|
+
* sdbm.each_key { |key| ... }
|
785
|
+
*
|
786
|
+
* Iterates over each +key+ in the database.
|
787
|
+
*
|
788
|
+
* If no block is given, returns an Enumerator.
|
789
|
+
*/
|
790
|
+
static VALUE
|
791
|
+
fsdbm_each_key(VALUE obj)
|
792
|
+
{
|
793
|
+
datum key;
|
794
|
+
struct dbmdata *dbmp;
|
795
|
+
DBM *dbm;
|
796
|
+
|
797
|
+
RETURN_ENUMERATOR(obj, 0, 0);
|
798
|
+
|
799
|
+
GetDBM2(obj, dbmp, dbm);
|
800
|
+
for (key = sdbm_firstkey(dbm); key.dptr; key = sdbm_nextkey(dbm)) {
|
801
|
+
rb_yield(rb_external_str_new(key.dptr, key.dsize));
|
802
|
+
GetDBM2(obj, dbmp, dbm);
|
803
|
+
}
|
804
|
+
return obj;
|
805
|
+
}
|
806
|
+
|
807
|
+
/*
|
808
|
+
* call-seq:
|
809
|
+
* sdbm.each
|
810
|
+
* sdbm.each { |key, value| ... }
|
811
|
+
* sdbm.each_pair
|
812
|
+
* sdbm.each_pair { |key, value| ... }
|
813
|
+
*
|
814
|
+
* Iterates over each key-value pair in the database.
|
815
|
+
*
|
816
|
+
* If no block is given, returns an Enumerator.
|
817
|
+
*/
|
818
|
+
static VALUE
|
819
|
+
fsdbm_each_pair(VALUE obj)
|
820
|
+
{
|
821
|
+
datum key, val;
|
822
|
+
DBM *dbm;
|
823
|
+
struct dbmdata *dbmp;
|
824
|
+
VALUE keystr, valstr;
|
825
|
+
|
826
|
+
RETURN_ENUMERATOR(obj, 0, 0);
|
827
|
+
|
828
|
+
GetDBM2(obj, dbmp, dbm);
|
829
|
+
for (key = sdbm_firstkey(dbm); key.dptr; key = sdbm_nextkey(dbm)) {
|
830
|
+
val = sdbm_fetch(dbm, key);
|
831
|
+
keystr = rb_external_str_new(key.dptr, key.dsize);
|
832
|
+
valstr = rb_external_str_new(val.dptr, val.dsize);
|
833
|
+
rb_yield(rb_assoc_new(keystr, valstr));
|
834
|
+
GetDBM2(obj, dbmp, dbm);
|
835
|
+
}
|
836
|
+
|
837
|
+
return obj;
|
838
|
+
}
|
839
|
+
|
840
|
+
/*
|
841
|
+
* call-seq:
|
842
|
+
* sdbm.keys -> Array
|
843
|
+
*
|
844
|
+
* Returns a new Array containing the keys in the database.
|
845
|
+
*/
|
846
|
+
static VALUE
|
847
|
+
fsdbm_keys(VALUE obj)
|
848
|
+
{
|
849
|
+
datum key;
|
850
|
+
struct dbmdata *dbmp;
|
851
|
+
DBM *dbm;
|
852
|
+
VALUE ary;
|
853
|
+
|
854
|
+
GetDBM2(obj, dbmp, dbm);
|
855
|
+
ary = rb_ary_new();
|
856
|
+
for (key = sdbm_firstkey(dbm); key.dptr; key = sdbm_nextkey(dbm)) {
|
857
|
+
rb_ary_push(ary, rb_external_str_new(key.dptr, key.dsize));
|
858
|
+
}
|
859
|
+
|
860
|
+
return ary;
|
861
|
+
}
|
862
|
+
|
863
|
+
/*
|
864
|
+
* call-seq:
|
865
|
+
* sdbm.values -> Array
|
866
|
+
*
|
867
|
+
* Returns a new Array containing the values in the database.
|
868
|
+
*/
|
869
|
+
static VALUE
|
870
|
+
fsdbm_values(VALUE obj)
|
871
|
+
{
|
872
|
+
datum key, val;
|
873
|
+
struct dbmdata *dbmp;
|
874
|
+
DBM *dbm;
|
875
|
+
VALUE ary;
|
876
|
+
|
877
|
+
GetDBM2(obj, dbmp, dbm);
|
878
|
+
ary = rb_ary_new();
|
879
|
+
for (key = sdbm_firstkey(dbm); key.dptr; key = sdbm_nextkey(dbm)) {
|
880
|
+
val = sdbm_fetch(dbm, key);
|
881
|
+
rb_ary_push(ary, rb_external_str_new(val.dptr, val.dsize));
|
882
|
+
}
|
883
|
+
|
884
|
+
return ary;
|
885
|
+
}
|
886
|
+
|
887
|
+
/*
|
888
|
+
* call-seq:
|
889
|
+
* sdbm.include?(key) -> true or false
|
890
|
+
* sdbm.key?(key) -> true or false
|
891
|
+
* sdbm.member?(key) -> true or false
|
892
|
+
* sdbm.has_key?(key) -> true or false
|
893
|
+
*
|
894
|
+
* Returns +true+ if the database contains the given +key+.
|
895
|
+
*/
|
896
|
+
static VALUE
|
897
|
+
fsdbm_has_key(VALUE obj, VALUE keystr)
|
898
|
+
{
|
899
|
+
datum key, val;
|
900
|
+
struct dbmdata *dbmp;
|
901
|
+
DBM *dbm;
|
902
|
+
|
903
|
+
ExportStringValue(keystr);
|
904
|
+
key.dptr = RSTRING_PTR(keystr);
|
905
|
+
key.dsize = RSTRING_LENINT(keystr);
|
906
|
+
|
907
|
+
GetDBM2(obj, dbmp, dbm);
|
908
|
+
val = sdbm_fetch(dbm, key);
|
909
|
+
if (val.dptr) return Qtrue;
|
910
|
+
return Qfalse;
|
911
|
+
}
|
912
|
+
|
913
|
+
/*
|
914
|
+
* call-seq:
|
915
|
+
* sdbm.value?(key) -> true or false
|
916
|
+
* sdbm.has_value?(key) -> true or false
|
917
|
+
*
|
918
|
+
* Returns +true+ if the database contains the given +value+.
|
919
|
+
*/
|
920
|
+
static VALUE
|
921
|
+
fsdbm_has_value(VALUE obj, VALUE valstr)
|
922
|
+
{
|
923
|
+
datum key, val;
|
924
|
+
struct dbmdata *dbmp;
|
925
|
+
DBM *dbm;
|
926
|
+
|
927
|
+
ExportStringValue(valstr);
|
928
|
+
val.dptr = RSTRING_PTR(valstr);
|
929
|
+
val.dsize = RSTRING_LENINT(valstr);
|
930
|
+
|
931
|
+
GetDBM2(obj, dbmp, dbm);
|
932
|
+
for (key = sdbm_firstkey(dbm); key.dptr; key = sdbm_nextkey(dbm)) {
|
933
|
+
val = sdbm_fetch(dbm, key);
|
934
|
+
if (val.dsize == RSTRING_LENINT(valstr) &&
|
935
|
+
memcmp(val.dptr, RSTRING_PTR(valstr), val.dsize) == 0)
|
936
|
+
return Qtrue;
|
937
|
+
}
|
938
|
+
return Qfalse;
|
939
|
+
}
|
940
|
+
|
941
|
+
/*
|
942
|
+
* call-seq:
|
943
|
+
* sdbm.to_a -> Array
|
944
|
+
*
|
945
|
+
* Returns a new Array containing each key-value pair in the database.
|
946
|
+
*
|
947
|
+
* Example:
|
948
|
+
*
|
949
|
+
* require 'sdbm'
|
950
|
+
*
|
951
|
+
* SDBM.open 'my_database' do |db|
|
952
|
+
* db.update('apple' => 'fruit', 'spinach' => 'vegetable')
|
953
|
+
*
|
954
|
+
* db.to_a #=> [["apple", "fruit"], ["spinach", "vegetable"]]
|
955
|
+
* end
|
956
|
+
*/
|
957
|
+
static VALUE
|
958
|
+
fsdbm_to_a(VALUE obj)
|
959
|
+
{
|
960
|
+
datum key, val;
|
961
|
+
struct dbmdata *dbmp;
|
962
|
+
DBM *dbm;
|
963
|
+
VALUE ary;
|
964
|
+
|
965
|
+
GetDBM2(obj, dbmp, dbm);
|
966
|
+
ary = rb_ary_new();
|
967
|
+
for (key = sdbm_firstkey(dbm); key.dptr; key = sdbm_nextkey(dbm)) {
|
968
|
+
val = sdbm_fetch(dbm, key);
|
969
|
+
rb_ary_push(ary, rb_assoc_new(rb_external_str_new(key.dptr, key.dsize),
|
970
|
+
rb_external_str_new(val.dptr, val.dsize)));
|
971
|
+
}
|
972
|
+
|
973
|
+
return ary;
|
974
|
+
}
|
975
|
+
|
976
|
+
/*
|
977
|
+
* call-seq:
|
978
|
+
* sdbm.to_hash -> Hash
|
979
|
+
*
|
980
|
+
* Returns a new Hash containing each key-value pair in the database.
|
981
|
+
*/
|
982
|
+
static VALUE
|
983
|
+
fsdbm_to_hash(VALUE obj)
|
984
|
+
{
|
985
|
+
datum key, val;
|
986
|
+
struct dbmdata *dbmp;
|
987
|
+
DBM *dbm;
|
988
|
+
VALUE hash;
|
989
|
+
|
990
|
+
GetDBM2(obj, dbmp, dbm);
|
991
|
+
hash = rb_hash_new();
|
992
|
+
for (key = sdbm_firstkey(dbm); key.dptr; key = sdbm_nextkey(dbm)) {
|
993
|
+
val = sdbm_fetch(dbm, key);
|
994
|
+
rb_hash_aset(hash, rb_external_str_new(key.dptr, key.dsize),
|
995
|
+
rb_external_str_new(val.dptr, val.dsize));
|
996
|
+
}
|
997
|
+
|
998
|
+
return hash;
|
999
|
+
}
|
1000
|
+
|
1001
|
+
/*
|
1002
|
+
* call-seq:
|
1003
|
+
* sdbm.reject { |key, value| ... } -> Hash
|
1004
|
+
*
|
1005
|
+
* Creates a new Hash using the key-value pairs from the database, then
|
1006
|
+
* calls Hash#reject with the given block, which returns a Hash with
|
1007
|
+
* only the key-value pairs for which the block returns +false+.
|
1008
|
+
*/
|
1009
|
+
static VALUE
|
1010
|
+
fsdbm_reject(VALUE obj)
|
1011
|
+
{
|
1012
|
+
return rb_hash_delete_if(fsdbm_to_hash(obj));
|
1013
|
+
}
|
1014
|
+
|
1015
|
+
void
|
1016
|
+
Init_sdbm(void)
|
1017
|
+
{
|
1018
|
+
rb_cDBM = rb_define_class("SDBM", rb_cObject);
|
1019
|
+
rb_eDBMError = rb_define_class("SDBMError", rb_eStandardError);
|
1020
|
+
/* Document-class: SDBMError
|
1021
|
+
* Exception class used to return errors from the sdbm library.
|
1022
|
+
*/
|
1023
|
+
rb_include_module(rb_cDBM, rb_mEnumerable);
|
1024
|
+
|
1025
|
+
rb_define_alloc_func(rb_cDBM, fsdbm_alloc);
|
1026
|
+
rb_define_singleton_method(rb_cDBM, "open", fsdbm_s_open, -1);
|
1027
|
+
|
1028
|
+
rb_define_method(rb_cDBM, "initialize", fsdbm_initialize, -1);
|
1029
|
+
rb_define_method(rb_cDBM, "close", fsdbm_close, 0);
|
1030
|
+
rb_define_method(rb_cDBM, "closed?", fsdbm_closed, 0);
|
1031
|
+
rb_define_method(rb_cDBM, "[]", fsdbm_aref, 1);
|
1032
|
+
rb_define_method(rb_cDBM, "fetch", fsdbm_fetch_m, -1);
|
1033
|
+
rb_define_method(rb_cDBM, "[]=", fsdbm_store, 2);
|
1034
|
+
rb_define_method(rb_cDBM, "store", fsdbm_store, 2);
|
1035
|
+
rb_define_method(rb_cDBM, "index", fsdbm_index, 1);
|
1036
|
+
rb_define_method(rb_cDBM, "key", fsdbm_key, 1);
|
1037
|
+
rb_define_method(rb_cDBM, "select", fsdbm_select, 0);
|
1038
|
+
rb_define_method(rb_cDBM, "values_at", fsdbm_values_at, -1);
|
1039
|
+
rb_define_method(rb_cDBM, "length", fsdbm_length, 0);
|
1040
|
+
rb_define_method(rb_cDBM, "size", fsdbm_length, 0);
|
1041
|
+
rb_define_method(rb_cDBM, "empty?", fsdbm_empty_p, 0);
|
1042
|
+
rb_define_method(rb_cDBM, "each", fsdbm_each_pair, 0);
|
1043
|
+
rb_define_method(rb_cDBM, "each_value", fsdbm_each_value, 0);
|
1044
|
+
rb_define_method(rb_cDBM, "each_key", fsdbm_each_key, 0);
|
1045
|
+
rb_define_method(rb_cDBM, "each_pair", fsdbm_each_pair, 0);
|
1046
|
+
rb_define_method(rb_cDBM, "keys", fsdbm_keys, 0);
|
1047
|
+
rb_define_method(rb_cDBM, "values", fsdbm_values, 0);
|
1048
|
+
rb_define_method(rb_cDBM, "shift", fsdbm_shift, 0);
|
1049
|
+
rb_define_method(rb_cDBM, "delete", fsdbm_delete, 1);
|
1050
|
+
rb_define_method(rb_cDBM, "delete_if", fsdbm_delete_if, 0);
|
1051
|
+
rb_define_method(rb_cDBM, "reject!", fsdbm_delete_if, 0);
|
1052
|
+
rb_define_method(rb_cDBM, "reject", fsdbm_reject, 0);
|
1053
|
+
rb_define_method(rb_cDBM, "clear", fsdbm_clear, 0);
|
1054
|
+
rb_define_method(rb_cDBM,"invert", fsdbm_invert, 0);
|
1055
|
+
rb_define_method(rb_cDBM,"update", fsdbm_update, 1);
|
1056
|
+
rb_define_method(rb_cDBM,"replace", fsdbm_replace, 1);
|
1057
|
+
|
1058
|
+
rb_define_method(rb_cDBM, "has_key?", fsdbm_has_key, 1);
|
1059
|
+
rb_define_method(rb_cDBM, "include?", fsdbm_has_key, 1);
|
1060
|
+
rb_define_method(rb_cDBM, "key?", fsdbm_has_key, 1);
|
1061
|
+
rb_define_method(rb_cDBM, "member?", fsdbm_has_key, 1);
|
1062
|
+
rb_define_method(rb_cDBM, "has_value?", fsdbm_has_value, 1);
|
1063
|
+
rb_define_method(rb_cDBM, "value?", fsdbm_has_value, 1);
|
1064
|
+
|
1065
|
+
rb_define_method(rb_cDBM, "to_a", fsdbm_to_a, 0);
|
1066
|
+
rb_define_method(rb_cDBM, "to_hash", fsdbm_to_hash, 0);
|
1067
|
+
}
|