File Coverage

blib/lib/Catalyst/Model/DBI/SQL/Library.pm
Criterion Covered Total %
statement 18 62 29.0
branch 0 32 0.0
condition 0 39 0.0
subroutine 6 10 60.0
pod n/a
total 24 143 16.7


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;