File Coverage

blib/lib/DBD/mysql/AutoTypes.pm
Criterion Covered Total %
statement 9 12 75.0
branch 0 4 0.0
condition 0 3 0.0
subroutine 3 4 75.0
pod n/a
total 12 23 52.1


line stmt bran cond sub pod time code
1             package DBD::mysql::AutoTypes;
2            
3 1     1   13097 use strict;
  1         2  
  1         33  
4 1     1   6 use Exporter;
  1         2  
  1         99  
5             our @ISA = qw( Exporter );
6             our @EXPORT = qw( mysql_auto_types );
7            
8             our $VERSION = "1.0";
9             our $DBD_mysql_VERSION = 2.9002;
10            
11 1     1   1011 use Regexp::Common qw ( number );
  1         23279  
  1         6  
12            
13             sub _mysql_fix {
14 0     0     my ($sth, $attr, @bind) = @_;
15 0           my $n = 1;
16             $sth->bind_param( $n, $_,
17             $attr->{TYPES} && $attr->{TYPES}[$n-1] ||
18             /^$RE{num}{int}$/ ? DBI::SQL_INTEGER :
19             /^$RE{num}{real}$/ ? DBI::SQL_DOUBLE :
20             DBI::SQL_VARCHAR
21 0 0 0       ), $n++ foreach (@bind);
    0          
22             }
23            
24             our $FIXES = {
25            
26             'selectall_arrayref' => { pkg => '_', code => sub {
27             my ($dbh, $stmt, $attr, @bind) = @_;
28             my $sth = ( ref $stmt ) ? $stmt : $dbh->prepare( $stmt, $attr ) or return;
29             _mysql_fix( $sth, $attr, @bind);
30             $sth->execute() || return;
31             my $slice = $attr->{Slice};
32             if (!$slice and $slice=$attr->{Columns}) {
33             if (ref $slice eq 'ARRAY') {
34             $slice = [ @{$attr->{Columns}} ];
35             for (@$slice) { $_-- }
36             }
37             }
38             return $sth->fetchall_arrayref($slice, $attr->{MaxRows});
39             }},
40            
41             'selectall_hashref' => { pkg => '_', code => sub {
42             my ($dbh, $stmt, $key_field, $attr, @bind) = @_;
43             my $sth = (ref $stmt) ? $stmt : $dbh->prepare($stmt, $attr) or return;
44             _mysql_fix( $sth, $attr, @bind);
45             $sth->execute(@bind) || return;
46             return $sth->fetchall_hashref($key_field);
47             }},
48            
49             'selectcol_arrayref' => { pkg => '_', code => sub {
50             my ($dbh, $stmt, $attr, @bind) = @_;
51             my $sth = (ref $stmt) ? $stmt : $dbh->prepare($stmt, $attr) or return;
52             _mysql_fix( $sth, $attr, @bind);
53             $sth->execute(@bind) || return;
54             my @columns = ($attr->{Columns}) ? @{$attr->{Columns}} : (1);
55             my @values = (undef) x @columns;
56             my $idx = 0;
57             for (@columns) {
58             $sth->bind_col($_, \$values[$idx++]) || return;
59             }
60             my @col;
61             if (my $max = $attr->{MaxRows}) {
62             push @col, @values while @col<$max && $sth->fetch;
63             } else {
64             push @col, @values while $sth->fetch;
65             }
66             return \@col;
67             }},
68            
69             'do' => { pkg => 'mysql', code => sub {
70             my($dbh, $statement, $attr, @bind) = @_;
71             my $sth = $dbh->prepare($statement, $attr) or return undef;
72             _mysql_fix( $sth, $attr, @bind );
73             $sth->execute(@bind) or return undef;
74             my $rows = $sth->rows;
75             ($rows == 0) ? "0E0" : $rows;
76             }},
77            
78             '_do_selectrow' => { pkg => 'mysql', code => sub {
79             my ($method, $dbh, $stmt, $attr, @bind) = @_;
80             my $sth = ((ref $stmt) ? $stmt : $dbh->prepare($stmt, $attr)) or return;
81             _mysql_fix( $sth, $attr, @bind );
82             $sth->execute(@bind) or return;
83             my $row = $sth->$method() and $sth->finish;
84             return $row;
85             }},
86            
87             'selectrow_array' => { pkg => 'mysql', code => sub {
88             my $row = DBD::mysql::db::_do_selectrow('fetchrow_arrayref', @_) or return;
89             return $row->[0] unless wantarray;
90             return @$row;
91             }},
92            
93             'selectrow_arrayref' => { pkg => 'mysql', code => sub {
94             return DBD::mysql::db::_do_selectrow('fetchrow_arrayref', @_);
95             }},
96            
97             'selectrow_hashref' => { pkg => '_', code => sub {
98             return DBD::mysql::db::_do_selectrow('fetchrow_hashref', @_);
99             }},
100            
101             };
102            
103             sub mysql_auto_types {
104             return if $DBD::mysql::VERSION < $DBD_mysql_VERSION;
105            
106             while (my ($meth, $params) = each %$FIXES) {
107             no warnings;
108             if ($params->{pkg} eq '_') {
109             $DBD::_::db::{$meth} = $params->{code};
110             } elsif ($params->{pkg} eq 'mysql') {
111             $DBD::mysql::db::{$meth} = $params->{code};
112             }
113             }
114             }
115            
116             'Grishace';
117            
118             =head1 NAME
119            
120             DBD::mysql::AutoTypes -- automatically assign parameters' sql type to support old DBD::mysql functionality
121            
122             =head1 SYNOPSIS
123            
124             use DBI;
125             use DBD::mysql::AutoTypes;
126            
127             my $dbh = DBI->connect('DBI:mysql:...', '...', '...') and mysql_auto_types();
128            
129             =head1 DESCRIPTION
130            
131             Since version 2.9002 DBD::mysql requires explicit sql type for query parameters.
132             You should change the tonnes of $dbh->selectall_arrayref() to the ugly
133             "prepare - bind - execute - fetch" pipeline.
134            
135             This module is provided to solve the problem.
136            
137             You have to change only two lines of code (use the module, and apply fixup after accuring database connection).
138            
139             =head1 DEPENDENCIES
140            
141             =over 3
142            
143             =item *
144            
145             B
146            
147             =item *
148            
149             B
150            
151             =item *
152            
153             B
154            
155             =back
156            
157             =head1 BUGS
158            
159             May be...
160            
161             =head1 SEE ALSO
162            
163             =over 4
164            
165             =item *
166            
167             B -- Perl DataBase Interface (L)
168            
169             =item *
170            
171             B -- MySQL (L) driver (L) and
172             B -- look for the version 2.9002 changes (L),
173             that break old behaviour
174            
175             =item *
176            
177             B -- determine is data number or string
178            
179             =back
180            
181             =head1 AUTHOR
182            
183             Greg "Grishace" Belenky
184            
185             =head1 COPYRIGHT
186            
187             Copyright (C) 2004 Greg "Grishace" Belenky
188             Portions of code cut'n'pasted from the DBI module
189            
190             This module is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
191            
192             =cut