libcdb-ruby 0.0.1-x86-mswin32-60 → 0.0.2-x86-mswin32-60

Sign up to get free protection for your applications and to get access to all the features.
data/ChangeLog CHANGED
@@ -1,5 +1,12 @@
1
1
  = Revision history for libcdb-ruby
2
2
 
3
+ == 0.0.2 [2012-01-20]
4
+
5
+ * Refactored C code to DRY.
6
+ * Added Writer#<< as alias for Writer#store.
7
+ * Added missing delegate CDB#total.
8
+ * A little housekeeping.
9
+
3
10
  == 0.0.1 [2012-01-12]
4
11
 
5
12
  * Birthday :-)
data/README CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  == VERSION
4
4
 
5
- This documentation refers to libcdb-ruby version 0.0.1
5
+ This documentation refers to libcdb-ruby version 0.0.2
6
6
 
7
7
 
8
8
  == DESCRIPTION
@@ -35,6 +35,8 @@ creating and reading {constant databases}[http://cr.yp.to/cdb.html].
35
35
  cdb['b'] #=> "123"
36
36
  cdb['c'] #=> nil
37
37
 
38
+ # database is truncated whenever
39
+ # a new writer is opened:
38
40
  cdb['a'] = 'two'
39
41
  cdb['c'] = 'xyz'
40
42
 
@@ -45,8 +47,10 @@ creating and reading {constant databases}[http://cr.yp.to/cdb.html].
45
47
 
46
48
  # update existing database
47
49
  LibCDB::CDB.open('foo.cdb', 'r+') { |cdb|
48
- cdb.store(cdb.to_h)
50
+ # store existing records
51
+ cdb << cdb.to_h
49
52
 
53
+ # and add a new one
50
54
  cdb['d'] = '42'
51
55
 
52
56
  cdb['a'] #=> "two"
@@ -56,10 +60,23 @@ creating and reading {constant databases}[http://cr.yp.to/cdb.html].
56
60
  }
57
61
 
58
62
 
63
+ == PREREQUISITES
64
+
65
+ <b></b>
66
+ * Ruby 1.8.7+ or 1.9+ (see below for details)
67
+ * TinyCDB[http://corpit.ru/mjt/tinycdb.html] headers (not
68
+ needed when installing the fat binary gem on Windows)
69
+
70
+ Debian/Ubuntu:: +libcdb-dev+
71
+ Fedora/SuSE:: +tinycdb-devel+
72
+ Gentoo:: +dev-db/tinycdb+
73
+
74
+
59
75
  == SUPPORTED PLATFORMS
60
76
 
61
- Linux:: 1.8 & 1.9
62
- Windows:: 1.9 only
77
+ <b></b>
78
+ Linux:: 1.8 & 1.9 (Tested on Ubuntu with 1.8.7p302 and 1.9.3p19)
79
+ Windows:: 1.9 only (Tested on XP with 1.9.3p0)
63
80
 
64
81
 
65
82
  == LINKS
@@ -77,6 +94,16 @@ CDB:: http://cr.yp.to/cdb.html
77
94
  * Jens Wille <mailto:jens.wille@uni-koeln.de>
78
95
 
79
96
 
97
+ == CREDITS
98
+
99
+ This project was inspired by ruby-cdb[https://github.com/mbj/ruby-cdb] and
100
+ cdb-full[https://rubygems.org/gems/cdb-full]. The code organization, especially the
101
+ extension part, was modeled after libxml-ruby[https://github.com/xml4r/libxml-ruby].
102
+
103
+ And props to the rake-compiler[http://github.com/luislavena/rake-compiler]
104
+ team for making extension building such a breeze :)
105
+
106
+
80
107
  == LICENSE AND COPYRIGHT
81
108
 
82
109
  Copyright (C) 2012 University of Cologne,
data/TODO CHANGED
@@ -1,4 +1,5 @@
1
1
  * More specs!!
2
2
  * More Documentation!
3
3
  * Atomic updates? (rename after create)
4
+ * Memory efficient way to update an existing database?
4
5
  * Benchmarks?
@@ -2,11 +2,62 @@
2
2
  #define __RUBY_CDB_H__
3
3
 
4
4
  #ifdef HAVE_RUBY_IO_H
5
- #define GetFileFD(fptr) (fptr)->fd
5
+ #define RCDB_GET_FD(fptr) (fptr)->fd
6
6
  #else
7
- #define GetFileFD(fptr) fileno((fptr)->f)
7
+ #define RCDB_GET_FD(fptr) fileno((fptr)->f)
8
8
  #endif
9
9
 
10
+ #define RCDB_GET_STRUCT(what, _struct, obj, ptr) {\
11
+ if (RTEST(rcdb_##what##er_closed_p(obj))) {\
12
+ rb_raise(rb_eIOError, "closed stream");\
13
+ }\
14
+ else {\
15
+ Data_Get_Struct((obj), struct _struct, (ptr));\
16
+ }\
17
+ }
18
+
19
+ #define RCDB_DEFINE_ALLOC(what, _struct) \
20
+ static void \
21
+ rcdb_##what##er_free(void *ptr) {\
22
+ free(ptr);\
23
+ }\
24
+ \
25
+ static VALUE \
26
+ rcdb_##what##er_alloc(VALUE klass) {\
27
+ struct _struct *ptr = ALLOC_N(struct _struct, 1);\
28
+ return Data_Wrap_Struct(klass, NULL, rcdb_##what##er_free, ptr);\
29
+ }
30
+
31
+ #define RCDB_INITIALIZE(what, WHAT, _struct, init) \
32
+ struct _struct *ptr = NULL;\
33
+ rb_io_t *fptr;\
34
+ \
35
+ Check_Type(io, T_FILE);\
36
+ GetOpenFile(io, fptr);\
37
+ \
38
+ rb_io_check_##what##able(fptr);\
39
+ rb_iv_set(self, "@io", io);\
40
+ rb_iv_set(self, "closed", Qfalse);\
41
+ \
42
+ RCDB_##WHAT##ER_GET(self, ptr);\
43
+ \
44
+ if (cdb_##init(ptr, RCDB_GET_FD(fptr)) == -1) {\
45
+ rb_sys_fail(0);\
46
+ }
47
+
48
+ #define RCDB_DEFINE_INSPECT(what) \
49
+ static VALUE \
50
+ rcdb_##what##er_inspect(VALUE self) {\
51
+ VALUE str = rb_call_super(0, NULL);\
52
+ \
53
+ if (RTEST(rcdb_##what##er_closed_p(self))) {\
54
+ rb_funcall(str,\
55
+ rb_intern("insert"), 2, INT2FIX(-2), rb_str_new2(" (closed)"));\
56
+ }\
57
+ \
58
+ return str;\
59
+ }
60
+
10
61
  VALUE cCDB;
11
62
  void rcdb_init_cdb(void);
12
63
 
@@ -1,15 +1,6 @@
1
1
  #include "ruby_libcdb.h"
2
2
 
3
- static void
4
- rcdb_reader_free(void *ptr) {
5
- free(ptr);
6
- }
7
-
8
- static VALUE
9
- rcdb_reader_alloc(VALUE klass) {
10
- struct cdb *cdb = ALLOC_N(struct cdb, 1);
11
- return Data_Wrap_Struct(klass, NULL, rcdb_reader_free, cdb);
12
- }
3
+ RCDB_DEFINE_ALLOC(read, cdb)
13
4
 
14
5
  /*
15
6
  * call-seq:
@@ -31,64 +22,22 @@ rcdb_reader_closed_p(VALUE self) {
31
22
  */
32
23
  static VALUE
33
24
  rcdb_reader_initialize(VALUE self, VALUE io) {
34
- struct cdb *cdb = NULL;
35
- rb_io_t *fptr;
36
-
37
- Check_Type(io, T_FILE);
38
- GetOpenFile(io, fptr);
39
-
40
- rb_io_check_readable(fptr);
41
- rb_iv_set(self, "@io", io);
42
- rb_iv_set(self, "closed", Qfalse);
43
-
44
- Get_CDB_Reader(self, cdb);
45
-
46
- if (cdb_init(cdb, GetFileFD(fptr)) == -1) {
47
- rb_sys_fail(0);
48
- }
49
-
25
+ RCDB_INITIALIZE(read, READ, cdb, init)
50
26
  return self;
51
27
  }
52
28
 
53
- /* Helper method */
54
- static VALUE
55
- rcdb_reader_read_key(struct cdb *cdb) {
56
- size_t len;
57
- VALUE key;
58
-
59
- len = cdb_keylen(cdb);
60
- key = rb_str_buf_new(len);
61
-
62
- cdb_read(cdb, RSTRING_PTR(key), len, cdb_keypos(cdb));
63
- rb_str_set_len(key, len);
64
-
65
- return key;
66
- }
67
-
68
- /* Helper method */
69
- static VALUE
70
- rcdb_reader_read_value(struct cdb *cdb) {
71
- size_t len;
72
- VALUE val;
73
-
74
- len = cdb_datalen(cdb);
75
- val = rb_str_buf_new(len);
76
-
77
- cdb_read(cdb, RSTRING_PTR(val), len, cdb_datapos(cdb));
78
- rb_str_set_len(val, len);
79
-
80
- return val;
81
- }
29
+ RCDB_READER_DEFINE_READ(key)
30
+ RCDB_READER_DEFINE_READ(data)
82
31
 
83
32
  /* Helper method */
84
33
  static VALUE
85
- rcdb_reader_iter_push(VALUE val, VALUE ary) {
34
+ _rcdb_reader_iter_push(VALUE val, VALUE ary) {
86
35
  return rb_ary_push(ary, val);
87
36
  }
88
37
 
89
38
  /* Helper method */
90
39
  static VALUE
91
- rcdb_reader_iter_aset(VALUE pair, VALUE hash) {
40
+ _rcdb_reader_iter_aset(VALUE pair, VALUE hash) {
92
41
  VALUE key = rb_ary_entry(pair, 0), val = rb_ary_entry(pair, 1), old;
93
42
 
94
43
  if (!st_lookup(RHASH_TBL(hash), key, 0)) {
@@ -112,8 +61,8 @@ rcdb_reader_iter_aset(VALUE pair, VALUE hash) {
112
61
 
113
62
  /* Helper method */
114
63
  static VALUE
115
- rcdb_reader_break_equal(VALUE val, VALUE ary) {
116
- if (VALUE_EQUAL(val)) {
64
+ _rcdb_reader_break_equal(VALUE val, VALUE ary) {
65
+ if (RCDB_READER_EQUAL(val)) {
117
66
  rb_ary_store(ary, 0, Qtrue);
118
67
  rb_iter_break();
119
68
  }
@@ -123,8 +72,8 @@ rcdb_reader_break_equal(VALUE val, VALUE ary) {
123
72
 
124
73
  /* Helper method */
125
74
  static VALUE
126
- rcdb_reader_break_equal2(VALUE pair, VALUE ary) {
127
- if (VALUE_EQUAL(rb_ary_entry(pair, 1))) {
75
+ _rcdb_reader_break_equal2(VALUE pair, VALUE ary) {
76
+ if (RCDB_READER_EQUAL(rb_ary_entry(pair, 1))) {
128
77
  rb_ary_store(ary, 0, rb_ary_entry(pair, 0));
129
78
  rb_iter_break();
130
79
  }
@@ -134,7 +83,7 @@ rcdb_reader_break_equal2(VALUE pair, VALUE ary) {
134
83
 
135
84
  /* Helper method */
136
85
  static VALUE
137
- rcdb_reader_break_shift(VALUE val, VALUE ary) {
86
+ _rcdb_reader_break_shift(VALUE val, VALUE ary) {
138
87
  rb_ary_shift(ary);
139
88
  rb_iter_break();
140
89
 
@@ -143,16 +92,14 @@ rcdb_reader_break_shift(VALUE val, VALUE ary) {
143
92
 
144
93
  /* Helper method */
145
94
  static VALUE
146
- rcdb_reader_iter_inc(VALUE val, VALUE ary) {
95
+ _rcdb_reader_iter_inc(VALUE val, VALUE ary) {
147
96
  rb_ary_store(ary, 0, rb_funcall(rb_ary_entry(ary, 0), rb_intern("succ"), 0));
148
97
  return Qnil;
149
98
  }
150
99
 
151
100
  /* Helper method */
152
101
  static VALUE
153
- rcdb_reader_iter_dump(VALUE val, VALUE ary) {
154
- VALUE str = rb_ary_entry(ary, 0);
155
-
102
+ _rcdb_reader_iter_dump(VALUE val, VALUE str) {
156
103
  rb_str_append(str, val);
157
104
  rb_str_cat2(str, "\n");
158
105
 
@@ -161,7 +108,7 @@ rcdb_reader_iter_dump(VALUE val, VALUE ary) {
161
108
 
162
109
  /* Helper method */
163
110
  static VALUE
164
- rcdb_reader_dump_pair(VALUE key, VALUE val) {
111
+ _rcdb_reader_dump_pair(VALUE key, VALUE val) {
165
112
  VALUE str = rb_str_new2("");
166
113
 
167
114
  rb_str_cat2(str, "+");
@@ -178,40 +125,21 @@ rcdb_reader_dump_pair(VALUE key, VALUE val) {
178
125
 
179
126
  /* Helper method */
180
127
  static VALUE
181
- rcdb_reader_yield_dump(VALUE pair, VALUE ary) {
182
- return rb_yield(rcdb_reader_dump_pair(
128
+ _rcdb_reader_yield_dump(VALUE pair, VALUE ary) {
129
+ return rb_yield(_rcdb_reader_dump_pair(
183
130
  rb_ary_entry(pair, 0), rb_ary_entry(pair, 1)));
184
131
  }
185
132
 
186
133
  /* Helper method */
187
134
  static VALUE
188
- rcdb_reader_yield_dump2(VALUE val, VALUE ary) {
189
- return rb_yield(rcdb_reader_dump_pair(rb_ary_entry(ary, 0), val));
135
+ _rcdb_reader_yield_dump2(VALUE val, VALUE ary) {
136
+ return rb_yield(_rcdb_reader_dump_pair(rb_ary_entry(ary, 0), val));
190
137
  }
191
138
 
192
- /* Helper method */
193
- static VALUE
194
- rcdb_reader_call_each(VALUE args) {
195
- CALL_ITERATOR("each")
196
- }
197
-
198
- /* Helper method */
199
- static VALUE
200
- rcdb_reader_call_each_key(VALUE args) {
201
- CALL_ITERATOR("each_key")
202
- }
203
-
204
- /* Helper method */
205
- static VALUE
206
- rcdb_reader_call_each_value(VALUE args) {
207
- CALL_ITERATOR("each_value")
208
- }
209
-
210
- /* Helper method */
211
- static VALUE
212
- rcdb_reader_call_each_dump(VALUE args) {
213
- CALL_ITERATOR("each_dump")
214
- }
139
+ RCDB_READER_DEFINE_CALL(each)
140
+ RCDB_READER_DEFINE_CALL(each_key)
141
+ RCDB_READER_DEFINE_CALL(each_value)
142
+ RCDB_READER_DEFINE_CALL(each_dump)
215
143
 
216
144
  /*
217
145
  * call-seq:
@@ -235,7 +163,7 @@ rcdb_reader_each(int argc, VALUE *argv, VALUE self) {
235
163
 
236
164
  RETURN_ENUMERATOR(self, argc, argv);
237
165
 
238
- Get_CDB_Reader(self, cdb);
166
+ RCDB_READER_GET(self, cdb);
239
167
 
240
168
  if (rb_scan_args(argc, argv, "01", &key) == 1 && !NIL_P(key)) {
241
169
  StringValue(key);
@@ -245,7 +173,7 @@ rcdb_reader_each(int argc, VALUE *argv, VALUE self) {
245
173
  }
246
174
 
247
175
  while (cdb_findnext(&cdbf) > 0) {
248
- rb_yield(rcdb_reader_read_value(cdb));
176
+ rb_yield(_rcdb_reader_read_data(cdb));
249
177
  }
250
178
  }
251
179
  else {
@@ -253,8 +181,8 @@ rcdb_reader_each(int argc, VALUE *argv, VALUE self) {
253
181
 
254
182
  while (cdb_seqnext(&cdbp, cdb) > 0) {
255
183
  rb_yield(rb_ary_new3(2,
256
- rcdb_reader_read_key(cdb),
257
- rcdb_reader_read_value(cdb)));
184
+ _rcdb_reader_read_key(cdb),
185
+ _rcdb_reader_read_data(cdb)));
258
186
  }
259
187
  }
260
188
 
@@ -273,7 +201,7 @@ rcdb_reader_each(int argc, VALUE *argv, VALUE self) {
273
201
  static VALUE
274
202
  rcdb_reader_each_dump(int argc, VALUE *argv, VALUE self) {
275
203
  VALUE key, args = rb_ary_new3(1, self), ary = rb_ary_new();
276
- VALUE (*block)(ANYARGS) = rcdb_reader_yield_dump;
204
+ VALUE (*block)(ANYARGS) = _rcdb_reader_yield_dump;
277
205
 
278
206
  if (argc > 1) {
279
207
  rb_raise(rb_eArgError, "wrong number of arguments (%d for 0-1)", argc);
@@ -285,10 +213,10 @@ rcdb_reader_each_dump(int argc, VALUE *argv, VALUE self) {
285
213
  rb_ary_push(ary, key);
286
214
  rb_ary_push(args, key);
287
215
 
288
- block = rcdb_reader_yield_dump2;
216
+ block = _rcdb_reader_yield_dump2;
289
217
  }
290
218
 
291
- rb_iterate(rcdb_reader_call_each, args, block, ary);
219
+ rb_iterate(_rcdb_reader_call_each, args, block, ary);
292
220
 
293
221
  return self;
294
222
  }
@@ -307,11 +235,11 @@ rcdb_reader_each_key(VALUE self) {
307
235
  unsigned cdbp;
308
236
  VALUE key, hash = rb_hash_new();
309
237
 
310
- Get_CDB_Reader(self, cdb);
238
+ RCDB_READER_GET(self, cdb);
311
239
  cdb_seqinit(&cdbp, cdb);
312
240
 
313
241
  while (cdb_seqnext(&cdbp, cdb) > 0) {
314
- if (!st_lookup(RHASH_TBL(hash), key = rcdb_reader_read_key(cdb), 0)) {
242
+ if (!st_lookup(RHASH_TBL(hash), key = _rcdb_reader_read_key(cdb), 0)) {
315
243
  rb_hash_aset(hash, key, Qtrue);
316
244
  rb_yield(key);
317
245
  }
@@ -333,11 +261,11 @@ rcdb_reader_each_value(VALUE self) {
333
261
  struct cdb *cdb = NULL;
334
262
  unsigned cdbp;
335
263
 
336
- Get_CDB_Reader(self, cdb);
264
+ RCDB_READER_GET(self, cdb);
337
265
  cdb_seqinit(&cdbp, cdb);
338
266
 
339
267
  while (cdb_seqnext(&cdbp, cdb) > 0) {
340
- rb_yield(rcdb_reader_read_value(cdb));
268
+ rb_yield(_rcdb_reader_read_data(cdb));
341
269
  }
342
270
 
343
271
  return self;
@@ -351,12 +279,10 @@ rcdb_reader_each_value(VALUE self) {
351
279
  */
352
280
  static VALUE
353
281
  rcdb_reader_fetch(VALUE self, VALUE key) {
354
- VALUE ary = rb_ary_new();
355
-
356
- rb_iterate(rcdb_reader_call_each,
357
- rb_ary_new3(2, self, key), rcdb_reader_iter_push, ary);
282
+ RCDB_READER_ITERATE0(each, iter_push,
283
+ rb_ary_new(), rb_ary_new3(2, self, key))
358
284
 
359
- return ary;
285
+ return arg;
360
286
  }
361
287
 
362
288
  /*
@@ -371,10 +297,10 @@ rcdb_reader_fetch_first(VALUE self, VALUE key) {
371
297
  VALUE val = Qnil;
372
298
 
373
299
  StringValue(key);
374
- Get_CDB_Reader(self, cdb);
300
+ RCDB_READER_GET(self, cdb);
375
301
 
376
302
  if (cdb_find(cdb, RSTRING_PTR(key), RSTRING_LEN(key)) > 0) {
377
- val = rcdb_reader_read_value(cdb);
303
+ val = _rcdb_reader_read_data(cdb);
378
304
  }
379
305
 
380
306
  return val;
@@ -395,7 +321,7 @@ rcdb_reader_fetch_last(VALUE self, VALUE key) {
395
321
  size_t len = 0;
396
322
 
397
323
  StringValue(key);
398
- Get_CDB_Reader(self, cdb);
324
+ RCDB_READER_GET(self, cdb);
399
325
 
400
326
  if (cdb_findinit(&cdbf, cdb, RSTRING_PTR(key), RSTRING_LEN(key)) == -1) {
401
327
  rb_sys_fail(0);
@@ -423,12 +349,7 @@ rcdb_reader_fetch_last(VALUE self, VALUE key) {
423
349
  */
424
350
  static VALUE
425
351
  rcdb_reader_keys(VALUE self) {
426
- VALUE ary = rb_ary_new();
427
-
428
- rb_iterate(rcdb_reader_call_each_key,
429
- rb_ary_new3(1, self), rcdb_reader_iter_push, ary);
430
-
431
- return ary;
352
+ RCDB_READER_ITERATE(each_key, iter_push, rb_ary_new())
432
353
  }
433
354
 
434
355
  /*
@@ -439,12 +360,7 @@ rcdb_reader_keys(VALUE self) {
439
360
  */
440
361
  static VALUE
441
362
  rcdb_reader_values(VALUE self) {
442
- VALUE ary = rb_ary_new();
443
-
444
- rb_iterate(rcdb_reader_call_each_value,
445
- rb_ary_new3(1, self), rcdb_reader_iter_push, ary);
446
-
447
- return ary;
363
+ RCDB_READER_ITERATE(each_value, iter_push, rb_ary_new())
448
364
  }
449
365
 
450
366
  /*
@@ -473,8 +389,8 @@ rcdb_reader_values_at(int argc, VALUE *argv, VALUE self) {
473
389
  */
474
390
  static VALUE
475
391
  rcdb_reader_has_key_p(VALUE self, VALUE key) {
476
- VALUE ary = rb_ary_new3(2, Qfalse, key);
477
- ITER_RESULT(rcdb_reader_call_each_key, rcdb_reader_break_equal)
392
+ RCDB_READER_ITERATE_ARY(each_key, break_equal,
393
+ rb_ary_new3(2, Qfalse, key))
478
394
  }
479
395
 
480
396
  /*
@@ -485,8 +401,8 @@ rcdb_reader_has_key_p(VALUE self, VALUE key) {
485
401
  */
486
402
  static VALUE
487
403
  rcdb_reader_has_value_p(VALUE self, VALUE val) {
488
- VALUE ary = rb_ary_new3(2, Qfalse, val);
489
- ITER_RESULT(rcdb_reader_call_each_value, rcdb_reader_break_equal)
404
+ RCDB_READER_ITERATE_ARY(each_value, break_equal,
405
+ rb_ary_new3(2, Qfalse, val))
490
406
  }
491
407
 
492
408
  /*
@@ -498,8 +414,8 @@ rcdb_reader_has_value_p(VALUE self, VALUE val) {
498
414
  */
499
415
  static VALUE
500
416
  rcdb_reader_key(VALUE self, VALUE val) {
501
- VALUE ary = rb_ary_new3(2, Qnil, val);
502
- ITER_RESULT(rcdb_reader_call_each, rcdb_reader_break_equal2)
417
+ RCDB_READER_ITERATE_ARY(each, break_equal2,
418
+ rb_ary_new3(2, Qnil, val))
503
419
  }
504
420
 
505
421
  /*
@@ -510,8 +426,8 @@ rcdb_reader_key(VALUE self, VALUE val) {
510
426
  */
511
427
  static VALUE
512
428
  rcdb_reader_empty_p(VALUE self) {
513
- VALUE ary = rb_ary_new3(2, Qtrue, Qfalse);
514
- ITER_RESULT(rcdb_reader_call_each_key, rcdb_reader_break_shift)
429
+ RCDB_READER_ITERATE_ARY(each_key, break_shift,
430
+ rb_ary_new3(2, Qtrue, Qfalse))
515
431
  }
516
432
 
517
433
  /*
@@ -522,8 +438,8 @@ rcdb_reader_empty_p(VALUE self) {
522
438
  */
523
439
  static VALUE
524
440
  rcdb_reader_size(VALUE self) {
525
- VALUE ary = rb_ary_new3(1, INT2FIX(0));
526
- ITER_RESULT(rcdb_reader_call_each_key, rcdb_reader_iter_inc)
441
+ RCDB_READER_ITERATE_ARY(each_key, iter_inc,
442
+ rb_ary_new3(1, INT2FIX(0)))
527
443
  }
528
444
 
529
445
  /*
@@ -538,7 +454,7 @@ rcdb_reader_total(VALUE self) {
538
454
  unsigned cdbp;
539
455
  long i = 0;
540
456
 
541
- Get_CDB_Reader(self, cdb);
457
+ RCDB_READER_GET(self, cdb);
542
458
  cdb_seqinit(&cdbp, cdb);
543
459
 
544
460
  while (cdb_seqnext(&cdbp, cdb) > 0) {
@@ -556,8 +472,7 @@ rcdb_reader_total(VALUE self) {
556
472
  */
557
473
  static VALUE
558
474
  rcdb_reader_dump(VALUE self) {
559
- VALUE ary = rb_ary_new3(1, rb_str_new2(""));
560
- ITER_RESULT(rcdb_reader_call_each_dump, rcdb_reader_iter_dump)
475
+ RCDB_READER_ITERATE(each_dump, iter_dump, rb_str_new2(""))
561
476
  }
562
477
 
563
478
  /*
@@ -571,12 +486,7 @@ rcdb_reader_dump(VALUE self) {
571
486
  */
572
487
  static VALUE
573
488
  rcdb_reader_to_h(VALUE self) {
574
- VALUE hash = rb_hash_new();
575
-
576
- rb_iterate(rcdb_reader_call_each,
577
- rb_ary_new3(1, self), rcdb_reader_iter_aset, hash);
578
-
579
- return hash;
489
+ RCDB_READER_ITERATE(each, iter_aset, rb_hash_new())
580
490
  }
581
491
 
582
492
  /*
@@ -589,12 +499,7 @@ rcdb_reader_to_h(VALUE self) {
589
499
  */
590
500
  static VALUE
591
501
  rcdb_reader_to_a(VALUE self) {
592
- VALUE ary = rb_ary_new();
593
-
594
- rb_iterate(rcdb_reader_call_each,
595
- rb_ary_new3(1, self), rcdb_reader_iter_push, ary);
596
-
597
- return ary;
502
+ RCDB_READER_ITERATE(each, iter_push, rb_ary_new())
598
503
  }
599
504
 
600
505
  /*
@@ -611,7 +516,7 @@ rcdb_reader_close(VALUE self) {
611
516
  return Qnil;
612
517
  }
613
518
 
614
- Get_CDB_Reader(self, cdb);
519
+ RCDB_READER_GET(self, cdb);
615
520
  rb_iv_set(self, "closed", Qtrue);
616
521
 
617
522
  rb_io_close(rb_iv_get(self, "@io"));
@@ -619,18 +524,7 @@ rcdb_reader_close(VALUE self) {
619
524
  return Qnil;
620
525
  }
621
526
 
622
- /* :nodoc: */
623
- static VALUE
624
- rcdb_reader_inspect(VALUE self) {
625
- VALUE str = rb_call_super(0, NULL);
626
-
627
- if (RTEST(rcdb_reader_closed_p(self))) {
628
- rb_funcall(str,
629
- rb_intern("insert"), 2, INT2FIX(-2), rb_str_new2(" (closed)"));
630
- }
631
-
632
- return str;
633
- }
527
+ RCDB_DEFINE_INSPECT(read)
634
528
 
635
529
  void
636
530
  rcdb_init_reader(void) {
@@ -1,29 +1,49 @@
1
1
  #ifndef __RCDB_READER_H__
2
2
  #define __RCDB_READER_H__
3
3
 
4
- #define Get_CDB_Reader(obj, var) {\
5
- if (RTEST(rcdb_reader_closed_p(obj))) {\
6
- rb_raise(rb_eRuntimeError, "closed stream");\
7
- }\
8
- else {\
9
- Data_Get_Struct((obj), struct cdb, (var));\
10
- }\
11
- }
4
+ #define RCDB_READER_GET(obj, ptr) RCDB_GET_STRUCT(read, cdb, obj, ptr)
12
5
 
13
- #define CALL_ITERATOR(iter) {\
6
+ #define RCDB_READER_DEFINE_CALL(iter) \
7
+ static VALUE \
8
+ _rcdb_reader_call_##iter(VALUE args) {\
14
9
  VALUE self = rb_ary_shift(args);\
15
- return rb_funcall2(self, rb_intern(iter),\
10
+ return rb_funcall2(self, rb_intern(#iter),\
16
11
  RARRAY_LEN(args), RARRAY_PTR(args));\
17
12
  }
18
13
 
19
- #define ITER_RESULT(method, block) {\
20
- rb_iterate(method, rb_ary_new3(1, self), block, ary);\
21
- return rb_ary_entry(ary, 0);\
22
- }
14
+ #define RCDB_READER_ITERATE0(method, block, arg1, arg2) \
15
+ VALUE arg = arg1;\
16
+ rb_iterate(_rcdb_reader_call_##method, arg2, _rcdb_reader_##block, arg);
17
+
18
+ #define RCDB_READER_ITERATE1(method, block, arg1) \
19
+ RCDB_READER_ITERATE0(method, block, arg1, rb_ary_new3(1, self))
20
+
21
+ #define RCDB_READER_ITERATE(method, block, arg1) \
22
+ RCDB_READER_ITERATE1(method, block, arg1)\
23
+ return arg;
23
24
 
24
- #define VALUE_EQUAL(val) \
25
+ #define RCDB_READER_ITERATE_ARY(method, block, arg1) \
26
+ RCDB_READER_ITERATE1(method, block, arg1)\
27
+ return rb_ary_entry(arg, 0);
28
+
29
+ #define RCDB_READER_EQUAL(val) \
25
30
  RTEST(rb_funcall((val), rb_intern("=="), 1, rb_ary_entry(ary, 1)))
26
31
 
32
+ #define RCDB_READER_DEFINE_READ(what) \
33
+ static VALUE \
34
+ _rcdb_reader_read_##what(struct cdb *cdb) {\
35
+ size_t len;\
36
+ VALUE ret;\
37
+ \
38
+ len = cdb_##what##len(cdb);\
39
+ ret = rb_str_buf_new(len);\
40
+ \
41
+ cdb_read(cdb, RSTRING_PTR(ret), len, cdb_##what##pos(cdb));\
42
+ rb_str_set_len(ret, len);\
43
+ \
44
+ return ret;\
45
+ }
46
+
27
47
  VALUE cCDBReader;
28
48
  void rcdb_init_reader(void);
29
49
 
@@ -1,15 +1,6 @@
1
1
  #include "ruby_libcdb.h"
2
2
 
3
- static void
4
- rcdb_writer_free(void *ptr) {
5
- free(ptr);
6
- }
7
-
8
- static VALUE
9
- rcdb_writer_alloc(VALUE klass) {
10
- struct cdb_make *cdbm = ALLOC_N(struct cdb_make, 1);
11
- return Data_Wrap_Struct(klass, NULL, rcdb_writer_free, cdbm);
12
- }
3
+ RCDB_DEFINE_ALLOC(writ, cdb_make)
13
4
 
14
5
  /*
15
6
  * call-seq:
@@ -32,23 +23,9 @@ rcdb_writer_closed_p(VALUE self) {
32
23
  */
33
24
  static VALUE
34
25
  rcdb_writer_initialize(VALUE self, VALUE io) {
35
- struct cdb_make *cdbm = NULL;
36
- rb_io_t *fptr;
37
-
38
- Check_Type(io, T_FILE);
39
- GetOpenFile(io, fptr);
40
-
41
- rb_io_check_writable(fptr);
42
- rb_iv_set(self, "@io", io);
43
- rb_iv_set(self, "closed", Qfalse);
44
-
45
- Get_CDB_Writer(self, cdbm);
26
+ RCDB_INITIALIZE(writ, WRIT, cdb_make, make_start)
46
27
 
47
- if (cdb_make_start(cdbm, GetFileFD(fptr)) == -1) {
48
- rb_sys_fail(0);
49
- }
50
-
51
- if (lseek(cdb_fileno(cdbm), 0, SEEK_SET) == -1) {
28
+ if (lseek(cdb_fileno(ptr), 0, SEEK_SET) == -1) {
52
29
  rb_sys_fail(0);
53
30
  }
54
31
 
@@ -137,7 +114,7 @@ rcdb_writer_put(int argc, VALUE *argv, VALUE self, enum cdb_put_mode mode) {
137
114
  VALUE arg, val;
138
115
  long i;
139
116
 
140
- Get_CDB_Writer(self, cdbm);
117
+ RCDB_WRITER_GET(self, cdbm);
141
118
 
142
119
  switch (argc) {
143
120
  case 1:
@@ -256,7 +233,7 @@ rcdb_writer_close(VALUE self) {
256
233
  return Qnil;
257
234
  }
258
235
 
259
- Get_CDB_Writer(self, cdbm);
236
+ RCDB_WRITER_GET(self, cdbm);
260
237
  rb_iv_set(self, "closed", Qtrue);
261
238
 
262
239
  if (cdb_make_finish(cdbm) == -1) {
@@ -268,18 +245,7 @@ rcdb_writer_close(VALUE self) {
268
245
  return Qnil;
269
246
  }
270
247
 
271
- /* :nodoc: */
272
- static VALUE
273
- rcdb_writer_inspect(VALUE self) {
274
- VALUE str = rb_call_super(0, NULL);
275
-
276
- if (RTEST(rcdb_writer_closed_p(self))) {
277
- rb_funcall(str,
278
- rb_intern("insert"), 2, INT2FIX(-2), rb_str_new2(" (closed)"));
279
- }
280
-
281
- return str;
282
- }
248
+ RCDB_DEFINE_INSPECT(writ)
283
249
 
284
250
  void rcdb_init_writer(void) {
285
251
  /*
@@ -296,6 +262,7 @@ void rcdb_init_writer(void) {
296
262
  rb_define_method(cCDBWriter, "replace", rcdb_writer_replace, -1);
297
263
  rb_define_method(cCDBWriter, "store", rcdb_writer_store, -1);
298
264
 
265
+ rb_define_alias(cCDBWriter, "<<", "store");
299
266
  rb_define_alias(cCDBWriter, "[]=", "replace");
300
267
  rb_define_alias(cCDBWriter, "add", "store");
301
268
  }
@@ -1,14 +1,7 @@
1
1
  #ifndef __RCDB_WRITER_H__
2
2
  #define __RCDB_WRITER_H__
3
3
 
4
- #define Get_CDB_Writer(obj, var) {\
5
- if (RTEST(rcdb_writer_closed_p(obj))) {\
6
- rb_raise(rb_eRuntimeError, "closed stream");\
7
- }\
8
- else {\
9
- Data_Get_Struct((obj), struct cdb_make, (var));\
10
- }\
11
- }
4
+ #define RCDB_WRITER_GET(obj, ptr) RCDB_GET_STRUCT(writ, cdb_make, obj, ptr)
12
5
 
13
6
  VALUE cCDBWriter;
14
7
  void rcdb_init_writer(void);
Binary file
Binary file
@@ -6,7 +6,7 @@ module LibCDB
6
6
 
7
7
  MAJOR = 0
8
8
  MINOR = 0
9
- TINY = 1
9
+ TINY = 2
10
10
 
11
11
  class << self
12
12
 
data/lib/libcdb.rb CHANGED
@@ -13,8 +13,8 @@ module LibCDB
13
13
 
14
14
  extend Forwardable
15
15
 
16
- MODE_READ = 'r' # :nodoc:
17
- MODE_WRITE = 'w' # :nodoc:
16
+ MODE_READ = 'r' # :nodoc:
17
+ MODE_WRITE = 'w' # :nodoc:
18
18
 
19
19
  class << self
20
20
 
@@ -133,9 +133,9 @@ module LibCDB
133
133
  :fetch_first, :fetch_last, :get, :has_key?,
134
134
  :has_value?, :include?, :key, :key?, :keys,
135
135
  :length, :member?, :rget, :size, :to_a,
136
- :to_h, :value?, :values, :values_at
136
+ :to_h, :total, :value?, :values, :values_at
137
137
 
138
- def_delegators :writer, :[]=, :add, :insert, :replace, :store
138
+ def_delegators :writer, :<<, :[]=, :add, :insert, :replace, :store
139
139
 
140
140
  # call-seq:
141
141
  # cdb.read? -> true | false
@@ -55,6 +55,18 @@ describe LibCDB::CDB::Reader do
55
55
  @db.size.should == 0
56
56
  end
57
57
 
58
+ it "should know its total" do
59
+ @db.total.should == 0
60
+ end
61
+
62
+ it "should know its keys" do
63
+ @db.keys.should == []
64
+ end
65
+
66
+ it "should know its values" do
67
+ @db.values.should == []
68
+ end
69
+
58
70
  it "should know if it doesn't have a key" do
59
71
  @db.should_not have_key('key3')
60
72
  end
@@ -63,6 +75,18 @@ describe LibCDB::CDB::Reader do
63
75
  @db.should_not have_value('value3.2')
64
76
  end
65
77
 
78
+ it "should dump itself" do
79
+ @db.dump.should == ''
80
+ end
81
+
82
+ it "should convert itself into a hash" do
83
+ @db.to_h.should == {}
84
+ end
85
+
86
+ it "should convert itself into an array" do
87
+ @db.to_a.should == []
88
+ end
89
+
66
90
  end
67
91
 
68
92
  describe "non-empty" do
@@ -87,6 +111,18 @@ describe LibCDB::CDB::Reader do
87
111
  @db.size.should == 11
88
112
  end
89
113
 
114
+ it "should know its total" do
115
+ @db.total.should == 56
116
+ end
117
+
118
+ it "should know its keys" do
119
+ @db.keys.should == TEST_DATA.map { |k, _| k }.uniq
120
+ end
121
+
122
+ it "should know its values" do
123
+ @db.values.should == TEST_DATA.map { |_, v| v }.flatten
124
+ end
125
+
90
126
  it "should know if it has a key" do
91
127
  @db.should have_key('key3')
92
128
  end
@@ -137,6 +173,24 @@ describe LibCDB::CDB::Reader do
137
173
  @db.key('value33.22').should be_nil
138
174
  end
139
175
 
176
+ it "should dump records for key" do
177
+ d = []
178
+ @db.each_dump('key3') { |e| d << e }
179
+ d.should == %w[+4,8:key3->value3.1 +4,8:key3->value3.2 +4,8:key3->value3.3]
180
+ end
181
+
182
+ it "should convert itself into a hash" do
183
+ h = {}
184
+ TEST_DATA.each { |k, v| h[k] = v.size > 1 ? v : v.first }
185
+ @db.to_h.should == h
186
+ end
187
+
188
+ it "should convert itself into an array" do
189
+ a = []
190
+ TEST_DATA.each { |k, v| v.each { |w| a << [k, w] } }
191
+ @db.to_a.should == a
192
+ end
193
+
140
194
  end
141
195
 
142
196
  end
data/spec/spec_helper.rb CHANGED
@@ -8,8 +8,8 @@ RSpec.configure { |config|
8
8
  TEST_DATA = {}
9
9
 
10
10
  1.upto(10) { |i|
11
- val = TEST_DATA[key = "key#{i}"] = []
12
- 1.upto(i) { |j| val << "value#{i}.#{j}" }
11
+ v = TEST_DATA["key#{i}"] = []
12
+ 1.upto(i) { |j| v << "value#{i}.#{j}" }
13
13
  }
14
14
 
15
15
  TEST_DATA['a' * 1024] = Array('b' * 1024 ** 2)
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: libcdb-ruby
3
3
  version: !ruby/object:Gem::Version
4
- hash: 29
4
+ hash: 27
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
8
  - 0
9
- - 1
10
- version: 0.0.1
9
+ - 2
10
+ version: 0.0.2
11
11
  platform: x86-mswin32-60
12
12
  authors:
13
13
  - Jens Wille
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2012-01-18 00:00:00 Z
18
+ date: 2012-01-20 00:00:00 Z
19
19
  dependencies: []
20
20
 
21
21
  description: Ruby bindings for CDB Constant Databases.
@@ -63,13 +63,13 @@ licenses: []
63
63
 
64
64
  post_install_message:
65
65
  rdoc_options:
66
- - --charset
67
- - UTF-8
68
- - --title
69
- - libcdb-ruby Application documentation (v0.0.1)
70
66
  - --main
71
67
  - README
72
68
  - --all
69
+ - --charset
70
+ - UTF-8
71
+ - --title
72
+ - libcdb-ruby Application documentation (v0.0.2)
73
73
  - --line-numbers
74
74
  require_paths:
75
75
  - lib