tdb 0.1.0
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/.document +8 -0
- data/.gitignore +19 -0
- data/COPYING +165 -0
- data/GIT-VERSION-GEN +40 -0
- data/GNUmakefile +190 -0
- data/Hash_Functions +67 -0
- data/LICENSE +17 -0
- data/README +57 -0
- data/Rakefile +140 -0
- data/TODO +7 -0
- data/ext/tdb/djb.c +26 -0
- data/ext/tdb/extconf.rb +12 -0
- data/ext/tdb/fnv.c +28 -0
- data/ext/tdb/lookup3.c +429 -0
- data/ext/tdb/murmur1.c +151 -0
- data/ext/tdb/murmur2.c +290 -0
- data/ext/tdb/rbtdb.h +22 -0
- data/ext/tdb/tdb.c +690 -0
- data/lib/tdb.rb +2 -0
- data/setup.rb +1586 -0
- data/tdb.gemspec +36 -0
- data/test/test_tdb.rb +260 -0
- metadata +105 -0
data/tdb.gemspec
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
ENV["VERSION"] or abort "VERSION= must be specified"
|
2
|
+
manifest = File.readlines('.manifest').map! { |x| x.chomp! }
|
3
|
+
summary = File.readlines("README")[0].gsub(/\A=\s+\S+[^\w]+/, '').strip
|
4
|
+
description = File.read("README").split(/\n\n/)[1].strip
|
5
|
+
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = %q{tdb}
|
8
|
+
s.version = ENV["VERSION"]
|
9
|
+
|
10
|
+
s.homepage = 'http://bogomips.org/ruby-tdb/'
|
11
|
+
s.authors = ["Ruby tdb hackers"]
|
12
|
+
s.date = Time.now.utc.strftime('%Y-%m-%d')
|
13
|
+
s.description = description
|
14
|
+
s.email = %q{ruby.tdb@librelist.org}
|
15
|
+
|
16
|
+
s.extra_rdoc_files = File.readlines('.document').map! do |x|
|
17
|
+
x.chomp!
|
18
|
+
if File.directory?(x)
|
19
|
+
manifest.grep(%r{\A#{x}/})
|
20
|
+
elsif File.file?(x)
|
21
|
+
x
|
22
|
+
else
|
23
|
+
nil
|
24
|
+
end
|
25
|
+
end.flatten.compact
|
26
|
+
|
27
|
+
s.files = manifest
|
28
|
+
s.rdoc_options = [ "-t", summary ]
|
29
|
+
s.require_paths = %w(lib ext)
|
30
|
+
s.rubyforge_project = %q{tdb}
|
31
|
+
s.summary = summary
|
32
|
+
s.test_files = Dir['test/test_*.rb']
|
33
|
+
s.extensions = %w(ext/tdb/extconf.rb)
|
34
|
+
|
35
|
+
# s.license = %w(LGPL) # disabled for compatibility with older RubyGems
|
36
|
+
end
|
data/test/test_tdb.rb
ADDED
@@ -0,0 +1,260 @@
|
|
1
|
+
# -*- encoding: binary -*-
|
2
|
+
$stdout.sync = $stderr.sync = true
|
3
|
+
require 'test/unit'
|
4
|
+
require 'tempfile'
|
5
|
+
$-w = true
|
6
|
+
require 'tdb'
|
7
|
+
|
8
|
+
class TestTdb < Test::Unit::TestCase
|
9
|
+
|
10
|
+
def setup
|
11
|
+
@tmp = @tdb = nil
|
12
|
+
end
|
13
|
+
|
14
|
+
def teardown
|
15
|
+
@tmp.close! if @tmp.respond_to?(:close!)
|
16
|
+
@tdb.close if @tdb && ! @tdb.closed?
|
17
|
+
end
|
18
|
+
|
19
|
+
def test_create_file
|
20
|
+
assert_nothing_raised do
|
21
|
+
@tmp = Tempfile.new('tdb')
|
22
|
+
File.unlink(@tmp.path)
|
23
|
+
end
|
24
|
+
@tdb = TDB.new(@tmp.path)
|
25
|
+
assert_kind_of TDB, @tdb
|
26
|
+
assert File.exist?(@tmp.path)
|
27
|
+
end
|
28
|
+
|
29
|
+
def test_to_a
|
30
|
+
@tdb = TDB.new(nil)
|
31
|
+
assert_equal [], @tdb.to_a
|
32
|
+
end
|
33
|
+
|
34
|
+
def test_each
|
35
|
+
@tdb = TDB.new(nil)
|
36
|
+
@tdb["X"] = "Y"
|
37
|
+
|
38
|
+
tmp = []
|
39
|
+
rc = @tdb.each { |k,v| tmp << [k, v ] }
|
40
|
+
assert_equal([ %w(X Y) ], tmp)
|
41
|
+
assert_equal @tdb.object_id, rc.object_id
|
42
|
+
|
43
|
+
tmp = []
|
44
|
+
assert_raises(EOFError) {
|
45
|
+
@tdb.each { |k,v| raise EOFError, "FOO"; tmp << [ k, v ] }
|
46
|
+
}
|
47
|
+
assert tmp.empty?
|
48
|
+
|
49
|
+
tmp = []
|
50
|
+
rc = catch(:zzz) { @tdb.each { |k,v| throw(:zzz, "FOO"); tmp << [ k, v ] } }
|
51
|
+
assert_equal rc, "FOO"
|
52
|
+
assert tmp.empty?
|
53
|
+
end
|
54
|
+
|
55
|
+
def test_each_bigger
|
56
|
+
@tdb = TDB.new(nil)
|
57
|
+
@tdb["a"] = "A"
|
58
|
+
@tdb["b"] = "B"
|
59
|
+
@tdb["c"] = "C"
|
60
|
+
|
61
|
+
tmp = []
|
62
|
+
rc = @tdb.each { |k,v| tmp << [k, v ] }
|
63
|
+
assert_equal 3, tmp.size
|
64
|
+
assert_equal @tdb.object_id, rc.object_id
|
65
|
+
|
66
|
+
tmp = []
|
67
|
+
assert_raises(EOFError) {
|
68
|
+
@tdb.each { |k,v|
|
69
|
+
tmp << [ k, v ]
|
70
|
+
raise EOFError, "FOO"
|
71
|
+
}
|
72
|
+
}
|
73
|
+
assert_equal 1, tmp.size
|
74
|
+
|
75
|
+
tmp = []
|
76
|
+
rc = catch(:zzz) {
|
77
|
+
@tdb.each { |k,v|
|
78
|
+
tmp << [ k, v ]
|
79
|
+
throw(:zzz, "FOO")
|
80
|
+
}
|
81
|
+
}
|
82
|
+
assert_equal rc, "FOO"
|
83
|
+
assert_equal 1, tmp.size
|
84
|
+
end
|
85
|
+
|
86
|
+
def test_memory
|
87
|
+
assert_nothing_raised do
|
88
|
+
@tdb = TDB.new(nil)
|
89
|
+
end
|
90
|
+
assert ! @tdb.closed?
|
91
|
+
assert_nil @tdb.close
|
92
|
+
assert @tdb.closed?
|
93
|
+
assert_raises(IOError) { @tdb.close }
|
94
|
+
end
|
95
|
+
|
96
|
+
def test_delete
|
97
|
+
@tdb = TDB.new(nil)
|
98
|
+
@tdb["hello"] = "X"
|
99
|
+
assert_equal "X", @tdb.delete("hello")
|
100
|
+
assert_nil @tdb["hello"]
|
101
|
+
assert_nil @tdb.fetch("hello")
|
102
|
+
assert_nil @tdb.delete("hello")
|
103
|
+
@tdb["hello"] = "world"
|
104
|
+
assert_equal "world", @tdb.delete("hello")
|
105
|
+
assert_nil @tdb.delete("hello")
|
106
|
+
end
|
107
|
+
|
108
|
+
def test_nuke!
|
109
|
+
@tdb = TDB.new(nil)
|
110
|
+
assert_equal false, @tdb.nuke!("hello")
|
111
|
+
@tdb["hello"] = "world"
|
112
|
+
assert_equal true, @tdb.nuke!("hello")
|
113
|
+
assert ! @tdb.include?("hello")
|
114
|
+
assert_equal false, @tdb.nuke!("hello")
|
115
|
+
end
|
116
|
+
|
117
|
+
def test_exists?
|
118
|
+
@tdb = TDB.new(nil)
|
119
|
+
assert_equal false, @tdb.key?("hello")
|
120
|
+
assert_equal false, @tdb.include?("hello")
|
121
|
+
@tdb["hello"] = "world"
|
122
|
+
assert_equal true, @tdb.key?("hello")
|
123
|
+
end
|
124
|
+
|
125
|
+
def test_store_fetch_mem
|
126
|
+
@tdb = TDB.new(nil)
|
127
|
+
assert_nothing_raised { @tdb["hello"] = "world" }
|
128
|
+
assert_equal "world", @tdb["hello"]
|
129
|
+
@tdb.store("hello", "Z")
|
130
|
+
assert_equal "Z", @tdb["hello"]
|
131
|
+
assert_equal "Z", @tdb.fetch("hello")
|
132
|
+
end
|
133
|
+
|
134
|
+
def test_store_modify_mem
|
135
|
+
@tdb = TDB.new(nil)
|
136
|
+
assert_nothing_raised { @tdb["hello"] = "world" }
|
137
|
+
assert_equal "world", @tdb["hello"]
|
138
|
+
assert_equal "Z", @tdb.modify("hello", "Z")
|
139
|
+
assert_equal "Z", @tdb["hello"]
|
140
|
+
|
141
|
+
assert_nil @tdb.modify("none", "Z")
|
142
|
+
assert_raises(TDB::ERR::NOEXIST) { @tdb.modify!("none", "Z") }
|
143
|
+
end
|
144
|
+
|
145
|
+
def test_store_insert_mem
|
146
|
+
@tdb = TDB.new(nil)
|
147
|
+
assert_equal "world", @tdb.insert("hello", "world")
|
148
|
+
assert_equal "world", @tdb["hello"]
|
149
|
+
assert_nil @tdb.insert("hello", "Z")
|
150
|
+
assert_raises(TDB::ERR::EXISTS) { @tdb.insert!("hello", "Z") }
|
151
|
+
assert_equal "world", @tdb["hello"]
|
152
|
+
end
|
153
|
+
|
154
|
+
def test_gc
|
155
|
+
assert_nothing_raised do
|
156
|
+
100000.times { TDB.new(nil) }
|
157
|
+
100000.times { TDB.new(Tempfile.new('tdb').path) }
|
158
|
+
end
|
159
|
+
end if ENV["TEST_GC"]
|
160
|
+
|
161
|
+
def test_new_with_hash_size
|
162
|
+
assert_nothing_raised { TDB.new(nil, :hash_size => 6) }
|
163
|
+
assert_raises(TypeError) { TDB.new(nil, :hash_size => "6") }
|
164
|
+
end
|
165
|
+
|
166
|
+
def test_const
|
167
|
+
assert_equal 0, TDB::DEFAULT
|
168
|
+
assert_equal 1, TDB::CLEAR_IF_FIRST
|
169
|
+
end
|
170
|
+
|
171
|
+
def test_new_with_open_flags
|
172
|
+
@tmp = Tempfile.new('tdb_excl')
|
173
|
+
assert_raises(Errno::EEXIST) {
|
174
|
+
TDB.new(@tmp.path, :open_flags => IO::EXCL|IO::CREAT|IO::RDWR)
|
175
|
+
}
|
176
|
+
File.unlink(@tmp.path)
|
177
|
+
assert_nothing_raised {
|
178
|
+
@tdb = TDB.new(@tmp.path, :open_flags => IO::EXCL|IO::CREAT|IO::RDWR)
|
179
|
+
}
|
180
|
+
end
|
181
|
+
|
182
|
+
def test_open_with_tdb_flags
|
183
|
+
assert_nothing_raised do
|
184
|
+
@tdb = TDB.new("/non/existent/file", :tdb_flags => TDB::INTERNAL)
|
185
|
+
end
|
186
|
+
end
|
187
|
+
|
188
|
+
def test_alternate_hashes
|
189
|
+
results = {}
|
190
|
+
expect = TDB::HASHES.to_a.map { |k,v| [ k.to_s, v.to_s ] }.sort
|
191
|
+
%w(default jenkins_lookup3 djb2 djb3 fnv1a
|
192
|
+
murmur1 murmur1_aligned murmur2 murmur2a murmur2_aligned).each do |h|
|
193
|
+
assert_nothing_raised do
|
194
|
+
tdb = TDB.new(nil, :hash => h.to_sym)
|
195
|
+
TDB::HASHES.each do |k,v|
|
196
|
+
tdb[k.to_s] = v.to_s
|
197
|
+
end
|
198
|
+
assert_equal expect, tdb.to_a.sort
|
199
|
+
assert_nil tdb.close
|
200
|
+
end
|
201
|
+
assert_raises(ArgumentError) do
|
202
|
+
TDB.new(nil, :hash => h)
|
203
|
+
end
|
204
|
+
end
|
205
|
+
end
|
206
|
+
|
207
|
+
def test_lock_unlock_all
|
208
|
+
@tmp = Tempfile.new('tdb')
|
209
|
+
File.unlink(@tmp.path)
|
210
|
+
@tdb = TDB.new(@tmp.path)
|
211
|
+
assert_equal true, @tdb.lockall
|
212
|
+
assert_equal true, @tdb.unlockall
|
213
|
+
assert_raises(TDB::ERR::LOCK) { @tdb.unlockall }
|
214
|
+
end
|
215
|
+
|
216
|
+
def test_read_locks
|
217
|
+
@tmp = Tempfile.new('tdb')
|
218
|
+
File.unlink(@tmp.path)
|
219
|
+
@tdb = TDB.new(@tmp.path)
|
220
|
+
assert_equal true, @tdb.lockall_read
|
221
|
+
assert_equal true, @tdb.unlockall_read
|
222
|
+
assert_raises(TDB::ERR::LOCK) { @tdb.unlockall_read }
|
223
|
+
assert_equal true, @tdb.trylockall_read
|
224
|
+
assert_equal true, @tdb.unlockall_read
|
225
|
+
assert_raises(TDB::ERR::LOCK) { @tdb.unlockall_read }
|
226
|
+
end
|
227
|
+
|
228
|
+
def test_mark_locks
|
229
|
+
@tmp = Tempfile.new('tdb')
|
230
|
+
File.unlink(@tmp.path)
|
231
|
+
@tdb = TDB.new(@tmp.path)
|
232
|
+
assert_equal true, @tdb.lockall_mark
|
233
|
+
assert_equal true, @tdb.lockall_unmark
|
234
|
+
assert_raises(TDB::ERR::LOCK) { @tdb.lockall_unmark }
|
235
|
+
end
|
236
|
+
|
237
|
+
def test_trylockall
|
238
|
+
@tmp = Tempfile.new('tdb')
|
239
|
+
File.unlink(@tmp.path)
|
240
|
+
@tdb = TDB.new(@tmp.path)
|
241
|
+
ard, awr = IO.pipe
|
242
|
+
brd, bwr = IO.pipe
|
243
|
+
pid = fork do
|
244
|
+
@tdb.close
|
245
|
+
ard.close
|
246
|
+
bwr.close
|
247
|
+
tdb = TDB.new(@tmp.path)
|
248
|
+
assert_equal true, tdb.lockall
|
249
|
+
awr.close
|
250
|
+
brd.read
|
251
|
+
end
|
252
|
+
awr.close
|
253
|
+
brd.close
|
254
|
+
assert_equal "", ard.read
|
255
|
+
assert_equal false, @tdb.trylockall
|
256
|
+
bwr.close
|
257
|
+
assert Process.waitpid2(pid)[1].success?
|
258
|
+
assert_equal true, @tdb.trylockall
|
259
|
+
end
|
260
|
+
end
|
metadata
ADDED
@@ -0,0 +1,105 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: tdb
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 27
|
5
|
+
prerelease: false
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 1
|
9
|
+
- 0
|
10
|
+
version: 0.1.0
|
11
|
+
platform: ruby
|
12
|
+
authors:
|
13
|
+
- Ruby tdb hackers
|
14
|
+
autorequire:
|
15
|
+
bindir: bin
|
16
|
+
cert_chain: []
|
17
|
+
|
18
|
+
date: 2010-12-01 00:00:00 +00:00
|
19
|
+
default_executable:
|
20
|
+
dependencies: []
|
21
|
+
|
22
|
+
description: |-
|
23
|
+
TDB is much like other DBM implementations, except it allows concurrent
|
24
|
+
writer processes. TDB was initially developed for Samba, but is used by
|
25
|
+
other projects as well. These Ruby bindings allow Ruby apps to read and
|
26
|
+
write to the same databases used by Samba!
|
27
|
+
email: ruby.tdb@librelist.org
|
28
|
+
executables: []
|
29
|
+
|
30
|
+
extensions:
|
31
|
+
- ext/tdb/extconf.rb
|
32
|
+
extra_rdoc_files:
|
33
|
+
- LICENSE
|
34
|
+
- README
|
35
|
+
- Hash_Functions
|
36
|
+
- TODO
|
37
|
+
- NEWS
|
38
|
+
- ChangeLog
|
39
|
+
- lib/tdb.rb
|
40
|
+
- ext/tdb/tdb.c
|
41
|
+
files:
|
42
|
+
- .document
|
43
|
+
- .gitignore
|
44
|
+
- .manifest
|
45
|
+
- COPYING
|
46
|
+
- ChangeLog
|
47
|
+
- GIT-VERSION-FILE
|
48
|
+
- GIT-VERSION-GEN
|
49
|
+
- GNUmakefile
|
50
|
+
- Hash_Functions
|
51
|
+
- LICENSE
|
52
|
+
- NEWS
|
53
|
+
- README
|
54
|
+
- Rakefile
|
55
|
+
- TODO
|
56
|
+
- ext/tdb/djb.c
|
57
|
+
- ext/tdb/extconf.rb
|
58
|
+
- ext/tdb/fnv.c
|
59
|
+
- ext/tdb/lookup3.c
|
60
|
+
- ext/tdb/murmur1.c
|
61
|
+
- ext/tdb/murmur2.c
|
62
|
+
- ext/tdb/rbtdb.h
|
63
|
+
- ext/tdb/tdb.c
|
64
|
+
- lib/tdb.rb
|
65
|
+
- setup.rb
|
66
|
+
- tdb.gemspec
|
67
|
+
- test/test_tdb.rb
|
68
|
+
has_rdoc: true
|
69
|
+
homepage: http://bogomips.org/ruby-tdb/
|
70
|
+
licenses: []
|
71
|
+
|
72
|
+
post_install_message:
|
73
|
+
rdoc_options:
|
74
|
+
- -t
|
75
|
+
- Trivial Database bindings for Ruby
|
76
|
+
require_paths:
|
77
|
+
- lib
|
78
|
+
- ext
|
79
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
80
|
+
none: false
|
81
|
+
requirements:
|
82
|
+
- - ">="
|
83
|
+
- !ruby/object:Gem::Version
|
84
|
+
hash: 3
|
85
|
+
segments:
|
86
|
+
- 0
|
87
|
+
version: "0"
|
88
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
89
|
+
none: false
|
90
|
+
requirements:
|
91
|
+
- - ">="
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
hash: 3
|
94
|
+
segments:
|
95
|
+
- 0
|
96
|
+
version: "0"
|
97
|
+
requirements: []
|
98
|
+
|
99
|
+
rubyforge_project: tdb
|
100
|
+
rubygems_version: 1.3.7
|
101
|
+
signing_key:
|
102
|
+
specification_version: 3
|
103
|
+
summary: Trivial Database bindings for Ruby
|
104
|
+
test_files:
|
105
|
+
- test/test_tdb.rb
|