| line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
|
1
|
|
|
|
|
|
|
#!/usr/bin/perl |
|
2
|
|
|
|
|
|
|
#$Id: pssql.pm 4848 2014-08-07 21:22:41Z pro $ $URL: svn://svn.setun.net/search/trunk/lib/pssql.pm $ |
|
3
|
|
|
|
|
|
|
|
|
4
|
|
|
|
|
|
|
=copyright |
|
5
|
|
|
|
|
|
|
PRO-search sql library |
|
6
|
|
|
|
|
|
|
Copyright (C) 2003-2011 Oleg Alexeenkov http://pro.setun.net/search/ proler@gmail.com |
|
7
|
|
|
|
|
|
|
|
|
8
|
|
|
|
|
|
|
This program is free software: you can redistribute it and/or modify |
|
9
|
|
|
|
|
|
|
it under the terms of the GNU General Public License as published by |
|
10
|
|
|
|
|
|
|
the Free Software Foundation, either version 3 of the License, or |
|
11
|
|
|
|
|
|
|
(at your option) any later version. |
|
12
|
|
|
|
|
|
|
|
|
13
|
|
|
|
|
|
|
This program is distributed in the hope that it will be useful, |
|
14
|
|
|
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
15
|
|
|
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
16
|
|
|
|
|
|
|
GNU General Public License for more details. |
|
17
|
|
|
|
|
|
|
|
|
18
|
|
|
|
|
|
|
You should have received a copy of the GNU General Public License |
|
19
|
|
|
|
|
|
|
along with this program. If not, see . |
|
20
|
|
|
|
|
|
|
=cut |
|
21
|
|
|
|
|
|
|
|
|
22
|
|
|
|
|
|
|
=c |
|
23
|
|
|
|
|
|
|
todo: |
|
24
|
|
|
|
|
|
|
|
|
25
|
|
|
|
|
|
|
pg |
|
26
|
|
|
|
|
|
|
2009/10/06-13:53:11 dev HandleError DBD::Pg::db do failed: no connection to the server |
|
27
|
|
|
|
|
|
|
DBI::db=HASH(0x1229568) 7 no connection to the server |
|
28
|
|
|
|
|
|
|
|
|
29
|
|
|
|
|
|
|
|
|
30
|
|
|
|
|
|
|
|
|
31
|
|
|
|
|
|
|
2009/06/02-19:37:35 dev HandleError DBD::Pg::st execute failed: FATAL: terminating connection due to administrator command |
|
32
|
|
|
|
|
|
|
server closed the connection unexpectedly |
|
33
|
|
|
|
|
|
|
This probably means the server terminated abnormally |
|
34
|
|
|
|
|
|
|
before or while processing the request. |
|
35
|
|
|
|
|
|
|
DBI::st=HASH(0x271b688) 7 FATAL: terminating connection due to administrator command |
|
36
|
|
|
|
|
|
|
server closed the connection unexpectedly |
|
37
|
|
|
|
|
|
|
This probably means the server terminated abnormally |
|
38
|
|
|
|
|
|
|
before or while processing the request. |
|
39
|
|
|
|
|
|
|
|
|
40
|
|
|
|
|
|
|
2009/06/02-19:37:35 dev err_parse st0 ret1 wdi= di= fa= 1 er= 300 1000 fatal 57P01 |
|
41
|
|
|
|
|
|
|
2009/06/02-19:37:36 dev HandleError DBD::Pg::st execute failed: no connection to the server |
|
42
|
|
|
|
|
|
|
DBI::st=HASH(0x271b718) 7 no connection to the server |
|
43
|
|
|
|
|
|
|
|
|
44
|
|
|
|
|
|
|
2009/06/02-19:37:39 dev HandleError DBD::Pg::db do failed: no connection to the server |
|
45
|
|
|
|
|
|
|
DBI::db=HASH(0x1209d38) 7 no connection to the server |
|
46
|
|
|
|
|
|
|
|
|
47
|
|
|
|
|
|
|
|
|
48
|
|
|
|
|
|
|
|
|
49
|
|
|
|
|
|
|
$work |
|
50
|
|
|
|
|
|
|
|
|
51
|
|
|
|
|
|
|
=cut |
|
52
|
|
|
|
|
|
|
|
|
53
|
|
|
|
|
|
|
#our ( %config); |
|
54
|
|
|
|
|
|
|
package #no cpan |
|
55
|
|
|
|
|
|
|
pssql; |
|
56
|
1
|
|
|
1
|
|
7
|
use strict; |
|
|
1
|
|
|
|
|
2
|
|
|
|
1
|
|
|
|
|
53
|
|
|
57
|
1
|
|
|
1
|
|
5
|
use utf8; |
|
|
1
|
|
|
|
|
3
|
|
|
|
1
|
|
|
|
|
9
|
|
|
58
|
1
|
|
|
1
|
|
27
|
no warnings qw(uninitialized); |
|
|
1
|
|
|
|
|
2
|
|
|
|
1
|
|
|
|
|
53
|
|
|
59
|
1
|
|
|
1
|
|
6
|
no if $] >= 5.017011, warnings => 'experimental::smartmatch'; |
|
|
1
|
|
|
|
|
2
|
|
|
|
1
|
|
|
|
|
8
|
|
|
60
|
|
|
|
|
|
|
our $VERSION = ( split( ' ', '$Revision: 4848 $' ) )[1]; |
|
61
|
|
|
|
|
|
|
#use locale; |
|
62
|
1
|
|
|
1
|
|
7776
|
use DBI; |
|
|
1
|
|
|
|
|
63976
|
|
|
|
1
|
|
|
|
|
92
|
|
|
63
|
1
|
|
|
1
|
|
15
|
use Time::HiRes qw(time); |
|
|
1
|
|
|
|
|
2
|
|
|
|
1
|
|
|
|
|
12
|
|
|
64
|
1
|
|
|
1
|
|
160
|
use Data::Dumper; #dev only |
|
|
1
|
|
|
|
|
2
|
|
|
|
1
|
|
|
|
|
145
|
|
|
65
|
|
|
|
|
|
|
$Data::Dumper::Sortkeys = $Data::Dumper::Useqq = $Data::Dumper::Indent = $Data::Dumper::Terse = 1; |
|
66
|
|
|
|
|
|
|
our ( %work, ); #%stat %static, $param, |
|
67
|
|
|
|
|
|
|
our (%config); |
|
68
|
|
|
|
|
|
|
#local *config = *main::config; |
|
69
|
|
|
|
|
|
|
#*pssql::config = *main::config; |
|
70
|
|
|
|
|
|
|
#*pssql::work = *main::work; |
|
71
|
|
|
|
|
|
|
#*pssql::stat = *main::stat; |
|
72
|
|
|
|
|
|
|
*config = *main::config; |
|
73
|
|
|
|
|
|
|
*work = *main::work; |
|
74
|
|
|
|
|
|
|
*stat = *main::stat; |
|
75
|
1
|
|
|
1
|
|
5
|
use lib::abs './'; |
|
|
1
|
|
|
|
|
2
|
|
|
|
1
|
|
|
|
|
12
|
|
|
76
|
1
|
|
|
1
|
|
601
|
use psmisc; |
|
|
1
|
|
|
|
|
3
|
|
|
|
1
|
|
|
|
|
40
|
|
|
77
|
|
|
|
|
|
|
#use psconn; |
|
78
|
|
|
|
|
|
|
#our ( %config, %work, %stat, %static, $param, ); |
|
79
|
1
|
|
|
1
|
|
6
|
use base 'psconn'; |
|
|
1
|
|
|
|
|
2
|
|
|
|
1
|
|
|
|
|
3996
|
|
|
80
|
|
|
|
|
|
|
our $AUTOLOAD; |
|
81
|
|
|
|
|
|
|
#our $VERSION = ( split( ' ', '$Revision: 4848 $' ) )[1]; |
|
82
|
|
|
|
|
|
|
my ( $tq, $rq, $vq ); |
|
83
|
|
|
|
|
|
|
my ( $roworder, $tableorder, ); |
|
84
|
|
|
|
|
|
|
our ( %row, %default ); |
|
85
|
|
|
|
|
|
|
$config{ 'log_' . $_ } = 0 for grep { !exists $config{ 'log_' . $_ } } qw(trace dmpbef); |
|
86
|
|
|
|
|
|
|
#warn "SQL UESEEDDD" ; |
|
87
|
|
|
|
|
|
|
sub row { |
|
88
|
4
|
|
|
4
|
0
|
10
|
my $row = shift @_; |
|
89
|
|
|
|
|
|
|
return { |
|
90
|
4
|
50
|
33
|
|
|
7
|
%{ ( defined $config{'row'} ? $config{'row'}{$row} : undef ) || $row{$row} || {} }, %{ $config{'row_all'} || {} }, |
|
|
4
|
50
|
|
|
|
58
|
|
|
|
4
|
50
|
|
|
|
75
|
|
|
91
|
|
|
|
|
|
|
'order' => --$roworder, |
|
92
|
|
|
|
|
|
|
@_ |
|
93
|
|
|
|
|
|
|
}; |
|
94
|
|
|
|
|
|
|
} |
|
95
|
|
|
|
|
|
|
|
|
96
|
|
|
|
|
|
|
sub table { |
|
97
|
0
|
|
|
0
|
0
|
|
my $table = shift @_; |
|
98
|
0
|
|
|
|
|
|
return @_; |
|
99
|
|
|
|
|
|
|
#{ |
|
100
|
|
|
|
|
|
|
#%{ ( defined $config{'row'} ? $config{'row'}{$row} : undef ) || $row{$row} || {} }, %{ $config{'row_all'} || {} }, |
|
101
|
|
|
|
|
|
|
#'order' => --$tableorder, |
|
102
|
|
|
|
|
|
|
#@_ |
|
103
|
|
|
|
|
|
|
#}; |
|
104
|
|
|
|
|
|
|
} |
|
105
|
|
|
|
|
|
|
#} |
|
106
|
|
|
|
|
|
|
BEGIN { |
|
107
|
1
|
|
|
1
|
|
20
|
%row = ( |
|
108
|
|
|
|
|
|
|
'time' => { |
|
109
|
|
|
|
|
|
|
'type' => 'INT', |
|
110
|
|
|
|
|
|
|
'unsigned' => 1, |
|
111
|
|
|
|
|
|
|
'default' => 0, |
|
112
|
|
|
|
|
|
|
'date_time' => 1, #todo |
|
113
|
|
|
|
|
|
|
}, |
|
114
|
|
|
|
|
|
|
'uint' => { 'type' => 'INTEGER', 'unsigned' => 1, 'default' => 0, }, |
|
115
|
|
|
|
|
|
|
'uint16' => { 'type' => 'SMALLINT', 'unsigned' => 1, 'default' => 0, }, |
|
116
|
|
|
|
|
|
|
'uint64' => { 'type' => 'BIGINT', 'unsigned' => 1, 'default' => 0, }, |
|
117
|
|
|
|
|
|
|
'text' => { 'type' => 'VARCHAR', 'index' => 10, 'default' => '', }, |
|
118
|
|
|
|
|
|
|
'stem' => { |
|
119
|
|
|
|
|
|
|
'type' => 'VARCHAR', |
|
120
|
|
|
|
|
|
|
#! 'length' => 128, |
|
121
|
|
|
|
|
|
|
'fulltext' => 'stemi', |
|
122
|
|
|
|
|
|
|
'default' => '', |
|
123
|
|
|
|
|
|
|
'not null' => 1, |
|
124
|
|
|
|
|
|
|
'stem_index' => 1, |
|
125
|
|
|
|
|
|
|
}, |
|
126
|
|
|
|
|
|
|
); |
|
127
|
1
|
|
33
|
|
|
11
|
$row{'id'} ||= row( 'uint', 'auto_increment' => 1, 'primary' => 1 ), |
|
|
|
|
33
|
|
|
|
|
|
128
|
|
|
|
|
|
|
$row{'added'} ||= row( 'time', 'default_insert' => int( time() ), 'no_insert_update' => 1, ); |
|
129
|
1
|
|
33
|
|
|
14
|
$row{'year'} ||= row('uint16'); |
|
130
|
1
|
|
33
|
|
|
10
|
$row{'size'} ||= row('uint64'); |
|
131
|
|
|
|
|
|
|
%default = ( |
|
132
|
0
|
0
|
|
|
|
0
|
'null' => { 'do' => sub { }, 'query' => sub { wantarray ? () : [] }, 'line' => sub { {} }, }, |
|
|
0
|
|
|
|
|
0
|
|
|
|
0
|
|
|
|
|
0
|
|
|
133
|
|
|
|
|
|
|
'sqlite' => { |
|
134
|
|
|
|
|
|
|
#'dbi' => 'SQLite2', |
|
135
|
|
|
|
|
|
|
'dbi' => 'SQLite', |
|
136
|
|
|
|
|
|
|
'params' => [qw(dbname)], |
|
137
|
|
|
|
|
|
|
'dbname' => $config{'root_path'} . 'sqlite.db', |
|
138
|
|
|
|
|
|
|
'no_update_limit' => 1, #pg sux |
|
139
|
|
|
|
|
|
|
'table quote' => '"', |
|
140
|
|
|
|
|
|
|
'row quote' => '"', |
|
141
|
|
|
|
|
|
|
'value quote' => "'", |
|
142
|
|
|
|
|
|
|
'IF NOT EXISTS' => 'IF NOT EXISTS', |
|
143
|
|
|
|
|
|
|
'index_IF NOT EXISTS' => 'IF NOT EXISTS', |
|
144
|
|
|
|
|
|
|
'IF EXISTS' => 'IF EXISTS', |
|
145
|
|
|
|
|
|
|
'REPLACE' => 'REPLACE', |
|
146
|
|
|
|
|
|
|
'AUTO_INCREMENT' => 'AUTOINCREMENT', |
|
147
|
|
|
|
|
|
|
'ANALYZE' => 'ANALYZE', |
|
148
|
|
|
|
|
|
|
'err_ignore' => [qw( 1 )], |
|
149
|
|
|
|
|
|
|
'error_type' => sub { #TODO!!! |
|
150
|
0
|
|
|
|
|
0
|
my $self = shift; |
|
151
|
0
|
|
|
|
|
0
|
my ( $err, $errstr ) = @_; |
|
152
|
|
|
|
|
|
|
#$self->log('dev',"ERRDETECT($err, $errstr)"); |
|
153
|
0
|
0
|
|
|
|
0
|
return 'install' if $errstr =~ /no such table:|unable to open database file/i; |
|
154
|
0
|
0
|
0
|
|
|
0
|
return 'syntax' if $errstr =~ /syntax|unrecognized token/i or $errstr =~ /misuse of aggregate/; |
|
155
|
0
|
0
|
|
|
|
0
|
return 'retry' if $errstr =~ /database is locked/i; |
|
156
|
0
|
0
|
|
|
|
0
|
return 'upgrade' if $errstr =~ /no such column/i; |
|
157
|
|
|
|
|
|
|
#return 'connection' if $errstr =~ /connect/i; |
|
158
|
0
|
|
|
|
|
0
|
return undef; |
|
159
|
|
|
|
|
|
|
}, |
|
160
|
2
|
|
|
|
|
25564
|
'pragma' => { |
|
161
|
|
|
|
|
|
|
map { |
|
162
|
|
|
|
|
|
|
$_ => $_ |
|
163
|
|
|
|
|
|
|
} 'synchronous = OFF', |
|
164
|
|
|
|
|
|
|
'auto_vacuum = FULL' |
|
165
|
|
|
|
|
|
|
}, |
|
166
|
|
|
|
|
|
|
'on_connect' => sub { |
|
167
|
0
|
|
|
|
|
0
|
my $self = shift; |
|
168
|
0
|
0
|
|
|
|
0
|
$self->do("PRAGMA $_;") for keys %{ $self->{'pragma'} || {} }; |
|
|
0
|
|
|
|
|
0
|
|
|
169
|
|
|
|
|
|
|
#$self->log( 'sql', 'on_connect!' ); |
|
170
|
|
|
|
|
|
|
}, |
|
171
|
|
|
|
|
|
|
'no_dbirows' => 1, |
|
172
|
|
|
|
|
|
|
}, |
|
173
|
|
|
|
|
|
|
'pg' => { |
|
174
|
|
|
|
|
|
|
'dbi' => 'Pg', |
|
175
|
|
|
|
|
|
|
'user' => ( $^O =~ /^(?:(ms)?(dos|win(32|nt)?)|linux)/i ? 'postgres' : 'pgsql' ), |
|
176
|
|
|
|
|
|
|
#'port' => 5432, |
|
177
|
|
|
|
|
|
|
'IF EXISTS' => 'IF EXISTS', |
|
178
|
|
|
|
|
|
|
'CREATE TABLE' => 'CREATE TABLE', |
|
179
|
|
|
|
|
|
|
'OFFSET' => 'OFFSET', |
|
180
|
|
|
|
|
|
|
'IF NOT EXISTS' => 'IF NOT EXISTS', #9.2 ok |
|
181
|
|
|
|
|
|
|
#'unsigned' => 0, |
|
182
|
|
|
|
|
|
|
'UNSIGNED' => '', #pg sux |
|
183
|
|
|
|
|
|
|
'no_delete_limit' => 1, #pg sux |
|
184
|
|
|
|
|
|
|
'table quote' => '"', |
|
185
|
|
|
|
|
|
|
'row quote' => '"', |
|
186
|
|
|
|
|
|
|
'value quote' => "'", |
|
187
|
|
|
|
|
|
|
'index_name_table' => 1, |
|
188
|
|
|
|
|
|
|
'REPLACE' => 'INSERT', |
|
189
|
|
|
|
|
|
|
'EXPLAIN' => 'EXPLAIN ANALYZE', |
|
190
|
|
|
|
|
|
|
'CASCADE' => 'CASCADE', |
|
191
|
|
|
|
|
|
|
'SET NAMES' => 'SET client_encoding = ', |
|
192
|
|
|
|
|
|
|
'fulltext_config' => 'pg_catalog.simple', |
|
193
|
|
|
|
|
|
|
'params' => [ |
|
194
|
|
|
|
|
|
|
qw(host hostaddr port options dbname database db user username password service sslmode), qw( |
|
195
|
|
|
|
|
|
|
) |
|
196
|
|
|
|
|
|
|
], |
|
197
|
|
|
|
|
|
|
'err_ignore' => [qw( 1 7)], |
|
198
|
|
|
|
|
|
|
'error_type' => sub { |
|
199
|
0
|
|
|
|
|
0
|
my $self = shift, my ( $err, $errstr ) = @_; |
|
200
|
|
|
|
|
|
|
#$self->log('dev',"ERRDETECT($err, [$errstr])"); |
|
201
|
0
|
0
|
|
|
|
0
|
return 'connection' if $errstr eq $err; # 7, [7] # wtf |
|
202
|
0
|
0
|
|
|
|
0
|
return 'install_db' if $errstr =~ /FATAL:\s*database ".*?" does not exist/i; |
|
203
|
0
|
0
|
|
|
|
0
|
return 'connection' if $errstr =~ /FATAL:\s*terminating connection/i; #7 |
|
204
|
0
|
0
|
|
|
|
0
|
return 'fatal' if $errstr =~ /fatal/i; |
|
205
|
0
|
0
|
|
|
|
0
|
return 'syntax' if $errstr =~ /syntax/i; |
|
206
|
0
|
0
|
|
|
|
0
|
return 'connection' if $errstr =~ /ERROR:\s*prepared statement ".*?" does not exist/i; |
|
207
|
0
|
0
|
0
|
|
|
0
|
return 'connection' if $errstr =~ /connect|Unknown message type: ''/i and $errstr !~ /(?:column|relation) "/; #"mc |
|
208
|
0
|
0
|
|
|
|
0
|
return 'install' if $errstr =~ /ERROR:\s*(?:relation \S+ does not exist)/i; |
|
209
|
|
|
|
|
|
|
#return 'retry' if $errstr =~ /ERROR:\s*cannot drop the currently open database/i; |
|
210
|
0
|
0
|
|
|
|
0
|
return 'retry' if $errstr =~ /ERROR: database ".*?" is being accessed by other users/i; |
|
211
|
0
|
0
|
|
|
|
0
|
return 'ignore' |
|
212
|
|
|
|
|
|
|
if $errstr =~ |
|
213
|
|
|
|
|
|
|
/(?:duplicate key violates unique constraint)|(?:duplicate key value violates unique constraint)|(?:ERROR:\s*(?:database ".*?" already exists)|(?:relation ".*?" already exists)|(?:invalid byte sequence for encoding)|(?:function .*? does not exist)|(?:null value in column .*? violates not-null constraint)|(?:Can't create database '.*?'; database exists))/i; |
|
214
|
0
|
|
|
|
|
0
|
return undef; |
|
215
|
|
|
|
|
|
|
}, |
|
216
|
|
|
|
|
|
|
'set' => { 'lc_messages' => 'C' }, |
|
217
|
|
|
|
|
|
|
'on_connect' => sub { |
|
218
|
0
|
|
|
|
|
0
|
my $self = shift; |
|
219
|
0
|
|
|
|
|
0
|
$self->{dbh}->{pg_utf8_strings} = $self->{dbh}->{pg_enable_utf8} = 1; |
|
220
|
0
|
|
|
|
|
0
|
$self->set_names(); |
|
221
|
0
|
0
|
0
|
|
|
0
|
$self->do("select set_curcfg('default');") if $self->{'use_fulltext'} and $self->{'old_fulltext'}; |
|
222
|
0
|
0
|
|
|
|
0
|
$self->do("SET $_=$vq$self->{'set'}{$_}$vq;") for grep {!$self->{'no_set_'.$_}} sort keys %{ $self->{'set'} || {} }; |
|
|
0
|
|
|
|
|
0
|
|
|
|
0
|
|
|
|
|
0
|
|
|
223
|
|
|
|
|
|
|
}, |
|
224
|
|
|
|
|
|
|
'no_dbirows' => 1, |
|
225
|
|
|
|
|
|
|
'cp1251' => 'win1251', |
|
226
|
|
|
|
|
|
|
'fulltext_word_glue' => '&', |
|
227
|
|
|
|
|
|
|
}, |
|
228
|
|
|
|
|
|
|
'sphinx' => { |
|
229
|
|
|
|
|
|
|
'dbi' => 'mysql', |
|
230
|
|
|
|
|
|
|
'user' => 'root', |
|
231
|
|
|
|
|
|
|
'port' => 9306, |
|
232
|
|
|
|
|
|
|
'params' => [qw(host port )], # perldoc DBD::mysql |
|
233
|
|
|
|
|
|
|
'sphinx' => 1, |
|
234
|
|
|
|
|
|
|
'value quote' => "'", |
|
235
|
|
|
|
|
|
|
'no_dbirows' => 1, |
|
236
|
|
|
|
|
|
|
'no_column_prepend_table' => 1, |
|
237
|
|
|
|
|
|
|
'no_join' => 1, |
|
238
|
|
|
|
|
|
|
'OPTION' => 'OPTION', |
|
239
|
|
|
|
|
|
|
'option' => { 'max_query_time' => 20000, 'cutoff' => 1000, 'ranker' => 'sph04', }, |
|
240
|
|
|
|
|
|
|
}, |
|
241
|
|
|
|
|
|
|
'mysql5' => { |
|
242
|
|
|
|
|
|
|
'dbi' => 'mysql', |
|
243
|
|
|
|
|
|
|
'user' => 'root', |
|
244
|
|
|
|
|
|
|
'use_drh' => 1, |
|
245
|
|
|
|
|
|
|
'mysql_enable_utf8' => 1, |
|
246
|
|
|
|
|
|
|
'varchar_max' => 65530, |
|
247
|
|
|
|
|
|
|
'unique_max' => 1000, |
|
248
|
|
|
|
|
|
|
'primary_max' => 999, |
|
249
|
|
|
|
|
|
|
'fulltext_max' => 1000, |
|
250
|
|
|
|
|
|
|
'key_length' => 1000, # maybe 3072 for mariadb |
|
251
|
|
|
|
|
|
|
'err_connection' => [qw( 1 1040 1053 1129 1213 1226 2002 2003 2006 2013 )], |
|
252
|
|
|
|
|
|
|
'err_fatal' => [qw( 1016 1046 1251 )], # 1045, |
|
253
|
|
|
|
|
|
|
'err_syntax' => [qw( 1060 1064 1065 1067 1071 1096 1103 1118 1148 1191 1364 1366 1406 1439)], #1054 #maybe all 1045..1075 |
|
254
|
|
|
|
|
|
|
'err_repair' => [qw( 126 130 144 145 1034 1062 1194 1582 )], |
|
255
|
|
|
|
|
|
|
'err_retry' => [qw( 1317 )], |
|
256
|
|
|
|
|
|
|
'err_install' => [qw( 1146)], # 1017 repair? |
|
257
|
|
|
|
|
|
|
'err_install_db' => [qw( 1049 )], |
|
258
|
|
|
|
|
|
|
'err_upgrade' => [qw( 1054 )], |
|
259
|
|
|
|
|
|
|
'err_ignore ' => [qw( 2 1264 1061 )], |
|
260
|
|
|
|
|
|
|
'error_type' => sub { |
|
261
|
0
|
|
|
|
|
0
|
my $self = shift, my ( $err, $errstr ) = @_; |
|
262
|
|
|
|
|
|
|
#$self->log('dev',"MYERRDETECT($err, $errstr)"); |
|
263
|
0
|
|
|
|
|
0
|
for my $errtype (qw(connection retry syntax fatal repair install install_db upgrade)) { |
|
264
|
|
|
|
|
|
|
#$self->log('dev',"ERRDETECTED($err, $errstr) = $errtype"), |
|
265
|
0
|
0
|
|
|
|
0
|
return $errtype if grep { $err eq $_ } @{ $self->{ 'err_' . $errtype } }; |
|
|
0
|
|
|
|
|
0
|
|
|
|
0
|
|
|
|
|
0
|
|
|
266
|
|
|
|
|
|
|
} |
|
267
|
0
|
|
|
|
|
0
|
return undef; |
|
268
|
|
|
|
|
|
|
}, |
|
269
|
|
|
|
|
|
|
'table quote' => "`", |
|
270
|
|
|
|
|
|
|
'row quote' => "`", |
|
271
|
|
|
|
|
|
|
'value quote' => "'", |
|
272
|
|
|
|
|
|
|
#'index quote' => "`", |
|
273
|
|
|
|
|
|
|
#'unsigned' => 1, |
|
274
|
|
|
|
|
|
|
'quote_slash' => 1, |
|
275
|
|
|
|
|
|
|
'index in create table' => 1, |
|
276
|
|
|
|
|
|
|
'utf-8' => 'utf8', |
|
277
|
|
|
|
|
|
|
'koi8-r' => 'koi8r', |
|
278
|
|
|
|
|
|
|
'table options' => 'ENGINE = MYISAM DELAY_KEY_WRITE=1', |
|
279
|
|
|
|
|
|
|
'IF NOT EXISTS' => 'IF NOT EXISTS', |
|
280
|
|
|
|
|
|
|
'IF EXISTS' => 'IF EXISTS', |
|
281
|
|
|
|
|
|
|
'IGNORE' => 'IGNORE', |
|
282
|
|
|
|
|
|
|
'REPLACE' => 'REPLACE', |
|
283
|
|
|
|
|
|
|
'INSERT' => 'INSERT', |
|
284
|
|
|
|
|
|
|
'HIGH_PRIORITY' => 'HIGH_PRIORITY', |
|
285
|
|
|
|
|
|
|
'SET NAMES' => 'SET NAMES', |
|
286
|
|
|
|
|
|
|
'DEFAULT CHARACTER SET' => 'DEFAULT CHARACTER SET', |
|
287
|
|
|
|
|
|
|
'USE_FRM' => 'USE_FRM', |
|
288
|
|
|
|
|
|
|
'EXTENDED' => 'EXTENDED', |
|
289
|
|
|
|
|
|
|
'QUICK' => 'QUICK', |
|
290
|
|
|
|
|
|
|
'ON DUPLICATE KEY UPDATE' => 'ON DUPLICATE KEY UPDATE', |
|
291
|
|
|
|
|
|
|
'UNSIGNED' => 'UNSIGNED', |
|
292
|
|
|
|
|
|
|
'UNLOCK TABLES' => 'UNLOCK TABLES', |
|
293
|
|
|
|
|
|
|
'LOCK TABLES' => 'LOCK TABLES', |
|
294
|
|
|
|
|
|
|
'OPTIMIZE' => 'OPTIMIZE TABLE', |
|
295
|
|
|
|
|
|
|
'ANALYZE' => 'ANALYZE TABLE', |
|
296
|
|
|
|
|
|
|
'CHECK' => 'CHECK TABLE', |
|
297
|
|
|
|
|
|
|
'FLUSH' => 'FLUSH TABLE', |
|
298
|
|
|
|
|
|
|
'LOW_PRIORITY' => 'LOW_PRIORITY', |
|
299
|
|
|
|
|
|
|
'on_connect' => sub { |
|
300
|
0
|
|
|
|
|
0
|
my $self = shift; |
|
301
|
0
|
|
|
|
|
0
|
$self->{'db_id'} = $self->{'dbh'}->{'mysql_thread_id'}; |
|
302
|
0
|
0
|
0
|
|
|
0
|
$self->set_names() if !( $ENV{'MOD_PERL'} || $ENV{'FCGI_ROLE'} ); |
|
303
|
|
|
|
|
|
|
}, |
|
304
|
|
|
|
|
|
|
'on_user' => sub { |
|
305
|
0
|
|
|
|
|
0
|
my $self = shift; |
|
306
|
0
|
0
|
0
|
|
|
0
|
$self->set_names() if $ENV{'MOD_PERL'} || $ENV{'FCGI_ROLE'}; |
|
307
|
|
|
|
|
|
|
}, |
|
308
|
|
|
|
|
|
|
'params' => [ |
|
309
|
|
|
|
|
|
|
qw(host port database mysql_client_found_rows mysql_compression mysql_connect_timeout mysql_read_default_file mysql_read_default_group mysql_socket |
|
310
|
|
|
|
|
|
|
mysql_ssl mysql_ssl_client_key mysql_ssl_client_cert mysql_ssl_ca_file mysql_ssl_ca_path mysql_ssl_cipher |
|
311
|
|
|
|
|
|
|
mysql_local_infile mysql_embedded_options mysql_embedded_groups mysql_enable_utf8) |
|
312
|
|
|
|
|
|
|
], # perldoc DBD::mysql |
|
313
|
|
|
|
|
|
|
'insert_by' => 1000, ( !$ENV{'SERVER_PORT'} ? ( 'auto_check' => 1 ) : () ), 'unique name' => 1, # test it |
|
314
|
|
|
|
|
|
|
'match' => sub { |
|
315
|
0
|
|
|
|
|
0
|
my $self = shift; |
|
316
|
0
|
|
|
|
|
0
|
my ( $param, $param_num, $table, $search_str, $search_str_stem ) = @_; |
|
317
|
0
|
|
|
|
|
0
|
my ( $ask, $glue ); |
|
318
|
0
|
|
|
|
|
0
|
local %_; |
|
319
|
0
|
0
|
0
|
|
|
0
|
map { $_{ $self->{'table'}{$table}{$_}{'fulltext'} } = 1 } |
|
|
0
|
|
|
|
|
0
|
|
|
320
|
0
|
|
|
|
|
0
|
grep { $self->{'table'}{$table}{$_}{'fulltext'} or ( $self->{'sphinx'} and $self->{'table'}{$table}{$_}{'sphinx'} ) } |
|
321
|
0
|
|
|
|
|
0
|
keys %{ $self->{'table'}{$table} }; |
|
322
|
0
|
|
|
|
|
0
|
for my $index ( keys %_ ) { |
|
323
|
0
|
0
|
|
|
|
0
|
if ( |
|
324
|
0
|
|
|
|
|
0
|
$_ = join( ' , ', |
|
325
|
0
|
|
|
|
|
0
|
map { "$rq$_$rq" } |
|
326
|
0
|
|
|
|
|
0
|
sort { $self->{'table'}{$table}{$b}{'order'} <=> $self->{'table'}{$table}{$a}{'order'} } |
|
327
|
0
|
|
|
|
|
0
|
grep { $self->{'table'}{$table}{$_}{'fulltext'} eq $index } keys %{ $self->{'table'}{$table} } ) |
|
328
|
|
|
|
|
|
|
) |
|
329
|
|
|
|
|
|
|
{ |
|
330
|
0
|
0
|
|
|
|
0
|
my $stem = |
|
331
|
0
|
|
|
|
|
0
|
grep { $self->{'table'}{$table}{$_}{'fulltext'} eq $index and $self->{'table'}{$table}{$_}{'stem_index'} } |
|
332
|
0
|
|
|
|
|
0
|
keys %{ $self->{'table'}{$table} }; |
|
333
|
|
|
|
|
|
|
#TODO: maybe some message for user ? |
|
334
|
0
|
0
|
0
|
|
|
0
|
$self->{'accurate'} = 1, next, |
|
|
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
335
|
|
|
|
|
|
|
if ($stem |
|
336
|
|
|
|
|
|
|
and length $search_str_stem |
|
337
|
|
|
|
|
|
|
and $self->{'auto_accurate_on_slow'} |
|
338
|
|
|
|
|
|
|
and $search_str_stem =~ /\b\w{$self->{'auto_accurate_on_slow'}}\b/ ); |
|
339
|
0
|
0
|
|
|
|
0
|
my $double = |
|
340
|
0
|
|
|
|
|
0
|
grep { $self->{'table'}{$table}{$_}{'fulltext'} and $self->{'table'}{$table}{$_}{'stem'} } |
|
341
|
0
|
|
|
|
|
0
|
keys %{ $self->{'table'}{$table} }; |
|
342
|
0
|
0
|
0
|
|
|
0
|
next if $double and ( $self->{'accurate'} xor !$stem ); |
|
|
|
|
0
|
|
|
|
|
|
343
|
0
|
|
|
|
|
0
|
my $match; |
|
344
|
0
|
0
|
|
|
|
0
|
if ( $self->{'sphinx'} ) { $match = ' MATCH (' . $self->squotes( $stem ? $search_str_stem : $search_str ) . ')' } |
|
|
0
|
0
|
|
|
|
0
|
|
|
345
|
|
|
|
|
|
|
else { |
|
346
|
0
|
0
|
0
|
|
|
0
|
$match = ' MATCH (' . $_ . ')' . ' AGAINST (' . $self->squotes( $stem ? $search_str_stem : $search_str ) . ( |
|
|
|
0
|
|
|
|
|
|
|
347
|
|
|
|
|
|
|
( !$self->{'no_boolean'} and $param->{ 'adv_query' . $param_num } eq 'on' ) |
|
348
|
|
|
|
|
|
|
? 'IN BOOLEAN MODE' |
|
349
|
|
|
|
|
|
|
#: ( $self->{'allow_query_expansion'} ? 'WITH QUERY EXPANSION' : '' ) |
|
350
|
|
|
|
|
|
|
: $self->{'fulltext_extra'} |
|
351
|
|
|
|
|
|
|
) . ') '; |
|
352
|
|
|
|
|
|
|
} |
|
353
|
0
|
|
|
|
|
0
|
$ask .= " $glue " . $match; |
|
354
|
0
|
0
|
0
|
|
|
0
|
$work{'what_relevance'}{$table} ||= $match . " AS $rq" . "relev$rq" |
|
|
|
|
0
|
|
|
|
|
|
355
|
|
|
|
|
|
|
if $self->{'select_relevance'} |
|
356
|
|
|
|
|
|
|
or $self->{'table_param'}{$table}{'select_relevance'}; |
|
357
|
|
|
|
|
|
|
} |
|
358
|
0
|
|
|
|
|
0
|
$glue = $self->{'fulltext_glue'}; |
|
359
|
|
|
|
|
|
|
} |
|
360
|
0
|
|
|
|
|
0
|
return $ask; |
|
361
|
|
|
|
|
|
|
}, |
|
362
|
|
|
|
|
|
|
}, |
|
363
|
1
|
50
|
|
|
|
26
|
); |
|
|
|
50
|
|
|
|
|
|
|
364
|
|
|
|
|
|
|
} |
|
365
|
|
|
|
|
|
|
|
|
366
|
|
|
|
|
|
|
sub new { |
|
367
|
0
|
|
|
0
|
0
|
|
my $self = bless( {}, shift ); |
|
368
|
0
|
|
|
|
|
|
$self->init(@_); |
|
369
|
0
|
|
|
|
|
|
$self->psconn::init(@_); |
|
370
|
0
|
|
|
|
|
|
return $self; |
|
371
|
|
|
|
|
|
|
} |
|
372
|
|
|
|
|
|
|
|
|
373
|
|
|
|
|
|
|
sub cmd { |
|
374
|
0
|
|
|
0
|
0
|
|
my $self = shift; |
|
375
|
0
|
|
|
|
|
|
my $cmd = shift; |
|
376
|
0
|
0
|
|
|
|
|
$self->log( 'trace', "pssql::$cmd [$self->{'dbh'}]", @_ ) if $cmd ne 'log'; |
|
377
|
0
|
0
|
|
|
|
|
$self->{'handler_bef'}{$cmd}->( $self, \@_ ) if $self->{'handler_bef'}{$cmd}; |
|
378
|
0
|
0
|
|
|
|
|
my @ret = |
|
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
379
|
|
|
|
|
|
|
ref( $self->{$cmd} ) eq 'CODE' |
|
380
|
|
|
|
|
|
|
? ( wantarray ? ( $self->{$cmd}->( $self, @_ ) ) : scalar $self->{$cmd}->( $self, @_ ) ) |
|
381
|
|
|
|
|
|
|
: ( |
|
382
|
|
|
|
|
|
|
exists $self->{$cmd} |
|
383
|
|
|
|
|
|
|
? ( ( defined( $_[0] ) ? ( $self->{$cmd} = $_[0] ) : ( $self->{$cmd} ) ) ) |
|
384
|
|
|
|
|
|
|
: ((!ref $self->{'dbh'}) ? () |
|
385
|
|
|
|
|
|
|
: $self->{'dbh'}->can($cmd) ? $self->{'dbh'}->$cmd(@_) |
|
386
|
|
|
|
|
|
|
: exists $self->{'dbh'}{$cmd} ? ( ( defined( $_[0] ) ? ( $self->{'dbh'}->{$cmd} = $_[0] ) : ( $self->{'dbh'}->{$cmd} ) ) ) |
|
387
|
|
|
|
|
|
|
: undef ) |
|
388
|
|
|
|
|
|
|
); |
|
389
|
0
|
0
|
|
|
|
|
$self->{'handler'}{$cmd}->( $self, \@_, \@ret ) if $self->{'handler'}{$cmd}; |
|
390
|
0
|
0
|
|
|
|
|
return wantarray ? @ret : $ret[0]; |
|
391
|
|
|
|
|
|
|
} |
|
392
|
|
|
|
|
|
|
|
|
393
|
|
|
|
|
|
|
sub AUTOLOAD { |
|
394
|
0
|
|
|
0
|
|
|
my $self = shift; |
|
395
|
0
|
0
|
|
|
|
|
my $type = ref($self) or return; |
|
396
|
0
|
|
|
|
|
|
my $name = $AUTOLOAD; |
|
397
|
0
|
|
|
|
|
|
$name =~ s/.*://; # strip fully-qualified portion |
|
398
|
|
|
|
|
|
|
#$self->log('dev', 'autoload', $name, $AUTOLOAD, @_); |
|
399
|
0
|
|
|
|
|
|
return $self->cmd( $name, @_ ); |
|
400
|
|
|
|
|
|
|
} |
|
401
|
|
|
|
|
|
|
|
|
402
|
|
|
|
|
|
|
sub _disconnect { |
|
403
|
0
|
|
|
0
|
|
|
my $self = shift; |
|
404
|
0
|
|
|
|
|
|
$self->log( 'trace', 'pssql::_diconnect', "dbh=$self->{'dbh'}" ); |
|
405
|
0
|
0
|
|
|
|
|
$self->flush_insert() unless $self->{'in_disconnect'}; |
|
406
|
0
|
|
|
|
|
|
$self->{'in_disconnect'} = 1; |
|
407
|
0
|
|
|
|
|
|
return 0; |
|
408
|
|
|
|
|
|
|
} |
|
409
|
|
|
|
|
|
|
|
|
410
|
|
|
|
|
|
|
sub _dropconnect { |
|
411
|
0
|
|
|
0
|
|
|
my $self = shift; |
|
412
|
0
|
|
|
|
|
|
$self->log( 'trace', 'pssql::_dropconnect' ); |
|
413
|
0
|
|
|
|
|
|
$self->{'in_disconnect'} = 1; |
|
414
|
0
|
0
|
|
|
|
|
$self->{'sth'}->finish() if $self->{'sth'}; |
|
415
|
0
|
0
|
0
|
|
|
|
$self->{'dbh'}->disconnect(), $self->{'dbh'} = undef if $self->{'dbh'} and keys %{ $self->{'dbh'} }; |
|
|
0
|
|
|
|
|
|
|
|
416
|
0
|
|
|
|
|
|
delete $self->{'in_disconnect'}; |
|
417
|
0
|
|
|
|
|
|
return 0; |
|
418
|
|
|
|
|
|
|
} |
|
419
|
|
|
|
|
|
|
|
|
420
|
|
|
|
|
|
|
sub _check { |
|
421
|
0
|
|
|
0
|
|
|
my $self = shift; |
|
422
|
0
|
0
|
0
|
|
|
|
return 1 if !$self->{'dbh'} or !$self->{'connected'}; #or !keys %{$self->{'dbh'}}; |
|
423
|
0
|
|
|
|
|
|
return !$self->{'dbh'}->ping(); |
|
424
|
|
|
|
|
|
|
} |
|
425
|
|
|
|
|
|
|
|
|
426
|
|
|
|
|
|
|
sub init { |
|
427
|
0
|
|
|
0
|
0
|
|
my $self = shift; |
|
428
|
|
|
|
|
|
|
#warn Dumper $self, \@_; |
|
429
|
|
|
|
|
|
|
local %_ = ( |
|
430
|
|
|
|
|
|
|
'log' => sub (@) { |
|
431
|
0
|
|
|
0
|
|
|
shift; |
|
432
|
0
|
|
|
|
|
|
psmisc::printlog(@_); |
|
433
|
|
|
|
|
|
|
}, |
|
434
|
|
|
|
|
|
|
'trace'=>sub(@) { |
|
435
|
0
|
|
|
0
|
|
|
shift; |
|
436
|
0
|
|
|
|
|
|
psmisc::trace(@_); |
|
437
|
|
|
|
|
|
|
}, |
|
438
|
|
|
|
|
|
|
'driver' => 'mysql5', |
|
439
|
|
|
|
|
|
|
'host' => ( $^O eq 'cygwin' ? '127.0.0.1' : 'localhost' ), |
|
440
|
|
|
|
|
|
|
'database' => 'pssqldef', |
|
441
|
|
|
|
|
|
|
#'connect_tries' => 100, |
|
442
|
|
|
|
|
|
|
'error_sleep' => ( $ENV{'SERVER_PORT'} ? 1 : 3600 ), |
|
443
|
|
|
|
|
|
|
'error_tries' => ( $ENV{'SERVER_PORT'} ? 1 : 1000 ), |
|
444
|
|
|
|
|
|
|
'error_chain_tries' => ( $ENV{'SERVER_PORT'} ? 1 : 100 ), |
|
445
|
|
|
|
|
|
|
#($ENV{'SERVER_PORT'} ? ('connect_tries'=>1) : ()), |
|
446
|
|
|
|
|
|
|
#'reconnect_tries' => 10, #look old |
|
447
|
|
|
|
|
|
|
'connect_tries' => ( $ENV{'SERVER_PORT'} ? 1 : 0 ), |
|
448
|
|
|
|
|
|
|
'connect_chain_tries' => 0, |
|
449
|
|
|
|
|
|
|
'connect_auto' => 0, |
|
450
|
|
|
|
|
|
|
'connect_params' => { |
|
451
|
|
|
|
|
|
|
'RaiseError' => 0, |
|
452
|
|
|
|
|
|
|
'AutoCommit' => 1, |
|
453
|
|
|
|
|
|
|
'PrintError' => 0, |
|
454
|
|
|
|
|
|
|
'PrintWarn' => 0, |
|
455
|
|
|
|
|
|
|
'HandleError' => sub { |
|
456
|
0
|
|
|
0
|
|
|
$self->trace( 'dev', 'HandleError', @_, $DBI::err, $DBI::errstr ); |
|
457
|
0
|
|
|
|
|
|
$self->err(join ', ', grep {$_} $DBI::err, $DBI::errstr); |
|
|
0
|
|
|
|
|
|
|
|
458
|
0
|
0
|
0
|
|
|
|
push @{$self->{error_log}||=[]},$self->err() if $self->{'error_collect'}; |
|
|
0
|
|
|
|
|
|
|
|
459
|
|
|
|
|
|
|
#psmisc::caller_trace(15) |
|
460
|
|
|
|
|
|
|
}, |
|
461
|
|
|
|
|
|
|
}, |
|
462
|
|
|
|
|
|
|
#'connect_check' => 1, #check connection on every keep() |
|
463
|
0
|
0
|
|
|
|
|
( $ENV{'SERVER_PORT'} ? () : ( 'auto_repair' => 10 ) ), # or number 10-30 |
|
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
464
|
|
|
|
|
|
|
'auto_repair_selected' => 0, # repair all tables |
|
465
|
|
|
|
|
|
|
'auto_install' => 1, 'auto_install_db' => 1, 'err_retry_unknown' => 0, |
|
466
|
|
|
|
|
|
|
#'reconnect_sleep' => 3600, #maximum sleep on connect error |
|
467
|
|
|
|
|
|
|
'codepage' => 'utf-8', |
|
468
|
|
|
|
|
|
|
#'cp_in' => 'utf-8', |
|
469
|
|
|
|
|
|
|
'index_postfix' => '_i', 'limit_max' => 1000, 'limit_default' => 100, |
|
470
|
|
|
|
|
|
|
#'limit' => 100, |
|
471
|
|
|
|
|
|
|
'page_min' => 1, 'page_default' => 1, |
|
472
|
|
|
|
|
|
|
#'varchar_max' => 255, |
|
473
|
|
|
|
|
|
|
'varchar_max' => 65535, |
|
474
|
|
|
|
|
|
|
'row_max' => 65535, |
|
475
|
|
|
|
|
|
|
'primary_max' => 65535, |
|
476
|
|
|
|
|
|
|
'fulltext_max' => 65535, |
|
477
|
|
|
|
|
|
|
'AUTO_INCREMENT' => 'AUTO_INCREMENT', |
|
478
|
|
|
|
|
|
|
'EXPLAIN' => 'EXPLAIN', |
|
479
|
|
|
|
|
|
|
'statable' => { 'queries' => 1, 'connect_tried' => 1, 'connects' => 1, 'inserts' => 1 }, |
|
480
|
|
|
|
|
|
|
'statable_time' => { 'queries_time' => 1, 'queries_avg' => 1, }, |
|
481
|
|
|
|
|
|
|
'param_trans_int' => { 'on_page' => 'limit', 'show_from' => 'limit_offset', 'page' => 'page', 'accurate' => 'accurate' }, |
|
482
|
|
|
|
|
|
|
#'param_trans' => { 'codepage'=>'cp_out' ,}, |
|
483
|
|
|
|
|
|
|
'connect_cached' => 1, |
|
484
|
|
|
|
|
|
|
'char_type' => 'VARCHAR', |
|
485
|
|
|
|
|
|
|
'true' => 1, |
|
486
|
|
|
|
|
|
|
'fulltext_glue' => 'OR', |
|
487
|
|
|
|
|
|
|
'retry_vars' => [qw(auto_repair connect_tries connect_chain_tries error_sleep error_tries auto_check)], |
|
488
|
|
|
|
|
|
|
'err' => 0, |
|
489
|
|
|
|
|
|
|
'insert_cached_time' => 60, |
|
490
|
|
|
|
|
|
|
'stat_every' => 60, |
|
491
|
|
|
|
|
|
|
'auto_repairs_max' => 2, |
|
492
|
|
|
|
|
|
|
@_, |
|
493
|
|
|
|
|
|
|
); |
|
494
|
0
|
|
|
|
|
|
@{$self}{ keys %_ } = values %_; |
|
|
0
|
|
|
|
|
|
|
|
495
|
|
|
|
|
|
|
#$self->{$_} //= $_{$_} for keys %_; |
|
496
|
|
|
|
|
|
|
#%_ = @_; |
|
497
|
|
|
|
|
|
|
#$self->{$_} = $_{$_} for keys %_; |
|
498
|
|
|
|
|
|
|
#$self->log( 'dev', 'initdb', "$self->{'database'},$self->{'dbname'};"); |
|
499
|
0
|
0
|
|
|
|
|
$self->{'database'} = $self->{'dbname'} if $self->{'dbname'}; |
|
500
|
0
|
|
0
|
|
|
|
$self->{'dbname'} ||= $self->{'database'}; |
|
501
|
0
|
|
|
|
|
|
$self->calc(); |
|
502
|
0
|
|
|
|
|
|
$self->functions(); |
|
503
|
0
|
|
|
|
|
|
( $tq, $rq, $vq ) = $self->quotes(); |
|
504
|
0
|
0
|
0
|
|
|
|
DBI->trace( $self->{'trace_level'}, $self->{'trace'} ) if $self->{'trace_level'} and $self->{'trace'}; |
|
505
|
0
|
|
|
|
|
|
return 0; |
|
506
|
|
|
|
|
|
|
} |
|
507
|
|
|
|
|
|
|
|
|
508
|
|
|
|
|
|
|
sub calc { |
|
509
|
0
|
|
|
0
|
0
|
|
my $self = shift; |
|
510
|
0
|
|
0
|
|
|
|
$self->{'default'} ||= \%default; |
|
511
|
|
|
|
|
|
|
$self->{'default'}{'pg'}{'match'} = sub { |
|
512
|
0
|
|
|
0
|
|
|
my $self = shift; |
|
513
|
0
|
0
|
|
|
|
|
return undef unless $self->{'use_fulltext'}; |
|
514
|
0
|
|
|
|
|
|
my ( $param, $param_num, $table, $search_str, $search_str_stem ) = @_; |
|
515
|
0
|
|
|
|
|
|
my ( $ask, $glue ); |
|
516
|
0
|
|
|
|
|
|
s/(?:^\s+)|(?:\s+$)//, s/\s+/$self->{'fulltext_word_glue'}/g for ( $search_str, $search_str_stem ); |
|
517
|
0
|
|
|
|
|
|
local %_; |
|
518
|
0
|
|
|
|
|
|
map { $_{ $self->{'table'}{$table}{$_}{'fulltext'} } = 1 } |
|
|
0
|
|
|
|
|
|
|
|
519
|
0
|
|
|
|
|
|
grep { $self->{'table'}{$table}{$_}{'fulltext'} } keys %{ $self->{'table'}{$table} }; |
|
|
0
|
|
|
|
|
|
|
|
520
|
0
|
|
|
|
|
|
for my $index ( keys %_ ) { |
|
521
|
0
|
0
|
|
|
|
|
my $stem = |
|
522
|
0
|
|
|
|
|
|
grep { $self->{'table'}{$table}{$_}{'fulltext'} eq $index and $self->{'table'}{$table}{$_}{'stem_index'} } |
|
523
|
0
|
|
|
|
|
|
keys %{ $self->{'table'}{$table} }; |
|
524
|
0
|
0
|
|
|
|
|
my $double = |
|
525
|
0
|
|
|
|
|
|
grep { $self->{'table'}{$table}{$_}{'fulltext'} and $self->{'table'}{$table}{$_}{'stem'} } |
|
526
|
0
|
|
|
|
|
|
keys %{ $self->{'table'}{$table} }; |
|
527
|
0
|
0
|
0
|
|
|
|
next if $double and ( $self->{'accurate'} xor !$stem ); |
|
|
|
|
0
|
|
|
|
|
|
528
|
0
|
0
|
|
|
|
|
$ask .= " $glue $index @@ to_tsquery( ${vq}$self->{'fulltext_config'}${vq}, " |
|
529
|
|
|
|
|
|
|
. $self->squotes( $stem ? $search_str_stem : $search_str ) . ")"; |
|
530
|
0
|
|
0
|
|
|
|
$glue ||= $self->{'fulltext_glue'}; |
|
531
|
|
|
|
|
|
|
} |
|
532
|
0
|
|
|
|
|
|
return $ask; |
|
533
|
|
|
|
|
|
|
} |
|
534
|
0
|
0
|
|
|
|
|
if $self->{'use_fulltext'}; |
|
535
|
0
|
|
|
|
|
|
%{ $self->{'default'}{'mysql6'} } = %{ $self->{'default'}{'mysql5'} }; |
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
536
|
0
|
|
|
|
|
|
%{ $self->{'default'}{'mysql4'} } = %{ $self->{'default'}{'mysql5'} }; |
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
537
|
0
|
|
|
|
|
|
$self->{'default'}{'mysql4'}{'SET NAMES'} = $self->{'default'}{'mysql4'}{'DEFAULT CHARACTER SET'} = |
|
538
|
|
|
|
|
|
|
$self->{'default'}{'mysql4'}{'ON DUPLICATE KEY UPDATE'} = ''; |
|
539
|
0
|
|
|
|
|
|
$self->{'default'}{'mysql4'}{'varchar_max'} = 255; |
|
540
|
0
|
|
|
|
|
|
%{ $self->{'default'}{'mysql3'} } = %{ $self->{'default'}{'mysql4'} }; |
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
541
|
0
|
|
|
|
|
|
$self->{'default'}{'mysql3'}{'table options'} = ''; |
|
542
|
0
|
|
|
|
|
|
$self->{'default'}{'mysql3'}{'USE_FRM'} = ''; |
|
543
|
0
|
|
|
|
|
|
$self->{'default'}{'mysql3'}{'no_boolean'} = 1; |
|
544
|
|
|
|
|
|
|
#%{ $self->{'default'}{'sqlite2'} } = %{ $self->{'default'}{'sqlite'} }; |
|
545
|
|
|
|
|
|
|
#$self->{'default'}{'sqlite2'}{'IF NOT EXISTS'} = $self->{'default'}{'sqlite2'}{'IF EXISTS'} = ''; |
|
546
|
0
|
0
|
|
|
|
|
$self->{'default'}{'pg'}{'fulltext_config'} = 'default' if $self->{'old_fulltext'}; |
|
547
|
0
|
|
|
|
|
|
%{ $self->{'default'}{'pgpp'} } = %{ $self->{'default'}{'pg'} }; |
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
548
|
0
|
|
|
|
|
|
$self->{'default'}{'pgpp'}{'dbi'} = 'PgPP'; |
|
549
|
0
|
|
|
|
|
|
$self->{'default'}{'pgpp'}{'params'} = [qw(dbname host port path debug)]; |
|
550
|
0
|
|
|
|
|
|
%{ $self->{'default'}{'mysqlpp'} } = %{ $self->{'default'}{'mysql5'} }; |
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
551
|
0
|
|
|
|
|
|
$self->{'default'}{'mysqlpp'}{'dbi'} = 'mysqlPP'; |
|
552
|
0
|
|
|
|
|
|
$self->{'default'}{'sphinx'}{'match'} = $self->{'default'}{'mysql5'}{'match'}; |
|
553
|
0
|
|
0
|
|
|
|
$self->{'driver'} ||= 'mysql5'; |
|
554
|
0
|
0
|
|
|
|
|
$self->{'driver'} = 'mysql5' if $self->{'driver'} eq 'mysql'; |
|
555
|
|
|
|
|
|
|
#print "U0:", $self->{user}; |
|
556
|
|
|
|
|
|
|
#print "D0:", $self->{dbi}; |
|
557
|
0
|
|
0
|
|
|
|
$self->{$_} //= $self->{'default'}{ $self->{'driver'} }{$_} for keys %{ $self->{'default'}{ $self->{'driver'} } }; |
|
|
0
|
|
|
|
|
|
|
|
558
|
|
|
|
|
|
|
#print "U1:", $self->{user}; |
|
559
|
|
|
|
|
|
|
#print "D1:", $self->{dbi}; |
|
560
|
|
|
|
|
|
|
#$self->log( 'dev', "calc dbi[$self->{'dbi'} ||= $self->{'driver'}]"); |
|
561
|
0
|
0
|
0
|
|
|
|
$self->{'dbi'} ||= $self->{'driver'}, $self->{'dbi'} =~ s/\d+$//i unless $self->{'dbi'}; |
|
562
|
0
|
|
|
|
|
|
$self->{'codepage'} = psmisc::cp_normalize( $self->{'codepage'} ); |
|
563
|
0
|
|
0
|
|
|
|
local $_ = $self->{ $self->{'codepage'} } || $self->{'codepage'}; |
|
564
|
0
|
|
|
|
|
|
$self->{'cp'} = $_; |
|
565
|
0
|
|
0
|
|
|
|
$self->{'cp_set_names'} ||= $_; |
|
566
|
|
|
|
|
|
|
#$self->{'cp_int'} ||= 'cp1251'; # internal |
|
567
|
0
|
|
0
|
|
|
|
$self->{'cp_int'} ||= 'utf-8'; # internal |
|
568
|
0
|
|
0
|
|
|
|
$self->{'cp_out'} ||= 'utf-8'; # internal |
|
569
|
0
|
|
|
|
|
|
$self->cp_client( $self->{'codepage'} ); |
|
570
|
|
|
|
|
|
|
} |
|
571
|
|
|
|
|
|
|
|
|
572
|
|
|
|
|
|
|
sub _connect { |
|
573
|
0
|
|
|
0
|
|
|
my $self = shift; |
|
574
|
|
|
|
|
|
|
|
|
575
|
|
|
|
|
|
|
=c |
|
576
|
|
|
|
|
|
|
$self->log( |
|
577
|
|
|
|
|
|
|
'dev', 'conn', |
|
578
|
|
|
|
|
|
|
"dbi:$self->{'dbi'}:" |
|
579
|
|
|
|
|
|
|
#"dbi:$self->{'default'}{ $self->{'driver'} }{'dbi'}:database=$self->{'base'};" |
|
580
|
|
|
|
|
|
|
#map {"$_:$self->{$_}"} qw(dbi database) |
|
581
|
|
|
|
|
|
|
. join( |
|
582
|
|
|
|
|
|
|
';', |
|
583
|
|
|
|
|
|
|
map( { $_ . '=' . $self->{$_} } |
|
584
|
|
|
|
|
|
|
grep { defined( $self->{$_} ) } @{ $self->{'params'} } ) |
|
585
|
|
|
|
|
|
|
), |
|
586
|
|
|
|
|
|
|
$self->{'user'}, |
|
587
|
|
|
|
|
|
|
$self->{'pass'}, |
|
588
|
|
|
|
|
|
|
#\%{ $self->{'connect_params'} } |
|
589
|
|
|
|
|
|
|
$self->{'connect_params'} |
|
590
|
|
|
|
|
|
|
); |
|
591
|
|
|
|
|
|
|
=cut |
|
592
|
|
|
|
|
|
|
|
|
593
|
0
|
|
|
|
|
|
local @_ = ( |
|
594
|
|
|
|
|
|
|
"dbi:$self->{'dbi'}:" |
|
595
|
0
|
|
|
|
|
|
. join( ';', map( { $_ . '=' . $self->{$_} } grep { defined( $self->{$_} ) } @{ $self->{'params'} } ) ), |
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
596
|
|
|
|
|
|
|
$self->{'user'}, $self->{'pass'}, $self->{'connect_params'} |
|
597
|
|
|
|
|
|
|
); |
|
598
|
|
|
|
|
|
|
#$self->log('dmp', "connect_cached = ",$self->{'connect_cached'}, Dumper(\@_)); |
|
599
|
0
|
0
|
|
|
|
|
$self->{'dbh'} = ( $self->{'connect_cached'} ? DBI->connect_cached(@_) : DBI->connect(@_) ); |
|
600
|
0
|
|
|
|
|
|
local $_ = $self->err_parse( \'Connection', $DBI::err, $DBI::errstr ); |
|
601
|
0
|
|
|
|
|
|
return $_; |
|
602
|
|
|
|
|
|
|
} |
|
603
|
|
|
|
|
|
|
|
|
604
|
|
|
|
|
|
|
sub sleep { |
|
605
|
0
|
|
|
0
|
0
|
|
my $self = shift; |
|
606
|
0
|
|
|
|
|
|
return psmisc::sleeper(@_); |
|
607
|
|
|
|
|
|
|
} |
|
608
|
|
|
|
|
|
|
|
|
609
|
|
|
|
|
|
|
sub functions { |
|
610
|
0
|
|
|
0
|
0
|
|
my $self = shift; |
|
611
|
|
|
|
|
|
|
$self->{'user_params'} ||= sub { |
|
612
|
0
|
|
|
0
|
|
|
my $self = shift; |
|
613
|
0
|
|
|
|
|
|
( $tq, $rq, $vq ) = $self->quotes(); |
|
614
|
0
|
|
|
|
|
|
my $param = { map { %$_ } @_ }; |
|
|
0
|
|
|
|
|
|
|
|
615
|
0
|
|
|
|
|
|
for my $from ( keys %{ $self->{'param_trans_int'} } ) { |
|
|
0
|
|
|
|
|
|
|
|
616
|
0
|
|
0
|
|
|
|
my $to = $self->{'param_trans_int'}{$from} || $from; |
|
617
|
0
|
0
|
|
|
|
|
$param->{$from} = 1 if $param->{$from} eq 'on'; |
|
618
|
0
|
|
|
|
|
|
$self->{$to} = |
|
619
|
|
|
|
|
|
|
psmisc::check_int( $param->{$from}, ( $self->{ $to . '_min' } ), $self->{ $to . '_max' }, $self->{ $to . '_default' } ); |
|
620
|
|
|
|
|
|
|
} |
|
621
|
0
|
|
0
|
|
|
|
$self->cp_client( $work{'codepage'} || $param->{'codepage'} || $config{'codepage'} ); |
|
622
|
0
|
|
0
|
|
|
|
}; |
|
623
|
|
|
|
|
|
|
$self->{'dump'} ||= sub { |
|
624
|
0
|
|
|
0
|
|
|
my $self = shift; |
|
625
|
0
|
|
|
|
|
|
$self->log( 'dmp', caller, ':=', join( ':', %$self ) ); |
|
626
|
0
|
|
|
|
|
|
return 0; |
|
627
|
0
|
|
0
|
|
|
|
}; |
|
628
|
|
|
|
|
|
|
$self->{'quotes'} ||= sub { |
|
629
|
|
|
|
|
|
|
#sub quotes { # my ($tq, $rq, $vq) = $self->quotes(); |
|
630
|
0
|
|
|
0
|
|
|
my $self = shift; |
|
631
|
0
|
|
0
|
|
|
|
$self->{'tq'} ||= $self->{'table quote'}; |
|
632
|
0
|
|
0
|
|
|
|
$self->{'rq'} ||= $self->{'row quote'}; |
|
633
|
0
|
|
0
|
|
|
|
$self->{'vq'} ||= $self->{'value quote'}; |
|
634
|
|
|
|
|
|
|
return ( |
|
635
|
0
|
|
|
|
|
|
$self->{'table quote'}, #$tq |
|
636
|
|
|
|
|
|
|
$self->{'row quote'}, #$rq |
|
637
|
|
|
|
|
|
|
$self->{'value quote'}, #$vq |
|
638
|
|
|
|
|
|
|
); |
|
639
|
0
|
|
0
|
|
|
|
}; |
|
640
|
|
|
|
|
|
|
$self->{'sleep'} ||= sub { |
|
641
|
0
|
|
|
0
|
|
|
my $self = shift; |
|
642
|
0
|
|
|
|
|
|
$self->log( 'dev', 'sql_sleeper', @_ ); |
|
643
|
0
|
|
|
|
|
|
return psmisc::sleeper(@_); |
|
644
|
0
|
|
0
|
|
|
|
}; |
|
645
|
|
|
|
|
|
|
$self->{'drh_init'} ||= sub { |
|
646
|
0
|
|
|
0
|
|
|
my $self = shift; |
|
647
|
0
|
|
0
|
|
|
|
$self->{'drh'} ||= DBI->install_driver( $self->{'dbi'} ); |
|
648
|
0
|
|
|
|
|
|
return 0; |
|
649
|
0
|
|
0
|
|
|
|
}; |
|
650
|
|
|
|
|
|
|
$self->{'repair'} ||= sub { |
|
651
|
0
|
|
|
0
|
|
|
my $self = shift; |
|
652
|
0
|
|
|
|
|
|
my $tim = psmisc::timer(); |
|
653
|
0
|
0
|
|
|
|
|
@_ = sort keys %{ $self->{'table'} } unless @_; |
|
|
0
|
|
|
|
|
|
|
|
654
|
0
|
0
|
|
|
|
|
@_ = grep { $_ and $self->{'table'}{$_} } @_; |
|
|
0
|
|
|
|
|
|
|
|
655
|
0
|
|
|
|
|
|
$self->log( 'info', 'Repairing table...', @_ ); |
|
656
|
0
|
0
|
|
|
|
|
$self->flush() unless $self->{'no_repair_flush'}; |
|
657
|
0
|
|
|
|
|
|
local $self->{'error_tries'} = 0; #! |
|
658
|
0
|
0
|
|
|
|
|
$self->query_log( "REPAIR TABLE " |
|
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
659
|
|
|
|
|
|
|
. join( ',', map( $self->tquote("$self->{'table_prefix'}$_"), @_ ) ) |
|
660
|
|
|
|
|
|
|
. ( $self->{'rep_quick'} ? ' ' . $self->{'QUICK'} : '' ) |
|
661
|
|
|
|
|
|
|
. ( $self->{'rep_ext'} ? ' ' . $self->{'EXTENDED'} : '' ) |
|
662
|
|
|
|
|
|
|
. ( $self->{'rep_frm'} ? ' ' . $self->{'USE_FRM'} : '' ) ); |
|
663
|
0
|
|
|
|
|
|
$self->flush(); |
|
664
|
0
|
|
|
|
|
|
$self->log( 'time', 'Repair per', psmisc::human( 'time_period', $tim->() ) ); |
|
665
|
0
|
|
|
|
|
|
return 0; |
|
666
|
0
|
|
0
|
|
|
|
}; |
|
667
|
|
|
|
|
|
|
$self->{'query_time'} ||= sub { |
|
668
|
0
|
|
|
0
|
|
|
my $self = shift; |
|
669
|
|
|
|
|
|
|
#$self->log( 'dev', 'query_time ', $_[0]); |
|
670
|
0
|
|
|
|
|
|
++$self->{'queries'}; |
|
671
|
0
|
|
|
|
|
|
$self->{'queries_time'} += $_[0]; |
|
672
|
0
|
|
0
|
|
|
|
$self->{'queries_avg'} = $self->{'queries_time'} / $self->{'queries'} || 1; |
|
673
|
0
|
|
0
|
|
|
|
}; |
|
674
|
|
|
|
|
|
|
$self->{'do'} ||= sub { |
|
675
|
0
|
|
|
0
|
|
|
my $self = shift; |
|
676
|
|
|
|
|
|
|
#$self->log( 'dev', 'do', @_); |
|
677
|
0
|
|
|
|
|
|
my $ret; |
|
678
|
0
|
0
|
|
|
|
|
return $ret if $self->keep(); |
|
679
|
0
|
|
|
|
|
|
$self->err(0); |
|
680
|
0
|
|
|
|
|
|
for my $cmd (@_) { |
|
681
|
0
|
0
|
|
|
|
|
next unless $cmd; |
|
682
|
0
|
|
0
|
|
|
|
do { |
|
683
|
|
|
|
|
|
|
{ |
|
684
|
0
|
|
|
|
|
|
$self->log( 'dmpbef', 'do(' . $self->{database} . '):[', $cmd, '] ' ); |
|
|
0
|
|
|
|
|
|
|
|
685
|
0
|
|
|
|
|
|
my $tim = psmisc::timer(); |
|
686
|
0
|
0
|
|
|
|
|
$ret += $self->{'dbh'}->do($cmd) if $self->{'dbh'}; |
|
687
|
0
|
|
0
|
|
|
|
$self->log( |
|
688
|
|
|
|
|
|
|
'dmp', 'do(' . $self->{database} . '):[', |
|
689
|
|
|
|
|
|
|
$cmd, '] = ', $ret, ' per', psmisc::human( 'time_period', $tim->() ), |
|
690
|
|
|
|
|
|
|
'rps', psmisc::human( 'float', $ret / ( $tim->() || 1 ) ) |
|
691
|
|
|
|
|
|
|
); |
|
692
|
0
|
|
|
|
|
|
$self->query_time( $tim->() ); |
|
693
|
|
|
|
|
|
|
} |
|
694
|
|
|
|
|
|
|
} while ( $self->can_query() and $self->err_parse( \$cmd, $DBI::err, $DBI::errstr ) ); |
|
695
|
|
|
|
|
|
|
} |
|
696
|
0
|
|
|
|
|
|
return $ret; |
|
697
|
0
|
|
0
|
|
|
|
}; |
|
698
|
|
|
|
|
|
|
$self->{'can_query'} ||= sub { |
|
699
|
0
|
|
|
0
|
|
|
my $self = shift; |
|
700
|
|
|
|
|
|
|
return |
|
701
|
0
|
|
0
|
|
|
|
!( $work{'die'} or $self->{'die'} or $self->{'fatal'} ) |
|
702
|
|
|
|
|
|
|
&& ( !$self->{'error_chain_tries'} or $self->{'errors_chain'} < $self->{'error_chain_tries'} ) |
|
703
|
|
|
|
|
|
|
&& ( !$self->{'error_tries'} or $self->{'errors'} < $self->{'error_tries'} ); |
|
704
|
0
|
|
0
|
|
|
|
}; |
|
705
|
|
|
|
|
|
|
$self->{'prepare'} ||= sub { |
|
706
|
0
|
|
|
0
|
|
|
my $self = shift; |
|
707
|
0
|
|
|
|
|
|
my ($query) = @_; |
|
708
|
0
|
0
|
|
|
|
|
return 1 if $self->keep(); |
|
709
|
0
|
|
|
|
|
|
$self->log( 'dmpbef', "prepare query {$query}" ); |
|
710
|
0
|
0
|
|
|
|
|
return 2 unless $query; |
|
711
|
|
|
|
|
|
|
#warn $self->err(); |
|
712
|
0
|
|
|
|
|
|
$self->err(0); |
|
713
|
0
|
|
|
|
|
|
my $ret; |
|
714
|
0
|
|
|
|
|
|
my $tim = psmisc::timer(); |
|
715
|
|
|
|
|
|
|
#$self->log('dbg', "prepare", __LINE__, ); |
|
716
|
0
|
|
0
|
|
|
|
do { |
|
717
|
|
|
|
|
|
|
{ |
|
718
|
0
|
0
|
|
|
|
|
next unless $self->{'dbh'}; |
|
|
0
|
|
|
|
|
|
|
|
719
|
0
|
0
|
|
|
|
|
$self->{'sth'}->finish() if $self->{'sth'}; |
|
720
|
0
|
|
|
|
|
|
$self->{'sth'} = $self->{'dbh'}->prepare($query); |
|
721
|
0
|
0
|
0
|
|
|
|
redo if $self->can_query() and $self->err_parse( \$query, $DBI::err, $DBI::errstr, 1 ); |
|
722
|
0
|
0
|
|
|
|
|
last unless $self->{'sth'}; |
|
723
|
0
|
|
|
|
|
|
$ret = $self->{'sth'}->execute(); |
|
724
|
|
|
|
|
|
|
} |
|
725
|
|
|
|
|
|
|
} while ( $self->can_query() and $self->err_parse( \$query, $DBI::err, $DBI::errstr ) ); |
|
726
|
0
|
|
|
|
|
|
$self->query_time( $tim->() ); |
|
727
|
|
|
|
|
|
|
#$self->log('dbg', "prepare", __LINE__, ); |
|
728
|
0
|
0
|
|
|
|
|
return 3 if $DBI::err; |
|
729
|
0
|
0
|
|
|
|
|
$self->{'dbirows'} = 0 if ( $self->{'dbirows'} = $DBI::rows ) == 4294967294; |
|
730
|
0
|
0
|
|
|
|
|
$self->{'dbirows'} = $self->{'limit'} if $self->{'no_dbirows'}; |
|
731
|
|
|
|
|
|
|
#$self->log('dbg', "prepare", __LINE__, ':',$ret, $DBI::rows,'=',(($self->{'no_dbirows'} && $ret) ? '0E0' : !int $ret), 'dr=', $self->{'dbirows'}); |
|
732
|
0
|
0
|
0
|
|
|
|
return ( ( $self->{'no_dbirows'} && $ret ) ? undef : !int $ret ); |
|
733
|
0
|
|
0
|
|
|
|
}; |
|
734
|
|
|
|
|
|
|
$self->{'line'} ||= sub { |
|
735
|
0
|
|
|
0
|
|
|
my $self = shift; |
|
736
|
|
|
|
|
|
|
#$self->log('dev', "line prep"); |
|
737
|
0
|
0
|
0
|
|
|
|
return {} if @_ and $self->prepare(@_); |
|
738
|
|
|
|
|
|
|
#$self->log('dev', "line sth"); |
|
739
|
0
|
0
|
0
|
|
|
|
return {} if !$self->{'sth'} or $self->{'sth'}->err; |
|
740
|
0
|
|
|
|
|
|
my $tim = psmisc::timer(); |
|
741
|
|
|
|
|
|
|
#$self->log('dev', "line fetch"); |
|
742
|
0
|
|
0
|
|
|
|
local $_ = $self->{'sth'}->fetchrow_hashref() || {}; |
|
743
|
0
|
0
|
|
|
|
|
$_ = scalar( psmisc::cp_trans_hash( $self->{'codepage'}, $self->{'cp_out'}, $_ ) ) if $self->{'codepage'} ne $self->{'cp_out'}; |
|
744
|
0
|
|
|
|
|
|
$self->{'queries_time'} += $tim->(); |
|
745
|
0
|
0
|
|
|
|
|
$self->log( |
|
746
|
|
|
|
|
|
|
'dmp', 'line(' . $self->{database} . '):[', @_, '] = ', scalar keys %$_, ' per', psmisc::human( 'time_period', $tim->() ), |
|
747
|
|
|
|
|
|
|
'err=', $self->err(), |
|
748
|
|
|
|
|
|
|
#( caller(2) )[0]); |
|
749
|
|
|
|
|
|
|
) if ( caller(2) )[0] ne 'pssql'; |
|
750
|
0
|
|
|
|
|
|
return $_; |
|
751
|
0
|
|
0
|
|
|
|
}; |
|
752
|
|
|
|
|
|
|
$self->{'query'} ||= sub { |
|
753
|
0
|
|
|
0
|
|
|
my $self = shift; |
|
754
|
|
|
|
|
|
|
#$self->log("qrun"); |
|
755
|
0
|
|
|
|
|
|
my $tim = psmisc::timer(); |
|
756
|
0
|
|
|
|
|
|
my @hash; |
|
757
|
0
|
|
|
|
|
|
for my $query (@_) { |
|
758
|
0
|
0
|
|
|
|
|
next unless $query; |
|
759
|
0
|
0
|
0
|
|
|
|
local $self->{'explain'} = 0, $self->query_log( $self->{'EXPLAIN'} . ' ' . $query ) |
|
760
|
|
|
|
|
|
|
if $self->{'explain'} and $self->{'EXPLAIN'}; |
|
761
|
0
|
|
|
|
|
|
local $_ = $self->line($query); |
|
762
|
0
|
0
|
|
|
|
|
next unless keys %$_; |
|
763
|
0
|
|
|
|
|
|
push( @hash, $_ ); |
|
764
|
0
|
0
|
0
|
|
|
|
next unless $self->{'sth'} and keys %$_; |
|
765
|
0
|
|
|
|
|
|
my $tim = psmisc::timer(); |
|
766
|
|
|
|
|
|
|
#$self->log("Db[",%$_,"]($self->{'codepage'}, $self->{'cp_out'})"), |
|
767
|
0
|
|
|
|
|
|
while ( $_ = $self->{'sth'}->fetchrow_hashref() ) { |
|
768
|
0
|
0
|
|
|
|
|
if ($self->{'codepage'} ne $self->{'cp_out'}) { |
|
769
|
0
|
|
|
|
|
|
push @hash, scalar psmisc::cp_trans_hash( $self->{'codepage'}, $self->{'cp_out'}, $_ ); |
|
770
|
|
|
|
|
|
|
} else { |
|
771
|
0
|
|
|
|
|
|
push @hash, $_; |
|
772
|
|
|
|
|
|
|
} |
|
773
|
|
|
|
|
|
|
} |
|
774
|
|
|
|
|
|
|
#$self->log("Da[",%$_,"]"), |
|
775
|
0
|
|
|
|
|
|
$self->{'queries_time'} += $tim->(); |
|
776
|
|
|
|
|
|
|
} |
|
777
|
|
|
|
|
|
|
$self->log( |
|
778
|
0
|
|
0
|
|
|
|
'dmp', 'query(' . $self->{database} . '):[', |
|
779
|
|
|
|
|
|
|
@_, '] = ', scalar @hash, ' per', psmisc::human( 'time_period', $tim->() ), |
|
780
|
|
|
|
|
|
|
'rps', psmisc::human( 'float', ( scalar @hash ) / ( $tim->() || 1 ) ), |
|
781
|
|
|
|
|
|
|
'err=', $self->err() |
|
782
|
|
|
|
|
|
|
); |
|
783
|
0
|
0
|
0
|
|
|
|
$self->{'dbirows'} = scalar @hash if $self->{'no_dbirows'} or $self->{'dbirows'} <= 0; |
|
784
|
|
|
|
|
|
|
#$self->log('dbirows=', $self->{'dbirows'}); |
|
785
|
|
|
|
|
|
|
#$self->query_print($_) for @hash; |
|
786
|
|
|
|
|
|
|
#$self->log('qcp', $self->{'codepage'}, Dumper \@hash); |
|
787
|
0
|
0
|
|
|
|
|
if ( $self->{'codepage'} eq 'utf-8' ) { |
|
788
|
0
|
|
|
|
|
|
for (@hash) { utf8::decode $_ for grep {!ref} %$_; } |
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
789
|
|
|
|
|
|
|
} |
|
790
|
0
|
0
|
|
|
|
|
return wantarray ? @hash : \@hash; |
|
791
|
0
|
|
0
|
|
|
|
}; |
|
792
|
|
|
|
|
|
|
$self->{'query_log'} ||= sub { |
|
793
|
0
|
|
|
0
|
|
|
my $self = shift; |
|
794
|
0
|
|
|
|
|
|
my @ret; |
|
795
|
0
|
|
|
|
|
|
for (@_) { push( @ret, $self->query_print( $self->query($_) ) ); } |
|
|
0
|
|
|
|
|
|
|
|
796
|
0
|
0
|
|
|
|
|
return wantarray ? @ret : \@ret; |
|
797
|
0
|
|
0
|
|
|
|
}; |
|
798
|
|
|
|
|
|
|
$self->{'query_print'} ||= sub { |
|
799
|
0
|
|
|
0
|
|
|
my $self = shift; |
|
800
|
0
|
|
|
|
|
|
my @hash = @_; |
|
801
|
0
|
0
|
0
|
|
|
|
return unless @hash and %{ $hash[0] }; |
|
|
0
|
|
|
|
|
|
|
|
802
|
0
|
|
|
|
|
|
$self->log( 'dbg', 'sql query', $_ ); |
|
803
|
0
|
0
|
|
|
|
|
$self->log( 'dbg', '|', join "\t|", keys %{ $hash[0] } ) if keys %{ $hash[0] }; |
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
804
|
0
|
|
|
|
|
|
$self->log( 'dbg', '|', join( "\t|", values %{$_} ) ) for @hash; |
|
|
0
|
|
|
|
|
|
|
|
805
|
0
|
0
|
|
|
|
|
return wantarray ? @_ : \@_; |
|
806
|
0
|
|
0
|
|
|
|
}; |
|
807
|
|
|
|
|
|
|
$self->{'quote'} ||= sub { |
|
808
|
0
|
|
|
0
|
|
|
my $self = shift; |
|
809
|
0
|
|
|
|
|
|
my ( $s, $q, $qmask ) = @_; |
|
810
|
0
|
0
|
0
|
|
|
|
return $s if $self->{'no_quote_null'} and $s =~ /^null$/i; |
|
811
|
0
|
0
|
0
|
|
|
|
return $self->{'dbh'}->quote( defined $s ? $s : '' ) if $self->{'dbh'} and !$q; |
|
|
|
0
|
|
|
|
|
|
|
812
|
0
|
|
0
|
|
|
|
$q ||= "'"; # mask "|', q=' |
|
813
|
0
|
0
|
|
|
|
|
if ( $self->{'quote_slash'} ) { $s =~ s/($q|\\)/\\$1/g; } |
|
|
0
|
|
|
|
|
|
|
|
814
|
0
|
|
|
|
|
|
else { $s =~ s/($q)/$1$1/g; } |
|
815
|
0
|
|
|
|
|
|
return $q . $s . $q; |
|
816
|
0
|
|
0
|
|
|
|
}; |
|
817
|
|
|
|
|
|
|
$self->{'squotes'} ||= sub { |
|
818
|
0
|
|
|
0
|
|
|
my $self = shift; |
|
819
|
0
|
|
|
|
|
|
return ' ' . $self->quote(@_) . ' '; |
|
820
|
0
|
|
0
|
|
|
|
}; |
|
821
|
|
|
|
|
|
|
$self->{'tquote'} ||= sub { |
|
822
|
0
|
|
|
0
|
|
|
my $self = shift; |
|
823
|
0
|
|
|
|
|
|
return $self->{'tq'} . $_[0] . $self->{'tq'}; |
|
824
|
0
|
|
0
|
|
|
|
}; |
|
825
|
|
|
|
|
|
|
$self->{'rquote'} ||= sub { |
|
826
|
0
|
|
|
0
|
|
|
my $self = shift; |
|
827
|
0
|
|
|
|
|
|
return $self->{'rq'} . $_[0] . $self->{'rq'}; |
|
828
|
0
|
|
0
|
|
|
|
}; |
|
829
|
0
|
|
0
|
|
|
|
$self->{'vquote'} ||= $self->{'quote'}; |
|
830
|
|
|
|
|
|
|
$self->{'filter_row'} ||= sub { |
|
831
|
0
|
|
|
0
|
|
|
my $self = shift; |
|
832
|
0
|
|
|
|
|
|
my ( $table, $filter, $values ) = @_; |
|
833
|
0
|
|
|
|
|
|
local %_; |
|
834
|
0
|
|
|
|
|
|
map { $_{$_} = $values->{$_} } grep { $self->{'table'}{$table}{$_}{$filter} } keys %{ $self->{'table'}{$table} }; |
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
835
|
0
|
0
|
|
|
|
|
return wantarray ? %_ : \%_; |
|
836
|
0
|
|
0
|
|
|
|
}; |
|
837
|
|
|
|
|
|
|
$self->{'err_parse'} ||= sub { |
|
838
|
0
|
|
|
0
|
|
|
my $self = shift; |
|
839
|
0
|
|
|
|
|
|
my ( $cmd, $err, $errstr, $sth ) = @_; |
|
840
|
0
|
|
0
|
|
|
|
$err ||= $DBI::err; |
|
841
|
0
|
|
0
|
|
|
|
$errstr ||= $DBI::errstr; |
|
842
|
0
|
0
|
|
|
|
|
my $state = $self->{'dbh'}->state if $self->{'dbh'}; |
|
843
|
0
|
|
|
|
|
|
my $errtype = $self->error_type( $err, $errstr ); |
|
844
|
0
|
0
|
0
|
|
|
|
$errtype ||= 'connection' unless $self->{'dbh'}; |
|
845
|
0
|
0
|
|
|
|
|
$self->{'fatal'} = 1 if $errtype eq 'fatal'; |
|
846
|
|
|
|
|
|
|
#$self->log('dev','error entry', $errtype, $err, $errstr, 'wdi=', $work{'die'}, 'di=', $self->{'die'}, 'fa=', $self->{'fatal'}); |
|
847
|
|
|
|
|
|
|
|
|
848
|
|
|
|
|
|
|
=c |
|
849
|
|
|
|
|
|
|
|
|
850
|
|
|
|
|
|
|
ok |
|
851
|
|
|
|
|
|
|
no dbi ret1 |
|
852
|
|
|
|
|
|
|
install act ret1 |
|
853
|
|
|
|
|
|
|
repair act ret1 |
|
854
|
|
|
|
|
|
|
syntax ret0 |
|
855
|
|
|
|
|
|
|
fatal ret0 |
|
856
|
|
|
|
|
|
|
ignore ret0 |
|
857
|
|
|
|
|
|
|
other ret1 n times |
|
858
|
|
|
|
|
|
|
|
|
859
|
|
|
|
|
|
|
tries total |
|
860
|
|
|
|
|
|
|
tries |
|
861
|
|
|
|
|
|
|
|
|
862
|
|
|
|
|
|
|
=cut |
|
863
|
|
|
|
|
|
|
|
|
864
|
0
|
0
|
0
|
|
|
|
$self->log( |
|
|
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
865
|
|
|
|
|
|
|
'dev', "err_parse st0 ret1 ", |
|
866
|
|
|
|
|
|
|
'wdi=', $work{'die'}, 'di=', $self->{'die'}, 'fa=', $self->{'fatal'}, 'er=', |
|
867
|
|
|
|
|
|
|
( $self->{'errors'} >= $self->{'error_tries'} ), |
|
868
|
|
|
|
|
|
|
$self->{'errors'}, $self->{'error_tries'}, |
|
869
|
|
|
|
|
|
|
$errtype, $state |
|
870
|
|
|
|
|
|
|
), |
|
871
|
|
|
|
|
|
|
CORE::sleep(1), return $self->err(1) |
|
872
|
|
|
|
|
|
|
if $work{'die'} |
|
873
|
|
|
|
|
|
|
or $self->{'die'} |
|
874
|
|
|
|
|
|
|
or $self->{'fatal'} |
|
875
|
|
|
|
|
|
|
or ( $self->{'error_tries'} and $self->{'errors'} > $self->{'error_tries'} ) |
|
876
|
|
|
|
|
|
|
or ( $self->{'error_chain_tries'} and $self->{'errors_chain'} > $self->{'error_chain_tries'} ); |
|
877
|
0
|
0
|
0
|
|
|
|
$self->log( 'err', 'err_parse: IMPOSIBLE! !$err and !$self->{sth}' ), $self->err('sth'), return 0 |
|
|
|
|
0
|
|
|
|
|
|
878
|
|
|
|
|
|
|
if $sth and ( !$err and !$self->{'sth'} ); |
|
879
|
0
|
0
|
0
|
|
|
|
$self->{'errors_chain'} = 0, return $self->err(0) if !$err and $self->{'dbh'}; |
|
880
|
0
|
|
|
|
|
|
++$self->{'errors_chain'}; |
|
881
|
0
|
|
|
|
|
|
++$self->{'errors'}; |
|
882
|
0
|
|
|
|
|
|
$self->log( 'err', |
|
883
|
|
|
|
|
|
|
"SQL: error[$err,$errstr,$errtype,$state] on executing {$$cmd} [sleep:$self->{'error_sleep'}] dbh=[$self->{'dbh'}]" ); |
|
884
|
0
|
|
|
|
|
|
$self->log( 'dev', "err_parse st3 ret0 fatal=$errtype" ), $self->err($errtype), return (0) |
|
885
|
0
|
0
|
0
|
|
|
|
if $errtype and grep { $errtype eq $_ } qw(fatal syntax ignore); |
|
886
|
0
|
|
|
|
|
|
$self->log( 'dev', "err_parse sleep($self->{'error_sleep'}), ret1 ", ); |
|
887
|
0
|
0
|
|
|
|
|
$self->sleep( $self->{'error_sleep'}, 'sql_parse' ) if $self->{'error_sleep'}; |
|
888
|
0
|
|
|
|
|
|
$self->log( 'dev', "err_parse st3 ret1 fatal=$errtype" ), return $self->err($errtype) |
|
889
|
0
|
0
|
0
|
|
|
|
if $errtype and grep { $errtype eq $_ } qw(retry); |
|
890
|
|
|
|
|
|
|
|
|
891
|
0
|
0
|
0
|
|
|
|
if ( $errtype eq 'install_db' and $self->{'auto_install_db'}-- > 0 ) { |
|
892
|
0
|
|
|
|
|
|
$self->log( 'info', "SQL: trying automatic install db" ); |
|
893
|
0
|
|
|
|
|
|
$self->create_databases(@_); |
|
894
|
0
|
|
|
|
|
|
return $self->err($errtype); |
|
895
|
|
|
|
|
|
|
} |
|
896
|
0
|
0
|
|
|
|
|
$self->log( 'info', "SQL: trying reconnect[$self->{'connected'}]" ), $self->reconnect(), return $self->err('dbh') |
|
897
|
|
|
|
|
|
|
if !$self->{'dbh'}; |
|
898
|
0
|
0
|
0
|
|
|
|
if ( $errtype eq 'install' or $errtype eq 'upgrade' ) { |
|
899
|
0
|
0
|
|
|
|
|
if ( $self->{'auto_install'}-- > 0 ) { |
|
900
|
0
|
|
|
|
|
|
$self->log( 'dev', "SQL:install err " ); |
|
901
|
0
|
|
|
|
|
|
$self->log( 'info', "SQL: trying automatic install" ); |
|
902
|
0
|
|
|
|
|
|
$self->$errtype(); |
|
903
|
0
|
|
|
|
|
|
return $self->err($errtype); |
|
904
|
|
|
|
|
|
|
} else { |
|
905
|
0
|
|
|
|
|
|
$self->log( 'dev', "SQL:NOinstall err " ); |
|
906
|
0
|
|
|
|
|
|
$self->err($errtype); |
|
907
|
0
|
|
|
|
|
|
return (0); |
|
908
|
|
|
|
|
|
|
} |
|
909
|
|
|
|
|
|
|
} |
|
910
|
0
|
0
|
|
|
|
|
$self->log( 'err', "SQL: connection error, trying reconnect and retry last query" ), $self->dropconnect(), |
|
911
|
|
|
|
|
|
|
$self->reconnect(), return $self->err($errtype) |
|
912
|
|
|
|
|
|
|
if $errtype eq 'connection'; |
|
913
|
0
|
0
|
0
|
|
|
|
if ( $self->{'auto_repair'} and $errtype eq 'repair' ) { |
|
914
|
0
|
|
|
|
|
|
my ($repair) = $errstr =~ /'(?:.*[\\\/])*(\w+)(?:\.my\w)?'/i; |
|
915
|
0
|
0
|
|
|
|
|
$repair = $self->{'current_table'} unless %{ $self->{'table'}{$repair} || {} }; |
|
|
0
|
0
|
|
|
|
|
|
|
916
|
0
|
0
|
|
|
|
|
if ( $self->{'auto_repairs'}{$repair} < $self->{'auto_repairs_max'} ) { |
|
917
|
0
|
|
|
|
|
|
my $sl = int( rand( $self->{'auto_repair'} + 1 ) ); |
|
918
|
0
|
|
|
|
|
|
$self->log( 'info', 'pre repair sleeping', $sl ); |
|
919
|
0
|
|
|
|
|
|
$self->sleep($sl); |
|
920
|
0
|
0
|
0
|
|
|
|
if ( $sl == 0 or $self->{'force_repair'} ) { |
|
921
|
0
|
0
|
0
|
|
|
|
$self->log( 'info', 'denied repair', $repair ), return $self->err(1) |
|
|
|
|
0
|
|
|
|
|
|
922
|
|
|
|
|
|
|
if $self->{'auto_repair_selected'} |
|
923
|
|
|
|
|
|
|
and ( !$repair or $self->{'auto_repair_selected'} and $self->{'table_param'}{$repair}{'no_auto_repair'} ); |
|
924
|
0
|
|
|
|
|
|
++$self->{'auto_repairs'}{$repair}; |
|
925
|
0
|
|
|
|
|
|
$self->log( 'info', "SQL: trying automatic repair", $repair ); |
|
926
|
0
|
|
|
|
|
|
$self->repair($repair); |
|
927
|
0
|
|
|
|
|
|
$self->{'rep_ext'} = $self->{'rep_frm'} = 1; |
|
928
|
0
|
|
|
|
|
|
$self->{'rep_quick'} = 0; |
|
929
|
0
|
|
|
|
|
|
return $self->err($errtype); |
|
930
|
|
|
|
|
|
|
} |
|
931
|
|
|
|
|
|
|
} |
|
932
|
|
|
|
|
|
|
} |
|
933
|
0
|
0
|
|
|
|
|
$self->log( 'dev', "err_parse st2 ret1 no dbh", $err, $errstr ), return $self->err('dbh') if !$self->{'dbh'}; |
|
934
|
0
|
|
|
|
|
|
$self->log( 'dev', "err_parse unknown error ret($self->{'err_retry_unknown'}), end: [$err], [$errstr], [$errtype]" ); |
|
935
|
0
|
|
|
|
|
|
return $self->err( $self->{'err_retry_unknown'} ); |
|
936
|
0
|
|
0
|
|
|
|
}; |
|
937
|
|
|
|
|
|
|
$self->{'install'} ||= sub { |
|
938
|
0
|
|
|
0
|
|
|
my $self = shift; |
|
939
|
0
|
|
|
|
|
|
return $self->create_databases(@_) + $self->create_tables(); |
|
940
|
0
|
|
0
|
|
|
|
}; |
|
941
|
|
|
|
|
|
|
$self->{'create_database'} ||= sub { |
|
942
|
0
|
|
|
0
|
|
|
my $self = shift; |
|
943
|
0
|
|
|
|
|
|
my $ret; |
|
944
|
0
|
|
|
|
|
|
local $_; |
|
945
|
0
|
0
|
|
|
|
|
local @_ = ( $self->{'database'} ) unless @_; |
|
946
|
0
|
0
|
|
|
|
|
$self->drh_init() if $self->{'use_drh'}; |
|
947
|
0
|
|
|
|
|
|
for my $db (@_) { |
|
948
|
0
|
0
|
|
|
|
|
if ( $self->{'use_drh'} ) { |
|
|
|
0
|
|
|
|
|
|
|
949
|
0
|
|
|
|
|
|
$ret += $_ = $self->{'drh'}->func( 'createdb', $db, $self->{'host'}, $self->{'user'}, $self->{'pass'}, 'admin' ); |
|
950
|
|
|
|
|
|
|
} elsif ( $self->{'driver'} =~ /pg/i ) { |
|
951
|
|
|
|
|
|
|
{ |
|
952
|
0
|
|
|
|
|
|
my $db = $self->{'dbname'}; |
|
|
0
|
|
|
|
|
|
|
|
953
|
0
|
|
|
|
|
|
local $self->{'dbname'} = 'postgres'; |
|
954
|
0
|
|
|
|
|
|
local $self->{'database'} = undef; |
|
955
|
0
|
|
|
|
|
|
local $self->{'in_connect'} = undef; |
|
956
|
0
|
|
|
|
|
|
$self->do("CREATE DATABASE $rq$db$rq WITH ENCODING $vq$self->{'cp'}$vq"); |
|
957
|
|
|
|
|
|
|
} |
|
958
|
0
|
|
|
|
|
|
$self->reconnect(); |
|
959
|
|
|
|
|
|
|
} |
|
960
|
0
|
|
|
|
|
|
$self->log( 'info', 'install database ', $db, '=', $ret ); |
|
961
|
|
|
|
|
|
|
} |
|
962
|
0
|
|
|
|
|
|
return $ret; |
|
963
|
0
|
|
0
|
|
|
|
}; |
|
964
|
|
|
|
|
|
|
$self->{'create_databases'} ||= sub { #http://dev.mysql.com/doc/refman/5.1/en/create-table.html |
|
965
|
0
|
|
|
0
|
|
|
my $self = shift; |
|
966
|
0
|
|
|
|
|
|
return $self->create_database( $self->{'database'} ); |
|
967
|
0
|
|
0
|
|
|
|
}; |
|
968
|
|
|
|
|
|
|
$self->{'create_tables'} ||= sub { #http://dev.mysql.com/doc/refman/5.1/en/create-table.html |
|
969
|
0
|
|
|
0
|
|
|
my $self = shift; |
|
970
|
0
|
0
|
|
|
|
|
my (%table) = %{ $self->{'table'} or {} }; |
|
|
0
|
|
|
|
|
|
|
|
971
|
0
|
|
|
|
|
|
my @ret; |
|
972
|
0
|
|
|
|
|
|
for my $tab ( sort keys %table ) { |
|
973
|
0
|
|
|
|
|
|
$self->log( 'dev', 'creating table', $tab ); |
|
974
|
0
|
|
|
|
|
|
push( @ret, $self->{'create_table'}->( $self, $tab, $table{$tab} ) ); |
|
975
|
0
|
0
|
|
|
|
|
push( @ret, $self->{'create_index'}->( $self, $tab, $table{$tab} ) ) unless $self->{'index in create table'}; |
|
976
|
|
|
|
|
|
|
} |
|
977
|
0
|
|
|
|
|
|
return @ret; |
|
978
|
0
|
|
0
|
|
|
|
}; |
|
979
|
|
|
|
|
|
|
$self->{'create_table'} ||= sub { #http://dev.mysql.com/doc/refman/5.1/en/create-table.html |
|
980
|
0
|
|
|
0
|
|
|
my $self = shift; |
|
981
|
0
|
|
|
|
|
|
my ( $tab, $table ) = @_; |
|
982
|
0
|
|
|
|
|
|
my ( @subq, @ret ); |
|
983
|
0
|
0
|
|
|
|
|
return undef if $tab =~ /^\W/; |
|
984
|
0
|
|
|
|
|
|
my ( @primary, %unique, %fulltext, @do ); |
|
985
|
0
|
|
|
|
|
|
for my $row ( sort { $table->{$b}{'order'} <=> $table->{$a}{'order'} } keys %$table ) { |
|
|
0
|
|
|
|
|
|
|
|
986
|
0
|
0
|
|
|
|
|
push( @primary, $rq . $row . $rq ) if $table->{$row}{'primary'} |
|
987
|
|
|
|
|
|
|
#!and $self->{'driver'} ne 'sqlite' |
|
988
|
|
|
|
|
|
|
; |
|
989
|
0
|
0
|
|
|
|
|
push( @{ $fulltext{ $table->{$row}{'fulltext'} } }, $rq . $row . $rq ) if $table->{$row}{'fulltext'}; |
|
|
0
|
|
|
|
|
|
|
|
990
|
0
|
0
|
0
|
|
|
|
push( @{ $unique{ $table->{$row}{'unique'} } }, $rq . $row . $rq ) |
|
|
0
|
|
|
|
|
|
|
|
991
|
|
|
|
|
|
|
if $table->{$row}{'unique'} and $table->{$row}{'unique'} =~ /\D/; |
|
992
|
|
|
|
|
|
|
} |
|
993
|
0
|
0
|
0
|
|
|
|
if ( $self->{'driver'} =~ /pg/i and $self->{'use_fulltext'} ) { |
|
994
|
|
|
|
|
|
|
#$self->log('dev', 'ftdev',$tab,Dumper(\%fulltext), |
|
995
|
0
|
0
|
|
|
|
|
1 || $self->{'fulltext_trigger'} |
|
996
|
|
|
|
|
|
|
? push( |
|
997
|
|
|
|
|
|
|
@do, |
|
998
|
|
|
|
|
|
|
"DROP TRIGGER $self->{'IF EXISTS'} ${tab}_update_$_ ON $tab", |
|
999
|
|
|
|
|
|
|
$self->{'old_fulltext'} |
|
1000
|
|
|
|
|
|
|
? ( "CREATE TRIGGER ${tab}_update_$_ BEFORE UPDATE OR INSERT ON $tab FOR EACH ROW EXECUTE PROCEDURE tsearch2($rq$_$rq, " |
|
1001
|
0
|
0
|
|
|
|
|
. ( join( ', ', @{ $fulltext{$_} || [] } ) ) |
|
1002
|
|
|
|
|
|
|
. ")" ) |
|
1003
|
|
|
|
|
|
|
: ( |
|
1004
|
|
|
|
|
|
|
"CREATE TRIGGER ${tab}_update_$_ BEFORE UPDATE OR INSERT ON $tab FOR EACH ROW EXECUTE PROCEDURE tsvector_update_trigger($rq$_$rq, ${vq}$self->{'fulltext_config'}${vq}, " |
|
1005
|
|
|
|
|
|
|
. ( join( ', ', @{ $fulltext{$_} || [] } ) ) |
|
1006
|
|
|
|
|
|
|
. ")" ) |
|
1007
|
|
|
|
|
|
|
) |
|
1008
|
|
|
|
|
|
|
: (), |
|
1009
|
|
|
|
|
|
|
#), |
|
1010
|
0
|
0
|
|
|
|
|
$table->{$_} = { 'order' => -9999, 'type' => 'tsvector', } for keys %fulltext; |
|
1011
|
|
|
|
|
|
|
#push(@do,"update pg_ts_cfg set locale = 'en_US.UTF-8' where ts_name = 'default'") , |
|
1012
|
|
|
|
|
|
|
#push(@do,"select set_curcfg('default');") if @do; |
|
1013
|
|
|
|
|
|
|
} |
|
1014
|
0
|
|
|
|
|
|
for my $row ( grep { keys %{ $table->{$_} } } keys %$table ) { |
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
1015
|
0
|
0
|
|
|
|
|
$table->{$row}{'varchar'} = 1 if $table->{$row}{'type'} =~ /^varchar$/i; # |
|
1016
|
|
|
|
|
|
|
} |
|
1017
|
|
|
|
|
|
|
#$self->log('dev', Dumper $table); |
|
1018
|
0
|
|
|
|
|
|
for my $row ( sort { $table->{$b}{'order'} <=> $table->{$a}{'order'} } grep { keys %{ $table->{$_} } } keys %$table ) { |
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
1019
|
0
|
0
|
|
|
|
|
next if $row =~ /^\W/; |
|
1020
|
0
|
|
|
|
|
|
$table->{$row}{'length'} = psmisc::min( $self->{'varchar_max'}, $table->{$row}{'length'} ); |
|
1021
|
0
|
|
|
|
|
|
my $length = $table->{$row}{'length'}; |
|
1022
|
0
|
0
|
|
|
|
|
if ( !defined $length ) { |
|
1023
|
|
|
|
|
|
|
{ |
|
1024
|
0
|
|
|
|
|
|
my ( @types, @maxs, ); |
|
|
0
|
|
|
|
|
|
|
|
1025
|
0
|
0
|
0
|
|
|
|
push @types, 'primary' if $table->{$row}{'primary'} and $table->{$row}{'type'} =~ /char/i; |
|
1026
|
0
|
0
|
|
|
|
|
push @types, 'fulltext' if $table->{$row}{'fulltext'}; |
|
1027
|
0
|
0
|
|
|
|
|
push @types, 'unique' if $table->{$row}{'unique'}; |
|
1028
|
0
|
0
|
|
|
|
|
push( @types, 'varchar' ) if $table->{$row}{'varchar'}; #= 1 if $table->{$row}{'type'} =~ /^varchar$/i; |
|
1029
|
0
|
0
|
|
|
|
|
last unless @types; |
|
1030
|
|
|
|
|
|
|
#$self->log( 'dev', ' ======= ', $row, ' length detect start', @types ); |
|
1031
|
0
|
|
|
|
|
|
for my $type (@types) { |
|
1032
|
0
|
|
|
|
|
|
my $max; |
|
1033
|
|
|
|
|
|
|
#$type = $types[0]; |
|
1034
|
0
|
|
|
|
|
|
$max = $self->{ $type . '_max' }; # if $type ne 'varchar'; |
|
1035
|
|
|
|
|
|
|
#$self->log('dev',"type $type start ", $row, " max=$max"); |
|
1036
|
0
|
0
|
0
|
|
|
|
$max /= 3 if $self->{'codepage'} eq 'utf-8' and $self->{'driver'} =~ /mysql/; |
|
1037
|
|
|
|
|
|
|
#$max-=2; |
|
1038
|
|
|
|
|
|
|
#$self->log('dev','lenmax:',$row, "type=$type; max=$max, ", Dumper($table)); |
|
1039
|
0
|
|
|
|
|
|
my $same; |
|
1040
|
|
|
|
|
|
|
my $nowtotal; |
|
1041
|
0
|
|
|
|
|
|
for ( |
|
1042
|
0
|
|
|
|
|
|
grep { |
|
1043
|
0
|
|
|
|
|
|
$_ |
|
1044
|
|
|
|
|
|
|
#$table->{ $_ }{$type} and $_ ne $row |
|
1045
|
|
|
|
|
|
|
#and $table->{ $_ }{$type} eq $table->{ $row }{$type} |
|
1046
|
|
|
|
|
|
|
} keys %{$table} |
|
1047
|
|
|
|
|
|
|
) |
|
1048
|
|
|
|
|
|
|
{ |
|
1049
|
0
|
0
|
0
|
|
|
|
$nowtotal += 2 if $type eq 'varchar' and $table->{$_}{'type'} =~ /^smallint$/i; |
|
1050
|
0
|
0
|
0
|
|
|
|
$nowtotal += 4 if $type eq 'varchar' and $table->{$_}{'type'} =~ /^int$/i; |
|
1051
|
0
|
0
|
0
|
|
|
|
$nowtotal += 8 if $type eq 'varchar' and $table->{$_}{'type'} =~ /^bigint$/i; |
|
1052
|
|
|
|
|
|
|
#$self->log('dev', $row, 'look', $_, $type, $table->{ $_ }{$type} , $table->{ $_ }{'length'}, $table->{ $_ }{'type'}); |
|
1053
|
0
|
0
|
|
|
|
|
next unless $table->{$_}{$type} eq $table->{$row}{$type}; |
|
1054
|
0
|
0
|
0
|
|
|
|
next if !( $table->{$_}{$type} and $_ ne $row ); |
|
1055
|
|
|
|
|
|
|
#$self->log( 'dev', $row, 'minus', $_, $table->{$_}{'length'} ), |
|
1056
|
|
|
|
|
|
|
#$max -= $table->{ $_ }{'length'}; |
|
1057
|
0
|
|
|
|
|
|
$nowtotal += $table->{$_}{'length'}; |
|
1058
|
0
|
0
|
|
|
|
|
++$same, |
|
1059
|
|
|
|
|
|
|
#$self->log('dev', $row, 'same', $_, $same), |
|
1060
|
|
|
|
|
|
|
if !( $table->{$_}{'length'} ); |
|
1061
|
|
|
|
|
|
|
} |
|
1062
|
0
|
|
|
|
|
|
$max -= $nowtotal; |
|
1063
|
0
|
|
|
|
|
|
my $want = $max / ( $same + 1 ); |
|
1064
|
|
|
|
|
|
|
#$self->log('dev', $row, 'same', $same, 'tot:', $nowtotal,); |
|
1065
|
|
|
|
|
|
|
#$self->log('dev','len0:',$row, "type=$type; max=$max, same=$same totalwo=$nowtotal want=$want el=", scalar keys %$table); |
|
1066
|
0
|
|
|
|
|
|
$nowtotal = 0; |
|
1067
|
0
|
|
|
|
|
|
for ( |
|
1068
|
0
|
0
|
0
|
|
|
|
grep { |
|
|
|
|
0
|
|
|
|
|
|
1069
|
0
|
|
|
|
|
|
$table->{$_}{$type} |
|
1070
|
|
|
|
|
|
|
and $_ ne $row |
|
1071
|
|
|
|
|
|
|
and $table->{$_}{$type} eq $table->{$row}{$type} |
|
1072
|
|
|
|
|
|
|
and !$table->{$_}{'length'} |
|
1073
|
|
|
|
|
|
|
} keys %{$table} |
|
1074
|
|
|
|
|
|
|
) |
|
1075
|
|
|
|
|
|
|
{ |
|
1076
|
0
|
0
|
0
|
|
|
|
--$same, |
|
1077
|
|
|
|
|
|
|
#$max += $want - $table->{ $_ }{'length_max'} , |
|
1078
|
|
|
|
|
|
|
$max -= $table->{$_}{'length_max'}, $nowtotal += $table->{$_}{'length_max'}, |
|
1079
|
|
|
|
|
|
|
#$self->log('dev','maxlen:',$row, "look=$_ type=$type; max=$max, same=$same totalwo=$nowtotal want=$want lenmax=$table->{$_}{'length_max'} ret=",$want - $table->{ $_ }{'length_max'}), |
|
1080
|
|
|
|
|
|
|
if $table->{$_}{'length_max'} and $table->{$_}{'length_max'} < $want; |
|
1081
|
|
|
|
|
|
|
} |
|
1082
|
|
|
|
|
|
|
#|| $table->{ $_ }{'length_max'} |
|
1083
|
|
|
|
|
|
|
#$self->log( 'dev', $row, 'same', $same, 'tot:', $nowtotal ); |
|
1084
|
|
|
|
|
|
|
#$self->log('dev','len1:',$row, "type=$type; max=$max, "); |
|
1085
|
|
|
|
|
|
|
#$self->log('dev','lenpresame',$row, "type=$type; max=$max, same=$same totalwo=$nowtotal el=", scalar keys %$table); |
|
1086
|
0
|
0
|
|
|
|
|
$max /= $same + 1 if $same; |
|
1087
|
0
|
|
|
|
|
|
$max = int($max); |
|
1088
|
|
|
|
|
|
|
#$self->log('dev','tot:',$row, $nowtotal+(($same+1) * $max)); |
|
1089
|
|
|
|
|
|
|
#$self->log('dev','len:',$row, "type=$type; max=$max, same=$same totalwo=$nowtotal el=", scalar keys %$table); |
|
1090
|
|
|
|
|
|
|
#$max /= ( scalar @primary or 1 ) if $table->{$row}{'primary'} and $table->{$row}{'primary'}; |
|
1091
|
|
|
|
|
|
|
#$length /= ( scalar keys(%unique) + 1 ) if $table->{$row}{'unique'} and $table->{$row}{'unique'} =~ /\D/; |
|
1092
|
0
|
|
|
|
|
|
push @maxs, $max; |
|
1093
|
|
|
|
|
|
|
} |
|
1094
|
0
|
0
|
|
|
|
|
push @maxs, $table->{$row}{'length_max'} if $table->{$row}{'length_max'}; |
|
1095
|
0
|
0
|
|
|
|
|
push @maxs, $self->{'varchar_max'} if $table->{$row}{'type'} =~ /^varchar$/i; |
|
1096
|
|
|
|
|
|
|
#push @maxs, 1000 / 3 |
|
1097
|
0
|
0
|
0
|
|
|
|
push @maxs, $self->{'key_length'} / 3 |
|
|
|
|
0
|
|
|
|
|
|
1098
|
|
|
|
|
|
|
if $table->{$row}{'type'} =~ /^varchar$/i |
|
1099
|
|
|
|
|
|
|
and $table->{$row}{'primary'} |
|
1100
|
|
|
|
|
|
|
and $self->{'codepage'} eq 'utf-8'; |
|
1101
|
|
|
|
|
|
|
#$self->log( 'dev', $row, "key=$self->{'key_length'}", 'maxs:', @maxs , Dumper $table->{$row}); |
|
1102
|
|
|
|
|
|
|
#print "mx:",@maxs; |
|
1103
|
0
|
|
|
|
|
|
$length = psmisc::min( grep { $_ > 0 } @maxs ); |
|
|
0
|
|
|
|
|
|
|
|
1104
|
|
|
|
|
|
|
#$table->{$row}{'length'} ||= $length if $table->{$row}{'type'} eq 'varchar'; |
|
1105
|
0
|
|
0
|
|
|
|
$table->{$row}{'length'} ||= $length; |
|
1106
|
|
|
|
|
|
|
|
|
1107
|
|
|
|
|
|
|
=z |
|
1108
|
|
|
|
|
|
|
$length ||= $self->{'primary_max'} if $table->{$row}{'primary'} and $table->{$row}{'type'} =~ /char/i; |
|
1109
|
|
|
|
|
|
|
$length ||= $self->{'fulltext_max'} if $table->{$row}{'fulltext'}; |
|
1110
|
|
|
|
|
|
|
$length ||= $self->{'unique_max'} if $table->{$row}{'unique'}; |
|
1111
|
|
|
|
|
|
|
$length ||= $self->{'varchar_max'} if $table->{$row}{'type'} =~ /^varchar$/i; |
|
1112
|
|
|
|
|
|
|
$self->log('dev', 'crelenbef',$row, $length, 'prim=', $table->{$row}{'primary'}); |
|
1113
|
|
|
|
|
|
|
my $maxl = $self->{'row_max'} / scalar keys %$table; #todo better counting |
|
1114
|
|
|
|
|
|
|
#my $maxl = $length / scalar keys %$table; #todo better counting |
|
1115
|
|
|
|
|
|
|
$self->log('dev', 'maxl',$row, $maxl); |
|
1116
|
|
|
|
|
|
|
$length = $maxl if $length > $maxl; |
|
1117
|
|
|
|
|
|
|
$length /= 3 if $self->{'codepage'} eq 'utf-8' and $self->{'driver'} =~ /mysql/; |
|
1118
|
|
|
|
|
|
|
#$self->log('dev', 'crelen',$row, $length, scalar keys(%unique) +1); |
|
1119
|
|
|
|
|
|
|
#$self->log('dev', 'crelen',$row, $length, scalar @primary ); |
|
1120
|
|
|
|
|
|
|
$length /= ( scalar @primary or 1 ) if $table->{$row}{'primary'} and $table->{$row}{'primary'}; |
|
1121
|
|
|
|
|
|
|
$length /= ( scalar keys(%unique) + 1 ) if $table->{$row}{'unique'} and $table->{$row}{'unique'} =~ /\D/; |
|
1122
|
|
|
|
|
|
|
#$length=int($length/(4)); |
|
1123
|
|
|
|
|
|
|
$self->log('dev', 'crelenaft',$row, $length); |
|
1124
|
|
|
|
|
|
|
=cut |
|
1125
|
|
|
|
|
|
|
|
|
1126
|
0
|
|
|
|
|
|
$length = int($length); |
|
1127
|
|
|
|
|
|
|
} |
|
1128
|
|
|
|
|
|
|
} |
|
1129
|
|
|
|
|
|
|
#$self->log('dev', "$row NN= $table->{$row}{'not null'}"); |
|
1130
|
|
|
|
|
|
|
push( |
|
1131
|
0
|
0
|
0
|
|
|
|
@subq, |
|
|
|
0
|
0
|
|
|
|
|
|
|
|
0
|
0
|
|
|
|
|
|
|
|
0
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
1132
|
|
|
|
|
|
|
$rq |
|
1133
|
|
|
|
|
|
|
. $row |
|
1134
|
|
|
|
|
|
|
. $rq |
|
1135
|
|
|
|
|
|
|
. " $table->{$row}{'type'} " |
|
1136
|
|
|
|
|
|
|
#. ( $table->{$row}{'length'} ? "($table->{$row}{'length'}) " : '' ) |
|
1137
|
|
|
|
|
|
|
. ( $length ? "($length) " : '' ) |
|
1138
|
|
|
|
|
|
|
. ( ( $table->{$row}{'unsigned'} and $self->{'UNSIGNED'} ) ? ' ' . $self->{'UNSIGNED'} : '' ) |
|
1139
|
|
|
|
|
|
|
. ( ( |
|
1140
|
|
|
|
|
|
|
#!S$self->{'driver'} ne 'sqlite' or |
|
1141
|
|
|
|
|
|
|
!$table->{$row}{'auto_increment'} |
|
1142
|
|
|
|
|
|
|
) |
|
1143
|
|
|
|
|
|
|
#? ( ( $table->{$row}{'null'} ) ? ' NULL ' : ' NOT NULL ' ) |
|
1144
|
|
|
|
|
|
|
#? ( ( $table->{$row}{'null'} ) ? '' : ' NOT NULL ' ) |
|
1145
|
|
|
|
|
|
|
? ( ( $table->{$row}{'not null'} ) ? ' NOT NULL ' : '' ) |
|
1146
|
|
|
|
|
|
|
: '' |
|
1147
|
|
|
|
|
|
|
) |
|
1148
|
|
|
|
|
|
|
. ( |
|
1149
|
|
|
|
|
|
|
( defined( $table->{$row}{'default'} ) and !$table->{$row}{'auto_increment'} ) |
|
1150
|
|
|
|
|
|
|
? " DEFAULT " . ( $table->{$row}{'default'} eq 'NULL' ? 'NULL' : "$vq$table->{$row}{'default'}$vq" ) . " " |
|
1151
|
|
|
|
|
|
|
: '' |
|
1152
|
|
|
|
|
|
|
) |
|
1153
|
|
|
|
|
|
|
. ( ( $table->{$row}{'unique'} and $table->{$row}{'unique'} =~ /^\d+$/ ) ? ' UNIQUE ' : '' ) |
|
1154
|
|
|
|
|
|
|
#.( ( $self->{'driver'} eq '!Ssqlite' and $table->{$row}{'primary'} ) ? ' PRIMARY KEY ' : '' ) |
|
1155
|
|
|
|
|
|
|
. ( ( |
|
1156
|
|
|
|
|
|
|
$table->{$row}{'auto_increment'} and ( |
|
1157
|
|
|
|
|
|
|
#TEST S! $self->{'driver'} ne '!Ssqlite' or |
|
1158
|
|
|
|
|
|
|
#$table->{$row}{'primary'} #? |
|
1159
|
|
|
|
|
|
|
1 |
|
1160
|
|
|
|
|
|
|
) |
|
1161
|
|
|
|
|
|
|
) |
|
1162
|
|
|
|
|
|
|
? ' ' |
|
1163
|
|
|
|
|
|
|
. $self->{'AUTO_INCREMENT'} . ' ' |
|
1164
|
|
|
|
|
|
|
: '' |
|
1165
|
|
|
|
|
|
|
) |
|
1166
|
|
|
|
|
|
|
. "$table->{$row}{'param'}" |
|
1167
|
|
|
|
|
|
|
); |
|
1168
|
|
|
|
|
|
|
} |
|
1169
|
|
|
|
|
|
|
#iwh |
|
1170
|
0
|
0
|
|
|
|
|
push( @subq, "PRIMARY KEY (" . join( ',', @primary ) . ")" ) if @primary; |
|
1171
|
0
|
|
|
|
|
|
for my $row ( sort { $table->{$b}{'order'} <=> $table->{$a}{'order'} } keys %$table ) { |
|
|
0
|
|
|
|
|
|
|
|
1172
|
0
|
0
|
0
|
|
|
|
push( |
|
|
|
0
|
0
|
|
|
|
|
|
1173
|
|
|
|
|
|
|
@subq, |
|
1174
|
|
|
|
|
|
|
"INDEX " |
|
1175
|
|
|
|
|
|
|
. $rq |
|
1176
|
|
|
|
|
|
|
. $row |
|
1177
|
|
|
|
|
|
|
. $self->{'index_postfix'} |
|
1178
|
|
|
|
|
|
|
. $rq . " (" |
|
1179
|
|
|
|
|
|
|
. $rq |
|
1180
|
|
|
|
|
|
|
. $row |
|
1181
|
|
|
|
|
|
|
. $rq |
|
1182
|
|
|
|
|
|
|
. ( |
|
1183
|
|
|
|
|
|
|
( $table->{$row}{'index'} > 1 and $table->{$row}{'index'} < $table->{$row}{'length'} ) |
|
1184
|
|
|
|
|
|
|
? '(' . $table->{$row}{'index'} . ')' |
|
1185
|
|
|
|
|
|
|
: '' |
|
1186
|
|
|
|
|
|
|
) |
|
1187
|
|
|
|
|
|
|
. ")" |
|
1188
|
|
|
|
|
|
|
) if $table->{$row}{'index'} and $self->{'index in create table'}; |
|
1189
|
|
|
|
|
|
|
|
|
1190
|
|
|
|
|
|
|
=c |
|
1191
|
|
|
|
|
|
|
push( |
|
1192
|
|
|
|
|
|
|
@subq, |
|
1193
|
|
|
|
|
|
|
"INDEX UNIQUE" |
|
1194
|
|
|
|
|
|
|
. $rq |
|
1195
|
|
|
|
|
|
|
. $row |
|
1196
|
|
|
|
|
|
|
. $self->{'index_postfix'} . 'u' |
|
1197
|
|
|
|
|
|
|
. $rq . " (" |
|
1198
|
|
|
|
|
|
|
. $rq |
|
1199
|
|
|
|
|
|
|
. $row |
|
1200
|
|
|
|
|
|
|
. $rq |
|
1201
|
|
|
|
|
|
|
. ")" |
|
1202
|
|
|
|
|
|
|
) |
|
1203
|
|
|
|
|
|
|
if $table->{$row}{'unique'} |
|
1204
|
|
|
|
|
|
|
and $self->{'index in create table'}; |
|
1205
|
|
|
|
|
|
|
=cut |
|
1206
|
|
|
|
|
|
|
|
|
1207
|
0
|
0
|
|
|
|
|
push( @primary, $rq . $row . $rq ) if $table->{$row}{'primary'}; |
|
1208
|
|
|
|
|
|
|
} |
|
1209
|
0
|
|
|
|
|
|
push( @subq, "UNIQUE " . ( $self->{'unique name'} ? $rq . $_ . $rq : '' ) . " (" . join( ',', @{ $unique{$_} } ) . ")" ) |
|
|
0
|
|
|
|
|
|
|
|
1210
|
0
|
0
|
|
|
|
|
for grep @{ $unique{$_} }, keys %unique; |
|
1211
|
0
|
0
|
|
|
|
|
if ( $self->{'index in create table'} ) { |
|
1212
|
0
|
|
|
|
|
|
push( @subq, "FULLTEXT $rq$_$rq (" . join( ',', @{ $fulltext{$_} } ) . ")" ) for grep @{ $fulltext{$_} }, keys %fulltext; |
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
1213
|
|
|
|
|
|
|
#push( @subq, "UNIQUE $rq$_$rq (" . join( ',', @{ $unique{$_} } ) . ")" ) for grep @{ $unique{$_} }, keys %unique; |
|
1214
|
|
|
|
|
|
|
} |
|
1215
|
|
|
|
|
|
|
#push( |
|
1216
|
|
|
|
|
|
|
#$self->log('dev', "[cp:$self->{'cp'}; dcs:$self->{'DEFAULT CHARACTER SET'}]"); |
|
1217
|
|
|
|
|
|
|
#@ret, |
|
1218
|
|
|
|
|
|
|
return |
|
1219
|
|
|
|
|
|
|
#print |
|
1220
|
0
|
|
|
|
|
|
map { $self->do($_) } |
|
|
0
|
|
|
|
|
|
|
|
1221
|
0
|
|
|
|
|
|
grep { $_ } |
|
1222
|
|
|
|
|
|
|
( !@subq |
|
1223
|
|
|
|
|
|
|
? () |
|
1224
|
|
|
|
|
|
|
: 'CREATE TABLE ' |
|
1225
|
|
|
|
|
|
|
. $self->{'IF NOT EXISTS'} |
|
1226
|
|
|
|
|
|
|
. " $tq$self->{'table_prefix'}$tab$tq (" |
|
1227
|
|
|
|
|
|
|
. join( ",", @subq ) |
|
1228
|
0
|
0
|
0
|
|
|
|
. ( join ' ', '', grep { $_ } $self->{'table_constraint'}, $self->{'table_param'}{$tab}{'table_constraint'} ) . ") " |
|
|
|
0
|
|
|
|
|
|
|
1229
|
|
|
|
|
|
|
. $self->{'table options'} . ' ' |
|
1230
|
|
|
|
|
|
|
. $self->{'table_param'}{$tab}{'table options'} |
|
1231
|
|
|
|
|
|
|
. ( $self->{'cp'} && $self->{'DEFAULT CHARACTER SET'} ? " $self->{'DEFAULT CHARACTER SET'} $vq$self->{'cp'}$vq " : '' ) |
|
1232
|
|
|
|
|
|
|
. ';' ), @do; |
|
1233
|
|
|
|
|
|
|
#return undef; |
|
1234
|
0
|
|
0
|
|
|
|
}; |
|
1235
|
|
|
|
|
|
|
#$self->{'do'}{'create_index'} = 1; |
|
1236
|
|
|
|
|
|
|
$self->{'create_index'} ||= sub { |
|
1237
|
|
|
|
|
|
|
#sub create_index { |
|
1238
|
0
|
|
|
0
|
|
|
my $self = shift; |
|
1239
|
0
|
|
|
|
|
|
my @ret; |
|
1240
|
0
|
|
|
|
|
|
my ( $tab, $table ) = @_; |
|
1241
|
|
|
|
|
|
|
#for my $table( @_){ |
|
1242
|
|
|
|
|
|
|
#for my $tab ( keys %$table ) { |
|
1243
|
0
|
|
|
|
|
|
my (@subq); |
|
1244
|
|
|
|
|
|
|
#next if $tab =~ /^\W/; |
|
1245
|
0
|
|
|
|
|
|
for my $row ( sort { $table->{$b}{'order'} <=> $table->{$a}{'order'} } keys %$table ) { |
|
|
0
|
|
|
|
|
|
|
|
1246
|
0
|
0
|
|
|
|
|
next if $row =~ /^\W/; |
|
1247
|
0
|
0
|
|
|
|
|
push( @ret, |
|
|
|
0
|
|
|
|
|
|
|
1248
|
|
|
|
|
|
|
'CREATE INDEX ' |
|
1249
|
|
|
|
|
|
|
. $self->{'index_IF NOT EXISTS'} . ' ' |
|
1250
|
|
|
|
|
|
|
. $rq |
|
1251
|
|
|
|
|
|
|
. $row |
|
1252
|
|
|
|
|
|
|
. ( $self->{'index_name_table'} ? '_' . $tab : '' ) |
|
1253
|
|
|
|
|
|
|
. $self->{'index_postfix'} |
|
1254
|
|
|
|
|
|
|
. $rq . ' ON ' |
|
1255
|
|
|
|
|
|
|
. " $tq$self->{'table_prefix'}$tab$tq ( $rq$row$rq )" ) |
|
1256
|
|
|
|
|
|
|
if $table->{$row}{'index'}; |
|
1257
|
|
|
|
|
|
|
} |
|
1258
|
|
|
|
|
|
|
#} |
|
1259
|
0
|
|
|
|
|
|
return $self->do(@ret); |
|
1260
|
0
|
|
0
|
|
|
|
}; |
|
1261
|
|
|
|
|
|
|
$self->{'create_indexes'} ||= sub { |
|
1262
|
|
|
|
|
|
|
#$self->log values %{ $self->{'table'}}; |
|
1263
|
0
|
|
|
0
|
|
|
$self->create_index( $_, $self->{'table'}{$_} ) for keys %{ $self->{'table'} }; |
|
|
0
|
|
|
|
|
|
|
|
1264
|
0
|
|
0
|
|
|
|
}; |
|
1265
|
|
|
|
|
|
|
#$self->{'do'}{'drop_table'} = 1; |
|
1266
|
|
|
|
|
|
|
$self->{'drop_table'} ||= sub { |
|
1267
|
|
|
|
|
|
|
#sub drop_table { |
|
1268
|
0
|
|
|
0
|
|
|
my $self = shift; |
|
1269
|
0
|
|
|
|
|
|
my @ret; |
|
1270
|
0
|
|
|
|
|
|
for my $tab (@_) { |
|
1271
|
0
|
|
|
|
|
|
my ($sql); |
|
1272
|
0
|
0
|
0
|
|
|
|
next if $tab =~ /^\W/ or $tab !~ /\w/; |
|
1273
|
0
|
|
|
|
|
|
$sql .= "DROP TABLE " . $self->{'IF EXISTS'} . " $tq$self->{'table_prefix'}$tab$tq $self->{'CASCADE'}"; |
|
1274
|
0
|
|
|
|
|
|
push( @ret, $sql ); |
|
1275
|
|
|
|
|
|
|
} |
|
1276
|
0
|
|
|
|
|
|
return $self->do(@ret); |
|
1277
|
0
|
|
0
|
|
|
|
}; |
|
1278
|
|
|
|
|
|
|
$self->{'drop_database'} ||= sub { |
|
1279
|
|
|
|
|
|
|
#sub drop_table { |
|
1280
|
0
|
|
|
0
|
|
|
my $self = shift; |
|
1281
|
0
|
|
|
|
|
|
my @ret; |
|
1282
|
0
|
0
|
|
|
|
|
@_ = $self->{'database'} if !@_; |
|
1283
|
0
|
0
|
0
|
|
|
|
my $rec = 1 if $self->{'driver'} =~ /pg/i and grep { $self->{'database'} eq $_ } @_; |
|
|
0
|
|
|
|
|
|
|
|
1284
|
0
|
0
|
|
|
|
|
if ($rec) { |
|
1285
|
|
|
|
|
|
|
#$self->log('dev','tryreconnect', $self->{'connected'}); |
|
1286
|
0
|
|
|
|
|
|
local $self->{'dbname'} = undef; |
|
1287
|
0
|
|
|
|
|
|
local $self->{'database'} = undef; |
|
1288
|
0
|
0
|
|
|
|
|
$self->{'dbname'} = $self->{'database'} = 'postgres' if $self->{'driver'} =~ /pg/i; #TODO MYSQL |
|
1289
|
|
|
|
|
|
|
#$self->dropconnect(); |
|
1290
|
0
|
|
|
|
|
|
$self->reconnect(); |
|
1291
|
|
|
|
|
|
|
} |
|
1292
|
0
|
|
|
|
|
|
for my $tab (@_) { |
|
1293
|
0
|
|
|
|
|
|
my ($sql); |
|
1294
|
0
|
0
|
0
|
|
|
|
next if $tab =~ /^\W/ or $tab !~ /\w/; |
|
1295
|
0
|
|
|
|
|
|
$sql .= "DROP DATABASE " . $self->{'IF EXISTS'} . " $tq$self->{'table_prefix'}$tab$tq"; |
|
1296
|
0
|
|
|
|
|
|
push( @ret, $sql ); |
|
1297
|
|
|
|
|
|
|
} |
|
1298
|
0
|
|
|
|
|
|
@ret = $self->do(@ret); |
|
1299
|
0
|
0
|
|
|
|
|
if ($rec) { $self->reconnect(); } |
|
|
0
|
|
|
|
|
|
|
|
1300
|
0
|
|
|
|
|
|
return @ret; |
|
1301
|
0
|
|
0
|
|
|
|
}; |
|
1302
|
|
|
|
|
|
|
$self->{'drop_tables'} ||= sub { |
|
1303
|
0
|
|
|
0
|
|
|
my $self = shift; |
|
1304
|
0
|
0
|
|
|
|
|
@_ = keys %{ $self->{'table'} or {} } if !@_; |
|
|
0
|
0
|
|
|
|
|
|
|
1305
|
0
|
|
|
|
|
|
return $self->drop_table(@_); |
|
1306
|
0
|
|
0
|
|
|
|
}; |
|
1307
|
|
|
|
|
|
|
#{ |
|
1308
|
|
|
|
|
|
|
#my (%buffer); |
|
1309
|
|
|
|
|
|
|
#$processor{'out'}{'array'} ||= sub { |
|
1310
|
|
|
|
|
|
|
$self->{'insert_fields'} ||= sub { |
|
1311
|
0
|
|
|
0
|
|
|
my $self = shift; |
|
1312
|
0
|
|
0
|
|
|
|
my $table = shift || $self->{'current_table'}; |
|
1313
|
0
|
|
|
|
|
|
return grep { |
|
1314
|
0
|
|
|
|
|
|
$self->{'table'}{$table}{$_}{'array_insert'} |
|
1315
|
|
|
|
|
|
|
#or !defined $self->{'table'}{$table}{$_}{'default'} |
|
1316
|
0
|
|
|
|
|
|
} keys %{ $self->{'table'}{$table} }; |
|
1317
|
0
|
|
0
|
|
|
|
}; |
|
1318
|
|
|
|
|
|
|
$self->{'insert_order'} ||= sub { |
|
1319
|
0
|
|
|
0
|
|
|
my $self = shift; |
|
1320
|
0
|
|
0
|
|
|
|
my $table = shift || $self->{'current_table'}; |
|
1321
|
0
|
|
|
|
|
|
return sort { $self->{'table'}{$table}{$b}{'order'} <=> $self->{'table'}{$table}{$a}{'order'} } $self->insert_fields($table) |
|
|
0
|
|
|
|
|
|
|
|
1322
|
|
|
|
|
|
|
#grep { $self->{'table'}{$table}{$_}{'array_insert'} or !defined $self->{'table'}{$table}{$_}{'default'} |
|
1323
|
|
|
|
|
|
|
#} keys %{ $self->{'table'}{$table} } |
|
1324
|
0
|
|
0
|
|
|
|
}; |
|
1325
|
|
|
|
|
|
|
$self->{'insert_cached'} ||= sub { |
|
1326
|
0
|
|
|
0
|
|
|
my $self = shift; |
|
1327
|
0
|
|
|
|
|
|
my $table = shift; |
|
1328
|
0
|
|
0
|
|
|
|
my $table_insert = $table || $self->{'current_table'}; |
|
1329
|
|
|
|
|
|
|
#$self->log('dev','insert_cached', $table,Dumper(\@_), 'by', ( $self->{'table_param'}{$table}{'insert_by'} or $self->{'insert_by'} ), 'bytime=', $self->{'insert_cached_time'}); |
|
1330
|
0
|
|
|
|
|
|
my @dummy; |
|
1331
|
|
|
|
|
|
|
#my ( $tq, $rq, $vq ) = sql_quotes(); |
|
1332
|
0
|
0
|
0
|
|
|
|
++$self->{'inserts'}, ++$self->{'table_updated'}{$table_insert}, push( @{ $self->{'insert_buffer'}{$table_insert} }, \@_ ) |
|
|
0
|
|
|
|
|
|
|
|
1333
|
|
|
|
|
|
|
if $table_insert and @_; |
|
1334
|
|
|
|
|
|
|
#$self->log('dev', 'cached', keys %{ $self->{'insert_buffer'} }); |
|
1335
|
0
|
0
|
|
|
|
|
for my $table ( $table ? ($table) : ( keys %{ $self->{'insert_buffer'} } ) ) { |
|
|
0
|
|
|
|
|
|
|
|
1336
|
0
|
|
0
|
|
|
|
$self->{'insert_block'}{$table} //= $self->{'table_param'}{$table}{'insert_by'} || $self->{'insert_by'}; |
|
|
|
|
0
|
|
|
|
|
|
1337
|
|
|
|
|
|
|
#unless defined $self->{'insert_block'}{$table}; |
|
1338
|
|
|
|
|
|
|
#$self->log('ict', $table,int(time() - $self->{'insert_buffer_time'}{$table})); |
|
1339
|
|
|
|
|
|
|
#$self->{'insert_buffer_time'}{$table}||=time(); |
|
1340
|
0
|
0
|
0
|
|
|
|
if ( |
|
|
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
1341
|
|
|
|
|
|
|
$self->{'insert_block'}{$table}-- <= 1 |
|
1342
|
|
|
|
|
|
|
or !scalar(@_) |
|
1343
|
|
|
|
|
|
|
#or time() - $self->{'insert_buffer_time'}{$table} > $self->{'insert_cached_time'} |
|
1344
|
|
|
|
|
|
|
or time() - ( $self->{'insert_buffer_time'}{$table} ||= time() ) > $self->{'insert_cached_time'} |
|
1345
|
|
|
|
|
|
|
) |
|
1346
|
|
|
|
|
|
|
{ |
|
1347
|
0
|
0
|
|
|
|
|
$self->{'stat'}{'time'}{'count'} += scalar @{ $self->{'insert_buffer'}{$table_insert} || [] }; |
|
|
0
|
|
|
|
|
|
|
|
1348
|
0
|
|
|
|
|
|
$self->{'insert_buffer_time'}{$table} = time(); |
|
1349
|
0
|
|
|
|
|
|
$self->{'current_table'} = $table; |
|
1350
|
|
|
|
|
|
|
#$self->log('doing insert', $table, Dumper $self->{'insert_buffer'}{$table}); |
|
1351
|
0
|
|
|
|
|
|
$self->do( |
|
1352
|
|
|
|
|
|
|
join( |
|
1353
|
|
|
|
|
|
|
'', |
|
1354
|
|
|
|
|
|
|
( $self->{'ON DUPLICATE KEY UPDATE'} ? $self->{'INSERT'} : $self->{'REPLACE'} ) |
|
1355
|
|
|
|
|
|
|
. " $self->{$self->{'insert_options'}} INTO $tq$self->{'table_prefix'}$table$tq (", |
|
1356
|
0
|
|
|
|
|
|
join( ',', map { $rq . $_ . $rq } $self->insert_order($table) ), |
|
1357
|
|
|
|
|
|
|
") VALUES\n", |
|
1358
|
|
|
|
|
|
|
join( |
|
1359
|
|
|
|
|
|
|
",\n", |
|
1360
|
|
|
|
|
|
|
map { |
|
1361
|
0
|
|
|
|
|
|
join( |
|
1362
|
|
|
|
|
|
|
'', '(', |
|
1363
|
|
|
|
|
|
|
join( |
|
1364
|
|
|
|
|
|
|
',', |
|
1365
|
|
|
|
|
|
|
#map { $self->quote( scalar cp_trans( $self->{'cp_in'}, $self->{'codepage'}, $$_ ), $self->{'value quote'} ) } |
|
1366
|
0
|
|
|
|
|
|
map { $self->quote( scalar psmisc::cp_trans( $self->{'cp_in'}, $self->{'codepage'}, $$_ ) ) } |
|
1367
|
0
|
|
|
|
|
|
@{$_}[ 0 .. scalar( $self->insert_fields($table) ) - 1 ], |
|
1368
|
|
|
|
|
|
|
@dummy = |
|
1369
|
0
|
|
|
|
|
|
( map { \$self->{'table'}{$table}{$_}{'default'} } $self->insert_order($table) ) |
|
1370
|
0
|
|
|
|
|
|
[ scalar( @{$_} ) .. scalar( $self->insert_fields($table) ) - 1 ] |
|
1371
|
|
|
|
|
|
|
), |
|
1372
|
|
|
|
|
|
|
')' |
|
1373
|
|
|
|
|
|
|
) |
|
1374
|
0
|
|
|
|
|
|
} @{ $self->{'insert_buffer'}{$table} } |
|
1375
|
|
|
|
|
|
|
), ( |
|
1376
|
|
|
|
|
|
|
!$self->{'ON DUPLICATE KEY UPDATE'} ? '' : " \n" . $self->{'ON DUPLICATE KEY UPDATE'} . ' ' . join( |
|
1377
|
|
|
|
|
|
|
',', |
|
1378
|
|
|
|
|
|
|
map { |
|
1379
|
0
|
|
|
|
|
|
$rq . $_ . $rq . '=VALUES(' . $rq . $_ . $rq . ')' |
|
1380
|
|
|
|
|
|
|
} sort { |
|
1381
|
0
|
0
|
0
|
|
|
|
$self->{'table'}{$table}{$b}{'order'} <=> $self->{'table'}{$table}{$a}{'order'} |
|
1382
|
|
|
|
|
|
|
} grep { |
|
1383
|
0
|
|
|
|
|
|
$self->{'table'}{$table}{$_}{'array_insert'} |
|
1384
|
|
|
|
|
|
|
and !$self->{'table'}{$table}{$_}{'no_insert_update'} |
|
1385
|
|
|
|
|
|
|
and !$self->{'table'}{$table}{$_}{'added'} |
|
1386
|
0
|
0
|
|
|
|
|
} keys %{ $self->{'table'}{$table} } |
|
1387
|
|
|
|
|
|
|
) |
|
1388
|
|
|
|
|
|
|
), |
|
1389
|
|
|
|
|
|
|
';' |
|
1390
|
|
|
|
|
|
|
) |
|
1391
|
|
|
|
|
|
|
), |
|
1392
|
|
|
|
|
|
|
delete $self->{'insert_buffer'}{$table} |
|
1393
|
0
|
0
|
|
|
|
|
if scalar @{ $self->{'insert_buffer'}{$table} || [] }; |
|
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
1394
|
0
|
|
0
|
|
|
|
$self->{'insert_block'}{$table} = $self->{'table_param'}{$table}{'insert_by'} || $self->{'insert_by'}; |
|
1395
|
0
|
|
|
|
|
|
$self->{'stat'}{'time'}{'time'} += time - $self->{'insert_buffer_time'}{$table}; |
|
1396
|
|
|
|
|
|
|
psmisc::schedule( |
|
1397
|
|
|
|
|
|
|
[ $self->{'stat_every'}, $self->{'stat_every'} ], |
|
1398
|
|
|
|
|
|
|
sub { |
|
1399
|
|
|
|
|
|
|
#my $per = $self->{'stat'}{'time'}{'time'}; |
|
1400
|
0
|
|
0
|
|
|
|
$self->log( |
|
|
|
|
0
|
|
|
|
|
|
1401
|
|
|
|
|
|
|
'time', |
|
1402
|
|
|
|
|
|
|
'inserts', |
|
1403
|
|
|
|
|
|
|
$self->{'stat'}{'time'}{'count'}, |
|
1404
|
|
|
|
|
|
|
'per', |
|
1405
|
|
|
|
|
|
|
psmisc::human( 'time_period', $self->{'stat'}{'time'}{'time'} ), |
|
1406
|
|
|
|
|
|
|
'at', |
|
1407
|
|
|
|
|
|
|
psmisc::human( 'float', $self->{'stat'}{'time'}{'count'} / ( $self->{'stat'}{'time'}{'time'} || 1 ) ), |
|
1408
|
|
|
|
|
|
|
'rps', |
|
1409
|
|
|
|
|
|
|
'full', |
|
1410
|
|
|
|
|
|
|
psmisc::human( 'float', $self->{'stat'}{'time'}{'count'} / ( time - $self->{'stat'}{'time'}{'full'} or 1 ) ), |
|
1411
|
|
|
|
|
|
|
'rps' |
|
1412
|
|
|
|
|
|
|
); |
|
1413
|
0
|
|
|
|
|
|
$self->{'stat'}{'time'} = { 'full' => time }; |
|
1414
|
|
|
|
|
|
|
} |
|
1415
|
0
|
0
|
|
|
|
|
) if $self->{'stat_every'}; |
|
1416
|
|
|
|
|
|
|
} |
|
1417
|
|
|
|
|
|
|
} |
|
1418
|
|
|
|
|
|
|
#$self->log('dev', 'insert:',@{ $buffer{$table} }); |
|
1419
|
0
|
|
|
|
|
|
return undef; |
|
1420
|
0
|
|
0
|
|
|
|
}; |
|
1421
|
|
|
|
|
|
|
#} |
|
1422
|
|
|
|
|
|
|
#$self->{'flush'} ||= $self->{'insert'}; |
|
1423
|
|
|
|
|
|
|
$self->{'flush_insert'} ||= sub { |
|
1424
|
0
|
|
|
0
|
|
|
my $self = shift; |
|
1425
|
0
|
|
|
|
|
|
$self->insert_cached(@_); |
|
1426
|
|
|
|
|
|
|
#pg tsearch |
|
1427
|
|
|
|
|
|
|
#push( @{ $fulltext{ $table->{$row}{'fulltext'} } }, $rq . $row . $rq ) if $table->{$row}{'fulltext'}; |
|
1428
|
0
|
|
|
|
|
|
if ( 0 and $self->{'driver'} =~ /pg/i and $self->{'use_fulltext'} ) { |
|
1429
|
|
|
|
|
|
|
for my $tablen ( grep { $_ and $self->{'table_updated'}{$_} } keys %{ $self->{'table_updated'} || {} } ) { |
|
1430
|
|
|
|
|
|
|
my $table = $self->{'table'}{$tablen}; |
|
1431
|
|
|
|
|
|
|
my (%fulltext); |
|
1432
|
|
|
|
|
|
|
for my $row ( sort { $table->{$b}{'order'} <=> $table->{$a}{'order'} } keys %$table ) { |
|
1433
|
|
|
|
|
|
|
push( @{ $fulltext{ $table->{$row}{'fulltext'} } }, $rq . $row . $rq ) if $table->{$row}{'fulltext'}; |
|
1434
|
|
|
|
|
|
|
} |
|
1435
|
|
|
|
|
|
|
my @do; |
|
1436
|
|
|
|
|
|
|
#local @_ = map {$self->rquote($_)}grep {$table->{$_}{'fulltext'}} keys %{%$table || {}} or next; |
|
1437
|
|
|
|
|
|
|
push @do, |
|
1438
|
|
|
|
|
|
|
"SELECT tsvector_update_trigger($rq$_$rq, ${vq}$self->{'fulltext_config'}${vq}, " |
|
1439
|
|
|
|
|
|
|
. ( join( ', ', @{ $fulltext{$_} || [] } ) ) |
|
1440
|
|
|
|
|
|
|
. ") FROM $tq$tablen$tq" |
|
1441
|
|
|
|
|
|
|
for keys %fulltext; |
|
1442
|
|
|
|
|
|
|
#$self->log('dev', 'ftup',$self->{'table_updated'}{$table},$table, $do); |
|
1443
|
|
|
|
|
|
|
$self->do(@do); |
|
1444
|
|
|
|
|
|
|
$self->{'table_updated'}{$tablen} = 0; |
|
1445
|
|
|
|
|
|
|
} |
|
1446
|
|
|
|
|
|
|
} |
|
1447
|
0
|
|
0
|
|
|
|
}; |
|
1448
|
|
|
|
|
|
|
$self->{'insert'} ||= sub { |
|
1449
|
0
|
|
|
0
|
|
|
my $self = shift; |
|
1450
|
0
|
|
|
|
|
|
my @ret = $self->insert_cached(@_); |
|
1451
|
0
|
0
|
|
|
|
|
$self->flush_insert( $_[0] ) if scalar @_ > 1; |
|
1452
|
0
|
|
|
|
|
|
return @ret; |
|
1453
|
0
|
|
0
|
|
|
|
}; |
|
1454
|
|
|
|
|
|
|
$self->{'update'} ||= sub { |
|
1455
|
0
|
|
|
0
|
|
|
my $self = shift; |
|
1456
|
0
|
|
0
|
|
|
|
my $table = ( shift or $self->{'current_table'} ); |
|
1457
|
|
|
|
|
|
|
#sub update { #v5 |
|
1458
|
|
|
|
|
|
|
#my $self = shift; |
|
1459
|
0
|
|
|
|
|
|
my ( $by, $values, $where, $set, $setignore, $whereignore ) = @_; |
|
1460
|
|
|
|
|
|
|
#$self->log('dev','sql_update:', $self->{database}, join ':',@_, "PREUPVAL=",%{$values} ); |
|
1461
|
|
|
|
|
|
|
#$self->log('dev','sql_update:', "[$set],[$setignore]" ); |
|
1462
|
0
|
0
|
|
|
|
|
return unless %{ $self->{'table'}{$table} or {} }; |
|
|
0
|
0
|
|
|
|
|
|
|
1463
|
0
|
|
|
|
|
|
$self->{'current_table'} = $table; |
|
1464
|
|
|
|
|
|
|
#my ( $tq, $rq, $vq ) = sql_quotes(); |
|
1465
|
|
|
|
|
|
|
#$self->log('dev','HIRUN', $table, $self->{'handler_insert'} , |
|
1466
|
|
|
|
|
|
|
#$self->log( 'filter', 'f2', $self->{'table_param'}{$table}{'filter'} ); |
|
1467
|
|
|
|
|
|
|
next |
|
1468
|
0
|
0
|
0
|
|
|
|
if ref $self->{'table_param'}{$table}{'filter'} eq 'CODE' |
|
1469
|
|
|
|
|
|
|
and $self->{'table_param'}{$table}{'filter'}->( $self, $values ); |
|
1470
|
0
|
0
|
|
|
|
|
$self->{'handler_insert'}->( $table, $values ) if ref $self->{'handler_insert'} eq 'CODE'; |
|
1471
|
0
|
|
|
|
|
|
$self->stem_insert( $table, $values ); |
|
1472
|
|
|
|
|
|
|
#$self->{'handler_insert'}->( $table, \%{$values} ) if $self->{'handler_insert'}; |
|
1473
|
0
|
|
|
|
|
|
local $self->{'handler_insert'} = undef; |
|
1474
|
0
|
|
|
|
|
|
local $self->{'stem_insert'} = sub { }; |
|
|
0
|
|
|
|
|
|
|
|
1475
|
0
|
|
|
|
|
|
local @_; |
|
1476
|
0
|
0
|
|
|
|
|
$by ||= |
|
1477
|
0
|
0
|
|
|
|
|
[ grep { $self->{'table'}{$table}{$_}{'primary'} or $self->{'table'}{$table}{$_}{'unique'} } |
|
1478
|
0
|
|
0
|
|
|
|
keys %{ $self->{'table'}{$table} || {} } ]; |
|
1479
|
0
|
|
|
|
|
|
my $bymask = '^(' . join( ')|(', @$by ) . ')$'; |
|
1480
|
0
|
0
|
|
|
|
|
my $bywhere = join( |
|
1481
|
|
|
|
|
|
|
' AND ', |
|
1482
|
|
|
|
|
|
|
map ( "$rq$_$rq=" . $self->quote( $values->{$_} ), |
|
1483
|
|
|
|
|
|
|
grep { |
|
1484
|
0
|
0
|
0
|
|
|
|
%{ $self->{'table'}{$table}{$_} || {} } |
|
|
0
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
1485
|
|
|
|
|
|
|
and ( $self->{'table'}{$table}{$_}{'primary'} or $self->{'table'}{$table}{$_}{'unique'} ) |
|
1486
|
|
|
|
|
|
|
and $self->{'table'}{$table}{$_}{'type'} ne 'serial' |
|
1487
|
|
|
|
|
|
|
and !$self->{'table'}{$table}{$_}{'auto_increment'} #todo mysql |
|
1488
|
|
|
|
|
|
|
} @$by ) |
|
1489
|
|
|
|
|
|
|
); |
|
1490
|
0
|
|
|
|
|
|
$set ||= join( |
|
1491
|
|
|
|
|
|
|
', ', ( |
|
1492
|
|
|
|
|
|
|
map { |
|
1493
|
|
|
|
|
|
|
#$self->log('dev','sql_update:', "[$_:$values->{$_}]" ); |
|
1494
|
|
|
|
|
|
|
$rq . $_ . $rq . "=" . $self->quote( |
|
1495
|
|
|
|
|
|
|
$self->cut( $values->{$_}, $self->{'table'}{$table}{$_}{'length'} ) |
|
1496
|
|
|
|
|
|
|
#$values->{$_} |
|
1497
|
|
|
|
|
|
|
) |
|
1498
|
|
|
|
|
|
|
} ( |
|
1499
|
0
|
0
|
|
|
|
|
@_ = grep( ( ( $_ !~ $bymask ) and $_ and %{ $self->{'table'}{$table}{$_} || {} } and defined( $values->{$_} ) ), |
|
1500
|
|
|
|
|
|
|
keys %$values ), ( |
|
1501
|
|
|
|
|
|
|
@_ ? () : grep { |
|
1502
|
0
|
0
|
0
|
|
|
|
$_ and %{ $self->{'table'}{$table}{$_} or {} } and defined( $values->{$_} ) |
|
|
0
|
0
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
1503
|
|
|
|
|
|
|
} keys %$values |
|
1504
|
|
|
|
|
|
|
) |
|
1505
|
|
|
|
|
|
|
) |
|
1506
|
|
|
|
|
|
|
) |
|
1507
|
|
|
|
|
|
|
); |
|
1508
|
0
|
0
|
|
|
|
|
$set = 'SET ' . $set if $set; |
|
1509
|
0
|
|
|
|
|
|
my $lwhere = $where; |
|
1510
|
0
|
0
|
|
|
|
|
$where = '' if $where eq 1; |
|
1511
|
0
|
0
|
0
|
|
|
|
$where = ' AND ' . $where if $where and $bywhere; |
|
1512
|
0
|
0
|
0
|
|
|
|
$whereignore = ' AND ' . $whereignore if $whereignore and ( $where or $bywhere ); |
|
|
|
|
0
|
|
|
|
|
|
1513
|
0
|
|
|
|
|
|
local $_; |
|
1514
|
|
|
|
|
|
|
#$processor{'out'}{'sql'} |
|
1515
|
0
|
0
|
0
|
|
|
|
$_ = $self->do( |
|
|
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
1516
|
|
|
|
|
|
|
"UPDATE $self->{$self->{'update_options'}} $self->{'IGNORE'} $tq$self->{'table_prefix'}$table$tq $set $setignore WHERE $bywhere $where $whereignore" |
|
1517
|
|
|
|
|
|
|
) |
|
1518
|
|
|
|
|
|
|
if ( $set or $lwhere or !$self->{'ON DUPLICATE KEY UPDATE'} ) |
|
1519
|
|
|
|
|
|
|
and ( $bywhere or $where or $whereignore ); |
|
1520
|
|
|
|
|
|
|
#$self->log( 'dev','by', Dumper $by); |
|
1521
|
|
|
|
|
|
|
#$self->log( 'dev', "WHERE[" . $where . "] BYwhere[" . $bywhere . "] whereignore[$whereignore] ", " UPVAL=", %{$values}, "UPSET=", $set, "RES[$_]" , Dumper $self->{'table'}{$table}); |
|
1522
|
|
|
|
|
|
|
#$processor{'out'}{'hash'}-> |
|
1523
|
|
|
|
|
|
|
#$self->hash($table, { '' => $values } ), #$processor{'out'}{'array'}->($table) |
|
1524
|
|
|
|
|
|
|
#$self->log( 'dev',"insert_hash run? ", "( !$set or !int($_) ) and !$where"); |
|
1525
|
|
|
|
|
|
|
#$self->log( 'dev',"insert_hash run "), |
|
1526
|
0
|
0
|
0
|
|
|
|
$self->insert_data( $table, $values ), #$processor{'out'}{'array'}->($table) |
|
|
|
|
0
|
|
|
|
|
|
1527
|
|
|
|
|
|
|
$self->flush_insert($table) if ( !$set or !int($_) ) and !$lwhere; |
|
1528
|
0
|
|
|
|
|
|
return undef; |
|
1529
|
0
|
|
0
|
|
|
|
}; |
|
1530
|
|
|
|
|
|
|
$self->{'insert_hash'} ||= sub { |
|
1531
|
0
|
|
|
0
|
|
|
my $self = shift; |
|
1532
|
0
|
0
|
|
|
|
|
return $self->insert_data(@_) unless $self->{'driver'} =~ /pg/i; |
|
1533
|
0
|
|
0
|
|
|
|
my $table = shift || $self->{'current_table'}; |
|
1534
|
0
|
|
|
|
|
|
my $ret; |
|
1535
|
0
|
|
|
|
|
|
for (@_) { |
|
1536
|
|
|
|
|
|
|
#$self->log( 'dev',"insert_hash run "), |
|
1537
|
0
|
|
|
|
|
|
$ret += $self->update( $table, undef, $_ ); |
|
1538
|
|
|
|
|
|
|
} |
|
1539
|
0
|
|
|
|
|
|
return $ret; |
|
1540
|
0
|
|
0
|
|
|
|
}; |
|
1541
|
|
|
|
|
|
|
#=z |
|
1542
|
|
|
|
|
|
|
$self->{'cut'} ||= sub { |
|
1543
|
0
|
|
|
0
|
|
|
my $self = shift; |
|
1544
|
0
|
0
|
|
|
|
|
return $_[0] unless $_[1]; |
|
1545
|
|
|
|
|
|
|
#return $_[0] = substr( $_[0], 0, $_[1] - ( ( $self->{'codepage'} eq 'utf-8' and $self->{'driver'} =~ /mysql/ ) ? 2 : 0 ) ), |
|
1546
|
|
|
|
|
|
|
# ( $self->{'codepage'} eq 'utf-8' ? $_[0] =~ s/[\xD0\xD1]+$// : () ); |
|
1547
|
0
|
|
|
|
|
|
return $_[0] = substr( $_[0], 0, $_[1] ); |
|
1548
|
0
|
|
0
|
|
|
|
}; |
|
1549
|
|
|
|
|
|
|
#=cut |
|
1550
|
|
|
|
|
|
|
$self->{'insert_data'} ||= sub { |
|
1551
|
0
|
|
|
0
|
|
|
my $self = shift; |
|
1552
|
|
|
|
|
|
|
#$self->log('dmp','insertdata=',Dumper(\@_)); |
|
1553
|
0
|
|
0
|
|
|
|
my $table = ( shift or $self->{'current_table'} ); #or $self->{'tfile'} |
|
1554
|
|
|
|
|
|
|
#$self->log('dev','hash!', $table); |
|
1555
|
|
|
|
|
|
|
#$processor{'out'}{'hash'} ||= sub { |
|
1556
|
|
|
|
|
|
|
#my $self = shift; |
|
1557
|
|
|
|
|
|
|
#my $table = ( shift or $self->{'tfile'} ); |
|
1558
|
0
|
|
|
|
|
|
for my $hash (@_) { |
|
1559
|
|
|
|
|
|
|
#$self->log('dev','hash1=',Dumper($hash)); |
|
1560
|
|
|
|
|
|
|
#for my $col ( keys %$hash ) { |
|
1561
|
|
|
|
|
|
|
#$self->log('dev','hash col',$col ); |
|
1562
|
|
|
|
|
|
|
#$self->log('dev','hash col2',$col , $hash->{$col}{'path'}); |
|
1563
|
|
|
|
|
|
|
#$self->log('dev','hash col2',$col , $hash->{$col}{'path'}); |
|
1564
|
0
|
0
|
|
|
|
|
next if !$hash; |
|
1565
|
|
|
|
|
|
|
#$self->log('dev',"def for $_", $self->{'table'}{$table}{$_}{'array_insert'}), |
|
1566
|
|
|
|
|
|
|
#$self->log('dev',"hash[$hash]",Dumper($hash) ) if ref $hash eq 'REF'; |
|
1567
|
0
|
|
|
|
|
|
$hash->{$_} = ( |
|
1568
|
|
|
|
|
|
|
$self->{'table'}{$table}{$_}{'default_insert'} |
|
1569
|
|
|
|
|
|
|
or ( $self->{'table'}{$table}{$_}{'array_insert'} ? $self->{'table'}{$table}{$_}{'default'} : undef ) |
|
1570
|
|
|
|
|
|
|
), |
|
1571
|
|
|
|
|
|
|
#$self->log('dev','hash def',$_, $hash->{$_}), |
|
1572
|
0
|
|
0
|
|
|
|
for grep { !defined $hash->{$_} } #$self->{'table'}{ $table }{$_}{'array_insert'} and |
|
|
0
|
|
|
|
|
|
|
|
1573
|
|
|
|
|
|
|
keys %{ $self->{'table'}{$table} }; |
|
1574
|
|
|
|
|
|
|
#$self->log('dev','hash next insert_min', $hash->{$col}, grep { $self->{'table'}{$table}{$_}{'insert_min'} and $hash->{$_} } keys %{ $self->{'table'}{$table} }), |
|
1575
|
|
|
|
|
|
|
#$self->log('dev','hash2=',Dumper($hash), |
|
1576
|
|
|
|
|
|
|
#grep { $self->{'table'}{$table}{$_}{'insert_min'} and !$hash->{$_} } keys %{ $self->{'table'}{$table} } |
|
1577
|
|
|
|
|
|
|
#), |
|
1578
|
|
|
|
|
|
|
#$self->log('dev','SKIP'), |
|
1579
|
|
|
|
|
|
|
next if #!$hash->{$col} |
|
1580
|
|
|
|
|
|
|
#and !(grep { $self->{'table'}{$table}{$_}{'insert_min'} } keys %{ $self->{'table'}{$table} }) |
|
1581
|
|
|
|
|
|
|
#or |
|
1582
|
0
|
0
|
|
|
|
|
grep { $self->{'table'}{$table}{$_}{'insert_min'} and !$hash->{$_} } keys %{ $self->{'table'}{$table} }; |
|
|
0
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
1583
|
|
|
|
|
|
|
#$self->log('dev','hash1'); |
|
1584
|
|
|
|
|
|
|
#########not here |
|
1585
|
0
|
|
|
|
|
|
$self->handler_insert0( $table, $hash ); |
|
1586
|
|
|
|
|
|
|
#if $self->{'handler_insert0'}; |
|
1587
|
|
|
|
|
|
|
#########not here |
|
1588
|
|
|
|
|
|
|
#$self->log('dev','hash3=',Dumper($hash)); |
|
1589
|
|
|
|
|
|
|
#( $self->{'filter_handler'} ? $self->{'filter_handler'}->($hash) : () ), next |
|
1590
|
|
|
|
|
|
|
#if grep { $self->{'table'}{$table}{$_}{'skip_mask'} and $hash->{$_} =~ /$self->{'table'}{ $table }{$_}{'skip_mask'}/i } |
|
1591
|
|
|
|
|
|
|
#keys %{ $self->{'table'}{$table} }; |
|
1592
|
|
|
|
|
|
|
#$self->log('filter', 'f1', $self->{'table_param'}{$table}{'filter'}); |
|
1593
|
|
|
|
|
|
|
next |
|
1594
|
0
|
0
|
0
|
|
|
|
if ref $self->{'table_param'}{$table}{'filter'} eq 'CODE' |
|
1595
|
|
|
|
|
|
|
and $self->{'table_param'}{$table}{'filter'}->( $self, $hash ); |
|
1596
|
|
|
|
|
|
|
#$self->handler_insert( $table, $hash ); |
|
1597
|
0
|
|
|
|
|
|
$self->handler_insert( $table, $hash ); # if $self->{'handler_insert'}; |
|
1598
|
0
|
|
|
|
|
|
$self->stem_insert( $table, $hash ); |
|
1599
|
|
|
|
|
|
|
#$self->log('dev',"lenCUT[$hash->{$_}]"), |
|
1600
|
0
|
0
|
0
|
|
|
|
$self->cut( $hash->{$_}, $self->{'table'}{$table}{$_}{'length'} ) |
|
1601
|
|
|
|
|
|
|
#$hash->{$_} = substr( $hash->{$_}, 0, $self->{'table'}{$table}{$_}{'length'} - ( $self->{'codepage'} eq 'utf-8' ? 2 : 0 ) ),($self->{'codepage'} eq 'utf-8' ? $hash->{$_} =~ s/[\xD0\xD1]+$// : ()), |
|
1602
|
|
|
|
|
|
|
#$self->log('dev',"lenCUT[$self->{'codepage'}][$hash->{$_}]"), |
|
1603
|
0
|
|
|
|
|
|
for grep { |
|
1604
|
0
|
|
|
|
|
|
( $self->{'table'}{$table}{$_}{'type'} eq $self->{'char_type'} ) |
|
1605
|
|
|
|
|
|
|
and $self->{'table'}{$table}{$_}{'length'} |
|
1606
|
|
|
|
|
|
|
and length( $hash->{$_} ) > |
|
1607
|
|
|
|
|
|
|
( $self->{'table'}{$table}{$_}{'length'} ) |
|
1608
|
|
|
|
|
|
|
} keys %{ $self->{'table'}{$table} }; |
|
1609
|
|
|
|
|
|
|
#$processor{'out'}{'array'}-> |
|
1610
|
|
|
|
|
|
|
#$self->log('dev','ic from here='); |
|
1611
|
0
|
|
|
|
|
|
local $self->{'table'}{$table} = $self->{'table'}{$table}; |
|
1612
|
|
|
|
|
|
|
#$self->log('dev', $self->{'table'}{$table}); |
|
1613
|
0
|
|
|
|
|
|
my $chanded; |
|
1614
|
|
|
|
|
|
|
#$self->log('dev', 'set array_insert', $table, $_, ), |
|
1615
|
|
|
|
|
|
|
( |
|
1616
|
0
|
|
|
|
|
|
++$chanded == 1 |
|
1617
|
|
|
|
|
|
|
? ( |
|
1618
|
|
|
|
|
|
|
#$self->log('dev', 'flush on change', $table, $_), |
|
1619
|
|
|
|
|
|
|
$self->flush_insert($table) |
|
1620
|
|
|
|
|
|
|
) |
|
1621
|
|
|
|
|
|
|
: () |
|
1622
|
|
|
|
|
|
|
), |
|
1623
|
|
|
|
|
|
|
$self->{'table'}{$table}{$_}{'array_insert'} = 1 |
|
1624
|
0
|
0
|
|
|
|
|
for grep { |
|
1625
|
0
|
|
|
|
|
|
defined $hash->{$_} |
|
1626
|
|
|
|
|
|
|
and length $hash->{$_} |
|
1627
|
|
|
|
|
|
|
#and ($hash->{$_} ne $self->{'table'}{$table}{$_}{'default'} ) |
|
1628
|
0
|
0
|
0
|
|
|
|
and keys %{ $self->{'table'}{$table}{$_} } and !$self->{'table'}{$table}{$_}{'array_insert'} |
|
|
|
|
0
|
|
|
|
|
|
1629
|
|
|
|
|
|
|
} keys %{ $self->{'table'}{$table} }; |
|
1630
|
|
|
|
|
|
|
#$self->log('dmp','insertdata2($table)=',Dumper(\@_)); |
|
1631
|
0
|
|
|
|
|
|
$self->insert_cached( |
|
1632
|
|
|
|
|
|
|
$table, |
|
1633
|
|
|
|
|
|
|
\@{$hash}{ |
|
1634
|
0
|
|
|
|
|
|
$self->insert_order($table) |
|
1635
|
|
|
|
|
|
|
#sort { $self->{'table'}{$table}{$b}{'order'} <=> $self->{'table'}{$table}{$a}{'order'} } |
|
1636
|
|
|
|
|
|
|
#grep { $self->{'table'}{$table}{$_}{'array_insert'} } keys %{ $self->{'table'}{$table} } |
|
1637
|
|
|
|
|
|
|
} |
|
1638
|
|
|
|
|
|
|
); |
|
1639
|
|
|
|
|
|
|
#########not here |
|
1640
|
0
|
|
|
|
|
|
$self->handler_insert2( $table, $hash ); |
|
1641
|
|
|
|
|
|
|
#########not here |
|
1642
|
|
|
|
|
|
|
} |
|
1643
|
|
|
|
|
|
|
#} |
|
1644
|
0
|
|
|
|
|
|
return undef; |
|
1645
|
0
|
|
0
|
|
|
|
}; |
|
1646
|
|
|
|
|
|
|
$self->{'insert_hash_hash'} ||= sub { |
|
1647
|
0
|
|
|
0
|
|
|
my $self = shift; |
|
1648
|
0
|
|
0
|
|
|
|
my $table = ( shift or $self->{'current_table'} ); #or $self->{'tfile'} |
|
1649
|
0
|
|
|
|
|
|
for my $hash (@_) { $self->insert_hash( $table, values %$hash ); } |
|
|
0
|
|
|
|
|
|
|
|
1650
|
0
|
|
|
|
|
|
return undef; |
|
1651
|
0
|
|
0
|
|
|
|
}; |
|
1652
|
|
|
|
|
|
|
$self->{'q_file'} ||= sub { |
|
1653
|
0
|
|
|
0
|
|
|
my $self = shift; |
|
1654
|
0
|
|
0
|
|
|
|
my $table = shift || $self->{'current_table'}; |
|
1655
|
0
|
|
|
|
|
|
my $search_str = shift; |
|
1656
|
0
|
|
|
|
|
|
my %tparam; |
|
1657
|
|
|
|
|
|
|
#return () if $self->{'sphinx'}; |
|
1658
|
|
|
|
|
|
|
#if ( $self->{'table'}{$table}{'name'} and $self->{'table'}{$table}{'ext'} and $search_str =~ /^\s*(\S+)\.+(\S+)\s*$/ ) { |
|
1659
|
0
|
0
|
0
|
|
|
|
if ( $self->{'table'}{$table}{'name'} |
|
|
|
0
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
1660
|
|
|
|
|
|
|
and $self->{'table'}{$table}{'ext'} |
|
1661
|
|
|
|
|
|
|
and $search_str =~ m{^([^/|"]+[^\s/|"])\.([^/\."|]+)$} ) #" |
|
1662
|
|
|
|
|
|
|
{ |
|
1663
|
0
|
|
|
|
|
|
%tparam = ( 'name' => $1, 'ext' => $2 ); |
|
1664
|
|
|
|
|
|
|
} elsif ( $self->{'table'}{$table}{'tiger'} and $search_str =~ /^\s*([A-Z0-9]{39})\s*$/i ) { |
|
1665
|
0
|
|
|
|
|
|
%tparam = ( 'tiger' => uc $1 ); |
|
1666
|
|
|
|
|
|
|
} |
|
1667
|
0
|
|
|
|
|
|
return %tparam; |
|
1668
|
0
|
|
0
|
|
|
|
}; |
|
1669
|
|
|
|
|
|
|
$self->{'where_body'} ||= sub { |
|
1670
|
0
|
|
|
0
|
|
|
my $self = shift; |
|
1671
|
0
|
|
|
|
|
|
my ( $param_orig, $param_num, $table, $after ) = @_; |
|
1672
|
0
|
0
|
|
|
|
|
my $param = { %{ $param_orig || {} } }; |
|
|
0
|
|
|
|
|
|
|
|
1673
|
|
|
|
|
|
|
#my $param = $param_orig; |
|
1674
|
0
|
|
0
|
|
|
|
$table ||= $self->{'current_table'}; |
|
1675
|
0
|
|
|
|
|
|
my ( $search_str_add, $ask, $close ); |
|
1676
|
|
|
|
|
|
|
#$self->log('dev', 'where_body', 1, $table, %$param, $self->{'current_table'}); |
|
1677
|
0
|
|
|
|
|
|
my $questions = 0; |
|
1678
|
0
|
|
|
|
|
|
map ++$questions, grep defined( $param->{ $_ . $param_num } ), |
|
1679
|
0
|
0
|
|
|
|
|
@{ $config{'user_param_founded'} || [ 'q', keys %{ $self->{'table'}{$table} } ] }; |
|
|
0
|
|
|
|
|
|
|
|
1680
|
|
|
|
|
|
|
#$self->log('dev', 'recstop' , $param_num), |
|
1681
|
0
|
0
|
0
|
|
|
|
return if ( $param_num and !$questions ) or ++$self->{'rec_stop'} > 20; |
|
|
|
|
0
|
|
|
|
|
|
1682
|
0
|
|
|
|
|
|
my $first = 1; |
|
1683
|
0
|
|
|
|
|
|
my $local_cond = 0; |
|
1684
|
|
|
|
|
|
|
#my ( $tq, $rq, $vq ) = sql_quotes(); |
|
1685
|
|
|
|
|
|
|
#$self->log('dev', 'where_body', 1.1, $param->{ 'q' . $param_num }); |
|
1686
|
0
|
|
0
|
|
|
|
while ( defined( $param->{ 'q' . $param_num } ) and $param->{ 'q' . $param_num } =~ s/(\w+\S?[=:](?:".+?"|\S+))// ) { |
|
1687
|
|
|
|
|
|
|
#$self->log('dev', 'where_body', 1.2, $param->{ 'q' . $param_num }, $1); |
|
1688
|
|
|
|
|
|
|
#$self->log('dev', 'where_body selected', $1); |
|
1689
|
|
|
|
|
|
|
#$self->log('dev', 'where_body selected', |
|
1690
|
|
|
|
|
|
|
#get_params_one( $param, $1 ); |
|
1691
|
0
|
|
|
|
|
|
local $_ = $1; |
|
1692
|
0
|
|
|
|
|
|
s/^(\S+):/$1=/; |
|
1693
|
0
|
|
|
|
|
|
my $lparam = get_params_one( undef, $_ ); |
|
1694
|
0
|
|
|
|
|
|
$lparam->{$_} =~ s/^"|"$//g, $param->{$_} = $lparam->{$_} for keys %$lparam; |
|
1695
|
|
|
|
|
|
|
#$self->log('dev', 'where_body selected', $1, %$param); #%$lparam, |
|
1696
|
|
|
|
|
|
|
} |
|
1697
|
|
|
|
|
|
|
#$self->log('dev', 'where_body', 2); |
|
1698
|
0
|
|
|
|
|
|
for my $preset ( $param->{ 'q' . $param_num } =~ /:(\S+)/g ) { |
|
1699
|
0
|
|
|
|
|
|
for my $sets ( keys %{ $config{'preset'} } ) { |
|
|
0
|
|
|
|
|
|
|
|
1700
|
0
|
0
|
|
|
|
|
if ( $config{'preset'}{$sets}{$preset} ) { |
|
1701
|
0
|
|
|
|
|
|
$param->{ 'q' . $param_num } =~ s/:$preset//; |
|
1702
|
0
|
|
|
|
|
|
for ( keys %{ $config{'preset'}{$sets}{$preset}{'set'} } ) { |
|
|
0
|
|
|
|
|
|
|
|
1703
|
0
|
0
|
|
|
|
|
$param->{ $_ . $param_num } .= |
|
1704
|
|
|
|
|
|
|
( $param->{ $_ . $param_num } ? ' ' : '' ) . $config{'preset'}{$sets}{$preset}{'set'}{$_}; |
|
1705
|
|
|
|
|
|
|
} |
|
1706
|
|
|
|
|
|
|
} |
|
1707
|
|
|
|
|
|
|
} |
|
1708
|
|
|
|
|
|
|
} |
|
1709
|
0
|
|
|
|
|
|
my $search_str = $param->{ 'q' . $param_num }; |
|
1710
|
|
|
|
|
|
|
#$self->log( 'dev', 'where_body', 3, $search_str, $param_num ); |
|
1711
|
0
|
0
|
|
|
|
|
my $glueg = $param->{ 'glueg' . $param_num } eq 'or' ? ' OR ' : ' AND '; |
|
1712
|
0
|
0
|
|
|
|
|
my $gluel = $param->{ 'gluel' . $param_num } eq 'or' ? ' OR ' : ' AND '; |
|
1713
|
0
|
0
|
0
|
|
|
|
$glueg = ' XOR ' if $self->{'enable_xor_query'} and $param->{ 'glueg' . $param_num } eq 'xor'; |
|
1714
|
0
|
0
|
0
|
|
|
|
$gluel = ' XOR ' if $self->{'enable_xor_query'} and $param->{ 'gluel' . $param_num } eq 'xor'; |
|
1715
|
0
|
0
|
0
|
|
|
|
if ( my ($days) = $param->{ 'search_days' . $param_num } =~ /(\d+)/ and $1 and %{ $self->{'table'}{$table}{'time'} or {} } ) |
|
|
0
|
0
|
0
|
|
|
|
|
|
1716
|
|
|
|
|
|
|
{ |
|
1717
|
0
|
0
|
|
|
|
|
$ask .= " " . ( $self->{'no_column_prepend_table'} ? () : "$tq$self->{'table_prefix'}$table$tq." ) . "$rq" . "time$rq "; |
|
1718
|
0
|
0
|
|
|
|
|
if ( $param->{ 'search_days_mode' . $param_num } eq 'l' ) { $ask .= '<'; } |
|
|
0
|
|
|
|
|
|
|
|
1719
|
0
|
|
|
|
|
|
else { $ask .= '>'; } |
|
1720
|
0
|
|
|
|
|
|
$days = int( time() ) - $days * 24 * 60 * 60; |
|
1721
|
0
|
0
|
|
|
|
|
$ask .= '= ' . ( $self->{'sphinx'} ? $days : $self->squotes($days) ); |
|
1722
|
|
|
|
|
|
|
} |
|
1723
|
|
|
|
|
|
|
#$self->log('dev', 'online1', Dumper($param)); |
|
1724
|
0
|
0
|
0
|
|
|
|
if ( !$self->{'no_online'} and defined( $param->{ 'online' . $param_num } ) ) { |
|
1725
|
0
|
0
|
|
|
|
|
if ( $param->{ 'online' . $param_num } eq 'on' ) { $param->{ 'online' . $param_num } = $config{'online_minutes'}; } |
|
|
0
|
|
|
|
|
|
|
|
1726
|
|
|
|
|
|
|
#$self->log('dev', 'online2', Dumper($param)); |
|
1727
|
0
|
0
|
|
|
|
|
if ( $param->{ 'online' . $param_num } > 0 ) { |
|
1728
|
0
|
|
|
|
|
|
$param->{ 'live' . $param_num } = int( time() ) + $self->{'timediff'} - int( $param->{ 'online' . $param_num } ) * 60; |
|
1729
|
0
|
|
|
|
|
|
$param->{ 'live_mode' . $param_num } = 'g'; |
|
1730
|
|
|
|
|
|
|
#$self->log('dev', $param->{ 'live' . $param_num }); |
|
1731
|
|
|
|
|
|
|
} |
|
1732
|
|
|
|
|
|
|
} |
|
1733
|
0
|
0
|
0
|
|
|
|
if ( |
|
|
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
1734
|
|
|
|
|
|
|
$self->{'path_complete'} |
|
1735
|
|
|
|
|
|
|
and $param->{ 'path' . $param_num } |
|
1736
|
|
|
|
|
|
|
and !( $param->{ 'path' . $param_num } =~ /^[ !\/\*]/ ) |
|
1737
|
|
|
|
|
|
|
and ( $param->{ 'path' . $param_num } ne 'EMPTY' ) |
|
1738
|
|
|
|
|
|
|
and !( ( |
|
1739
|
|
|
|
|
|
|
!$self->{'no_regex'} |
|
1740
|
|
|
|
|
|
|
and |
|
1741
|
|
|
|
|
|
|
( $param->{ 'path' . $param_num } =~ /^\s*reg?e?x?p?:\s*/i or $param->{ 'path' . '_mode' . $param_num } =~ /[r~]/i ) |
|
1742
|
|
|
|
|
|
|
) |
|
1743
|
|
|
|
|
|
|
) |
|
1744
|
|
|
|
|
|
|
) |
|
1745
|
|
|
|
|
|
|
{ # bad idea ? |
|
1746
|
0
|
|
|
|
|
|
$search_str_add .= ' /' . $param->{ 'path' . $param_num } . '/ '; |
|
1747
|
0
|
|
|
|
|
|
delete $param->{ 'path' . $param_num }; |
|
1748
|
|
|
|
|
|
|
} |
|
1749
|
0
|
0
|
|
|
|
|
for my $item ( ( |
|
|
0
|
|
|
|
|
|
|
|
1750
|
|
|
|
|
|
|
sort { |
|
1751
|
0
|
0
|
0
|
|
|
|
$self->{'table'}{$table}{$b}{'weight'} <=> $self->{'table'}{$table}{$a}{'weight'} |
|
|
|
|
0
|
|
|
|
|
|
1752
|
|
|
|
|
|
|
|| $self->{'table'}{$table}{$b}{'order'} <=> $self->{'table'}{$table}{$a}{'order'} |
|
1753
|
|
|
|
|
|
|
} grep { |
|
1754
|
0
|
|
|
|
|
|
$self->{'nav_all'} |
|
1755
|
|
|
|
|
|
|
or $self->{'table'}{$table}{$_}{'nav_num_field'} |
|
1756
|
|
|
|
|
|
|
or $self->{'table'}{$table}{$_}{'nav_field'} |
|
1757
|
|
|
|
|
|
|
or $self->{'table'}{$table}{$_}{'nav_hide'} |
|
1758
|
0
|
|
|
|
|
|
} keys %{ $self->{'table'}{$table} } |
|
1759
|
|
|
|
|
|
|
), |
|
1760
|
|
|
|
|
|
|
@{ $self->{'table_param'}{$table}{'join_fields'} } |
|
1761
|
|
|
|
|
|
|
) |
|
1762
|
|
|
|
|
|
|
{ |
|
1763
|
|
|
|
|
|
|
#$self->log('dev', 'where_body', 4, $item); |
|
1764
|
|
|
|
|
|
|
next |
|
1765
|
0
|
0
|
0
|
|
|
|
if $self->{'no_index'} |
|
|
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
1766
|
|
|
|
|
|
|
or $self->{'ignore_index'} |
|
1767
|
|
|
|
|
|
|
or $self->{'table_param'}{$table}{'no_index'} |
|
1768
|
|
|
|
|
|
|
or $self->{'table_param'}{$table}{'ignore_index'} |
|
1769
|
|
|
|
|
|
|
or $param->{ $item . $param_num } !~ /\S/; |
|
1770
|
|
|
|
|
|
|
#$self->log('dev', 'where_body', 4, $item); |
|
1771
|
0
|
|
|
|
|
|
my $lask; |
|
1772
|
0
|
0
|
|
|
|
|
++$local_cond, $lask .= $gluel if $ask; |
|
1773
|
0
|
|
|
|
|
|
my $pib = $param->{ $item . $param_num }; |
|
1774
|
0
|
|
|
|
|
|
$pib =~ s/^\s*|\s*$//g; |
|
1775
|
0
|
|
|
|
|
|
my ( $group_not, $group_not_close ); #, |
|
1776
|
|
|
|
|
|
|
#$self->log('dev', 'where_body', 5, $item, $self->{$item}, $_, 'C=', $config{$item}); |
|
1777
|
0
|
|
|
|
|
|
$pib =~ s/\:$_(\W|$)/$config{$item}{$_}{'to'}$1/g and ++$group_not |
|
1778
|
0
|
0
|
0
|
|
|
|
for grep { defined $config{$item}{$_}{'to'} } keys %{ ref $config{$item} eq 'HASH' ? $config{$item} : {} }; |
|
|
0
|
|
|
|
|
|
|
|
1779
|
|
|
|
|
|
|
#for grep {defined $self->{$item}{$_}{'to'}} keys %{ $self->{$item} or {}}; |
|
1780
|
0
|
0
|
|
|
|
|
next if $pib eq ''; |
|
1781
|
0
|
|
|
|
|
|
my ( $brstr, $space ); |
|
1782
|
0
|
0
|
0
|
|
|
|
if ( $self->{'table'}{$table}{$item}{'no_split_space'} |
|
|
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
1783
|
|
|
|
|
|
|
or ( !$self->{'no_regex'} and ( $pib =~ /\s*reg?e?x?p?:\s*/ or $param->{ $item . '_mode' . $param_num } =~ /[r~]/i ) ) ) |
|
1784
|
|
|
|
|
|
|
{ |
|
1785
|
|
|
|
|
|
|
#$self->log('dev', 'SPA') ; |
|
1786
|
0
|
|
|
|
|
|
$space = '\s+'; |
|
1787
|
|
|
|
|
|
|
} else { |
|
1788
|
0
|
|
|
|
|
|
$brstr = '|\s+'; |
|
1789
|
|
|
|
|
|
|
} |
|
1790
|
|
|
|
|
|
|
#$brstr = $space . '\&+' . $space . '|' . '\|+' . '|(\s+AND\s+)|\s+OR\s+' . $brstr; |
|
1791
|
0
|
|
|
|
|
|
$brstr = $space . '\&+' . $space . '|' . $space . '\|+' . $space . '|(\s+AND\s+)|\s+OR\s+' . $brstr; |
|
1792
|
0
|
|
|
|
|
|
my $num_cond = 0; |
|
1793
|
0
|
|
|
|
|
|
my $next_cond; |
|
1794
|
|
|
|
|
|
|
my $llask; |
|
1795
|
0
|
|
0
|
|
|
|
do { |
|
1796
|
0
|
|
|
|
|
|
my ( $pi, $cond ); |
|
1797
|
0
|
|
|
|
|
|
$cond = $next_cond; |
|
1798
|
|
|
|
|
|
|
#$self->log('dev', "split[$pib] with [($brstr)]"); |
|
1799
|
0
|
0
|
|
|
|
|
if ( $pib =~ /($brstr)/ ) { ( $pib, $pi, $next_cond ) = ( $', $`, $1 ); } |
|
|
0
|
|
|
|
|
|
|
|
1800
|
0
|
|
|
|
|
|
else { $pi = $pib, $pib = ''; } |
|
1801
|
0
|
0
|
|
|
|
|
if ( $num_cond++ ) { |
|
1802
|
|
|
|
|
|
|
#$self->log('dev', "andf1, $llask"); |
|
1803
|
0
|
0
|
0
|
|
|
|
if ( $cond =~ /(and)|\&+/i ) { $llask .= ' AND '; } |
|
|
0
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
1804
|
0
|
|
|
|
|
|
elsif ( $self->{'enable_xor_query'} and $cond =~ /(xor)/i ) { $llask .= ' XOR '; } #too slow |
|
1805
|
0
|
|
|
|
|
|
elsif ( $cond =~ /(or)|\|+|\s+|^$/i ) { $llask .= ' OR '; } |
|
1806
|
|
|
|
|
|
|
#$self->log('dev', "andf2, $llask"); |
|
1807
|
|
|
|
|
|
|
} |
|
1808
|
|
|
|
|
|
|
#$self->log('dev', "$pib, $pi, $next_cond, $llask"); |
|
1809
|
0
|
0
|
0
|
|
|
|
my $not = 1 if ( !$self->{'no_slow'} or $self->{'table'}{$table}{$item}{'fast_not'} ) and ( $pi =~ s/^\s*[\!\-]\s*//g ); |
|
|
|
|
0
|
|
|
|
|
|
1810
|
0
|
0
|
|
|
|
|
$llask .= ' NOT ' . ( $group_not ? ( ++$group_not_close, ' ( ' ) : '' ) if $not; |
|
|
|
0
|
|
|
|
|
|
|
1811
|
|
|
|
|
|
|
#$self->log('dev', "not1 $llask"); |
|
1812
|
0
|
0
|
|
|
|
|
if ( $self->{'table_param'}{$table}{'name_to_base'}{$item} ) { |
|
1813
|
|
|
|
|
|
|
#$self->log('dev', "here", $self->{'table_param'}{$table}{'name_to_base'}{$item}); |
|
1814
|
|
|
|
|
|
|
#$llask .= ' ' . $tq . $self->{'table_prefix'} . $self->{'table_param'}{$table}{'name_to_base'}{$item} . $tq . ' '; |
|
1815
|
0
|
|
|
|
|
|
$llask .= ' ' . $self->{'table_param'}{$table}{'name_to_base'}{$item} . ' '; |
|
1816
|
|
|
|
|
|
|
} else { |
|
1817
|
0
|
0
|
|
|
|
|
$llask .= |
|
1818
|
|
|
|
|
|
|
" " . ( $self->{'no_column_prepend_table'} ? () : "$tq$self->{'table_prefix'}$table$tq." ) . "$rq$item" . "$rq "; |
|
1819
|
|
|
|
|
|
|
} |
|
1820
|
0
|
|
|
|
|
|
my ($dequote_); #, $dequotesl |
|
1821
|
|
|
|
|
|
|
#$self->log('dev', !$self->{'no_regex'}); |
|
1822
|
0
|
0
|
0
|
|
|
|
if ( !$self->{'no_regex'} |
|
|
|
0
|
0
|
|
|
|
|
|
|
|
0
|
0
|
|
|
|
|
|
|
|
0
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
1823
|
|
|
|
|
|
|
and ( $pi =~ s/^\s*reg?e?x?p?:\s*//ig or $param->{ $item . '_mode' . $param_num } =~ /[r~]/i ) ) |
|
1824
|
|
|
|
|
|
|
{ |
|
1825
|
0
|
|
|
|
|
|
$llask .= ' REGEXP '; |
|
1826
|
|
|
|
|
|
|
#++$dequotesl; |
|
1827
|
|
|
|
|
|
|
} elsif ( !$self->{'no_soundex'} |
|
1828
|
|
|
|
|
|
|
and ( $pi =~ s/^\s*sou?n?d?e?x?:\s*//ig or $param->{ $item . '_mode' . $param_num } =~ /[s@]/i ) ) |
|
1829
|
|
|
|
|
|
|
{ |
|
1830
|
0
|
|
|
|
|
|
$llask .= ' SOUNDS LIKE '; |
|
1831
|
|
|
|
|
|
|
} elsif ( $pi =~ /[*?]/ ) { |
|
1832
|
0
|
|
|
|
|
|
$pi =~ s/%/\\%/g; |
|
1833
|
0
|
0
|
|
|
|
|
$pi =~ s/_/\\_/g and ++$dequote_; |
|
1834
|
0
|
|
|
|
|
|
$pi =~ tr/*?/%_/; |
|
1835
|
0
|
0
|
0
|
|
|
|
next if $self->{'no_empty'} and ( $pi !~ /\S/ or $pi =~ /^\s*[%_]+\s*$/ ); |
|
|
|
|
0
|
|
|
|
|
|
1836
|
|
|
|
|
|
|
#$self->log('dev', 'pi_:', $pi); |
|
1837
|
0
|
|
|
|
|
|
$llask .= ' LIKE '; |
|
1838
|
|
|
|
|
|
|
} |
|
1839
|
|
|
|
|
|
|
#} else { |
|
1840
|
0
|
|
|
|
|
|
elsif ( $param->{ $item . '_mode' . $param_num } =~ /notnull/i ) { $llask .= 'IS NOT NULL'; next; } |
|
|
0
|
|
|
|
|
|
|
|
1841
|
0
|
|
|
|
|
|
elsif ( $param->{ $item . '_mode' . $param_num } =~ /null/i ) { $llask .= 'IS NULL'; next; } |
|
|
0
|
|
|
|
|
|
|
|
1842
|
0
|
0
|
|
|
|
|
elsif ( $param->{ $item . '_mode' . $param_num } =~ /[g>]/i ) { $llask .= ( $not ? '<' : '>' ) . '= '; } |
|
1843
|
0
|
0
|
|
|
|
|
elsif ( $param->{ $item . '_mode' . $param_num } =~ /[l<]/i ) { $llask .= ( $not ? '>' : '<' ) . '= '; } |
|
1844
|
0
|
|
|
|
|
|
else { $llask .= '= '; } |
|
1845
|
|
|
|
|
|
|
#} |
|
1846
|
0
|
|
|
|
|
|
$pi =~ s/(^\s*)|(\s*$)//g; |
|
1847
|
0
|
0
|
|
|
|
|
$pi = psmisc::human( 'number_k', $pi ) if $item eq 'size'; |
|
1848
|
0
|
|
|
|
|
|
$work{ 'bold_' . $item } .= ' ' . $pi; |
|
1849
|
0
|
0
|
0
|
|
|
|
if ( !( $self->{'sphinx'} and $self->{'table'}{$table}{$item}{'nav_num_field'} and $pi =~ /^\d+$/ ) ) { |
|
|
|
|
0
|
|
|
|
|
|
1850
|
0
|
0
|
|
|
|
|
$pi = ( $pi ne 'EMPTY' ? $self->squotes($pi) : $self->squotes('') ); |
|
1851
|
|
|
|
|
|
|
} |
|
1852
|
0
|
0
|
|
|
|
|
$pi =~ s|\\_|\_|g if $dequote_; |
|
1853
|
|
|
|
|
|
|
#$self->log('dev', '$pi:', $pi, $dequotesl); |
|
1854
|
|
|
|
|
|
|
#$pi =~ s|\\{2}|\\|g if $dequotesl; |
|
1855
|
|
|
|
|
|
|
#$self->log('dev', '$pi a:', $pi); |
|
1856
|
0
|
|
|
|
|
|
$llask .= $pi; |
|
1857
|
|
|
|
|
|
|
#$self->log('dev', '$llask:', $llask); |
|
1858
|
|
|
|
|
|
|
} while ( $pib and $num_cond < 50 ); |
|
1859
|
|
|
|
|
|
|
#$self->log('dev', '1 $llask:', $llask); |
|
1860
|
0
|
|
|
|
|
|
$llask .= " ) " x $group_not_close; |
|
1861
|
0
|
|
|
|
|
|
$group_not_close = 0; |
|
1862
|
0
|
0
|
|
|
|
|
$lask .= ( $num_cond > 1 ? ' ( ' : '' ) . $llask . ( $num_cond > 1 ? ' ) ' : '' ); |
|
|
|
0
|
|
|
|
|
|
|
1863
|
|
|
|
|
|
|
#$self->log('dev', '1 $lask:', $lask); |
|
1864
|
0
|
|
0
|
|
|
|
$ask .= |
|
1865
|
|
|
|
|
|
|
( ( !$self->{'no_slow'} or $self->{'table'}{$table}{$item}{'fast_not'} ) |
|
1866
|
|
|
|
|
|
|
and $param->{ $item . '_mode' . $param_num } =~ /[n!]/i ? ' NOT ' : ' ' ) |
|
1867
|
|
|
|
|
|
|
. $lask; |
|
1868
|
|
|
|
|
|
|
#$self->log('dev', '1 $ask:', $ask); |
|
1869
|
|
|
|
|
|
|
} |
|
1870
|
0
|
|
|
|
|
|
$work{'search_str'} .= ' ' . $search_str . ' ' . $search_str_add; |
|
1871
|
|
|
|
|
|
|
#$self->log('dev', 'Sstr', $work{'search_str'}); |
|
1872
|
0
|
0
|
0
|
|
|
|
if ( $search_str =~ /\S/ or $search_str_add ) { |
|
1873
|
0
|
0
|
0
|
|
|
|
unless ( $param->{'page'} > 1 or $param->{'order'} or $param->{'no_querystat'} ) { |
|
|
|
|
0
|
|
|
|
|
|
1874
|
|
|
|
|
|
|
#$self->log('dev', '2 $ask:', $search_str); |
|
1875
|
|
|
|
|
|
|
#$self->dump_cp(); |
|
1876
|
0
|
|
|
|
|
|
++$work{'query'}{$search_str}; |
|
1877
|
0
|
|
|
|
|
|
map { ++$work{'word'}{$_} } grep $_, split /[\W_]+/, $search_str; #if $self->{'codepage'} ne 'utf-8'; |
|
|
0
|
|
|
|
|
|
|
|
1878
|
|
|
|
|
|
|
} |
|
1879
|
|
|
|
|
|
|
#$self->log('dev', '2 $ask:', $ask, Dumper %work); |
|
1880
|
0
|
0
|
|
|
|
|
++$local_cond, $ask .= $gluel if $ask; |
|
1881
|
|
|
|
|
|
|
#$self->log('dev', '3 $ask:', $ask, $search_str, $search_str_add); |
|
1882
|
0
|
0
|
0
|
|
|
|
$param->{ 'adv_query' . $param_num } = 'on' |
|
|
|
|
0
|
|
|
|
|
|
1883
|
|
|
|
|
|
|
if $search_str =~ /\S+\*+\s*/ |
|
1884
|
|
|
|
|
|
|
or $search_str =~ /(^|\s+)(([+\-><~]+\()|\")[^"()]*\S+\s+\S+[^"()]*[\"\)]($|\s+)/ |
|
1885
|
|
|
|
|
|
|
or $search_str =~ /(^|\s+)[\~\+\-\<\>]\S+/; |
|
1886
|
0
|
0
|
0
|
|
|
|
$search_str =~ s/(\S+)/\+$1/g |
|
|
|
|
0
|
|
|
|
|
|
1887
|
|
|
|
|
|
|
if $param->{ 'adv_query' . $param_num } eq 'on' |
|
1888
|
|
|
|
|
|
|
and !( $search_str =~ /((^|\s)\W+\S)|\S\W+(\s|$)/ ) |
|
1889
|
|
|
|
|
|
|
and $search_str =~ /\s/; |
|
1890
|
0
|
0
|
|
|
|
|
$ask .= ( $search_str =~ s/^\s*\!\s*// ? ' NOT ' : '' ); |
|
1891
|
|
|
|
|
|
|
#! |
|
1892
|
0
|
0
|
0
|
|
|
|
if ( !$self->{'use_q_file_fallback'} and my %tparam = $self->q_file( $table, $search_str ) ) { |
|
|
|
0
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
1893
|
|
|
|
|
|
|
#$search_str =~ /^\s*(\S+)\.+(\S+)\s*$/ and $self->{'table'}{$table}{'name'} and $self->{'table'}{$table}{'ext'} ) { |
|
1894
|
|
|
|
|
|
|
#my %tparam = ( 'name' => $1, 'ext' => $2 ); |
|
1895
|
0
|
|
|
|
|
|
$ask .= ' ( ' . $self->where_body( \%tparam, undef, $table ) . ' ) '; |
|
1896
|
|
|
|
|
|
|
} elsif ( !$self->{'sphinx'} |
|
1897
|
|
|
|
|
|
|
and !$self->{'no_slow'} |
|
1898
|
|
|
|
|
|
|
and $search_str =~ /^\s*\*+\S+/ |
|
1899
|
|
|
|
|
|
|
and $self->{'table'}{$table}{'path'} |
|
1900
|
|
|
|
|
|
|
and $self->{'table'}{$table}{'name'} |
|
1901
|
|
|
|
|
|
|
and $self->{'table'}{$table}{'ext'} ) |
|
1902
|
|
|
|
|
|
|
{ |
|
1903
|
0
|
|
|
|
|
|
my %tparam = ( 'path' => '/' . $search_str, 'name' => $search_str, 'ext' => $search_str, 'gluel' => 'or' ); |
|
1904
|
0
|
|
|
|
|
|
$ask .= ' ( ' . $self->where_body( \%tparam, undef, $table ) . ' ) '; |
|
1905
|
|
|
|
|
|
|
#! |
|
1906
|
|
|
|
|
|
|
} else { |
|
1907
|
|
|
|
|
|
|
#my $search_str = $search_str . $search_str_add; |
|
1908
|
|
|
|
|
|
|
#$self->log('ss', $search_str); |
|
1909
|
0
|
|
|
|
|
|
$search_str .= $search_str_add; |
|
1910
|
0
|
0
|
|
|
|
|
$self->{'handler_search_str'}->( $table, \$search_str ) if ref $self->{'handler_search_str'} eq 'CODE'; |
|
1911
|
0
|
|
|
|
|
|
my $search_str_stem = $self->stem($search_str) |
|
1912
|
0
|
0
|
|
|
|
|
if grep { $self->{'table'}{$table}{$_}{'stem'} } keys %{ $self->{'table'}{$table} }; |
|
|
0
|
|
|
|
|
|
|
|
1913
|
|
|
|
|
|
|
#$self->log('ss1',$param_num, $search_str); |
|
1914
|
0
|
0
|
0
|
|
|
|
local $param->{ 'adv_query' . $param_num } = 'on' |
|
1915
|
|
|
|
|
|
|
if $self->{'ignore_index'} |
|
1916
|
|
|
|
|
|
|
or $self->{'table_param'}{$table}{'ignore_index'}; |
|
1917
|
|
|
|
|
|
|
#$self->log( 'dev', 'where_body', 6, $search_str, $table, $ask, grep { $self->{'table'}{$table}{$_}{'fulltext'} } keys %{ $self->{'table'}{$table} } ); |
|
1918
|
0
|
0
|
0
|
|
|
|
if ( ( #!$self->{'use_sphinx'} and |
|
|
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
1919
|
|
|
|
|
|
|
!$param->{ 'adv_query' . $param_num } and ( |
|
1920
|
|
|
|
|
|
|
$self->{'ignore_index_fulltext'} or !grep { |
|
1921
|
|
|
|
|
|
|
$self->{'table'}{$table}{$_}{'fulltext'} |
|
1922
|
|
|
|
|
|
|
or ( $self->{'sphinx'} and $self->{'table'}{$table}{$_}{'sphinx'} ) |
|
1923
|
|
|
|
|
|
|
} keys %{ $self->{'table'}{$table} } |
|
1924
|
|
|
|
|
|
|
) |
|
1925
|
|
|
|
|
|
|
) |
|
1926
|
|
|
|
|
|
|
or !$self->{'match'} |
|
1927
|
|
|
|
|
|
|
) |
|
1928
|
|
|
|
|
|
|
{ |
|
1929
|
|
|
|
|
|
|
#my $sl = $self->squotes( '%' . $search_str . '%' ); |
|
1930
|
|
|
|
|
|
|
#$self->log( 'dev', 'where_body', 7, $search_str, $table , $ask); |
|
1931
|
0
|
0
|
0
|
|
|
|
$_ = join( |
|
1932
|
|
|
|
|
|
|
' OR ', |
|
1933
|
|
|
|
|
|
|
#map{ "$rq$_$rq LIKE $sl"} grep{ defined $self->{'table'}{$table}{$_}{'fulltext'}} keys %{ $self->{'table'}{$table} } |
|
1934
|
|
|
|
|
|
|
map { |
|
1935
|
0
|
0
|
0
|
|
|
|
"$rq$_$rq LIKE " |
|
1936
|
|
|
|
|
|
|
. $self->squotes( ( ( |
|
1937
|
|
|
|
|
|
|
!$self->{'no_slow'} |
|
1938
|
|
|
|
|
|
|
and $self->{'table'}{$table}{$_}{'like_bef'} |
|
1939
|
|
|
|
|
|
|
|| $self->{'table_param'}{$table}{'like_bef'} |
|
1940
|
|
|
|
|
|
|
|| $self->{'like_bef'} |
|
1941
|
|
|
|
|
|
|
) ? '%' : '' |
|
1942
|
|
|
|
|
|
|
) |
|
1943
|
|
|
|
|
|
|
. $search_str . '%' |
|
1944
|
|
|
|
|
|
|
) |
|
1945
|
|
|
|
|
|
|
} grep { |
|
1946
|
0
|
|
|
|
|
|
$self->{'table'}{$table}{$_}{'q'} || $self->{'table'}{$table}{$_}{'nav_field'} |
|
1947
|
|
|
|
|
|
|
and !$self->{'table'}{$table}{$_}{'q_skip'} |
|
1948
|
0
|
|
|
|
|
|
} keys %{ $self->{'table'}{$table} } |
|
1949
|
|
|
|
|
|
|
); |
|
1950
|
|
|
|
|
|
|
#$self->log( 'dev', 'where_body', 8, $_ , $ask); |
|
1951
|
0
|
0
|
|
|
|
|
$ask .= ' ( ' . $_ . ' ) ' if $_; |
|
1952
|
|
|
|
|
|
|
#$self->log( 'dev', 'where_body', 9, $search_str, $ask ); |
|
1953
|
|
|
|
|
|
|
} else { |
|
1954
|
|
|
|
|
|
|
#$self->log( 'dev', 'where_body', 10, $search_str ); |
|
1955
|
0
|
|
|
|
|
|
$ask .= $self->match( $param, $param_num, $table, $search_str, $search_str_stem ); |
|
1956
|
|
|
|
|
|
|
} |
|
1957
|
|
|
|
|
|
|
} |
|
1958
|
|
|
|
|
|
|
} |
|
1959
|
|
|
|
|
|
|
#$self->log( 'dev', 'ask1:', $ask); |
|
1960
|
|
|
|
|
|
|
#$ask = ( $local_cond > 1 ? ' ( ' : '' ) . $ask . ( $local_cond>1 ? ' ) ' : '' ); |
|
1961
|
0
|
0
|
0
|
|
|
|
if ( !$self->{'sphinx'} and $local_cond > 1 ) { $ask = ' ( ' . $ask . ' ) '; } |
|
|
0
|
|
|
|
|
|
|
|
1962
|
|
|
|
|
|
|
#$self->log( 'dev', 'ask2:', $ask); |
|
1963
|
0
|
0
|
0
|
|
|
|
$ask = $glueg . $ask if $after and $ask; |
|
1964
|
|
|
|
|
|
|
#$self->log( 'dev', 'ask3:', $ask); |
|
1965
|
|
|
|
|
|
|
#$self->log( 'dbg', $local_cond, ' lret: ', $ask . ( $ask and $close ? ' ) ' x $close : '' ), 'after=', $after, '$glueg', $glueg, $param->{'search_prev'}, ); |
|
1966
|
|
|
|
|
|
|
#"RET=[$ask]" |
|
1967
|
|
|
|
|
|
|
# |
|
1968
|
|
|
|
|
|
|
#. ( $ask and $close ? ' ) ' x $close : '' ) |
|
1969
|
|
|
|
|
|
|
#. $self->where_body( |
|
1970
|
|
|
|
|
|
|
#$param, $param_num + ( defined($param_num) ? 1 : ( $param->{'search_prev'} ? 0 : 1 ) ), |
|
1971
|
|
|
|
|
|
|
#$table, ( $ask ? 1 : 0 ) |
|
1972
|
|
|
|
|
|
|
#) |
|
1973
|
|
|
|
|
|
|
# |
|
1974
|
|
|
|
|
|
|
#); |
|
1975
|
|
|
|
|
|
|
return |
|
1976
|
0
|
0
|
0
|
|
|
|
$ask |
|
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
1977
|
|
|
|
|
|
|
. ( $ask and $close ? ' ) ' x $close : '' ) |
|
1978
|
|
|
|
|
|
|
. $self->where_body( $param, $param_num + ( defined($param_num) ? 1 : ( $param->{'search_prev'} ? 0 : 1 ) ), |
|
1979
|
|
|
|
|
|
|
$table, ( $ask ? 1 : 0 ) ); |
|
1980
|
0
|
|
0
|
|
|
|
}; |
|
1981
|
|
|
|
|
|
|
$self->{'where'} ||= sub { |
|
1982
|
|
|
|
|
|
|
#sub where { |
|
1983
|
0
|
|
|
0
|
|
|
my $self = shift; |
|
1984
|
0
|
|
|
|
|
|
my ( $param, undef, $table ) = @_; |
|
1985
|
|
|
|
|
|
|
#my $where = sql_where_body(@_); |
|
1986
|
0
|
|
|
|
|
|
$self->{'rec_stop'} = 0; |
|
1987
|
0
|
|
|
|
|
|
my $where = $self->where_body(@_); |
|
1988
|
|
|
|
|
|
|
#$self->log( 'dbg', "WHERE($table):[$where]", Dumper(\@_) , "$self->{'cp_in'} -> $self->{'codepage'} [extra=$self->{'table_param'}{$table}{'where_extra'}]"); |
|
1989
|
|
|
|
|
|
|
#return ' WHERE ' . scalar psmisc::cp_trans( $self->{'cp_in'}, $self->{'codepage'}, $where ) if $where; |
|
1990
|
0
|
0
|
|
|
|
|
if ( $self->{'table_param'}{$table}{'where_extra'} ) { |
|
1991
|
|
|
|
|
|
|
#$self->log( 'dbg','where_extra', $self->{'table_param'}{$table}{'where_extra'}); |
|
1992
|
0
|
0
|
|
|
|
|
$where .= (' AND ') if length $where; |
|
1993
|
0
|
|
|
|
|
|
$where .= $self->{'table_param'}{$table}{'where_extra'}; |
|
1994
|
|
|
|
|
|
|
} |
|
1995
|
0
|
0
|
|
|
|
|
return ' WHERE ' . $where if $where; |
|
1996
|
0
|
|
|
|
|
|
return undef; |
|
1997
|
0
|
|
0
|
|
|
|
}; |
|
1998
|
|
|
|
|
|
|
$self->{'count'} ||= sub { |
|
1999
|
|
|
|
|
|
|
#sub query_count { |
|
2000
|
0
|
|
|
0
|
|
|
my $self = shift; |
|
2001
|
0
|
|
|
|
|
|
my ( $param, $table ) = @_; |
|
2002
|
|
|
|
|
|
|
#my ( $tq, $rq, $vq ) = sql_quotes(); |
|
2003
|
0
|
|
|
|
|
|
$self->limit_calc( $self, $param, $table ); |
|
2004
|
|
|
|
|
|
|
return undef |
|
2005
|
0
|
0
|
0
|
|
|
|
if $self->{'query_count'}{$table}++ |
|
|
|
|
0
|
|
|
|
|
|
2006
|
|
|
|
|
|
|
or $self->{'ignore_index'} |
|
2007
|
|
|
|
|
|
|
or $self->{'table_param'}{$table}{'ignore_index'}; |
|
2008
|
0
|
|
|
|
|
|
my @ask; |
|
2009
|
0
|
0
|
|
|
|
|
$param->{'count_f'} = 'on' if $self->{'page'} eq 'rnd'; |
|
2010
|
0
|
0
|
|
|
|
|
push( @ask, ' COUNT(*) ' ) if $param->{'count_f'} eq 'on'; |
|
2011
|
0
|
|
|
|
|
|
push( @ask, " SUM($tq$table$tq.$rq$_$rq) " ) |
|
2012
|
0
|
|
0
|
|
|
|
for grep( |
|
2013
|
|
|
|
|
|
|
( ( $self->{'allow_count_all'} or $self->{'table'}{$table}{$_}{'allow_count'} ) and $param->{ 'count_' . $_ } eq 'on' ), |
|
2014
|
|
|
|
|
|
|
sort keys %{ $self->{'table'}{$table} } ); |
|
2015
|
0
|
0
|
|
|
|
|
if (@ask) { |
|
2016
|
0
|
|
|
|
|
|
my %tmp_para = %$param; |
|
2017
|
0
|
|
|
|
|
|
local $self->{'dbirows'}; |
|
2018
|
0
|
|
|
|
|
|
delete $tmp_para{'online'}; |
|
2019
|
0
|
|
|
|
|
|
my $where = $self->where( \%tmp_para, undef, $table ); |
|
2020
|
0
|
0
|
0
|
|
|
|
return unless $self->{'allow_null_count'} or $where; |
|
2021
|
0
|
|
|
|
|
|
my $from = join ' ', $tq . $self->{'table_prefix'} . $table . $tq, $self->join_what( undef, $param, $table ); |
|
2022
|
0
|
|
|
|
|
|
my $req = ' SELECT ' . join( ' , ', @ask ) . " FROM $from $where "; |
|
2023
|
0
|
|
|
|
|
|
psmisc::flush(); |
|
2024
|
|
|
|
|
|
|
#$self->log( 'dmp', 'query:[', @_, '] = ', scalar @hash, ' per', psmisc::human( 'time_period', $tim->() ), 'err=',$self->err() ); |
|
2025
|
0
|
|
|
|
|
|
@ask = values %{ $self->query($req)->[0] }; |
|
|
0
|
|
|
|
|
|
|
|
2026
|
|
|
|
|
|
|
#@ask = values %{ $self->line($req) }; |
|
2027
|
0
|
0
|
|
|
|
|
$self->{'stat'}{'found'}{'files'} = pop(@ask) if $param->{'count_f'} eq 'on'; |
|
2028
|
0
|
|
0
|
|
|
|
for ( |
|
2029
|
0
|
|
|
|
|
|
grep( ( $self->{'table'}{$table}{$_}{'allow_count'} and $param->{ 'count_' . $_ } eq 'on' ), |
|
2030
|
|
|
|
|
|
|
sort keys %{ $self->{'table'}{$table} } ) |
|
2031
|
|
|
|
|
|
|
) |
|
2032
|
|
|
|
|
|
|
{ |
|
2033
|
0
|
|
|
|
|
|
my $t = pop(@ask); |
|
2034
|
0
|
0
|
|
|
|
|
$self->{'stat'}{'found'}{$_} = $t if $t; |
|
2035
|
|
|
|
|
|
|
} |
|
2036
|
|
|
|
|
|
|
} |
|
2037
|
0
|
|
|
|
|
|
$self->{'calc_count'}->( $self, $param, $table ); |
|
2038
|
0
|
|
|
|
|
|
return undef; |
|
2039
|
0
|
|
0
|
|
|
|
}; |
|
2040
|
|
|
|
|
|
|
$self->{'can_select'} ||= sub { |
|
2041
|
0
|
|
|
0
|
|
|
my $self = shift; |
|
2042
|
0
|
|
|
|
|
|
my ( $param, $table, ) = @_; |
|
2043
|
0
|
|
|
|
|
|
my $where = $self->where( $param, undef, $table ); |
|
2044
|
0
|
0
|
|
|
|
|
return $where if $where; |
|
2045
|
0
|
0
|
0
|
|
|
|
return '0E0' if $self->{'use_sphinx'} and $self->{'sphinx_dbi'} and length $param->{'q'}; |
|
|
|
|
0
|
|
|
|
|
|
2046
|
0
|
|
0
|
|
|
|
}; |
|
2047
|
|
|
|
|
|
|
$self->{'select'} ||= sub { |
|
2048
|
0
|
|
|
0
|
|
|
my $self = shift; |
|
2049
|
0
|
|
|
|
|
|
my ( $table, $param, $opt ) = @_; |
|
2050
|
0
|
|
0
|
|
|
|
$opt ||= {}; |
|
2051
|
0
|
|
|
|
|
|
$self->{'current_table'} = $table; |
|
2052
|
|
|
|
|
|
|
#$self->log( 'dbg', "SELECTR[$self->{'sphinx'}]", ,Dumper($param)); |
|
2053
|
|
|
|
|
|
|
#$self->log( 'dbg', "$self->{'cp_in'} -> $self->{'codepage'}"); |
|
2054
|
|
|
|
|
|
|
#return ' WHERE ' . scalar psmisc::cp_trans( $self->{'cp_in'}, $self->{'codepage'}, $where ) if $where; |
|
2055
|
|
|
|
|
|
|
#$self->log( 'dbg', 'q1', scalar psmisc::cp_trans( $self->{'cp_in'}, $self->{'codepage'}, $self->select_body( $self->where($param), $param, $table ) )); |
|
2056
|
|
|
|
|
|
|
#$self->log( 'dbg', 'q2', $self->select_body( $self->where($param, undef, $table), $param, $table ) ); |
|
2057
|
|
|
|
|
|
|
#$self->log( 'dbg', 'q3', $self->where($param)); |
|
2058
|
0
|
|
|
|
|
|
my $select; |
|
2059
|
0
|
|
|
|
|
|
my $ids = []; |
|
2060
|
0
|
|
|
|
|
|
my $idsh = {}; |
|
2061
|
0
|
|
|
|
|
|
my %id; |
|
2062
|
0
|
|
|
|
|
|
my $ret = []; |
|
2063
|
0
|
|
|
|
|
|
$self->{'founded_max'} = $self->{'dbirows'} = 0; |
|
2064
|
|
|
|
|
|
|
#my ($fail_q, $fail_n); |
|
2065
|
0
|
|
|
|
|
|
my @fail; |
|
2066
|
|
|
|
|
|
|
my @selects; |
|
2067
|
0
|
|
|
|
|
|
my $file_fallback; |
|
2068
|
0
|
|
|
|
|
|
my $n; |
|
2069
|
|
|
|
|
|
|
my $post_process = sub ($) { |
|
2070
|
0
|
|
|
|
|
|
my ($ret) = @_; |
|
2071
|
0
|
|
|
|
|
|
for my $r (@$ret) { |
|
2072
|
0
|
0
|
0
|
|
|
|
$r->{$_} ||= $idsh->{ $r->{'id'} }{$_} for keys %{ $idsh->{ $r->{'id'} } || {} }; |
|
|
0
|
|
|
|
|
|
|
|
2073
|
|
|
|
|
|
|
#$self->log( 'dev123', Dumper $r, ); |
|
2074
|
|
|
|
|
|
|
} |
|
2075
|
0
|
|
|
|
|
|
@$ret = sort { $idsh->{ $a->{'id'} }{'n'} <=> $idsh->{ $b->{'id'} }{'n'} } @$ret; |
|
|
0
|
|
|
|
|
|
|
|
2076
|
|
|
|
|
|
|
#@$ret = sort { $ids{ $a->{'weight'} } <=> $ids{ $b->{'weight'} } } @$ret; |
|
2077
|
|
|
|
|
|
|
#$self->log( 'dev124', Dumper $ret ); |
|
2078
|
|
|
|
|
|
|
#$self->log( 'devFail', Dumper \@fail); |
|
2079
|
0
|
|
|
|
|
|
for (@fail) { |
|
2080
|
0
|
0
|
|
|
|
|
next if scalar @$ret < $_->{'n'}; |
|
2081
|
0
|
|
|
|
|
|
$ret->[ $_->{'n'} ]{'__fulltext_fail'} = $_->{'q'}; |
|
2082
|
|
|
|
|
|
|
#$self->log( 'setFail', $_->{'n'}); |
|
2083
|
|
|
|
|
|
|
} |
|
2084
|
0
|
|
|
|
|
|
@fail = (); |
|
2085
|
0
|
|
|
|
|
|
}; |
|
2086
|
|
|
|
|
|
|
my $do_select = sub { |
|
2087
|
|
|
|
|
|
|
#my ($s, $ids) = @_; |
|
2088
|
|
|
|
|
|
|
#$self->log('do_select', Dumper \@_); |
|
2089
|
|
|
|
|
|
|
# $self->log('devids', Dumper $ids); |
|
2090
|
0
|
|
|
|
|
|
my $count; |
|
2091
|
0
|
|
|
|
|
|
for my $s (@_) { |
|
2092
|
|
|
|
|
|
|
#my ( $select, $ids ); |
|
2093
|
0
|
|
|
|
|
|
my ($select); |
|
2094
|
|
|
|
|
|
|
#( $select, $ids ) = $s->() if psmisc::is_code $s; |
|
2095
|
0
|
|
|
|
|
|
my ( $count_add, $idst ); |
|
2096
|
0
|
0
|
|
|
|
|
( $select, $idst, $count_add ) = $s->() if psmisc::is_code $s; |
|
2097
|
0
|
0
|
|
|
|
|
if ( psmisc::is_array_size $idst) { |
|
2098
|
0
|
|
|
|
|
|
$ids = $idst; |
|
2099
|
|
|
|
|
|
|
#$self->log('do_select', $count_add, $self->{'limit_offset'}, $self->{'sphinx_dbi'}{'limit_offset'}); |
|
2100
|
0
|
|
0
|
|
|
|
my $nn = $self->{'sphinx_dbi'}{'limit_offset'} || $self->{'limit_offset'}; |
|
2101
|
0
|
|
0
|
|
|
|
$idsh = { map { $_->{'n'} //= ++$nn; $_->{'id'} => $_ } @$ids }; |
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
2102
|
|
|
|
|
|
|
} |
|
2103
|
0
|
|
|
|
|
|
$count += $count_add; |
|
2104
|
0
|
0
|
|
|
|
|
( $select, ) = $s if psmisc::is_hash $s; |
|
2105
|
0
|
|
|
|
|
|
local $self->{'limit_body'} = sub { } |
|
2106
|
0
|
0
|
|
|
|
|
if psmisc::is_array_size $ids; |
|
2107
|
|
|
|
|
|
|
#$self->log('select extracted:', $s, $select, Dumper $param); |
|
2108
|
|
|
|
|
|
|
#my $idsh = {}; |
|
2109
|
0
|
0
|
|
|
|
|
if ( psmisc::is_hash($select) ) { |
|
2110
|
0
|
|
|
|
|
|
for my $s ( sort { $select->{$a} <=> $select->{$b} } keys %$select ) { |
|
|
0
|
|
|
|
|
|
|
|
2111
|
|
|
|
|
|
|
#$self->log('r', $s, ':', Dumper $select->{$s}); |
|
2112
|
0
|
|
|
|
|
|
my $r; |
|
2113
|
|
|
|
|
|
|
#sleep 2; |
|
2114
|
0
|
0
|
|
|
|
|
$r = |
|
2115
|
|
|
|
|
|
|
$self->{'shard_dbis'}{ $select->{$s} } |
|
2116
|
|
|
|
|
|
|
->query( scalar psmisc::cp_trans( $self->{'cp_in'}, $self->{'codepage'}, $self->select_body( $s, $param ) ) ) |
|
2117
|
|
|
|
|
|
|
if $s; |
|
2118
|
0
|
0
|
|
|
|
|
next unless $r; |
|
2119
|
|
|
|
|
|
|
# map { |
|
2120
|
|
|
|
|
|
|
#$self->log('r1', Dumper $idsh->{$_->{id}}); |
|
2121
|
|
|
|
|
|
|
# $_->{id} //= psmisc::join_url($_) } @$r; #unless $self->{'use_sphinx'}; |
|
2122
|
0
|
|
|
|
|
|
for my $l (@$r) { |
|
2123
|
|
|
|
|
|
|
#$self->log('r1',$l, $idsh->{$l->{id}}); |
|
2124
|
|
|
|
|
|
|
#$l->{$_} ||= $idsh->{$l->{id}}{$_} for keys %{$idsh->{$l->{id}} || {}}; |
|
2125
|
0
|
|
0
|
|
|
|
$l->{id} //= psmisc::join_url($l); |
|
2126
|
|
|
|
|
|
|
} |
|
2127
|
|
|
|
|
|
|
#$self->log('r1', Dumper $r); |
|
2128
|
0
|
|
|
|
|
|
$r = [ grep { !$id{ $_->{id} }++ } @$r ]; |
|
|
0
|
|
|
|
|
|
|
|
2129
|
0
|
|
|
|
|
|
$post_process->($r); |
|
2130
|
|
|
|
|
|
|
# @$r = sort { $idsh->{ $a->{'id'} }{'n'} <=> $idsh->{ $b->{'id'} }{'n'} } @$r; |
|
2131
|
|
|
|
|
|
|
# for (@fail) {next if scalar @$r < $_->{'n'}; |
|
2132
|
|
|
|
|
|
|
# $r->[ $_->{'n'} ]{'__fulltext_fail'} = $_->{'q'} |
|
2133
|
|
|
|
|
|
|
#} |
|
2134
|
0
|
|
|
|
|
|
$count += scalar @$r; |
|
2135
|
0
|
0
|
|
|
|
|
$opt->{row}->(@$r), psmisc::code_run( $opt->{flush} ), |
|
2136
|
|
|
|
|
|
|
#$self->log('flush!'), |
|
2137
|
|
|
|
|
|
|
next if psmisc::is_code $opt->{row}; |
|
2138
|
0
|
|
|
|
|
|
push @$ret, @$r; |
|
2139
|
|
|
|
|
|
|
} |
|
2140
|
|
|
|
|
|
|
} else { |
|
2141
|
0
|
|
|
|
|
|
for my $select ( psmisc::array $select) { #select from sphinx |
|
2142
|
0
|
|
|
|
|
|
my $r; |
|
2143
|
|
|
|
|
|
|
#sleep 2; |
|
2144
|
0
|
0
|
|
|
|
|
$r = $self->query( |
|
2145
|
|
|
|
|
|
|
scalar psmisc::cp_trans( $self->{'cp_in'}, $self->{'codepage'}, $self->select_body( $select, $param ) ) ) |
|
2146
|
|
|
|
|
|
|
if $select; |
|
2147
|
0
|
0
|
|
|
|
|
next unless $r; |
|
2148
|
|
|
|
|
|
|
#$self->log('SSSs', "sp[$self->{'use_sphinx'}]"); |
|
2149
|
0
|
|
0
|
|
|
|
map { $_->{id} //= psmisc::join_url($_) } @$r; # unless $self->{'use_sphinx'}; |
|
|
0
|
|
|
|
|
|
|
|
2150
|
0
|
|
|
|
|
|
$r = [ grep { !$id{ $_->{id} }++ } @$r ]; |
|
|
0
|
|
|
|
|
|
|
|
2151
|
|
|
|
|
|
|
#my %already = map { $_->{'id'} => 1 } @$ret; |
|
2152
|
|
|
|
|
|
|
#$self->log('SSSs', Dumper $r); |
|
2153
|
|
|
|
|
|
|
#$self->log('SSSsRRb', Dumper $ret); |
|
2154
|
|
|
|
|
|
|
#$self->log('SSSsRRbr', Dumper $r); |
|
2155
|
|
|
|
|
|
|
#push @fail, { 'n' => scalar @$ids, 'q' => $param->{'q'} } if $n ; |
|
2156
|
|
|
|
|
|
|
#$self->log('SSSsid5', Dumper \%id); |
|
2157
|
|
|
|
|
|
|
#$ret += scalar @$r; |
|
2158
|
0
|
|
|
|
|
|
$count += scalar @$r; |
|
2159
|
0
|
|
|
|
|
|
push @$ret, @$r; |
|
2160
|
|
|
|
|
|
|
#$self->log('SSSsRRa', Dumper $ret); |
|
2161
|
|
|
|
|
|
|
#$self->log('SSSsid6', Dumper \%id); |
|
2162
|
|
|
|
|
|
|
#++$id{$_->{id}} for @$r; |
|
2163
|
|
|
|
|
|
|
#push @$ids, grep { !$already{ $_->{id} } } @$r; |
|
2164
|
|
|
|
|
|
|
#$self->log('SS', scalar @$ret , 'L', $self->{'limit'}, map { $_->{'id'} } @$r); |
|
2165
|
|
|
|
|
|
|
} |
|
2166
|
|
|
|
|
|
|
} |
|
2167
|
|
|
|
|
|
|
#$self->log('cnts:', $count, scalar @$ret , $self->{'limit'}); |
|
2168
|
|
|
|
|
|
|
#last if @$ret >= $self->{'limit'}; |
|
2169
|
0
|
0
|
|
|
|
|
last if $count >= $self->{'limit'}; |
|
2170
|
|
|
|
|
|
|
} continue { |
|
2171
|
0
|
|
|
|
|
|
++$n; |
|
2172
|
|
|
|
|
|
|
#$self->log('continue', $n); |
|
2173
|
|
|
|
|
|
|
} |
|
2174
|
0
|
|
|
|
|
|
return $count; |
|
2175
|
0
|
|
|
|
|
|
}; |
|
2176
|
|
|
|
|
|
|
push @selects, sub { # try LIKE by name |
|
2177
|
|
|
|
|
|
|
# $self->log( 'dbg', 'selectrun', __LINE__); |
|
2178
|
0
|
|
|
|
|
|
my $ask; |
|
2179
|
0
|
|
|
|
|
|
my $search_str = $param->{'q'}; |
|
2180
|
0
|
0
|
|
|
|
|
if ( my %tparam = $self->q_file( $table, $search_str ) ) { |
|
2181
|
|
|
|
|
|
|
#$self->log( 'qf', %tparam ); |
|
2182
|
|
|
|
|
|
|
#$search_str =~ /^\s*(\S+)\.+(\S+)\s*$/ and $self->{'table'}{$table}{'name'} and $self->{'table'}{$table}{'ext'} ) { |
|
2183
|
|
|
|
|
|
|
#my %tparam = ( 'name' => $1, 'ext' => $2 ); |
|
2184
|
0
|
|
|
|
|
|
$ask .= ' ( ' . $self->where_body( \%tparam, undef, $table ) . ' ) '; |
|
2185
|
|
|
|
|
|
|
} |
|
2186
|
|
|
|
|
|
|
#$self->log('S1', $ask); |
|
2187
|
|
|
|
|
|
|
#$file_fallback = 1, return ' WHERE ' . $ask if $ask; |
|
2188
|
|
|
|
|
|
|
} |
|
2189
|
0
|
0
|
0
|
|
|
|
if $self->{'use_q_file_fallback'} and !$self->{'sphinx'}; |
|
2190
|
|
|
|
|
|
|
push @selects, sub { |
|
2191
|
|
|
|
|
|
|
# $self->log( 'dbg', 'selectrun', __LINE__); |
|
2192
|
|
|
|
|
|
|
#$self->log( 'dbg', 'selectrun2 sph'); |
|
2193
|
0
|
|
|
|
|
|
my $ids = []; |
|
2194
|
0
|
|
|
|
|
|
my %id; |
|
2195
|
0
|
0
|
0
|
|
|
|
if ( $self->{'use_sphinx'} |
|
|
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
2196
|
|
|
|
|
|
|
and $self->{'sphinx_dbi'} |
|
2197
|
|
|
|
|
|
|
and length $param->{'q'} |
|
2198
|
|
|
|
|
|
|
and ( $file_fallback or !$self->q_file( $table, $param->{'q'} ) ) ) |
|
2199
|
|
|
|
|
|
|
{ |
|
2200
|
|
|
|
|
|
|
#$self->log( 'dbg', 'selectin', __LINE__); |
|
2201
|
0
|
|
|
|
|
|
( $tq, $rq, $vq ) = $self->quotes(); |
|
2202
|
0
|
0
|
|
|
|
|
local $self->{'sphinx_dbi'}->{'option'}{'max_query_time'} = 2000 if $config{'client_bot'}; |
|
2203
|
|
|
|
|
|
|
# my %already = map { $_->{'id'} => 1 } @$ids, @$ret; |
|
2204
|
0
|
|
|
|
|
|
my $idsl = []; |
|
2205
|
|
|
|
|
|
|
# $self->log('SSSsid1', Dumper \%id); |
|
2206
|
0
|
|
|
|
|
|
push @$idsl, grep { !$id{ $_->{id} }++ } @{ $self->{'sphinx_dbi'}->select( $table, $param ) }; |
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
2207
|
|
|
|
|
|
|
# $self->log('SSSsid2', Dumper \%id); |
|
2208
|
|
|
|
|
|
|
#my $ids = $self->{'sphinx_dbi'}->select( $table, $param ); |
|
2209
|
|
|
|
|
|
|
#++$id{$_->{id}} for @$ids; |
|
2210
|
0
|
|
|
|
|
|
$self->{'founded_max'} = $self->{'sphinx_dbi'}{'option'}{'cutoff'}; |
|
2211
|
|
|
|
|
|
|
#$self->log ('d1', "fmax", $self->{'founded_max'}, Dumper $ids,$idsl); |
|
2212
|
|
|
|
|
|
|
# $self->log ('cnt',scalar @$ids , scalar @$idsl , $self->{'limit'}); |
|
2213
|
0
|
0
|
|
|
|
|
if ( |
|
2214
|
|
|
|
|
|
|
( @$ids + @$idsl < $self->{'limit'} ) #and (!$self->{'use_sphinx'} or !$config{'client_bot'}) |
|
2215
|
|
|
|
|
|
|
) |
|
2216
|
|
|
|
|
|
|
{ |
|
2217
|
|
|
|
|
|
|
#warn "limit[]" |
|
2218
|
|
|
|
|
|
|
# $self->log( 'dbg','q', $param->{'q'}); |
|
2219
|
|
|
|
|
|
|
#local $self->{'sphinx_dbi'}->{'select_append'} = ' OPTION ranker=wordcount '; |
|
2220
|
0
|
0
|
|
|
|
|
++$work{'fulltext_fail'} unless @$ids; |
|
2221
|
0
|
|
|
|
|
|
local $param->{'q'} = $param->{'q'}; |
|
2222
|
0
|
0
|
|
|
|
|
for my $func ( sub { $_[0] =~ s/^\s*"\s*// and $_[0] =~ s/\s*"\s*$// }, sub { $_[0] =~ s/(\w\s+)(\w)/$1 | $2/g }, ) { |
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
2223
|
0
|
0
|
|
|
|
|
if ( $func->( $param->{'q'} ) ) { |
|
2224
|
0
|
|
|
|
|
|
local $param->{'no_querystat'} = 1; |
|
2225
|
|
|
|
|
|
|
#$self->log( 'idn', scalar @$ids, scalar @$idsl ); |
|
2226
|
|
|
|
|
|
|
#my %already = map { $_->{'id'} => 1 } @$ids, @$ret; |
|
2227
|
0
|
|
|
|
|
|
local $self->{'sphinx_dbi'}{'limit_minus'} = scalar @$idsl; |
|
2228
|
0
|
|
|
|
|
|
local $self->{'sphinx_dbi'}{'limit_offset'}; |
|
2229
|
0
|
0
|
|
|
|
|
local $self->{'sphinx_dbi'}{'page'} = 0 if $self->{'sphinx_dbi'}{'limit_minus'}; |
|
2230
|
0
|
|
|
|
|
|
my $ids_add = $self->{'sphinx_dbi'}->select( $table, $param ); |
|
2231
|
0
|
|
|
|
|
|
$self->{'founded_max'} = $self->{'sphinx_dbi'}{'option'}{'cutoff'}; |
|
2232
|
|
|
|
|
|
|
#TODO: info about changed query |
|
2233
|
|
|
|
|
|
|
#$self->log('dev', "setfail $#$ids:$ids->[$#$ids]{id};"), |
|
2234
|
|
|
|
|
|
|
#$self->log('dev', "setfail ", scalar @$ids, scalar @$idsl , scalar @$ids_add), |
|
2235
|
0
|
0
|
|
|
|
|
push @fail, { 'n' => scalar @$ids + scalar @$idsl, 'q' => $param->{'q'} } if @$ids_add; |
|
2236
|
0
|
0
|
|
|
|
|
unless (@$ids_add) { ++$work{'fulltext_fail_or'}; } |
|
|
0
|
|
|
|
|
|
|
|
2237
|
|
|
|
|
|
|
#$self->log('SSSsid3', Dumper \%id, $ids_add); |
|
2238
|
0
|
|
|
|
|
|
push @$idsl, grep { !$id{ $_->{id} }++ } @$ids_add; |
|
|
0
|
|
|
|
|
|
|
|
2239
|
|
|
|
|
|
|
#$self->log('SSSsid4', Dumper \%id, $idsl); |
|
2240
|
|
|
|
|
|
|
#++$id{$_->{id}} for @$ids_add; |
|
2241
|
|
|
|
|
|
|
} |
|
2242
|
0
|
0
|
|
|
|
|
last if @$ids + @$idsl >= $self->{'limit'}; |
|
2243
|
|
|
|
|
|
|
} |
|
2244
|
|
|
|
|
|
|
} |
|
2245
|
|
|
|
|
|
|
#psmisc::dmp ('dbiSmin', $self->{'sphinx_dbi'}{'limit_minus'}); |
|
2246
|
|
|
|
|
|
|
#psmisc::dmp ('dbiSoff', $self->{'sphinx_dbi'}{'limit_offset'}); |
|
2247
|
|
|
|
|
|
|
#psmisc::dmp ('dbimin', $self->{'limit_minus'}); |
|
2248
|
|
|
|
|
|
|
#psmisc::dmp ('dbioff', $self->{'limit_offset'}); |
|
2249
|
0
|
0
|
|
|
|
|
if (@$idsl) { |
|
2250
|
|
|
|
|
|
|
# $self->log(__LINE__, 'prep idsl'); |
|
2251
|
|
|
|
|
|
|
my $wheregen = sub { |
|
2252
|
0
|
|
|
|
|
|
@_ = psmisc::array @_; |
|
2253
|
|
|
|
|
|
|
# $self->log('dmp','wheregen', Dumper \@_); |
|
2254
|
0
|
0
|
|
|
|
|
return " WHERE ${rq}id${rq} IN (" . ( join ',', map { $_->{'id'} } @_ ) . ')' if @_; |
|
|
0
|
|
|
|
|
|
|
|
2255
|
|
|
|
|
|
|
#(); |
|
2256
|
0
|
|
|
|
|
|
}; |
|
2257
|
|
|
|
|
|
|
#$self->log('joining',$select, 'sh=', $self->{'shard'}, Dumper $ids, $idsl); |
|
2258
|
0
|
0
|
0
|
|
|
|
if ( !$self->{'sphinx'} and $self->{'shard'} ) { |
|
2259
|
|
|
|
|
|
|
# $self->log('shard',keys %{$self->{'shard_dbis'}} ); |
|
2260
|
0
|
|
|
|
|
|
my %ids; |
|
2261
|
0
|
|
|
|
|
|
for my $r (@$idsl) { |
|
2262
|
0
|
|
|
|
|
|
for my $from ( reverse sort keys %{ $self->{'shard_dbis'} } ) { |
|
|
0
|
|
|
|
|
|
|
|
2263
|
|
|
|
|
|
|
#$self->log('shardC',$from, $self->{'shard_dbis'}{$from}{database}, $self->{'shard_dbis'}{$from}{dbname}); |
|
2264
|
|
|
|
|
|
|
# $self->log('shardC',$from, $r); |
|
2265
|
0
|
0
|
|
|
|
|
if ( $r->{id} >= $from ) { |
|
2266
|
0
|
|
0
|
|
|
|
push @{ $ids{$from} ||= [] }, $r; |
|
|
0
|
|
|
|
|
|
|
|
2267
|
0
|
|
|
|
|
|
last; |
|
2268
|
|
|
|
|
|
|
} |
|
2269
|
|
|
|
|
|
|
} |
|
2270
|
|
|
|
|
|
|
} |
|
2271
|
|
|
|
|
|
|
#$self->log('sh', Dumper \%ids); |
|
2272
|
0
|
|
|
|
|
|
$select = {}; |
|
2273
|
0
|
|
|
|
|
|
for my $from ( keys %{ $self->{'shard_dbis'} } ) { |
|
|
0
|
|
|
|
|
|
|
|
2274
|
0
|
|
0
|
|
|
|
my $w = $ids{$from} || next; |
|
2275
|
0
|
|
|
|
|
|
$select->{ $wheregen->($w) } = $from; #scalar @{$ids{$from}}; |
|
2276
|
|
|
|
|
|
|
#$self->log('sh22', $from, $ids{$from}); |
|
2277
|
|
|
|
|
|
|
} |
|
2278
|
|
|
|
|
|
|
#$self->log('sh22', Dumper $select,); |
|
2279
|
|
|
|
|
|
|
} else { |
|
2280
|
|
|
|
|
|
|
# $self->log('wgen', Dumper $select,); |
|
2281
|
0
|
|
|
|
|
|
$select = $wheregen->($idsl); |
|
2282
|
|
|
|
|
|
|
# $self->log('simple', Dumper $select,); |
|
2283
|
|
|
|
|
|
|
} |
|
2284
|
0
|
|
|
|
|
|
push @$ids, @$idsl; |
|
2285
|
|
|
|
|
|
|
} |
|
2286
|
|
|
|
|
|
|
} |
|
2287
|
0
|
|
|
|
|
|
local $self->{'limit_body'} = sub { } |
|
2288
|
0
|
0
|
|
|
|
|
if @$ids; |
|
2289
|
0
|
|
|
|
|
|
( $tq, $rq, $vq ) = $self->quotes(); |
|
2290
|
|
|
|
|
|
|
#unless ($select) { |
|
2291
|
|
|
|
|
|
|
#local $self->{'table'}{$table}{$table}{'ext'}{'nav_field'} = 0; |
|
2292
|
|
|
|
|
|
|
#local $self->{'table'}{$table}{'ext'}{'q_skip'} = 1; |
|
2293
|
|
|
|
|
|
|
# $self->log( 'dev', "!$select and !$config{'client_bot'} and sp!$self->{'use_sphinx'}"); |
|
2294
|
0
|
|
|
|
|
|
my $count; |
|
2295
|
0
|
0
|
0
|
|
|
|
if ( !$select and ( !$self->{'use_sphinx'} or !$config{'client_bot'} ) ) { |
|
|
|
|
0
|
|
|
|
|
|
2296
|
0
|
0
|
0
|
|
|
|
if ( !$self->{'use_sphinx'} or !$self->{'no_sphinx_like'} ) { |
|
2297
|
|
|
|
|
|
|
#$select = $self->where( $param, undef, $table ); |
|
2298
|
|
|
|
|
|
|
# $self->log( 'dev', "!$select and !$config{'client_bot'}"); |
|
2299
|
|
|
|
|
|
|
#$self->log( 'dbg', 'selectshrd', __LINE__); |
|
2300
|
0
|
0
|
0
|
|
|
|
if ( !$self->{'sphinx'} and $self->{'shard'} ) { |
|
2301
|
|
|
|
|
|
|
# $self->log('shard',keys %{$self->{'shard_dbis'}} ); |
|
2302
|
|
|
|
|
|
|
#$self->log('sh', Dumper \%ids); |
|
2303
|
|
|
|
|
|
|
#$select = {}; |
|
2304
|
0
|
|
|
|
|
|
for my $from ( sort keys %{ $self->{'shard_dbis'} } ) { |
|
|
0
|
|
|
|
|
|
|
|
2305
|
|
|
|
|
|
|
#my $w = $ids{$from} || next; |
|
2306
|
|
|
|
|
|
|
#$select->{ $wheregen->( $w ) } = $from; #scalar @{$ids{$from}}; |
|
2307
|
|
|
|
|
|
|
#local $self->{limit} = $self->{limit} - $count; |
|
2308
|
0
|
0
|
|
|
|
|
local $self->{'limit_from'} = $self->{'limit_offset'} + $count if $count; |
|
2309
|
0
|
|
|
|
|
|
local $self->{'limit_minus'} = $count; |
|
2310
|
|
|
|
|
|
|
# $self->log( 'limi', $from, $count, $self->{limit}, $self->{'limit_offset'}, $self->{'limit_from'}, $self->{'limit_minus'} ); |
|
2311
|
0
|
|
|
|
|
|
$select = {}; |
|
2312
|
0
|
|
|
|
|
|
$select->{ "/* $from */" . $self->where( $param, undef, $table ) } = $from; |
|
2313
|
|
|
|
|
|
|
#$do_select->($select, $ids); |
|
2314
|
0
|
|
|
|
|
|
$count += $do_select->($select); |
|
2315
|
|
|
|
|
|
|
#$self->log('shard lst', $from, $count, $self->{limit}); |
|
2316
|
0
|
|
|
|
|
|
$select = undef; |
|
2317
|
0
|
0
|
|
|
|
|
last if $count >= $self->{limit}; |
|
2318
|
|
|
|
|
|
|
#$self->log('shard after', $from, $count); |
|
2319
|
|
|
|
|
|
|
} |
|
2320
|
|
|
|
|
|
|
#$self->log( 'sh22', Dumper $param, $self->{limit} ); |
|
2321
|
|
|
|
|
|
|
} else { |
|
2322
|
|
|
|
|
|
|
# $self->log( 'noshard',); |
|
2323
|
0
|
|
|
|
|
|
$select = $self->where( $param, undef, $table ); |
|
2324
|
|
|
|
|
|
|
} |
|
2325
|
|
|
|
|
|
|
} |
|
2326
|
0
|
|
|
|
|
|
$self->{'founded_max'} = 0; |
|
2327
|
|
|
|
|
|
|
} |
|
2328
|
|
|
|
|
|
|
#$self->log( 'S2', $select, Dumper \%id); |
|
2329
|
|
|
|
|
|
|
#$self->log( 'S2', $select, Dumper $ids); |
|
2330
|
0
|
|
|
|
|
|
return $select, $ids, $count; |
|
2331
|
0
|
|
|
|
|
|
}; |
|
2332
|
|
|
|
|
|
|
#push @selects, $select if $select; |
|
2333
|
|
|
|
|
|
|
#} |
|
2334
|
|
|
|
|
|
|
#$self->log('devpredoselect',Dumper \@selects); |
|
2335
|
0
|
|
|
|
|
|
my $count = $do_select->(@selects); |
|
2336
|
|
|
|
|
|
|
#{'use_q_file_fallback'} |
|
2337
|
|
|
|
|
|
|
#if (@$ids) { |
|
2338
|
|
|
|
|
|
|
#my %byid = map { $_->{id} => $_ } @$ret; |
|
2339
|
|
|
|
|
|
|
#for my $s (@$ids) { $byid{ $s->{id} }{$_} //= $s->{$_} for keys %$s; } |
|
2340
|
|
|
|
|
|
|
#$self->log('devret', Dumper $ret); |
|
2341
|
|
|
|
|
|
|
#$self->log('dev1', "sph[$self->{'use_sphinx'}]", Dumper $ids); |
|
2342
|
0
|
0
|
0
|
|
|
|
if ( $self->{'use_sphinx'} and @$ids ) { |
|
2343
|
0
|
|
|
|
|
|
my $n = 0; |
|
2344
|
|
|
|
|
|
|
#my %ids = map { $_->{'id'} => ++$n } @$ids; |
|
2345
|
|
|
|
|
|
|
#my %ids = map {$_->{'n'} = ++$n; $_->{'id'} => $_ } @$ids; |
|
2346
|
|
|
|
|
|
|
#$self->log( 'dev123', map { $_->{'id'} } @$ret); |
|
2347
|
|
|
|
|
|
|
#$self->log( 'dev123', Dumper \%ids ); |
|
2348
|
|
|
|
|
|
|
#$self->log( 'dev123', Dumper $ids ); |
|
2349
|
|
|
|
|
|
|
#$self->log( 'dev123r', Dumper $ret ); |
|
2350
|
0
|
|
|
|
|
|
$post_process->($ret); |
|
2351
|
|
|
|
|
|
|
|
|
2352
|
|
|
|
|
|
|
=no |
|
2353
|
|
|
|
|
|
|
for my $r (@$ret) { |
|
2354
|
|
|
|
|
|
|
$r->{$_} ||= $idsh->{$r->{'id'}}{$_} for keys %{$idsh->{$r->{'id'}}||{}}; |
|
2355
|
|
|
|
|
|
|
#$self->log( 'dev123', Dumper $r, ); |
|
2356
|
|
|
|
|
|
|
|
|
2357
|
|
|
|
|
|
|
} |
|
2358
|
|
|
|
|
|
|
@$ret = sort { $ids{ $a->{'id'} }{'n'} <=> $ids{ $b->{'id'} }{'n'} } @$ret; |
|
2359
|
|
|
|
|
|
|
#@$ret = sort { $ids{ $a->{'weight'} } <=> $ids{ $b->{'weight'} } } @$ret; |
|
2360
|
|
|
|
|
|
|
#$self->log( 'dev124', Dumper $ret ); |
|
2361
|
|
|
|
|
|
|
#$self->log( 'devFail', Dumper \@fail); |
|
2362
|
|
|
|
|
|
|
for (@fail) { |
|
2363
|
|
|
|
|
|
|
next if scalar @$ret < $_->{'n'}; |
|
2364
|
|
|
|
|
|
|
$ret->[ $_->{'n'} ]{'__fulltext_fail'} = $_->{'q'} |
|
2365
|
|
|
|
|
|
|
} |
|
2366
|
|
|
|
|
|
|
=cut |
|
2367
|
|
|
|
|
|
|
|
|
2368
|
|
|
|
|
|
|
} |
|
2369
|
|
|
|
|
|
|
#$self->log( 'devFIN', $self->{'dbirows'}, $count, Dumper $ret ); |
|
2370
|
|
|
|
|
|
|
#} |
|
2371
|
|
|
|
|
|
|
#$self->log( 'fnd', "$self->{'founded'}, $self->{'dbirows'},$count;" ); |
|
2372
|
|
|
|
|
|
|
#$self->log( 'devFIN', $self->{'dbirows'}, $count, Dumper $param ); |
|
2373
|
0
|
|
0
|
|
|
|
$self->{'dbirows'} ||= $count; |
|
2374
|
0
|
0
|
|
|
|
|
return wantarray ? @$ret : $ret; |
|
2375
|
0
|
|
0
|
|
|
|
}; |
|
2376
|
|
|
|
|
|
|
$self->{'select_log'} ||= sub { |
|
2377
|
0
|
|
|
0
|
|
|
my $self = shift; |
|
2378
|
0
|
|
|
|
|
|
my ( $table, $param, ) = @_; |
|
2379
|
0
|
|
|
|
|
|
return $self->query_log( $self->select_body( $self->where( $param, undef, $table ), $param, $table ) ); |
|
2380
|
0
|
|
0
|
|
|
|
}; |
|
2381
|
|
|
|
|
|
|
$self->{'join_what'} ||= sub { |
|
2382
|
|
|
|
|
|
|
#sub select { |
|
2383
|
0
|
|
|
0
|
|
|
my $self = shift; |
|
2384
|
0
|
|
|
|
|
|
my ( $where, $param, $table ) = @_; |
|
2385
|
0
|
|
0
|
|
|
|
$table ||= $self->{'current_table'}; |
|
2386
|
0
|
|
|
|
|
|
my @join; |
|
2387
|
|
|
|
|
|
|
#=dev |
|
2388
|
0
|
|
|
|
|
|
for my $jt ( keys %{ $self->{'table_join'}{$table} } ) { |
|
|
0
|
|
|
|
|
|
|
|
2389
|
0
|
0
|
|
|
|
|
local @_ = ( #( |
|
2390
|
|
|
|
|
|
|
#map { $_ } |
|
2391
|
0
|
|
|
|
|
|
grep { $_ and $self->{'table'}{$jt}{$_} } keys %{ $self->{'table_join'}{$table}{$jt}{'on'} } |
|
|
0
|
|
|
|
|
|
|
|
2392
|
|
|
|
|
|
|
#) |
|
2393
|
|
|
|
|
|
|
); |
|
2394
|
|
|
|
|
|
|
#$self->log('dev','join', %{$self->{'table_join'}}); |
|
2395
|
|
|
|
|
|
|
#$self->log('dev', "JOd $table -> $jt,",@_,"::", keys %{ $self->{'table_join'}{$table}{$jt}{'on'} }); |
|
2396
|
|
|
|
|
|
|
#push @join, " $tq$self->{'table_prefix'}$table$tq LEFT JOIN " .$tq. $self->{'table_prefix'} . $jt . $tq. |
|
2397
|
0
|
|
|
|
|
|
push @join, " LEFT JOIN " . $tq . $self->{'table_prefix'} . $jt . $tq . ' ON ' . '(' . join( |
|
2398
|
|
|
|
|
|
|
', ', |
|
2399
|
|
|
|
|
|
|
map { |
|
2400
|
0
|
0
|
|
|
|
|
$tq |
|
2401
|
|
|
|
|
|
|
. $self->{'table_prefix'} |
|
2402
|
|
|
|
|
|
|
. $table |
|
2403
|
|
|
|
|
|
|
. $tq . '.' |
|
2404
|
|
|
|
|
|
|
. $rq |
|
2405
|
|
|
|
|
|
|
. $self->{'table_join'}{$table}{$jt}{'on'}{$_} |
|
2406
|
|
|
|
|
|
|
. $rq . ' = ' |
|
2407
|
|
|
|
|
|
|
. $tq |
|
2408
|
|
|
|
|
|
|
. $self->{'table_prefix'} |
|
2409
|
|
|
|
|
|
|
. $jt |
|
2410
|
|
|
|
|
|
|
. $tq . '.' |
|
2411
|
|
|
|
|
|
|
. $rq |
|
2412
|
|
|
|
|
|
|
. $_ |
|
2413
|
|
|
|
|
|
|
. $rq |
|
2414
|
|
|
|
|
|
|
} @_ |
|
2415
|
|
|
|
|
|
|
) |
|
2416
|
|
|
|
|
|
|
. ')' |
|
2417
|
|
|
|
|
|
|
if @_; |
|
2418
|
0
|
0
|
|
|
|
|
unless (@_) { |
|
2419
|
0
|
0
|
|
|
|
|
@_ = ( |
|
2420
|
|
|
|
|
|
|
#( |
|
2421
|
|
|
|
|
|
|
#map { $_ } |
|
2422
|
0
|
|
|
|
|
|
grep { $_ and $self->{'table'}{$jt}{$_} } keys %{ $self->{'table_join'}{$table}{$jt}{'using'} } |
|
|
0
|
|
|
|
|
|
|
|
2423
|
|
|
|
|
|
|
#) |
|
2424
|
|
|
|
|
|
|
#or (grep { $self->{'table'}{$jt}{$_}{'primary'} } |
|
2425
|
|
|
|
|
|
|
#keys %{ $self->{'table'}{$jt} }) |
|
2426
|
|
|
|
|
|
|
); |
|
2427
|
|
|
|
|
|
|
#$self->log('dev',"joprim{$jt}{$_}", |
|
2428
|
|
|
|
|
|
|
#keys (%{ $self->{'table'}{$jt} }),"oooooo", |
|
2429
|
|
|
|
|
|
|
#grep( { $self->{'table'}{$jt}{$_}{'primary'} } |
|
2430
|
|
|
|
|
|
|
#keys (%{ $self->{'table'}{$jt} })), |
|
2431
|
|
|
|
|
|
|
#"j[".join(':',@_)."]", scalar @_), |
|
2432
|
|
|
|
|
|
|
#$self->log('dev',"joprim{$jt} keys:", map( {'[', keys %{ $self->{'table'}{$jt}{$_}} , ']'} ,keys %{ $self->{'table'}{$jt} }),'prim:',grep { $self->{'table'}{$jt}{$_}{'primary'} } |
|
2433
|
|
|
|
|
|
|
#keys %{ $self->{'table'}{$jt} } |
|
2434
|
|
|
|
|
|
|
#); |
|
2435
|
|
|
|
|
|
|
#$self->log('dev',"joprim{$jt:",%{$self->{'table'}{$jt}{'host'}}); |
|
2436
|
|
|
|
|
|
|
#$self->log('dev','jop1',@_, "::", Dumper($self->{'table'}{$jt} )); |
|
2437
|
0
|
0
|
|
|
|
|
@_ = ( grep { $self->{'table'}{$jt}{$_}{'primary'} } keys %{ $self->{'table'}{$jt} } ) unless @_; |
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
2438
|
|
|
|
|
|
|
#$self->log('dev','jop2',@_); |
|
2439
|
|
|
|
|
|
|
#$self->log('dev','jop', "j[$jt][$_][".join(':',@_)."]", scalar @_); |
|
2440
|
|
|
|
|
|
|
#$self->log('dev', 'jo:',@_, ',,,:',grep { $self->{'table'}{$jt}{$_} } |
|
2441
|
|
|
|
|
|
|
#grep { $_ }keys %{ $self->{'table_join'}{$table}{$jt}{'using'} }); |
|
2442
|
|
|
|
|
|
|
#push @join, "$tq$self->{'table_prefix'}$table$tq LEFT JOIN " .$tq. $self->{'table_prefix'} . $jt . $tq.' USING ' . '(' . join( ', ', map { $rq . $_ . $rq } @_ ) . ')' |
|
2443
|
|
|
|
|
|
|
#$self->log('dev', "JO1 $table -> $jt,@_ [".join(':',@_)."]::", keys %{ $self->{'table_join'}{$table}{$jt}{'on'} }); |
|
2444
|
0
|
|
|
|
|
|
push @join, |
|
2445
|
|
|
|
|
|
|
" LEFT JOIN " |
|
2446
|
|
|
|
|
|
|
. $tq |
|
2447
|
|
|
|
|
|
|
. $self->{'table_prefix'} |
|
2448
|
|
|
|
|
|
|
. $jt |
|
2449
|
|
|
|
|
|
|
. $tq |
|
2450
|
|
|
|
|
|
|
. ' USING ' . '(' |
|
2451
|
0
|
0
|
|
|
|
|
. join( ', ', map { $rq . $_ . $rq } @_ ) . ')' |
|
2452
|
|
|
|
|
|
|
if @_; |
|
2453
|
|
|
|
|
|
|
} |
|
2454
|
|
|
|
|
|
|
#=cut |
|
2455
|
|
|
|
|
|
|
} |
|
2456
|
|
|
|
|
|
|
#=cut |
|
2457
|
0
|
|
|
|
|
|
return join( ' ', @join ); |
|
2458
|
0
|
|
0
|
|
|
|
}; |
|
2459
|
|
|
|
|
|
|
$self->{'join_where'} ||= sub { |
|
2460
|
|
|
|
|
|
|
#sub select { |
|
2461
|
0
|
|
|
0
|
|
|
my $self = shift; |
|
2462
|
0
|
|
|
|
|
|
my ( $where, $param, $table ) = @_; |
|
2463
|
0
|
|
|
|
|
|
my @what; |
|
2464
|
0
|
|
0
|
|
|
|
$table ||= $self->{'current_table'}; |
|
2465
|
0
|
|
|
|
|
|
for my $jt ( sort keys %{ $self->{'table_join'}{$table} } ) { |
|
|
0
|
|
|
|
|
|
|
|
2466
|
|
|
|
|
|
|
#$self->log('dev', "here $jt"); |
|
2467
|
0
|
|
|
|
|
|
local $_ = join ', ', map { |
|
2468
|
0
|
|
|
|
|
|
$tq |
|
2469
|
|
|
|
|
|
|
. $self->{'table_prefix'} |
|
2470
|
|
|
|
|
|
|
. $jt |
|
2471
|
|
|
|
|
|
|
. $tq . '.' |
|
2472
|
|
|
|
|
|
|
. $rq |
|
2473
|
|
|
|
|
|
|
. $self->{'table_join'}{$table}{$jt}{'fields'}{$_} |
|
2474
|
|
|
|
|
|
|
. $rq . ' AS ' |
|
2475
|
|
|
|
|
|
|
. $rq |
|
2476
|
|
|
|
|
|
|
. $_ |
|
2477
|
|
|
|
|
|
|
. $rq |
|
2478
|
|
|
|
|
|
|
} grep { |
|
2479
|
0
|
|
|
|
|
|
$self->{'table'}{$jt}{ $self->{'table_join'}{$table}{$jt}{'fields'}{$_} } |
|
2480
|
0
|
|
|
|
|
|
} sort keys %{ $self->{'table_join'}{$table}{$jt}{'fields'} }; |
|
2481
|
0
|
|
0
|
|
|
|
$_ ||= "$tq$self->{'table_prefix'}$jt" . "$tq.*"; |
|
2482
|
|
|
|
|
|
|
#$join .= $_ |
|
2483
|
0
|
|
|
|
|
|
push( @what, $_ ); |
|
2484
|
|
|
|
|
|
|
} |
|
2485
|
|
|
|
|
|
|
#$join = ', ' . $join if $join; |
|
2486
|
|
|
|
|
|
|
#$sql = " $tq$self->{'table_prefix'}$table" . "$tq.* $work{'what_relevance'}{$table}".($join ? ', ' : ''). $join . " " . $sql; |
|
2487
|
|
|
|
|
|
|
#$self->log('dev', join(':',@what)); |
|
2488
|
|
|
|
|
|
|
#@what = ('*'); |
|
2489
|
0
|
|
|
|
|
|
return join( ', ', grep { $_ } @what ); |
|
|
0
|
|
|
|
|
|
|
|
2490
|
0
|
|
0
|
|
|
|
}; |
|
2491
|
0
|
|
|
|
|
|
for my $by (qw(order group)) { |
|
2492
|
|
|
|
|
|
|
$self->{ $by . 'by' } ||= sub { |
|
2493
|
|
|
|
|
|
|
#sub select { |
|
2494
|
0
|
|
|
0
|
|
|
my $self = shift; |
|
2495
|
0
|
|
|
|
|
|
my ( $param, $table ) = @_; |
|
2496
|
0
|
|
0
|
|
|
|
$table ||= $self->{'current_table'}; |
|
2497
|
0
|
|
|
|
|
|
my $sql; |
|
2498
|
|
|
|
|
|
|
my %order; |
|
2499
|
0
|
|
|
|
|
|
for my $ordern ( '', 0 .. 10 ) { |
|
2500
|
0
|
|
0
|
|
|
|
my $order = ( $param->{ $by . $ordern } or next ); |
|
2501
|
0
|
0
|
0
|
|
|
|
last if ( $self->{'ignore_index'} or $self->{'table_param'}{$table}{'ignore_index'} ); |
|
2502
|
|
|
|
|
|
|
#$self->log('dev',1, $ordern, $order); |
|
2503
|
0
|
|
|
|
|
|
my $min_data; |
|
2504
|
0
|
0
|
|
|
|
|
++$min_data |
|
2505
|
0
|
|
|
|
|
|
for grep { $self->{'table'}{$table}{$_}{'sort_min'} and defined( $param->{$_} ) } keys %{ $self->{'table'}{$table} }; |
|
|
0
|
|
|
|
|
|
|
|
2506
|
0
|
0
|
0
|
|
|
|
last if $self->{'no_slow'} and !$min_data; |
|
2507
|
|
|
|
|
|
|
#$self->log('dev',2, $ordern, $order); |
|
2508
|
0
|
|
|
|
|
|
for my $join ( |
|
|
0
|
|
|
|
|
|
|
|
2509
|
0
|
0
|
|
|
|
|
grep { $order eq $_ } ( |
|
2510
|
0
|
|
|
|
|
|
grep { $self->{'table'}{$table}{$_}{'sort'} or !$self->{'table'}{$table}{$_}{'no_order'} } |
|
2511
|
0
|
|
|
|
|
|
keys %{ $self->{'table'}{$table} } |
|
2512
|
|
|
|
|
|
|
), |
|
2513
|
|
|
|
|
|
|
@{ $self->{'table_param'}{$table}{'join_fields'} } |
|
2514
|
|
|
|
|
|
|
) |
|
2515
|
|
|
|
|
|
|
{ |
|
2516
|
0
|
|
|
|
|
|
my ($intable) = grep { keys %{ $self->{'table'}{$_}{$join} } } $table, keys %{ $config{'sql'}{'table_join'}{$table} }; |
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
2517
|
|
|
|
|
|
|
#print "INTABLE[$intable]"; |
|
2518
|
|
|
|
|
|
|
#$order{ $tq . $table . $tq . '.' . $rq . $_ . $rq |
|
2519
|
0
|
0
|
|
|
|
|
$order{ ( $self->{'no_column_prepend_table'} ? '' : $tq . $intable . $tq . '.' ) |
|
|
|
0
|
|
|
|
|
|
|
2520
|
|
|
|
|
|
|
. $rq |
|
2521
|
|
|
|
|
|
|
. $join |
|
2522
|
|
|
|
|
|
|
. $rq |
|
2523
|
|
|
|
|
|
|
. ( ( $param->{ $by . '_mode' . $ordern } ) ? ' DESC ' : ' ASC' ) } |
|
2524
|
|
|
|
|
|
|
= #$param->{ 'order_rev' . $ordern } eq 'on' or |
|
2525
|
|
|
|
|
|
|
$ordern; |
|
2526
|
|
|
|
|
|
|
} |
|
2527
|
|
|
|
|
|
|
} |
|
2528
|
0
|
0
|
|
|
|
|
if ( keys %order ) { |
|
2529
|
0
|
|
|
|
|
|
$sql .= ' ' . uc($by) . ' BY ' . join ', ', sort { $order{$a} <=> $order{$b} } keys %order; |
|
|
0
|
|
|
|
|
|
|
|
2530
|
|
|
|
|
|
|
} |
|
2531
|
|
|
|
|
|
|
#print 'ORDERBY', Dumper($param,$table,$sql, $self->{'table_param'}{$table}{'join_fields'} ); |
|
2532
|
0
|
|
|
|
|
|
return $sql; |
|
2533
|
0
|
|
0
|
|
|
|
}; |
|
2534
|
|
|
|
|
|
|
} |
|
2535
|
|
|
|
|
|
|
$self->{'select_body'} ||= sub { |
|
2536
|
|
|
|
|
|
|
#sub select { |
|
2537
|
0
|
|
|
0
|
|
|
my $self = shift; |
|
2538
|
0
|
|
|
|
|
|
my ( $where, $param, $table ) = @_; |
|
2539
|
0
|
|
0
|
|
|
|
$table ||= $self->{'current_table'}; |
|
2540
|
0
|
|
|
|
|
|
( $tq, $rq, $vq ) = $self->quotes(); |
|
2541
|
|
|
|
|
|
|
#$self->log( 'dev', 'select_body', $where ); |
|
2542
|
|
|
|
|
|
|
#my ( $tq, $rq, $vq ) = sql_quotes(); |
|
2543
|
0
|
|
|
|
|
|
$self->limit_calc( $param, $table ); |
|
2544
|
|
|
|
|
|
|
#limit(_calc( $param, $table ); |
|
2545
|
0
|
0
|
0
|
|
|
|
if ( ( $self->{'ignore_index'} or $self->{'table_param'}{$table}{'ignore_index'} ) |
|
|
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
2546
|
|
|
|
|
|
|
and !( $self->{'no_index'} or $self->{'table_param'}{$table}{'no_index'} ) ) |
|
2547
|
|
|
|
|
|
|
{ |
|
2548
|
0
|
|
|
|
|
|
local @_ = (); |
|
2549
|
0
|
|
|
|
|
|
local %_ = (); |
|
2550
|
0
|
|
|
|
|
|
for ( keys %{ $self->{'table'}{$table} } ) { |
|
|
0
|
|
|
|
|
|
|
|
2551
|
0
|
0
|
|
|
|
|
++$_{ $self->{'table'}{$table}{$_}{'fulltext'} } if $self->{'table'}{$table}{$_}{'fulltext'}; |
|
2552
|
0
|
0
|
|
|
|
|
push( @_, $_ ) if $self->{'table'}{$table}{$_}{'index'}; |
|
2553
|
|
|
|
|
|
|
} |
|
2554
|
0
|
0
|
0
|
|
|
|
push( @_, keys %_ ) unless $self->{'ignore_index_fulltext'} and $self->{'table_param'}{$table}{'ignore_index_fulltext'}; |
|
2555
|
0
|
|
|
|
|
|
$work{'sql_select_index'} = 'IGNORE INDEX (' . join( ',', @_ ) . ')'; |
|
2556
|
|
|
|
|
|
|
} |
|
2557
|
|
|
|
|
|
|
#my $join = ; |
|
2558
|
|
|
|
|
|
|
#!!! |
|
2559
|
0
|
|
|
|
|
|
my $from; |
|
2560
|
0
|
0
|
|
|
|
|
if ($table) { |
|
2561
|
0
|
0
|
0
|
|
|
|
if ( $self->{'sphinx'} and $self->{'table_param'}{$table}{'stemmed_index'} and !$param->{'accurate'} ) { |
|
|
|
|
0
|
|
|
|
|
|
2562
|
0
|
|
|
|
|
|
$from .= "$tq$self->{'table_param'}{$table}{'stemmed_index'}$tq "; |
|
2563
|
|
|
|
|
|
|
} else { |
|
2564
|
0
|
|
|
|
|
|
$from .= "$tq$self->{'table_prefix'}$table$tq "; |
|
2565
|
|
|
|
|
|
|
} |
|
2566
|
|
|
|
|
|
|
} |
|
2567
|
0
|
0
|
|
|
|
|
unless ( $self->{'no_join'} ) { $from .= $work{'sql_select_index'} . ' ' . $self->join_what( $where, $param, $table ); } |
|
|
0
|
|
|
|
|
|
|
|
2568
|
0
|
0
|
|
|
|
|
$from = "FROM " . $from if $from; |
|
2569
|
0
|
|
|
|
|
|
my $sql = $from . ' ' . $where; |
|
2570
|
0
|
0
|
0
|
|
|
|
my @what = ( |
|
2571
|
|
|
|
|
|
|
( ( $table and !$self->{'no_column_prepend_table'} ) ? $tq . $self->{'table_prefix'} . $table . $tq . '.' : '' ) . '*', |
|
2572
|
|
|
|
|
|
|
$work{'what_relevance'}{$table}, |
|
2573
|
|
|
|
|
|
|
#$param->{'what_extra'} |
|
2574
|
|
|
|
|
|
|
$self->{'table_param'}{$table}{'what_extra'} |
|
2575
|
|
|
|
|
|
|
); |
|
2576
|
0
|
0
|
|
|
|
|
if ( defined( $self->{'table'}{$table}{ $param->{'distinct'} } ) ) { |
|
2577
|
|
|
|
|
|
|
#$sql = " DISTINCT $rq$param->{'distinct'}$rq " . $sql . " "; |
|
2578
|
0
|
|
|
|
|
|
@what = ( "DISTINCT $rq$param->{'distinct'}$rq", $self->{'table_param'}{$table}{'what_extra'} ); |
|
2579
|
|
|
|
|
|
|
} else { |
|
2580
|
|
|
|
|
|
|
#my $join ; |
|
2581
|
|
|
|
|
|
|
#@join = () |
|
2582
|
|
|
|
|
|
|
#!! |
|
2583
|
0
|
0
|
|
|
|
|
unless ( $self->{'no_join'} ) { @what = ( $self->join_where( $where, $param, $table ), @what ); } |
|
|
0
|
|
|
|
|
|
|
|
2584
|
|
|
|
|
|
|
} |
|
2585
|
|
|
|
|
|
|
#$self->log('dmp', "SP=", $self->{'sphinx'} ); |
|
2586
|
0
|
|
|
|
|
|
$sql = join( ', ', grep { $_ } @what, ) . ' ' . $sql; |
|
|
0
|
|
|
|
|
|
|
|
2587
|
0
|
|
|
|
|
|
my $priority; |
|
2588
|
0
|
0
|
0
|
|
|
|
$priority = $self->{'HIGH_PRIORITY'} if !$config{'client_bot'} and !$config{'client_no_high_priority'}; |
|
2589
|
0
|
|
|
|
|
|
$sql = " SELECT $self->{'SELECT_FLAGS'} $priority " . $sql; #SQL_CALC_FOUND_ROWS |
|
2590
|
0
|
|
|
|
|
|
$sql .= $self->groupby( $param, $table ); |
|
2591
|
0
|
|
|
|
|
|
$sql .= $self->orderby( $param, $table ); |
|
2592
|
|
|
|
|
|
|
#$work{'on_page'} = 10 unless defined $work{'on_page'}; |
|
2593
|
|
|
|
|
|
|
#my $limit = psmisc::check_int( ( $param->{'limit'} or $work{'on_page'} ), 0, $self->{'limit_max'}, $self->{'on_page'} ); |
|
2594
|
|
|
|
|
|
|
#$sql .= ' LIMIT ' . ( $param->{'show_from'} ? $param->{'show_from'} . ',' : '' ) . " $limit" |
|
2595
|
|
|
|
|
|
|
#if $param->{'show_from'} |
|
2596
|
|
|
|
|
|
|
#or $limit; |
|
2597
|
|
|
|
|
|
|
#$self->{'limit'} = 10 unless defined $self->{'limit'}; |
|
2598
|
|
|
|
|
|
|
#my $limit = psmisc::check_int( ( $param->{'limit'} or $self->{'limit'} ), 0, $self->{'results_max'}, $self->{'on_page'} ); |
|
2599
|
|
|
|
|
|
|
#$sql .= ' LIMIT ' . ( $param->{'show_from'} ? $param->{'show_from'} . ',' : '' ) . " $limit" if $param->{'show_from'} |
|
2600
|
0
|
|
|
|
|
|
$sql .= $self->limit_body(); |
|
2601
|
0
|
0
|
0
|
|
|
|
if ( $self->{'OPTION'} and psmisc::is_hash $self->{'option'} ) { #sphinx |
|
2602
|
0
|
|
|
|
|
|
$sql .= $self->{'OPTION'} . ' ' . join ', ', map { "$_=$self->{'option'}{$_}" } keys %{ $self->{'option'} }; |
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
2603
|
|
|
|
|
|
|
} |
|
2604
|
0
|
|
|
|
|
|
$sql .= $self->{'select_append'}; |
|
2605
|
0
|
|
|
|
|
|
return $sql; |
|
2606
|
0
|
|
0
|
|
|
|
}; |
|
2607
|
|
|
|
|
|
|
$self->{'limit_body'} ||= sub { |
|
2608
|
|
|
|
|
|
|
#sub calc_count { |
|
2609
|
0
|
|
|
0
|
|
|
my $self = shift; |
|
2610
|
0
|
0
|
0
|
|
|
|
return unless $self->{'limit_offset'} or $self->{'limit'}; |
|
2611
|
|
|
|
|
|
|
return |
|
2612
|
0
|
0
|
0
|
|
|
|
' LIMIT ' |
|
|
|
0
|
0
|
|
|
|
|
|
2613
|
|
|
|
|
|
|
. ( $self->{'limit_offset'} && !$self->{'OFFSET'} ? $self->{'limit_offset'} . ',' : '' ) |
|
2614
|
|
|
|
|
|
|
. $self->{'limit'} |
|
2615
|
|
|
|
|
|
|
. ( $self->{'OFFSET'} && $self->{'limit_offset'} ? ' ' . $self->{'OFFSET'} . ' ' . $self->{'limit_offset'} : '' ) . ' '; |
|
2616
|
0
|
|
|
|
|
|
return ''; |
|
2617
|
0
|
|
0
|
|
|
|
}; |
|
2618
|
|
|
|
|
|
|
$self->{'calc_count'} ||= sub { |
|
2619
|
|
|
|
|
|
|
#sub calc_count { |
|
2620
|
0
|
|
|
0
|
|
|
my $self = shift; |
|
2621
|
0
|
|
|
|
|
|
my ( $param, $table, $count ) = @_; |
|
2622
|
0
|
0
|
|
|
|
|
return if $work{'calc_count'}{$table}++; |
|
2623
|
|
|
|
|
|
|
#$self->log( 'dev', "calc_count0 : founded=$self->{'founded'}; page=$self->{'page'} page_last=$self->{'page_last'} dbirows=$self->{'dbirows'} limit=$self->{'limit'} ", ); |
|
2624
|
0
|
|
0
|
|
|
|
$self->{'founded'} = $count |
|
2625
|
|
|
|
|
|
|
|| ( ( $self->{'dbirows'} > $self->{'stat'}{'found'}{'files'} and $self->{'dbirows'} < $self->{'limit'} ) |
|
2626
|
|
|
|
|
|
|
? $self->{'dbirows'} + $self->{'limit_offset'} |
|
2627
|
|
|
|
|
|
|
: $self->{'stat'}{'found'}{'files'} ); |
|
2628
|
0
|
0
|
0
|
|
|
|
$self->{'founded'} = 0 if $self->{'founded'} < 0 or !$self->{'founded'}; #or !$self->{'dbirows'} !!!experemental! |
|
2629
|
0
|
0
|
0
|
|
|
|
$self->{'page_last'} = |
|
|
|
0
|
0
|
|
|
|
|
|
2630
|
|
|
|
|
|
|
$self->{'limit'} > 0 |
|
2631
|
|
|
|
|
|
|
? ( int( $self->{'founded'} / ( $self->{'limit'} or 1 ) ) + ( $self->{'founded'} % ( $self->{'limit'} or 1 ) ? 1 : 0 ) ) |
|
2632
|
|
|
|
|
|
|
: 0; #3 |
|
2633
|
0
|
0
|
0
|
|
|
|
$self->{'page'} = int( rand( $self->{'page_last'} ) ) if $self->{'page'} eq 'rnd' and $param->{'count_f'} eq 'on'; #4 |
|
2634
|
|
|
|
|
|
|
#$self->log( 'dev', "calc_count : founded=$self->{'founded'}; page=$self->{'page'} page_last=$self->{'page_last'} dbirows=$self->{'dbirows'} limit=$self->{'limit'} ", ); |
|
2635
|
0
|
|
0
|
|
|
|
}; |
|
2636
|
|
|
|
|
|
|
$self->{'limit_calc'} ||= sub { |
|
2637
|
|
|
|
|
|
|
#sub pre_query { |
|
2638
|
0
|
|
|
0
|
|
|
my $self = shift; |
|
2639
|
0
|
|
|
|
|
|
my ($param) = @_; |
|
2640
|
|
|
|
|
|
|
#return if $work{'pre_query'}{$table}++; |
|
2641
|
|
|
|
|
|
|
#$self->{'page'} = int( $param->{'page'} > 0 ? $param->{'page'} : 1 ); |
|
2642
|
|
|
|
|
|
|
#$self->{'page'} = psmisc::check_int( $param->{'page'}, 1, $self->{'page_max'}, 1 ); |
|
2643
|
|
|
|
|
|
|
#$self->{'limit'} = psmisc::check_int( $param->{'on_page'}, 0, $self->{'limit_max'}, $self->{'on_page'} ); |
|
2644
|
|
|
|
|
|
|
#$self->{'limit'} ||= psmisc::check_int( $param->{'on_page'}, 0, $self->{'results_max'}, $self->{'on_page'} ); |
|
2645
|
0
|
0
|
0
|
|
|
|
$self->{'limit_offset'} = |
|
2646
|
|
|
|
|
|
|
int( $self->{'page'} > 0 ? $self->{'limit'} * ( $self->{'page'} - 1 ) : ( ( $param->{'show_from'} ) or 0 ) ); |
|
2647
|
0
|
0
|
|
|
|
|
$self->{'limit_offset'} -= $self->{'limit_from'} - $self->{'limit_minus'} if $self->{'limit_offset'}; |
|
2648
|
0
|
|
|
|
|
|
$self->{'limit'} -= $self->{'limit_minus'}; |
|
2649
|
|
|
|
|
|
|
#$self->log( 'dev',"limit_calc : limit_offset=$self->{'limit_offset'}; page=$self->{'page'} limit= $self->{'limit'} from=$self->{'limit_from'}" ); |
|
2650
|
|
|
|
|
|
|
#; #caller(), caller(1), caller(2) |
|
2651
|
0
|
|
|
|
|
|
return undef; |
|
2652
|
0
|
|
0
|
|
|
|
}; |
|
2653
|
|
|
|
|
|
|
$self->{'lock_tables'} ||= sub { |
|
2654
|
|
|
|
|
|
|
#sub lock_tables { |
|
2655
|
0
|
|
|
0
|
|
|
my $self = shift; |
|
2656
|
|
|
|
|
|
|
#local $_ = $self->do( $self->{'LOCK TABLES'}.' ' . join ' ', @_ ); |
|
2657
|
|
|
|
|
|
|
#$work{'sql_locked'} = join ' ', @_ if $_; |
|
2658
|
0
|
0
|
|
|
|
|
return $self->do( $self->{'LOCK TABLES'} . ' ' . join ' ', @_ ) if $self->{'LOCK TABLES'}; |
|
2659
|
0
|
|
0
|
|
|
|
}; |
|
2660
|
|
|
|
|
|
|
$self->{'unlock_tables'} ||= sub { |
|
2661
|
|
|
|
|
|
|
#sub unlock_tables { |
|
2662
|
0
|
|
|
0
|
|
|
my $self = shift; |
|
2663
|
|
|
|
|
|
|
#$work{'sql_locked'} = ''; |
|
2664
|
|
|
|
|
|
|
#return $self->do( 'UNLOCK TABLES ' . join ' ', @_ ); |
|
2665
|
0
|
0
|
|
|
|
|
return $self->do( $self->{'UNLOCK TABLES'} . ' ' . join ' ', @_ ) if $self->{'UNLOCK TABLES'}; |
|
2666
|
0
|
|
0
|
|
|
|
}; |
|
2667
|
|
|
|
|
|
|
$self->{'stat_string'} ||= sub { |
|
2668
|
0
|
|
|
0
|
|
|
my $self = shift; |
|
2669
|
|
|
|
|
|
|
#print "\nSTRAAAA\n"; |
|
2670
|
0
|
|
|
|
|
|
return 'sqlstat: ' |
|
2671
|
|
|
|
|
|
|
. join( |
|
2672
|
|
|
|
|
|
|
' ', |
|
2673
|
0
|
|
|
|
|
|
( map { "$_=$self->{$_};" } grep { $self->{$_} } ( @_ or sort keys %{ $self->{'statable'} } ) ), |
|
|
0
|
|
|
|
|
|
|
|
2674
|
|
|
|
|
|
|
( |
|
2675
|
0
|
|
|
|
|
|
map { "$_=" . psmisc::human( 'time_period', $self->{$_} ) . ';' } |
|
2676
|
0
|
|
0
|
|
|
|
grep { $self->{$_} } ( @_ or sort keys %{ $self->{'statable_time'} } ) |
|
|
|
|
0
|
|
|
|
|
|
2677
|
|
|
|
|
|
|
) |
|
2678
|
|
|
|
|
|
|
); |
|
2679
|
0
|
|
0
|
|
|
|
}; |
|
2680
|
|
|
|
|
|
|
$self->{'log_stat'} ||= sub { |
|
2681
|
0
|
|
|
0
|
|
|
my $self = shift; |
|
2682
|
0
|
|
|
|
|
|
$self->log( 'stat', $self->stat_string(@_) ); |
|
2683
|
0
|
|
0
|
|
|
|
}; |
|
2684
|
|
|
|
|
|
|
$self->{'check_data'} ||= sub { |
|
2685
|
0
|
|
|
0
|
|
|
my $self = shift; |
|
2686
|
0
|
|
|
|
|
|
local @_ = sort grep { $_ } keys %{ $self->{'table'} }; |
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
2687
|
0
|
0
|
|
|
|
|
return 0 unless @_; |
|
2688
|
|
|
|
|
|
|
#$self->log('dev',@_); |
|
2689
|
0
|
|
|
|
|
|
return 0; |
|
2690
|
0
|
|
|
|
|
|
return $self->query( 'SELECT * FROM ' . ( join ',', map { "$tq$_$tq" } @_ ) . ' WHERE 1 LIMIT 1' ); |
|
|
0
|
|
|
|
|
|
|
|
2691
|
0
|
|
0
|
|
|
|
}; |
|
2692
|
|
|
|
|
|
|
$self->{'check_data_every_table'} ||= sub { |
|
2693
|
0
|
|
|
0
|
|
|
my $self = shift; |
|
2694
|
0
|
|
|
|
|
|
local @_ = sort grep { $_ } keys %{ $self->{'table'} }; |
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
2695
|
0
|
0
|
|
|
|
|
return 0 unless @_; |
|
2696
|
0
|
|
|
|
|
|
for my $table (@_) { |
|
2697
|
|
|
|
|
|
|
#$self->log('check', $table, |
|
2698
|
0
|
|
|
|
|
|
$self->query_log("SELECT * FROM $tq$table$tq LIMIT 1"); #); |
|
2699
|
|
|
|
|
|
|
} |
|
2700
|
0
|
|
0
|
|
|
|
}; |
|
2701
|
|
|
|
|
|
|
$self->{'on_connect1'} ||= sub { |
|
2702
|
0
|
|
|
0
|
|
|
my $self = shift; |
|
2703
|
|
|
|
|
|
|
#$self->log( 'dev', 'ONCON1'); |
|
2704
|
0
|
0
|
|
|
|
|
$self->check_data() if $self->{'auto_check'}; |
|
2705
|
|
|
|
|
|
|
#use Data::Dumper; |
|
2706
|
|
|
|
|
|
|
#$self->log( 'dev', Dumper($config{'sql'})); |
|
2707
|
0
|
|
0
|
|
|
|
}; |
|
2708
|
|
|
|
|
|
|
$self->{'table_stat'} ||= sub { |
|
2709
|
0
|
|
|
0
|
|
|
my $self = shift; |
|
2710
|
0
|
|
|
|
|
|
$self->log( 'info', 'totals:', @_, |
|
2711
|
0
|
|
|
|
|
|
map { ( $_, '=', values %{ $self->line("SELECT COUNT(*) FROM $rq$self->{'table_prefix'}$_$rq ") } ) } |
|
|
0
|
|
|
|
|
|
|
|
2712
|
0
|
|
0
|
|
|
|
grep { $_ } ( @_ or keys %{ $self->{'table'} } ) ); |
|
2713
|
0
|
|
0
|
|
|
|
}; |
|
2714
|
|
|
|
|
|
|
$self->{'next_user_prepare'} ||= sub { |
|
2715
|
0
|
|
|
0
|
|
|
my $self = shift; |
|
2716
|
|
|
|
|
|
|
#$self->{'queries'} = $self->{''} = $self->{''} = $self->{''} = $self->{''} = 0; |
|
2717
|
|
|
|
|
|
|
#delete $self->{error_log} if $self->{'error_collect'}; |
|
2718
|
|
|
|
|
|
|
|
|
2719
|
0
|
|
|
|
|
|
delete $self->{$_} for qw(founded queries queries_time errors_chain errors connect_tried error_log); |
|
2720
|
0
|
|
|
|
|
|
$self->{'stat'}{'found'} = {}; |
|
2721
|
0
|
|
|
|
|
|
$self->{ 'on_user' . $_ }->($self) for grep { ref $self->{ 'on_user' . $_ } eq 'CODE' } ( '', 1 .. 5 ); |
|
|
0
|
|
|
|
|
|
|
|
2722
|
|
|
|
|
|
|
#$self->{ 'on_user' }->($self) for grep { ref $self->{ 'on_user' } eq 'CODE'}(''); |
|
2723
|
|
|
|
|
|
|
#$self->log('dev', 'nup'); |
|
2724
|
|
|
|
|
|
|
|
|
2725
|
0
|
|
0
|
|
|
|
}; |
|
2726
|
|
|
|
|
|
|
$self->{'next_user'} ||= sub { |
|
2727
|
0
|
|
|
0
|
|
|
my $self = shift; |
|
2728
|
0
|
|
|
|
|
|
$self->user_params(@_); |
|
2729
|
0
|
|
|
|
|
|
$self->next_user_prepare(@_); |
|
2730
|
0
|
0
|
|
|
|
|
$self->{'sphinx_dbi'}->next_user(@_) if $self->{'sphinx_dbi'}; |
|
2731
|
0
|
|
0
|
|
|
|
}; |
|
2732
|
|
|
|
|
|
|
|
|
2733
|
|
|
|
|
|
|
=stem links |
|
2734
|
|
|
|
|
|
|
http://en.wikipedia.org/wiki/New_York_State_Identification_and_Intelligence_System |
|
2735
|
|
|
|
|
|
|
http://translit.ru/ |
|
2736
|
|
|
|
|
|
|
http://koi8.pp.ru/koi8-r_iso9945-2.txt |
|
2737
|
|
|
|
|
|
|
http://en.wikipedia.org/wiki/Stemming |
|
2738
|
|
|
|
|
|
|
http://linguist.nm.ru/stemka/stemka.html |
|
2739
|
|
|
|
|
|
|
=cut |
|
2740
|
|
|
|
|
|
|
|
|
2741
|
|
|
|
|
|
|
$self->{'stem'} ||= sub { |
|
2742
|
0
|
|
|
0
|
|
|
my $self = shift; |
|
2743
|
|
|
|
|
|
|
#$self->log('dev', "stem in[$_[0]]( $self->{'codepage'}, $self->{'cp_in'} -> $self->{'cp_int'})"); |
|
2744
|
|
|
|
|
|
|
#return $_[0]; |
|
2745
|
0
|
|
|
|
|
|
local $_ = lc( scalar psmisc::cp_trans( $self->{'cp_in'}, $self->{'cp_int'}, $_[0] ) ); |
|
2746
|
|
|
|
|
|
|
#local $_ = lc( scalar psmisc::cp_trans( $self->{'codepage'}, $self->{'cp_int'}, $_[0] ) ); |
|
2747
|
|
|
|
|
|
|
#local $_ = lc($_[0] ); |
|
2748
|
|
|
|
|
|
|
#$self->log('dev', "stem bef[$_]"); |
|
2749
|
0
|
0
|
|
|
|
|
$self->{'stem_version'} = 4 if $self->{'stem_version'} <= 1; |
|
2750
|
0
|
0
|
|
|
|
|
if ( $self->{'stem_version'} == 2 ) { #first |
|
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
2751
|
0
|
|
|
|
|
|
s/(\d)(\D)/$1 $2/g; |
|
2752
|
0
|
|
|
|
|
|
s/(\D)(\d)/$1 $2/g; |
|
2753
|
0
|
|
|
|
|
|
tr/А-Я/а-я/; |
|
2754
|
0
|
|
|
|
|
|
s/[ъь]//g; |
|
2755
|
0
|
|
|
|
|
|
s/kn/n/g; |
|
2756
|
0
|
|
|
|
|
|
tr/абвгдеёжзийклмнопрстуфхцчшщыэюя/abvgdeejsiiklmnoprstufhccssieua/; |
|
2757
|
0
|
|
|
|
|
|
tr/ekouw/acaav/; |
|
2758
|
0
|
|
|
|
|
|
s/'//g; |
|
2759
|
0
|
0
|
|
|
|
|
s/\W/ /g if $_[1]; |
|
2760
|
0
|
|
|
|
|
|
s/_/ /g; |
|
2761
|
0
|
|
|
|
|
|
s/(?:rd|nd)\b/d/g; |
|
2762
|
0
|
|
|
|
|
|
s/ay\b/y/g; |
|
2763
|
0
|
|
|
|
|
|
s/\B[aeisuo]\b//g; |
|
2764
|
0
|
|
|
|
|
|
s/av/af/g; |
|
2765
|
0
|
|
|
|
|
|
s/sch/s/g; |
|
2766
|
0
|
|
|
|
|
|
s/ph/f/g; |
|
2767
|
0
|
|
|
|
|
|
s/\s+/ /g; |
|
2768
|
0
|
|
|
|
|
|
s/(\w)\1+/$1/g; |
|
2769
|
|
|
|
|
|
|
} elsif ( $self->{'stem_version'} == 3 ) { #temporary |
|
2770
|
0
|
|
|
|
|
|
s/(\d)(\D)/$1 $2/g; |
|
2771
|
0
|
|
|
|
|
|
s/(\D)(\d)/$1 $2/g; |
|
2772
|
0
|
|
|
|
|
|
tr/А-Я/а-я/; |
|
2773
|
0
|
|
|
|
|
|
s/[ъь]//g; |
|
2774
|
0
|
|
|
|
|
|
s/kn/n/g; |
|
2775
|
0
|
|
|
|
|
|
tr/абвгдеёжзийклмнопрстуфхцчшщыэюя/abvgdeejsiiklmnoprstufhccssieua/; |
|
2776
|
0
|
|
|
|
|
|
s/ks/x/g; #2 |
|
2777
|
0
|
|
|
|
|
|
tr/kw/cv/; #3 |
|
2778
|
0
|
|
|
|
|
|
s/'//g; |
|
2779
|
0
|
0
|
|
|
|
|
s/\W/ /g if $_[1]; |
|
2780
|
0
|
|
|
|
|
|
s/_/ /g; |
|
2781
|
0
|
|
|
|
|
|
s/(?:rd|nd)\b/d/g; |
|
2782
|
0
|
|
|
|
|
|
s/ay\b/y/g; |
|
2783
|
0
|
|
|
|
|
|
s/\B[aeisuo]\b//g; |
|
2784
|
0
|
|
|
|
|
|
s/av/af/g; |
|
2785
|
0
|
|
|
|
|
|
s/sch/s/g; |
|
2786
|
0
|
|
|
|
|
|
s/ph/f/g; |
|
2787
|
0
|
|
|
|
|
|
s/\s+/ /g; |
|
2788
|
0
|
|
|
|
|
|
s/(?:(?!xxx)|(?=xxxx))(\w)\1+(?:(?
|
|
2789
|
|
|
|
|
|
|
} elsif ( $self->{'stem_version'} == 4 ) { #release candidate |
|
2790
|
0
|
|
|
|
|
|
s/(\d)(\D)/$1 $2/g; |
|
2791
|
0
|
|
|
|
|
|
s/(\D)(\d)/$1 $2/g; |
|
2792
|
0
|
|
|
|
|
|
tr/А-Я/а-я/; |
|
2793
|
0
|
|
|
|
|
|
s/kn/n/g; |
|
2794
|
0
|
|
|
|
|
|
s/[ъь]//g; |
|
2795
|
0
|
|
|
|
|
|
tr{абвгдеёжзийклмнопрстуфхцчшщыэюя} |
|
2796
|
|
|
|
|
|
|
{abvgdeejziiklmnoprstufhccssieua}; #4 z |
|
2797
|
0
|
|
|
|
|
|
s/ks/x/g; #2 |
|
2798
|
0
|
|
|
|
|
|
tr/kw/cv/; #3 |
|
2799
|
0
|
|
|
|
|
|
s/'//g; |
|
2800
|
0
|
0
|
|
|
|
|
s/\W/ /g if $_[1]; |
|
2801
|
0
|
|
|
|
|
|
s/_/ /g; |
|
2802
|
0
|
|
|
|
|
|
s/(?:rd|nd)\b/d/g; |
|
2803
|
0
|
|
|
|
|
|
s/ay\b/y/g; |
|
2804
|
0
|
|
|
|
|
|
s/\B[aeisuo]\b//g; |
|
2805
|
0
|
|
|
|
|
|
s/av/af/g; |
|
2806
|
0
|
|
|
|
|
|
s/sch/s/g; |
|
2807
|
0
|
|
|
|
|
|
s/ph/f/g; |
|
2808
|
0
|
|
|
|
|
|
s/\s+/ /g; |
|
2809
|
0
|
|
|
|
|
|
s/(?:(?!xxx)|(?=xxxx))(\w)\1+(?:(?
|
|
2810
|
|
|
|
|
|
|
} |
|
2811
|
|
|
|
|
|
|
#$self->log('dev', "stem aft[$_]"); |
|
2812
|
|
|
|
|
|
|
#$_ = scalar psmisc::cp_trans( $self->{'cp_int'}, $self->{'cp_in'},$_); |
|
2813
|
|
|
|
|
|
|
#$_ = scalar psmisc::cp_trans( $self->{'cp_int'}, $self->{'codepage'}, $_ ); |
|
2814
|
|
|
|
|
|
|
#$self->log('dev', "stem out[$_]"); |
|
2815
|
|
|
|
|
|
|
#return scalar psmisc::cp_trans( $self->{'cp_int'}, $self->{'codepage'}, $_ ); |
|
2816
|
0
|
|
|
|
|
|
return scalar psmisc::cp_trans( $self->{'cp_int'}, $self->{'cp_in'}, $_ ); |
|
2817
|
0
|
|
0
|
|
|
|
}; |
|
2818
|
|
|
|
|
|
|
$self->{'stem_insert'} ||= sub { |
|
2819
|
0
|
|
|
0
|
|
|
my $self = shift; |
|
2820
|
|
|
|
|
|
|
#$config{'sql'}{'handler_insert'} = sub { |
|
2821
|
0
|
|
|
|
|
|
my ( $table, $col ) = @_; |
|
2822
|
0
|
0
|
|
|
|
|
return 1 unless ref $self->{'stem'} eq 'CODE'; |
|
2823
|
|
|
|
|
|
|
#$config{'stem'} and |
|
2824
|
|
|
|
|
|
|
#$config{'stem_func'}; |
|
2825
|
0
|
|
|
|
|
|
$col->{'stem'} = join ' ', |
|
2826
|
0
|
0
|
|
|
|
|
map { $self->stem( $col->{$_}, 1 ) } grep { $self->{'table'}{$table}{$_}{'stem'} and $col->{$_} } keys %$col; |
|
|
0
|
|
|
|
|
|
|
|
2827
|
0
|
|
|
|
|
|
return undef; |
|
2828
|
0
|
|
0
|
|
|
|
}; |
|
2829
|
|
|
|
|
|
|
$self->{'last_insert_id'} ||= sub { |
|
2830
|
0
|
|
|
0
|
|
|
my $self = shift; |
|
2831
|
0
|
|
0
|
|
|
|
my $table = shift || $self->{'current_table'}; |
|
2832
|
0
|
0
|
0
|
|
|
|
if ( $^O eq 'MSWin32' and $self->{'driver'} eq 'pgpp' ) { |
|
2833
|
0
|
0
|
|
|
|
|
my ($field) = |
|
2834
|
0
|
|
|
|
|
|
grep { $self->{'table'}{$table}{$_}{'type'} eq 'serial' or $self->{'table'}{$table}{$_}{'auto_increment'} } |
|
2835
|
0
|
|
|
|
|
|
keys %{ $self->{'table'}{$table} }; |
|
2836
|
|
|
|
|
|
|
#$self->log('dev', 'use lid1', "${table}_${field}"); |
|
2837
|
0
|
|
|
|
|
|
return $self->line("SELECT currval('${table}_${field}_seq') as lastid")->{'lastid'}; |
|
2838
|
|
|
|
|
|
|
} else { |
|
2839
|
|
|
|
|
|
|
#$self->log('use lid2'); |
|
2840
|
0
|
|
|
|
|
|
return $self->{dbh}->last_insert_id( undef, undef, $table, undef ); |
|
2841
|
|
|
|
|
|
|
} |
|
2842
|
0
|
|
0
|
|
|
|
}; |
|
2843
|
|
|
|
|
|
|
$self->{'dump_cp'} ||= sub { |
|
2844
|
0
|
|
|
0
|
|
|
$self->log( 'dev', map { "$_ = $self->{$_}; " } qw(codepage cp cp_in cp_out cp_int cp_set_names) ); |
|
|
0
|
|
|
|
|
|
|
|
2845
|
0
|
|
0
|
|
|
|
}; |
|
2846
|
|
|
|
|
|
|
$self->{'cp_client'} ||= sub { |
|
2847
|
0
|
|
|
0
|
|
|
my $self = shift; |
|
2848
|
0
|
0
|
|
|
|
|
$self->{'cp_in'} = $_[0] if $_[0]; |
|
2849
|
0
|
0
|
0
|
|
|
|
$self->{'cp_out'} = $_[1] || $self->{'cp_in'} if $_[1] or $_[0]; |
|
|
|
|
0
|
|
|
|
|
|
2850
|
0
|
|
|
|
|
|
return ( $self->{'cp_in'}, $self->{'cp_out'} ); |
|
2851
|
0
|
|
0
|
|
|
|
}; |
|
2852
|
|
|
|
|
|
|
$self->{'index_disable'} ||= sub { |
|
2853
|
0
|
|
|
0
|
|
|
my $self = shift; |
|
2854
|
0
|
|
|
|
|
|
my $tim = psmisc::timer(); |
|
2855
|
0
|
|
|
|
|
|
$self->log( 'info', 'Disabling indexes on', @_ ); |
|
2856
|
0
|
0
|
0
|
|
|
|
$self->log( 'err', 'ALTER TABLE ... DISABLE KEYS available in mysql >= 4' ), return |
|
2857
|
|
|
|
|
|
|
if $self->{'driver'} eq 'mysql3' |
|
2858
|
|
|
|
|
|
|
or $self->{'driver'} !~ /mysql/; |
|
2859
|
|
|
|
|
|
|
$self-> #query_log |
|
2860
|
0
|
|
|
|
|
|
do("ALTER TABLE $tq$config{'table_prefix'}$_$tq DISABLE KEYS") for @_; |
|
2861
|
0
|
|
|
|
|
|
$self->log( 'time', "Disable index per", psmisc::human( 'time_period', $tim->() ), "sec" ); |
|
2862
|
0
|
|
0
|
|
|
|
}; |
|
2863
|
|
|
|
|
|
|
$self->{'index_enable'} ||= sub { |
|
2864
|
0
|
|
|
0
|
|
|
my $self = shift; |
|
2865
|
0
|
|
|
|
|
|
my $tim = psmisc::timer(); |
|
2866
|
0
|
|
|
|
|
|
$self->log( 'info', 'Enabling indexes on', @_ ); |
|
2867
|
0
|
0
|
0
|
|
|
|
$self->log( 'err', 'ALTER TABLE ... DISABLE KEYS available in mysql >= 4' ), return |
|
2868
|
|
|
|
|
|
|
if $self->{'driver'} eq 'mysql3' |
|
2869
|
|
|
|
|
|
|
or $self->{'driver'} !~ /mysql/; |
|
2870
|
|
|
|
|
|
|
$self-> #query_log |
|
2871
|
0
|
|
|
|
|
|
do("ALTER TABLE $tq$config{'table_prefix'}$_$tq ENABLE KEYS") for @_; |
|
2872
|
0
|
|
|
|
|
|
$self->log( 'time', 'Enable index per ', psmisc::human( 'time_period', $tim->() ) ); |
|
2873
|
0
|
|
0
|
|
|
|
}; |
|
2874
|
0
|
|
|
|
|
|
for my $action (qw(optimize analyze check flush)) { |
|
2875
|
|
|
|
|
|
|
$self->{$action} ||= sub { |
|
2876
|
0
|
|
|
0
|
|
|
my $self = shift; |
|
2877
|
0
|
0
|
|
|
|
|
@_ = sort keys %{ $self->{'table'} } unless @_; |
|
|
0
|
|
|
|
|
|
|
|
2878
|
0
|
0
|
|
|
|
|
@_ = grep { $_ and $self->{'table'}{$_} } @_; |
|
|
0
|
|
|
|
|
|
|
|
2879
|
0
|
0
|
|
|
|
|
$self->log( 'err', 'not defined action', $action, ), return unless $self->{ uc $action }; |
|
2880
|
0
|
|
|
|
|
|
$self->log( 'info', $action, @_ ); |
|
2881
|
0
|
|
|
|
|
|
my $tim = psmisc::timer(); |
|
2882
|
0
|
0
|
|
|
|
|
for ( $self->{'bulk_service'} ? \@_ : @_ ) { |
|
2883
|
0
|
|
|
|
|
|
$self->query_log( |
|
2884
|
|
|
|
|
|
|
$self->{ uc $action } . ' ' . join( ',', map( $self->tquote("$self->{'table_prefix'}$_"), psmisc::array $_ ) ) ); |
|
2885
|
|
|
|
|
|
|
} |
|
2886
|
0
|
|
|
|
|
|
$self->log( 'time', $action, 'per ', psmisc::human( 'time_period', $tim->() ) ); |
|
2887
|
0
|
|
0
|
|
|
|
}; |
|
2888
|
|
|
|
|
|
|
} |
|
2889
|
|
|
|
|
|
|
|
|
2890
|
|
|
|
|
|
|
=no |
|
2891
|
|
|
|
|
|
|
for my $action (qw(flush)) { |
|
2892
|
|
|
|
|
|
|
$self->{$action} ||= sub { |
|
2893
|
|
|
|
|
|
|
my $self = shift; |
|
2894
|
|
|
|
|
|
|
@_ = sort keys %{ $self->{'table'} } unless @_; |
|
2895
|
|
|
|
|
|
|
@_ = grep { $_ and ( m/\./ or $self->{'table'}{$_} ) } @_; |
|
2896
|
|
|
|
|
|
|
$self->log( 'err', 'not defined action', $action, ), return unless $self->{ uc $action }; |
|
2897
|
|
|
|
|
|
|
$self->log( 'info', $action, @_ ); |
|
2898
|
|
|
|
|
|
|
my $tim = psmisc::timer(); |
|
2899
|
|
|
|
|
|
|
$self->do( $self->{ uc $action } . ' ' . join( ',', map( $self->tquote( $self->{'table_prefix'} . $_ ), @_ ) ) ); |
|
2900
|
|
|
|
|
|
|
$self->log( 'time', $action, 'per ', psmisc::human( 'time_period', $tim->() ) ); |
|
2901
|
|
|
|
|
|
|
}; |
|
2902
|
|
|
|
|
|
|
} |
|
2903
|
|
|
|
|
|
|
=cut |
|
2904
|
|
|
|
|
|
|
|
|
2905
|
|
|
|
|
|
|
$self->{'retry_off'} ||= sub { |
|
2906
|
0
|
|
|
0
|
|
|
my $self = shift; |
|
2907
|
0
|
0
|
|
|
|
|
return if %{ $self->{'retry_save'} || {} }; |
|
|
0
|
0
|
|
|
|
|
|
|
2908
|
0
|
|
|
|
|
|
$self->{'retry_save'}{$_} = $self->{$_}, $self->{$_} = 0 for @{ $self->{'retry_vars'} }; |
|
|
0
|
|
|
|
|
|
|
|
2909
|
0
|
|
0
|
|
|
|
}; |
|
2910
|
|
|
|
|
|
|
$self->{'retry_on'} ||= sub { |
|
2911
|
0
|
|
|
0
|
|
|
my $self = shift; |
|
2912
|
0
|
0
|
|
|
|
|
return unless %{ $self->{'retry_save'} || {} }; |
|
|
0
|
0
|
|
|
|
|
|
|
2913
|
0
|
|
|
|
|
|
$self->{$_} = $self->{'retry_save'}{$_} for @{ $self->{'retry_vars'} }; |
|
|
0
|
|
|
|
|
|
|
|
2914
|
0
|
|
|
|
|
|
$self->{'retry_save'} = {}; |
|
2915
|
0
|
|
0
|
|
|
|
}; |
|
2916
|
|
|
|
|
|
|
$self->{'set_names'} ||= sub { |
|
2917
|
0
|
|
|
0
|
|
|
my $self = shift; |
|
2918
|
0
|
|
0
|
|
|
|
local $_ = $_[0] || $self->{'cp_set_names'}; |
|
2919
|
0
|
0
|
0
|
|
|
|
$self->do( $self->{'SET NAMES'} . " $vq$_$vq" ) if $_ and $self->{'SET NAMES'}; |
|
2920
|
0
|
|
0
|
|
|
|
}; |
|
2921
|
|
|
|
|
|
|
} |
|
2922
|
|
|
|
|
|
|
1; |