File Coverage

blib/lib/ORM/Db/DBI/SQLite.pm
Criterion Covered Total %
statement 72 78 92.3
branch 21 32 65.6
condition 2 5 40.0
subroutine 12 13 92.3
pod 0 10 0.0
total 107 138 77.5


line stmt bran cond sub pod time code
1             #
2             # DESCRIPTION
3             # PerlORM - Object relational mapper (ORM) for Perl. PerlORM is Perl
4             # library that implements object-relational mapping. Its features are
5             # much similar to those of Java's Hibernate library, but interface is
6             # much different and easier to use.
7             #
8             # AUTHOR
9             # Alexey V. Akimov
10             #
11             # COPYRIGHT
12             # Copyright (C) 2005-2006 Alexey V. Akimov
13             #
14             # This library is free software; you can redistribute it and/or
15             # modify it under the terms of the GNU Lesser General Public
16             # License as published by the Free Software Foundation; either
17             # version 2.1 of the License, or (at your option) any later version.
18             #
19             # This library is distributed in the hope that it will be useful,
20             # but WITHOUT ANY WARRANTY; without even the implied warranty of
21             # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
22             # Lesser General Public License for more details.
23             #
24             # You should have received a copy of the GNU Lesser General Public
25             # License along with this library; if not, write to the Free Software
26             # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
27             #
28              
29             package ORM::Db::DBI::SQLite;
30              
31             $VERSION = 0.8;
32              
33 4     4   42647 use base 'ORM::Db::DBI';
  4         16  
  4         2926  
34              
35             ##
36             ## CONSTRUCTORS
37             ##
38              
39             sub new
40             {
41 4     4 0 924 my $class = shift;
42 4         53 my %arg = @_;
43              
44 4         10 $arg{driver} = 'SQLite';
45 4         48 $class->SUPER::new( %arg );
46             }
47              
48             ##
49             ## CLASS METHODS
50             ##
51              
52             sub qc
53             {
54 219     219 0 676 my $self = shift;
55 219         301 my $str = shift;
56              
57 219 100       439 if( defined $str )
58             {
59 195         328 $str =~ s/\'/\'\'/g;
60 195         368 $str = "'$str'";
61             }
62             else
63             {
64 24         38 $str = 'NULL';
65             }
66              
67 219         880 return $str;
68             }
69              
70             sub qi
71             {
72 423     423 0 546 my $self = shift;
73 423         527 my $str = shift;
74              
75 423         1079 $str =~ s/\[/\\\[/g;
76 423         530 $str =~ s/\]/\\\]/g;
77 423         763 $str = "[$str]";
78              
79 423         1716 return $str;
80             }
81              
82 212     212 0 1510 sub qt { $_[0]->qi( $_[1] ); }
83 195     195 0 594 sub qf { $_[0]->qi( $_[1] ); }
84              
85             ##
86             ## OBJECT METHODS
87             ##
88              
89              
90             sub begin_transaction
91             {
92 10     10 0 156 my $self = shift;
93 10         44 my %arg = @_;
94              
95 10         44 $self->{ta} = 1;
96 10         99 $self->do( query=>"BEGIN TRANSACTION", error=>$arg{error} );
97             }
98              
99             sub commit_transaction
100             {
101 9     9 0 89 my $self = shift;
102 9         32 my %arg = @_;
103              
104 9         25 delete $self->{ta};
105 9         45 $self->do( query=>"COMMIT TRANSACTION", error=>$arg{error} );
106             }
107              
108             sub rollback_transaction
109             {
110 1     1 0 8 my $self = shift;
111 1         3 my %arg = @_;
112              
113 1         3 delete $self->{ta};
114 1 50       3 unless( $self->{lost_connection} )
115             {
116 1         5 $self->do( query=>"ROLLBACK TRANSACTION", error=>$arg{error} );
117             }
118             }
119              
120             ## use: $id = $db->insertid()
121             ##
122             sub insertid
123             {
124 21     21 0 37 my $self = shift;
125 21 50       114 $self->_db_handler ? $self->_db_handler->func( 'last_insert_rowid' ) : undef;
126             }
127              
128             sub table_struct
129             {
130 10     10 0 100 my $self = shift;
131 10         46 my %arg = @_;
132 10         43 my $error = ORM::Error->new;
133 10         19 my %field;
134             my %defaults;
135 0         0 my $res;
136              
137             ## Fetch table structure
138 10         59 $res = $self->select
139             (
140             query => "SELECT sql FROM sqlite_master WHERE type='table' and name=".$self->qc($arg{table}),
141             error => $error,
142             );
143 10 50       47 unless( $error->fatal )
144             {
145 10         13 my $data;
146              
147 10         37 $data = $res->next_row;
148 10 100       52 $data = $data ? $data->{sql} : '';
149 10         85 $data =~ /^CREATE TABLE [^\(]+\((.+)\)/ism;
150 10   100     63 $data = $1 || '';
151 10         177 $data =~ s/[\r\n]/ /g;
152              
153 10 100       80 my @rows = split /,/, $data if( $data );
154              
155 10         29 for $row ( @rows )
156             {
157 43 50       401 if( $row =~ /^\s*([^\s]+)\s+([^\s]+)(.*?\s+default (NULL|\'[^\']*\'))?/i )
158             {
159 43 50       145 last if $1 =~ /PRIMARY|UNIQUE|CHECK/;
160 43         72 my $name = $1;
161 43         67 my $type = $2;
162 43         68 my $def = $4;
163              
164 43 50       192 $name = $1 if( $name =~ /^\[(.+)\]$/ );
165 43 50       102 $name = $2 if( $name =~ /^(['"])(.+)\1$/ );
166              
167 43 100       100 if( ! defined $def )
    100          
168             {
169             }
170             elsif( $def eq 'NULL' )
171             {
172 4         7 $def = undef;
173             }
174             else
175             {
176 30         64 $def = substr $def, 1, (length $def) - 2;
177             }
178              
179 43         105 $defaults{ $name } = $def;
180 43         202 $field{ $name } = $arg{class}->_db_type_to_class( $name, $type );
181             }
182             else
183             {
184 0         0 $error->add_fatal( "Can't detect columns for table '$arg{table}'" );
185 0         0 last;
186             }
187             }
188             }
189              
190             ## Fetch class references
191 10 100       31 if( scalar( %field ) )
192             {
193 9         39 $res = $self->select
194             (
195             error => $error,
196             query => 'SELECT * FROM '.$self->qt('_ORM_refs').' WHERE class='.$self->qc( $arg{class} ),
197             );
198 9 50       534 unless( $error->fatal )
199             {
200 9         34 while( $data = $res->next_row )
201             {
202 2 50       13 if( exists $field{$data->{prop}} )
203             {
204 2         10 $field{$data->{prop}} = $data->{ref_class};
205             }
206             }
207             }
208             }
209              
210 10         53 $error->upto( $arg{error} );
211 10         668 return \%field, \%defaults;
212             }
213              
214 2     2   6 sub _ta_select { ''; }
215              
216             sub _lost_connection
217             {
218 0     0     my $self = shift;
219 0           my $err = shift;
220              
221 0 0 0       defined $err && ( $err == 2006 || $err == 2013 );
222             }
223              
224             ##
225             ## SQL FUNCTIONS
226             ##
227