1 /************************************************
6 modified at: Mon Jan 24 15:59:52 JST 1994
8 Documentation by Peter Adolphs < futzilogik at users dot sourceforge dot net >
10 ************************************************/
19 * Document-class: GDBM
23 * Ruby extension for GNU dbm (gdbm) -- a simple database engine for storing
24 * key-value pairs on disk.
28 * GNU dbm is a library for simple databases. A database is a file that stores
29 * key-value pairs. Gdbm allows the user to store, retrieve, and delete data by
30 * key. It furthermore allows a non-sorted traversal of all key-value pairs.
31 * A gdbm database thus provides the same functionality as a hash. As
32 * with objects of the Hash class, elements can be accessed with <tt>[]</tt>.
33 * Furthermore, GDBM mixes in the Enumerable module, thus providing convenient
34 * methods such as #find, #collect, #map, etc.
36 * A process is allowed to open several different databases at the same time.
37 * A process can open a database as a "reader" or a "writer". Whereas a reader
38 * has only read-access to the database, a writer has read- and write-access.
39 * A database can be accessed either by any number of readers or by exactly one
40 * writer at the same time.
44 * 1. Opening/creating a database, and filling it with some entries:
48 * gdbm = GDBM.new("fruitstore.db")
49 * gdbm["ananas"] = "3"
50 * gdbm["banana"] = "8"
51 * gdbm["cranberry"] = "4909"
54 * 2. Reading out a database:
58 * gdbm = GDBM.new("fruitstore.db")
59 * gdbm.each_pair do |key, value|
60 * print "#{key}: #{value}\n"
72 * * http://www.gnu.org/software/gdbm/
74 static VALUE rb_cGDBM
, rb_eGDBMError
, rb_eGDBMFatalError
;
76 #define RUBY_GDBM_RW_BIT 0x20000000
78 #define MY_BLOCK_SIZE (2048)
79 #define MY_FATAL_FUNC rb_gdbm_fatal
81 rb_gdbm_fatal(char *msg
)
83 rb_raise(rb_eGDBMFatalError
, "%s", msg
);
94 rb_raise(rb_eRuntimeError
, "closed GDBM file");
97 #define GetDBM(obj, dbmp) do {\
98 Data_Get_Struct(obj, struct dbmdata, dbmp);\
99 if (dbmp == 0) closed_dbm();\
100 if (dbmp->di_dbm == 0) closed_dbm();\
103 #define GetDBM2(obj, data, dbm) {\
105 (dbm) = dbmp->di_dbm;\
109 free_dbm(struct dbmdata
*dbmp
)
112 if (dbmp
->di_dbm
) gdbm_close(dbmp
->di_dbm
);
121 * Closes the associated database file.
124 fgdbm_close(VALUE obj
)
126 struct dbmdata
*dbmp
;
129 gdbm_close(dbmp
->di_dbm
);
137 * gdbm.closed? -> true or false
139 * Returns true if the associated database file has been closed.
142 fgdbm_closed(VALUE obj
)
144 struct dbmdata
*dbmp
;
146 Data_Get_Struct(obj
, struct dbmdata
, dbmp
);
149 if (dbmp
->di_dbm
== 0)
156 fgdbm_s_alloc(VALUE klass
)
158 return Data_Wrap_Struct(klass
, 0, free_dbm
, 0);
163 * GDBM.new(filename, mode = 0666, flags = nil)
165 * Creates a new GDBM instance by opening a gdbm file named _filename_.
166 * If the file does not exist, a new file with file mode _mode_ will be
167 * created. _flags_ may be one of the following:
168 * * *READER* - open as a reader
169 * * *WRITER* - open as a writer
170 * * *WRCREAT* - open as a writer; if the database does not exist, create a new one
171 * * *NEWDB* - open as a writer; overwrite any existing databases
173 * The values *WRITER*, *WRCREAT* and *NEWDB* may be combined with the following
174 * values by bitwise or:
175 * * *SYNC* - cause all database operations to be synchronized to the disk
176 * * *NOLOCK* - do not lock the database file
178 * If no _flags_ are specified, the GDBM object will try to open the database
179 * file as a writer and will create it if it does not already exist
180 * (cf. flag <tt>WRCREAT</tt>). If this fails (for instance, if another process
181 * has already opened the database as a reader), it will try to open the
182 * database file as a reader (cf. flag <tt>READER</tt>).
185 fgdbm_initialize(int argc
, VALUE
*argv
, VALUE obj
)
187 VALUE file
, vmode
, vflags
;
189 struct dbmdata
*dbmp
;
192 if (rb_scan_args(argc
, argv
, "12", &file
, &vmode
, &vflags
) == 1) {
193 mode
= 0666; /* default value */
195 else if (NIL_P(vmode
)) {
196 mode
= -1; /* return nil if DB does not exist */
199 mode
= NUM2INT(vmode
);
203 flags
= NUM2INT(vflags
);
205 SafeStringValue(file
);
207 if (flags
& RUBY_GDBM_RW_BIT
) {
208 flags
&= ~RUBY_GDBM_RW_BIT
;
209 dbm
= gdbm_open(RSTRING_PTR(file
), MY_BLOCK_SIZE
,
210 flags
, mode
, MY_FATAL_FUNC
);
215 dbm
= gdbm_open(RSTRING_PTR(file
), MY_BLOCK_SIZE
,
216 GDBM_WRCREAT
|flags
, mode
, MY_FATAL_FUNC
);
218 dbm
= gdbm_open(RSTRING_PTR(file
), MY_BLOCK_SIZE
,
219 GDBM_WRITER
|flags
, 0, MY_FATAL_FUNC
);
221 dbm
= gdbm_open(RSTRING_PTR(file
), MY_BLOCK_SIZE
,
222 GDBM_READER
|flags
, 0, MY_FATAL_FUNC
);
226 if (mode
== -1) return Qnil
;
228 if (gdbm_errno
== GDBM_FILE_OPEN_ERROR
||
229 gdbm_errno
== GDBM_CANT_BE_READER
||
230 gdbm_errno
== GDBM_CANT_BE_WRITER
)
231 rb_sys_fail(RSTRING_PTR(file
));
233 rb_raise(rb_eGDBMError
, "%s", gdbm_strerror(gdbm_errno
));
236 dbmp
= ALLOC(struct dbmdata
);
237 free_dbm(DATA_PTR(obj
));
238 DATA_PTR(obj
) = dbmp
;
247 * GDBM.open(filename, mode = 0666, flags = nil)
248 * GDBM.open(filename, mode = 0666, flags = nil) { |gdbm| ... }
250 * If called without a block, this is synonymous to GDBM::new.
251 * If a block is given, the new GDBM instance will be passed to the block
252 * as a parameter, and the corresponding database file will be closed
253 * after the execution of the block code has been finished.
255 * Example for an open call with a block:
258 * GDBM.open("fruitstore.db") do |gdbm|
259 * gdbm.each_pair do |key, value|
260 * print "#{key}: #{value}\n"
265 fgdbm_s_open(int argc
, VALUE
*argv
, VALUE klass
)
267 VALUE obj
= Data_Wrap_Struct(klass
, 0, free_dbm
, 0);
269 if (NIL_P(fgdbm_initialize(argc
, argv
, obj
))) {
273 if (rb_block_given_p()) {
274 return rb_ensure(rb_yield
, obj
, fgdbm_close
, obj
);
281 rb_gdbm_fetch(GDBM_FILE dbm
, datum key
)
286 val
= gdbm_fetch(dbm
, key
);
290 str
= rb_str_new(val
.dptr
, val
.dsize
);
297 rb_gdbm_fetch2(GDBM_FILE dbm
, VALUE keystr
)
302 key
.dptr
= RSTRING_PTR(keystr
);
303 key
.dsize
= RSTRING_LEN(keystr
);
305 return rb_gdbm_fetch(dbm
, key
);
309 rb_gdbm_fetch3(VALUE obj
, VALUE keystr
)
311 struct dbmdata
*dbmp
;
314 GetDBM2(obj
, dbmp
, dbm
);
315 return rb_gdbm_fetch2(dbm
, keystr
);
319 rb_gdbm_firstkey(GDBM_FILE dbm
)
324 key
= gdbm_firstkey(dbm
);
328 str
= rb_str_new(key
.dptr
, key
.dsize
);
335 rb_gdbm_nextkey(GDBM_FILE dbm
, VALUE keystr
)
340 key
.dptr
= RSTRING_PTR(keystr
);
341 key
.dsize
= RSTRING_LEN(keystr
);
342 key2
= gdbm_nextkey(dbm
, key
);
346 str
= rb_str_new(key2
.dptr
, key2
.dsize
);
352 fgdbm_fetch(VALUE obj
, VALUE keystr
, VALUE ifnone
)
356 valstr
= rb_gdbm_fetch3(obj
, keystr
);
358 if (ifnone
== Qnil
&& rb_block_given_p())
359 return rb_yield(keystr
);
369 * Retrieves the _value_ corresponding to _key_.
372 fgdbm_aref(VALUE obj
, VALUE keystr
)
374 return rb_gdbm_fetch3(obj
, keystr
);
379 * gdbm.fetch(key [, default]) -> value
381 * Retrieves the _value_ corresponding to _key_. If there is no value
382 * associated with _key_, _default_ will be returned instead.
385 fgdbm_fetch_m(int argc
, VALUE
*argv
, VALUE obj
)
387 VALUE keystr
, valstr
, ifnone
;
389 rb_scan_args(argc
, argv
, "11", &keystr
, &ifnone
);
390 valstr
= fgdbm_fetch(obj
, keystr
, ifnone
);
391 if (argc
== 1 && !rb_block_given_p() && NIL_P(valstr
))
392 rb_raise(rb_eIndexError
, "key not found");
399 * gdbm.index(value) -> key
401 * Returns the _key_ for a given _value_. If several keys may map to the
402 * same value, the key that is found first will be returned.
405 fgdbm_index(VALUE obj
, VALUE valstr
)
407 struct dbmdata
*dbmp
;
409 VALUE keystr
, valstr2
;
412 GetDBM2(obj
, dbmp
, dbm
);
413 for (keystr
= rb_gdbm_firstkey(dbm
); RTEST(keystr
);
414 keystr
= rb_gdbm_nextkey(dbm
, keystr
)) {
416 valstr2
= rb_gdbm_fetch2(dbm
, keystr
);
417 if (!NIL_P(valstr2
) &&
418 RSTRING_LEN(valstr
) == RSTRING_LEN(valstr2
) &&
419 memcmp(RSTRING_PTR(valstr
), RSTRING_PTR(valstr2
),
420 RSTRING_LEN(valstr
)) == 0) {
429 * gdbm.select { |value| block } -> array
431 * Returns a new array of all values of the database for which _block_
435 fgdbm_select(VALUE obj
)
437 VALUE
new = rb_ary_new();
439 struct dbmdata
*dbmp
;
442 GetDBM2(obj
, dbmp
, dbm
);
443 for (keystr
= rb_gdbm_firstkey(dbm
); RTEST(keystr
);
444 keystr
= rb_gdbm_nextkey(dbm
, keystr
)) {
445 VALUE assoc
= rb_assoc_new(keystr
, rb_gdbm_fetch2(dbm
, keystr
));
446 VALUE v
= rb_yield(assoc
);
449 rb_ary_push(new, assoc
);
451 GetDBM2(obj
, dbmp
, dbm
);
459 * gdbm.values_at(key, ...) -> array
461 * Returns an array of the values associated with each specified _key_.
464 fgdbm_values_at(int argc
, VALUE
*argv
, VALUE obj
)
466 VALUE
new = rb_ary_new2(argc
);
469 for (i
=0; i
<argc
; i
++) {
470 rb_ary_push(new, rb_gdbm_fetch3(obj
, argv
[i
]));
477 rb_gdbm_modify(VALUE obj
)
480 if (OBJ_FROZEN(obj
)) rb_error_frozen("GDBM");
484 rb_gdbm_delete(VALUE obj
, VALUE keystr
)
487 struct dbmdata
*dbmp
;
492 key
.dptr
= RSTRING_PTR(keystr
);
493 key
.dsize
= RSTRING_LEN(keystr
);
495 GetDBM2(obj
, dbmp
, dbm
);
496 if (!gdbm_exists(dbm
, key
)) {
500 if (gdbm_delete(dbm
, key
)) {
502 rb_raise(rb_eGDBMError
, "%s", gdbm_strerror(gdbm_errno
));
504 else if (dbmp
->di_size
>= 0) {
512 * gdbm.delete(key) -> value or nil
514 * Removes the key-value-pair with the specified _key_ from this database and
515 * returns the corresponding _value_. Returns nil if the database is empty.
518 fgdbm_delete(VALUE obj
, VALUE keystr
)
522 valstr
= fgdbm_fetch(obj
, keystr
, Qnil
);
523 rb_gdbm_delete(obj
, keystr
);
529 * gdbm.shift -> (key, value) or nil
531 * Removes a key-value-pair from this database and returns it as a
532 * two-item array [ _key_, _value_ ]. Returns nil if the database is empty.
535 fgdbm_shift(VALUE obj
)
537 struct dbmdata
*dbmp
;
539 VALUE keystr
, valstr
;
542 GetDBM2(obj
, dbmp
, dbm
);
543 keystr
= rb_gdbm_firstkey(dbm
);
544 if (NIL_P(keystr
)) return Qnil
;
545 valstr
= rb_gdbm_fetch2(dbm
, keystr
);
546 rb_gdbm_delete(obj
, keystr
);
548 return rb_assoc_new(keystr
, valstr
);
553 * gdbm.delete_if { |key, value| block } -> gdbm
554 * gdbm.reject! { |key, value| block } -> gdbm
556 * Deletes every key-value pair from _gdbm_ for which _block_ evaluates to true.
559 fgdbm_delete_if(VALUE obj
)
561 struct dbmdata
*dbmp
;
563 VALUE keystr
, valstr
;
564 VALUE ret
, ary
= rb_ary_new();
565 int i
, status
= 0, n
;
568 GetDBM2(obj
, dbmp
, dbm
);
572 for (keystr
= rb_gdbm_firstkey(dbm
); RTEST(keystr
);
573 keystr
= rb_gdbm_nextkey(dbm
, keystr
)) {
575 valstr
= rb_gdbm_fetch2(dbm
, keystr
);
576 ret
= rb_protect(rb_yield
, rb_assoc_new(keystr
, valstr
), &status
);
577 if (status
!= 0) break;
578 if (RTEST(ret
)) rb_ary_push(ary
, keystr
);
579 GetDBM2(obj
, dbmp
, dbm
);
582 for (i
= 0; i
< RARRAY_LEN(ary
); i
++)
583 rb_gdbm_delete(obj
, RARRAY_PTR(ary
)[i
]);
584 if (status
) rb_jump_tag(status
);
585 if (n
> 0) dbmp
->di_size
= n
- RARRAY_LEN(ary
);
594 * Removes all the key-value pairs within _gdbm_.
597 fgdbm_clear(VALUE obj
)
600 struct dbmdata
*dbmp
;
604 GetDBM2(obj
, dbmp
, dbm
);
608 while (key
= gdbm_firstkey(dbm
), key
.dptr
) {
609 if (gdbm_delete(dbm
, key
)) {
611 rb_raise(rb_eGDBMError
, "%s", gdbm_strerror(gdbm_errno
));
616 while (key
= gdbm_firstkey(dbm
), key
.dptr
) {
617 for (; key
.dptr
; key
= nextkey
) {
618 nextkey
= gdbm_nextkey(dbm
, key
);
619 if (gdbm_delete(dbm
, key
)) {
621 if (nextkey
.dptr
) free(nextkey
.dptr
);
622 rb_raise(rb_eGDBMError
, "%s", gdbm_strerror(gdbm_errno
));
635 * gdbm.invert -> hash
637 * Returns a hash created by using _gdbm_'s values as keys, and the keys
641 fgdbm_invert(VALUE obj
)
643 struct dbmdata
*dbmp
;
645 VALUE keystr
, valstr
;
646 VALUE hash
= rb_hash_new();
648 GetDBM2(obj
, dbmp
, dbm
);
649 for (keystr
= rb_gdbm_firstkey(dbm
); RTEST(keystr
);
650 keystr
= rb_gdbm_nextkey(dbm
, keystr
)) {
651 valstr
= rb_gdbm_fetch2(dbm
, keystr
);
653 rb_hash_aset(hash
, valstr
, keystr
);
660 * gdbm[key]= value -> value
661 * gdbm.store(key, value) -> value
663 * Associates the value _value_ with the specified _key_.
666 fgdbm_store(VALUE obj
, VALUE keystr
, VALUE valstr
)
669 struct dbmdata
*dbmp
;
676 key
.dptr
= RSTRING_PTR(keystr
);
677 key
.dsize
= RSTRING_LEN(keystr
);
679 val
.dptr
= RSTRING_PTR(valstr
);
680 val
.dsize
= RSTRING_LEN(valstr
);
682 GetDBM2(obj
, dbmp
, dbm
);
684 if (gdbm_store(dbm
, key
, val
, GDBM_REPLACE
)) {
685 if (errno
== EPERM
) rb_sys_fail(0);
686 rb_raise(rb_eGDBMError
, "%s", gdbm_strerror(gdbm_errno
));
693 update_i(VALUE pair
, VALUE dbm
)
695 Check_Type(pair
, T_ARRAY
);
696 if (RARRAY_LEN(pair
) < 2) {
697 rb_raise(rb_eArgError
, "pair must be [key, value]");
699 fgdbm_store(dbm
, RARRAY_PTR(pair
)[0], RARRAY_PTR(pair
)[1]);
705 * gdbm.update(other) -> gdbm
707 * Adds the key-value pairs of _other_ to _gdbm_, overwriting entries with
708 * duplicate keys with those from _other_. _other_ must have an each_pair
712 fgdbm_update(VALUE obj
, VALUE other
)
714 rb_block_call(other
, rb_intern("each_pair"), 0, 0, update_i
, obj
);
720 * gdbm.replace(other) -> gdbm
722 * Replaces the content of _gdbm_ with the key-value pairs of _other_.
723 * _other_ must have an each_pair method.
726 fgdbm_replace(VALUE obj
, VALUE other
)
729 rb_block_call(other
, rb_intern("each_pair"), 0, 0, update_i
, obj
);
735 * gdbm.length -> fixnum
736 * gdbm.size -> fixnum
738 * Returns the number of key-value pairs in this database.
741 fgdbm_length(VALUE obj
)
744 struct dbmdata
*dbmp
;
748 GetDBM2(obj
, dbmp
, dbm
);
749 if (dbmp
->di_size
> 0) return INT2FIX(dbmp
->di_size
);
751 for (key
= gdbm_firstkey(dbm
); key
.dptr
; key
= nextkey
) {
752 nextkey
= gdbm_nextkey(dbm
, key
);
763 * gdbm.empty? -> true or false
765 * Returns true if the database is empty.
768 fgdbm_empty_p(VALUE obj
)
771 struct dbmdata
*dbmp
;
775 if (dbmp
->di_size
< 0) {
778 key
= gdbm_firstkey(dbm
);
786 if (dbmp
->di_size
== 0) return Qtrue
;
792 * gdbm.each_value { |value| block } -> gdbm
794 * Executes _block_ for each key in the database, passing the corresponding
795 * _value_ as a parameter.
798 fgdbm_each_value(VALUE obj
)
800 struct dbmdata
*dbmp
;
804 RETURN_ENUMERATOR(obj
, 0, 0);
806 GetDBM2(obj
, dbmp
, dbm
);
807 for (keystr
= rb_gdbm_firstkey(dbm
); RTEST(keystr
);
808 keystr
= rb_gdbm_nextkey(dbm
, keystr
)) {
810 rb_yield(rb_gdbm_fetch2(dbm
, keystr
));
811 GetDBM2(obj
, dbmp
, dbm
);
818 * gdbm.each_key { |key| block } -> gdbm
820 * Executes _block_ for each key in the database, passing the
821 * _key_ as a parameter.
824 fgdbm_each_key(VALUE obj
)
826 struct dbmdata
*dbmp
;
830 RETURN_ENUMERATOR(obj
, 0, 0);
832 GetDBM2(obj
, dbmp
, dbm
);
833 for (keystr
= rb_gdbm_firstkey(dbm
); RTEST(keystr
);
834 keystr
= rb_gdbm_nextkey(dbm
, keystr
)) {
837 GetDBM2(obj
, dbmp
, dbm
);
844 * gdbm.each_pair { |key, value| block } -> gdbm
846 * Executes _block_ for each key in the database, passing the _key_ and the
847 * correspoding _value_ as a parameter.
850 fgdbm_each_pair(VALUE obj
)
853 struct dbmdata
*dbmp
;
856 RETURN_ENUMERATOR(obj
, 0, 0);
858 GetDBM2(obj
, dbmp
, dbm
);
859 for (keystr
= rb_gdbm_firstkey(dbm
); RTEST(keystr
);
860 keystr
= rb_gdbm_nextkey(dbm
, keystr
)) {
862 rb_yield(rb_assoc_new(keystr
, rb_gdbm_fetch2(dbm
, keystr
)));
863 GetDBM2(obj
, dbmp
, dbm
);
873 * Returns an array of all keys of this database.
876 fgdbm_keys(VALUE obj
)
878 struct dbmdata
*dbmp
;
882 GetDBM2(obj
, dbmp
, dbm
);
884 for (keystr
= rb_gdbm_firstkey(dbm
); RTEST(keystr
);
885 keystr
= rb_gdbm_nextkey(dbm
, keystr
)) {
887 rb_ary_push(ary
, keystr
);
895 * gdbm.values -> array
897 * Returns an array of all values of this database.
900 fgdbm_values(VALUE obj
)
903 struct dbmdata
*dbmp
;
907 GetDBM2(obj
, dbmp
, dbm
);
909 for (key
= gdbm_firstkey(dbm
); key
.dptr
; key
= nextkey
) {
910 nextkey
= gdbm_nextkey(dbm
, key
);
911 valstr
= rb_gdbm_fetch(dbm
, key
);
913 rb_ary_push(ary
, valstr
);
921 * gdbm.has_key?(k) -> true or false
922 * gdbm.key?(k) -> true or false
924 * Returns true if the given key _k_ exists within the database.
925 * Returns false otherwise.
928 fgdbm_has_key(VALUE obj
, VALUE keystr
)
931 struct dbmdata
*dbmp
;
935 key
.dptr
= RSTRING_PTR(keystr
);
936 key
.dsize
= RSTRING_LEN(keystr
);
938 GetDBM2(obj
, dbmp
, dbm
);
939 if (gdbm_exists(dbm
, key
))
946 * gdbm.has_value?(v) -> true or false
947 * gdbm.value?(v) -> true or false
949 * Returns true if the given value _v_ exists within the database.
950 * Returns false otherwise.
953 fgdbm_has_value(VALUE obj
, VALUE valstr
)
955 struct dbmdata
*dbmp
;
957 VALUE keystr
, valstr2
;
960 GetDBM2(obj
, dbmp
, dbm
);
961 for (keystr
= rb_gdbm_firstkey(dbm
); RTEST(keystr
);
962 keystr
= rb_gdbm_nextkey(dbm
, keystr
)) {
964 valstr2
= rb_gdbm_fetch2(dbm
, keystr
);
966 if (!NIL_P(valstr2
) &&
967 RSTRING_LEN(valstr
) == RSTRING_LEN(valstr2
) &&
968 memcmp(RSTRING_PTR(valstr
), RSTRING_PTR(valstr2
),
969 RSTRING_LEN(valstr
)) == 0) {
980 * Returns an array of all key-value pairs contained in the database.
983 fgdbm_to_a(VALUE obj
)
985 struct dbmdata
*dbmp
;
989 GetDBM2(obj
, dbmp
, dbm
);
991 for (keystr
= rb_gdbm_firstkey(dbm
); RTEST(keystr
);
992 keystr
= rb_gdbm_nextkey(dbm
, keystr
)) {
994 rb_ary_push(ary
, rb_assoc_new(keystr
, rb_gdbm_fetch2(dbm
, keystr
)));
1002 * gdbm.reorganize -> gdbm
1004 * Reorganizes the database file. This operation removes reserved space of
1005 * elements that have already been deleted. It is only useful after a lot of
1006 * deletions in the database.
1009 fgdbm_reorganize(VALUE obj
)
1011 struct dbmdata
*dbmp
;
1014 rb_gdbm_modify(obj
);
1015 GetDBM2(obj
, dbmp
, dbm
);
1016 gdbm_reorganize(dbm
);
1024 * Unless the _gdbm_ object has been opened with the *SYNC* flag, it is not
1025 * guarenteed that database modification operations are immediately applied to
1026 * the database file. This method ensures that all recent modifications
1027 * to the database are written to the file. Blocks until all writing operations
1028 * to the disk have been finished.
1031 fgdbm_sync(VALUE obj
)
1033 struct dbmdata
*dbmp
;
1036 rb_gdbm_modify(obj
);
1037 GetDBM2(obj
, dbmp
, dbm
);
1044 * gdbm.cachesize = size -> size
1046 * Sets the size of the internal bucket cache to _size_.
1049 fgdbm_set_cachesize(VALUE obj
, VALUE val
)
1051 struct dbmdata
*dbmp
;
1055 GetDBM2(obj
, dbmp
, dbm
);
1056 optval
= FIX2INT(val
);
1057 if (gdbm_setopt(dbm
, GDBM_CACHESIZE
, &optval
, sizeof(optval
)) == -1) {
1058 rb_raise(rb_eGDBMError
, "%s", gdbm_strerror(gdbm_errno
));
1065 * gdbm.fastmode = boolean -> boolean
1067 * Turns the database's fast mode on or off. If fast mode is turned on, gdbm
1068 * does not wait for writes to be flushed to the disk before continuing.
1070 * This option is obsolete for gdbm >= 1.8 since fast mode is turned on by
1071 * default. See also: #syncmode=
1074 fgdbm_set_fastmode(VALUE obj
, VALUE val
)
1076 struct dbmdata
*dbmp
;
1080 GetDBM2(obj
, dbmp
, dbm
);
1085 if (gdbm_setopt(dbm
, GDBM_FASTMODE
, &optval
, sizeof(optval
)) == -1) {
1086 rb_raise(rb_eGDBMError
, "%s", gdbm_strerror(gdbm_errno
));
1093 * gdbm.syncmode = boolean -> boolean
1095 * Turns the database's synchronization mode on or off. If the synchronization
1096 * mode is turned on, the database's in-memory state will be synchronized to
1097 * disk after every database modification operation. If the synchronization
1098 * mode is turned off, GDBM does not wait for writes to be flushed to the disk
1099 * before continuing.
1101 * This option is only available for gdbm >= 1.8 where syncmode is turned off
1102 * by default. See also: #fastmode=
1105 fgdbm_set_syncmode(VALUE obj
, VALUE val
)
1107 #if !defined(GDBM_SYNCMODE)
1108 fgdbm_set_fastmode(obj
, RTEST(val
) ? Qfalse
: Qtrue
);
1111 struct dbmdata
*dbmp
;
1115 GetDBM2(obj
, dbmp
, dbm
);
1120 if (gdbm_setopt(dbm
, GDBM_FASTMODE
, &optval
, sizeof(optval
)) == -1) {
1121 rb_raise(rb_eGDBMError
, "%s", gdbm_strerror(gdbm_errno
));
1129 * gdbm.to_hash -> hash
1131 * Returns a hash of all key-value pairs contained in the database.
1134 fgdbm_to_hash(VALUE obj
)
1136 struct dbmdata
*dbmp
;
1140 GetDBM2(obj
, dbmp
, dbm
);
1141 hash
= rb_hash_new();
1142 for (keystr
= rb_gdbm_firstkey(dbm
); RTEST(keystr
);
1143 keystr
= rb_gdbm_nextkey(dbm
, keystr
)) {
1145 rb_hash_aset(hash
, keystr
, rb_gdbm_fetch2(dbm
, keystr
));
1153 * gdbm.reject { |key, value| block } -> hash
1155 * Returns a hash copy of _gdbm_ where all key-value pairs from _gdbm_ for
1156 * which _block_ evaluates to true are removed. See also: #delete_if
1159 fgdbm_reject(VALUE obj
)
1161 return rb_hash_delete_if(fgdbm_to_hash(obj
));
1167 rb_cGDBM
= rb_define_class("GDBM", rb_cObject
);
1168 rb_eGDBMError
= rb_define_class("GDBMError", rb_eStandardError
);
1169 rb_eGDBMFatalError
= rb_define_class("GDBMFatalError", rb_eException
);
1170 rb_include_module(rb_cGDBM
, rb_mEnumerable
);
1172 rb_define_alloc_func(rb_cGDBM
, fgdbm_s_alloc
);
1173 rb_define_singleton_method(rb_cGDBM
, "open", fgdbm_s_open
, -1);
1175 rb_define_method(rb_cGDBM
, "initialize", fgdbm_initialize
, -1);
1176 rb_define_method(rb_cGDBM
, "close", fgdbm_close
, 0);
1177 rb_define_method(rb_cGDBM
, "closed?", fgdbm_closed
, 0);
1178 rb_define_method(rb_cGDBM
, "[]", fgdbm_aref
, 1);
1179 rb_define_method(rb_cGDBM
, "fetch", fgdbm_fetch_m
, -1);
1180 rb_define_method(rb_cGDBM
, "[]=", fgdbm_store
, 2);
1181 rb_define_method(rb_cGDBM
, "store", fgdbm_store
, 2);
1182 rb_define_method(rb_cGDBM
, "index", fgdbm_index
, 1);
1183 rb_define_method(rb_cGDBM
, "select", fgdbm_select
, 0);
1184 rb_define_method(rb_cGDBM
, "values_at", fgdbm_values_at
, -1);
1185 rb_define_method(rb_cGDBM
, "length", fgdbm_length
, 0);
1186 rb_define_method(rb_cGDBM
, "size", fgdbm_length
, 0);
1187 rb_define_method(rb_cGDBM
, "empty?", fgdbm_empty_p
, 0);
1188 rb_define_method(rb_cGDBM
, "each", fgdbm_each_pair
, 0);
1189 rb_define_method(rb_cGDBM
, "each_value", fgdbm_each_value
, 0);
1190 rb_define_method(rb_cGDBM
, "each_key", fgdbm_each_key
, 0);
1191 rb_define_method(rb_cGDBM
, "each_pair", fgdbm_each_pair
, 0);
1192 rb_define_method(rb_cGDBM
, "keys", fgdbm_keys
, 0);
1193 rb_define_method(rb_cGDBM
, "values", fgdbm_values
, 0);
1194 rb_define_method(rb_cGDBM
, "shift", fgdbm_shift
, 0);
1195 rb_define_method(rb_cGDBM
, "delete", fgdbm_delete
, 1);
1196 rb_define_method(rb_cGDBM
, "delete_if", fgdbm_delete_if
, 0);
1197 rb_define_method(rb_cGDBM
, "reject!", fgdbm_delete_if
, 0);
1198 rb_define_method(rb_cGDBM
, "reject", fgdbm_reject
, 0);
1199 rb_define_method(rb_cGDBM
, "clear", fgdbm_clear
, 0);
1200 rb_define_method(rb_cGDBM
, "invert", fgdbm_invert
, 0);
1201 rb_define_method(rb_cGDBM
, "update", fgdbm_update
, 1);
1202 rb_define_method(rb_cGDBM
, "replace", fgdbm_replace
, 1);
1203 rb_define_method(rb_cGDBM
, "reorganize", fgdbm_reorganize
, 0);
1204 rb_define_method(rb_cGDBM
, "sync", fgdbm_sync
, 0);
1205 /* rb_define_method(rb_cGDBM, "setopt", fgdbm_setopt, 2); */
1206 rb_define_method(rb_cGDBM
, "cachesize=", fgdbm_set_cachesize
, 1);
1207 rb_define_method(rb_cGDBM
, "fastmode=", fgdbm_set_fastmode
, 1);
1208 rb_define_method(rb_cGDBM
, "syncmode=", fgdbm_set_syncmode
, 1);
1210 rb_define_method(rb_cGDBM
, "include?", fgdbm_has_key
, 1);
1211 rb_define_method(rb_cGDBM
, "has_key?", fgdbm_has_key
, 1);
1212 rb_define_method(rb_cGDBM
, "member?", fgdbm_has_key
, 1);
1213 rb_define_method(rb_cGDBM
, "has_value?", fgdbm_has_value
, 1);
1214 rb_define_method(rb_cGDBM
, "key?", fgdbm_has_key
, 1);
1215 rb_define_method(rb_cGDBM
, "value?", fgdbm_has_value
, 1);
1217 rb_define_method(rb_cGDBM
, "to_a", fgdbm_to_a
, 0);
1218 rb_define_method(rb_cGDBM
, "to_hash", fgdbm_to_hash
, 0);
1220 /* flag for #new and #open: open database as a reader */
1221 rb_define_const(rb_cGDBM
, "READER", INT2FIX(GDBM_READER
|RUBY_GDBM_RW_BIT
));
1222 /* flag for #new and #open: open database as a writer */
1223 rb_define_const(rb_cGDBM
, "WRITER", INT2FIX(GDBM_WRITER
|RUBY_GDBM_RW_BIT
));
1224 /* flag for #new and #open: open database as a writer; if the database does not exist, create a new one */
1225 rb_define_const(rb_cGDBM
, "WRCREAT", INT2FIX(GDBM_WRCREAT
|RUBY_GDBM_RW_BIT
));
1226 /* flag for #new and #open: open database as a writer; overwrite any existing databases */
1227 rb_define_const(rb_cGDBM
, "NEWDB", INT2FIX(GDBM_NEWDB
|RUBY_GDBM_RW_BIT
));
1229 /* flag for #new and #open. this flag is obsolete for gdbm >= 1.8 */
1230 rb_define_const(rb_cGDBM
, "FAST", INT2FIX(GDBM_FAST
));
1231 /* this flag is obsolete in gdbm 1.8.
1232 On gdbm 1.8, fast mode is default behavior. */
1234 /* gdbm version 1.8 specific */
1235 #if defined(GDBM_SYNC)
1236 /* flag for #new and #open. only for gdbm >= 1.8 */
1237 rb_define_const(rb_cGDBM
, "SYNC", INT2FIX(GDBM_SYNC
));
1239 #if defined(GDBM_NOLOCK)
1240 /* flag for #new and #open */
1241 rb_define_const(rb_cGDBM
, "NOLOCK", INT2FIX(GDBM_NOLOCK
));
1243 /* version of the gdbm library*/
1244 rb_define_const(rb_cGDBM
, "VERSION", rb_str_new2(gdbm_version
));