Line # Revision Author
1 3 ahitrov@rambler.ru package Contenido::DB::PostgreSQL;
2
3 # ----------------------------------------------------------------------------
4 # ����� ���������� ������ ����� ������ PostgreSQL
5 # ----------------------------------------------------------------------------
6 use strict;
7 use warnings;
8
9 use DBI;
10 use DBD::Pg;
11
12 use Contenido::Globals;
13 use Contenido::Msg;
14
15 # ������ ������� � ����������� � ����� �����
16 # ��������� ���������� � ����� ��� ��������� ������ ���� ��� �� ����
17 sub SQL {
18 my $self = shift;
19 return ($self->connect_check() ? $self->{SQL} : undef);
20 }
21
22 #��������� ��������������� ���������� � ����� ��� ��������� ������ ���� ��� �� ����
23 sub TSQL {
24 my $self = shift;
25 return ($self->t_connect_check() ? $self->{TSQL} : undef);
26 }
27
28 # -------------------------------------------------------------------------------------------------
29 # ��������� ���������� � ����� ������
30 # -------------------------------------------------------------------------------------------------
31 sub connect {
32 my $self = shift;
33 #���������� ��� ����
34 if ($self->is_connected) {
35 } else {
36 unless ($self->{SQL} = $self->create_db_connect) {
37 $log->error("�� ���� ����������� � ����� ������");
38 die;
39 }
40 $self->{SQL}->do("SET NAMES '".$self->state->db_client_encoding."'") if ($self->state->db_client_encoding);
41 }
42
43 $self->{_connect_ok} = 1;
44 return 1;
45 }
46
47 sub t_connect {
48 my $self = shift;
49 #�������������� connect ��� ����
50 if ($self->is_t_connected) {
51 $self->{TSQL_level}++;
52 } else {
53 unless ($self->{TSQL} = $self->create_db_t_connect) {
54 $log->error("�� ���� ����������� � ����� ������");
55 die;
56 }
57 $self->{TSQL}->do("SET NAMES '".$self->state->db_client_encoding."'") if ($self->state->db_client_encoding);
58 $self->{TSQL_level} = 1;
59 #���� �� ����������� �������� �� 0
60 $self->{TSQLStable} = 0 unless (exists $self->{TSQLStable});
61 }
62 $self->{_t_connect_ok} = 1;
63 $self->{oldSQL} = $self->{SQL} if ($self->{SQL} and (!$self->{oldSQL}));
64 $self->{SQL} = $self->{TSQL};
65
66 return 1;
67 }
68
69 #��������� ���������� � ����� (�������� ���� �� ��� keeper ����)
70 #���������� $dbh ��� undef
71 sub create_db_connect {
72 my $self = shift;
73 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} } );
74 }
75
76 sub create_db_t_connect {
77 my $self = shift;
78 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} } );
79 }
80
81 #���������� �������� ��������� ���������� � �����
82 sub is_connected {
83 my $self = shift;
84 if (ref($self->{SQL}) and $self->{SQL}->can('ping') and $self->{SQL}->ping()) {
85 $self->{_connect_ok} = 1;
86 return 1;
87 } else {
88 $self->{_connect_ok} = 0;
89 return 0;
90 }
91 }
92
93 #���������� �������� ��������� ���������� � �����
94 sub is_t_connected {
95 my $self = shift;
96 if (ref($self->{TSQL}) and $self->{TSQL}->can('ping') and $self->{TSQL}->ping()) {
97 $self->{_t_connect_ok} = 1;
98 return 1;
99 } else {
100 $self->{_t_connect_ok} = 0;
101 return 0;
102 }
103 }
104
105 #�������� ���������� � ����� ���������� ��������� ����������
106 sub connect_check {
107 my $self = shift;
108 return 1 if ($self->{_connect_ok});
109 if ($self->is_connected) {
110 $self->{_connect_ok} = 1;
111 return 1;
112 } else {
113 if ($self->connect) {
114 return 1;
115 } else {
116 #���� �� ������ �������� �� ������ ��� ��� die �������� ������
117 return 0;
118 }
119 }
120 }
121
122 sub t_connect_check {
123 my $self = shift;
124 return 1 if ($self->{_t_connect_ok});
125 if ($self->is_t_connected) {
126 $self->{_t_connect_ok} = 1;
127 return 1;
128 } else {
129 if ($self->t_connect) {
130 return 1;
131 } else {
132 #���� �� ������ �������� �� ������ ��� ��� die �������� ������
133 return 0;
134 }
135 }
136 }
137
138 # -------------------------------------------------------------------------------------------------
139 # ��������� ���������� � ����� ������
140 # -------------------------------------------------------------------------------------------------
141 sub shutdown
142 {
143 my $self = shift;
144 $self->{SQL} = $self->{oldSQL} if $self->{oldSQL};
145 delete $self->{oldSQL};
146 $self->{SQL}->disconnect() if ($self->is_connected);
147 delete $self->{SQL};
148 $self->{_connect_ok} = 0;
149 $log->info("������� ���������� � ����� ������ PostgreSQL �� ����� ".$self->{db_port}." keepalive=".$self->state->db_keepalive) if $self->{debug};
150 return 1;
151 }
152
153 #���������� ���������� � ���������� ����������
154 sub t_shutdown {
155 my $self = shift;
156 my $force = shift;
157 #���� �� ������ stable transaction enabled connect �� ������ ���
158 if ($force or !$self->TSQLStable) {
159 $self->{SQL} = $self->{oldSQL} if ($self->{oldSQL});
160 $self->{TSQL}->disconnect() if ($self->is_t_connected);
161 delete $self->{TSQL};
162 $self->{_t_connect_ok} = 0;
163 }
164 return 1;
165 }
166
167 #rollback+disconnect 2 � 1 ������� ��� ������ � ��������� ���������
168 #�������� ���������� ��� �� ���� || return $keeper->t_abort("��� �� ��������� ������");
169 sub t_abort {
170 my $self=shift;
171 if ($self->is_t_connected) {
172 $self->{TSQL}->rollback();
173 #� ����� t_abort �� ��������� ������� ����������� ����������
174 $self->t_shutdown();
175 }
176 return undef;
177 }
178
179 #commit+disconnect 2 � 1 �������
180 sub t_finish {
181 my $self=shift;
182 if ($self->is_t_connected) {
183 $self->{TSQL_level}--;
184 #����� �� ����� ���� ������� ��
185 #���� ������� ��������
186 # <0 ������ �� ������������ ������
187 if ($self->{TSQL_level}<=0) {
188 $self->{TSQL}->commit();
189 $self->t_shutdown();
190 }
191 }
192 return 1;
193 }
194
195 #������ � ���������� ���������� TSQLStable (����������� ��������������� ����������)
196 sub TSQLStable {
197 my $self = shift;
198 my $val = shift;
199 if (defined $val) {
200 $self->{TSQLStable} = $val;
201 } else {
202 $self->{TSQLStable} ||= 0;
203 }
204 return $self->{TSQLStable};
205 }
206
207
208 #COMPATIBILITY SUBS
209 sub db_connect {
210 return shift->connect;
211 }
212
213 sub t_dis_connect {
214 return shift->t_shutdown;
215 }
216
217 1;
218