多个连接字符串到具有不同密码的数据库

时间:2017-01-05 10:52:34

标签: perl dbi

尝试使用具有不同密码的多个连接字符串连接数据库。密码具有不同的权限。如果一个密码失败,它应该尝试使用另一个密码。

代码编写如下。虽然它工作正常,但我们如何重构代码(eval& DBH)来处理多个连接字符串?

my %config = do 'dbconfig.pl';

my $dbh = eval { DBI->connect("dbi:Pg:dbname=".$config{db}.";host=$socket_nm;port=".$config{port}."", $config{user},$config{password},{RaiseError=>1,PrintError=>0}) };

if (!$dbh) {
$dbh = eval { DBI->connect("dbi:Pg:dbname=".$config{db}.";host=$socket_nm;port=".$config{port}."",$config{user},$config{password},{RaiseError=>1,PrintError=>0}) };         
}

if ( $@ ) {
#Handle Exceptions
}

dbconfig.pl包含:

db => 'db',
port => '5432',
user => 'db_ro',
password => 'Pass01',
password2 => 'Pass02'

1 个答案:

答案 0 :(得分:1)

您需要使用循环并重试,直到获得有效连接。在每个循环中,您需要获取下一组配置值并尝试连接它。

my @configs = (
    {
        # ...
        user     => 'user1',
        password => 'password1',
    },
    {
        # ...
        user     => 'user2',
        password => 'password2',
    },
);

my $dbh;
while ( not $dbh ) {
    my $config = shift @configs;    # grab the next config
    if ( not $config ) {
        # we ran out of configs to try
        die "Couldn't connect to database";
    }

    # try the config
    $dbh = eval {
        DBI->connect(
            "dbi:Pg:dbname=" . $config->{db} . ";host=$socket_nm;port=" . $config->{port} . "",
            $config->{user}, $config->{password}, { RaiseError => 1, PrintError => 0 } );
    };
    # we don't need to look at $@ here, but if we care we can still do it
}

配置现在存储在数组@configs中。在里面,有哈希引用。在你的循环中,我们有一个词法$config,其中包含我们想要尝试的当前词汇。请注意,这也是一个哈希引用,因此您需要将$config->{...}与dsn中的箭头一起使用。

只要未设置$dbh,我们就会循环播放。情况就是这样,直到循环内部的eval返回一个正常工作的数据库句柄对象。

如果我们用完配置,我们还需要退出循环。死亡似乎是一个好主意。

如果您愿意,可以处理eval为您捕获的错误,但为此,您无需执行此操作。如果你关心的是你最终得到了一个有效的连接,那就足够了。

注意:您的%config = do 'dbconfig.pl'太可怕了。请使用适当的配置文件格式,如JSON和模块来读取它。我非常喜欢Config::ZOMG,因为它支持许多不同的格式,并允许您将多个文件合并为一个配置哈希。但Config::Simple对你来说可能就足够了。