Perl Rose:: БД нестатическая регистрация источника данных

Я пишу Perl-приложение, которое использует Rose::DB для абстракции постоянства, но я сталкиваюсь с проблемой инициализации моего подкласса Rose::DB со значениями из файла конфигурации.

В документации всегда представлены жестко закодированные примеры, например:

# Register your lone data source using the default type and domain
__PACKAGE__->register_db(
  driver   => 'pg',
  database => 'my_db',
  host     => 'localhost',
  username => 'joeuser',
  password => 'mysecret',
);

Однако для удобства обслуживания я хотел бы заполнить эти значения из отдельного файла конфигурации во время выполнения.

Используемый раздел файла конфигурации (Config::General format):

<database> 
    active_domain       development

    <db_domain development>
        db_driver       mysql
        db_name         stats_dev
        db_host         localhost
        db_user         stats_dev
        db_password     stats_dev
    </db_domain>
    <db_domain production>
        db_driver       mysql
        db_name         stats_prd
        db_host         localhost
        db_user         stats_prd
        db_password     stats_prd
    </db_domain>
</database>

Подкласс My Rose::DB, с методом инициализатора:

package Utils::DBUtils;

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

__PACKAGE__->use_private_registry;

sub registerAllDBs {
    my ($self,$config_obj) = @_;
    my $db_config = $config_obj->getDatabaseSection(); ## subconfig starts here
    my $def_domain = $db_config->{"active_domain"};

    __PACKAGE__->default_domain($def_domain);
    __PACKAGE__->default_type('main');

    my $db_domains = $db_config->{'db_domain'};
    foreach my $domain (keys %$db_domains) {
        my $domain_conf = $db_domains->{$domain};

        __PACKAGE__->register_db(
            domain => $domain,
            type => __PACKAGE__->default_type(),
            driver   => $domain_conf->{'db_driver'},
            database => $domain_conf->{'db_name'},
            host     => $domain_conf->{'db_host'},
            username => $domain_conf->{'db_user'},
            password => $domain_conf->{'db_password'}
        );          
    }
}
1;

Затем в моем основном скрипте я вызываю метод один раз, чтобы зарегистрировать все источники данных:

    Utils::DBUtils->registerAllDBs($conf);

Все мои постоянные объекты наследуются от пакета PersistentObject, который инициализирует объект DB с помощью:

    sub init_db { Utils::DBUtils->new() }

Тем не менее, это не работает, как я ожидал. Я получаю сообщение об ошибке во время компиляции:

    No database information found for domain 'default' and type 'default' and no driver type specified in call to Utils::DBUtils->new(...) at PersistentObject.pm line 9

Кажется, проблема в том, что Rose::DB ожидает иметь полные данные конфигурации во время компиляции, что было бы невозможно предоставить, поскольку они получены из файла конфигурации.

Я что-то здесь упускаю? Разве нельзя динамически инициализировать объект Rose::DB?

1 ответ

Решение

Мне удалось заставить его работать, кажется, что подклассу Rose::DB нужен как минимум один оператор register_db во время компиляции.

(Уродливое) решение было добавить

__PACKAGE__->register_db(
  driver   => 'mysql',
  database => 'fake',
  host     => 'localhost',
  username => 'fake',
  password => 'fake'
);

к определению пакета.

Другие вопросы по тегам