dbTalk Databases Forums  

Use of db->associate in perl

comp.databases.berkeley-db comp.databases.berkeley-db


Discuss Use of db->associate in perl in the comp.databases.berkeley-db forum.



Reply
 
Thread Tools Display Modes
  #1  
Old   
Jon Scarbrough
 
Posts: n/a

Default Use of db->associate in perl - 10-09-2003 , 11:20 AM






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.

Thanks.

Jon

Reply With Quote
  #2  
Old   
Paul Marquess
 
Posts: n/a

Default Re: Use of db->associate in perl - 10-10-2003 , 11:43 AM






jonscarbrough (AT) netscape (DOT) net (Jon Scarbrough) wrote in message news:<d7ede277.0310090820.2f61c1dc (AT) posting (DOT) google.com>...
Quote:
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" ;
}
}


Reply With Quote
  #3  
Old   
Jon Scarbrough
 
Posts: n/a

Default Re: Use of db->associate in perl - 10-13-2003 , 10:12 PM



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.

Trying to interpret the C api documentation to Perl usage can be
confusing at times.

Again, thanks.

Jon

Paul.Marquess (AT) btinternet (DOT) com (Paul Marquess) wrote in message news:<22fa329d.0310100843.1bc1ea81 (AT) posting (DOT) google.com>...
Quote:
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" ;
}
}

Reply With Quote
  #4  
Old   
Paul Marquess
 
Posts: n/a

Default Re: Use of db->associate in perl - 10-14-2003 , 05:42 AM



Hi John

Quote:
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;
}


Quote:
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.


Quote:
Again, thanks.

Jon
cheers
Paul


Reply With Quote
  #5  
Old   
Jon Scarbrough
 
Posts: n/a

Default Re: Use of db->associate in perl - 10-14-2003 , 05:02 PM



Yes, it all makes sense now. I re-read the api documentation on
db->associate and I now understand the call with your guidance. I
guess I wasn't looking closely enough at the dumpdb function to
realize what it was doing.

Thank you for your assistance.

Jon

Paul.Marquess (AT) btinternet (DOT) com (Paul Marquess) wrote in message news:<22fa329d.0310140242.598a1f55 (AT) posting (DOT) google.com>...
Quote:
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

Reply With Quote
Reply




Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off



Powered by vBulletin Version 3.5.3
Copyright ©2000 - 2012, Jelsoft Enterprises Ltd.