Ruby  2.1.10p492(2016-04-01revision54464)
dbm.c
Go to the documentation of this file.
1 /************************************************
2 
3  dbm.c -
4 
5  $Author: nobu $
6  created at: Mon Jan 24 15:59:52 JST 1994
7 
8  Copyright (C) 1995-2001 Yukihiro Matsumoto
9 
10 ************************************************/
11 
12 #include "ruby.h"
13 
14 #ifdef HAVE_CDEFS_H
15 # include <cdefs.h>
16 #endif
17 #ifdef HAVE_SYS_CDEFS_H
18 # include <sys/cdefs.h>
19 #endif
20 #include DBM_HDR
21 #include <fcntl.h>
22 #include <errno.h>
23 
24 #define DSIZE_TYPE TYPEOF_DATUM_DSIZE
25 #if SIZEOF_DATUM_DSIZE > SIZEOF_INT
26 # define RSTRING_DSIZE(s) RSTRING_LEN(s)
27 # define TOO_LONG(n) 0
28 #else
29 # define RSTRING_DSIZE(s) RSTRING_LENINT(s)
30 # define TOO_LONG(n) ((long)(+(DSIZE_TYPE)(n)) != (n))
31 #endif
32 
34 
35 #define RUBY_DBM_RW_BIT 0x20000000
36 
37 struct dbmdata {
38  long di_size;
40 };
41 
42 static void
44 {
45  rb_raise(rb_eDBMError, "closed DBM file");
46 }
47 
48 #define GetDBM(obj, dbmp) {\
49  Data_Get_Struct((obj), struct dbmdata, (dbmp));\
50  if ((dbmp) == 0) closed_dbm();\
51  if ((dbmp)->di_dbm == 0) closed_dbm();\
52 }
53 
54 #define GetDBM2(obj, data, dbm) {\
55  GetDBM((obj), (data));\
56  (dbm) = dbmp->di_dbm;\
57 }
58 
59 static void
60 free_dbm(struct dbmdata *dbmp)
61 {
62  if (dbmp) {
63  if (dbmp->di_dbm) dbm_close(dbmp->di_dbm);
64  xfree(dbmp);
65  }
66 }
67 
68 /*
69  * call-seq:
70  * dbm.close
71  *
72  * Closes the database.
73  */
74 static VALUE
76 {
77  struct dbmdata *dbmp;
78 
79  GetDBM(obj, dbmp);
80  dbm_close(dbmp->di_dbm);
81  dbmp->di_dbm = 0;
82 
83  return Qnil;
84 }
85 
86 /*
87  * call-seq:
88  * dbm.closed? -> true or false
89  *
90  * Returns true if the database is closed, false otherwise.
91  */
92 static VALUE
94 {
95  struct dbmdata *dbmp;
96 
97  Data_Get_Struct(obj, struct dbmdata, dbmp);
98  if (dbmp == 0)
99  return Qtrue;
100  if (dbmp->di_dbm == 0)
101  return Qtrue;
102 
103  return Qfalse;
104 }
105 
106 static VALUE
108 {
109  return Data_Wrap_Struct(klass, 0, free_dbm, 0);
110 }
111 
112 /*
113  * call-seq:
114  * DBM.new(filename[, mode[, flags]]) -> dbm
115  *
116  * Open a dbm database with the specified name, which can include a directory
117  * path. Any file extensions needed will be supplied automatically by the dbm
118  * library. For example, Berkeley DB appends '.db', and GNU gdbm uses two
119  * physical files with extensions '.dir' and '.pag'.
120  *
121  * The mode should be an integer, as for Unix chmod.
122  *
123  * Flags should be one of READER, WRITER, WRCREAT or NEWDB.
124  */
125 static VALUE
127 {
128  volatile VALUE file;
129  VALUE vmode, vflags;
130  DBM *dbm;
131  struct dbmdata *dbmp;
132  int mode, flags = 0;
133 
134  if (rb_scan_args(argc, argv, "12", &file, &vmode, &vflags) == 1) {
135  mode = 0666; /* default value */
136  }
137  else if (NIL_P(vmode)) {
138  mode = -1; /* return nil if DB not exist */
139  }
140  else {
141  mode = NUM2INT(vmode);
142  }
143 
144  if (!NIL_P(vflags))
145  flags = NUM2INT(vflags);
146 
147  FilePathValue(file);
148 
149  /*
150  * Note:
151  * gdbm 1.10 works with O_CLOEXEC. gdbm 1.9.1 silently ignore it.
152  */
153 #ifndef O_CLOEXEC
154 # define O_CLOEXEC 0
155 #endif
156 
157  if (flags & RUBY_DBM_RW_BIT) {
158  flags &= ~RUBY_DBM_RW_BIT;
159  dbm = dbm_open(RSTRING_PTR(file), flags|O_CLOEXEC, mode);
160  }
161  else {
162  dbm = 0;
163  if (mode >= 0) {
164  dbm = dbm_open(RSTRING_PTR(file), O_RDWR|O_CREAT|O_CLOEXEC, mode);
165  }
166  if (!dbm) {
167  dbm = dbm_open(RSTRING_PTR(file), O_RDWR|O_CLOEXEC, 0);
168  }
169  if (!dbm) {
170  dbm = dbm_open(RSTRING_PTR(file), O_RDONLY|O_CLOEXEC, 0);
171  }
172  }
173 
174  if (dbm) {
175  /*
176  * History of dbm_pagfno() and dbm_dirfno() in ndbm and its compatibles.
177  * (dbm_pagfno() and dbm_dirfno() is not standardized.)
178  *
179  * 1986: 4.3BSD provides ndbm.
180  * It provides dbm_pagfno() and dbm_dirfno() as macros.
181  * 1991: gdbm-1.5 provides them as functions.
182  * They returns a same descriptor.
183  * (Earlier releases may have the functions too.)
184  * 1991: Net/2 provides Berkeley DB.
185  * It doesn't provide dbm_pagfno() and dbm_dirfno().
186  * 1992: 4.4BSD Alpha provides Berkeley DB with dbm_dirfno() as a function.
187  * dbm_pagfno() is a macro as DBM_PAGFNO_NOT_AVAILABLE.
188  * 1997: Berkeley DB 2.0 is released by Sleepycat Software, Inc.
189  * It defines dbm_pagfno() and dbm_dirfno() as macros.
190  * 2011: gdbm-1.9 creates a separate dir file.
191  * dbm_pagfno() and dbm_dirfno() returns different descriptors.
192  */
193 #if defined(HAVE_DBM_PAGFNO)
194  rb_fd_fix_cloexec(dbm_pagfno(dbm));
195 #endif
196 #if defined(HAVE_DBM_DIRFNO)
197  rb_fd_fix_cloexec(dbm_dirfno(dbm));
198 #endif
199 
200 #if defined(RUBYDBM_DB_HEADER) && defined(HAVE_TYPE_DBC)
201  /* Disable Berkeley DB error messages such as:
202  * DB->put: attempt to modify a read-only database */
203  ((DBC*)dbm)->dbp->set_errfile(((DBC*)dbm)->dbp, NULL);
204 #endif
205  }
206 
207  if (!dbm) {
208  if (mode == -1) return Qnil;
209  rb_sys_fail_str(file);
210  }
211 
212  dbmp = ALLOC(struct dbmdata);
213  DATA_PTR(obj) = dbmp;
214  dbmp->di_dbm = dbm;
215  dbmp->di_size = -1;
216 
217  return obj;
218 }
219 
220 /*
221  * call-seq:
222  * DBM.open(filename[, mode[, flags]]) -> dbm
223  * DBM.open(filename[, mode[, flags]]) {|dbm| block}
224  *
225  * Open a dbm database and yields it if a block is given. See also
226  * <code>DBM.new</code>.
227  */
228 static VALUE
230 {
231  VALUE obj = Data_Wrap_Struct(klass, 0, free_dbm, 0);
232 
233  if (NIL_P(fdbm_initialize(argc, argv, obj))) {
234  return Qnil;
235  }
236 
237  if (rb_block_given_p()) {
238  return rb_ensure(rb_yield, obj, fdbm_close, obj);
239  }
240 
241  return obj;
242 }
243 
244 static VALUE
245 fdbm_fetch(VALUE obj, VALUE keystr, VALUE ifnone)
246 {
247  datum key, value;
248  struct dbmdata *dbmp;
249  DBM *dbm;
250  long len;
251 
252  ExportStringValue(keystr);
253  len = RSTRING_LEN(keystr);
254  if (TOO_LONG(len)) goto not_found;
255  key.dptr = RSTRING_PTR(keystr);
256  key.dsize = (DSIZE_TYPE)len;
257 
258  GetDBM2(obj, dbmp, dbm);
259  value = dbm_fetch(dbm, key);
260  if (value.dptr == 0) {
261  not_found:
262  if (ifnone == Qnil && rb_block_given_p())
263  return rb_yield(rb_tainted_str_new(key.dptr, key.dsize));
264  return ifnone;
265  }
266  return rb_tainted_str_new(value.dptr, value.dsize);
267 }
268 
269 /*
270  * call-seq:
271  * dbm[key] -> string value or nil
272  *
273  * Return a value from the database by locating the key string
274  * provided. If the key is not found, returns nil.
275  */
276 static VALUE
278 {
279  return fdbm_fetch(obj, keystr, Qnil);
280 }
281 
282 /*
283  * call-seq:
284  * dbm.fetch(key[, ifnone]) -> value
285  *
286  * Return a value from the database by locating the key string
287  * provided. If the key is not found, returns +ifnone+. If +ifnone+
288  * is not given, raises IndexError.
289  */
290 static VALUE
292 {
293  VALUE keystr, valstr, ifnone;
294 
295  rb_scan_args(argc, argv, "11", &keystr, &ifnone);
296  valstr = fdbm_fetch(obj, keystr, ifnone);
297  if (argc == 1 && !rb_block_given_p() && NIL_P(valstr))
298  rb_raise(rb_eIndexError, "key not found");
299 
300  return valstr;
301 }
302 
303 /*
304  * call-seq:
305  * dbm.key(value) -> string
306  *
307  * Returns the key for the specified value.
308  */
309 static VALUE
311 {
312  datum key, val;
313  struct dbmdata *dbmp;
314  DBM *dbm;
315  long len;
316 
317  ExportStringValue(valstr);
318  len = RSTRING_LEN(valstr);
319  if (TOO_LONG(len)) return Qnil;
320  val.dptr = RSTRING_PTR(valstr);
321  val.dsize = (DSIZE_TYPE)len;
322 
323  GetDBM2(obj, dbmp, dbm);
324  for (key = dbm_firstkey(dbm); key.dptr; key = dbm_nextkey(dbm)) {
325  val = dbm_fetch(dbm, key);
326  if ((long)val.dsize == RSTRING_LEN(valstr) &&
327  memcmp(val.dptr, RSTRING_PTR(valstr), val.dsize) == 0) {
328  return rb_tainted_str_new(key.dptr, key.dsize);
329  }
330  }
331  return Qnil;
332 }
333 
334 /* :nodoc: */
335 static VALUE
337 {
338  rb_warn("DBM#index is deprecated; use DBM#key");
339  return fdbm_key(hash, value);
340 }
341 
342 /*
343  * call-seq:
344  * dbm.select {|key, value| block} -> array
345  *
346  * Returns a new array consisting of the [key, value] pairs for which the code
347  * block returns true.
348  */
349 static VALUE
351 {
352  VALUE new = rb_ary_new();
353  datum key, val;
354  DBM *dbm;
355  struct dbmdata *dbmp;
356 
357  GetDBM2(obj, dbmp, dbm);
358  for (key = dbm_firstkey(dbm); key.dptr; key = dbm_nextkey(dbm)) {
359  VALUE assoc, v;
360  val = dbm_fetch(dbm, key);
361  assoc = rb_assoc_new(rb_tainted_str_new(key.dptr, key.dsize),
362  rb_tainted_str_new(val.dptr, val.dsize));
363  v = rb_yield(assoc);
364  if (RTEST(v)) {
365  rb_ary_push(new, assoc);
366  }
367  GetDBM2(obj, dbmp, dbm);
368  }
369 
370  return new;
371 }
372 
373 /*
374  * call-seq:
375  * dbm.values_at(key, ...) -> Array
376  *
377  * Returns an array containing the values associated with the given keys.
378  */
379 static VALUE
381 {
382  VALUE new = rb_ary_new2(argc);
383  int i;
384 
385  for (i=0; i<argc; i++) {
386  rb_ary_push(new, fdbm_fetch(obj, argv[i], Qnil));
387  }
388 
389  return new;
390 }
391 
392 static void
394 {
395  if (OBJ_FROZEN(obj)) rb_error_frozen("DBM");
396 }
397 
398 /*
399  * call-seq:
400  * dbm.delete(key)
401  *
402  * Deletes an entry from the database.
403  */
404 static VALUE
406 {
407  datum key, value;
408  struct dbmdata *dbmp;
409  DBM *dbm;
410  VALUE valstr;
411  long len;
412 
413  fdbm_modify(obj);
414  ExportStringValue(keystr);
415  len = RSTRING_LEN(keystr);
416  if (TOO_LONG(len)) goto not_found;
417  key.dptr = RSTRING_PTR(keystr);
418  key.dsize = (DSIZE_TYPE)len;
419 
420  GetDBM2(obj, dbmp, dbm);
421 
422  value = dbm_fetch(dbm, key);
423  if (value.dptr == 0) {
424  not_found:
425  if (rb_block_given_p()) return rb_yield(keystr);
426  return Qnil;
427  }
428 
429  /* need to save value before dbm_delete() */
430  valstr = rb_tainted_str_new(value.dptr, value.dsize);
431 
432  if (dbm_delete(dbm, key)) {
433  dbmp->di_size = -1;
434  rb_raise(rb_eDBMError, "dbm_delete failed");
435  }
436  else if (dbmp->di_size >= 0) {
437  dbmp->di_size--;
438  }
439  return valstr;
440 }
441 
442 /*
443  * call-seq:
444  * dbm.shift() -> [key, value]
445  *
446  * Removes a [key, value] pair from the database, and returns it.
447  * If the database is empty, returns nil.
448  * The order in which values are removed/returned is not guaranteed.
449  */
450 static VALUE
452 {
453  datum key, val;
454  struct dbmdata *dbmp;
455  DBM *dbm;
456  VALUE keystr, valstr;
457 
458  fdbm_modify(obj);
459  GetDBM2(obj, dbmp, dbm);
460  dbmp->di_size = -1;
461 
462  key = dbm_firstkey(dbm);
463  if (!key.dptr) return Qnil;
464  val = dbm_fetch(dbm, key);
465  keystr = rb_tainted_str_new(key.dptr, key.dsize);
466  valstr = rb_tainted_str_new(val.dptr, val.dsize);
467  dbm_delete(dbm, key);
468 
469  return rb_assoc_new(keystr, valstr);
470 }
471 
472 /*
473  * call-seq:
474  * dbm.reject! {|key, value| block} -> self
475  * dbm.delete_if {|key, value| block} -> self
476  *
477  * Deletes all entries for which the code block returns true.
478  * Returns self.
479  */
480 static VALUE
482 {
483  datum key, val;
484  struct dbmdata *dbmp;
485  DBM *dbm;
486  VALUE keystr, valstr;
487  VALUE ret, ary = rb_ary_tmp_new(0);
488  int i, status = 0;
489  long n;
490 
491  fdbm_modify(obj);
492  GetDBM2(obj, dbmp, dbm);
493  n = dbmp->di_size;
494  dbmp->di_size = -1;
495 
496  for (key = dbm_firstkey(dbm); key.dptr; key = dbm_nextkey(dbm)) {
497  val = dbm_fetch(dbm, key);
498  keystr = rb_tainted_str_new(key.dptr, key.dsize);
499  OBJ_FREEZE(keystr);
500  valstr = rb_tainted_str_new(val.dptr, val.dsize);
501  ret = rb_protect(rb_yield, rb_assoc_new(rb_str_dup(keystr), valstr), &status);
502  if (status != 0) break;
503  if (RTEST(ret)) rb_ary_push(ary, keystr);
504  GetDBM2(obj, dbmp, dbm);
505  }
506 
507  for (i = 0; i < RARRAY_LEN(ary); i++) {
508  keystr = RARRAY_PTR(ary)[i];
509  key.dptr = RSTRING_PTR(keystr);
510  key.dsize = (DSIZE_TYPE)RSTRING_LEN(keystr);
511  if (dbm_delete(dbm, key)) {
512  rb_raise(rb_eDBMError, "dbm_delete failed");
513  }
514  }
515  if (status) rb_jump_tag(status);
516  if (n > 0) dbmp->di_size = n - RARRAY_LEN(ary);
517  rb_ary_clear(ary);
518 
519  return obj;
520 }
521 
522 /*
523  * call-seq:
524  * dbm.clear
525  *
526  * Deletes all data from the database.
527  */
528 static VALUE
530 {
531  datum key;
532  struct dbmdata *dbmp;
533  DBM *dbm;
534 
535  fdbm_modify(obj);
536  GetDBM2(obj, dbmp, dbm);
537  dbmp->di_size = -1;
538  while (key = dbm_firstkey(dbm), key.dptr) {
539  if (dbm_delete(dbm, key)) {
540  rb_raise(rb_eDBMError, "dbm_delete failed");
541  }
542  }
543  dbmp->di_size = 0;
544 
545  return obj;
546 }
547 
548 /*
549  * call-seq:
550  * dbm.invert -> hash
551  *
552  * Returns a Hash (not a DBM database) created by using each value in the
553  * database as a key, with the corresponding key as its value.
554  */
555 static VALUE
557 {
558  datum key, val;
559  struct dbmdata *dbmp;
560  DBM *dbm;
561  VALUE keystr, valstr;
562  VALUE hash = rb_hash_new();
563 
564  GetDBM2(obj, dbmp, dbm);
565  for (key = dbm_firstkey(dbm); key.dptr; key = dbm_nextkey(dbm)) {
566  val = dbm_fetch(dbm, key);
567  keystr = rb_tainted_str_new(key.dptr, key.dsize);
568  valstr = rb_tainted_str_new(val.dptr, val.dsize);
569  rb_hash_aset(hash, valstr, keystr);
570  }
571  return hash;
572 }
573 
575 
576 static VALUE
577 update_i(RB_BLOCK_CALL_FUNC_ARGLIST(pair, dbm))
578 {
580  if (RARRAY_LEN(pair) < 2) {
581  rb_raise(rb_eArgError, "pair must be [key, value]");
582  }
583  fdbm_store(dbm, RARRAY_PTR(pair)[0], RARRAY_PTR(pair)[1]);
584  return Qnil;
585 }
586 
587 /*
588  * call-seq:
589  * dbm.update(obj)
590  *
591  * Updates the database with multiple values from the specified object.
592  * Takes any object which implements the each_pair method, including
593  * Hash and DBM objects.
594  */
595 static VALUE
597 {
598  rb_block_call(other, rb_intern("each_pair"), 0, 0, update_i, obj);
599  return obj;
600 }
601 
602 /*
603  * call-seq:
604  * dbm.replace(obj)
605  *
606  * Replaces the contents of the database with the contents of the specified
607  * object. Takes any object which implements the each_pair method, including
608  * Hash and DBM objects.
609  */
610 static VALUE
612 {
613  fdbm_clear(obj);
614  rb_block_call(other, rb_intern("each_pair"), 0, 0, update_i, obj);
615  return obj;
616 }
617 
618 /*
619  * call-seq:
620  * dbm.store(key, value) -> value
621  * dbm[key] = value
622  *
623  * Stores the specified string value in the database, indexed via the
624  * string key provided.
625  */
626 static VALUE
627 fdbm_store(VALUE obj, VALUE keystr, VALUE valstr)
628 {
629  datum key, val;
630  struct dbmdata *dbmp;
631  DBM *dbm;
632 
633  fdbm_modify(obj);
634  keystr = rb_obj_as_string(keystr);
635  valstr = rb_obj_as_string(valstr);
636 
637  key.dptr = RSTRING_PTR(keystr);
638  key.dsize = RSTRING_DSIZE(keystr);
639 
640  val.dptr = RSTRING_PTR(valstr);
641  val.dsize = RSTRING_DSIZE(valstr);
642 
643  GetDBM2(obj, dbmp, dbm);
644  dbmp->di_size = -1;
645  if (dbm_store(dbm, key, val, DBM_REPLACE)) {
646  dbm_clearerr(dbm);
647  if (errno == EPERM) rb_sys_fail(0);
648  rb_raise(rb_eDBMError, "dbm_store failed");
649  }
650 
651  return valstr;
652 }
653 
654 /*
655  * call-seq:
656  * dbm.length -> integer
657  * dbm.size -> integer
658  *
659  * Returns the number of entries in the database.
660  */
661 static VALUE
663 {
664  datum key;
665  struct dbmdata *dbmp;
666  DBM *dbm;
667  int i = 0;
668 
669  GetDBM2(obj, dbmp, dbm);
670  if (dbmp->di_size > 0) return INT2FIX(dbmp->di_size);
671 
672  for (key = dbm_firstkey(dbm); key.dptr; key = dbm_nextkey(dbm)) {
673  i++;
674  }
675  dbmp->di_size = i;
676 
677  return INT2FIX(i);
678 }
679 
680 /*
681  * call-seq:
682  * dbm.empty?
683  *
684  * Returns true if the database is empty, false otherwise.
685  */
686 static VALUE
688 {
689  datum key;
690  struct dbmdata *dbmp;
691  DBM *dbm;
692 
693  GetDBM2(obj, dbmp, dbm);
694  if (dbmp->di_size < 0) {
695  dbm = dbmp->di_dbm;
696 
697  for (key = dbm_firstkey(dbm); key.dptr; key = dbm_nextkey(dbm)) {
698  return Qfalse;
699  }
700  }
701  else {
702  if (dbmp->di_size)
703  return Qfalse;
704  }
705  return Qtrue;
706 }
707 
708 /*
709  * call-seq:
710  * dbm.each_value {|value| block} -> self
711  *
712  * Calls the block once for each value string in the database. Returns self.
713  */
714 static VALUE
716 {
717  datum key, val;
718  struct dbmdata *dbmp;
719  DBM *dbm;
720 
721  RETURN_ENUMERATOR(obj, 0, 0);
722 
723  GetDBM2(obj, dbmp, dbm);
724  for (key = dbm_firstkey(dbm); key.dptr; key = dbm_nextkey(dbm)) {
725  val = dbm_fetch(dbm, key);
727  GetDBM2(obj, dbmp, dbm);
728  }
729  return obj;
730 }
731 
732 /*
733  * call-seq:
734  * dbm.each_key {|key| block} -> self
735  *
736  * Calls the block once for each key string in the database. Returns self.
737  */
738 static VALUE
740 {
741  datum key;
742  struct dbmdata *dbmp;
743  DBM *dbm;
744 
745  RETURN_ENUMERATOR(obj, 0, 0);
746 
747  GetDBM2(obj, dbmp, dbm);
748  for (key = dbm_firstkey(dbm); key.dptr; key = dbm_nextkey(dbm)) {
750  GetDBM2(obj, dbmp, dbm);
751  }
752  return obj;
753 }
754 
755 /*
756  * call-seq:
757  * dbm.each_pair {|key,value| block} -> self
758  *
759  * Calls the block once for each [key, value] pair in the database.
760  * Returns self.
761  */
762 static VALUE
764 {
765  datum key, val;
766  DBM *dbm;
767  struct dbmdata *dbmp;
768  VALUE keystr, valstr;
769 
770  RETURN_ENUMERATOR(obj, 0, 0);
771 
772  GetDBM2(obj, dbmp, dbm);
773 
774  for (key = dbm_firstkey(dbm); key.dptr; key = dbm_nextkey(dbm)) {
775  val = dbm_fetch(dbm, key);
776  keystr = rb_tainted_str_new(key.dptr, key.dsize);
777  valstr = rb_tainted_str_new(val.dptr, val.dsize);
778  rb_yield(rb_assoc_new(keystr, valstr));
779  GetDBM2(obj, dbmp, dbm);
780  }
781 
782  return obj;
783 }
784 
785 /*
786  * call-seq:
787  * dbm.keys -> array
788  *
789  * Returns an array of all the string keys in the database.
790  */
791 static VALUE
793 {
794  datum key;
795  struct dbmdata *dbmp;
796  DBM *dbm;
797  VALUE ary;
798 
799  GetDBM2(obj, dbmp, dbm);
800 
801  ary = rb_ary_new();
802  for (key = dbm_firstkey(dbm); key.dptr; key = dbm_nextkey(dbm)) {
803  rb_ary_push(ary, rb_tainted_str_new(key.dptr, key.dsize));
804  }
805 
806  return ary;
807 }
808 
809 /*
810  * call-seq:
811  * dbm.values -> array
812  *
813  * Returns an array of all the string values in the database.
814  */
815 static VALUE
817 {
818  datum key, val;
819  struct dbmdata *dbmp;
820  DBM *dbm;
821  VALUE ary;
822 
823  GetDBM2(obj, dbmp, dbm);
824  ary = rb_ary_new();
825  for (key = dbm_firstkey(dbm); key.dptr; key = dbm_nextkey(dbm)) {
826  val = dbm_fetch(dbm, key);
827  rb_ary_push(ary, rb_tainted_str_new(val.dptr, val.dsize));
828  }
829 
830  return ary;
831 }
832 
833 /*
834  * call-seq:
835  * dbm.include?(key) -> boolean
836  * dbm.has_key?(key) -> boolean
837  * dbm.member?(key) -> boolean
838  * dbm.key?(key) -> boolean
839  *
840  * Returns true if the database contains the specified key, false otherwise.
841  */
842 static VALUE
844 {
845  datum key, val;
846  struct dbmdata *dbmp;
847  DBM *dbm;
848  long len;
849 
850  ExportStringValue(keystr);
851  len = RSTRING_LEN(keystr);
852  if (TOO_LONG(len)) return Qfalse;
853  key.dptr = RSTRING_PTR(keystr);
854  key.dsize = (DSIZE_TYPE)len;
855 
856  GetDBM2(obj, dbmp, dbm);
857  val = dbm_fetch(dbm, key);
858  if (val.dptr) return Qtrue;
859  return Qfalse;
860 }
861 
862 /*
863  * call-seq:
864  * dbm.has_value?(value) -> boolean
865  * dbm.value?(value) -> boolean
866  *
867  * Returns true if the database contains the specified string value, false
868  * otherwise.
869  */
870 static VALUE
872 {
873  datum key, val;
874  struct dbmdata *dbmp;
875  DBM *dbm;
876  long len;
877 
878  ExportStringValue(valstr);
879  len = RSTRING_LEN(valstr);
880  if (TOO_LONG(len)) return Qfalse;
881  val.dptr = RSTRING_PTR(valstr);
882  val.dsize = (DSIZE_TYPE)len;
883 
884  GetDBM2(obj, dbmp, dbm);
885  for (key = dbm_firstkey(dbm); key.dptr; key = dbm_nextkey(dbm)) {
886  val = dbm_fetch(dbm, key);
887  if ((DSIZE_TYPE)val.dsize == (DSIZE_TYPE)RSTRING_LEN(valstr) &&
888  memcmp(val.dptr, RSTRING_PTR(valstr), val.dsize) == 0)
889  return Qtrue;
890  }
891  return Qfalse;
892 }
893 
894 /*
895  * call-seq:
896  * dbm.to_a -> array
897  *
898  * Converts the contents of the database to an array of [key, value] arrays,
899  * and returns it.
900  */
901 static VALUE
903 {
904  datum key, val;
905  struct dbmdata *dbmp;
906  DBM *dbm;
907  VALUE ary;
908 
909  GetDBM2(obj, dbmp, dbm);
910  ary = rb_ary_new();
911  for (key = dbm_firstkey(dbm); key.dptr; key = dbm_nextkey(dbm)) {
912  val = dbm_fetch(dbm, key);
914  rb_tainted_str_new(val.dptr, val.dsize)));
915  }
916 
917  return ary;
918 }
919 
920 /*
921  * call-seq:
922  * dbm.to_hash -> hash
923  *
924  * Converts the contents of the database to an in-memory Hash object, and
925  * returns it.
926  */
927 static VALUE
929 {
930  datum key, val;
931  struct dbmdata *dbmp;
932  DBM *dbm;
933  VALUE hash;
934 
935  GetDBM2(obj, dbmp, dbm);
936  hash = rb_hash_new();
937  for (key = dbm_firstkey(dbm); key.dptr; key = dbm_nextkey(dbm)) {
938  val = dbm_fetch(dbm, key);
939  rb_hash_aset(hash, rb_tainted_str_new(key.dptr, key.dsize),
940  rb_tainted_str_new(val.dptr, val.dsize));
941  }
942 
943  return hash;
944 }
945 
946 /*
947  * call-seq:
948  * dbm.reject {|key,value| block} -> Hash
949  *
950  * Converts the contents of the database to an in-memory Hash, then calls
951  * Hash#reject with the specified code block, returning a new Hash.
952  */
953 static VALUE
955 {
956  return rb_hash_delete_if(fdbm_to_hash(obj));
957 }
958 
959 /*
960  * == Introduction
961  *
962  * The DBM class provides a wrapper to a Unix-style
963  * {dbm}[http://en.wikipedia.org/wiki/Dbm] or Database Manager library.
964  *
965  * Dbm databases do not have tables or columns; they are simple key-value
966  * data stores, like a Ruby Hash except not resident in RAM. Keys and values
967  * must be strings.
968  *
969  * The exact library used depends on how Ruby was compiled. It could be any
970  * of the following:
971  *
972  * - The original ndbm library is released in 4.3BSD.
973  * It is based on dbm library in Unix Version 7 but has different API to
974  * support multiple databases in a process.
975  * - {Berkeley DB}[http://en.wikipedia.org/wiki/Berkeley_DB] versions
976  * 1 thru 5, also known as BDB and Sleepycat DB, now owned by Oracle
977  * Corporation.
978  * - Berkeley DB 1.x, still found in 4.4BSD derivatives (FreeBSD, OpenBSD, etc).
979  * - {gdbm}[http://www.gnu.org/software/gdbm/], the GNU implementation of dbm.
980  * - {qdbm}[http://fallabs.com/qdbm/index.html], another open source
981  * reimplementation of dbm.
982  *
983  * All of these dbm implementations have their own Ruby interfaces
984  * available, which provide richer (but varying) APIs.
985  *
986  * == Cautions
987  *
988  * Before you decide to use DBM, there are some issues you should consider:
989  *
990  * - Each implementation of dbm has its own file format. Generally, dbm
991  * libraries will not read each other's files. This makes dbm files
992  * a bad choice for data exchange.
993  *
994  * - Even running the same OS and the same dbm implementation, the database
995  * file format may depend on the CPU architecture. For example, files may
996  * not be portable between PowerPC and 386, or between 32 and 64 bit Linux.
997  *
998  * - Different versions of Berkeley DB use different file formats. A change to
999  * the OS may therefore break DBM access to existing files.
1000  *
1001  * - Data size limits vary between implementations. Original Berkeley DB was
1002  * limited to 2GB of data. Dbm libraries also sometimes limit the total
1003  * size of a key/value pair, and the total size of all the keys that hash
1004  * to the same value. These limits can be as little as 512 bytes. That said,
1005  * gdbm and recent versions of Berkeley DB do away with these limits.
1006  *
1007  * Given the above cautions, DBM is not a good choice for long term storage of
1008  * important data. It is probably best used as a fast and easy alternative
1009  * to a Hash for processing large amounts of data.
1010  *
1011  * == Example
1012  *
1013  * require 'dbm'
1014  * db = DBM.open('rfcs', 666, DBM::WRCREAT)
1015  * db['822'] = 'Standard for the Format of ARPA Internet Text Messages'
1016  * db['1123'] = 'Requirements for Internet Hosts - Application and Support'
1017  * db['3068'] = 'An Anycast Prefix for 6to4 Relay Routers'
1018  * puts db['822']
1019  */
1020 void
1022 {
1024  /* Document-class: DBMError
1025  * Exception class used to return errors from the dbm library.
1026  */
1029 
1032 
1033  rb_define_method(rb_cDBM, "initialize", fdbm_initialize, -1);
1034  rb_define_method(rb_cDBM, "close", fdbm_close, 0);
1035  rb_define_method(rb_cDBM, "closed?", fdbm_closed, 0);
1036  rb_define_method(rb_cDBM, "[]", fdbm_aref, 1);
1037  rb_define_method(rb_cDBM, "fetch", fdbm_fetch_m, -1);
1038  rb_define_method(rb_cDBM, "[]=", fdbm_store, 2);
1039  rb_define_method(rb_cDBM, "store", fdbm_store, 2);
1040  rb_define_method(rb_cDBM, "index", fdbm_index, 1);
1041  rb_define_method(rb_cDBM, "key", fdbm_key, 1);
1042  rb_define_method(rb_cDBM, "select", fdbm_select, 0);
1043  rb_define_method(rb_cDBM, "values_at", fdbm_values_at, -1);
1044  rb_define_method(rb_cDBM, "length", fdbm_length, 0);
1045  rb_define_method(rb_cDBM, "size", fdbm_length, 0);
1046  rb_define_method(rb_cDBM, "empty?", fdbm_empty_p, 0);
1048  rb_define_method(rb_cDBM, "each_value", fdbm_each_value, 0);
1049  rb_define_method(rb_cDBM, "each_key", fdbm_each_key, 0);
1050  rb_define_method(rb_cDBM, "each_pair", fdbm_each_pair, 0);
1051  rb_define_method(rb_cDBM, "keys", fdbm_keys, 0);
1052  rb_define_method(rb_cDBM, "values", fdbm_values, 0);
1053  rb_define_method(rb_cDBM, "shift", fdbm_shift, 0);
1054  rb_define_method(rb_cDBM, "delete", fdbm_delete, 1);
1055  rb_define_method(rb_cDBM, "delete_if", fdbm_delete_if, 0);
1056  rb_define_method(rb_cDBM, "reject!", fdbm_delete_if, 0);
1057  rb_define_method(rb_cDBM, "reject", fdbm_reject, 0);
1058  rb_define_method(rb_cDBM, "clear", fdbm_clear, 0);
1059  rb_define_method(rb_cDBM, "invert", fdbm_invert, 0);
1060  rb_define_method(rb_cDBM, "update", fdbm_update, 1);
1061  rb_define_method(rb_cDBM, "replace", fdbm_replace, 1);
1062 
1063  rb_define_method(rb_cDBM, "include?", fdbm_has_key, 1);
1064  rb_define_method(rb_cDBM, "has_key?", fdbm_has_key, 1);
1065  rb_define_method(rb_cDBM, "member?", fdbm_has_key, 1);
1066  rb_define_method(rb_cDBM, "has_value?", fdbm_has_value, 1);
1067  rb_define_method(rb_cDBM, "key?", fdbm_has_key, 1);
1068  rb_define_method(rb_cDBM, "value?", fdbm_has_value, 1);
1069 
1070  rb_define_method(rb_cDBM, "to_a", fdbm_to_a, 0);
1071  rb_define_method(rb_cDBM, "to_hash", fdbm_to_hash, 0);
1072 
1073  /* Indicates that dbm_open() should open the database in read-only mode */
1074  rb_define_const(rb_cDBM, "READER", INT2FIX(O_RDONLY|RUBY_DBM_RW_BIT));
1075 
1076  /* Indicates that dbm_open() should open the database in read/write mode */
1077  rb_define_const(rb_cDBM, "WRITER", INT2FIX(O_RDWR|RUBY_DBM_RW_BIT));
1078 
1079  /* Indicates that dbm_open() should open the database in read/write mode,
1080  * and create it if it does not already exist
1081  */
1082  rb_define_const(rb_cDBM, "WRCREAT", INT2FIX(O_RDWR|O_CREAT|RUBY_DBM_RW_BIT));
1083 
1084  /* Indicates that dbm_open() should open the database in read/write mode,
1085  * create it if it does not already exist, and delete all contents if it
1086  * does already exist.
1087  */
1088  rb_define_const(rb_cDBM, "NEWDB", INT2FIX(O_RDWR|O_CREAT|O_TRUNC|RUBY_DBM_RW_BIT));
1089 
1090  {
1091  VALUE version;
1092 #if defined(_DBM_IOERR)
1093  version = rb_str_new2("ndbm (4.3BSD)");
1094 #elif defined(RUBYDBM_GDBM_HEADER)
1095 # if defined(HAVE_DECLARED_LIBVAR_GDBM_VERSION)
1096  /* since gdbm 1.9 */
1097  version = rb_str_new2(gdbm_version);
1098 # elif defined(HAVE_UNDECLARED_LIBVAR_GDBM_VERSION)
1099  /* ndbm.h doesn't declare gdbm_version until gdbm 1.8.3.
1100  * See extconf.rb for more information. */
1101  RUBY_EXTERN char *gdbm_version;
1102  version = rb_str_new2(gdbm_version);
1103 # else
1104  version = rb_str_new2("GDBM (unknown)");
1105 # endif
1106 #elif defined(RUBYDBM_DB_HEADER)
1107 # if defined(HAVE_DB_VERSION)
1108  /* The version of the dbm library, if using Berkeley DB */
1109  version = rb_str_new2(db_version(NULL, NULL, NULL));
1110 # else
1111  version = rb_str_new2("Berkeley DB (unknown)");
1112 # endif
1113 #elif defined(_RELIC_H)
1114 # if defined(HAVE_DPVERSION)
1115  version = rb_sprintf("QDBM %s", dpversion);
1116 # else
1117  version = rb_str_new2("QDBM (unknown)");
1118 # endif
1119 #else
1120  version = rb_str_new2("ndbm (unknown)");
1121 #endif
1122  /*
1123  * Identifies ndbm library version.
1124  *
1125  * Examples:
1126  *
1127  * - "ndbm (4.3BSD)"
1128  * - "Berkeley DB 4.8.30: (April 9, 2010)"
1129  * - "Berkeley DB (unknown)" (4.4BSD, maybe)
1130  * - "GDBM version 1.8.3. 10/15/2002 (built Jul 1 2011 12:32:45)"
1131  * - "QDBM 1.8.78"
1132  *
1133  */
1134  rb_define_const(rb_cDBM, "VERSION", version);
1135  }
1136 }
RARRAY_PTR(q->result)[0]
DBM * di_dbm
Definition: dbm.c:39
#define ALLOC(type)
static VALUE fdbm_delete(VALUE obj, VALUE keystr)
Definition: dbm.c:405
VALUE rb_eStandardError
Definition: error.c:546
#define FilePathValue(v)
static VALUE fdbm_length(VALUE obj)
Definition: dbm.c:662
memo u1 value
Definition: enum.c:587
static VALUE fdbm_s_open(int argc, VALUE *argv, VALUE klass)
Definition: dbm.c:229
volatile VALUE pair
Definition: tkutil.c:554
static VALUE fdbm_store(VALUE, VALUE, VALUE)
Definition: dbm.c:627
void rb_define_singleton_method(VALUE obj, const char *name, VALUE(*func)(ANYARGS), int argc)
Defines a singleton method for obj.
Definition: class.c:1646
static VALUE fdbm_index(VALUE hash, VALUE value)
Definition: dbm.c:336
void rb_error_frozen(const char *what)
Definition: error.c:2077
static VALUE fdbm_values(VALUE obj)
Definition: dbm.c:816
int ret
Definition: tcltklib.c:285
int status
Definition: tcltklib.c:2197
rb_yield(i)
#define OBJ_FREEZE(x)
void rb_define_alloc_func(VALUE, rb_alloc_func_t)
VALUE rb_ary_push(VALUE ary, VALUE item)
Definition: array.c:900
static VALUE fdbm_replace(VALUE obj, VALUE other)
Definition: dbm.c:611
long di_size
Definition: dbm.c:38
VALUE rb_ary_tmp_new(long capa)
Definition: array.c:538
#define RSTRING_PTR(str)
NIL_P(eventloop_thread)
Definition: tcltklib.c:4056
#define T_ARRAY
VALUE rb_protect(VALUE(*proc)(VALUE), VALUE data, int *state)
Definition: eval.c:807
#define xfree
void rb_raise(VALUE exc, const char *fmt,...)
Definition: error.c:1857
return Qtrue
Definition: tcltklib.c:9618
#define RETURN_ENUMERATOR(obj, argc, argv)
VALUE rb_ary_clear(VALUE ary)
Definition: array.c:3392
Definition: dbm.c:37
#define GetDBM2(obj, data, dbm)
Definition: dbm.c:54
void rb_include_module(VALUE klass, VALUE module)
Definition: class.c:808
char * dptr
Definition: sdbm.h:51
#define DSIZE_TYPE
Definition: dbm.c:24
#define rb_str_new2
#define TOO_LONG(n)
Definition: dbm.c:30
#define rb_ary_new2
static VALUE fdbm_has_key(VALUE obj, VALUE keystr)
Definition: dbm.c:843
static void free_dbm(struct dbmdata *dbmp)
Definition: dbm.c:60
void rb_fd_fix_cloexec(int fd)
Definition: io.c:221
i
Definition: enum.c:446
VALUE ary
Definition: enum.c:674
static VALUE fdbm_values_at(int argc, VALUE *argv, VALUE obj)
Definition: dbm.c:380
static VALUE fdbm_empty_p(VALUE obj)
Definition: dbm.c:687
#define RSTRING_DSIZE(s)
Definition: dbm.c:29
static VALUE fdbm_reject(VALUE obj)
Definition: dbm.c:954
VALUE hash
Definition: tkutil.c:267
#define O_CLOEXEC
return Data_Wrap_Struct(CLASS_OF(interp), 0, ip_free, slave)
return Qfalse
Definition: tcltklib.c:6790
Definition: sdbm.h:50
int rb_block_given_p(void)
Definition: eval.c:712
#define DBM_REPLACE
Definition: sdbm.h:67
#define RARRAY_LEN(a)
#define Qnil
Definition: enum.c:67
#define val
Definition: tcltklib.c:1935
static VALUE fdbm_aref(VALUE obj, VALUE keystr)
Definition: dbm.c:277
static VALUE fdbm_to_a(VALUE obj)
Definition: dbm.c:902
static VALUE fdbm_select(VALUE obj)
Definition: dbm.c:350
VALUE rb_ary_new(void)
Definition: array.c:499
static VALUE fdbm_close(VALUE obj)
Definition: dbm.c:75
int flags
Definition: tcltklib.c:3015
static void fdbm_modify(VALUE obj)
Definition: dbm.c:393
void rb_define_const(VALUE, const char *, VALUE)
Definition: variable.c:2228
Check_Type(i, T_ARRAY)
VALUE rb_define_class(const char *name, VALUE super)
Defines a top-level class.
Definition: class.c:611
static VALUE VALUE obj
Definition: tcltklib.c:3150
#define RSTRING_LEN(str)
#define INT2FIX(i)
void rb_sys_fail_str(VALUE mesg)
Definition: error.c:1982
#define RUBY_DBM_RW_BIT
Definition: dbm.c:35
static VALUE fdbm_shift(VALUE obj)
Definition: dbm.c:451
void Init_dbm(void)
Definition: dbm.c:1021
static VALUE VALUE assoc
Definition: tkutil.c:545
VALUE rb_eIndexError
Definition: error.c:550
static int VALUE key
Definition: tkutil.c:265
int len
Definition: enumerator.c:1332
static VALUE fdbm_each_key(VALUE obj)
Definition: dbm.c:739
VALUE rb_str_dup(VALUE)
Definition: string.c:1062
#define ExportStringValue(v)
VALUE rb_obj_as_string(VALUE)
Definition: string.c:1011
VALUE * argv
Definition: tcltklib.c:1969
VALUE rb_tainted_str_new(const char *, long)
Definition: string.c:589
#define RTEST(v)
static VALUE fdbm_clear(VALUE obj)
Definition: dbm.c:529
int errno
#define RUBY_EXTERN
Definition: missing.h:67
VALUE rb_mEnumerable
Definition: enum.c:20
VALUE rb_sprintf(const char *format,...)
Definition: sprintf.c:1250
rb_block_call(enumerable, id_each, 0, 0, chunk_ii, arg)
VALUE v
Definition: enum.c:845
Definition: sdbm.h:20
VALUE mode
Definition: tcltklib.c:1668
int rb_scan_args(int argc, const VALUE *argv, const char *fmt,...)
Definition: class.c:1719
VALUE rb_assoc_new(VALUE car, VALUE cdr)
Definition: array.c:620
#define OBJ_FROZEN(x)
static VALUE fdbm_to_hash(VALUE obj)
Definition: dbm.c:928
int dsize
Definition: sdbm.h:52
int argc
Definition: tcltklib.c:1968
rb_hash_aset(hash, RARRAY_AREF(key_value_pair, 0), RARRAY_AREF(key_value_pair, 1))
#define EPERM
Definition: _sdbm.c:93
VALUE rb_ensure(VALUE(*b_proc)(ANYARGS), VALUE data1, VALUE(*e_proc)(ANYARGS), VALUE data2)
Definition: eval.c:839
int memcmp(const void *s1, const void *s2, size_t len)
Definition: memcmp.c:7
void rb_sys_fail(const char *mesg)
Definition: error.c:1976
void rb_jump_tag(int tag)
Definition: eval.c:706
static VALUE rb_eDBMError
Definition: dbm.c:33
static VALUE fdbm_alloc(VALUE klass)
Definition: dbm.c:107
static VALUE rb_cDBM
Definition: dbm.c:33
static VALUE fdbm_fetch(VALUE obj, VALUE keystr, VALUE ifnone)
Definition: dbm.c:245
static VALUE fdbm_initialize(int argc, VALUE *argv, VALUE obj)
Definition: dbm.c:126
DATA_PTR(self)
static VALUE fdbm_closed(VALUE obj)
Definition: dbm.c:93
RUBY_EXTERN VALUE rb_cObject
Definition: ripper.y:1561
static VALUE fdbm_each_value(VALUE obj)
Definition: dbm.c:715
static VALUE fdbm_keys(VALUE obj)
Definition: dbm.c:792
klass
Definition: tcltklib.c:3496
#define Data_Get_Struct(obj, type, sval)
static VALUE fdbm_update(VALUE obj, VALUE other)
Definition: dbm.c:596
static VALUE fdbm_invert(VALUE obj)
Definition: dbm.c:556
static VALUE fdbm_has_value(VALUE obj, VALUE valstr)
Definition: dbm.c:871
data n
Definition: enum.c:860
VALUE rb_hash_delete_if(VALUE)
Definition: hash.c:1103
static void closed_dbm(void)
Definition: dbm.c:43
#define NUM2INT(x)
VALUE rb_hash_new(void)
Definition: hash.c:307
#define GetDBM(obj, dbmp)
Definition: dbm.c:48
unsigned long VALUE
Definition: ripper.y:88
static void version(void)
Definition: nkf.c:898
#define rb_intern(str)
#define RB_BLOCK_CALL_FUNC_ARGLIST(yielded_arg, callback_arg)
#define NULL
Definition: _sdbm.c:102
static VALUE fdbm_key(VALUE obj, VALUE valstr)
Definition: dbm.c:310
static VALUE fdbm_delete_if(VALUE obj)
Definition: dbm.c:481
void rb_define_method(VALUE klass, const char *name, VALUE(*func)(ANYARGS), int argc)
Definition: class.c:1479
void rb_warn(const char *fmt,...)
Definition: error.c:223
static VALUE fdbm_each_pair(VALUE obj)
Definition: dbm.c:763
VALUE rb_eArgError
Definition: error.c:549
static VALUE fdbm_fetch_m(int argc, VALUE *argv, VALUE obj)
Definition: dbm.c:291