![]() | |
![]() |
| | Thread Tools | Display Modes |
#1
| |||
| |||
|
#2
| |||
| |||
|
|
Has anyone used the BerkeleyDB db->associate capability in Perl? Would you be willing to share an example? I've tried a number of different ways and are not passing the correct parameters. |
#3
| |||
| |||
|
|
jonscarbrough (AT) netscape (DOT) net (Jon Scarbrough) wrote in message news:<d7ede277.0310090820.2f61c1dc (AT) posting (DOT) google.com>... Has anyone used the BerkeleyDB db->associate capability in Perl? Would you be willing to share an example? I've tried a number of different ways and are not passing the correct parameters. The code below (which is somewhat lacking in error checking) displays this Primary database ================ cat mammal:4:domesticated lizard reptile:4:wild dog mammal:4:domesticated chicken bird:2:domesticated horse mammal:4:domesticated Secondary database ================== 2 bird:2:domesticated 4 mammal:4:domesticated 4 mammal:4:domesticated 4 mammal:4:domesticated 4 reptile:4:wild Shout of you have any questions Paul use strict; use warnings; use BerkeleyDB; sub sec_key_legs { my $pkey = shift ; my $pdata = shift ; my @bits = split ':', $pdata; $_[0] = $bits[1] ; return 0; } my $primaryDB = "primary.db" ; my $secondaryDB = 'secondary.db'; my %hash ; my ($k, $v) ; # create primary database my $primary = new BerkeleyDB::Hash -Filename => $primaryDB, -Flags => DB_CREATE or die "Cannot open prinary database '$primaryDB': $!\n" ; # create secondary database my $secondary = new BerkeleyDB::Hash -Filename => $secondaryDB, -Flags => DB_CREATE , -Property => DB_DUP|DB_DUPSORT or die "Cannot open secondary database '$secondaryDB': $!\n" ; # associate primary with secondary $primary->associate($secondary, \&sec_key_legs) ; # add data to the primary # data will automagically be added to the secondary my %data = ( "horse" => join(':', qw(mammal 4 domesticated )), "cat" => join(':', qw(mammal 4 domesticated )), "dog" => join(':', qw(mammal 4 domesticated )), "chicken" => join(':', qw(bird 2 domesticated )), "lizard" => join(':', qw(reptile 4 wild )), ) ; my $ret = 0 ; while (($k, $v) = each %data) { $primary->db_put($k, $v) ; } print "Primary database\n" ; print "================\n" ; dumpDB($primary); print "\n\n"; print "Secondary database\n" ; print "==================\n" ; dumpDB($secondary); sub dumpDB { my $db = shift ; my $cursor = $db->db_cursor() or return () ; my $k = ''; my $v = ''; for ( my $status = $cursor->c_get($k, $v, DB_FIRST) ; $status == 0 ; $status = $cursor->c_get($k, $v, DB_NEXT)) { print "$k\t$v\n" ; } } |
#4
| |||
| |||
|
|
Thanks Paul. I guess the issue I couldn't get right was the second parameter to the associate call ($primary->associate($secondary, \&sec_key_legs)). So now I know it must a reference to a subroutine. So my next question is the --- $_[0] = $bits[1]; statement. Is the important item here to set the first value passed to the function the key needed for the secondary index? |
|
Also, I thought the value for the secondary index was the key to the primary database. |
|
Again, thanks. Jon |
#5
| |||
| |||
|
|
Hi John Thanks Paul. I guess the issue I couldn't get right was the second parameter to the associate call ($primary->associate($secondary, \&sec_key_legs)). So now I know it must a reference to a subroutine. So my next question is the --- $_[0] = $bits[1]; statement. Is the important item here to set the first value passed to the function the key needed for the secondary index? Actually, the important part is to set the *third* parameter to the secondary index key. The way I wrote sec_key_legs mixes two styles of dealing with parameters and, not surprisingly, can be a bit confusing. If I write it like this, is it any clearer? sub sec_key_legs { my @bits = split ':', $_[1]; $_[2] = $bits[1] ; return 0; } Also, I thought the value for the secondary index was the key to the primary database. It is. I assume you are referring to the output from dumpDB on the secondary database? Have a read at this snippet from the c_get man page When called on a cursor opened on a database that has been made into a secondary index using the DB->associate method, the DBcursor->c_get and DBcursor->c_pget methods return the key from the secondary index and the data item from the primary database. In addition, the DBcursor->c_pget method returns the key from the primary database. In databases that are not secondary indices, the DBcursor->c_pget interface will always fail and return EINVAL. Basically the c_get/c_pget interface hide the actual value used by the secondary index from you and return the value from the primary instead. Again, thanks. Jon cheers Paul |
![]() |
| Thread Tools | |
| Display Modes | |
| |