| line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
|
1
|
|
|
|
|
|
|
package Fry::Lib::CDBI::Basic; |
|
2
|
1
|
|
|
1
|
|
1780
|
use strict; |
|
|
1
|
|
|
|
|
2
|
|
|
|
1
|
|
|
|
|
1519
|
|
|
3
|
|
|
|
|
|
|
|
|
4
|
|
|
|
|
|
|
our $VERSION='0.15'; |
|
5
|
|
|
|
|
|
|
my $sql_count; |
|
6
|
|
|
|
|
|
|
#our $cdbi_search = "search_abstract"; |
|
7
|
|
|
|
|
|
|
#other possible values are cdbi_search,cdbi_regex and cdbi_search_like |
|
8
|
|
|
|
|
|
|
|
|
9
|
|
|
|
|
|
|
#functions |
|
10
|
|
|
|
|
|
|
sub _default_data { |
|
11
|
0
|
|
|
0
|
|
|
my $class = shift; |
|
12
|
|
|
|
|
|
|
|
|
13
|
|
|
|
|
|
|
return { |
|
14
|
0
|
|
|
|
|
|
depend=>[':CDBI::Load'], |
|
15
|
|
|
|
|
|
|
vars=>{ |
|
16
|
|
|
|
|
|
|
editor=>$ENV{EDITOR}, |
|
17
|
|
|
|
|
|
|
splitter=>'=', |
|
18
|
|
|
|
|
|
|
insert_columns=>'', |
|
19
|
|
|
|
|
|
|
abstract_opts=>{logic=>'and'}, |
|
20
|
|
|
|
|
|
|
insert_delimiter=>',,', |
|
21
|
|
|
|
|
|
|
cdbi_search=>'search_abstract', |
|
22
|
|
|
|
|
|
|
#flags |
|
23
|
|
|
|
|
|
|
safe_update=>1, |
|
24
|
|
|
|
|
|
|
only_modified=>1, |
|
25
|
|
|
|
|
|
|
}, |
|
26
|
|
|
|
|
|
|
subs=>{parseHash=>{qw/a h/},parseHashref=>{qw/a hr/}, |
|
27
|
|
|
|
|
|
|
printTextTable=>{qw/a tt/} |
|
28
|
|
|
|
|
|
|
#search=>{sub=>'search'},search_like=>{} |
|
29
|
|
|
|
|
|
|
}, |
|
30
|
|
|
|
|
|
|
cmds=>{ |
|
31
|
|
|
|
|
|
|
print_columns=>{a=>'pc',d=>'Prints columns of current table',u=>''}, |
|
32
|
|
|
|
|
|
|
search_abstract=>{a=>'s',aa=>\&aliasInputAndSql, |
|
33
|
|
|
|
|
|
|
d=>'Search for results via AbstractSearch' |
|
34
|
|
|
|
|
|
|
,u=>'@search_term'}, |
|
35
|
|
|
|
|
|
|
cdbi_search=>{a=>'sn',aa=>\&aliasInputAndSql,u=>'@search_term'}, |
|
36
|
|
|
|
|
|
|
cdbi_search_like=>{a=>'sl',aa=>\&aliasInputAndSql,u=>'@search_term'}, |
|
37
|
|
|
|
|
|
|
cdbi_search_regex=>{a=>'sr',aa=>\&aliasInputAndSql,u=>'@search_term'}, |
|
38
|
|
|
|
|
|
|
cdbi_delete=>{a=>'d',aa=>\&aliasInputAndSql, |
|
39
|
|
|
|
|
|
|
d=>'Deletes results of given query',u=>'@search_term'}, |
|
40
|
|
|
|
|
|
|
cdbi_create=>{a=>'i',aa=>\&aliasInsert, d=>"Creates a record", |
|
41
|
|
|
|
|
|
|
u=>'($value$delim)+'}, |
|
42
|
|
|
|
|
|
|
cdbi_find_or_create=>{a=>'fc',aa=>\&aliasInputAndSql, d=>"Find or create a record", |
|
43
|
|
|
|
|
|
|
u=>'@search_term'}, |
|
44
|
|
|
|
|
|
|
cdbi_multi_insert=>{a=>'mi',arg=>'$file',u=>'$file'}, |
|
45
|
|
|
|
|
|
|
cdbi_update=>{a=>'U',aa=>\&aliasInputAndSql, d=>'Updates records via a text editor', |
|
46
|
|
|
|
|
|
|
u=>'@search_term'}, |
|
47
|
|
|
|
|
|
|
replace=>{d=>'evals each value of each result row with $operation', a=>'r', |
|
48
|
|
|
|
|
|
|
u=>'@search_term$operation'}, |
|
49
|
|
|
|
|
|
|
cdbi_delete_obj=>{a=>':d',u=>'@cdbi'}, |
|
50
|
|
|
|
|
|
|
cdbi_update_obj=>{a=>':U',u=>'@cdbi'}, |
|
51
|
|
|
|
|
|
|
verify_no_delim=>{a=>'V',aa=>\&aliasInputAndSql, u=>'@cdbi', |
|
52
|
|
|
|
|
|
|
d=>"Verify that specified records don't have display delimiter in them"}, |
|
53
|
|
|
|
|
|
|
display_table_list=>{qw/a dpt/, d=>'Displays public tables',u=>''}, |
|
54
|
|
|
|
|
|
|
print_dbi_log=>{a=>'dpl',d=>'Prints the current DBI log',u=>''}, |
|
55
|
|
|
|
|
|
|
clear_dbi_log=>{d=>'Clears the dbi log',u=>'',a=>'dcl',u=>''}, |
|
56
|
|
|
|
|
|
|
set_dbi_log_level=>{a=>'dsl',d=>'Sets the log level of a DBI handler', |
|
57
|
|
|
|
|
|
|
u=>'$num'}, |
|
58
|
|
|
|
|
|
|
}, |
|
59
|
|
|
|
|
|
|
opts=>{cdbi_search=>{qw/a cs type var noreset 1 default cdbi_search_regex/ }} |
|
60
|
|
|
|
|
|
|
#retrieve_all retrieve/], |
|
61
|
|
|
|
|
|
|
#construct,has*,trigger,constrain_column,set_sql |
|
62
|
|
|
|
|
|
|
#} |
|
63
|
|
|
|
|
|
|
#subs=>{aliasInputAndSql=>{}}, |
|
64
|
|
|
|
|
|
|
#td: obj-$result(autoupdate,update,delete,set/get,copy,discard_changes,is_changed),$iterator,$col,$relation |
|
65
|
|
|
|
|
|
|
} |
|
66
|
|
|
|
|
|
|
} |
|
67
|
|
|
|
|
|
|
sub _initLib { |
|
68
|
0
|
|
|
0
|
|
|
my $cls = shift; |
|
69
|
0
|
|
|
|
|
|
$cls->_set_insert_col; |
|
70
|
0
|
|
|
|
|
|
$cls->Var('abstract_opts')->{cmp} = $cls->_regex_operator; |
|
71
|
|
|
|
|
|
|
|
|
72
|
|
|
|
|
|
|
#ugly, should be in _default_data |
|
73
|
0
|
|
|
|
|
|
$cls->call(var=>'set','cdbi_search',enum=>[qw/cdbi_search cdbi_search_like cdbi_search_regex search_abstract/]); |
|
74
|
0
|
|
|
|
|
|
$cls->call(var=>'set','cdbi_search',default=>'cdbi_search_regex'); |
|
75
|
|
|
|
|
|
|
} |
|
76
|
|
|
|
|
|
|
#note for library use outside of shell |
|
77
|
|
|
|
|
|
|
#this module depends on external subs: &parse_num |
|
78
|
|
|
|
|
|
|
|
|
79
|
|
|
|
|
|
|
##utils |
|
80
|
|
|
|
|
|
|
sub uniqueInArrays { |
|
81
|
0
|
|
|
0
|
|
|
my ($cls,$uniq,$array2) =@_; |
|
82
|
0
|
|
|
|
|
|
my (@unique,%seen,$i,@num); |
|
83
|
|
|
|
|
|
|
|
|
84
|
0
|
|
|
|
|
|
for (@$array2) {$seen{$_}++} |
|
|
0
|
|
|
|
|
|
|
|
85
|
0
|
0
|
|
|
|
|
for (@$uniq) { $i++; do {push(@unique,$_);push(@num,$i) } if (! exists $seen{$_}) } |
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
86
|
0
|
|
|
|
|
|
return (\@unique,\@num); |
|
87
|
|
|
|
|
|
|
} |
|
88
|
|
|
|
|
|
|
sub file2array { |
|
89
|
0
|
|
|
0
|
|
|
shift; |
|
90
|
|
|
|
|
|
|
#local function |
|
91
|
|
|
|
|
|
|
#d:converts file to @ of lines |
|
92
|
0
|
|
|
|
|
|
open(FILE,"< $_[0]"); |
|
93
|
0
|
|
|
|
|
|
my @lines; chomp(@lines = ); |
|
|
0
|
|
|
|
|
|
|
|
94
|
0
|
|
|
|
|
|
close FILE; |
|
95
|
0
|
|
|
|
|
|
return @lines; |
|
96
|
|
|
|
|
|
|
} |
|
97
|
|
|
|
|
|
|
sub check_for_regex { |
|
98
|
|
|
|
|
|
|
#d: AoHregexp, could be used as an 'or' search on multiple columns |
|
99
|
0
|
|
|
0
|
|
|
my ($class,$regex,@records) = @_; |
|
100
|
0
|
|
|
|
|
|
my @unclean; |
|
101
|
|
|
|
|
|
|
|
|
102
|
0
|
|
|
|
|
|
for (@records) { |
|
103
|
0
|
|
|
|
|
|
for my $col (@{$class->Var('action_columns')}) { |
|
|
0
|
|
|
|
|
|
|
|
104
|
0
|
0
|
|
|
|
|
if ($_->$col =~ /$regex/) { |
|
105
|
0
|
|
|
|
|
|
push(@unclean,$_); |
|
106
|
0
|
|
|
|
|
|
last; #break? |
|
107
|
|
|
|
|
|
|
} |
|
108
|
|
|
|
|
|
|
} |
|
109
|
|
|
|
|
|
|
} |
|
110
|
0
|
|
|
|
|
|
return @unclean; |
|
111
|
|
|
|
|
|
|
} |
|
112
|
|
|
|
|
|
|
#internal methods |
|
113
|
|
|
|
|
|
|
sub _set_insert_col { |
|
114
|
0
|
|
|
0
|
|
|
my $cls = shift; |
|
115
|
|
|
|
|
|
|
#set insert_columns |
|
116
|
0
|
|
|
|
|
|
my @insert_columns = @{$cls->Var('columns')}; |
|
|
0
|
|
|
|
|
|
|
|
117
|
0
|
|
|
|
|
|
shift @insert_columns; |
|
118
|
0
|
|
|
|
|
|
$cls->setVar(insert_columns=>\@insert_columns); |
|
119
|
|
|
|
|
|
|
|
|
120
|
|
|
|
|
|
|
} |
|
121
|
|
|
|
|
|
|
sub regexChangeAoH { |
|
122
|
0
|
|
|
0
|
|
|
my ($cls,$op,@records2update) = @_; |
|
123
|
0
|
|
|
|
|
|
for my $rec (@records2update) { |
|
124
|
0
|
|
|
|
|
|
for (my $j=0; $j < @{$cls->Var('action_columns')}; $j++) { |
|
|
0
|
|
|
|
|
|
|
|
125
|
0
|
|
|
|
|
|
my $col= $cls->Var('action_columns')->[$j]; |
|
126
|
0
|
|
|
|
|
|
$_ = $rec->$col; |
|
127
|
0
|
0
|
|
|
|
|
eval $op; die($@) if $@; |
|
|
0
|
|
|
|
|
|
|
|
128
|
0
|
|
|
|
|
|
$rec->$col($_); |
|
129
|
|
|
|
|
|
|
} |
|
130
|
0
|
|
|
|
|
|
$rec->update; |
|
131
|
|
|
|
|
|
|
} |
|
132
|
|
|
|
|
|
|
} |
|
133
|
|
|
|
|
|
|
sub modify_file { |
|
134
|
0
|
|
|
0
|
|
|
my ($cls,$tempfile) = @_; |
|
135
|
0
|
|
|
|
|
|
my $inp; |
|
136
|
|
|
|
|
|
|
|
|
137
|
0
|
|
|
|
|
|
system($cls->Var('editor') . " $tempfile");# or die "can't execute command as $<: $@"; |
|
138
|
|
|
|
|
|
|
#?: why does this system always return a fail code |
|
139
|
|
|
|
|
|
|
#$cls->view("cdbi_update (y/n)? "); chomp($inp = ); |
|
140
|
0
|
|
|
|
|
|
$inp = $cls->Rline->stdin("cdbi_update (y/n)?"); |
|
141
|
0
|
|
|
|
|
|
return ($inp eq "y"); |
|
142
|
|
|
|
|
|
|
} |
|
143
|
|
|
|
|
|
|
sub update_from_file { |
|
144
|
0
|
|
|
0
|
|
|
my ($cls,$tempfile,@records) = @_; |
|
145
|
|
|
|
|
|
|
|
|
146
|
0
|
|
|
|
|
|
my @lines = $cls->file2array($tempfile); |
|
147
|
|
|
|
|
|
|
|
|
148
|
|
|
|
|
|
|
#my $firstline = shift(@lines); |
|
149
|
|
|
|
|
|
|
#read column order from file |
|
150
|
|
|
|
|
|
|
#my @fields = split(/$updatedelim/,$firstline); |
|
151
|
|
|
|
|
|
|
#or not |
|
152
|
0
|
|
|
|
|
|
my @fields = @{$cls->Var('action_columns')}; |
|
|
0
|
|
|
|
|
|
|
|
153
|
|
|
|
|
|
|
|
|
154
|
0
|
|
|
|
|
|
my $i; |
|
155
|
0
|
|
|
|
|
|
foreach (@records) { #each row to update |
|
156
|
0
|
|
|
|
|
|
my @fvalues = split(/${\$cls->Var('field_delimiter')}/,$lines[$i]); |
|
|
0
|
|
|
|
|
|
|
|
157
|
0
|
|
|
|
|
|
for (my $j=0; $j < @fields; $j++) { #each column to update |
|
158
|
|
|
|
|
|
|
|
|
159
|
0
|
|
|
|
|
|
my $temp=$fields[$j]; |
|
160
|
0
|
|
|
|
|
|
$_->$temp($fvalues[$j]); # this line = $_->$field($fieldvalue) |
|
161
|
|
|
|
|
|
|
} |
|
162
|
0
|
|
|
|
|
|
$_->update; |
|
163
|
|
|
|
|
|
|
#$_->dbi_commit if ($db = postgres |
|
164
|
0
|
|
|
|
|
|
$i++; |
|
165
|
|
|
|
|
|
|
} |
|
166
|
|
|
|
|
|
|
} |
|
167
|
|
|
|
|
|
|
sub col2f1 { |
|
168
|
|
|
|
|
|
|
#d: aliases column names with c and number |
|
169
|
0
|
|
|
0
|
|
|
my $class = shift; |
|
170
|
0
|
|
|
|
|
|
my @newterms; |
|
171
|
|
|
|
|
|
|
|
|
172
|
0
|
|
|
|
|
|
for (@_) { |
|
173
|
|
|
|
|
|
|
#if (/c(\d+)=/) { my $col = $col[$1-1];s/c\d+/$col/} |
|
174
|
0
|
0
|
|
|
|
|
if (/c([-,\d]+)(.*)/) { |
|
|
0
|
|
|
|
|
|
|
|
175
|
0
|
|
|
|
|
|
my @tempcol = $class->sub->parseNum($1,@{$class->Var('columns')}); |
|
|
0
|
|
|
|
|
|
|
|
176
|
0
|
|
|
|
|
|
for my $eachcol (@tempcol) { |
|
177
|
0
|
|
|
|
|
|
push(@newterms,$eachcol.$2); |
|
178
|
|
|
|
|
|
|
} |
|
179
|
|
|
|
|
|
|
} |
|
180
|
|
|
|
|
|
|
else {push (@newterms,$_)} |
|
181
|
|
|
|
|
|
|
} |
|
182
|
0
|
|
|
|
|
|
return @newterms; |
|
183
|
|
|
|
|
|
|
} |
|
184
|
|
|
|
|
|
|
#sub objects |
|
185
|
|
|
|
|
|
|
##print functions,input is objects |
|
186
|
|
|
|
|
|
|
sub printtofile { |
|
187
|
|
|
|
|
|
|
#d:prints rows to temporary file |
|
188
|
0
|
|
|
0
|
|
|
my ($cls,$tempfile,@records) = @_; |
|
189
|
|
|
|
|
|
|
|
|
190
|
0
|
|
|
|
|
|
my $output = join($cls->Var('field_delimiter'),@{$cls->Var('action_columns')})."\n"; |
|
|
0
|
|
|
|
|
|
|
|
191
|
0
|
|
|
|
|
|
$output .= $cls->View->objAoH_dt(\@records,$cls->Var('action_columns')); |
|
192
|
0
|
|
|
|
|
|
$cls->View->file($tempfile,$output); |
|
193
|
|
|
|
|
|
|
} |
|
194
|
|
|
|
|
|
|
sub printTextTable { |
|
195
|
0
|
|
|
0
|
|
|
my $cls = shift; |
|
196
|
0
|
|
|
|
|
|
$cls->print_text_table(\@_,$cls->Var('action_columns')); |
|
197
|
|
|
|
|
|
|
} |
|
198
|
|
|
|
|
|
|
sub print_text_table { |
|
199
|
|
|
|
|
|
|
my $cls = shift; |
|
200
|
|
|
|
|
|
|
my ($ref1,$ref2) = @_; my @row = @{$ref1}; my @columns = @{$ref2}; |
|
201
|
|
|
|
|
|
|
my (@column_values,@longest); |
|
202
|
|
|
|
|
|
|
|
|
203
|
|
|
|
|
|
|
#defaul |
|
204
|
1
|
|
|
1
|
|
387
|
eval { use Text::Reform}; die $@ if ($@); |
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
205
|
|
|
|
|
|
|
|
|
206
|
|
|
|
|
|
|
for my $column (@columns) { |
|
207
|
|
|
|
|
|
|
my @column_value; |
|
208
|
|
|
|
|
|
|
my $longest = length($column); |
|
209
|
|
|
|
|
|
|
for (@row) { |
|
210
|
|
|
|
|
|
|
#find longest string in each column including string |
|
211
|
|
|
|
|
|
|
my $newlength = length($_->$column); |
|
212
|
|
|
|
|
|
|
$longest = $newlength if ($newlength > $longest); |
|
213
|
|
|
|
|
|
|
|
|
214
|
|
|
|
|
|
|
push(@column_value,$_->$column); |
|
215
|
|
|
|
|
|
|
} |
|
216
|
|
|
|
|
|
|
push(@longest,$longest); |
|
217
|
|
|
|
|
|
|
push(@column_values,\@column_value); |
|
218
|
|
|
|
|
|
|
} |
|
219
|
|
|
|
|
|
|
|
|
220
|
|
|
|
|
|
|
#create format |
|
221
|
|
|
|
|
|
|
my $line_length = 3 * @columns + 1; |
|
222
|
|
|
|
|
|
|
my $picture_line = "|"; |
|
223
|
|
|
|
|
|
|
|
|
224
|
|
|
|
|
|
|
for (@longest) { |
|
225
|
|
|
|
|
|
|
$line_length += $_ ; |
|
226
|
|
|
|
|
|
|
$picture_line .= " " . "["x $_ . " |"; |
|
227
|
|
|
|
|
|
|
} |
|
228
|
|
|
|
|
|
|
my $firstline = "=" x $line_length; |
|
229
|
|
|
|
|
|
|
#$picture_line .= "\n" . "-" x $line_length; |
|
230
|
|
|
|
|
|
|
|
|
231
|
|
|
|
|
|
|
#print column names |
|
232
|
|
|
|
|
|
|
$cls->view(form $picture_line,@columns); |
|
233
|
|
|
|
|
|
|
#print body |
|
234
|
|
|
|
|
|
|
$cls->view(form $firstline,$picture_line, @column_values); |
|
235
|
|
|
|
|
|
|
} |
|
236
|
|
|
|
|
|
|
sub print_horizontal_numbered_list { |
|
237
|
|
|
|
|
|
|
my ($cls,$prompt,$list) = @_; |
|
238
|
|
|
|
|
|
|
my $a; |
|
239
|
|
|
|
|
|
|
|
|
240
|
|
|
|
|
|
|
my $output = $prompt; |
|
241
|
|
|
|
|
|
|
for (@$list){$a++;$output .= "$a.$_ " }; |
|
242
|
|
|
|
|
|
|
$output .= "\n"; |
|
243
|
|
|
|
|
|
|
$cls->view($output); |
|
244
|
|
|
|
|
|
|
} |
|
245
|
|
|
|
|
|
|
##alias fns |
|
246
|
|
|
|
|
|
|
sub cdbiDbh { shift->Var('table_class')->db_Main } |
|
247
|
|
|
|
|
|
|
sub aliasInputAndSql { my $cls = shift; |
|
248
|
|
|
|
|
|
|
return $cls->aliasSqlAbstract($cls->aliasInput(@_)) } |
|
249
|
|
|
|
|
|
|
sub aliasInput { |
|
250
|
|
|
|
|
|
|
my $class = shift; |
|
251
|
|
|
|
|
|
|
@_ = $class->Var('columns')->[0].$class->Var('splitter').".*" if ($_[0] eq "a"); #all results given |
|
252
|
|
|
|
|
|
|
@_ = $class->col2f1(@_) if ("@_" =~ /c[-,\d]+=/); #c\d instead of column name |
|
253
|
|
|
|
|
|
|
return @_; |
|
254
|
|
|
|
|
|
|
} |
|
255
|
|
|
|
|
|
|
sub aliasInsert { |
|
256
|
|
|
|
|
|
|
#d:parses userinput to hashref for &create |
|
257
|
|
|
|
|
|
|
my $cls = shift; |
|
258
|
|
|
|
|
|
|
my %chosenf; |
|
259
|
|
|
|
|
|
|
#die "Nothing given for cdbi_insert" if (not defined @_); |
|
260
|
|
|
|
|
|
|
my @fields = split(/${\$cls->Var('insert_delimiter')}/,"@_"); |
|
261
|
|
|
|
|
|
|
my @insert_columns = @{$cls->Var('insert_columns')}; |
|
262
|
|
|
|
|
|
|
|
|
263
|
|
|
|
|
|
|
for (my $i=0;$i< @insert_columns;$i++) { |
|
264
|
|
|
|
|
|
|
$chosenf{$insert_columns[$i]} = $fields[$i]; |
|
265
|
|
|
|
|
|
|
$cls->view("$insert_columns[$i] = $fields[$i]\n"); |
|
266
|
|
|
|
|
|
|
} |
|
267
|
|
|
|
|
|
|
return \%chosenf; |
|
268
|
|
|
|
|
|
|
} |
|
269
|
|
|
|
|
|
|
sub aliasSqlAbstract { |
|
270
|
|
|
|
|
|
|
#d:parse to feed to sql::abstract |
|
271
|
|
|
|
|
|
|
#note: operators hardcoded for now |
|
272
|
|
|
|
|
|
|
my $class = shift; |
|
273
|
|
|
|
|
|
|
my @processf; |
|
274
|
|
|
|
|
|
|
my $splitter = $class->Var('splitter'); |
|
275
|
|
|
|
|
|
|
|
|
276
|
|
|
|
|
|
|
foreach (@_) { |
|
277
|
|
|
|
|
|
|
if (/$splitter([>!<])=/) { |
|
278
|
|
|
|
|
|
|
my $operator = $1; |
|
279
|
|
|
|
|
|
|
my ($key,$value) = split(/=$operator=/); |
|
280
|
|
|
|
|
|
|
push(@processf,$key,{"$operator\=",$value}); |
|
281
|
|
|
|
|
|
|
} |
|
282
|
|
|
|
|
|
|
elsif (/$splitter([><=])/) { |
|
283
|
|
|
|
|
|
|
my $operator = $1; |
|
284
|
|
|
|
|
|
|
my ($key,$value) = split (/$splitter$operator/); |
|
285
|
|
|
|
|
|
|
push(@processf,$key,{$operator,$value}); |
|
286
|
|
|
|
|
|
|
} |
|
287
|
|
|
|
|
|
|
#embedded sql |
|
288
|
|
|
|
|
|
|
elsif (/$splitter(.*)$splitter/) { |
|
289
|
|
|
|
|
|
|
my $literal_sql = $1; |
|
290
|
|
|
|
|
|
|
$literal_sql =~ s/_/ /g; |
|
291
|
|
|
|
|
|
|
my ($key,$dump) = split (/$splitter/); |
|
292
|
|
|
|
|
|
|
push(@processf,$key,\$literal_sql); |
|
293
|
|
|
|
|
|
|
} |
|
294
|
|
|
|
|
|
|
#default operator |
|
295
|
|
|
|
|
|
|
#elsif(/=/) |
|
296
|
|
|
|
|
|
|
else { |
|
297
|
|
|
|
|
|
|
my ($key,$value) = split(/$splitter/) or die "error splitting select"; |
|
298
|
|
|
|
|
|
|
push(@processf,$key,$value); |
|
299
|
|
|
|
|
|
|
} |
|
300
|
|
|
|
|
|
|
#else { warn "no valid operator specified" }; |
|
301
|
|
|
|
|
|
|
} |
|
302
|
|
|
|
|
|
|
return @processf; |
|
303
|
|
|
|
|
|
|
} |
|
304
|
|
|
|
|
|
|
##parse functions,input is from commandine |
|
305
|
|
|
|
|
|
|
sub parseHash { |
|
306
|
|
|
|
|
|
|
my ($cls,$input) = @_; |
|
307
|
|
|
|
|
|
|
|
|
308
|
|
|
|
|
|
|
my @arg = split(/ /,$input); |
|
309
|
|
|
|
|
|
|
my $cmd = shift @arg; |
|
310
|
|
|
|
|
|
|
my %results = $cls->parseIndHash($cls->Var('splitter'),@arg); |
|
311
|
|
|
|
|
|
|
return ($cmd,%results) |
|
312
|
|
|
|
|
|
|
} |
|
313
|
|
|
|
|
|
|
sub parseHashref { |
|
314
|
|
|
|
|
|
|
my ($cls,$input) = @_; |
|
315
|
|
|
|
|
|
|
my ($cmd,%results) = $cls->parseHash($input); |
|
316
|
|
|
|
|
|
|
return ($cmd,\%results); |
|
317
|
|
|
|
|
|
|
} |
|
318
|
|
|
|
|
|
|
sub parseIndHash { |
|
319
|
|
|
|
|
|
|
my ($class,$splitter,@chunks) = @_; |
|
320
|
|
|
|
|
|
|
my %processf; |
|
321
|
|
|
|
|
|
|
|
|
322
|
|
|
|
|
|
|
for (@chunks) { |
|
323
|
|
|
|
|
|
|
my ($key,$value) = split(/$splitter/) or die "error splitting select"; |
|
324
|
|
|
|
|
|
|
$processf{$key} = $value; |
|
325
|
|
|
|
|
|
|
} |
|
326
|
|
|
|
|
|
|
return %processf; |
|
327
|
|
|
|
|
|
|
} |
|
328
|
|
|
|
|
|
|
#commands |
|
329
|
|
|
|
|
|
|
sub print_columns { |
|
330
|
|
|
|
|
|
|
my $cls = shift; |
|
331
|
|
|
|
|
|
|
$cls->print_horizontal_numbered_list($cls->Var('table')."'s columns are ",$cls->Var('columns')); |
|
332
|
|
|
|
|
|
|
} |
|
333
|
|
|
|
|
|
|
sub search_abstract { |
|
334
|
|
|
|
|
|
|
#d:handles multiple parsing cases and returns search results |
|
335
|
|
|
|
|
|
|
my $cls = shift; |
|
336
|
|
|
|
|
|
|
if (@_ ==0 ) {warn("No arguments given to &search_abstract\n");return () } |
|
337
|
|
|
|
|
|
|
$cls->sub->_require('Class::DBI::AbstractSearch'); |
|
338
|
|
|
|
|
|
|
$cls->sub->useThere('Class::DBI::AbstractSearch',$cls->Var('table_class')); |
|
339
|
|
|
|
|
|
|
|
|
340
|
|
|
|
|
|
|
#calling class determines class |
|
341
|
|
|
|
|
|
|
my @results = $cls->Var('table_class')->Class::DBI::AbstractSearch::search_where(\@_,$cls->Var('abstract_opts')); |
|
342
|
|
|
|
|
|
|
$cls->saveArray(@results) if ($cls->Flag('menu')); |
|
343
|
|
|
|
|
|
|
return @results; |
|
344
|
|
|
|
|
|
|
} |
|
345
|
|
|
|
|
|
|
sub cdbi_search { shift->Var('table_class')->search(@_) } |
|
346
|
|
|
|
|
|
|
sub cdbi_search_like { shift->Var('table_class')->search_like(@_) } |
|
347
|
|
|
|
|
|
|
sub cdbi_search_regex { shift->Var('table_class')->search_regex(@_) } |
|
348
|
|
|
|
|
|
|
sub cdbi_create { shift->Var('table_class')->create(@_) } |
|
349
|
|
|
|
|
|
|
sub cdbi_delete { |
|
350
|
|
|
|
|
|
|
#td: chain |
|
351
|
|
|
|
|
|
|
my $cls = shift; |
|
352
|
|
|
|
|
|
|
my @aliasedinput = @_; |
|
353
|
|
|
|
|
|
|
my @results = $cls->${\$cls->Var('cdbi_search')}(@aliasedinput); |
|
354
|
|
|
|
|
|
|
#my @results = $cls->sub->subHook(args=>\@aliasedinput,var=>'cdbi_search',default=>'search_abstract',caller=>$cls); |
|
355
|
|
|
|
|
|
|
$cls->cdbi_delete_obj(@results); |
|
356
|
|
|
|
|
|
|
} |
|
357
|
|
|
|
|
|
|
sub cdbi_find_or_create { |
|
358
|
|
|
|
|
|
|
my ($cls,%dt) = @_; |
|
359
|
|
|
|
|
|
|
#my $hash = ref $_[0] eq "HASH" ? shift: {@_}; |
|
360
|
|
|
|
|
|
|
my ($exists) = $cls->${\$cls->Var('cdbi_search')}(%dt); |
|
361
|
|
|
|
|
|
|
return defined($exists) ? $exists : $cls->Var('table_class')->create(\%dt); |
|
362
|
|
|
|
|
|
|
} |
|
363
|
|
|
|
|
|
|
sub cdbi_multi_insert { |
|
364
|
|
|
|
|
|
|
my ($cls,$file) = @_; |
|
365
|
|
|
|
|
|
|
|
|
366
|
|
|
|
|
|
|
chomp(my @lines= $cls->file2array($file)); |
|
367
|
|
|
|
|
|
|
for (@lines) { |
|
368
|
|
|
|
|
|
|
$cls->create($cls->aliasInsert($_)); |
|
369
|
|
|
|
|
|
|
} |
|
370
|
|
|
|
|
|
|
} |
|
371
|
|
|
|
|
|
|
sub replace { |
|
372
|
|
|
|
|
|
|
#td:chain |
|
373
|
|
|
|
|
|
|
my $cls = shift; |
|
374
|
|
|
|
|
|
|
my $op = pop(@_); |
|
375
|
|
|
|
|
|
|
|
|
376
|
|
|
|
|
|
|
my @records2update = $cls->${\$cls->Var('cdbi_search')}($cls->aliasInputAndSql(@_)); |
|
377
|
|
|
|
|
|
|
$cls->regexChangeAoH($op,@records2update); |
|
378
|
|
|
|
|
|
|
} |
|
379
|
|
|
|
|
|
|
sub verify_no_delim { |
|
380
|
|
|
|
|
|
|
#td:chain |
|
381
|
|
|
|
|
|
|
my $cls = shift; |
|
382
|
|
|
|
|
|
|
|
|
383
|
|
|
|
|
|
|
my @records2update = $cls->${\$cls->Var('cdbi_search')}(@_); |
|
384
|
|
|
|
|
|
|
my $clean = $cls->verify_no_delim_obj(@records2update); |
|
385
|
|
|
|
|
|
|
$cls->view("No records containing delimiter found") if ($clean); |
|
386
|
|
|
|
|
|
|
} |
|
387
|
|
|
|
|
|
|
sub cdbi_update { |
|
388
|
|
|
|
|
|
|
#td:chain |
|
389
|
|
|
|
|
|
|
my $cls = shift; |
|
390
|
|
|
|
|
|
|
#$cls->cdbi_update_obj($cls->${\$cls->Var('cdbi_search')}(@_)); |
|
391
|
|
|
|
|
|
|
$cls->cdbi_update_obj($cls->search_abstract(@_)); |
|
392
|
|
|
|
|
|
|
} |
|
393
|
|
|
|
|
|
|
##$result obj |
|
394
|
|
|
|
|
|
|
sub cdbi_update_obj { |
|
395
|
|
|
|
|
|
|
my ($cls,@records2update) = @_; |
|
396
|
|
|
|
|
|
|
$cls->sub->_require('File::Temp'); |
|
397
|
|
|
|
|
|
|
do {warn("File::Temp"); return} if ($@); |
|
398
|
|
|
|
|
|
|
my (undef,$tempfile) = File::Temp::tempfile(); |
|
399
|
|
|
|
|
|
|
#$tempfile = 'ya'; |
|
400
|
|
|
|
|
|
|
|
|
401
|
|
|
|
|
|
|
if ($cls->Flag('safe_update')) { |
|
402
|
|
|
|
|
|
|
my $clean = $cls->verify_no_delim_obj(@records2update); |
|
403
|
|
|
|
|
|
|
return if (not $clean); |
|
404
|
|
|
|
|
|
|
} |
|
405
|
|
|
|
|
|
|
|
|
406
|
|
|
|
|
|
|
$cls->printtofile($tempfile,@records2update); |
|
407
|
|
|
|
|
|
|
|
|
408
|
|
|
|
|
|
|
#only for changed rec |
|
409
|
|
|
|
|
|
|
my @original_lines = $cls->file2array($tempfile) |
|
410
|
|
|
|
|
|
|
if ($cls->Flag('only_modified')); |
|
411
|
|
|
|
|
|
|
|
|
412
|
|
|
|
|
|
|
my $modify = $cls->modify_file($tempfile); |
|
413
|
|
|
|
|
|
|
|
|
414
|
|
|
|
|
|
|
#only update changed records |
|
415
|
|
|
|
|
|
|
if ($cls->Flag('only_modified')) { |
|
416
|
|
|
|
|
|
|
my @new_lines = $cls->file2array($tempfile); |
|
417
|
|
|
|
|
|
|
#shift off columns line |
|
418
|
|
|
|
|
|
|
shift(@new_lines); shift(@original_lines); |
|
419
|
|
|
|
|
|
|
|
|
420
|
|
|
|
|
|
|
my ($modified_lines,$num) = ([],[]); |
|
421
|
|
|
|
|
|
|
($modified_lines,$num) = $cls->uniqueInArrays(\@new_lines,\@original_lines); |
|
422
|
|
|
|
|
|
|
#exit early if nothing to modify |
|
423
|
|
|
|
|
|
|
if (@$modified_lines == 0) { $modify = 0; last } |
|
424
|
|
|
|
|
|
|
|
|
425
|
|
|
|
|
|
|
#write new file |
|
426
|
|
|
|
|
|
|
$cls->View->file($tempfile,join("\n",@$modified_lines)); |
|
427
|
|
|
|
|
|
|
@records2update = $cls->sub->parseNum(join(',',@$num),@records2update); |
|
428
|
|
|
|
|
|
|
} |
|
429
|
|
|
|
|
|
|
|
|
430
|
|
|
|
|
|
|
$cls->update_from_file($tempfile,@records2update) if ($modify); |
|
431
|
|
|
|
|
|
|
} |
|
432
|
|
|
|
|
|
|
sub verify_no_delim_obj { |
|
433
|
|
|
|
|
|
|
my ($cls,@records) = @_; |
|
434
|
|
|
|
|
|
|
|
|
435
|
|
|
|
|
|
|
my @unclean_records = |
|
436
|
|
|
|
|
|
|
$cls->check_for_regex($cls->Var('field_delimiter'),@records); |
|
437
|
|
|
|
|
|
|
#$cls->check_for_regex('a',@records); |
|
438
|
|
|
|
|
|
|
|
|
439
|
|
|
|
|
|
|
if (defined @unclean_records) { |
|
440
|
|
|
|
|
|
|
$cls->view( "The following are records containing the delimiter '", |
|
441
|
|
|
|
|
|
|
$cls->Var('field_delimiter'),"':\n\n"); |
|
442
|
|
|
|
|
|
|
$cls->View->objAoH(\@unclean_records,$cls->Var('action_columns')); |
|
443
|
|
|
|
|
|
|
return 0; |
|
444
|
|
|
|
|
|
|
} |
|
445
|
|
|
|
|
|
|
#passed successfully |
|
446
|
|
|
|
|
|
|
return 1; |
|
447
|
|
|
|
|
|
|
} |
|
448
|
|
|
|
|
|
|
sub cdbi_delete_obj { |
|
449
|
|
|
|
|
|
|
my $class = shift; |
|
450
|
|
|
|
|
|
|
for (@_) { $_->delete; } |
|
451
|
|
|
|
|
|
|
} |
|
452
|
|
|
|
|
|
|
#$dbh commands: could be used in DBI |
|
453
|
|
|
|
|
|
|
sub display_table_list { |
|
454
|
|
|
|
|
|
|
my ($class,$dbh) = @_; |
|
455
|
|
|
|
|
|
|
$class->print_horizontal_numbered_list("Database's tables are ",[$class->get_table_list($dbh)]); |
|
456
|
|
|
|
|
|
|
} |
|
457
|
|
|
|
|
|
|
sub print_dbi_log { |
|
458
|
|
|
|
|
|
|
my ($cls) = @_; |
|
459
|
|
|
|
|
|
|
my $dbh = $cls->cdbiDbh; |
|
460
|
|
|
|
|
|
|
$cls->view($dbh->{Profile}->format); |
|
461
|
|
|
|
|
|
|
} |
|
462
|
|
|
|
|
|
|
sub clear_dbi_log { |
|
463
|
|
|
|
|
|
|
my ($cls) = @_; |
|
464
|
|
|
|
|
|
|
my $dbh = $cls->cdbiDbh; |
|
465
|
|
|
|
|
|
|
$dbh->{Profile}->{Data}=undef; |
|
466
|
|
|
|
|
|
|
} |
|
467
|
|
|
|
|
|
|
sub set_dbi_log_level{ |
|
468
|
|
|
|
|
|
|
my ($cls,$num) = @_; |
|
469
|
|
|
|
|
|
|
my $dbh = $cls->cdbiDbh; |
|
470
|
|
|
|
|
|
|
|
|
471
|
|
|
|
|
|
|
if ($num > 15 or $num < -15) { |
|
472
|
|
|
|
|
|
|
warn" given log level out of -15 to 15 range"; |
|
473
|
|
|
|
|
|
|
} |
|
474
|
|
|
|
|
|
|
else { $dbh->{Profile} = $num; } |
|
475
|
|
|
|
|
|
|
} |
|
476
|
|
|
|
|
|
|
#$dbh = (defined $dbh) ? $cls->idToObj($dbh) : $cls->cdbiDbh; |
|
477
|
|
|
|
|
|
|
##other |
|
478
|
|
|
|
|
|
|
sub t_file { |
|
479
|
|
|
|
|
|
|
my $cls = shift; |
|
480
|
|
|
|
|
|
|
#w |
|
481
|
|
|
|
|
|
|
my $file = shift || do { $cls->view("No file given.\n"); return 0 }; |
|
482
|
|
|
|
|
|
|
if (! -e $file) { $cls->view("File doesn't exist.\n"); return 0}; |
|
483
|
|
|
|
|
|
|
return 1; |
|
484
|
|
|
|
|
|
|
} |
|
485
|
|
|
|
|
|
|
sub cmpl_file { |
|
486
|
|
|
|
|
|
|
} |
|
487
|
|
|
|
|
|
|
###internal |
|
488
|
|
|
|
|
|
|
sub get_table_list { |
|
489
|
|
|
|
|
|
|
my ($cls,$dbh) = @_; |
|
490
|
|
|
|
|
|
|
$dbh = (defined $dbh) ? $cls->idToObj($dbh) : $cls->cdbiDbh; |
|
491
|
|
|
|
|
|
|
my $sth = $cls->get_table_info($dbh); |
|
492
|
|
|
|
|
|
|
return warn "Driver hasn't implemented the table_info() method" unless (ref $sth); |
|
493
|
|
|
|
|
|
|
my @tables = map {$_->[2]} @{$sth->fetchall_arrayref}; |
|
494
|
|
|
|
|
|
|
return @tables; |
|
495
|
|
|
|
|
|
|
} |
|
496
|
|
|
|
|
|
|
sub get_table_info { |
|
497
|
|
|
|
|
|
|
#d: displays public tables for postgres, may have to adjust &table_info per database |
|
498
|
|
|
|
|
|
|
my ($class,$dbh,$table) = @_; |
|
499
|
|
|
|
|
|
|
my $catalog = undef; |
|
500
|
|
|
|
|
|
|
my $schema = ($class->Var('db') eq "postgres") ? 'public' : undef; |
|
501
|
|
|
|
|
|
|
my $type; |
|
502
|
|
|
|
|
|
|
return $dbh->table_info($catalog,$schema,$table,$type); |
|
503
|
|
|
|
|
|
|
} |
|
504
|
|
|
|
|
|
|
1; |
|
505
|
|
|
|
|
|
|
|
|
506
|
|
|
|
|
|
|
__END__ |