В моей организации есть собственный пакет для подключения к нашим серверам баз данных, который заботится о том, чтобы произвольно использовать различные зеркала (в соответствии с конфигурационным файлом) и только пытается использовать мастер-сервер базы данных для не-readonly соединений или если ни одно из зеркал не может быть достигнуто. Я хочу использовать это и использовать его для постоянных подключений в приложении Catalyst.Стойкие соединения с базой данных с Catalyst
Что я пытался создать пакет модели на основе Catalyst :: Model :: DBI, но это переопределяет метод connect() этого модуля, чтобы использовать метод соединения нашего пакета. Затем я переопределил методы «selectall_arrayref», «do», которые используют stay_connected() ... Он работает нормально, но он создает новое соединение для каждого запроса - даже во время одного и того же запроса http - хотя документация для Catalyst :: Model :: DBI, похоже, подразумевает, что соединение должно быть постоянным.
Так что мой вопрос: что ДОЛЖНО происходить? Нужно ли мне делать что-то другое, чтобы получить постоянный дескриптор? может ли Model :: DBI обеспечить это? если да, то как мне перевести эту вещь в нашу, или есть более простой способ? Я не хочу переписывать весь наш пакет для использования DBIx :: Class, я просто хочу подключить нашу процедуру, которая дает мне дескриптор базы данных, который подходит для нашей системы.
package SpamControl::Model::Database;
use strict;
use Freecycle::Database;
use base 'Catalyst::Model::DBI';
# redefine the connect method, this is just copied from Model::DBI but using the Freecycle package for the actual connection.
sub connect {
my $self = shift;
my $dbh;
# TODO: I wish this could be a persistent connection.
eval {
$dbh = Freecycle::Database::connect({ username => 'member', read_only => 1 });
};
if ([email protected]) { $self->{log}->debug(qq{Couldn't connect to the database "[email protected]"}) if $self->{debug} }
else { $self->{log}->debug ('Connected to the database') if $self->{debug}; }
$self->_pid($$);
$self->_tid(threads->tid) if $INC{'threads.pm'};
return $dbh;
}
# for read/write connections
sub dbh_admin {
my ($self,$c) = @_;
my $dbh = Freecycle::Database::connect({ username => 'admin', read_only => 0 });
return $dbh;
}
sub do {
my $self = shift;
return $self->dbh_admin->do(@_);
}
sub selectall_hashref {
my $self = shift;
return $self->stay_connected->selectall_hashref(@_);
}
...etc etc.
Возможно, я не был чист, но то, что я сделал, просто расширило Catalyst :: Model :: DBI, потому что наш модуль НЕ обрабатывает стойкость и тому подобное. Он просто обрабатывает соединение с правильными базами данных (как с мастером, подчиненными устройствами, так и с резервными копиями) с правильными учетными данными. Я посмотрел на Catalyst :: Model :: Adapter, и он выглядит больше, чем мне нужно. или менее. – steev
Возможно, я тоже не был ясен: использование Catalyst :: Model :: DBI (CMD) означает, что вы должны позволить ему подключаться к СУБД. Если вы сделаете соединение самостоятельно, вы наступаете на пальцы CMD. Подклассификация CMD могла бы быть жизнеспособной идеей, но это должно быть ограничено добавлением перед вашей логикой «круглого робанга» выбора DB DSN и учетных данных IMO (циклирование произойдет только при запуске приложения или в случае повторного подключения, хотя, поскольку вы хотят настойчивости). Пожалуйста, посмотрите следующий фрагмент документа CMD о предполагаемом использовании CMD (2-й абзац): https://metacpan.org/pod/Catalyst::Model::DBI#DESCRIPTION – emazep
Спасибо за разъяснение. Таким образом, похоже, что Catalyst :: Model :: Adapter - единственный способ пойти. Но, читая документы об этом, поскольку мой модуль не является надлежащим классом объектов (он просто соединяется и передает обратно dbh), похоже, что если я не захочу его переписать, мне, возможно, придется поместить его в другой модуль, который создает объект, а затем использовать CMA для «обертывания» этого. который чувствует себя раздражающим, но, возможно, это единственный способ. – steev