cdb 0.0.2

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/README ADDED
@@ -0,0 +1,67 @@
1
+ ====================
2
+ cdb library for ruby
3
+ ====================
4
+
5
+ Author: Markus Schirp, Seonic GbR
6
+ License: Ruby's License
7
+
8
+ Description:
9
+
10
+ Simple CDB reading an writing Plugin for Ruby.
11
+
12
+ Constant - Database Reference:
13
+
14
+ http://cr.yp.to/cdb.html
15
+
16
+ Requirements:
17
+ =============
18
+
19
+ -l:cdb.a -l:unix.a -l:buffer.a -l:byte -l:alloc
20
+ cdb.h
21
+
22
+ Installing cdb under Gentoo:
23
+
24
+ portage:
25
+ emerge dev-db/cdb
26
+
27
+ paludis:
28
+ paludis -i dev-db/cdb
29
+
30
+
31
+ Examples:
32
+ =========
33
+
34
+ reading:
35
+
36
+ # read example begin
37
+
38
+ require 'cdb'
39
+
40
+ File.open("some.cdb") do |file|
41
+ reader = CDB::CDBReader.new(file)
42
+ reader.each_value("somekey") do |value|
43
+ # do something with value
44
+ end
45
+ end
46
+
47
+ # read example end
48
+
49
+ writing:
50
+
51
+ # write example begin
52
+
53
+ require 'cdb'
54
+
55
+ File.open("some.cdb","w") do |file|
56
+ CDB::CDBMaker.fill(file) do |maker|
57
+ (1..10).each do |x|
58
+ key = "key#{x}"
59
+ 1.upto(x) do |y|
60
+ value = "value#{x}.#{y}"
61
+ maker.store(key,value)
62
+ end
63
+ end
64
+ end
65
+ end
66
+
67
+ # write example end
@@ -0,0 +1,257 @@
1
+ #include "ruby.h"
2
+ #include "rubyio.h"
3
+ #include <cdb.h>
4
+
5
+ #ifndef TINYCDB_VERSION
6
+ #include <cdb_make.h>
7
+ #include <uint32.h>
8
+ #else
9
+ #define uint32 unsigned int
10
+ #endif /* TINYCDB_VERSION */
11
+
12
+ typedef struct cdb_make cdb_make;
13
+ typedef struct cdb cdb;
14
+
15
+ VALUE CDBMaker_alloc(VALUE klass);
16
+ VALUE CDBMaker_initialize(VALUE self,VALUE io);
17
+ VALUE CDBMaker_store(VALUE self,VALUE key,VALUE value);
18
+ VALUE CDBMaker_finish(VALUE self);
19
+ VALUE CDBMaker_is_finished(VALUE self);
20
+
21
+ VALUE CDBReader_alloc(VALUE klass);
22
+ VALUE CDBReader_initialize(VALUE self,VALUE io);
23
+ VALUE CDBReader_has_key(VALUE self,VALUE key);
24
+ VALUE CDBReader_each_for_key(VALUE self,VALUE key);
25
+ VALUE CDBReader_each(VALUE self);
26
+ VALUE CDBReader_each_key(VALUE self);
27
+ VALUE CDBReader_each_value(VALUE self);
28
+
29
+ void _cdb_read(cdb *db,void *buf,uint32 len,uint32 *pos) {
30
+ if(cdb_read(db,buf,len,*pos) == -1) {
31
+ rb_sys_fail(0);
32
+ }
33
+ *pos+=len;
34
+ return;
35
+ }
36
+
37
+ void
38
+ getnum(cdb *db,uint32 *num,uint32 *pos) {
39
+ #ifndef TINYCDB_VERSION
40
+ char buf[4];
41
+ #else
42
+ unsigned char buf[4];
43
+ #endif /* TINYCDB_VERSION */
44
+ _cdb_read(db,buf,4,pos);
45
+ // Can we skip unpack on little endian?
46
+ #ifndef TINYCDB_VERSION
47
+ uint32_unpack(buf,num);
48
+ #else
49
+ *num=cdb_unpack(buf);
50
+ #endif /* TINYDB_VERSION */
51
+ }
52
+
53
+ /* Implements CDB::CDBMaker */
54
+ static void
55
+ CDBMaker_free(void *ptr) { free(ptr); }
56
+
57
+ VALUE
58
+ CDBMaker_alloc(VALUE klass) {
59
+ cdb_make *db = ALLOC_N(cdb_make,1);
60
+ return Data_Wrap_Struct(klass,NULL,CDBMaker_free,db);
61
+ }
62
+
63
+ VALUE
64
+ CDBMaker_initialize(VALUE self,VALUE io) {
65
+ OpenFile *fptr = NULL;
66
+ cdb_make *db = NULL;
67
+ rb_check_type(io,T_FILE);
68
+ GetOpenFile(io, fptr);
69
+ rb_io_check_writable(fptr);
70
+ rb_iv_set(self,"finished",Qfalse);
71
+ Data_Get_Struct(self,cdb_make,db);
72
+ if(cdb_make_start(db,fileno(GetReadFile(fptr))) == -1)
73
+ rb_sys_fail(0);
74
+ return self;
75
+ }
76
+
77
+ VALUE
78
+ CDBMaker_store(VALUE self,VALUE key,VALUE value) {
79
+ if(rb_iv_get(self,"finished") == Qtrue)
80
+ rb_raise(rb_eRuntimeError,"cdb is already finished!");
81
+ cdb_make *db = NULL;
82
+ Data_Get_Struct(self,cdb_make,db);
83
+ key = StringValue(key);
84
+ value = StringValue(value);
85
+ if(cdb_make_add(db,RSTRING(key)->ptr,RSTRING(key)->len,RSTRING(value)->ptr,RSTRING(value)->len) == -1)
86
+ rb_sys_fail(0);
87
+ return Qnil;
88
+ }
89
+
90
+ VALUE
91
+ CDBMaker_finish(VALUE self) {
92
+ cdb_make *db = NULL;
93
+ if(rb_iv_get(self,"finished") == Qtrue)
94
+ rb_raise(rb_eRuntimeError,"cdb is already finished!");
95
+ rb_iv_set(self,"finished",Qtrue);
96
+ Data_Get_Struct(self,cdb_make,db);
97
+ if(cdb_make_finish(db) == -1) rb_sys_fail(0);
98
+ return Qnil;
99
+ }
100
+
101
+ VALUE
102
+ CDBMaker_is_finished(VALUE self) {
103
+ return rb_iv_get(self,"finished");
104
+ }
105
+
106
+ /* Implements CDB::CDBReader */
107
+
108
+ static void CDBReader_free(void *ptr) {
109
+ free(ptr);
110
+ }
111
+
112
+ VALUE
113
+ CDBReader_alloc(VALUE klass) {
114
+ cdb *db = ALLOC_N(cdb,1);
115
+ return Data_Wrap_Struct(klass,NULL,CDBReader_free,db);
116
+ }
117
+
118
+ VALUE
119
+ CDBReader_initialize(VALUE self,VALUE io) {
120
+ OpenFile *fptr = NULL;
121
+ cdb *db = NULL;
122
+ rb_check_type(io,T_FILE);
123
+ GetOpenFile(io, fptr);
124
+ rb_io_check_readable(fptr);
125
+ Data_Get_Struct(self,cdb,db);
126
+ cdb_init(db,fileno(GetReadFile(fptr)));
127
+ return self;
128
+ }
129
+
130
+ VALUE
131
+ CDBReader_has_key(VALUE self,VALUE key) {
132
+ cdb *db = NULL;
133
+ Data_Get_Struct(self,cdb,db);
134
+ key = StringValue(key);
135
+ return cdb_find(db,RSTRING(key)->ptr,RSTRING(key)->len) ? Qtrue : Qfalse;
136
+ }
137
+
138
+
139
+
140
+ VALUE
141
+ CDBReader_each_key(VALUE self) {
142
+ VALUE key;
143
+ cdb *db = NULL;
144
+ uint32 eod,klen,dlen,pos=0;
145
+ Data_Get_Struct(self,cdb,db);
146
+ getnum(db,&eod,&pos);
147
+ pos = 2048;
148
+
149
+ while(pos < eod) {
150
+ getnum(db,&klen,&pos);
151
+ getnum(db,&dlen,&pos);
152
+ key = rb_str_buf_new(klen);
153
+ RSTRING(key)->len = klen;
154
+ _cdb_read(db,RSTRING(key)->ptr,klen,&pos);
155
+ pos+=dlen;
156
+ rb_yield(key);
157
+ }
158
+
159
+ return Qnil;
160
+ }
161
+
162
+ VALUE
163
+ CDBReader_each_value(VALUE self) {
164
+ VALUE value;
165
+ cdb *db = NULL;
166
+ uint32 eod,klen,dlen,pos=0;
167
+ Data_Get_Struct(self,cdb,db);
168
+ getnum(db,&eod,&pos);
169
+ pos = 2048;
170
+
171
+ while(pos < eod) {
172
+ getnum(db,&klen,&pos);
173
+ getnum(db,&dlen,&pos);
174
+ value = rb_str_buf_new(dlen);
175
+ RSTRING(value)->len = dlen;
176
+ pos+=klen;
177
+ _cdb_read(db,RSTRING(value)->ptr,dlen,&pos);
178
+ rb_yield(value);
179
+ }
180
+ return Qnil;
181
+ }
182
+
183
+ VALUE
184
+ CDBReader_each(VALUE self) {
185
+ VALUE key,value;
186
+ cdb *db = NULL;
187
+ uint32 eod,klen,dlen,pos=0;
188
+ Data_Get_Struct(self,cdb,db);
189
+ getnum(db,&eod,&pos);
190
+ pos = 2048;
191
+
192
+ while(pos < eod) {
193
+ getnum(db,&klen,&pos);
194
+ getnum(db,&dlen,&pos);
195
+ key = rb_str_buf_new(klen);
196
+ RSTRING(key)->len = klen;
197
+ value = rb_str_buf_new(dlen);
198
+ RSTRING(value)->len = dlen;
199
+
200
+ _cdb_read(db,RSTRING(key)->ptr,klen,&pos);
201
+ _cdb_read(db,RSTRING(value)->ptr,dlen,&pos);
202
+
203
+ rb_yield(rb_ary_new3(2,key,value));
204
+ }
205
+ return Qnil;
206
+ }
207
+
208
+ VALUE
209
+ CDBReader_each_for_key(VALUE self,VALUE key) {
210
+ cdb *db = NULL;
211
+ Data_Get_Struct(self,cdb,db);
212
+ VALUE value;
213
+ key = StringValue(key);
214
+ #ifndef TINYCDB_VERSION
215
+ if(cdb_find(db,RSTRING(key)->ptr,RSTRING(key)->len) == -1) rb_sys_fail(0);
216
+ do {
217
+ value = rb_str_buf_new(cdb_datalen(db));
218
+ RSTRING(value)->len = cdb_datalen(db);
219
+ _cdb_read(db,RSTRING(value)->ptr,cdb_datalen(db),&cdb_datapos(db));
220
+ rb_yield(value);
221
+ } while(cdb_findnext(db,RSTRING(key)->ptr,RSTRING(key)->len));
222
+ #else
223
+ struct cdb_find find;
224
+ cdb_findinit(&find,db,RSTRING(key)->ptr,RSTRING(key)->len);
225
+ while(cdb_findnext(&find) > 0) {
226
+ value = rb_str_buf_new(cdb_datalen(db));
227
+ RSTRING(value)->len = cdb_datalen(db);
228
+ _cdb_read(db,RSTRING(value)->ptr,cdb_datalen(db),&cdb_datapos(db));
229
+ rb_yield(value);
230
+ }
231
+ #endif /* TINYCDB_VERSION */
232
+ return Qnil;
233
+ }
234
+
235
+ VALUE mCDB;
236
+ VALUE cCDBReader;
237
+ VALUE cCDBMaker;
238
+
239
+ void Init_cdb_ext() {
240
+ mCDB = rb_define_module("CDB");
241
+
242
+ cCDBReader = rb_define_class_under(mCDB,"CDBReader",rb_cObject);
243
+ rb_define_alloc_func(cCDBReader,CDBReader_alloc);
244
+ rb_define_method(cCDBReader,"initialize",CDBReader_initialize,1);
245
+ rb_define_method(cCDBReader,"has_key?",CDBReader_has_key,1);
246
+ rb_define_method(cCDBReader,"each_for_key",CDBReader_each_for_key,1);
247
+ rb_define_method(cCDBReader,"each_key",CDBReader_each_key,0);
248
+ rb_define_method(cCDBReader,"each_value",CDBReader_each_value,0);
249
+ rb_define_method(cCDBReader,"each",CDBReader_each,0);
250
+
251
+ cCDBMaker = rb_define_class_under(mCDB,"CDBMaker",rb_cObject);
252
+ rb_define_alloc_func(cCDBMaker,CDBMaker_alloc);
253
+ rb_define_method(cCDBMaker,"initialize",CDBMaker_initialize,1);
254
+ rb_define_method(cCDBMaker,"store",CDBMaker_store,2);
255
+ rb_define_method(cCDBMaker,"finish!",CDBMaker_finish,0);
256
+ rb_define_method(cCDBMaker,"finished?",CDBMaker_is_finished,0);
257
+ }
@@ -0,0 +1,11 @@
1
+ require 'mkmf'
2
+ have_header("cdb.h") || exit
3
+ if macro_defined?("TINYCDB_VERSION",cpp_include("cdb.h"))
4
+ $LDFLAGS << " -lcdb"
5
+ else
6
+ %w(cdb unix buffer byte alloc).each do |ld|
7
+ $LDFLAGS << " -l:#{ld}.a"
8
+ end
9
+ end
10
+ $CFLAGS << " -Wall"
11
+ create_makefile("cdb/cdb_ext")
@@ -0,0 +1,3 @@
1
+ require 'cdb/cdb_ext'
2
+ require 'cdb/reader_util'
3
+ require 'cdb/maker_util'
@@ -0,0 +1,9 @@
1
+ module CDB
2
+ class CDBMaker
3
+ def self.fill(file)
4
+ maker = self.new(file)
5
+ yield maker
6
+ maker.finish!
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,13 @@
1
+ require 'cdb/cdb_ext'
2
+
3
+ module CDB
4
+ class CDBReader
5
+ def values(key)
6
+ ret = Array.new
7
+ each_for_key(key) do |value|
8
+ ret << value
9
+ end
10
+ ret
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,34 @@
1
+ require 'cdb'
2
+ require 'tempfile'
3
+ require 'test/unit'
4
+
5
+ require 'test_data'
6
+
7
+ class TestCDBMaker < Test::Unit::TestCase
8
+ include ::CDB
9
+ include ::TestData
10
+
11
+ def setup
12
+ @tmpfile = Tempfile.new("cdb_maker_test")
13
+ @db = CDBMaker.new(@tmpfile.to_io)
14
+ end
15
+
16
+ def test_initialize
17
+ assert_raise(Errno::ESPIPE) do
18
+ CDBMaker.new($stdout)
19
+ end
20
+ assert_raise(TypeError) do
21
+ CDBMaker.new("test")
22
+ end
23
+ end
24
+
25
+ def test_store
26
+ Data.each do |key,values|
27
+ values.each do |value|
28
+ @db.store(key,value)
29
+ end
30
+ end
31
+ @db.finish!
32
+ assert(@db.finished?)
33
+ end
34
+ end
@@ -0,0 +1,121 @@
1
+ #!/usr/bin/ruby
2
+ require 'test/unit'
3
+ require 'tempfile'
4
+ require 'test_data'
5
+
6
+ require 'cdb'
7
+
8
+ class TestCDBReader < ::Test::Unit::TestCase
9
+ include ::TestData
10
+ class Dummy
11
+ def to_str
12
+ "lala"
13
+ end
14
+ end
15
+
16
+ class Dummy2
17
+ def to_str
18
+ "key1"
19
+ end
20
+ end
21
+
22
+ def self.cdb_format(key,value)
23
+ "+#{key.length.to_s},#{value.length.to_s}:#{key}->#{value}"
24
+ end
25
+
26
+ db = CDB::CDBMaker.new(file=Tempfile.new("test_cdb").to_io)
27
+
28
+ Data.each do |key,values|
29
+ values.each do |value|
30
+ db.store(key,value)
31
+ end
32
+ end
33
+ db.finish!
34
+ @@file_path = file.path
35
+ file.close
36
+
37
+ def setup
38
+ @db = CDB::CDBReader.new(@file=File.open(@@file_path))
39
+ end
40
+
41
+ def teardown
42
+ @file.close
43
+ end
44
+
45
+ def test_has_key?
46
+ Data.each do |pair|
47
+ key,value = pair
48
+ assert(@db.has_key?(key),"key: #{key} was not found!")
49
+ end
50
+ assert(!@db.has_key?("nonexistend"))
51
+ assert_raise(TypeError) do
52
+ assert(!@db.has_key?(1))
53
+ end
54
+ assert(!@db.has_key?(Dummy.new))
55
+ assert(@db.has_key?(Dummy2.new))
56
+ end
57
+
58
+ def test_each
59
+ tmp = Hash.new
60
+ Data.each do |key,value|
61
+ tmp[key] = value.dup
62
+ end
63
+ @db.each do |key,value|
64
+ assert(tmp.has_key?(key))
65
+ values = tmp.fetch(key)
66
+ assert(values.include?(value))
67
+ values.delete(value)
68
+ tmp.delete(key) if values.empty?
69
+ end
70
+ assert(tmp.empty?)
71
+ end
72
+
73
+ def test_each_key
74
+ tmp = Hash.new
75
+ @db.each_key do |key|
76
+ assert(Data.has_key?(key))
77
+ if tmp[key]
78
+ tmp[key]+=1
79
+ else
80
+ tmp[key]=1
81
+ end
82
+ end
83
+ tmp.each do |key,count|
84
+ assert_equal(Data[key].length,count)
85
+ end
86
+ end
87
+
88
+ def test_each_value
89
+ values = Data.values.flatten
90
+ @db.each_value do |value|
91
+ assert(values.include?(value),"#{value} was not expected!")
92
+ values.delete(value)
93
+ end
94
+ assert(values.empty?)
95
+ end
96
+
97
+ def test_each_for_key
98
+ Data.each do |key,ovalue|
99
+ rvalue = Array.new
100
+ @db.each_for_key(key) do |x|
101
+ rvalue << x
102
+ end
103
+ assert_equal(ovalue,@db.values(key))
104
+ assert_equal(ovalue,rvalue)
105
+ end
106
+ end
107
+
108
+ def test_initialize
109
+ assert_raise(IOError) do
110
+ CDB::CDBReader.new($stdout)
111
+ end
112
+
113
+ assert_raise(TypeError) do
114
+ CDB::CDBReader.new(1)
115
+ end
116
+
117
+ assert_nothing_raised do
118
+ CDB::CDBReader.new($stdin)
119
+ end
120
+ end
121
+ end
@@ -0,0 +1,27 @@
1
+ module TestData
2
+ LARGE_KEY = "a"*1024
3
+ LARGE_VALUE = "b"*(1024*1024)
4
+ class Dummy
5
+ def to_str
6
+ "lala"
7
+ end
8
+ end
9
+
10
+ class Dummy2
11
+ def to_str
12
+ "key1"
13
+ end
14
+ end
15
+
16
+ Data = Hash.new
17
+
18
+ (1..10).each do |x|
19
+ key = "key#{x}"
20
+ values = Array.new
21
+ Data[key] = values
22
+ 1.upto(x) do |i|
23
+ values << value = "value#{x}.#{i}"
24
+ end
25
+ end
26
+ Data[LARGE_KEY]=Array(LARGE_VALUE)
27
+ end
@@ -0,0 +1,3 @@
1
+ $: << File.dirname(__FILE__)
2
+ require 'tc_maker'
3
+ require 'tc_reader'
metadata ADDED
@@ -0,0 +1,56 @@
1
+ --- !ruby/object:Gem::Specification
2
+ rubygems_version: 0.9.4
3
+ specification_version: 1
4
+ name: cdb
5
+ version: !ruby/object:Gem::Version
6
+ version: 0.0.2
7
+ date: 2008-01-13 00:00:00 +01:00
8
+ summary: Reading and creating CDB Constant Databases
9
+ require_paths:
10
+ - lib
11
+ email: mbj@seonic.net
12
+ homepage: http://mbj.seonic.net
13
+ rubyforge_project:
14
+ description:
15
+ autorequire:
16
+ default_executable:
17
+ bindir: bin
18
+ has_rdoc: false
19
+ required_ruby_version: !ruby/object:Gem::Version::Requirement
20
+ requirements:
21
+ - - ">"
22
+ - !ruby/object:Gem::Version
23
+ version: 0.0.0
24
+ version:
25
+ platform: ruby
26
+ signing_key:
27
+ cert_chain:
28
+ post_install_message:
29
+ authors:
30
+ - Markus Schirp
31
+ files:
32
+ - README
33
+ - lib/cdb
34
+ - lib/cdb.rb
35
+ - lib/cdb/maker_util.rb
36
+ - lib/cdb/reader_util.rb
37
+ - test/ts_cdb.rb
38
+ - test/tc_reader.rb
39
+ - test/test_data.rb
40
+ - test/tc_maker.rb
41
+ - ext/extconf.rb
42
+ - ext/cdb_ext.c
43
+ test_files:
44
+ - test/ts_cdb.rb
45
+ rdoc_options: []
46
+
47
+ extra_rdoc_files: []
48
+
49
+ executables: []
50
+
51
+ extensions:
52
+ - ext/extconf.rb
53
+ requirements: []
54
+
55
+ dependencies: []
56
+