cdb 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
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
+