database driver from config file revisited

24 views
Skip to first unread message

Matt Zagrabelny

unread,
Dec 14, 2012, 5:43:18 PM12/14/12
to rose-db...@googlegroups.com
Greetings,

About a month ago I asked about getting the connection parameters for
Rose::DB from a config file. Peter Karman was kind enough to reply
with a solution that he uses. Thanks, Peter.

I would ideally like to set up the connection parameters in the main
section of the program due to using Getopt::Long to override config
file values.

I have a simple prototype of my program that is not working as
expected and am hoping a more veteran pair of eyes and mind will be
able to assist.

---{begin of program: /home/mzagrabe/git/rosetest/bin/rosetest}---
#!/usr/bin/perl

=head1
CREATE TABLE "books" (
"author" TEXT PRIMARY KEY,
"title" TEXT
);
=cut

use strict;
use warnings;

use lib "/home/mzagrabe/git/rosetest/lib";

use RoseTest::DB;

RoseTest::DB->configs(
{
'database-driver' => 'Pg',
'database-name' => 'rosetest',
'database-host' => 'localhost',
'database-user' => 'mike',
'database-pass' => 'GlermtheWorm',
}
);

use RoseTest::Book;

my $metadata = RoseTest::DB->new(
type => 'rosetest',
);

my $book = RoseTest::Book->new(
author => 'Tolkien',
title => 'The Hobbit',
);

$book->save;
---{end of program}---

---{begin of module: /home/mzagrabe/git/rosetest/lib/RoseTest/DB.pm}---
package RoseTest::DB;

use strict;
use warnings;

use Carp;
use Data::Dumper;
use Rose::DB;

use base qw( Rose::DB );

{
my $configs = {};

sub configs {
my $class = shift;
if (scalar(@_) == 0) {
return $configs;
}
elsif (scalar(@_) == 1) {
$configs = $_[0];
}
else {
croak "Error: Wrong number of arguments. Please pass zero
or one argument.";
}
}
}

__PACKAGE__->use_private_registry;
__PACKAGE__->default_domain('production');

# Comment out the following to allow functionality.

__PACKAGE__->register_db(
domain => __PACKAGE__->default_domain,
type => 'rosetest',
driver => __PACKAGE__->configs->{'database-driver'},
database => __PACKAGE__->configs->{'database-name'},
host => __PACKAGE__->configs->{'database-host'},
username => __PACKAGE__->configs->{'database-user'},
password => __PACKAGE__->configs->{'database-pass'},
);


# Uncomment the following to allow functionality.

#__PACKAGE__->register_db(
# domain => __PACKAGE__->default_domain,
# type => 'rosetest',
# driver => 'Pg',
# database => 'rosetest',
# host => 'localhost',
# username => 'mike',
# password => 'GlermtheWorm',
#);

1;
---{end of module}---

---{begin of module: /home/mzagrabe/git/rosetest/lib/RoseTest/Book.pm}---
package RoseTest::Book;

use strict;
use warnings;
use RoseTest::DB;

use base qw( Rose::DB::Object );

__PACKAGE__->meta->setup(
table => 'books',
auto => 1,
);

sub init_db {
RoseTest::DB->new(
type => 'rosetest',
);
}

1;
---{end of module}---

When I run the program, I get:

% /home/mzagrabe/git/rosetest/bin/rosetest
No driver found for domain 'production' and type 'rosetest' at
/home/mzagrabe/git/rosetest/lib/RoseTest/Book.pm line 15
Compilation failed in require at
/home/mzagrabe/git/rosetest/bin/rosetest line 27.
BEGIN failed--compilation aborted at
/home/mzagrabe/git/rosetest/bin/rosetest line 27.

Thanks for any help, it is much appreciated.

-mz

Peter Karman

unread,
Dec 16, 2012, 9:35:41 PM12/16/12
to Rose::DB::Object


On Dec 14, 4:43 pm, Matt Zagrabelny <mzagr...@d.umn.edu> wrote:

> ---{begin of program: /home/mzagrabe/git/rosetest/bin/rosetest}---
> #!/usr/bin/perl
>
> =head1
> CREATE TABLE "books" (
>     "author"  TEXT PRIMARY KEY,
>     "title"   TEXT
> );
> =cut
>
> use strict;
> use warnings;
>
> use lib "/home/mzagrabe/git/rosetest/lib";
>
> use RoseTest::DB;


at this point, register_db() has already been called in RoseTest::DB,
so your call to configs() below
doesn't result in 'database-driver' being set in the registry.

suggested fix below.
put your register_db() calls here for each in $configs



>     }
>
> }
>
> __PACKAGE__->use_private_registry;
> __PACKAGE__->default_domain('production');
>
> # Comment out the following to allow functionality.
>

# configs isn't populated yet, so these all render undef.

Matt Zagrabelny

unread,
Dec 17, 2012, 12:42:37 PM12/17/12
to rose-db...@googlegroups.com
Hi Peter,

Thanks for the reply. Comments are inline.
Hmm. Not exactly sure what you mean by "for each in $configs". I did
some testing by putting the register_db call into this subroutine, but
it still doesn't work. The Object class (Book.pm) seems to not
recognize the registry:

No database information found for domain 'default' and type 'rosetest'
and no driver type specified in call to RoseTest::DB->new(...) at
/home/mzagrabe/git/rosetest/lib/RoseTest/Book.pm line 15
Compilation failed in require at
/home/mzagrabe/git/rosetest/bin/rosetest line 27.
BEGIN failed--compilation aborted at
/home/mzagrabe/git/rosetest/bin/rosetest line 27.

Thanks for your help!

-mz

Peter Karman

unread,
Dec 17, 2012, 1:04:25 PM12/17/12
to rose-db...@googlegroups.com
On 12/17/12 11:42 AM, Matt Zagrabelny wrote:

>
> Hmm. Not exactly sure what you mean by "for each in $configs". I did
> some testing by putting the register_db call into this subroutine, but
> it still doesn't work. The Object class (Book.pm) seems to not
> recognize the registry:
>

the problem is that you are doing a mix of compile-time and run-time
actions, and end up with chicken-and-egg scenario. If you are going to
set your config with a run-time action (which you do now), then you need
to defer the loading of your Book.pm class till run-time too. Try changing:

use RoseTest::Book;

to

require RoseTest::Book;

and see if that helps.


--
Peter Karman . http://peknet.com/ . pe...@peknet.com
Reply all
Reply to author
Forward
0 new messages