gdbm 1.3.1 → 2.0.0.beta1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/ext/gdbm/extconf.rb +19 -0
- data/ext/gdbm/gdbm.c +1309 -0
- metadata +79 -20
- data/README.md +0 -58
- data/lib/gdbm.rb +0 -608
metadata
CHANGED
@@ -1,27 +1,86 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: gdbm
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 2.0.0.beta1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
|
-
-
|
8
|
-
autorequire:
|
9
|
-
bindir:
|
7
|
+
- Yukihiro Matsumoto
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
12
|
-
dependencies:
|
13
|
-
|
11
|
+
date: 2017-04-28 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.14'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.14'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '10.0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '10.0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rake-compiler
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: test-unit
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
description: Ruby extension for GNU dbm.
|
14
70
|
email:
|
71
|
+
- matz@ruby-lang.org
|
15
72
|
executables: []
|
16
|
-
extensions:
|
73
|
+
extensions:
|
74
|
+
- ext/gdbm/extconf.rb
|
17
75
|
extra_rdoc_files: []
|
18
76
|
files:
|
19
|
-
-
|
20
|
-
-
|
21
|
-
homepage:
|
22
|
-
licenses:
|
77
|
+
- ext/gdbm/extconf.rb
|
78
|
+
- ext/gdbm/gdbm.c
|
79
|
+
homepage: https://github.com/ruby/gdbm
|
80
|
+
licenses:
|
81
|
+
- BSD-2-Clause
|
23
82
|
metadata: {}
|
24
|
-
post_install_message:
|
83
|
+
post_install_message:
|
25
84
|
rdoc_options: []
|
26
85
|
require_paths:
|
27
86
|
- lib
|
@@ -29,16 +88,16 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
29
88
|
requirements:
|
30
89
|
- - ">="
|
31
90
|
- !ruby/object:Gem::Version
|
32
|
-
version:
|
91
|
+
version: 2.5.0dev
|
33
92
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
34
93
|
requirements:
|
35
|
-
- - "
|
94
|
+
- - ">"
|
36
95
|
- !ruby/object:Gem::Version
|
37
|
-
version:
|
96
|
+
version: 1.3.1
|
38
97
|
requirements: []
|
39
|
-
rubyforge_project:
|
40
|
-
rubygems_version: 2.
|
41
|
-
signing_key:
|
98
|
+
rubyforge_project:
|
99
|
+
rubygems_version: 2.6.11
|
100
|
+
signing_key:
|
42
101
|
specification_version: 4
|
43
|
-
summary:
|
102
|
+
summary: Ruby extension for GNU dbm.
|
44
103
|
test_files: []
|
data/README.md
DELETED
@@ -1,58 +0,0 @@
|
|
1
|
-
## ffi-gdbm
|
2
|
-
|
3
|
-
An attempt to make [gdbm](http://www.vivtek.com/gdbm/) available beyond the C Ruby implementation.
|
4
|
-
|
5
|
-
Faithfully mimics MRI's standard library and is compatible with gdbm files produced by that version.
|
6
|
-
|
7
|
-
## Installing
|
8
|
-
|
9
|
-
You can download and use `gdbm.rb` anyhow you would like.
|
10
|
-
|
11
|
-
You can also install it using Ruby Gems:
|
12
|
-
|
13
|
-
`gem install gdbm`
|
14
|
-
|
15
|
-
or, if using JRuby:
|
16
|
-
|
17
|
-
`jgem install gdbm`
|
18
|
-
|
19
|
-
JRuby does not require further installation, but Rubinius will need the FFI gem:
|
20
|
-
|
21
|
-
`gem install ffi`
|
22
|
-
|
23
|
-
## Notes
|
24
|
-
|
25
|
-
* Conforms to tests from MRI 1.8.7 and 1.9.1 and follows the C library for MRI if there are contradictions with the documentation
|
26
|
-
* Should be compatible with gdbm files created with MRI's standard library
|
27
|
-
* Certainly works with JRuby, may work with other alternative Ruby implementations
|
28
|
-
|
29
|
-
## Status
|
30
|
-
|
31
|
-
Tests passing on 64 bit Linux with
|
32
|
-
|
33
|
-
* JRuby 1.7.21 and 9.0.5.0
|
34
|
-
|
35
|
-
### Older Tests
|
36
|
-
|
37
|
-
Passing all tests with JRuby 1.4, 1.5.3, 1.6 on 32-bit Linux.
|
38
|
-
|
39
|
-
Passing all tests with MRI Ruby 1.8.7, 1.9.1, 1.9.2 with Ruby-FFI 0.5.4, 0.6.3, 1.0.7 on 32-bit Linux.
|
40
|
-
|
41
|
-
Something weird happens with temp files (used in tests) with JRuby on Ubuntu. For some reason, it gets permission denied when trying to delete them. Any thoughts on that would be helpful.
|
42
|
-
|
43
|
-
Further testing on other systems is welcome!
|
44
|
-
|
45
|
-
## Testing
|
46
|
-
|
47
|
-
Two sets of tests are included, copied straight from the MRI distribution. However, they do require the use of ObjectSpace, so this is how to run them with JRuby:
|
48
|
-
|
49
|
-
`jruby --1.8 -X+O -r lib/gdbm test/test_gdbm-1.8.7.rb` (Note: only works with JRuby prior to 9.0.0.0)
|
50
|
-
|
51
|
-
`jruby -X+O -r ./lib/gdbm test/test_gdbm-1.9.1.rb`
|
52
|
-
|
53
|
-
## License
|
54
|
-
|
55
|
-
Copyright (c), Justin Collins
|
56
|
-
|
57
|
-
This library is released under the same tri-license (GPL/LGPL/CPL) as JRuby.
|
58
|
-
Please see the COPYING file distributed with JRuby for details.
|
data/lib/gdbm.rb
DELETED
@@ -1,608 +0,0 @@
|
|
1
|
-
=begin
|
2
|
-
JRuby access to gdbm via FFI. Faithfully mimics MRI's standard library and is
|
3
|
-
compatible with gdbm files produced by that version.
|
4
|
-
|
5
|
-
Author: Justin Collins
|
6
|
-
Based on the C version by: yugui
|
7
|
-
Website: http://github.com/presidentbeef/ffi-gdbm
|
8
|
-
Documentation: http://ruby-doc.org/stdlib/libdoc/gdbm/rdoc/classes/GDBM.html
|
9
|
-
JRuby: http://www.jruby.org/
|
10
|
-
gdbm: http://directory.fsf.org/project/gdbm/
|
11
|
-
|
12
|
-
Copyright (c) 2009, Justin Collins
|
13
|
-
|
14
|
-
This library is released under the same tri-license (GPL/LGPL/CPL) as JRuby.
|
15
|
-
Please see the COPYING file distributed with JRuby for details.
|
16
|
-
=end
|
17
|
-
|
18
|
-
unless defined? FFI
|
19
|
-
require 'ffi'
|
20
|
-
end
|
21
|
-
|
22
|
-
module GDBM_FFI
|
23
|
-
extend FFI::Library
|
24
|
-
ffi_lib "gdbm"
|
25
|
-
|
26
|
-
#Note that MRI does not store the null byte, so neither does this version,
|
27
|
-
#even though FFI automatically appends one to the String.
|
28
|
-
class Datum < FFI::Struct
|
29
|
-
layout :dptr, :pointer, :dsize, :int
|
30
|
-
|
31
|
-
#Expects either a MemoryPointer or a String as an argument.
|
32
|
-
#If it is given a String, it will initialize the fields, including
|
33
|
-
#setting dsize.
|
34
|
-
def initialize(*args)
|
35
|
-
if args.length == 1 and args[0].is_a? String
|
36
|
-
super()
|
37
|
-
self.dptr = args[0]
|
38
|
-
self[:dsize] = args[0].bytesize
|
39
|
-
else
|
40
|
-
super
|
41
|
-
end
|
42
|
-
end
|
43
|
-
|
44
|
-
def value
|
45
|
-
if self[:dptr].nil? or self[:dptr].null?
|
46
|
-
nil
|
47
|
-
else
|
48
|
-
self[:dptr].read_string(self.size)
|
49
|
-
end
|
50
|
-
end
|
51
|
-
|
52
|
-
#_Do not use_. Creates a new MemoryPointer from the String.
|
53
|
-
def dptr=(str)
|
54
|
-
@dptr = FFI::MemoryPointer.from_string(str)
|
55
|
-
self[:dptr] = @dptr
|
56
|
-
end
|
57
|
-
|
58
|
-
#Returns the size of the stored String.
|
59
|
-
def size
|
60
|
-
self[:dsize]
|
61
|
-
end
|
62
|
-
end
|
63
|
-
|
64
|
-
callback :fatal_func, [:string], :void
|
65
|
-
|
66
|
-
#Attach gdbm functions
|
67
|
-
attach_function :gdbm_open, [ :string, :int, :int, :int, :fatal_func ], :pointer
|
68
|
-
attach_function :close, :gdbm_close, [ :pointer ], :void
|
69
|
-
attach_function :gdbm_store, [ :pointer, Datum.by_value, Datum.by_value, :int ], :int
|
70
|
-
attach_function :gdbm_fetch, [ :pointer, Datum.by_value ], Datum.by_value
|
71
|
-
attach_function :gdbm_delete, [ :pointer, Datum.by_value ], :int
|
72
|
-
attach_function :gdbm_firstkey, [ :pointer ], Datum.by_value
|
73
|
-
attach_function :gdbm_nextkey, [ :pointer, Datum.by_value ], Datum.by_value
|
74
|
-
attach_function :reorganize, :gdbm_reorganize, [ :pointer ], :int
|
75
|
-
attach_function :sync, :gdbm_sync, [ :pointer ], :void
|
76
|
-
attach_function :gdbm_exists, [ :pointer, Datum.by_value ], :int
|
77
|
-
attach_function :set_opt, :gdbm_setopt, [ :pointer, :int, :pointer, :int ], :int
|
78
|
-
attach_function :error_string, :gdbm_strerror, [ :int ], :string
|
79
|
-
|
80
|
-
READER = 0
|
81
|
-
WRITER = 1
|
82
|
-
WRCREAT = 2
|
83
|
-
NEWDB = 3
|
84
|
-
FAST = 0x10
|
85
|
-
SYNC = 0x20
|
86
|
-
NOLOCK = 0x40
|
87
|
-
REPLACE = 1
|
88
|
-
CACHE_SIZE = 1
|
89
|
-
FAST_MODE = 2
|
90
|
-
SYNC_MODE = 3
|
91
|
-
CANT_BE_READER = 9
|
92
|
-
CANT_BE_WRITER = 10
|
93
|
-
FILE_OPEN_ERROR = 3
|
94
|
-
|
95
|
-
FATAL = Proc.new { |msg| raise RuntimeError, msg }
|
96
|
-
|
97
|
-
attach_variable :error_number, :gdbm_errno, :int
|
98
|
-
attach_variable :VERSION, :gdbm_version, :string
|
99
|
-
|
100
|
-
#Store the given Strings in _file_. _file_ is always GDBM_FILE pointer in these functions.
|
101
|
-
def self.store(file, key, value)
|
102
|
-
key_datum = Datum.new key
|
103
|
-
val_datum = Datum.new value
|
104
|
-
|
105
|
-
result = gdbm_store file, key_datum, val_datum, GDBM_FFI::REPLACE
|
106
|
-
raise GDBMError, last_error if result != 0
|
107
|
-
end
|
108
|
-
|
109
|
-
#Fetch a String from the _file_ matching the given _key_. Returns _nil_ if
|
110
|
-
#there is no such key.
|
111
|
-
def self.fetch(file, key)
|
112
|
-
key_datum = Datum.new key
|
113
|
-
|
114
|
-
val_datum = gdbm_fetch file, key_datum
|
115
|
-
|
116
|
-
val_datum.value
|
117
|
-
end
|
118
|
-
|
119
|
-
#Returns the first key in the _file_.
|
120
|
-
def self.first_key(file)
|
121
|
-
key_datum = GDBM_FFI.gdbm_firstkey file
|
122
|
-
key_datum.value
|
123
|
-
end
|
124
|
-
|
125
|
-
#Deletes the _key_ from the _file_.
|
126
|
-
def self.delete(file, key)
|
127
|
-
return nil if not self.exists? file, key
|
128
|
-
key_datum = Datum.new key
|
129
|
-
result = gdbm_delete file, key_datum
|
130
|
-
raise GDBMError, last_error if result != 0
|
131
|
-
end
|
132
|
-
|
133
|
-
#Checks if the _file_ contains the given _key_.
|
134
|
-
def self.exists?(file, key)
|
135
|
-
key_datum = Datum.new key
|
136
|
-
|
137
|
-
gdbm_exists(file, key_datum) != 0
|
138
|
-
end
|
139
|
-
|
140
|
-
#Iterates over each _key_, _value_ pair in the _file_.
|
141
|
-
def self.each_pair(file)
|
142
|
-
current = self.gdbm_firstkey file
|
143
|
-
until current.value.nil?
|
144
|
-
value = gdbm_fetch file, current
|
145
|
-
yield current.value, value.value
|
146
|
-
current = self.gdbm_nextkey file, current
|
147
|
-
end
|
148
|
-
end
|
149
|
-
|
150
|
-
#Iterates over each key in the _file_.
|
151
|
-
def self.each_key(file)
|
152
|
-
keys = []
|
153
|
-
current = self.gdbm_firstkey file
|
154
|
-
until current.value.nil?
|
155
|
-
if block_given?
|
156
|
-
yield current.value
|
157
|
-
else
|
158
|
-
keys << current.value
|
159
|
-
end
|
160
|
-
current = self.gdbm_nextkey file, current
|
161
|
-
end
|
162
|
-
block_given? ? nil : keys.each
|
163
|
-
end
|
164
|
-
|
165
|
-
#Iterates over each value in the _file_.
|
166
|
-
def self.each_value(file)
|
167
|
-
current = self.gdbm_firstkey file
|
168
|
-
until current.value.nil?
|
169
|
-
value = gdbm_fetch file, current
|
170
|
-
yield value.value
|
171
|
-
current = self.gdbm_nextkey file, current
|
172
|
-
end
|
173
|
-
end
|
174
|
-
|
175
|
-
#Deletes all keys and values from the _file_.
|
176
|
-
def self.clear(file)
|
177
|
-
until (key = self.gdbm_firstkey(file)).value.nil?
|
178
|
-
until key.value.nil?
|
179
|
-
next_key = self.gdbm_nextkey(file, key)
|
180
|
-
result = self.gdbm_delete file, key
|
181
|
-
raise GDBMError, last_error if result != 0
|
182
|
-
key = next_key
|
183
|
-
end
|
184
|
-
end
|
185
|
-
end
|
186
|
-
|
187
|
-
#Returns the last error encountered from the gdbm library as a String.
|
188
|
-
def self.last_error
|
189
|
-
error_string(error_number)
|
190
|
-
end
|
191
|
-
|
192
|
-
#Opens a gdbm file. Returns the GDBM_FILE pointer, which should be treated
|
193
|
-
#as an opaque value, to be passed in to GDBM_FFI methods.
|
194
|
-
def self.open(filename, blocksize, flags, mode)
|
195
|
-
self.gdbm_open filename, blocksize, flags, mode, FATAL
|
196
|
-
end
|
197
|
-
|
198
|
-
#Sets the cache size.
|
199
|
-
def self.set_cache_size(file, size)
|
200
|
-
opt = FFI::MemoryPointer.new size
|
201
|
-
self.set_opt file, CACHE_SIZE, opt, opt.size
|
202
|
-
end
|
203
|
-
|
204
|
-
#Sets the sync mode.
|
205
|
-
def self.set_sync_mode(file, boolean)
|
206
|
-
if boolean
|
207
|
-
opt = FFI::MemoryPointer.new 1
|
208
|
-
else
|
209
|
-
opt = FFI::MemoryPointer.new 0
|
210
|
-
end
|
211
|
-
|
212
|
-
self.set_opt file, SYNC_MODE, opt, opt.size
|
213
|
-
end
|
214
|
-
end
|
215
|
-
|
216
|
-
class GDBMError < StandardError; end
|
217
|
-
class GDBMFatalError < Exception; end
|
218
|
-
|
219
|
-
class GDBM
|
220
|
-
include Enumerable
|
221
|
-
|
222
|
-
#This constant is to check if a flag is READER, WRITER, WRCREAT, or NEWDB
|
223
|
-
RUBY_GDBM_RW_BIT = 0x20000000
|
224
|
-
|
225
|
-
BLOCKSIZE = 2048
|
226
|
-
READER = GDBM_FFI::READER | RUBY_GDBM_RW_BIT
|
227
|
-
WRITER = GDBM_FFI::WRITER | RUBY_GDBM_RW_BIT
|
228
|
-
WRCREAT = GDBM_FFI::WRCREAT | RUBY_GDBM_RW_BIT
|
229
|
-
NEWDB = GDBM_FFI::NEWDB | RUBY_GDBM_RW_BIT
|
230
|
-
FAST = GDBM_FFI::FAST
|
231
|
-
SYNC = GDBM_FFI::SYNC
|
232
|
-
NOLOCK = GDBM_FFI::NOLOCK
|
233
|
-
VERSION = GDBM_FFI.VERSION
|
234
|
-
|
235
|
-
def initialize(filename, mode = 0666, flags = nil)
|
236
|
-
|
237
|
-
mode = -1 if mode.nil?
|
238
|
-
flags = 0 if flags.nil?
|
239
|
-
@file = nil
|
240
|
-
|
241
|
-
if flags & RUBY_GDBM_RW_BIT != 0 #Check if flags are appropriate
|
242
|
-
flags &= ~RUBY_GDBM_RW_BIT #Remove check to make flag match GDBM constants
|
243
|
-
|
244
|
-
@file = GDBM_FFI.open filename, BLOCKSIZE, flags, mode
|
245
|
-
else
|
246
|
-
if mode >= 0
|
247
|
-
@file = GDBM_FFI.open filename, BLOCKSIZE, WRCREAT | flags, mode
|
248
|
-
end
|
249
|
-
|
250
|
-
@file = GDBM_FFI.open filename, BLOCKSIZE, WRITER | flags, 0 if @file.nil? or @file.null?
|
251
|
-
@file = GDBM_FFI.open filename, BLOCKSIZE, READER | flags, 0 if @file.nil? or @file.null?
|
252
|
-
end
|
253
|
-
|
254
|
-
if @file.nil? or @file.null?
|
255
|
-
return if mode == -1 #C code returns Qnil, but we can't
|
256
|
-
if GDBM_FFI.error_number == GDBM_FFI::FILE_OPEN_ERROR ||
|
257
|
-
GDBM_FFI.error_number == GDBM_FFI::CANT_BE_READER ||
|
258
|
-
GDBM_FFI.error_number == GDBM_FFI::CANT_BE_WRITER
|
259
|
-
|
260
|
-
raise SystemCallError.new(GDBM_FFI.last_error, FFI.errno)
|
261
|
-
else
|
262
|
-
raise GDBMError, GDBM_FFI.last_error;
|
263
|
-
end
|
264
|
-
end
|
265
|
-
end
|
266
|
-
|
267
|
-
def self.open(filename, mode = 0666, flags = nil)
|
268
|
-
obj = self.new filename, mode, flags
|
269
|
-
|
270
|
-
if block_given?
|
271
|
-
begin
|
272
|
-
result = yield obj
|
273
|
-
ensure
|
274
|
-
obj.close unless obj.closed?
|
275
|
-
end
|
276
|
-
result
|
277
|
-
elsif obj.nil?
|
278
|
-
nil
|
279
|
-
else
|
280
|
-
obj
|
281
|
-
end
|
282
|
-
end
|
283
|
-
|
284
|
-
def [](key)
|
285
|
-
GDBM_FFI.fetch file, key
|
286
|
-
end
|
287
|
-
|
288
|
-
def []=(key, value)
|
289
|
-
modifiable?
|
290
|
-
GDBM_FFI.store file, key, value
|
291
|
-
end
|
292
|
-
|
293
|
-
alias :store :[]=
|
294
|
-
|
295
|
-
def cachesize=(size)
|
296
|
-
GDBM_FFI.set_cache_size file, size
|
297
|
-
end
|
298
|
-
|
299
|
-
def clear
|
300
|
-
modifiable?
|
301
|
-
GDBM_FFI.clear file
|
302
|
-
self
|
303
|
-
end
|
304
|
-
|
305
|
-
def close
|
306
|
-
if closed?
|
307
|
-
raise RuntimeError, "closed GDBM file"
|
308
|
-
else
|
309
|
-
GDBM_FFI.close @file
|
310
|
-
@file = nil unless frozen?
|
311
|
-
end
|
312
|
-
end
|
313
|
-
|
314
|
-
def closed?
|
315
|
-
@file.nil? or @file.null?
|
316
|
-
end
|
317
|
-
|
318
|
-
def delete(key)
|
319
|
-
modifiable?
|
320
|
-
value = self[key]
|
321
|
-
#This is bizarre and not mentioned in the docs,
|
322
|
-
#but this is what the tests expect and what the MRI
|
323
|
-
#version does.
|
324
|
-
if value.nil? and block_given?
|
325
|
-
value = yield key
|
326
|
-
end
|
327
|
-
GDBM_FFI.delete file, key
|
328
|
-
value
|
329
|
-
end
|
330
|
-
|
331
|
-
def delete_if
|
332
|
-
modifiable?
|
333
|
-
rejects = []
|
334
|
-
begin
|
335
|
-
GDBM_FFI.each_pair(file) do |k,v|
|
336
|
-
if yield k, v
|
337
|
-
rejects << k
|
338
|
-
end
|
339
|
-
end
|
340
|
-
#unsure about this, but it handles breaking during
|
341
|
-
#the iteration
|
342
|
-
ensure
|
343
|
-
rejects.each do |k|
|
344
|
-
GDBM_FFI.delete file, k
|
345
|
-
end
|
346
|
-
end
|
347
|
-
|
348
|
-
self
|
349
|
-
end
|
350
|
-
|
351
|
-
alias :reject! :delete_if
|
352
|
-
|
353
|
-
def each_key(&block)
|
354
|
-
enumerator = GDBM_FFI.each_key(file, &block)
|
355
|
-
enumerator || self
|
356
|
-
end
|
357
|
-
|
358
|
-
def each_pair(&block)
|
359
|
-
GDBM_FFI.each_pair file, &block
|
360
|
-
self
|
361
|
-
end
|
362
|
-
|
363
|
-
alias :each :each_pair
|
364
|
-
|
365
|
-
def each_value(&block)
|
366
|
-
GDBM_FFI.each_value file, &block
|
367
|
-
self
|
368
|
-
end
|
369
|
-
|
370
|
-
def empty?
|
371
|
-
key = GDBM_FFI.first_key file
|
372
|
-
key.nil?
|
373
|
-
end
|
374
|
-
|
375
|
-
def fastmode=(boolean)
|
376
|
-
GDBM_FFI.set_sync_mode file, !boolean
|
377
|
-
end
|
378
|
-
|
379
|
-
def fetch(key, default = nil)
|
380
|
-
result = GDBM_FFI.fetch file, key
|
381
|
-
if result.nil?
|
382
|
-
if default
|
383
|
-
default
|
384
|
-
elsif block_given?
|
385
|
-
yield key
|
386
|
-
else
|
387
|
-
raise IndexError, "key not found"
|
388
|
-
end
|
389
|
-
else
|
390
|
-
result
|
391
|
-
end
|
392
|
-
end
|
393
|
-
|
394
|
-
def has_key?(key)
|
395
|
-
GDBM_FFI.exists? file, key
|
396
|
-
end
|
397
|
-
|
398
|
-
alias :key? :has_key?
|
399
|
-
alias :member? :has_key?
|
400
|
-
alias :include? :has_key?
|
401
|
-
|
402
|
-
def has_value?(value)
|
403
|
-
GDBM_FFI.each_value(file) do |v|
|
404
|
-
if v == value
|
405
|
-
return true
|
406
|
-
end
|
407
|
-
end
|
408
|
-
false
|
409
|
-
end
|
410
|
-
|
411
|
-
alias :value? :has_value?
|
412
|
-
|
413
|
-
def index(value)
|
414
|
-
if RUBY_VERSION >= "1.9"
|
415
|
-
warn "GDBM#index is deprecated; use GDBM#key"
|
416
|
-
end
|
417
|
-
|
418
|
-
self.key(value)
|
419
|
-
end
|
420
|
-
|
421
|
-
def invert
|
422
|
-
result = {}
|
423
|
-
|
424
|
-
GDBM_FFI.each_pair(file) do |k,v|
|
425
|
-
result[v] = k
|
426
|
-
end
|
427
|
-
|
428
|
-
result
|
429
|
-
end
|
430
|
-
|
431
|
-
def key(value)
|
432
|
-
GDBM_FFI.each_pair(file) do |k,v|
|
433
|
-
if v == value
|
434
|
-
return k
|
435
|
-
end
|
436
|
-
end
|
437
|
-
nil
|
438
|
-
end
|
439
|
-
|
440
|
-
def keys
|
441
|
-
keys = []
|
442
|
-
|
443
|
-
GDBM_FFI.each_key(file) do |k|
|
444
|
-
keys << k
|
445
|
-
end
|
446
|
-
|
447
|
-
keys
|
448
|
-
end
|
449
|
-
|
450
|
-
def length
|
451
|
-
len = 0
|
452
|
-
|
453
|
-
GDBM_FFI.each_key(file) do |k|
|
454
|
-
len = len + 1
|
455
|
-
end
|
456
|
-
|
457
|
-
len
|
458
|
-
end
|
459
|
-
|
460
|
-
alias :size :length
|
461
|
-
|
462
|
-
def nil?
|
463
|
-
@file.nil? or @file.null?
|
464
|
-
end
|
465
|
-
|
466
|
-
def reject
|
467
|
-
result = {}
|
468
|
-
|
469
|
-
GDBM_FFI.each_pair(file) do |k,v|
|
470
|
-
if not yield k, v
|
471
|
-
result[k] = v
|
472
|
-
end
|
473
|
-
end
|
474
|
-
|
475
|
-
result
|
476
|
-
end
|
477
|
-
|
478
|
-
def reorganize
|
479
|
-
modifiable?
|
480
|
-
GDBM_FFI.reorganize file
|
481
|
-
self
|
482
|
-
end
|
483
|
-
|
484
|
-
def replace(other)
|
485
|
-
self.clear
|
486
|
-
self.update other
|
487
|
-
self
|
488
|
-
end
|
489
|
-
|
490
|
-
def select(*args)
|
491
|
-
result = []
|
492
|
-
#This method behaves completely contrary to what the docs state:
|
493
|
-
#http://ruby-doc.org/stdlib/libdoc/gdbm/rdoc/classes/GDBM.html#M000318
|
494
|
-
#Instead, it yields a pair and returns [[k1, v1], [k2, v2], ...]
|
495
|
-
#But this is how it is in 1.8.7 and 1.9.1, so...
|
496
|
-
#
|
497
|
-
#Update: Docs have been patched: http://redmine.ruby-lang.org/repositories/revision/1?rev=25300
|
498
|
-
|
499
|
-
if block_given?
|
500
|
-
if args.length > 0
|
501
|
-
raise ArgumentError, "wrong number of arguments(#{args.length} for 0)"
|
502
|
-
end
|
503
|
-
|
504
|
-
GDBM_FFI.each_pair(file) do |k, v|
|
505
|
-
if yield k, v
|
506
|
-
result << [k, v]
|
507
|
-
end
|
508
|
-
end
|
509
|
-
#This is for 1.8.7 compatibility
|
510
|
-
elsif RUBY_VERSION <= "1.8.7"
|
511
|
-
warn "GDBM#select(index..) is deprecated; use GDBM#values_at"
|
512
|
-
|
513
|
-
result = values_at(*args)
|
514
|
-
else
|
515
|
-
result = []
|
516
|
-
end
|
517
|
-
|
518
|
-
result
|
519
|
-
end
|
520
|
-
|
521
|
-
def shift
|
522
|
-
modifiable?
|
523
|
-
key = GDBM_FFI.first_key file
|
524
|
-
if key
|
525
|
-
value = GDBM_FFI.fetch file, key
|
526
|
-
GDBM_FFI.delete file, key
|
527
|
-
[key, value]
|
528
|
-
else
|
529
|
-
nil
|
530
|
-
end
|
531
|
-
end
|
532
|
-
|
533
|
-
def sync
|
534
|
-
modifiable?
|
535
|
-
GDBM_FFI.sync file
|
536
|
-
self
|
537
|
-
end
|
538
|
-
|
539
|
-
def syncmode=(boolean)
|
540
|
-
GDBM_FFI.set_sync_mode file, boolean
|
541
|
-
end
|
542
|
-
|
543
|
-
def to_a
|
544
|
-
result = []
|
545
|
-
GDBM_FFI.each_pair(file) do |k,v|
|
546
|
-
result << [k, v]
|
547
|
-
end
|
548
|
-
result
|
549
|
-
end
|
550
|
-
|
551
|
-
def to_hash
|
552
|
-
result = {}
|
553
|
-
GDBM_FFI.each_pair(file) do |k,v|
|
554
|
-
result[k] = v
|
555
|
-
end
|
556
|
-
result
|
557
|
-
end
|
558
|
-
|
559
|
-
def update(other)
|
560
|
-
other.each_pair do |k,v|
|
561
|
-
GDBM_FFI.store file, k, v
|
562
|
-
end
|
563
|
-
self
|
564
|
-
end
|
565
|
-
|
566
|
-
def values
|
567
|
-
values = []
|
568
|
-
|
569
|
-
GDBM_FFI.each_value(file) do |v|
|
570
|
-
values << v
|
571
|
-
end
|
572
|
-
|
573
|
-
values
|
574
|
-
end
|
575
|
-
|
576
|
-
def values_at(*keys)
|
577
|
-
results = []
|
578
|
-
|
579
|
-
keys.each do |k|
|
580
|
-
results << self[k]
|
581
|
-
end
|
582
|
-
|
583
|
-
results
|
584
|
-
end
|
585
|
-
|
586
|
-
private
|
587
|
-
|
588
|
-
def modifiable?
|
589
|
-
#raise SecurityError, "Insecure operation at level #$SAFE" if $SAFE >= 4 #Not currently supported in JRuby
|
590
|
-
if self.frozen?
|
591
|
-
if RUBY_VERSION > "1.8.7"
|
592
|
-
raise RuntimeError, "Can't modify frozen #{self}"
|
593
|
-
else
|
594
|
-
raise TypeError, "Can't modify frozen #{self}"
|
595
|
-
end
|
596
|
-
end
|
597
|
-
end
|
598
|
-
|
599
|
-
#Raises a RuntimeError if the file is closed.
|
600
|
-
def file
|
601
|
-
unless @file.nil? or @file.null?
|
602
|
-
@file
|
603
|
-
else
|
604
|
-
raise(RuntimeError, "closed GDBM file")
|
605
|
-
end
|
606
|
-
end
|
607
|
-
end
|
608
|
-
|