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

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