File Coverage

blib/lib/DBD/Mock/StatementTrack.pm
Criterion Covered Total %
statement 115 127 90.5
branch 44 52 84.6
condition 18 20 90.0
subroutine 26 28 92.8
pod 0 26 0.0
total 203 253 80.2


line stmt bran cond sub pod time code
1             package DBD::Mock::StatementTrack;
2              
3 39     39   293 use strict;
  39         89  
  39         1267  
4 39     39   210 use warnings;
  39         83  
  39         64524  
5              
6             sub new {
7 143     143 0 7167 my ( $class, %params ) = @_;
8              
9             # these params have default values
10             # but can be overridden
11 143   100     623 $params{return_data} ||= [];
12 143 100 100     719 $params{fields} ||= $DBD::Mock::DefaultFieldsToUndef ? undef : [];
13 143   100     701 $params{bound_params} ||= [];
14 143   50     729 $params{bound_param_attrs} ||= [];
15 143   100     386 $params{statement} ||= "";
16 143   100     668 $params{failure} ||= undef;
17 143   100     604 $params{callback} ||= undef;
18              
19             # these params should never be overridden
20             # and should always start out in a default
21             # state to assure the sanity of this class
22 143         290 $params{is_executed} = 'no';
23 143         292 $params{is_finished} = 'no';
24 143         270 $params{current_record_num} = 0;
25              
26             # NOTE:
27             # changed from \%params here because that
28             # would bind the hash sent in so that it
29             # would reflect alterations in the object
30             # this violates encapsulation
31 143         1010 my $self = bless {%params}, $class;
32 143         633 return $self;
33             }
34              
35             sub has_failure {
36 145     145 0 292 my ($self) = @_;
37 145 100       589 $self->{failure} ? 1 : 0;
38             }
39              
40             sub get_failure {
41 3     3 0 5 my ($self) = @_;
42 3         5 @{ $self->{failure} };
  3         59  
43             }
44              
45             sub num_fields {
46 4     4 0 724 my ($self) = @_;
47 4 100       19 return $self->{fields} ? scalar @{ $self->{fields} } : $self->{fields};
  3         15  
48             }
49              
50             sub num_rows {
51 48     48 0 99 my ($self) = @_;
52 48         69 return scalar @{ $self->{return_data} };
  48         332  
53             }
54              
55             sub num_params {
56 139     139 0 307 my ($self) = @_;
57 139         205 return scalar @{ $self->{bound_params} };
  139         553  
58             }
59              
60             sub bind_col {
61 13     13 0 26 my ( $self, $param_num, $ref ) = @_;
62 13         37 $self->{bind_cols}->[ $param_num - 1 ] = $ref;
63             }
64              
65             sub bound_param {
66 17     17 0 65 my ( $self, $param_num, $value, $attr ) = @_;
67              
68             # Basic support for named parameters
69 17 100       97 if ( $param_num !~ /^\d+/ ) {
70 2         6 $param_num = $self->num_params + 1;
71             }
72              
73 17         57 $self->{bound_params}->[ $param_num - 1 ] = $value;
74 17 100       64 $self->{bound_param_attrs}->[ $param_num - 1 ] = ref $attr eq "HASH" ? { %$attr } : $attr;
75              
76 17         40 return $self->bound_params;
77             }
78              
79             sub bound_param_trailing {
80 1     1 0 4 my ( $self, @values ) = @_;
81 1         2 push @{ $self->{bound_params} }, @values;
  1         5  
82             }
83              
84             sub bind_cols {
85 123     123 0 198 my $self = shift;
86 123 100       174 return @{ $self->{bind_cols} || [] };
  123         650  
87             }
88              
89             sub bind_params {
90 46     46 0 136 my ( $self, @values ) = @_;
91 46         79 @{ $self->{bound_params} } = @values;
  46         127  
92 46         111 @{ $self->{bound_param_attrs} } = map { undef } @values;
  46         144  
  64         151  
93             }
94              
95             # Rely on the DBI's notion of Active: a statement is active if it's
96             # currently in a SELECT and has more records to fetch
97              
98             sub is_active {
99 10     10 0 24 my ($self) = @_;
100 10 100       27 return 0 unless $self->statement =~ /^\s*select/ism;
101 7 100       21 return 0 unless $self->is_executed eq 'yes';
102 6 100       18 return 0 if $self->is_depleted;
103 3         21 return 1;
104             }
105              
106             sub is_finished {
107 50     50 0 119 my ( $self, $value ) = @_;
108 50 100 100     243 if ( defined $value && $value eq 'yes' ) {
    100          
109 39         80 $self->{is_finished} = 'yes';
110 39         101 $self->current_record_num(0);
111 39         93 $self->{return_data} = [];
112             }
113             elsif ( defined $value ) {
114 1         2 $self->{is_finished} = 'no';
115             }
116 50         211 return $self->{is_finished};
117             }
118              
119             ####################
120             # RETURN VALUES
121              
122             sub mark_executed {
123 134     134 0 856 my ($self) = @_;
124              
125              
126 134         328 push @{$self->{execution_history} }, {
127 134         298 params => [ @{ $self->{bound_params} } ],
128 134         188 attrs => [ @{ $self->{bound_param_attrs} } ],
  134         492  
129             };
130              
131 134         450 $self->is_executed('yes');
132 134         366 $self->current_record_num(0);
133              
134 134 100       465 if (ref $self->{callback} eq "CODE") {
135 11         17 my %recordSet = $self->{callback}->(@{ $self->{bound_params} });
  11         26  
136              
137 11 100       179 if (ref $recordSet{fields} eq "ARRAY") {
138 8         16 $self->{fields} = $recordSet{fields};
139             }
140              
141 11 50       25 if (ref $recordSet{rows} eq "ARRAY") {
142 11         20 $self->{return_data} = $recordSet{rows};
143             }
144              
145 11 100       33 if (defined $recordSet{last_insert_id}) {
146 1         3 $self->{last_insert_id} = $recordSet{last_insert_id};
147             }
148             }
149             }
150              
151             sub next_record {
152 171     171 0 865 my ($self) = @_;
153 171 100       367 return if $self->is_depleted;
154 142         307 my $rec_num = $self->current_record_num;
155 142         279 my $rec = $self->return_data->[$rec_num];
156 142         372 $self->current_record_num( $rec_num + 1 );
157 142         409 return $rec;
158             }
159              
160             sub is_depleted {
161 190     190 0 1350 my ($self) = @_;
162 190         347 return ( $self->current_record_num >= scalar @{ $self->return_data } );
  190         355  
163             }
164              
165             # DEBUGGING AID
166              
167             sub to_string {
168 0     0 0 0 my ($self) = @_;
169             return join "\n" => (
170             $self->{statement},
171 0         0 "Values: [" . join( '] [', @{ $self->{bound_params} } ) . "]",
172             "Records: on $self->{current_record_num} of "
173 0         0 . scalar( @{ $self->return_data } ) . "\n",
  0         0  
174             "Executed? $self->{is_executed}; Finished? $self->{is_finished}"
175             );
176             }
177              
178             # PROPERTIES
179              
180             # boolean
181              
182             sub is_executed {
183 148     148 0 328 my ( $self, $yes_no ) = @_;
184 148 100       462 $self->{is_executed} = $yes_no if defined $yes_no;
185 148 100       441 return ( $self->{is_executed} eq 'yes' ) ? 'yes' : 'no';
186             }
187              
188             # single-element fields
189              
190             sub statement {
191 29     29 0 3573 my ( $self, $value ) = @_;
192 29 100       89 $self->{statement} = $value if defined $value;
193 29         173 return $self->{statement};
194             }
195              
196             sub current_record_num {
197 664     664 0 1081 my ( $self, $value ) = @_;
198 664 100       1336 $self->{current_record_num} = $value if defined $value;
199 664         1120 return $self->{current_record_num};
200             }
201              
202             sub callback {
203 0     0 0 0 my ( $self, $callback ) = @_;
204 0 0       0 $self->{callback} = $callback if defined $callback;
205 0         0 return $self->{callback};
206             }
207              
208             # multi-element fields
209              
210             sub return_data {
211 335     335 0 510 my ( $self, @values ) = @_;
212 335 50       625 push @{ $self->{return_data} }, @values if scalar @values;
  0         0  
213 335         982 return $self->{return_data};
214             }
215              
216             sub fields {
217 159     159 0 321 my ( $self, @values ) = @_;
218              
219 159   50     390 $self->{fields} ||= [];
220              
221 159 50       406 push @{ $self->{fields} }, @values if scalar @values;
  0         0  
222              
223 159         443 return $self->{fields};
224             }
225              
226             sub bound_params {
227 83     83 0 4178 my ( $self, @values ) = @_;
228 83 50       238 push @{ $self->{bound_params} }, @values if scalar @values;
  0         0  
229 83         332 return $self->{bound_params};
230             }
231              
232             sub bound_param_attrs {
233 6     6 0 5051 my ( $self, @values ) = @_;
234 6 50       18 push @{ $self->{bound_param_attrs} }, @values if scalar @values;
  0         0  
235 6         24 return $self->{bound_param_attrs};
236             }
237              
238             sub execution_history {
239 1     1 0 4 my ( $self, @values ) = @_;
240 1 50       4 push @{ $self->{execution_history} }, @values if scalar @values;
  0         0  
241 1         5 return $self->{execution_history};
242             }
243              
244             1;