File Coverage

blib/lib/DBIx/Cursor.pm
Criterion Covered Total %
statement 12 180 6.6
branch 0 48 0.0
condition 0 21 0.0
subroutine 4 20 20.0
pod 15 15 100.0
total 31 284 10.9


line stmt bran cond sub pod time code
1             ########################################################################
2             #
3             # Copyright (c) 2001,2002 by Tommi Mäkitalo
4             #
5             # This package is free software; you can redistribute it
6             # and/or modify it under the same terms as Perl itself.
7             #
8             ########################################################################
9              
10             package DBIx::Cursor;
11              
12 1     1   6900 use 5.6.0;
  1         3  
  1         43  
13 1     1   6 use strict;
  1         2  
  1         31  
14 1     1   5 use warnings;
  1         6  
  1         39  
15 1     1   5 use Carp;
  1         2  
  1         2055  
16              
17             our $VERSION = '0.14';
18              
19             my %cache;
20              
21             # ----------------------------------------------------------------------
22             sub new
23             {
24 0     0 1   shift;
25 0           my $self = {};
26 0           my $dbh = shift;
27 0           my $table = shift;
28 0           my $pk = \@_;
29              
30             # read names and types of columns
31 0 0         unless ($cache{$table})
32             {
33 0           my $sth = $dbh->prepare("select * from $table where 0=1");
34 0 0         $sth->execute or croak('error fetching columns');
35              
36 0           $self->{NAME} = $sth->{NAME};
37 0           $self->{TYPE} = $sth->{TYPE};
38 0           $self->{type} = {};
39 0           for (my $i = 0; $i < @{$self->{NAME}}; ++$i)
  0            
40             {
41 0           $self->{type}{$self->{NAME}[$i]} = $self->{TYPE}[$i];
42             }
43              
44             # read primary-key if not given
45 0 0         unless ($pk)
46             {
47 0           my @pk = $dbh->primary_key(undef, undef, $table);
48 0 0         if (@pk)
49             {
50 0           $pk = \@pk;
51             }
52             else
53             {
54 0           croak ('primary key not known');
55             }
56             }
57              
58 0           $self->{pk} = $pk;
59              
60 0           $cache{$table} = [$self->{NAME}, $self->{TYPE}, $self->{type}, $self->{pk}];
61             }
62             else
63             {
64 0           ($self->{NAME}, $self->{TYPE}, $self->{type}, $self->{pk}) = @{$cache{$table}};
  0            
65             }
66              
67             # initialize values
68 0           $self->{dbh} = $dbh;
69 0           $self->{table} = $table;
70              
71             # initialize data
72 0           $self->{data} = {};
73 0           $self->{olddata} = {};
74              
75             # return value
76 0           bless $self;
77 0           return $self;
78             }
79              
80             # ----------------------------------------------------------------------
81             sub DESTROY
82             {
83 0     0     my $self = shift;
84 0           $self->reset;
85             }
86              
87             # ----------------------------------------------------------------------
88             sub dbh
89             {
90 0     0 1   my $self = shift;
91 0           return $self->{dbh};
92             }
93              
94             # ----------------------------------------------------------------------
95             sub get_type
96             {
97 0     0 1   my $self = shift;
98 0           my $colname = shift;
99              
100 0 0         return $self->{type}{$colname} or croak ("column $colname not found");
101             }
102              
103             # ----------------------------------------------------------------------
104             sub get_columns
105             {
106 0     0 1   my $self = shift;
107 0           return @{$self->{NAME}};
  0            
108             }
109              
110             # ----------------------------------------------------------------------
111             sub read
112             {
113 0     0 1   my $self = shift;
114 0           my @values = @_;
115              
116 0           my @pk = @{$self->{pk}};
  0            
117              
118 0 0         croak ('invalid number of parameters') unless @values == @pk;
119              
120 0           my $dbh = $self->{dbh};
121 0           my $table = $self->{table};
122              
123 0           my $sth = $self->{sth_select};
124 0 0         unless ($sth)
125             {
126 0           my $sql = "select * from $table where "
127 0           . join(' and ', map { "$_ = ?" } @pk);
128              
129 0           $self->reset;
130 0           $sth = $self->{sth_select} = $dbh->prepare($sql);
131             }
132 0           $sth->execute(@values);
133              
134 0 0         if ($self->{data} = $sth->fetchrow_hashref)
135             {
136 0           %{$self->{olddata}} = %{$self->{data}};
  0            
  0            
137 0           return $self;
138             }
139             else
140             {
141 0           return undef;
142             }
143             }
144              
145             # ----------------------------------------------------------------------
146             sub set
147             {
148 0     0 1   my $self = shift;
149 0           my %newval = @_;
150              
151 0           while (my ($key, $value) = each (%newval) )
152             {
153 0 0         croak("column $key not found") unless $self->{type}{$key};
154 0           $self->{data}{$key} = $value;
155             }
156              
157 0           return $self;
158             }
159              
160             # ----------------------------------------------------------------------
161             sub get
162             {
163 0     0 1   my $self = shift;
164 0           my @columns = @_;
165              
166 0 0         if (@columns)
    0          
167             {
168 0 0         if (wantarray)
169             {
170 0           return map { $self->{data}{$_} } @columns;
  0            
171             }
172             else
173             {
174 0           return $self->{data}{$columns[0]};
175             }
176             }
177             elsif (wantarray)
178             {
179 0           return %{$self->{data}};
  0            
180             }
181             else
182             {
183 0           return $self->{data};
184             }
185             }
186              
187             # ----------------------------------------------------------------------
188             sub reset
189             {
190 0     0 1   my $self = shift;
191              
192 0           $self->{data} = {};
193 0           $self->{olddata} = {};
194              
195 0 0         if ($self->{sth})
196             {
197 0           $self->{sth}->finish;
198 0           $self->{sth} = undef;
199             }
200              
201 0           return $self;
202             }
203              
204             # ----------------------------------------------------------------------
205             sub where
206             {
207 0     0 1   my $self = shift;
208              
209 0           $self->reset;
210 0           $self->{where} = shift;
211 0           $self->{values} = \@_;
212              
213 0           return $self;
214             }
215              
216             # ----------------------------------------------------------------------
217             sub values
218             {
219 0     0 1   my $self = shift;
220              
221 0           $self->reset;
222 0           $self->{values} = \@_;
223              
224 0           return $self;
225             }
226              
227             # ----------------------------------------------------------------------
228             sub fetch
229             {
230 0     0 1   my $self = shift;
231              
232 0 0         unless ($self->{sth})
233             {
234 0           my $table = $self->{table};
235 0           my $dbh = $self->{dbh};
236 0           my $sql = "select * from $table";
237 0           my $where = $self->{where};
238              
239 0 0         if ($where)
240             {
241 0 0         $sql .= ' where' if ($where !~ /^\s*(where)|(order\s+by)\s/i);
242 0           $sql .= " $where";
243             }
244              
245 0 0         my @values = @{$self->{values}} if $self->{values};
  0            
246 0           $self->{sth} = $dbh->prepare($sql);
247 0           $self->{sth}->execute(@values);
248             }
249              
250 0 0         if ($self->{data} = $self->{sth}->fetchrow_hashref)
251             {
252 0           %{$self->{olddata}} = %{$self->{data}};
  0            
  0            
253 0           return $self->get;
254             }
255             else
256             {
257 0           $self->reset;
258 0           return undef;
259             }
260             }
261              
262             # ----------------------------------------------------------------------
263             sub update
264             {
265 0     0 1   my $self = shift;
266              
267 0           my $data = $self->{data};
268 0           my $odata = $self->{olddata};
269 0           my $table = $self->{table};
270 0           my $dbh = $self->{dbh};
271 0           my $pk = $self->{pk};
272              
273             # the columns to update are either given as parameter or
274             # every not primary-key-column
275 0           my @updatecols = @_ ? @_
276             : grep { # seach columns
277 0           my $col = $_;
278             # return every column not in primary-key
279 0           ! grep { $col eq $_ } @$pk
  0            
280 0 0         } @{$self->{NAME}};
281              
282             # check if update is needed
283 0           my @cols;
284             my @values;
285 0           foreach my $col (@updatecols)
286             {
287 0           my $d = $data->{$col};
288 0           my $o = $odata->{$col};
289 0 0 0       next unless defined $d && !defined $o
      0        
      0        
      0        
      0        
      0        
290             || !defined $d && defined $o
291             || defined $d && defined $o && $o ne $d;
292 0           push @cols, $col;
293 0           push @values, $d;
294             }
295              
296 0 0         return unless @cols;
297              
298 0           my $sql = "update $table set "
299 0           . join(', ', map { "$_ = ?" } @cols )
300             . ' where '
301 0           . join(' and ', map { "$_ = ?" } @$pk);
302              
303 0 0         my @pkvalues = map { $odata->{$_} || $data->{$_} } @$pk;
  0            
304              
305 0           my $sth = $dbh->prepare($sql);
306 0           my $ret = $sth->execute(@values, @pkvalues);
307 0           %{$self->{olddata}} = %{$self->{data}};
  0            
  0            
308 0           return $ret;
309             }
310              
311             # ----------------------------------------------------------------------
312             sub insert
313             {
314 0     0 1   my $self = shift;
315 0           my $table = $self->{table};
316 0           my $dbh = $self->{dbh};
317              
318 0           my $sth = $self->{sth_insert};
319 0 0         unless ($sth)
320             {
321 0           my $sql = "insert into $table values ("
322 0           . join(', ', ('?') x @{$self->{NAME}})
323             . ')';
324              
325 0           $sth = $self->{sth_insert} = $dbh->prepare($sql);
326             }
327              
328 0           my @values = map { $self->{data}{$_} } @{$self->{NAME}};
  0            
  0            
329              
330 0           return $sth->execute(@values);
331             }
332              
333             # ----------------------------------------------------------------------
334             sub replace
335             {
336 0     0 1   my $self = shift;
337 0   0       return $self->update != 0 || $self->insert;
338             }
339              
340             # ----------------------------------------------------------------------
341             sub delete
342             {
343 0     0 1   my $self = shift;
344              
345 0           my $data = $self->{data};
346 0           my $table = $self->{table};
347 0           my $dbh = $self->{dbh};
348 0           my $pk = $self->{pk};
349              
350 0           my $sth = $self->{sth_delete};
351 0 0         unless ($sth)
352             {
353 0           my $sql = "delete from $table where "
354 0           . join(' and ', map { "$_ = ?" } @$pk);
355 0           $sth = $self->{sth_delete} = $dbh->prepare($sql);
356             }
357              
358 0           my @pkvalues = map { $data->{$_} } @$pk;
  0            
359              
360 0           $sth->execute(@pkvalues);
361             }
362              
363             1;
364              
365             __END__