Revision 3 (by ahitrov@rambler.ru, 2010/03/24 15:19:32) |
The CORE
|
package Contenido::DB::PostgreSQL;
# ----------------------------------------------------------------------------
# ����� ���������� ������ ����� ������ PostgreSQL
# ----------------------------------------------------------------------------
use strict;
use warnings;
use DBI;
use DBD::Pg;
use Contenido::Globals;
use Contenido::Msg;
# ������ ������� � ����������� � ����� �����
# ��������� ���������� � ����� ��� ��������� ������ ���� ��� �� ����
sub SQL {
my $self = shift;
return ($self->connect_check() ? $self->{SQL} : undef);
}
#��������� ��������������� ���������� � ����� ��� ��������� ������ ���� ��� �� ����
sub TSQL {
my $self = shift;
return ($self->t_connect_check() ? $self->{TSQL} : undef);
}
# -------------------------------------------------------------------------------------------------
# ��������� ���������� � ����� ������
# -------------------------------------------------------------------------------------------------
sub connect {
my $self = shift;
#���������� ��� ����
if ($self->is_connected) {
} else {
unless ($self->{SQL} = $self->create_db_connect) {
$log->error("�� ���� ����������� � ����� ������");
die;
}
$self->{SQL}->do("SET NAMES '".$self->state->db_client_encoding."'") if ($self->state->db_client_encoding);
}
$self->{_connect_ok} = 1;
return 1;
}
sub t_connect {
my $self = shift;
#�������������� connect ��� ����
if ($self->is_t_connected) {
$self->{TSQL_level}++;
} else {
unless ($self->{TSQL} = $self->create_db_t_connect) {
$log->error("�� ���� ����������� � ����� ������");
die;
}
$self->{TSQL}->do("SET NAMES '".$self->state->db_client_encoding."'") if ($self->state->db_client_encoding);
$self->{TSQL_level} = 1;
#���� �� ����������� �������� �� 0
$self->{TSQLStable} = 0 unless (exists $self->{TSQLStable});
}
$self->{_t_connect_ok} = 1;
$self->{oldSQL} = $self->{SQL} if ($self->{SQL} and (!$self->{oldSQL}));
$self->{SQL} = $self->{TSQL};
return 1;
}
#��������� ���������� � ����� (�������� ���� �� ��� keeper ����)
#���������� $dbh ��� undef
sub create_db_connect {
my $self = shift;
return DBI->connect("dbi:Pg:dbname=$self->{db_name};".( $self->{db_host} ne 'localhost' ? "host=$self->{db_host};" : "" )."port=$self->{db_port}", $self->{db_user}, $self->{db_password}, { 'AutoCommit' => 1, pg_server_prepare => $self->{db_prepare}, 'pg_enable_utf8' => $self->{db_enable_utf8} } );
}
sub create_db_t_connect {
my $self = shift;
return DBI->connect("dbi:Pg:dbname=$self->{db_name};".( $self->{db_host} ne 'localhost' ? "host=$self->{db_host};" : "" )."port=$self->{db_port}", $self->{db_user}, $self->{db_password}, { 'AutoCommit' => 0, pg_server_prepare => $self->{db_prepare}, 'pg_enable_utf8' => $self->{db_enable_utf8} } );
}
#���������� �������� ��������� ���������� � �����
sub is_connected {
my $self = shift;
if (ref($self->{SQL}) and $self->{SQL}->can('ping') and $self->{SQL}->ping()) {
$self->{_connect_ok} = 1;
return 1;
} else {
$self->{_connect_ok} = 0;
return 0;
}
}
#���������� �������� ��������� ���������� � �����
sub is_t_connected {
my $self = shift;
if (ref($self->{TSQL}) and $self->{TSQL}->can('ping') and $self->{TSQL}->ping()) {
$self->{_t_connect_ok} = 1;
return 1;
} else {
$self->{_t_connect_ok} = 0;
return 0;
}
}
#�������� ���������� � ����� ���������� ��������� ����������
sub connect_check {
my $self = shift;
return 1 if ($self->{_connect_ok});
if ($self->is_connected) {
$self->{_connect_ok} = 1;
return 1;
} else {
if ($self->connect) {
return 1;
} else {
#���� �� ������ �������� �� ������ ��� ��� die �������� ������
return 0;
}
}
}
sub t_connect_check {
my $self = shift;
return 1 if ($self->{_t_connect_ok});
if ($self->is_t_connected) {
$self->{_t_connect_ok} = 1;
return 1;
} else {
if ($self->t_connect) {
return 1;
} else {
#���� �� ������ �������� �� ������ ��� ��� die �������� ������
return 0;
}
}
}
# -------------------------------------------------------------------------------------------------
# ��������� ���������� � ����� ������
# -------------------------------------------------------------------------------------------------
sub shutdown
{
my $self = shift;
$self->{SQL} = $self->{oldSQL} if $self->{oldSQL};
delete $self->{oldSQL};
$self->{SQL}->disconnect() if ($self->is_connected);
delete $self->{SQL};
$self->{_connect_ok} = 0;
$log->info("������� ���������� � ����� ������ PostgreSQL �� ����� ".$self->{db_port}." keepalive=".$self->state->db_keepalive) if $self->{debug};
return 1;
}
#���������� ���������� � ���������� ����������
sub t_shutdown {
my $self = shift;
my $force = shift;
#���� �� ������ stable transaction enabled connect �� ������ ���
if ($force or !$self->TSQLStable) {
$self->{SQL} = $self->{oldSQL} if ($self->{oldSQL});
$self->{TSQL}->disconnect() if ($self->is_t_connected);
delete $self->{TSQL};
$self->{_t_connect_ok} = 0;
}
return 1;
}
#rollback+disconnect 2 � 1 ������� ��� ������ � ��������� ���������
#�������� ���������� ��� �� ���� || return $keeper->t_abort("��� �� ��������� ������");
sub t_abort {
my $self=shift;
if ($self->is_t_connected) {
$self->{TSQL}->rollback();
#� ����� t_abort �� ��������� ������� ����������� ����������
$self->t_shutdown();
}
return undef;
}
#commit+disconnect 2 � 1 �������
sub t_finish {
my $self=shift;
if ($self->is_t_connected) {
$self->{TSQL_level}--;
#����� �� ����� ���� ������� ��
#���� ������� ��������
# <0 ������ �� ������������ ������
if ($self->{TSQL_level}<=0) {
$self->{TSQL}->commit();
$self->t_shutdown();
}
}
return 1;
}
#������ � ���������� ���������� TSQLStable (����������� ��������������� ����������)
sub TSQLStable {
my $self = shift;
my $val = shift;
if (defined $val) {
$self->{TSQLStable} = $val;
} else {
$self->{TSQLStable} ||= 0;
}
return $self->{TSQLStable};
}
#COMPATIBILITY SUBS
sub db_connect {
return shift->connect;
}
sub t_dis_connect {
return shift->t_shutdown;
}
1;