File Coverage

blib/lib/Teng/Iterator.pm
Criterion Covered Total %
statement 58 60 96.6
branch 24 28 85.7
condition 15 33 45.4
subroutine 10 10 100.0
pod 3 3 100.0
total 110 134 82.0


line stmt bran cond sub pod time code
1             package Teng::Iterator;
2 68     68   398 use strict;
  68         137  
  68         1672  
3 68     68   297 use warnings;
  68         115  
  68         1307  
4 68     68   282 use Carp ();
  68         122  
  68         1073  
5 68     68   280 use Scalar::Util qw/looks_like_number/;
  68         116  
  68         2955  
6             use Class::Accessor::Lite (
7 68         460 rw => [qw/suppress_object_creation apply_sql_types guess_sql_types/],
8 68     68   25100 );
  68         57091  
9 68     68   5951 use DBI qw(:sql_types);
  68         126  
  68         51312  
10              
11             sub new {
12 61     61 1 505 my ($class, %args) = @_;
13              
14 61         220 return bless \%args, $class;
15             }
16              
17             sub next {
18 58     58 1 15168 my $self = shift;
19              
20 58         111 my $row;
21 58 100       187 if ($self->{sth}) {
22 57         1331 $row = $self->{sth}->fetchrow_hashref;
23 57   66     554 $self->{select_columns} ||= $self->{sth}->{$self->{teng}->{fields_case}};
24 57 100       173 unless ( $row ) {
25 5         19 $self->{sth}->finish;
26 5         9 $self->{sth} = undef;
27 5         49 return;
28             }
29             } else {
30 1         6 return;
31             }
32              
33 52 100       160 if ($self->{suppress_object_creation}) {
34 4         12 return $row;
35             } else {
36 48 100       152 $self->_apply_sql_types($row) if $self->{apply_sql_types};
37             return $self->{row_class}->new(
38             {
39             sql => $self->{sql},
40             row_data => $row,
41             teng => $self->{teng},
42             table => $self->{table},
43             table_name => $self->{table_name},
44             select_columns => $self->{select_columns},
45             }
46 48         406 );
47             }
48             }
49              
50             sub _apply_sql_types {
51 11     11   22 my ($self, $row) = @_;
52              
53 11         35 foreach my $column (keys %$row) {
54 29         43 my $type = $self->{table}->{sql_types}->{$column};
55 29 100       60 if (defined $type) {
    100          
56 27 100 33     456 if ( $type == SQL_BIGINT
    100 33        
      33        
      66        
      66        
      66        
      33        
      33        
      33        
57             or $type == SQL_BIT
58             or $type == SQL_TINYINT
59             or $type == SQL_NUMERIC
60             or $type == SQL_INTEGER
61             or $type == SQL_SMALLINT
62             or $type == SQL_DECIMAL
63             or $type == SQL_FLOAT
64             or $type == SQL_REAL
65             or $type == SQL_DOUBLE
66             ) {
67 9         19 $row->{$column} += 0;
68             } elsif ($type == SQL_BOOLEAN) {
69 9 50       21 if ($self->{teng}->{boolean_value}) {
70 9 100       19 if ($row->{$column}) {
71 6         13 $row->{$column} = $self->{teng}->{boolean_value}->{true};
72             } else {
73 3         8 $row->{$column} = $self->{teng}->{boolean_value}->{false};
74             }
75             } else {
76 0         0 $row->{$column} += 0;
77             }
78             } else {
79 9         25 $row->{$column} .= '';
80             }
81             } elsif ($self->{guess_sql_types}) {
82 1 50       11 if (looks_like_number($row->{$column})) {
83 1         4 $row->{$column} += 0;
84             } else {
85 0         0 $row->{$column} .= '';
86             }
87             }
88             }
89             }
90              
91             sub all {
92 21     21 1 923 my $self = shift;
93              
94 21         58 my $result = [];
95              
96 21 50       90 if ($self->{sth}) {
97 21   33     442 $self->{select_columns} ||= $self->{sth}->{$self->{teng}->{fields_case}};
98 21         248 $result = $self->{sth}->fetchall_arrayref(+{});
99 21         1954 $self->{sth}->finish;
100 21         41 $self->{sth} = undef;
101              
102 21 50       108 if (!$self->{suppress_object_creation}) {
103             $result = [map {
104 21         56 $self->{row_class}->new(
105             {
106             sql => $self->{sql},
107             row_data => $_,
108             teng => $self->{teng},
109             table => $self->{table},
110             table_name => $self->{table_name},
111             select_columns => $self->{select_columns},
112             }
113             )
114 85         421 } @$result];
115             }
116             }
117              
118 21 100       229 return wantarray ? @$result : $result;
119             }
120              
121             1;
122              
123             __END__
124             =head1 NAME
125              
126             Teng::Iterator - Iterator for Teng
127              
128             =head1 DESCRIPTION
129              
130             This is an iterator class for L<Teng>.
131              
132             =head1 SYNOPSIS
133              
134             my $itr = Your::Model->search('user',{});
135            
136             my @rows = $itr->all; # get all rows
137              
138             # do iteration
139             while (my $row = $itr->next) {
140             ...
141             }
142              
143             =head1 METHODS
144              
145             =over
146              
147             =item $itr = Teng::Iterator->new()
148              
149             Create new Teng::Iterator's object. You may not call this method directly.
150              
151             =item my $row = $itr->next();
152              
153             Get next row data.
154              
155             =item my @ary = $itr->all;
156              
157             Get all row data in array.
158              
159             =item $itr->suppress_object_creation($bool)
160              
161             Set row object creation mode.
162              
163             =item $itr->apply_sql_types($bool)
164              
165             Set column type application mode.
166              
167             If column has SQL type and it is numeric, regard it as number and add 0 to the value.
168             If column has SQL type and it isn't numeric, regard it as string and add '' to the value.
169             If column doesn't have SQL type, the value won't be changed.
170              
171             =item $itr->guess_sql_types($bool)
172              
173             If this is true, this implies apply_sql_types also true.
174             If column has no SQL type, it guesses SQL type with its value.
175             When column value likes numeric, regard it as number and add 0 to the value.
176             If not, regard it as string and add '' to the value.
177              
178             =back
179              
180             =cut
181