1#!./perl -w
2
3
4use strict ;
5
6
7use lib 't' ;
8use BerkeleyDB; 
9use util ;
10
11use Test::More ;
12
13BEGIN {
14    plan(skip_all => "this needs BerkeleyDB 4.6.x or better" )
15        if $BerkeleyDB::db_version < 4.6;
16
17    plan tests => 63;    
18}
19
20umask(0);
21
22{
23    # db->associate -- secondary keys returning DB_DBT_MULTIPLE
24
25    sub sec_key
26    {
27        my $pkey = shift ;
28        my $pdata = shift ;
29
30        $_[0] = ["a","b", "c"];
31
32        return 0;
33    }
34
35    my ($Dfile1, $Dfile2);
36    my $lex = new LexFile $Dfile1, $Dfile2 ;
37    my %hash ;
38    my $status;
39    my ($k, $v, $pk) = ('','','');
40
41    # create primary database
42    ok my $primary = new BerkeleyDB::Hash -Filename => $Dfile1, 
43				     -Flags    => DB_CREATE ;
44
45    # create secondary database
46    ok my $secondary = new BerkeleyDB::Hash -Filename => $Dfile2, 
47				     -Flags    => DB_CREATE ;
48
49    # associate primary with secondary
50    ok $primary->associate($secondary, \&sec_key) ==  0 ;
51
52    # add data to the primary
53    ok $primary->db_put("foo", "bar") == 0;
54
55    # check the records in the secondary (there should be three "a", "b", "c")
56    is countRecords($secondary), 3 ;
57
58    ok $secondary->db_get("a", $v) == 0;
59    is $v, "bar";
60
61    ok $secondary->db_get("b", $v) == 0;
62    is $v, "bar";
63
64    ok $secondary->db_get("c", $v) == 0;
65    is $v, "bar";
66}
67
68{
69    # db->associate -- secondary keys returning DB_DBT_MULTIPLE, but with
70    # one
71
72    sub sec_key1
73    {
74        my $pkey = shift ;
75        my $pdata = shift ;
76
77        $_[0] = ["a"];
78
79        return 0;
80    }
81
82    my ($Dfile1, $Dfile2);
83    my $lex = new LexFile $Dfile1, $Dfile2 ;
84    my %hash ;
85    my $status;
86    my ($k, $v, $pk) = ('','','');
87
88    # create primary database
89    ok my $primary = new BerkeleyDB::Hash -Filename => $Dfile1, 
90				     -Flags    => DB_CREATE ;
91
92    # create secondary database
93    ok my $secondary = new BerkeleyDB::Hash -Filename => $Dfile2, 
94				     -Flags    => DB_CREATE ;
95
96    # associate primary with secondary
97    ok $primary->associate($secondary, \&sec_key1) ==  0 ;
98
99    # add data to the primary
100    ok $primary->db_put("foo", "bar") == 0;
101
102    # check the records in the secondary (there should be three "a", "b", "c")
103    is countRecords($secondary), 1 ;
104
105    ok $secondary->db_get("a", $v) == 0;
106    is $v, "bar";
107
108}
109
110{
111    # db->associate -- multiple secondary keys
112
113    sub sec_key_mult
114    {
115        #print "in sec_key\n";
116        my $pkey = shift ;
117        my $pdata = shift ;
118
119        $_[0] = [ split ',', $pdata ] ;
120        return 0;
121    }
122
123    my ($Dfile1, $Dfile2);
124    my $lex = new LexFile $Dfile1, $Dfile2 ;
125    my %hash ;
126    my $status;
127    my ($k, $v, $pk) = ('','','');
128
129    # create primary database
130    ok my $primary = new BerkeleyDB::Hash -Filename => $Dfile1,
131				     -Flags    => DB_CREATE ;
132
133    # create secondary database
134    ok my $secondary = new BerkeleyDB::Hash -Filename => $Dfile2,
135				     -Flags    => DB_CREATE ;
136
137    # associate primary with secondary
138    ok $primary->associate($secondary, \&sec_key_mult) == 0;
139
140    # add data to the primary
141    my %data =  (
142		"red"	=> "flag",
143		"green"	=> "house",
144		"blue"	=> "sea",
145        "foo"   => "",
146        "bar"   => "hello,goodbye",
147		) ;
148
149    my $ret = 0 ;
150    while (($k, $v) = each %data) {
151        my $r = $primary->db_put($k, $v) ;
152        $ret += $r;
153    }
154    ok $ret == 0 ;
155
156    # check the records in the secondary
157    is countRecords($secondary), 5 ;
158
159    ok $secondary->db_get("house", $v) == 0;
160    ok $v eq "house";
161
162    ok $secondary->db_get("sea", $v) == 0;
163    ok $v eq "sea";
164
165    ok $secondary->db_get("flag", $v) == 0;
166    ok $v eq "flag";
167
168    ok $secondary->db_get("hello", $v) == 0;
169    ok $v eq "hello,goodbye";
170
171    ok $secondary->db_get("goodbye", $v) == 0;
172    ok $v eq "hello,goodbye";
173
174    # pget to primary database is illegal
175    ok $primary->db_pget('red', $pk, $v) != 0 ;
176
177    # pget to secondary database is ok
178    ok $secondary->db_pget('house', $pk, $v) == 0 ;
179    ok $pk eq 'green';
180    ok $v  eq 'house';
181
182    # pget to secondary database is ok
183    ok $secondary->db_pget('hello', $pk, $v) == 0 ;
184    ok $pk eq 'bar';
185    ok $v  eq 'hello,goodbye';
186
187    ok my $p_cursor = $primary->db_cursor();
188    ok my $s_cursor = $secondary->db_cursor();
189
190    # c_get from primary
191    $k = 'green';
192    ok $p_cursor->c_get($k, $v, DB_SET) == 0;
193    ok $k eq 'green';
194    ok $v eq 'house';
195
196    # c_get from secondary
197    $k = 'sea';
198    ok $s_cursor->c_get($k, $v, DB_SET) == 0;
199    ok $k eq 'sea';
200    ok $v eq 'sea';
201
202    # c_pget from primary database should fail
203    $k = 1;
204    ok $p_cursor->c_pget($k, $pk, $v, DB_FIRST) != 0;
205
206    # c_pget from secondary database
207    $k = 'flag';
208    ok $s_cursor->c_pget($k, $pk, $v, DB_SET) == 0;
209    ok $k eq 'flag';
210    ok $pk eq 'red';
211    ok $v eq 'flag';
212
213    # check put to secondary is illegal
214    ok $secondary->db_put("tom", "dick") != 0;
215    is countRecords($secondary), 5 ;
216
217    # delete from primary
218    ok $primary->db_del("green") == 0 ;
219    is countRecords($primary), 4 ;
220
221    # check has been deleted in secondary
222    ok $secondary->db_get("house", $v) != 0;
223    is countRecords($secondary), 4 ;
224
225    # delete from secondary
226    ok $secondary->db_del('flag') == 0 ;
227    is countRecords($secondary), 3 ;
228
229
230    # check deleted from primary
231    ok $primary->db_get("red", $v) != 0;
232    is countRecords($primary), 3 ;
233}
234
235