line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package Catalyst::Model::DBI::SQL::Library; |
2
|
|
|
|
|
|
|
|
3
|
1
|
|
|
1
|
|
34747
|
use strict; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
41
|
|
4
|
1
|
|
|
1
|
|
6
|
use base 'Catalyst::Model::DBI'; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
662
|
|
5
|
|
|
|
|
|
|
|
6
|
1
|
|
|
1
|
|
974
|
use NEXT; |
|
1
|
|
|
|
|
5602
|
|
|
1
|
|
|
|
|
32
|
|
7
|
1
|
|
|
1
|
|
910
|
use SQL::Library; |
|
1
|
|
|
|
|
762
|
|
|
1
|
|
|
|
|
26
|
|
8
|
1
|
|
|
1
|
|
5
|
use File::Spec; |
|
1
|
|
|
|
|
3
|
|
|
1
|
|
|
|
|
23
|
|
9
|
|
|
|
|
|
|
|
10
|
1
|
|
|
1
|
|
5
|
use constant DEFAULT_ROOT_PATH => 'root/sql'; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
834
|
|
11
|
|
|
|
|
|
|
|
12
|
|
|
|
|
|
|
our $VERSION = '0.19'; |
13
|
|
|
|
|
|
|
|
14
|
|
|
|
|
|
|
__PACKAGE__->mk_accessors('sql'); |
15
|
|
|
|
|
|
|
|
16
|
|
|
|
|
|
|
=head1 NAME |
17
|
|
|
|
|
|
|
|
18
|
|
|
|
|
|
|
Catalyst::Model::DBI::SQL::Library - SQL::Library DBI Model Class |
19
|
|
|
|
|
|
|
|
20
|
|
|
|
|
|
|
=head1 SYNOPSIS |
21
|
|
|
|
|
|
|
|
22
|
|
|
|
|
|
|
# use the helper |
23
|
|
|
|
|
|
|
create model DBI::SQL::Library DBI::SQL::Library dsn user password |
24
|
|
|
|
|
|
|
|
25
|
|
|
|
|
|
|
# lib/MyApp/Model/DBI/SQL/Library.pm |
26
|
|
|
|
|
|
|
package MyApp::Model::DBI::SQL::Library; |
27
|
|
|
|
|
|
|
|
28
|
|
|
|
|
|
|
use base 'Catalyst::Model::DBI::SQL::Library'; |
29
|
|
|
|
|
|
|
|
30
|
|
|
|
|
|
|
# define configuration in package |
31
|
|
|
|
|
|
|
|
32
|
|
|
|
|
|
|
__PACKAGE__->config( |
33
|
|
|
|
|
|
|
dsn => 'dbi:Pg:dbname=myapp', |
34
|
|
|
|
|
|
|
username => 'postgres', |
35
|
|
|
|
|
|
|
password => '', |
36
|
|
|
|
|
|
|
options => { AutoCommit => 1 }, |
37
|
|
|
|
|
|
|
sqldir => 'root/sql2' #optional, will default to $c->path_to( 'root/sql' ), |
38
|
|
|
|
|
|
|
sqlcache => 1 #can only be used when queries are loaded from file i.e. via scalar passed to load |
39
|
|
|
|
|
|
|
sqlcache_use_mtime => 1 #will use modification time of the file to determine when to refresh the cache, make sure sqlcache = 1 |
40
|
|
|
|
|
|
|
loglevel = 1 #integer value to control log notifications between 1 and 3 with 3 being the most verbose, defaults to 1 |
41
|
|
|
|
|
|
|
); |
42
|
|
|
|
|
|
|
|
43
|
|
|
|
|
|
|
1; |
44
|
|
|
|
|
|
|
|
45
|
|
|
|
|
|
|
# or define configuration in myapp.conf |
46
|
|
|
|
|
|
|
|
47
|
|
|
|
|
|
|
name MyApp |
48
|
|
|
|
|
|
|
|
49
|
|
|
|
|
|
|
<Model::DBI::SQL::Library> |
50
|
|
|
|
|
|
|
dsn "DBI:Pg:dbname=myapp" |
51
|
|
|
|
|
|
|
username pgsql |
52
|
|
|
|
|
|
|
password "" |
53
|
|
|
|
|
|
|
<options> |
54
|
|
|
|
|
|
|
AutoCommit 1 |
55
|
|
|
|
|
|
|
</options> |
56
|
|
|
|
|
|
|
loglevel 1 |
57
|
|
|
|
|
|
|
sqlcache 1 |
58
|
|
|
|
|
|
|
sqlcache_use_mtime 1 |
59
|
|
|
|
|
|
|
</Model> |
60
|
|
|
|
|
|
|
|
61
|
|
|
|
|
|
|
# then in controller / model code |
62
|
|
|
|
|
|
|
|
63
|
|
|
|
|
|
|
my $model = $c->model( 'DBI::SQL::Library' ); |
64
|
|
|
|
|
|
|
|
65
|
|
|
|
|
|
|
my $sql = $model->load( 'something.sql' ) ; |
66
|
|
|
|
|
|
|
|
67
|
|
|
|
|
|
|
#or my $sql = $model->load( [ <FH> ] ); |
68
|
|
|
|
|
|
|
#or my $sql = $model->load( [ $sql_query1, $sql_query2 ] ) ) |
69
|
|
|
|
|
|
|
|
70
|
|
|
|
|
|
|
my $query = $sql->retr( 'some_sql_query' ); |
71
|
|
|
|
|
|
|
|
72
|
|
|
|
|
|
|
#or my $query = $model->sql->retr( 'some_sql_query ); |
73
|
|
|
|
|
|
|
|
74
|
|
|
|
|
|
|
$model->dbh->do( $query ); |
75
|
|
|
|
|
|
|
|
76
|
|
|
|
|
|
|
#do something else with $sql ... |
77
|
|
|
|
|
|
|
|
78
|
|
|
|
|
|
|
=head1 DESCRIPTION |
79
|
|
|
|
|
|
|
|
80
|
|
|
|
|
|
|
This is the C<SQL::Library> model class. It provides access to C<SQL::Library> |
81
|
|
|
|
|
|
|
via sql accessor. Additional caching options are provided for increased performance |
82
|
|
|
|
|
|
|
via sqlcache and sqlcache_use_mtime, these options can only be used when sql strings are |
83
|
|
|
|
|
|
|
stored within a file and loaded by using a scalar value passed to load. The load and parse |
84
|
|
|
|
|
|
|
phase is then bypassed if cached version of the file is found. |
85
|
|
|
|
|
|
|
|
86
|
|
|
|
|
|
|
The use of these options can result in more memory being used but faster access to query |
87
|
|
|
|
|
|
|
data when running under persistent environment such as mod_perl or FastCGI. When sqlcache_use_mtime |
88
|
|
|
|
|
|
|
is in use, last modification time of the file is being referenced upon every cache check. |
89
|
|
|
|
|
|
|
If the modification time has changed only then query file is re-loaded. This should be much faster then |
90
|
|
|
|
|
|
|
re-creating the SQL::Library instance on every load. Please refer to the C<SQL::Library> for more information. |
91
|
|
|
|
|
|
|
|
92
|
|
|
|
|
|
|
=head1 METHODS |
93
|
|
|
|
|
|
|
|
94
|
|
|
|
|
|
|
=over 4 |
95
|
|
|
|
|
|
|
|
96
|
|
|
|
|
|
|
=item new |
97
|
|
|
|
|
|
|
|
98
|
|
|
|
|
|
|
Initializes database connection |
99
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
=cut |
101
|
|
|
|
|
|
|
|
102
|
|
|
|
|
|
|
sub new { |
103
|
0
|
|
|
0
|
|
|
my ( $self, $c, @args ) = @_; |
104
|
0
|
|
|
|
|
|
$self = $self->NEXT::new( $c, @args ); |
105
|
0
|
|
0
|
|
|
|
$self->{sqldir} ||= $c->path_to( DEFAULT_ROOT_PATH ); |
106
|
0
|
|
|
|
|
|
return $self; |
107
|
|
|
|
|
|
|
} |
108
|
|
|
|
|
|
|
|
109
|
|
|
|
|
|
|
=item $self->load |
110
|
|
|
|
|
|
|
|
111
|
|
|
|
|
|
|
Initializes C<SQL::Library> instance |
112
|
|
|
|
|
|
|
|
113
|
|
|
|
|
|
|
=cut |
114
|
|
|
|
|
|
|
|
115
|
|
|
|
|
|
|
sub load { |
116
|
0
|
|
|
0
|
|
|
my ( $self, $source ) = @_; |
117
|
0
|
0
|
|
|
|
|
$source = File::Spec->catfile( $self->{sqldir}, $source ) unless ref $source eq 'ARRAY'; |
118
|
|
|
|
|
|
|
|
119
|
0
|
|
|
|
|
|
my $log = $self->{log}; |
120
|
0
|
|
|
|
|
|
my $debug = $self->{debug}; |
121
|
0
|
|
|
|
|
|
my $loglevel = $self->{loglevel}; |
122
|
|
|
|
|
|
|
|
123
|
0
|
0
|
0
|
|
|
|
if ( ref $source ne 'ARRAY' && $self->{sqlcache} && exists $self->{obj_cache}->{$source} ) { |
|
|
|
0
|
|
|
|
|
124
|
0
|
|
|
|
|
|
my $source_cached = $self->{obj_cache}->{$source}; |
125
|
0
|
0
|
0
|
|
|
|
if ( $self->{sqlcache_use_mtime} && exists $source_cached->{mtime} ) { |
126
|
0
|
|
|
|
|
|
my $mtime_current = $self->_extract_mtime( $source ); |
127
|
0
|
0
|
|
|
|
|
if ( $mtime_current != $source_cached->{mtime} ) { |
128
|
0
|
0
|
0
|
|
|
|
$log->debug( |
129
|
|
|
|
|
|
|
qq/mtime changed for cached SQL::Library instance with path: "$source", reloading/ |
130
|
|
|
|
|
|
|
) if $debug && $loglevel >= $self->LOG_LEVEL_INTERMEDIATE; |
131
|
0
|
|
|
|
|
|
$self->_load_instance( $source ); |
132
|
|
|
|
|
|
|
} else { |
133
|
0
|
|
|
|
|
|
$self->sql( $source_cached->{sql} ); |
134
|
0
|
0
|
0
|
|
|
|
$log->debug( |
135
|
|
|
|
|
|
|
qq/cached SQL::Library instance with path: "$source" and mtime: "$mtime_current" found/ |
136
|
|
|
|
|
|
|
) if $debug && $loglevel == $self->LOG_LEVEL_FULL; |
137
|
|
|
|
|
|
|
} |
138
|
|
|
|
|
|
|
} else { |
139
|
0
|
|
|
|
|
|
$self->sql( $source_cached->{sql} ); |
140
|
0
|
0
|
0
|
|
|
|
$log->debug( |
141
|
|
|
|
|
|
|
qq/cached SQL::Library instance with path: "$source" found/ |
142
|
|
|
|
|
|
|
) if $debug && $loglevel == $self->LOG_LEVEL_FULL; |
143
|
|
|
|
|
|
|
} |
144
|
|
|
|
|
|
|
} else { |
145
|
0
|
|
|
|
|
|
$self->_load_instance( $source ); |
146
|
|
|
|
|
|
|
} |
147
|
0
|
|
|
|
|
|
return $self->sql; |
148
|
|
|
|
|
|
|
} |
149
|
|
|
|
|
|
|
|
150
|
|
|
|
|
|
|
sub _load_instance { |
151
|
0
|
|
|
0
|
|
|
my ( $self, $source ) = @_; |
152
|
|
|
|
|
|
|
|
153
|
0
|
|
|
|
|
|
my $log = $self->{log}; |
154
|
0
|
|
|
|
|
|
my $debug = $self->{debug}; |
155
|
0
|
|
|
|
|
|
my $loglevel = $self->{loglevel}; |
156
|
|
|
|
|
|
|
|
157
|
0
|
|
|
|
|
|
eval { $self->sql( SQL::Library->new( { lib => $source } ) ); }; |
|
0
|
|
|
|
|
|
|
158
|
0
|
0
|
|
|
|
|
if ( $@ ) { |
159
|
0
|
0
|
0
|
|
|
|
$log->debug( |
160
|
|
|
|
|
|
|
qq/couldn't create SQL::Library instance with path: "$source" error: "$@"/ |
161
|
|
|
|
|
|
|
) if $debug && $loglevel >= $self->LOG_LEVEL_BASIC; |
162
|
|
|
|
|
|
|
} else { |
163
|
0
|
0
|
0
|
|
|
|
$log->debug( |
164
|
|
|
|
|
|
|
qq/SQL::Library instance created with path: "$source"/ |
165
|
|
|
|
|
|
|
) if $debug && $loglevel >= $self->LOG_LEVEL_BASIC; |
166
|
0
|
0
|
0
|
|
|
|
if ( $self->{sqlcache} && ref $source ne 'ARRAY' ) { |
167
|
0
|
0
|
|
|
|
|
if ( $self->{sqlcache_use_mtime} ) { |
168
|
0
|
|
|
|
|
|
my $mtime = $self->_extract_mtime( $source ); |
169
|
0
|
|
|
|
|
|
$self->{obj_cache}->{$source} = { |
170
|
|
|
|
|
|
|
sql => $self->sql, |
171
|
|
|
|
|
|
|
mtime => $mtime |
172
|
|
|
|
|
|
|
}; |
173
|
0
|
0
|
0
|
|
|
|
$log->debug( |
174
|
|
|
|
|
|
|
qq/caching SQL::Library instance with path: "$source" and mtime: "$mtime"/ |
175
|
|
|
|
|
|
|
) if $debug && $loglevel >= $self->LOG_LEVEL_INTERMEDIATE; |
176
|
|
|
|
|
|
|
} else { |
177
|
0
|
|
|
|
|
|
$self->{obj_cache}->{$source} = { sql => $self->sql }; |
178
|
0
|
0
|
0
|
|
|
|
$log->debug( |
179
|
|
|
|
|
|
|
qq/caching SQL::Library instance with path: "$source"/ |
180
|
|
|
|
|
|
|
) if $debug && $loglevel >= $self->LOG_LEVEL_INTERMEDIATE; |
181
|
|
|
|
|
|
|
} |
182
|
|
|
|
|
|
|
} |
183
|
|
|
|
|
|
|
} |
184
|
|
|
|
|
|
|
} |
185
|
|
|
|
|
|
|
|
186
|
|
|
|
|
|
|
sub _extract_mtime { |
187
|
0
|
|
|
0
|
|
|
my ( $self, $source ) = @_; |
188
|
|
|
|
|
|
|
|
189
|
0
|
|
|
|
|
|
my $mtime; |
190
|
0
|
0
|
|
|
|
|
if (-r $source) { |
191
|
0
|
|
|
|
|
|
$mtime = return (stat(_))[9]; |
192
|
|
|
|
|
|
|
} else { |
193
|
0
|
0
|
0
|
|
|
|
$self->{log}->debug( |
194
|
|
|
|
|
|
|
qq/couldn't extract modification time for path: "$source"/ |
195
|
|
|
|
|
|
|
) if $self->{debug} && $self->{loglevel} >= $self->LOG_LEVEL_BASIC; |
196
|
|
|
|
|
|
|
} |
197
|
0
|
|
|
|
|
|
return $mtime; |
198
|
|
|
|
|
|
|
} |
199
|
|
|
|
|
|
|
|
200
|
|
|
|
|
|
|
=item $self->dbh |
201
|
|
|
|
|
|
|
|
202
|
|
|
|
|
|
|
Returns the current database handle. |
203
|
|
|
|
|
|
|
|
204
|
|
|
|
|
|
|
=item $self->sql |
205
|
|
|
|
|
|
|
|
206
|
|
|
|
|
|
|
Returns the current C<SQL::Library> instance |
207
|
|
|
|
|
|
|
|
208
|
|
|
|
|
|
|
=back |
209
|
|
|
|
|
|
|
|
210
|
|
|
|
|
|
|
=head1 SEE ALSO |
211
|
|
|
|
|
|
|
|
212
|
|
|
|
|
|
|
L<Catalyst>, L<DBI> |
213
|
|
|
|
|
|
|
|
214
|
|
|
|
|
|
|
=head1 AUTHOR |
215
|
|
|
|
|
|
|
|
216
|
|
|
|
|
|
|
Alex Pavlovic, C<alex.pavlovic@taskforce-1.com> |
217
|
|
|
|
|
|
|
|
218
|
|
|
|
|
|
|
=head1 COPYRIGHT |
219
|
|
|
|
|
|
|
|
220
|
|
|
|
|
|
|
This program is free software, you can redistribute it and/or modify it |
221
|
|
|
|
|
|
|
under the same terms as Perl itself. |
222
|
|
|
|
|
|
|
|
223
|
|
|
|
|
|
|
=cut |
224
|
|
|
|
|
|
|
|
225
|
|
|
|
|
|
|
1; |