line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
#$Id: LoadDB.pm,v 1.30 2009/09/30 07:37:09 dinosau2 Exp $ |
2
|
|
|
|
|
|
|
# /* vim:et: set ts=4 sw=4 sts=4 tw=78: */ |
3
|
|
|
|
|
|
|
|
4
|
|
|
|
|
|
|
package ACME::QuoteDB::LoadDB; |
5
|
|
|
|
|
|
|
|
6
|
7
|
|
|
7
|
|
127732
|
use 5.008005; # require perl 5.8.5, re: DBD::SQLite Unicode |
|
7
|
|
|
|
|
25
|
|
|
7
|
|
|
|
|
292
|
|
7
|
7
|
|
|
7
|
|
42
|
use warnings; |
|
7
|
|
|
|
|
16
|
|
|
7
|
|
|
|
|
386
|
|
8
|
7
|
|
|
7
|
|
43
|
use strict; |
|
7
|
|
|
|
|
12
|
|
|
7
|
|
|
|
|
258
|
|
9
|
|
|
|
|
|
|
|
10
|
|
|
|
|
|
|
#use criticism 'brutal'; # use critic with a ~/.perlcriticrc |
11
|
|
|
|
|
|
|
|
12
|
7
|
|
|
7
|
|
1206
|
use version; our $VERSION = qv('0.1.1'); |
|
7
|
|
|
|
|
3139
|
|
|
7
|
|
|
|
|
48
|
|
13
|
|
|
|
|
|
|
|
14
|
|
|
|
|
|
|
# with Text::CSV only use 'perl csv loader' |
15
|
|
|
|
|
|
|
# 'one time' db load performance not a concern |
16
|
7
|
|
|
7
|
|
967
|
BEGIN {local $ENV{PERL_TEXT_CSV} = 0} |
17
|
|
|
|
|
|
|
|
18
|
7
|
|
|
7
|
|
10250
|
use aliased 'ACME::QuoteDB::DB::Attribution' => 'Attr'; |
|
7
|
|
|
|
|
6114
|
|
|
7
|
|
|
|
|
44
|
|
19
|
7
|
|
|
7
|
|
817
|
use aliased 'ACME::QuoteDB::DB::QuoteCatg' => 'QuoteCatg'; |
|
7
|
|
|
|
|
13
|
|
|
7
|
|
|
|
|
45
|
|
20
|
7
|
|
|
7
|
|
692
|
use aliased 'ACME::QuoteDB::DB::Category' => 'Catg'; |
|
7
|
|
|
|
|
16
|
|
|
7
|
|
|
|
|
42
|
|
21
|
7
|
|
|
7
|
|
912
|
use aliased 'ACME::QuoteDB::DB::Quote' => 'Quote'; |
|
7
|
|
|
|
|
21
|
|
|
7
|
|
|
|
|
41
|
|
22
|
7
|
|
|
7
|
|
1045
|
use aliased 'ACME::QuoteDB::DB::DBI' => 'QDBI'; |
|
7
|
|
|
|
|
14
|
|
|
7
|
|
|
|
|
38
|
|
23
|
7
|
|
|
7
|
|
1043
|
use File::Basename qw/dirname basename/; |
|
7
|
|
|
|
|
18
|
|
|
7
|
|
|
|
|
739
|
|
24
|
7
|
|
|
7
|
|
45
|
use File::Glob qw(:globally :nocase); |
|
7
|
|
|
|
|
16
|
|
|
7
|
|
|
|
|
409
|
|
25
|
7
|
|
|
7
|
|
23393
|
use Encode qw/is_utf8 decode/; |
|
7
|
|
|
|
|
95612
|
|
|
7
|
|
|
|
|
764
|
|
26
|
7
|
|
|
7
|
|
1543
|
use Data::Dumper qw/Dumper/; |
|
7
|
|
|
|
|
6649
|
|
|
7
|
|
|
|
|
403
|
|
27
|
7
|
|
|
7
|
|
125
|
use Carp qw/carp croak/; |
|
7
|
|
|
|
|
16
|
|
|
7
|
|
|
|
|
445
|
|
28
|
7
|
|
|
7
|
|
8826
|
use Text::CSV; |
|
7
|
|
|
|
|
122143
|
|
|
7
|
|
|
|
|
51
|
|
29
|
7
|
|
|
7
|
|
328
|
use Readonly; |
|
7
|
|
|
|
|
18
|
|
|
7
|
|
|
|
|
491
|
|
30
|
7
|
|
|
7
|
|
47
|
use DBI; |
|
7
|
|
|
|
|
15
|
|
|
7
|
|
|
|
|
31498
|
|
31
|
|
|
|
|
|
|
|
32
|
|
|
|
|
|
|
# if not in utf8 latin1 is assumed |
33
|
|
|
|
|
|
|
my $FILE_ENCODING = 'iso-8859-1'; |
34
|
|
|
|
|
|
|
|
35
|
|
|
|
|
|
|
Readonly my @QUOTE_FIELDS => qw/quote name source catg rating/; |
36
|
|
|
|
|
|
|
|
37
|
|
|
|
|
|
|
# XXX refactor |
38
|
|
|
|
|
|
|
sub new { |
39
|
13
|
|
|
13
|
1
|
6670
|
my ($class, $args) = @_; |
40
|
|
|
|
|
|
|
|
41
|
|
|
|
|
|
|
# TODO encapsulation |
42
|
13
|
|
|
|
|
55
|
my $self = bless {}, $class; |
43
|
|
|
|
|
|
|
|
44
|
|
|
|
|
|
|
# store each record we extract - keys map to database fields |
45
|
|
|
|
|
|
|
# TODO proper encapsulation |
46
|
13
|
|
|
|
|
95
|
$self->{record} = {}; |
47
|
13
|
|
|
|
|
60
|
$self->{record}->{quote} = q{}; |
48
|
13
|
|
|
|
|
47
|
$self->{record}->{rating} = q{}; |
49
|
13
|
|
|
|
|
40
|
$self->{record}->{name} = q{}; |
50
|
13
|
|
|
|
|
50
|
$self->{record}->{source} = q{}; |
51
|
13
|
|
|
|
|
189
|
$self->{record}->{catg} = q{}; |
52
|
|
|
|
|
|
|
|
53
|
13
|
|
|
|
|
45
|
$self->{file} = $args->{file}; |
54
|
13
|
|
|
|
|
46
|
$self->{dir} = $args->{dir}; |
55
|
13
|
|
|
|
|
39
|
$self->{data} = $args->{data}; |
56
|
13
|
|
|
|
|
40
|
$self->{file_format} = $args->{file_format}; |
57
|
13
|
|
33
|
|
|
110
|
$FILE_ENCODING = $args->{file_encoding} || $FILE_ENCODING; |
58
|
13
|
|
|
|
|
47
|
$self->{delim} = $args->{delimiter}; |
59
|
13
|
|
|
|
|
48
|
$self->{verbose} = $args->{verbose}; |
60
|
13
|
|
|
|
|
54
|
$self->{category} = $args->{category}; |
61
|
13
|
|
|
|
|
38
|
$self->{rating} = $args->{rating}; |
62
|
13
|
|
|
|
|
39
|
$self->{attr_source} = $args->{attr_source}; |
63
|
13
|
|
|
|
|
40
|
$self->{orig_args} = $args; |
64
|
13
|
|
|
|
|
41
|
$self->{success} = undef; |
65
|
|
|
|
|
|
|
|
66
|
|
|
|
|
|
|
# start with if set |
67
|
13
|
|
|
|
|
49
|
$self->{record}->{rating} = $self->{rating}; |
68
|
13
|
|
|
|
|
40
|
$self->{record}->{name} = $self->{attr_source}; |
69
|
13
|
|
|
|
|
42
|
$self->{record}->{source} = $self->{attr_source}; |
70
|
13
|
50
|
|
|
|
64
|
if (ref $self->{category} eq 'ARRAY') { |
71
|
0
|
|
|
|
|
0
|
$self->{record}->{catg} = (); |
72
|
0
|
|
|
|
|
0
|
foreach my $c (@{$self->{category}}){ |
|
0
|
|
|
|
|
0
|
|
73
|
0
|
|
|
|
|
0
|
push @{$self->{record}->{catg}}, $c; |
|
0
|
|
|
|
|
0
|
|
74
|
|
|
|
|
|
|
} |
75
|
|
|
|
|
|
|
} |
76
|
|
|
|
|
|
|
else { |
77
|
13
|
|
|
|
|
50
|
$self->{record}->{catg} = $self->{category}; |
78
|
|
|
|
|
|
|
} |
79
|
|
|
|
|
|
|
|
80
|
|
|
|
|
|
|
# db connection info |
81
|
13
|
100
|
|
|
|
68
|
if ($ENV{ACME_QUOTEDB_DB}) { |
82
|
1
|
|
|
|
|
5
|
$self->{db} = $ENV{ACME_QUOTEDB_DB}; |
83
|
1
|
|
|
|
|
4
|
$self->{host} = $ENV{ACME_QUOTEDB_HOST}; |
84
|
1
|
|
|
|
|
4
|
$self->{user} = $ENV{ACME_QUOTEDB_USER}; |
85
|
1
|
|
|
|
|
6
|
$self->{pass} = $ENV{ACME_QUOTEDB_PASS}; |
86
|
|
|
|
|
|
|
} |
87
|
|
|
|
|
|
|
|
88
|
13
|
100
|
|
|
|
60
|
if (!$args->{dry_run}){$self->{write_db} = 1}; |
|
12
|
|
|
|
|
37
|
|
89
|
|
|
|
|
|
|
#if ($args->{create_db}) {$self->create_db}; |
90
|
13
|
100
|
|
|
|
60
|
if ($args->{create_db}) {$self->create_db_tables}; |
|
10
|
|
|
|
|
64
|
|
91
|
|
|
|
|
|
|
|
92
|
12
|
|
|
|
|
100
|
return $self; |
93
|
|
|
|
|
|
|
} |
94
|
|
|
|
|
|
|
|
95
|
|
|
|
|
|
|
sub set_record { |
96
|
1569
|
|
|
1569
|
1
|
157431
|
my ($self, $field, $value) = @_; |
97
|
|
|
|
|
|
|
|
98
|
|
|
|
|
|
|
# TODO support mult-field simultanous loading |
99
|
|
|
|
|
|
|
|
100
|
1569
|
100
|
|
|
|
6139
|
if ($value) { |
101
|
1502
|
|
|
|
|
5237
|
$self->{record}->{$field} = $value; |
102
|
|
|
|
|
|
|
} |
103
|
|
|
|
|
|
|
|
104
|
1569
|
|
|
|
|
5250
|
return $self; |
105
|
|
|
|
|
|
|
} |
106
|
|
|
|
|
|
|
|
107
|
|
|
|
|
|
|
sub debug_record { |
108
|
0
|
|
|
0
|
1
|
0
|
my ($self) = @_; |
109
|
|
|
|
|
|
|
|
110
|
0
|
|
|
|
|
0
|
print Dumper $self->{record}; |
111
|
|
|
|
|
|
|
|
112
|
0
|
|
|
|
|
0
|
return; |
113
|
|
|
|
|
|
|
} |
114
|
|
|
|
|
|
|
|
115
|
|
|
|
|
|
|
sub get_record { |
116
|
5082
|
|
|
5082
|
1
|
345401
|
my ($self, $field) = @_; |
117
|
|
|
|
|
|
|
|
118
|
5082
|
50
|
|
|
|
17440
|
if (not $field){return $self} |
|
0
|
|
|
|
|
0
|
|
119
|
|
|
|
|
|
|
|
120
|
5082
|
|
|
|
|
50042
|
return $self->{record}->{$field}; |
121
|
|
|
|
|
|
|
} |
122
|
|
|
|
|
|
|
|
123
|
|
|
|
|
|
|
sub data_to_db { |
124
|
9
|
|
|
9
|
1
|
13282
|
my ($self) = @_; |
125
|
|
|
|
|
|
|
|
126
|
9
|
50
|
66
|
|
|
231
|
if ($self->{file} and $self->{data} and $self->{dir}){ |
|
|
50
|
33
|
|
|
|
|
|
|
|
66
|
|
|
|
|
127
|
0
|
|
|
|
|
0
|
croak 'only file, data or dir as arg but not both' |
128
|
|
|
|
|
|
|
} |
129
|
|
|
|
|
|
|
elsif (! ($self->{file} or $self->{data} or $self->{dir})) { |
130
|
0
|
|
|
|
|
0
|
croak 'file, data or dir needed as arg' |
131
|
|
|
|
|
|
|
} |
132
|
|
|
|
|
|
|
|
133
|
9
|
100
|
|
|
|
60
|
if ($self->{file}) { |
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
134
|
8
|
|
|
|
|
52
|
$self->_parse_file($self->{file}); |
135
|
|
|
|
|
|
|
} |
136
|
|
|
|
|
|
|
elsif ($self->{data}) { |
137
|
0
|
|
|
|
|
0
|
$self->_parse_data($self->{data}); |
138
|
|
|
|
|
|
|
} |
139
|
|
|
|
|
|
|
elsif ($self->{dir}) { |
140
|
1
|
|
|
|
|
5
|
my $dir = $self->{dir}; |
141
|
1
|
|
|
|
|
4
|
my $e = q{}; |
142
|
1
|
|
|
|
|
451
|
foreach my $f (<$dir*>) { |
143
|
|
|
|
|
|
|
#if (! (-e $f) || -z $f) # no worky - need path info |
144
|
4
|
|
|
|
|
109
|
$self->_parse_file($f); |
145
|
4
|
|
|
|
|
16
|
$e++; |
146
|
|
|
|
|
|
|
} |
147
|
1
|
50
|
|
|
|
12
|
if (! $e){croak 'no files to parse in: ', Dumper $dir;}; |
|
0
|
|
|
|
|
0
|
|
148
|
|
|
|
|
|
|
} |
149
|
|
|
|
|
|
|
else { |
150
|
0
|
|
|
|
|
0
|
croak 'no file source in args!', Dumper $self; |
151
|
|
|
|
|
|
|
} |
152
|
|
|
|
|
|
|
|
153
|
9
|
|
|
|
|
44
|
return; |
154
|
|
|
|
|
|
|
} |
155
|
|
|
|
|
|
|
|
156
|
|
|
|
|
|
|
sub _parse_file { |
157
|
12
|
|
|
12
|
|
44
|
my ($self, $file) = @_; |
158
|
|
|
|
|
|
|
|
159
|
12
|
50
|
|
|
|
483
|
if (!-f $file) { croak "file not found: $file" } |
|
0
|
|
|
|
|
0
|
|
160
|
|
|
|
|
|
|
|
161
|
12
|
50
|
|
|
|
75
|
if ($self->{verbose}){warn "processing file: $file\n"}; |
|
0
|
|
|
|
|
0
|
|
162
|
|
|
|
|
|
|
|
163
|
12
|
100
|
100
|
|
|
430
|
if (($self->{file_format} eq 'csv') || ($self->{file_format} eq 'tsv')){ |
|
|
50
|
66
|
|
|
|
|
164
|
7
|
|
|
|
|
47
|
$self->dbload_from_csv($file); |
165
|
|
|
|
|
|
|
} |
166
|
|
|
|
|
|
|
elsif (($self->{file_format} eq 'html') || ($self->{file_format} eq 'custom')){ |
167
|
|
|
|
|
|
|
# not supported, too many possibilities |
168
|
|
|
|
|
|
|
# supply your own |
169
|
5
|
|
|
|
|
33
|
$self->dbload($file); |
170
|
|
|
|
|
|
|
} |
171
|
|
|
|
|
|
|
else { |
172
|
0
|
|
|
|
|
0
|
croak 'unsupported file format requested, format must be csv or tsv'; |
173
|
|
|
|
|
|
|
} |
174
|
|
|
|
|
|
|
|
175
|
12
|
|
|
|
|
2661
|
return; |
176
|
|
|
|
|
|
|
} |
177
|
|
|
|
|
|
|
|
178
|
|
|
|
|
|
|
sub _parse_data { |
179
|
0
|
|
|
0
|
|
0
|
my ($self, $data) = @_; |
180
|
|
|
|
|
|
|
|
181
|
0
|
0
|
|
|
|
0
|
if (!$data) {croak "data empty $data"} |
|
0
|
|
|
|
|
0
|
|
182
|
|
|
|
|
|
|
|
183
|
0
|
0
|
|
|
|
0
|
if ($self->{verbose}){carp 'processing data:'}; |
|
0
|
|
|
|
|
0
|
|
184
|
|
|
|
|
|
|
|
185
|
0
|
0
|
0
|
|
|
0
|
if ($self->{file_format} =~ /(?:csv|tsv)/sm) { |
|
|
0
|
|
|
|
|
|
186
|
0
|
|
|
|
|
0
|
croak 'TODO: not yet supported'; |
187
|
|
|
|
|
|
|
#$self->dbload_from_csv($data); |
188
|
|
|
|
|
|
|
} |
189
|
|
|
|
|
|
|
elsif (($self->{file_format} eq 'html') || ($self->{file_format} eq 'custom')){ |
190
|
|
|
|
|
|
|
# not supported, too many possibilities |
191
|
|
|
|
|
|
|
# supply your own |
192
|
0
|
|
|
|
|
0
|
$self->dbload($data); |
193
|
|
|
|
|
|
|
} |
194
|
|
|
|
|
|
|
else { |
195
|
0
|
|
|
|
|
0
|
croak 'unsupported file format requested, ' |
196
|
|
|
|
|
|
|
.'format must be csv, tsv. html, custom also possible'; |
197
|
|
|
|
|
|
|
} |
198
|
|
|
|
|
|
|
|
199
|
0
|
|
|
|
|
0
|
return $self; |
200
|
|
|
|
|
|
|
} |
201
|
|
|
|
|
|
|
|
202
|
|
|
|
|
|
|
sub _confirm_header_order { |
203
|
7
|
|
|
7
|
|
66227
|
my ($hr) = @_; |
204
|
|
|
|
|
|
|
|
205
|
7
|
0
|
33
|
|
|
178
|
return ($hr->{quote} eq 'Quote' |
206
|
|
|
|
|
|
|
and $hr->{name} eq 'Attribution Name', |
207
|
|
|
|
|
|
|
and $hr->{source} eq 'Attribution Source', |
208
|
|
|
|
|
|
|
and $hr->{catg} eq 'Category', |
209
|
|
|
|
|
|
|
and $hr->{rating} eq 'Rating') |
210
|
|
|
|
|
|
|
or croak 'incorrect headers or header order'; |
211
|
|
|
|
|
|
|
} |
212
|
|
|
|
|
|
|
|
213
|
|
|
|
|
|
|
sub dbload_from_csv { |
214
|
7
|
|
|
7
|
1
|
22
|
my ($self, $file) = @_; |
215
|
|
|
|
|
|
|
|
216
|
7
|
|
100
|
|
|
55
|
my $delim = $self->{delim} || ','; |
217
|
7
|
|
|
|
|
175
|
my $csv = Text::CSV->new({ |
218
|
|
|
|
|
|
|
sep_char => $delim, |
219
|
|
|
|
|
|
|
binary => 1 |
220
|
|
|
|
|
|
|
}); |
221
|
7
|
|
|
|
|
1374
|
$csv->column_names (@QUOTE_FIELDS); |
222
|
|
|
|
|
|
|
|
223
|
7
|
|
33
|
|
|
4627
|
open my $source, '<:encoding(utf8)', $file || croak $!; |
224
|
|
|
|
|
|
|
|
225
|
7
|
|
|
|
|
733
|
_confirm_header_order($csv->getline_hr($source)); |
226
|
|
|
|
|
|
|
|
227
|
7
|
|
|
|
|
50
|
while (my $hr = $csv->getline_hr($source)) { |
228
|
182
|
50
|
33
|
|
|
177223
|
next unless $hr->{quote} and $hr->{name}; |
229
|
|
|
|
|
|
|
|
230
|
182
|
50
|
|
|
|
752
|
if ($self->{verbose}){ |
231
|
0
|
|
|
|
|
0
|
print "\n", |
232
|
|
|
|
|
|
|
'Quote: ', $hr->{quote},"\n", |
233
|
|
|
|
|
|
|
'Name: ', $hr->{name},"\n", |
234
|
|
|
|
|
|
|
'Source: ', $hr->{source},"\n", |
235
|
|
|
|
|
|
|
'Category:', $hr->{catg},"\n", |
236
|
|
|
|
|
|
|
'Rating: ', $hr->{rating},"\n\n"; |
237
|
|
|
|
|
|
|
}; |
238
|
|
|
|
|
|
|
|
239
|
182
|
|
|
|
|
1110
|
$self->set_record(quote => $hr->{quote}); |
240
|
182
|
|
|
|
|
1383
|
$self->set_record(name => $hr->{name}); |
241
|
182
|
|
100
|
|
|
1950
|
$self->set_record(source => ($self->{attr_source} || $hr->{source})); |
242
|
|
|
|
|
|
|
# take user defined first |
243
|
|
|
|
|
|
|
# TODO support multi categories |
244
|
182
|
|
66
|
|
|
1649
|
$self->set_record(catg => ($self->{category} || $hr->{catg})); |
245
|
182
|
|
100
|
|
|
1181
|
$self->set_record(rating => ($self->{rating} || $hr->{rating})); |
246
|
182
|
|
|
|
|
6120
|
$self->write_record; |
247
|
|
|
|
|
|
|
} |
248
|
7
|
50
|
|
|
|
1519
|
close $source or carp $!; |
249
|
|
|
|
|
|
|
|
250
|
7
|
|
|
|
|
246
|
return $self; |
251
|
|
|
|
|
|
|
} |
252
|
|
|
|
|
|
|
|
253
|
|
|
|
|
|
|
# sub class this - i.e. provide this method in your code (see test |
254
|
|
|
|
|
|
|
# 01-load_quotes.t) |
255
|
|
|
|
|
|
|
sub dbload { |
256
|
0
|
|
|
0
|
1
|
0
|
croak 'Override this. Provide this method in a sub class (child) of this object'; |
257
|
|
|
|
|
|
|
# see tests: t/01-load_quotes.t for examples |
258
|
|
|
|
|
|
|
} |
259
|
|
|
|
|
|
|
|
260
|
|
|
|
|
|
|
sub _to_utf8 { |
261
|
312
|
|
|
312
|
|
977
|
my ($self) = @_; |
262
|
|
|
|
|
|
|
|
263
|
|
|
|
|
|
|
RECORD: |
264
|
312
|
|
|
|
|
3195
|
foreach my $r (@QUOTE_FIELDS){ |
265
|
1560
|
|
|
|
|
70965
|
my $val = $self->{record}->{$r}; |
266
|
1560
|
100
|
|
|
|
15644
|
if (ref $val eq 'ARRAY'){ |
267
|
1
|
|
|
|
|
3
|
foreach my $v (@{$val}){ |
|
1
|
|
|
|
|
5
|
|
268
|
12
|
100
|
|
|
|
238
|
if (!is_utf8($v)){ |
269
|
6
|
|
|
|
|
7
|
push @{$self->{record}->{$r}}, decode($FILE_ENCODING, $v); |
|
6
|
|
|
|
|
26
|
|
270
|
|
|
|
|
|
|
} |
271
|
|
|
|
|
|
|
} |
272
|
|
|
|
|
|
|
} |
273
|
|
|
|
|
|
|
else { |
274
|
1559
|
100
|
|
|
|
8293
|
if (!is_utf8($val)){ |
275
|
1509
|
|
|
|
|
5651
|
$self->{record}->{$r} = decode($FILE_ENCODING, $val); |
276
|
|
|
|
|
|
|
} |
277
|
|
|
|
|
|
|
} |
278
|
|
|
|
|
|
|
} |
279
|
|
|
|
|
|
|
|
280
|
312
|
|
|
|
|
11082
|
return $self; |
281
|
|
|
|
|
|
|
} |
282
|
|
|
|
|
|
|
|
283
|
|
|
|
|
|
|
# XXX refactor (the following 3 methods) |
284
|
|
|
|
|
|
|
|
285
|
|
|
|
|
|
|
# one person can have many quotes, is this person in our attribution table |
286
|
|
|
|
|
|
|
# already? |
287
|
|
|
|
|
|
|
sub _get_id_if_attr_name_exist { |
288
|
312
|
|
|
312
|
|
743
|
my ($self) = @_; |
289
|
|
|
|
|
|
|
|
290
|
312
|
|
|
|
|
730
|
my $attr_id = q{}; |
291
|
|
|
|
|
|
|
|
292
|
|
|
|
|
|
|
RECS: |
293
|
312
|
|
|
|
|
4973
|
foreach my $c_obj (Attr->retrieve_all){ |
294
|
3374
|
50
|
|
|
|
1199666
|
next RECS if not $c_obj->name; |
295
|
3374
|
100
|
|
|
|
3728036
|
if ($c_obj->name eq $self->get_record('name')){ |
296
|
|
|
|
|
|
|
# use attribution id if already exists |
297
|
190
|
|
|
|
|
1486
|
$attr_id = $c_obj->attr_id; |
298
|
|
|
|
|
|
|
} |
299
|
|
|
|
|
|
|
} |
300
|
312
|
|
|
|
|
100614
|
return $attr_id; |
301
|
|
|
|
|
|
|
} |
302
|
|
|
|
|
|
|
|
303
|
|
|
|
|
|
|
sub _get_id_if_catg_exist { |
304
|
294
|
|
|
294
|
|
991
|
my ($self, $ctg) = @_; |
305
|
|
|
|
|
|
|
|
306
|
294
|
|
|
|
|
713
|
my $catg_id = q{}; |
307
|
|
|
|
|
|
|
# get category id |
308
|
|
|
|
|
|
|
RECS: |
309
|
294
|
|
|
|
|
3805
|
foreach my $c_obj (Catg->retrieve_all){ |
310
|
338
|
50
|
|
|
|
307713
|
next RECS if not $c_obj->catg; |
311
|
338
|
100
|
|
|
|
343023
|
if ($c_obj->catg eq $ctg){ |
312
|
|
|
|
|
|
|
# use cat_id if already exists |
313
|
280
|
|
|
|
|
35572
|
$catg_id = $c_obj->catg_id; |
314
|
|
|
|
|
|
|
} |
315
|
|
|
|
|
|
|
} |
316
|
294
|
|
|
|
|
39342
|
return $catg_id; |
317
|
|
|
|
|
|
|
} |
318
|
|
|
|
|
|
|
|
319
|
|
|
|
|
|
|
#TODO : refactor |
320
|
|
|
|
|
|
|
sub write_record { |
321
|
312
|
|
|
312
|
1
|
1384
|
my ($self) = @_; |
322
|
|
|
|
|
|
|
|
323
|
312
|
|
|
|
|
1905
|
$self->_to_utf8; |
324
|
|
|
|
|
|
|
|
325
|
312
|
50
|
33
|
|
|
1749
|
if ($self->{verbose} and $self->get_record('name')){ |
326
|
0
|
|
|
|
|
0
|
print 'Attribution Name: ',$self->get_record('name'),"\n"; |
327
|
|
|
|
|
|
|
}; |
328
|
|
|
|
|
|
|
|
329
|
312
|
|
|
|
|
1549
|
my $attr_id = $self->_get_id_if_attr_name_exist; |
330
|
|
|
|
|
|
|
# nope, ok, add them |
331
|
312
|
100
|
|
|
|
67453
|
if (not $attr_id) { # attribution record does not already exist, |
332
|
|
|
|
|
|
|
# create new entry |
333
|
122
|
100
|
|
|
|
660
|
if ($self->{write_db}) { |
334
|
93
|
|
|
|
|
449
|
$attr_id = Attr->insert({ |
335
|
|
|
|
|
|
|
name => $self->get_record('name'), |
336
|
|
|
|
|
|
|
}); |
337
|
|
|
|
|
|
|
} |
338
|
|
|
|
|
|
|
} |
339
|
|
|
|
|
|
|
|
340
|
312
|
|
|
|
|
4801902
|
my $catg_ids = (); |
341
|
312
|
100
|
|
|
|
1771
|
if ($self->{write_db}) { |
342
|
283
|
|
|
|
|
2064
|
my ($catg) = $self->get_record('catg'); |
343
|
283
|
100
|
|
|
|
1501
|
if (! ref $catg){ # 'single' value |
|
|
50
|
|
|
|
|
|
344
|
282
|
|
|
|
|
1519
|
my $catg_id = $self->_get_id_if_catg_exist($catg); |
345
|
282
|
100
|
|
|
|
13883
|
if (!$catg_id) { |
346
|
|
|
|
|
|
|
# category does not already exist, |
347
|
|
|
|
|
|
|
# create new entry |
348
|
9
|
|
|
|
|
112
|
$catg_id = Catg->insert({catg => $catg}); |
349
|
|
|
|
|
|
|
} |
350
|
282
|
|
|
|
|
490990
|
push @{$catg_ids}, $catg_id; |
|
282
|
|
|
|
|
1502
|
|
351
|
|
|
|
|
|
|
} # support multi catg |
352
|
|
|
|
|
|
|
elsif (ref $catg eq 'ARRAY'){ |
353
|
1
|
|
|
|
|
2
|
foreach my $c (@{$catg}){ |
|
1
|
|
|
|
|
5
|
|
354
|
12
|
|
|
|
|
56
|
my $catg_id = $self->_get_id_if_catg_exist($c); |
355
|
12
|
100
|
|
|
|
706
|
if (!$catg_id) { # category does not already exist, |
356
|
|
|
|
|
|
|
# create new entry |
357
|
5
|
|
|
|
|
40
|
$catg_id = Catg->insert({catg => $c}); |
358
|
|
|
|
|
|
|
} |
359
|
12
|
|
|
|
|
330364
|
push @{$catg_ids}, $catg_id; |
|
12
|
|
|
|
|
59
|
|
360
|
|
|
|
|
|
|
} |
361
|
|
|
|
|
|
|
} |
362
|
|
|
|
|
|
|
} |
363
|
|
|
|
|
|
|
|
364
|
312
|
|
|
|
|
1745
|
$self->_display_vals_if_verbose; |
365
|
|
|
|
|
|
|
|
366
|
312
|
100
|
|
|
|
1231
|
if ($self->{write_db}) { |
367
|
283
|
50
|
|
|
|
1578
|
my $qid = Quote->insert({ |
368
|
|
|
|
|
|
|
attr_id => $attr_id, |
369
|
|
|
|
|
|
|
quote => $self->get_record('quote'), |
370
|
|
|
|
|
|
|
source => $self->get_record('source'), |
371
|
|
|
|
|
|
|
rating => $self->get_record('rating') |
372
|
|
|
|
|
|
|
}) or croak $!; |
373
|
|
|
|
|
|
|
|
374
|
283
|
50
|
|
|
|
13464487
|
if ($qid) { |
375
|
283
|
|
|
|
|
33737
|
my $id; |
376
|
283
|
|
|
|
|
844
|
foreach my $cid (@{$catg_ids}){ |
|
283
|
|
|
|
|
2808
|
|
377
|
294
|
50
|
|
|
|
1480491
|
$id = QuoteCatg->insert({ |
378
|
|
|
|
|
|
|
quot_id => $qid, |
379
|
|
|
|
|
|
|
catg_id => $cid, |
380
|
|
|
|
|
|
|
}) or croak $!; |
381
|
|
|
|
|
|
|
} |
382
|
|
|
|
|
|
|
} |
383
|
|
|
|
|
|
|
} |
384
|
|
|
|
|
|
|
# confirmation? |
385
|
|
|
|
|
|
|
# TODO add a test for failure |
386
|
312
|
50
|
66
|
|
|
11272789
|
if ($self->{write_db} and not $attr_id) {croak 'db write not successful'} |
|
0
|
|
|
|
|
0
|
|
387
|
|
|
|
|
|
|
|
388
|
|
|
|
|
|
|
#$self->set_record(undef); |
389
|
312
|
|
|
|
|
71945
|
$self->{record} = {}; |
390
|
312
|
|
|
|
|
8072
|
$self->_reset_orig_args; |
391
|
|
|
|
|
|
|
|
392
|
312
|
100
|
|
|
|
1457
|
if ($self->{write_db}) { |
393
|
283
|
|
|
|
|
1535
|
$self->success(1); |
394
|
|
|
|
|
|
|
} |
395
|
|
|
|
|
|
|
|
396
|
312
|
|
|
|
|
1375
|
return $self->success; |
397
|
|
|
|
|
|
|
} |
398
|
|
|
|
|
|
|
|
399
|
|
|
|
|
|
|
sub _reset_orig_args { |
400
|
312
|
|
|
312
|
|
940
|
my ($self) = @_; |
401
|
|
|
|
|
|
|
|
402
|
312
|
|
|
|
|
2444
|
$self->{record}->{rating} = $self->{orig_args}->{rating}; |
403
|
312
|
|
|
|
|
1700
|
$self->{record}->{name} = $self->{orig_args}->{attr_source}; |
404
|
312
|
|
|
|
|
1424
|
$self->{record}->{source} = $self->{orig_args}->{attr_source}; |
405
|
312
|
50
|
|
|
|
1930
|
if (ref $self->{orig_args}->{category} eq 'ARRAY') { |
406
|
0
|
|
|
|
|
0
|
foreach my $c (@{$self->{orig_args}->{category}}){ |
|
0
|
|
|
|
|
0
|
|
407
|
0
|
|
|
|
|
0
|
push @{$self->{record}->{catg}}, $c; |
|
0
|
|
|
|
|
0
|
|
408
|
|
|
|
|
|
|
} |
409
|
|
|
|
|
|
|
} |
410
|
|
|
|
|
|
|
else { |
411
|
312
|
|
|
|
|
2231
|
$self->{record}->{catg} = $self->{orig_args}->{category}; |
412
|
|
|
|
|
|
|
} |
413
|
|
|
|
|
|
|
|
414
|
|
|
|
|
|
|
} |
415
|
|
|
|
|
|
|
|
416
|
|
|
|
|
|
|
sub success { |
417
|
608
|
|
|
608
|
1
|
2512
|
my ($self, $flag) = @_; |
418
|
|
|
|
|
|
|
|
419
|
608
|
|
100
|
|
|
2325
|
$self->{success} ||= $flag; |
420
|
|
|
|
|
|
|
|
421
|
608
|
|
|
|
|
8800
|
return $self->{success}; |
422
|
|
|
|
|
|
|
}; |
423
|
|
|
|
|
|
|
|
424
|
|
|
|
|
|
|
sub _display_vals_if_verbose { |
425
|
312
|
|
|
312
|
|
985
|
my ($self) = @_; |
426
|
|
|
|
|
|
|
|
427
|
312
|
50
|
|
|
|
1698
|
if ($self->{verbose}){ |
428
|
|
|
|
|
|
|
#print 'Quote: ', $self->get_record('quote'),"\n"; |
429
|
|
|
|
|
|
|
#print 'Source: ', $self->get_record('source'),"\n"; |
430
|
|
|
|
|
|
|
#print 'Category: ',$self->get_record('catg'),"\n"; |
431
|
|
|
|
|
|
|
#print 'Rating: ', $self->get_record('rating'),"\n"; |
432
|
0
|
|
|
|
|
0
|
print Dumper $self->{record}; |
433
|
|
|
|
|
|
|
} |
434
|
|
|
|
|
|
|
|
435
|
312
|
|
|
|
|
710
|
return $self; |
436
|
|
|
|
|
|
|
} |
437
|
|
|
|
|
|
|
|
438
|
|
|
|
|
|
|
#sub create_db { |
439
|
|
|
|
|
|
|
# my ($self) = @_; |
440
|
|
|
|
|
|
|
# |
441
|
|
|
|
|
|
|
# if ($self->{db} and $self->{host}) { |
442
|
|
|
|
|
|
|
# $self->create_db_mysql(); |
443
|
|
|
|
|
|
|
# } |
444
|
|
|
|
|
|
|
#} |
445
|
|
|
|
|
|
|
|
446
|
|
|
|
|
|
|
sub create_db_tables { |
447
|
10
|
|
|
10
|
1
|
26
|
my ($self) = @_; |
448
|
|
|
|
|
|
|
|
449
|
10
|
100
|
66
|
|
|
71
|
if ($self->{db} and $self->{host}) { |
450
|
|
|
|
|
|
|
#$self->create_db_mysql(); |
451
|
1
|
|
|
|
|
6
|
$self->create_db_tables_mysql(); |
452
|
|
|
|
|
|
|
} |
453
|
|
|
|
|
|
|
else { |
454
|
9
|
|
|
|
|
36
|
create_db_tables_sqlite(); |
455
|
|
|
|
|
|
|
} |
456
|
|
|
|
|
|
|
|
457
|
9
|
|
|
|
|
44
|
return $self; |
458
|
|
|
|
|
|
|
|
459
|
|
|
|
|
|
|
} |
460
|
|
|
|
|
|
|
|
461
|
|
|
|
|
|
|
# XXX we want the user to supply a pre created database. |
462
|
|
|
|
|
|
|
# created as such 'CREATE DATABASE $dbn CHARACTER SET utf8 COLLATE utf8_general_ci' |
463
|
|
|
|
|
|
|
# this get's into too many isseuwith privs and database creation |
464
|
|
|
|
|
|
|
#Sat Aug 22 13:42:37 PDT 2009 |
465
|
|
|
|
|
|
|
# did this: |
466
|
|
|
|
|
|
|
#mysql> CREATE DATABASE acme_quotedb CHARACTER SET utf8 COLLATE utf8_general_ci; |
467
|
|
|
|
|
|
|
#mysql> grant usage on *.* to acme_user@localhost identified by 'acme'; |
468
|
|
|
|
|
|
|
#mysql> grant all privileges on acme_quotedb.* to acme_user@localhost ; |
469
|
|
|
|
|
|
|
|
470
|
|
|
|
|
|
|
#sub create_db_mysql { |
471
|
|
|
|
|
|
|
# my ($self) = @_; |
472
|
|
|
|
|
|
|
# |
473
|
|
|
|
|
|
|
# # hmmmm, what about priv's access, etc |
474
|
|
|
|
|
|
|
# # maybe user need to supply a db, they have |
475
|
|
|
|
|
|
|
# # access to, already created (just the db though) |
476
|
|
|
|
|
|
|
# ## create our db |
477
|
|
|
|
|
|
|
# #my $dbhc = DBI->connect('DBI:mysql:database=mysql;host=' |
478
|
|
|
|
|
|
|
# # .$self->{host}, $self->{user}, $self->{pass}) |
479
|
|
|
|
|
|
|
# # || croak "db cannot be accessed $! $DBI::errstr"; |
480
|
|
|
|
|
|
|
# |
481
|
|
|
|
|
|
|
# #my $dbn = $self->{db}; |
482
|
|
|
|
|
|
|
# #my $db = qq(CREATE DATABASE $dbn CHARACTER SET utf8 COLLATE utf8_general_ci); |
483
|
|
|
|
|
|
|
# # eval { |
484
|
|
|
|
|
|
|
# # $dbhc->do($db) or croak $dbhc->errstr; |
485
|
|
|
|
|
|
|
# # }; |
486
|
|
|
|
|
|
|
# # $@ and croak 'Cannot create database!'; |
487
|
|
|
|
|
|
|
# # $dbhc->disconnect; $dbhc = undef; |
488
|
|
|
|
|
|
|
# |
489
|
|
|
|
|
|
|
# my $drh = DBI->install_driver('mysql'); |
490
|
|
|
|
|
|
|
# my $rc = $drh->func("dropdb", $self->{db}, |
491
|
|
|
|
|
|
|
# [$self->{host}, $self->{user}, $self->{password}], |
492
|
|
|
|
|
|
|
# 'admin' |
493
|
|
|
|
|
|
|
# ); |
494
|
|
|
|
|
|
|
# |
495
|
|
|
|
|
|
|
# $rc = $drh->func("createdb", $self->{db}, |
496
|
|
|
|
|
|
|
# [$self->{host}, $self->{user}, $self->{password}], |
497
|
|
|
|
|
|
|
# 'admin' |
498
|
|
|
|
|
|
|
# ); |
499
|
|
|
|
|
|
|
#} |
500
|
|
|
|
|
|
|
|
501
|
|
|
|
|
|
|
# XXX refactor with sqlite |
502
|
|
|
|
|
|
|
sub create_db_tables_mysql { |
503
|
1
|
|
|
1
|
1
|
3
|
my ($self) = @_; |
504
|
|
|
|
|
|
|
|
505
|
|
|
|
|
|
|
# connect to our db |
506
|
1
|
|
|
|
|
5
|
my $c = $self->{db}.';host='.$self->{host}; |
507
|
1
|
|
0
|
|
|
17
|
my $dbh = DBI->connect( |
508
|
|
|
|
|
|
|
"DBI:mysql:database=$c", $self->{user}, $self->{pass}) |
509
|
|
|
|
|
|
|
|| croak "db cannot be accessed $! $DBI::errstr"; |
510
|
|
|
|
|
|
|
|
511
|
0
|
|
|
|
|
0
|
eval { |
512
|
0
|
0
|
|
|
|
0
|
$dbh->do('DROP TABLE IF EXISTS quote;') or croak $dbh->errstr; |
513
|
|
|
|
|
|
|
|
514
|
0
|
0
|
|
|
|
0
|
$dbh->do('CREATE TABLE IF NOT EXISTS quote ( |
515
|
|
|
|
|
|
|
quot_id INTEGER NOT NULL AUTO_INCREMENT, |
516
|
|
|
|
|
|
|
attr_id INTEGER, |
517
|
|
|
|
|
|
|
quote TEXT, |
518
|
|
|
|
|
|
|
source TEXT, |
519
|
|
|
|
|
|
|
rating REAL, |
520
|
|
|
|
|
|
|
PRIMARY KEY(quot_id) |
521
|
|
|
|
|
|
|
);') |
522
|
|
|
|
|
|
|
#)CHARACTER SET utf8 COLLATE utf8_general_ci; |
523
|
|
|
|
|
|
|
#) ENGINE = MYISAM CHARACTER SET utf8 COLLATE utf8_general_ci; |
524
|
|
|
|
|
|
|
or croak $dbh->errstr; |
525
|
|
|
|
|
|
|
|
526
|
0
|
0
|
|
|
|
0
|
$dbh->do('DROP TABLE IF EXISTS attribution;') or croak $dbh->errstr; |
527
|
|
|
|
|
|
|
|
528
|
0
|
0
|
|
|
|
0
|
$dbh->do('CREATE TABLE IF NOT EXISTS attribution ( |
529
|
|
|
|
|
|
|
attr_id INTEGER NOT NULL AUTO_INCREMENT, |
530
|
|
|
|
|
|
|
name TEXT, |
531
|
|
|
|
|
|
|
PRIMARY KEY(attr_id) |
532
|
|
|
|
|
|
|
);') or croak $dbh->errstr; |
533
|
|
|
|
|
|
|
|
534
|
0
|
0
|
|
|
|
0
|
$dbh->do('DROP TABLE IF EXISTS category;') or croak $dbh->errstr; |
535
|
|
|
|
|
|
|
|
536
|
0
|
0
|
|
|
|
0
|
$dbh->do('CREATE TABLE IF NOT EXISTS category ( |
537
|
|
|
|
|
|
|
catg_id INTEGER NOT NULL AUTO_INCREMENT, |
538
|
|
|
|
|
|
|
catg TEXT, |
539
|
|
|
|
|
|
|
PRIMARY KEY(catg_id) |
540
|
|
|
|
|
|
|
);') or croak $dbh->errstr; |
541
|
|
|
|
|
|
|
|
542
|
0
|
0
|
|
|
|
0
|
$dbh->do('DROP TABLE IF EXISTS quote_catg;') or croak $dbh->errstr; |
543
|
|
|
|
|
|
|
|
544
|
0
|
0
|
|
|
|
0
|
$dbh->do('CREATE TABLE IF NOT EXISTS quote_catg ( |
545
|
|
|
|
|
|
|
id INTEGER NOT NULL AUTO_INCREMENT, |
546
|
|
|
|
|
|
|
catg_id INTEGER, |
547
|
|
|
|
|
|
|
quot_id INTEGER, |
548
|
|
|
|
|
|
|
PRIMARY KEY(id) |
549
|
|
|
|
|
|
|
);') or croak $dbh->errstr; |
550
|
|
|
|
|
|
|
|
551
|
|
|
|
|
|
|
|
552
|
0
|
0
|
|
|
|
0
|
$dbh->disconnect or warn $dbh->errstr; |
553
|
|
|
|
|
|
|
|
554
|
0
|
|
|
|
|
0
|
$dbh = undef; |
555
|
|
|
|
|
|
|
}; |
556
|
|
|
|
|
|
|
|
557
|
0
|
0
|
|
|
|
0
|
return $@ and croak 'Cannot create database tables!'; |
558
|
|
|
|
|
|
|
|
559
|
|
|
|
|
|
|
} |
560
|
|
|
|
|
|
|
|
561
|
|
|
|
|
|
|
sub create_db_tables_sqlite { |
562
|
|
|
|
|
|
|
|
563
|
9
|
|
|
9
|
1
|
75
|
my $db = QDBI->get_current_db_path; |
564
|
|
|
|
|
|
|
|
565
|
|
|
|
|
|
|
#XXX is there really no way to do this with the existing |
566
|
|
|
|
|
|
|
# connection?!(class dbi) |
567
|
9
|
|
33
|
|
|
231
|
my $dbh = DBI->connect('dbi:SQLite:dbname='.$db, '', '') |
568
|
|
|
|
|
|
|
|| croak "$db cannot be accessed $! $DBI::errstr"; |
569
|
|
|
|
|
|
|
|
570
|
|
|
|
|
|
|
#-- sqlite does not have a varchar datatype: VARCHAR(255) |
571
|
|
|
|
|
|
|
#-- A column declared INTEGER PRIMARY KEY will autoincrement. |
572
|
9
|
|
|
|
|
13892
|
eval { |
573
|
9
|
50
|
|
|
|
82
|
$dbh->do('DROP TABLE IF EXISTS quote;') or croak $dbh->errstr; |
574
|
|
|
|
|
|
|
|
575
|
9
|
50
|
|
|
|
1209740
|
$dbh->do('CREATE TABLE IF NOT EXISTS quote ( |
576
|
|
|
|
|
|
|
quot_id INTEGER PRIMARY KEY, |
577
|
|
|
|
|
|
|
attr_id INTEGER, |
578
|
|
|
|
|
|
|
quote TEXT, |
579
|
|
|
|
|
|
|
source TEXT, |
580
|
|
|
|
|
|
|
rating REAL |
581
|
|
|
|
|
|
|
);') |
582
|
|
|
|
|
|
|
or croak $dbh->errstr; |
583
|
|
|
|
|
|
|
|
584
|
9
|
50
|
|
|
|
279795
|
$dbh->do('DROP TABLE IF EXISTS attribution;') or croak $dbh->errstr; |
585
|
|
|
|
|
|
|
|
586
|
9
|
50
|
|
|
|
135639
|
$dbh->do('CREATE TABLE IF NOT EXISTS attribution ( |
587
|
|
|
|
|
|
|
attr_id INTEGER PRIMARY KEY, |
588
|
|
|
|
|
|
|
name TEXT |
589
|
|
|
|
|
|
|
);') or croak $dbh->errstr; |
590
|
|
|
|
|
|
|
|
591
|
9
|
50
|
|
|
|
192421
|
$dbh->do('DROP TABLE IF EXISTS category;') or croak $dbh->errstr; |
592
|
|
|
|
|
|
|
|
593
|
9
|
50
|
|
|
|
538262
|
$dbh->do('CREATE TABLE IF NOT EXISTS category ( |
594
|
|
|
|
|
|
|
catg_id INTEGER PRIMARY KEY, |
595
|
|
|
|
|
|
|
catg TEXT |
596
|
|
|
|
|
|
|
);') or croak $dbh->errstr; |
597
|
|
|
|
|
|
|
|
598
|
9
|
50
|
|
|
|
169418
|
$dbh->do('DROP TABLE IF EXISTS quote_catg;') or croak $dbh->errstr; |
599
|
|
|
|
|
|
|
|
600
|
9
|
50
|
|
|
|
224002
|
$dbh->do('CREATE TABLE IF NOT EXISTS quote_catg ( |
601
|
|
|
|
|
|
|
id INTEGER PRIMARY KEY, |
602
|
|
|
|
|
|
|
catg_id INTEGER, |
603
|
|
|
|
|
|
|
quot_id INTEGER |
604
|
|
|
|
|
|
|
);') or croak $dbh->errstr; |
605
|
|
|
|
|
|
|
|
606
|
9
|
50
|
|
|
|
370744
|
$dbh->disconnect or carp $dbh->errstr; |
607
|
|
|
|
|
|
|
|
608
|
9
|
|
|
|
|
59
|
$dbh = undef; |
609
|
|
|
|
|
|
|
}; |
610
|
|
|
|
|
|
|
|
611
|
9
|
0
|
|
|
|
868
|
return $@ and croak 'Cannot create database tables!'; |
612
|
|
|
|
|
|
|
|
613
|
|
|
|
|
|
|
} |
614
|
|
|
|
|
|
|
|
615
|
|
|
|
|
|
|
q(My cat's breath smells like cat food. --Ralph Wiggum); |
616
|
|
|
|
|
|
|
|
617
|
|
|
|
|
|
|
|
618
|
|
|
|
|
|
|
__END__ |