mattbauer-bdb 0.0.1

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.
@@ -0,0 +1,102 @@
1
+
2
+ #ifndef BDB2_H
3
+ #define BDB2_H
4
+
5
+ #include <ruby.h>
6
+
7
+ #ifdef stat
8
+ #undef stat
9
+ #endif
10
+
11
+ #ifdef close
12
+ #undef close
13
+ #endif
14
+
15
+ #ifdef rename
16
+ #undef rename
17
+ #endif
18
+
19
+ #include <version.h>
20
+ #include <db.h>
21
+
22
+ #define NOTXN NULL
23
+
24
+ #ifdef OPEN_MAX
25
+ #define LMAXFD OPEN_MAX
26
+ #else
27
+ #ifdef FOPEN_MAX
28
+ #define LMAXFD FOPEN_MAX
29
+ #endif
30
+ #endif
31
+ #ifndef LMAXFD
32
+ #error "No max fd define available."
33
+ #endif
34
+
35
+ #define FNLEN 40
36
+
37
+ #define filename_copy(fp,fv) \
38
+ strncpy(fp,RSTRING_PTR(fv),FNLEN);
39
+
40
+ #define filename_dup(fpd,fps) \
41
+ strncpy(fpd,fps,FNLEN);
42
+
43
+ typedef struct s_envh {
44
+ VALUE self;
45
+ DB_ENV *env;
46
+ VALUE adb; /* Ruby array holding opened databases */
47
+ VALUE atxn; /* Ruby array holding open transactions */
48
+ } t_envh;
49
+
50
+ typedef struct s_dbh {
51
+ VALUE self;
52
+ DB *db;
53
+ int db_opened;
54
+ VALUE aproc;
55
+ t_envh *env; /* Parent environment, NULL if not opened from one */
56
+ VALUE adbc; /* Ruby array holding opened cursor */
57
+ char filename[FNLEN+1];
58
+ } t_dbh;
59
+
60
+ typedef struct s_dbch {
61
+ VALUE self;
62
+ DBC *dbc;
63
+ t_dbh *db;
64
+ char filename[FNLEN+1];
65
+ } t_dbch;
66
+
67
+ typedef struct s_txnh {
68
+ VALUE self;
69
+ DB_TXN *txn;
70
+ t_envh *env;
71
+ } t_txnh;
72
+
73
+ #define cu(b,m) \
74
+ rb_define_const(b,#m,UINT2NUM(m))
75
+
76
+ #define ci(b,m) \
77
+ rb_define_const(b,#m,INT2NUM(m))
78
+
79
+ #define cs(b,m) \
80
+ rb_define_const(b,#m,rb_str_new2(m))
81
+
82
+ #define simple_set(fname) \
83
+ VALUE db_ ## fname ## _eq(VALUE obj, VALUE v) \
84
+ { \
85
+ rb_ivar_set(obj,fv_ ## fname,v); \
86
+ return obj; \
87
+ }
88
+
89
+ #define attr_writer(fname) \
90
+ VALUE fname ## _writer(VALUE obj, VALUE v) \
91
+ { \
92
+ rb_ivar_set(obj,fv_ ## fname,v); \
93
+ return obj; \
94
+ }
95
+
96
+ #define attr_reader(fname) \
97
+ VALUE fname ## _reader(VALUE obj) \
98
+ { \
99
+ return rb_ivar_get(obj,fv_ ## fname); \
100
+ }
101
+
102
+ #endif
@@ -0,0 +1,91 @@
1
+ #!/usr/bin/env ruby
2
+ require 'mkmf'
3
+
4
+ inc, lib = dir_config('db')
5
+
6
+ # OS X compatibility
7
+ if(PLATFORM =~ /darwin/) then
8
+ # test if Bdb is probably universal
9
+
10
+ filetype = (IO.popen("file #{inc}/../db_dump").readline.chomp rescue nil)
11
+ # if it's not universal, ARCHFLAGS should be set
12
+ if((filetype !~ /universal binary/) && ENV['ARCHFLAGS'].nil?) then
13
+ arch = (IO.popen("uname -m").readline.chomp rescue nil)
14
+ $stderr.write %{
15
+ =========== WARNING ===========
16
+
17
+ You are building this extension on OS X without setting the
18
+ ARCHFLAGS environment variable, and BerkeleyDB does not appear
19
+ to have been built as a universal binary. If you are seeing this
20
+ message, that means that the build will probably fail.
21
+
22
+ Try setting the environment variable ARCHFLAGS
23
+ to '-arch #{arch}' before building.
24
+
25
+ For example:
26
+ (in bash) $ export ARCHFLAGS='-arch #{arch}'
27
+ (in tcsh) % setenv ARCHFLAGS '-arch #{arch}'
28
+
29
+ Then try building again.
30
+
31
+ ===================================
32
+
33
+ }
34
+ # We don't exit here. Who knows? It might build.
35
+ end
36
+ end
37
+
38
+ versions=%w(db-4.7 db-4.6 db-4.5 db-4.4 db-4.3 db-4.2)
39
+ until versions.empty?
40
+ (lib_ok = have_library(versions.shift,'db_version', 'db.h')) && break
41
+ end
42
+
43
+ def create_header
44
+ if File.exist?("bdb_aux._c")
45
+ message("Not writing bdb_aux._c (defines), already exists\n")
46
+ return
47
+ end
48
+
49
+ message("Writing bdb_aux._c (defines), this takes a while\n")
50
+ db_header = $CPPFLAGS.split.select { |f| f =~ /^-I/ }.map { |e|
51
+ f = File.join(e[2..-1], 'db.h')
52
+ File.exists?(f) ? f : nil
53
+ }.select { |e| e }.first
54
+
55
+ n=0
56
+ defines=[]
57
+ File.open(db_header) {|fd|
58
+ File.open("bdb_aux._c","w") {|hd|
59
+ hd.puts("/* This file automatically generated by extconf.rb */\n")
60
+ fd.each_line {|l|
61
+ if l =~ %r{^#define\s+(DBC?_\w*)\s+([^\/]*)\s*(.*?)(\/\*.*)?$}
62
+ name = $1
63
+ value = $2
64
+ if macro_defined?(name,"#include <db.h>")
65
+ case value
66
+ when /^"/
67
+ hd.print(%Q{cs(mBdb,%s);\n}%[name])
68
+ when /^\(?(0x|\d)/
69
+ hd.print(%Q{cu(mBdb,%s);\n}%[name])
70
+ when /^\(?-/
71
+ hd.print(%Q{ci(mBdb,%s);\n}%[name])
72
+ else
73
+ $stderr.puts "don't know how to handle #{name} #{value.strip}, guessing UINT"
74
+ hd.print(%Q{cu(mBdb,%s);\n}%[name])
75
+ end
76
+ n+=1
77
+ end
78
+ end
79
+ }
80
+ }
81
+ message("\nwrote #{n} defines\n")
82
+ }
83
+ end
84
+
85
+ if lib_ok
86
+ create_header
87
+ create_makefile('bdb')
88
+ else
89
+ $stderr.puts("cannot create Makefile")
90
+ exit 1
91
+ end
@@ -0,0 +1,103 @@
1
+ require 'test_helper'
2
+
3
+ class CursorTest < Test::Unit::TestCase
4
+
5
+ def setup
6
+ mkdir File.join(File.dirname(__FILE__), 'tmp')
7
+ @db = Bdb::Db.new
8
+ @db.open(nil, File.join(File.dirname(__FILE__), 'tmp', 'test.db'), nil, Bdb::Db::BTREE, Bdb::DB_CREATE, 0)
9
+ 10.times { |i| @db.put(nil, i.to_s, "data-#{i}", 0)}
10
+ @cursor = @db.cursor(nil, 0)
11
+ end
12
+
13
+ def teardown
14
+ @cursor.close if @cursor
15
+ assert(@db.close(0)) if @db
16
+ rm_rf File.join(File.dirname(__FILE__), 'tmp')
17
+ end
18
+
19
+ def test_get
20
+ key, value = @cursor.get(nil, nil, Bdb::DB_FIRST)
21
+ assert_equal '0', key
22
+ assert_equal 'data-0', value
23
+ end
24
+
25
+ def test_pget
26
+ @db1 = Bdb::Db.new
27
+ @db1.flags = Bdb::DB_DUPSORT
28
+ @db1.open(nil, File.join(File.dirname(__FILE__), 'tmp', 'test1.db'), nil, Bdb::Db::HASH, Bdb::DB_CREATE, 0)
29
+
30
+ @db.associate(nil, @db1, 0, proc { |sdb, key, data| key.split('-')[0] })
31
+
32
+ @db.put(nil, '1234-5678', 'data', 0)
33
+ @db.put(nil, '5678-1234', 'atad', 0)
34
+
35
+ @cursor1 = @db1.cursor(nil, 0)
36
+ key, pkey, value = @cursor1.pget(nil, nil, Bdb::DB_FIRST)
37
+ assert_equal '1234', key
38
+ assert_equal '1234-5678', pkey
39
+ assert_equal 'data', value
40
+
41
+ @cursor1.close
42
+ @db1.close(0)
43
+ end
44
+
45
+ def test_put
46
+ @cursor.put('10_000', 'data-10_000', Bdb::DB_KEYLAST)
47
+ value = @db.get(nil, '10_000', nil, 0)
48
+ assert_equal 'data-10_000', value
49
+ end
50
+
51
+ def test_del
52
+ key, value = @cursor.get(nil, nil, Bdb::DB_FIRST)
53
+ value = @db.get(nil, '0', nil, 0)
54
+ assert_equal '0', key
55
+ assert_equal 'data-0', value
56
+ @cursor.del
57
+ value = @db.get(nil, '0', nil, 0)
58
+ assert_nil value
59
+ end
60
+
61
+ def test_count
62
+ @cursor.get(nil, nil, Bdb::DB_FIRST)
63
+ assert_equal 1, @cursor.count
64
+ end
65
+
66
+ def test_join
67
+ @personnel_db = Bdb::Db.new
68
+ @personnel_db.open(nil, File.join(File.dirname(__FILE__), 'tmp', 'personnel_db.db'), nil, Bdb::Db::HASH, Bdb::DB_CREATE, 0)
69
+
70
+ @names_db = Bdb::Db.new
71
+ @names_db.flags = Bdb::DB_DUPSORT
72
+ @names_db.open(nil, File.join(File.dirname(__FILE__), 'tmp', 'names_db.db'), nil, Bdb::Db::HASH, Bdb::DB_CREATE, 0)
73
+
74
+ @jobs_db = Bdb::Db.new
75
+ @jobs_db.flags = Bdb::DB_DUPSORT
76
+ @jobs_db.open(nil, File.join(File.dirname(__FILE__), 'tmp', 'jobs_db.db'), nil, Bdb::Db::HASH, Bdb::DB_CREATE, 0)
77
+
78
+ [{:ssn => '111-11-1111', :lastname => 'Smith', :job => 'welder'},
79
+ {:ssn => '222-22-2222', :lastname => 'Jones', :job => 'welder'},
80
+ {:ssn => '333-33-3333', :lastname => 'Smith', :job => 'painter'}].each do |e|
81
+ @personnel_db.put(nil, e[:ssn], Marshal.dump([e[:ssn], e[:lastname], e[:job]]), 0)
82
+ @names_db.put(nil, e[:lastname], e[:ssn], 0)
83
+ @jobs_db.put(nil, e[:job], e[:ssn], 0)
84
+ end
85
+
86
+ @name_cursor = @names_db.cursor(nil, 0)
87
+ @name_cursor.get('Smith', nil, Bdb::DB_SET)
88
+ assert_equal 2, @name_cursor.count
89
+ @job_cursor = @jobs_db.cursor(nil, 0)
90
+ @job_cursor.get('welder', nil, Bdb::DB_SET)
91
+ assert_equal 2, @job_cursor.count
92
+ @personnel_cursor = @personnel_db.join([@name_cursor, @job_cursor], 0)
93
+ assert_equal '111-11-1111', @personnel_cursor.get(nil, nil, 0).first
94
+
95
+ @personnel_cursor.close
96
+ @name_cursor.close
97
+ @job_cursor.close
98
+
99
+ @jobs_db.close(0)
100
+ @names_db.close(0)
101
+ @personnel_db.close(0)
102
+ end
103
+ end
@@ -0,0 +1,133 @@
1
+ require 'test_helper'
2
+
3
+ class DbTest < Test::Unit::TestCase
4
+
5
+ def setup
6
+ mkdir File.join(File.dirname(__FILE__), 'tmp')
7
+ @db = Bdb::Db.new
8
+ @db.open(nil, File.join(File.dirname(__FILE__), 'tmp', 'test.db'), nil, Bdb::Db::BTREE, Bdb::DB_CREATE, 0)
9
+ end
10
+
11
+ def teardown
12
+ assert(@db.close(0)) if @db
13
+ rm_rf File.join(File.dirname(__FILE__), 'tmp')
14
+ end
15
+
16
+ def test_put_and_get
17
+ @db.put(nil, 'key', 'data', 0)
18
+ result = @db.get(nil, 'key', nil, 0)
19
+ assert_equal 'data', result
20
+ end
21
+
22
+ def test_del
23
+ @db.put(nil, 'key', 'data', 0)
24
+ result = @db.get(nil, 'key', nil, 0)
25
+ assert_equal 'data', result
26
+ @db.del(nil, 'key', 0)
27
+ result = @db.get(nil, 'key', nil, 0)
28
+ assert_nil result
29
+ end
30
+
31
+ def test_flags_set_and_get
32
+ @db1 = Bdb::Db.new
33
+ @db1.flags = Bdb::DB_DUPSORT
34
+ assert Bdb::DB_DUPSORT, @db1.flags
35
+ end
36
+
37
+ def test_associate_and_pget
38
+ @db1 = Bdb::Db.new
39
+ @db1.flags = Bdb::DB_DUPSORT
40
+ @db1.open(nil, File.join(File.dirname(__FILE__), 'tmp', 'test1.db'), nil, Bdb::Db::HASH, Bdb::DB_CREATE, 0)
41
+
42
+ @db.associate(nil, @db1, 0, proc { |sdb, key, data| key.split('-')[0] })
43
+
44
+ @db.put(nil, '1234-5678', 'data', 0)
45
+ @db.put(nil, '5678-1234', 'atad', 0)
46
+
47
+ result = @db.get(nil, '1234-5678', nil, 0)
48
+ assert_equal 'data', result
49
+ result = @db1.get(nil, '5678', nil, 0)
50
+ assert_equal 'atad', result
51
+
52
+ result = @db1.pget(nil, '1234', nil, 0)
53
+ assert_equal ['1234-5678', 'data'], result
54
+
55
+ @db1.close(0)
56
+ end
57
+
58
+ def test_aset_and_aget
59
+ @db['key'] = 'data'
60
+ result = @db.get(nil, 'key', nil, 0)
61
+ assert_equal 'data', result
62
+ result = @db['key']
63
+ assert_equal 'data', result
64
+ @db['key'] = 'data1'
65
+ result = @db['key']
66
+ assert_equal 'data1', result
67
+ end
68
+
69
+ def test_get_byteswapped
70
+ @db.get_byteswapped
71
+ end
72
+
73
+ def test_get_type
74
+ assert_equal Bdb::Db::BTREE, @db.get_type
75
+ end
76
+
77
+ def test_remove
78
+ @db1 = Bdb::Db.new
79
+ @db1.open(nil, File.join(File.dirname(__FILE__), 'tmp', 'other_test.db'), nil, Bdb::Db::BTREE, Bdb::DB_CREATE, 0)
80
+ @db1.close(0)
81
+ Bdb::Db.new.remove(File.join(File.dirname(__FILE__), 'tmp', 'other_test.db'), nil, 0)
82
+ assert !File.exists?(File.join(File.dirname(__FILE__), 'tmp', 'other_test.db'))
83
+ end
84
+
85
+ def test_key_range
86
+ 10.times { |i| @db.put(nil, i.to_s, 'data', 0) }
87
+ @db.key_range(nil, '2', 0)
88
+ end
89
+
90
+ def test_rename
91
+ @db1 = Bdb::Db.new
92
+ @db1.open(nil, File.join(File.dirname(__FILE__), 'tmp', 'other_test.db'), nil, Bdb::Db::BTREE, Bdb::DB_CREATE, 0)
93
+ @db1.close(0)
94
+ assert Bdb::Db.new.rename(File.join(File.dirname(__FILE__), 'tmp', 'other_test.db'), nil, File.join(File.dirname(__FILE__), 'tmp', 'other2_test.db'), 0)
95
+ assert File.exists?(File.join(File.dirname(__FILE__), 'tmp', 'other2_test.db'))
96
+ end
97
+
98
+ def test_pagesize_get_and_set
99
+ @db1 = Bdb::Db.new
100
+ @db1.pagesize = 1024
101
+ assert_equal 1024, @db1.pagesize
102
+ end
103
+
104
+ def test_h_ffactor_get_and_set
105
+ @db1 = Bdb::Db.new
106
+ @db1.h_ffactor = 5
107
+ assert_equal 5, @db1.h_ffactor
108
+ end
109
+
110
+ def test_h_nelem_get_and_set
111
+ @db1 = Bdb::Db.new
112
+ @db1.h_nelem = 10_000
113
+ assert_equal 10_000, @db1.h_nelem
114
+ end
115
+
116
+ def test_sync
117
+ assert @db.sync
118
+ end
119
+
120
+ def test_truncate
121
+ @db.put(nil, 'key', 'data', 0)
122
+ result = @db.get(nil, 'key', nil, 0)
123
+ assert_equal 'data', result
124
+ @db.truncate(nil)
125
+ result = @db.get(nil, 'key', nil, 0)
126
+ assert_nil result
127
+ end
128
+
129
+ def test_compact
130
+ assert @db.compact(nil, nil, nil, nil, 0)
131
+ end
132
+
133
+ end
@@ -0,0 +1,90 @@
1
+ require 'test_helper'
2
+
3
+ class EnvTest < Test::Unit::TestCase
4
+
5
+ def test_cachesize
6
+ env = Bdb::Env.new(0)
7
+ env.cachesize = 1024*1024*500
8
+ assert_equal 1024*1024*500, env.cachesize
9
+
10
+ env.cachesize = 1024*1024*1024*3
11
+ assert_equal 1024*1024*1024*3, env.cachesize
12
+
13
+ env.cachesize = 1024*1024*1024*3+1
14
+ assert_equal 1024*1024*1024*3+1, env.cachesize
15
+ end
16
+
17
+ def test_flags
18
+ env = Bdb::Env.new(0)
19
+
20
+ env.flags_on = Bdb::DB_AUTO_COMMIT | Bdb::DB_DSYNC_DB
21
+ assert_equal Bdb::DB_AUTO_COMMIT | Bdb::DB_DSYNC_DB, env.flags
22
+
23
+ env.flags_off = Bdb::DB_AUTO_COMMIT | Bdb::DB_DSYNC_DB
24
+ assert_equal 0, env.flags
25
+ end
26
+
27
+ def test_list_dbs
28
+ env = Bdb::Env.new(0)
29
+ assert env.list_dbs.empty?
30
+
31
+ db = env.db
32
+ assert_equal db, env.list_dbs.first
33
+ db.close(0)
34
+ end
35
+
36
+ def test_set_and_get_timeout
37
+ env = Bdb::Env.new(0)
38
+ env.set_timeout(10, Bdb::DB_SET_LOCK_TIMEOUT)
39
+ assert_equal 10, env.get_timeout(Bdb::DB_SET_LOCK_TIMEOUT)
40
+ end
41
+
42
+ def test_set_and_get_tx_max
43
+ env = Bdb::Env.new(0)
44
+ env.set_tx_max(100)
45
+ assert_equal 100, env.get_tx_max
46
+ end
47
+
48
+ def test_set_and_get_lk_detect
49
+ env = Bdb::Env.new(0)
50
+ env.set_lk_detect(Bdb::DB_LOCK_MAXWRITE)
51
+ assert_equal Bdb::DB_LOCK_MAXWRITE, env.get_lk_detect
52
+ end
53
+
54
+ def test_set_and_get_lk_max_locks
55
+ env = Bdb::Env.new(0)
56
+ env.set_lk_max_locks(10_000)
57
+ assert_equal 10_000, env.get_lk_max_locks
58
+ end
59
+
60
+ def test_set_and_get_lk_max_objects
61
+ env = Bdb::Env.new(0)
62
+ env.set_lk_max_objects(10_000)
63
+ assert_equal 10_000, env.get_lk_max_objects
64
+ end
65
+
66
+ def test_set_and_get_shm_key
67
+ env = Bdb::Env.new(0)
68
+ env.set_shm_key(2506400)
69
+ assert_equal 2506400, env.get_shm_key
70
+ end
71
+
72
+ def test_set_and_get_data_dir
73
+ env = Bdb::Env.new(0)
74
+ env.set_data_dir('/tmp')
75
+ assert_equal ['/tmp'], env.get_data_dirs
76
+ end
77
+
78
+ def test_set_lg_dir
79
+ env = Bdb::Env.new(0)
80
+ env.set_lg_dir('/tmp')
81
+ assert_equal '/tmp', env.get_lg_dir
82
+ end
83
+
84
+ def test_set_tmp_dir
85
+ env = Bdb::Env.new(0)
86
+ env.set_tmp_dir('/tmp')
87
+ assert_equal '/tmp', env.get_tmp_dir
88
+ end
89
+
90
+ end