File Coverage

blib/lib/Rose/DB/MySQL.pm
Criterion Covered Total %
statement 49 224 21.8
branch 0 110 0.0
condition 1 79 1.2
subroutine 15 65 23.0
pod 26 52 50.0
total 91 530 17.1


line stmt bran cond sub pod time code
1             package Rose::DB::MySQL;
2              
3 16     16   113 use strict;
  16         38  
  16         463  
4              
5 16     16   94 use Carp();
  16         36  
  16         289  
6              
7 16     16   7137 use DateTime::Format::MySQL;
  16         72622  
  16         536  
8 16     16   8195 use SQL::ReservedWords::MySQL();
  16         50538  
  16         917  
9              
10             TRY:
11             {
12             local $@;
13             eval { require DBD::mysql }; # Ignore errors
14             }
15              
16 16     16   129 use Rose::DB;
  16         62  
  16         836  
17              
18             our $VERSION = '0.774';
19              
20             our $Debug = 0;
21              
22             use Rose::Class::MakeMethods::Generic
23             (
24 16         145 inheritable_scalar =>
25             [
26             'supports_schema',
27             'coerce_autoincrement_to_serial',
28             ]
29 16     16   97 );
  16         36  
30              
31             __PACKAGE__->supports_schema(1);
32             __PACKAGE__->coerce_autoincrement_to_serial(1);
33              
34             #
35             # Object methods
36             #
37              
38 0     0 0 0 sub registration_schema { shift->database }
39              
40             sub build_dsn
41             {
42 12     12 0 111 my($self_or_class, %args) = @_;
43              
44 12         31 my %info;
45              
46 12   33     86 $info{'database'} = $args{'db'} || $args{'database'};
47 12         36 $info{'host'} = $args{'host'};
48 12         30 $info{'port'} = $args{'port'};
49              
50             return
51             "dbi:mysql:" .
52 12         35 join(';', map { "$_=$info{$_}" } grep { defined $info{$_} }
  24         173  
  36         104  
53             qw(database host port));
54             }
55              
56 13     13 0 60 sub dbi_driver { 'mysql' }
57              
58 0     0 1 0 sub mysql_auto_reconnect { shift->dbh_attribute_boolean('mysql_auto_reconnect', @_) }
59 0     0 1 0 sub mysql_client_found_rows { shift->dbh_attribute_boolean('mysql_client_found_rows', @_) }
60 0     0 1 0 sub mysql_compression { shift->dbh_attribute_boolean('mysql_compression', @_) }
61 0     0 1 0 sub mysql_connect_timeout { shift->dbh_attribute_boolean('mysql_connect_timeout', @_) }
62 0     0 1 0 sub mysql_embedded_groups { shift->dbh_attribute('mysql_embedded_groups', @_) }
63 0     0 1 0 sub mysql_embedded_options { shift->dbh_attribute('mysql_embedded_options', @_) }
64 0     0 1 0 sub mysql_local_infile { shift->dbh_attribute('mysql_local_infile', @_) }
65 0     0 1 0 sub mysql_multi_statements { shift->dbh_attribute_boolean('mysql_multi_statements', @_) }
66 0     0 1 0 sub mysql_read_default_file { shift->dbh_attribute('mysql_read_default_file', @_) }
67 0     0 1 0 sub mysql_read_default_group { shift->dbh_attribute('mysql_read_default_group', @_) }
68 0     0 1 0 sub mysql_socket { shift->dbh_attribute('mysql_socket', @_) }
69 0     0 1 0 sub mysql_ssl { shift->dbh_attribute_boolean('mysql_ssl', @_) }
70 0     0 1 0 sub mysql_ssl_ca_file { shift->dbh_attribute('mysql_ssl_ca_file', @_) }
71 0     0 1 0 sub mysql_ssl_ca_path { shift->dbh_attribute('mysql_ssl_ca_path', @_) }
72 0     0 1 0 sub mysql_ssl_cipher { shift->dbh_attribute('mysql_ssl_cipher', @_) }
73 0     0 1 0 sub mysql_ssl_client_cert { shift->dbh_attribute('mysql_ssl_client_cert', @_) }
74 0     0 1 0 sub mysql_ssl_client_key { shift->dbh_attribute('mysql_ssl_client_key', @_) }
75 0     0 1 0 sub mysql_use_result { shift->dbh_attribute_boolean('mysql_use_result', @_) }
76 0     0 1 0 sub mysql_bind_type_guessing { shift->dbh_attribute_boolean('mysql_bind_type_guessing', @_) }
77              
78             sub mysql_enable_utf8
79             {
80 0     0 1 0 my($self) = shift;
81 0 0 0     0 $self->dbh->do('SET NAMES utf8') if(@_ && $self->has_dbh);
82 0         0 $self->dbh_attribute_boolean('mysql_enable_utf8', @_)
83             }
84              
85             sub mysql_enable_utf8mb4
86             {
87 0     0 1 0 my($self) = shift;
88 0 0 0     0 $self->dbh->do('SET NAMES utf8mb4') if(@_ && $self->has_dbh);
89 0         0 $self->dbh_attribute_boolean('mysql_enable_utf8mb4', @_)
90             }
91              
92             sub database_version
93             {
94 0     0 0 0 my($self) = shift;
95 0 0       0 return $self->{'database_version'} if(defined $self->{'database_version'});
96              
97 0         0 my $vers = $self->dbh->get_info(18); # SQL_DBMS_VER
98              
99             # Convert to an integer, e.g., 5.1.13 -> 5001013
100 0 0       0 if($vers =~ /^(\d+)\.(\d+)(?:\.(\d+))?/)
101             {
102 0   0     0 $vers = sprintf('%d%03d%03d', $1, $2, $3 || 0);
103             }
104              
105 0         0 return $self->{'database_version'} = $vers;
106             }
107              
108             sub init_dbh
109             {
110 12     12 0 40 my($self) = shift;
111              
112 12         35 $self->{'supports_on_duplicate_key_update'} = undef;
113              
114 12         66 my $method = ref($self)->parent_class . '::init_dbh';
115              
116 16     16   17748 no strict 'refs';
  16         43  
  16         14615  
117 12         173 return $self->$method(@_);
118             }
119              
120 0     0 0   sub max_column_name_length { 64 }
121 0     0 0   sub max_column_alias_length { 255 }
122              
123             sub quote_column_name
124             {
125 0     0 0   my $name = $_[1];
126 0           $name =~ s/`/``/g;
127 0           return qq(`$name`);
128             }
129              
130             sub quote_table_name
131             {
132 0     0 0   my $name = $_[1];
133 0           $name =~ s/`/``/g;
134 0           return qq(`$name`);
135             }
136              
137             sub list_tables
138             {
139 0     0 0   my($self, %args) = @_;
140              
141 0 0         my $types = $args{'include_views'} ? "'TABLE','VIEW'" : 'TABLE';
142 0           my @tables;
143              
144 0           my $schema = $self->schema;
145              
146 0 0         $schema = $self->database unless(defined $schema);
147              
148 0           my $error;
149              
150             TRY:
151             {
152 0           local $@;
  0            
153              
154             eval
155 0           {
156 0 0         my $dbh = $self->dbh or die $self->error;
157              
158 0           local $dbh->{'RaiseError'} = 1;
159 0           local $dbh->{'FetchHashKeyName'} = 'NAME';
160              
161 0           my $sth = $dbh->table_info($self->catalog, $schema, '%', $types);
162              
163 0           $sth->execute;
164              
165 0           while(my $table_info = $sth->fetchrow_hashref)
166             {
167 0           push(@tables, $self->unquote_table_name($table_info->{'TABLE_NAME'}));
168             }
169             };
170              
171 0           $error = $@;
172             }
173              
174 0 0         if($error)
175             {
176 0           Carp::croak "Could not list tables from ", $self->dsn, " - $error";
177             }
178              
179 0 0         return wantarray ? @tables : \@tables;
180             }
181              
182 0     0 0   sub init_date_handler { DateTime::Format::MySQL->new }
183              
184 0     0 0   sub insertid_param { 'mysql_insertid' }
185              
186 0     0 0   sub last_insertid_from_sth { $_[1]->{'mysql_insertid'} }
187              
188             sub format_table_with_alias
189             {
190 0     0 0   my($self, $table, $alias, $hints) = @_;
191              
192 0           my $version = $self->database_version;
193              
194 0 0 0       if($hints && $version >= 3_023_012)
195             {
196 0           my $sql = "$table $alias ";
197              
198             # "ignore index()" and "use index()" were added in 3.23.12 (07 March 2000)
199             # "force index()" was added in 4.0.9 (09 January 2003)
200 0 0         my @types = (($version >= 4_000_009 ? 'force' : ()), qw(use ignore));
201              
202 0           foreach my $index_hint_type (@types)
203             {
204 0           my $key = "${index_hint_type}_index";
205              
206 0 0         if($hints->{$key})
207             {
208 0           $sql .= uc($index_hint_type) . ' INDEX (';
209              
210 0 0         if(ref $hints->{$key} eq 'ARRAY')
211             {
212 0           $sql .= join(', ', @{$hints->{$key}});
  0            
213             }
214 0           else { $sql .= $hints->{$key} }
215              
216 0           $sql .= ')';
217              
218             # Only one of these hints is allowed
219 0           last;
220             }
221             }
222              
223 0           return $sql;
224             }
225              
226 0           return "$table $alias";
227             }
228              
229             sub format_select_start_sql
230             {
231 0     0 0   my($self, $hints) = @_;
232              
233 0 0         return 'SELECT' unless($hints);
234              
235             return 'SELECT ' . ($hints->{'comment'} ? "/* $hints->{'comment'} */" : '') .
236 0 0         join(' ', (map { $hints->{$_} ? uc("sql_$_") : () }
237             qw(small_result big_result buffer_result cache no_cache calc_found_rows)),
238 0 0         (map { $hints->{$_} ? uc($_) : () } qw(high_priority straight_join)));
  0 0          
239             }
240              
241             sub format_select_lock
242             {
243 0     0 0   my($self, $class, $lock, $tables_list) = @_;
244              
245 0 0         $lock = { type => $lock } unless(ref $lock);
246              
247 0 0 0       $lock->{'type'} ||= 'for update' if($lock->{'for_update'});
248              
249 0           my %types =
250             (
251             'for update' => 'FOR UPDATE',
252             'shared' => 'LOCK IN SHARE MODE',
253             );
254              
255 0 0         my $sql = $types{$lock->{'type'}}
256             or Carp::croak "Invalid lock type: $lock->{'type'}";
257              
258 0           return $sql;
259             }
260              
261             sub validate_date_keyword
262             {
263 16     16   128 no warnings;
  16         51  
  16         3892  
264 0 0 0 0 1   !ref $_[1] && ($_[1] =~ /^(?:(?:now|cur(?:date|time)|sysdate)\(\)|
      0        
265             current_(?:time|date|timestamp)(?:\(\))?|0000-00-00)$/xi ||
266             ($_[0]->keyword_function_calls && $_[1] =~ /^\w+\(.*\)$/));
267             }
268              
269             sub validate_datetime_keyword
270             {
271 16     16   137 no warnings;
  16         41  
  16         3394  
272 0 0 0 0 1   !ref $_[1] && ($_[1] =~ /^(?:(?:now|cur(?:date|time)|sysdate)\(\)|
      0        
273             current_(?:time|date|timestamp)(?:\(\))?|0000-00-00[ ]00:00:00)$/xi ||
274             ($_[0]->keyword_function_calls && $_[1] =~ /^\w+\(.*\)$/));
275             }
276              
277             sub validate_timestamp_keyword
278             {
279 16     16   125 no warnings;
  16         34  
  16         4874  
280 0 0 0 0 1   !ref $_[1] && ($_[1] =~ /^(?:(?:now|cur(?:date|time)|sysdate)\(\)|
      0        
281             current_(?:time|date|timestamp)(?:\(\))?|0000-00-00[ ]00:00:00|00000000000000)$/xi ||
282             ($_[0]->keyword_function_calls && $_[1] =~ /^\w+\(.*\)$/));
283             }
284              
285             *format_timestamp = \&Rose::DB::format_datetime;
286              
287             sub parse_bitfield
288             {
289 0     0 0   my($self, $val, $size, $from_db) = @_;
290              
291 0 0         if(ref $val)
292             {
293 0 0 0       if($size && $val->Size != $size)
294             {
295 0           return Bit::Vector->new_Bin($size, $val->to_Bin);
296             }
297              
298 0           return $val;
299             }
300              
301 16     16   138 no warnings 'uninitialized';
  16         48  
  16         13772  
302 0 0 0       if($from_db && $val =~ /^\d+$/)
    0 0        
    0 0        
    0          
    0          
303             {
304 0   0       return Bit::Vector->new_Dec($size || (length($val) * 4), $val);
305             }
306             elsif($val =~ /^[10]+$/)
307             {
308 0   0       return Bit::Vector->new_Bin($size || length $val, $val);
309             }
310             elsif($val =~ /^\d*[2-9]\d*$/)
311             {
312 0   0       return Bit::Vector->new_Dec($size || (length($val) * 4), $val);
313             }
314             elsif($val =~ s/^0x// || $val =~ s/^X'(.*)'$/$1/ || $val =~ /^[0-9a-f]+$/i)
315             {
316 0   0       return Bit::Vector->new_Hex($size || (length($val) * 4), $val);
317             }
318             elsif($val =~ s/^B'([10]+)'$/$1/i)
319             {
320 0   0       return Bit::Vector->new_Bin($size || length $val, $val);
321             }
322             else
323             {
324 0           return undef;
325             #return Bit::Vector->new_Bin($size || length($val), $val);
326             }
327             }
328              
329             sub format_bitfield
330             {
331 0     0 0   my($self, $vec, $size) = @_;
332              
333 0 0         $vec = Bit::Vector->new_Bin($size, $vec->to_Bin) if($size);
334              
335             # MySQL 5.0.3 or later requires this crap...
336 0 0         if($self->database_version >= 5_000_003)
337             {
338 0           return q(b') . $vec->to_Bin . q('); # 'CAST(' . $vec->to_Dec . ' AS UNSIGNED)';
339             }
340              
341 0           return hex($vec->to_Hex);
342             }
343              
344 0 0   0 0   sub validate_bitfield_keyword { defined $_[1] ? 1 : 0 }
345              
346             sub should_inline_bitfield_value
347             {
348             # MySQL 5.0.3 or later requires this crap...
349 0 0 0 0 0   return $_[0]->{'should_inline_bitfield_value'} ||=
350             (shift->database_version >= 5_000_003) ? 1 : 0;
351             }
352              
353             sub select_bitfield_column_sql
354             {
355 0     0 0   my($self, $column, $table) = @_;
356              
357             # MySQL 5.0.3 or later requires this crap...
358 0 0         if($self->database_version >= 5_000_003)
359             {
360 0           return q{CONCAT("b'", BIN(} .
361             $self->auto_quote_column_with_table($column, $table) .
362             q{ + 0), "'")};
363             }
364             else
365             {
366 0           return $self->auto_quote_column_with_table($column, $table) . q{ + 0};
367             }
368             }
369              
370             sub parse_set
371             {
372 0     0 1   my($self) = shift;
373              
374 0 0         return $_[0] if(ref $_[0] eq 'ARRAY');
375              
376 0 0 0       if(@_ > 1 && !ref $_[1])
377             {
378 0           pop(@_);
379 0           return [ @_ ];
380             }
381              
382 0           my $val = $_[0];
383              
384 0 0         return undef unless(defined $val);
385              
386 0           my @set = split(/,/, $val);
387              
388 0           return \@set;
389             }
390              
391             sub format_set
392             {
393 0     0 1   my($self) = shift;
394              
395 0 0         my @set = (ref $_[0]) ? @{$_[0]} : @_;
  0            
396              
397 0 0 0       return undef unless(@set && defined $set[0]);
398              
399             return join(',', map
400             {
401 0 0         if(!defined $_)
  0            
402             {
403 0           Carp::croak 'Undefined value found in array or list passed to ',
404             __PACKAGE__, '::format_set()';
405             }
406 0           else { $_ }
407             }
408             @set);
409             }
410              
411             sub refine_dbi_column_info
412             {
413 0     0 0   my($self, $col_info) = @_;
414              
415 0           my $method = ref($self)->parent_class . '::refine_dbi_column_info';
416              
417 16     16   139 no strict 'refs';
  16         49  
  16         9879  
418 0           $self->$method($col_info);
419              
420 0 0 0       if($col_info->{'TYPE_NAME'} eq 'timestamp' && defined $col_info->{'COLUMN_DEF'})
421             {
422 0 0 0       if($col_info->{'COLUMN_DEF'} eq '0000-00-00 00:00:00' ||
    0          
423             $col_info->{'COLUMN_DEF'} eq '00000000000000')
424             {
425             # MySQL uses strange "all zeros" default values for timestamp fields.
426             # We'll just ignore them, since MySQL will use them internally no
427             # matter what we do.
428 0           $col_info->{'COLUMN_DEF'} = undef;
429             }
430             elsif($col_info->{'COLUMN_DEF'} eq 'CURRENT_TIMESTAMP')
431             {
432             # Translate "current time" value into something that our date parser
433             # will understand.
434             #$col_info->{'COLUMN_DEF'} = 'now';
435              
436             # Actually, let the database handle this.
437 0           $col_info->{'COLUMN_DEF'} = undef;
438             }
439             }
440              
441             # Put valid SET and ENUM values in standard keys
442 0 0         if($col_info->{'TYPE_NAME'} eq 'set')
    0          
443             {
444              
445 0           $col_info->{'RDBO_SET_VALUES'} = $col_info->{'mysql_values'};
446             }
447             elsif($col_info->{'TYPE_NAME'} eq 'enum')
448             {
449 0           $col_info->{'RDBO_ENUM_VALUES'} = $col_info->{'mysql_values'};
450             }
451              
452             # Consider (big)int autoincrement to be (big)serial
453 0 0 0       if($col_info->{'mysql_is_auto_increment'} &&
454             ref($self)->coerce_autoincrement_to_serial)
455             {
456 0 0         if($col_info->{'TYPE_NAME'} eq 'int')
    0          
457             {
458 0           $col_info->{'TYPE_NAME'} = 'serial';
459             }
460             elsif($col_info->{'TYPE_NAME'} eq 'bigint')
461             {
462 0           $col_info->{'TYPE_NAME'} = 'bigserial';
463             }
464             }
465              
466 0           return;
467             }
468              
469 0     0 0   sub supports_arbitrary_defaults_on_insert { 1 }
470 0     0 0   sub likes_redundant_join_conditions { 1 }
471              
472             sub supports_on_duplicate_key_update
473             {
474 0     0 0   my($self) = shift;
475              
476 0 0         if(defined $self->{'supports_on_duplicate_key_update'})
477             {
478 0           return $self->{'supports_on_duplicate_key_update'};
479             }
480              
481 0 0         if($self->database_version >= 4_001_000)
482             {
483 0           return $self->{'supports_on_duplicate_key_update'} = 1;
484             }
485              
486 0           return $self->{'supports_on_duplicate_key_update'} = 0;
487             }
488              
489             sub supports_select_from_subselect
490             {
491 0     0 0   my($self) = shift;
492              
493 0 0         if(defined $self->{'supports_select_from_subselect'})
494             {
495 0           return $self->{'supports_select_from_subselect'};
496             }
497              
498 0 0         if($self->database_version >= 5_000_045)
499             {
500 0           return $self->{'supports_select_from_subselect'} = 1;
501             }
502              
503 0           return $self->{'supports_select_from_subselect'} = 0;
504             }
505              
506             #our %Reserved_Words = map { $_ => 1 } qw(read for case);
507             #sub is_reserved_word { $Reserved_Words{lc $_[1]} }
508              
509             *is_reserved_word = \&SQL::ReservedWords::MySQL::is_reserved;
510              
511             #
512             # Introspection
513             #
514              
515             sub _get_primary_key_column_names
516             {
517 0     0     my($self, $catalog, $schema, $table) = @_;
518              
519 0 0         my $dbh = $self->dbh or die $self->error;
520              
521 0           local $dbh->{'FetchHashKeyName'} = 'NAME';
522              
523             my $fq_table =
524 0           join('.', grep { defined } ($catalog, $schema,
  0            
525             $self->quote_table_name($table)));
526              
527 0           my $sth = $dbh->prepare("SHOW INDEX FROM $fq_table");
528 0           $sth->execute;
529              
530 0           my @columns;
531              
532 0           while(my $row = $sth->fetchrow_hashref)
533             {
534 0 0         next unless($row->{'Key_name'} eq 'PRIMARY');
535 0           push(@columns, $row->{'Column_name'});
536             }
537              
538 0           return \@columns;
539             }
540              
541             # Bury warning down here to make nice with version extractors
542             if(defined $DBD::mysql::VERSION && $DBD::mysql::VERSION <= 2.9)
543             {
544             warn "WARNING: Rose::DB may not work correctly with DBD::mysql ",
545             "version 2.9 or earlier. You have version $DBD::mysql::VERSION";
546             }
547              
548             1;
549              
550             __END__
551              
552             =head1 NAME
553              
554             Rose::DB::MySQL - MySQL driver class for Rose::DB.
555              
556             =head1 SYNOPSIS
557              
558             use Rose::DB;
559              
560             Rose::DB->register_db(
561             domain => 'development',
562             type => 'main',
563             driver => 'mysql',
564             database => 'dev_db',
565             host => 'localhost',
566             username => 'devuser',
567             password => 'mysecret',
568             );
569              
570              
571             Rose::DB->default_domain('development');
572             Rose::DB->default_type('main');
573             ...
574              
575             # Set max length of varchar columns used to emulate the array data type
576             Rose::DB::MySQL->max_array_characters(128);
577              
578             $db = Rose::DB->new; # $db is really a Rose::DB::MySQL-derived object
579             ...
580              
581             =head1 DESCRIPTION
582              
583             L<Rose::DB> blesses objects into a class derived from L<Rose::DB::MySQL> when the L<driver|Rose::DB/driver> is "mysql". This mapping of driver names to class names is configurable. See the documentation for L<Rose::DB>'s L<new()|Rose::DB/new> and L<driver_class()|Rose::DB/driver_class> methods for more information.
584              
585             This class cannot be used directly. You must use L<Rose::DB> and let its L<new()|Rose::DB/new> method return an object blessed into the appropriate class for you, according to its L<driver_class()|Rose::DB/driver_class> mappings.
586              
587             Only the methods that are new or have different behaviors than those in L<Rose::DB> are documented here. See the L<Rose::DB> documentation for the full list of methods.
588              
589             =head1 CLASS METHODS
590              
591             =over 4
592              
593             =item B<coerce_autoincrement_to_serial [BOOL]>
594              
595             Get or set a boolean value that indicates whether or not "auto-increment" columns will be considered to have the column type "serial." If true, "integer" columns are coerced to the "serial" column type, and "bigint" columns use the "bigserial" column type. The default value is true.
596              
597             This setting comes into play when L<Rose::DB::Object::Loader> is used to auto-create column metadata based on an existing database schema.
598              
599             =item B<max_array_characters [INT]>
600              
601             Get or set the maximum length of varchar columns used to emulate the array data type. The default value is 255.
602              
603             MySQL does not have a native "ARRAY" data type, but this data type can be emulated using a "VARCHAR" column and a specially formatted string. The formatting and parsing of this string is handled by the L<format_array|/format_array> and L<parse_array|/parse_array> object methods. The maximum length limit is honored by the L<format_array|/format_array> object method.
604              
605             =item B<max_interval_characters [INT]>
606              
607             Get or set the maximum length of varchar columns used to emulate the interval data type. The default value is 255.
608              
609             MySQL does not have a native "interval" data type, but this data type can be emulated using a "VARCHAR" column and a specially formatted string. The formatting and parsing of this string is handled by the L<format_interval|/format_interval> and L<parse_interval|/parse_interval> object methods. The maximum length limit is honored by the L<format_interval|/format_interval> object method.
610              
611             =back
612              
613             =head1 OBJECT METHODS
614              
615             =over 4
616              
617             =item B<mysql_auto_reconnect [BOOL]>
618              
619             Get or set the L<mysql_auto_reconnect|DBD::mysql/mysql_auto_reconnect> database handle attribute. This is set directly on the L<dbh|Rose::DB/dbh>, if one exists. Otherwise, it will be set when the L<dbh|Rose::DB/dbh> is created. If no value for this attribute is defined (the default) then it will not be set when the L<dbh|Rose::DB/dbh> is created, deferring instead to whatever default value L<DBD::mysql> chooses.
620              
621             Returns the value of this attribute in the L<dbh|Rose::DB/dbh>, if one exists, or the value that will be set when the L<dbh|Rose::DB/dbh> is next created.
622              
623             See the L<DBD::mysql|DBD::mysql/mysql_auto_reconnect> documentation to learn more about this attribute.
624              
625             =item B<mysql_bind_type_guessing [BOOL]>
626              
627             Get or set the L<mysql_bind_type_guessing|DBD::mysql/mysql_bind_type_guessing> database handle attribute. This is set directly on the L<dbh|Rose::DB/dbh>, if one exists. Otherwise, it will be set when the L<dbh|Rose::DB/dbh> is created. If no value for this attribute is defined (the default) then it will not be set when the L<dbh|Rose::DB/dbh> is created, deferring instead to whatever default value L<DBD::mysql> chooses.
628              
629             Returns the value of this attribute in the L<dbh|Rose::DB/dbh>, if one exists, or the value that will be set when the L<dbh|Rose::DB/dbh> is next created.
630              
631             See the L<DBD::mysql|DBD::mysql/mysql_bind_type_guessing> documentation to learn more about this attribute.
632              
633             =item B<mysql_client_found_rows [BOOL]>
634              
635             Get or set the L<mysql_client_found_rows|DBD::mysql/mysql_client_found_rows> database handle attribute. This is set directly on the L<dbh|Rose::DB/dbh>, if one exists. Otherwise, it will be set when the L<dbh|Rose::DB/dbh> is created. If no value for this attribute is defined (the default) then it will not be set when the L<dbh|Rose::DB/dbh> is created, deferring instead to whatever default value L<DBD::mysql> chooses.
636              
637             Returns the value of this attribute in the L<dbh|Rose::DB/dbh>, if one exists, or the value that will be set when the L<dbh|Rose::DB/dbh> is next created.
638              
639             See the L<DBD::mysql|DBD::mysql/mysql_client_found_rows> documentation to learn more about this attribute.
640              
641             =item B<mysql_compression [BOOL]>
642              
643             Get or set the L<mysql_compression|DBD::mysql/mysql_compression> database handle attribute. This is set directly on the L<dbh|Rose::DB/dbh>, if one exists. Otherwise, it will be set when the L<dbh|Rose::DB/dbh> is created. If no value for this attribute is defined (the default) then it will not be set when the L<dbh|Rose::DB/dbh> is created, deferring instead to whatever default value L<DBD::mysql> chooses.
644              
645             Returns the value of this attribute in the L<dbh|Rose::DB/dbh>, if one exists, or the value that will be set when the L<dbh|Rose::DB/dbh> is next created.
646              
647             See the L<DBD::mysql|DBD::mysql/mysql_compression> documentation to learn more about this attribute.
648              
649             =item B<mysql_connect_timeout [BOOL]>
650              
651             Get or set the L<mysql_connect_timeout|DBD::mysql/mysql_connect_timeout> database handle attribute. This is set directly on the L<dbh|Rose::DB/dbh>, if one exists. Otherwise, it will be set when the L<dbh|Rose::DB/dbh> is created. If no value for this attribute is defined (the default) then it will not be set when the L<dbh|Rose::DB/dbh> is created, deferring instead to whatever default value L<DBD::mysql> chooses.
652              
653             Returns the value of this attribute in the L<dbh|Rose::DB/dbh>, if one exists, or the value that will be set when the L<dbh|Rose::DB/dbh> is next created.
654              
655             See the L<DBD::mysql|DBD::mysql/mysql_connect_timeout> documentation to learn more about this attribute.
656              
657             =item B<mysql_embedded_groups [STRING]>
658              
659             Get or set the L<mysql_embedded_groups|DBD::mysql/mysql_embedded_groups> database handle attribute. This is set directly on the L<dbh|Rose::DB/dbh>, if one exists. Otherwise, it will be set when the L<dbh|Rose::DB/dbh> is created. If no value for this attribute is defined (the default) then it will not be set when the L<dbh|Rose::DB/dbh> is created, deferring instead to whatever default value L<DBD::mysql> chooses.
660              
661             Returns the value of this attribute in the L<dbh|Rose::DB/dbh>, if one exists, or the value that will be set when the L<dbh|Rose::DB/dbh> is next created.
662              
663             See the L<DBD::mysql|DBD::mysql/mysql_embedded_groups> documentation to learn more about this attribute.
664              
665             =item B<mysql_embedded_options [STRING]>
666              
667             Get or set the L<mysql_embedded_options|DBD::mysql/mysql_embedded_options> database handle attribute. This is set directly on the L<dbh|Rose::DB/dbh>, if one exists. Otherwise, it will be set when the L<dbh|Rose::DB/dbh> is created. If no value for this attribute is defined (the default) then it will not be set when the L<dbh|Rose::DB/dbh> is created, deferring instead to whatever default value L<DBD::mysql> chooses.
668              
669             Returns the value of this attribute in the L<dbh|Rose::DB/dbh>, if one exists, or the value that will be set when the L<dbh|Rose::DB/dbh> is next created.
670              
671             See the L<DBD::mysql|DBD::mysql/mysql_embedded_options> documentation to learn more about this attribute.
672              
673             =item B<mysql_enable_utf8 [BOOL]>
674              
675             Get or set the L<mysql_enable_utf8|DBD::mysql/mysql_enable_utf8> database handle attribute. This is set directly on the L<dbh|Rose::DB/dbh>, if one exists, by executing the SQL C<SET NAMES utf8>. Otherwise, it will be set when the L<dbh|Rose::DB/dbh> is created. If no value for this attribute is defined (the default) then it will not be set when the L<dbh|Rose::DB/dbh> is created, deferring instead to whatever default value L<DBD::mysql> chooses.
676              
677             Returns the value of this attribute in the L<dbh|Rose::DB/dbh>, if one exists, or the value that will be set when the L<dbh|Rose::DB/dbh> is next created.
678              
679             See the L<DBD::mysql|DBD::mysql/mysql_enable_utf8> documentation to learn more about this attribute.
680              
681             =item B<mysql_enable_utf8mb4 [BOOL]>
682              
683             Get or set the L<mysql_enable_utf8mb4|DBD::mysql/mysql_enable_utf8mb4> database handle attribute. This is set directly on the L<dbh|Rose::DB/dbh>, if one exists, by executing the SQL C<SET NAMES utf8mb4>. Otherwise, it will be set when the L<dbh|Rose::DB/dbh> is created. If no value for this attribute is defined (the default) then it will not be set when the L<dbh|Rose::DB/dbh> is created, deferring instead to whatever default value L<DBD::mysql> chooses.
684              
685             Returns the value of this attribute in the L<dbh|Rose::DB/dbh>, if one exists, or the value that will be set when the L<dbh|Rose::DB/dbh> is next created.
686              
687             See the L<DBD::mysql|DBD::mysql/mysql_enable_utf8mb4> documentation to learn more about this attribute.
688              
689             =item B<mysql_local_infile [STRING]>
690              
691             Get or set the L<mysql_local_infile|DBD::mysql/mysql_local_infile> database handle attribute. This is set directly on the L<dbh|Rose::DB/dbh>, if one exists. Otherwise, it will be set when the L<dbh|Rose::DB/dbh> is created. If no value for this attribute is defined (the default) then it will not be set when the L<dbh|Rose::DB/dbh> is created, deferring instead to whatever default value L<DBD::mysql> chooses.
692              
693             Returns the value of this attribute in the L<dbh|Rose::DB/dbh>, if one exists, or the value that will be set when the L<dbh|Rose::DB/dbh> is next created.
694              
695             See the L<DBD::mysql|DBD::mysql/mysql_local_infile> documentation to learn more about this attribute.
696              
697             =item B<mysql_multi_statements [BOOL]>
698              
699             Get or set the L<mysql_multi_statements|DBD::mysql/mysql_multi_statements> database handle attribute. This is set directly on the L<dbh|Rose::DB/dbh>, if one exists. Otherwise, it will be set when the L<dbh|Rose::DB/dbh> is created. If no value for this attribute is defined (the default) then it will not be set when the L<dbh|Rose::DB/dbh> is created, deferring instead to whatever default value L<DBD::mysql> chooses.
700              
701             Returns the value of this attribute in the L<dbh|Rose::DB/dbh>, if one exists, or the value that will be set when the L<dbh|Rose::DB/dbh> is next created.
702              
703             See the L<DBD::mysql|DBD::mysql/mysql_multi_statements> documentation to learn more about this attribute.
704              
705             =item B<mysql_read_default_file [STRING]>
706              
707             Get or set the L<mysql_read_default_file|DBD::mysql/mysql_read_default_file> database handle attribute. This is set directly on the L<dbh|Rose::DB/dbh>, if one exists. Otherwise, it will be set when the L<dbh|Rose::DB/dbh> is created. If no value for this attribute is defined (the default) then it will not be set when the L<dbh|Rose::DB/dbh> is created, deferring instead to whatever default value L<DBD::mysql> chooses.
708              
709             Returns the value of this attribute in the L<dbh|Rose::DB/dbh>, if one exists, or the value that will be set when the L<dbh|Rose::DB/dbh> is next created.
710              
711             See the L<DBD::mysql|DBD::mysql/mysql_read_default_file> documentation to learn more about this attribute.
712              
713             =item B<mysql_read_default_group [STRING]>
714              
715             Get or set the L<mysql_read_default_group|DBD::mysql/mysql_read_default_group> database handle attribute. This is set directly on the L<dbh|Rose::DB/dbh>, if one exists. Otherwise, it will be set when the L<dbh|Rose::DB/dbh> is created. If no value for this attribute is defined (the default) then it will not be set when the L<dbh|Rose::DB/dbh> is created, deferring instead to whatever default value L<DBD::mysql> chooses.
716              
717             Returns the value of this attribute in the L<dbh|Rose::DB/dbh>, if one exists, or the value that will be set when the L<dbh|Rose::DB/dbh> is next created.
718              
719             See the L<DBD::mysql|DBD::mysql/mysql_read_default_group> documentation to learn more about this attribute.
720              
721             =item B<mysql_socket [STRING]>
722              
723             Get or set the L<mysql_socket|DBD::mysql/mysql_socket> database handle attribute. This is set directly on the L<dbh|Rose::DB/dbh>, if one exists. Otherwise, it will be set when the L<dbh|Rose::DB/dbh> is created. If no value for this attribute is defined (the default) then it will not be set when the L<dbh|Rose::DB/dbh> is created, deferring instead to whatever default value L<DBD::mysql> chooses.
724              
725             Returns the value of this attribute in the L<dbh|Rose::DB/dbh>, if one exists, or the value that will be set when the L<dbh|Rose::DB/dbh> is next created.
726              
727             See the L<DBD::mysql|DBD::mysql/mysql_socket> documentation to learn more about this attribute.
728              
729             =item B<mysql_ssl [BOOL]>
730              
731             Get or set the L<mysql_ssl|DBD::mysql/mysql_ssl> database handle attribute. This is set directly on the L<dbh|Rose::DB/dbh>, if one exists. Otherwise, it will be set when the L<dbh|Rose::DB/dbh> is created. If no value for this attribute is defined (the default) then it will not be set when the L<dbh|Rose::DB/dbh> is created, deferring instead to whatever default value L<DBD::mysql> chooses.
732              
733             Returns the value of this attribute in the L<dbh|Rose::DB/dbh>, if one exists, or the value that will be set when the L<dbh|Rose::DB/dbh> is next created.
734              
735             See the L<DBD::mysql|DBD::mysql/mysql_ssl> documentation to learn more about this attribute.
736              
737             =item B<mysql_ssl_ca_file [STRING]>
738              
739             Get or set the L<mysql_ssl_ca_file|DBD::mysql/mysql_ssl_ca_file> database handle attribute. This is set directly on the L<dbh|Rose::DB/dbh>, if one exists. Otherwise, it will be set when the L<dbh|Rose::DB/dbh> is created. If no value for this attribute is defined (the default) then it will not be set when the L<dbh|Rose::DB/dbh> is created, deferring instead to whatever default value L<DBD::mysql> chooses.
740              
741             Returns the value of this attribute in the L<dbh|Rose::DB/dbh>, if one exists, or the value that will be set when the L<dbh|Rose::DB/dbh> is next created.
742              
743             See the L<DBD::mysql|DBD::mysql/mysql_ssl_ca_file> documentation to learn more about this attribute.
744              
745             =item B<mysql_ssl_ca_path [STRING]>
746              
747             Get or set the L<mysql_ssl_ca_path|DBD::mysql/mysql_ssl_ca_path> database handle attribute. This is set directly on the L<dbh|Rose::DB/dbh>, if one exists. Otherwise, it will be set when the L<dbh|Rose::DB/dbh> is created. If no value for this attribute is defined (the default) then it will not be set when the L<dbh|Rose::DB/dbh> is created, deferring instead to whatever default value L<DBD::mysql> chooses.
748              
749             Returns the value of this attribute in the L<dbh|Rose::DB/dbh>, if one exists, or the value that will be set when the L<dbh|Rose::DB/dbh> is next created.
750              
751             See the L<DBD::mysql|DBD::mysql/mysql_ssl_ca_path> documentation to learn more about this attribute.
752              
753             =item B<mysql_ssl_cipher [STRING]>
754              
755             Get or set the L<mysql_ssl_cipher|DBD::mysql/mysql_ssl_cipher> database handle attribute. This is set directly on the L<dbh|Rose::DB/dbh>, if one exists. Otherwise, it will be set when the L<dbh|Rose::DB/dbh> is created. If no value for this attribute is defined (the default) then it will not be set when the L<dbh|Rose::DB/dbh> is created, deferring instead to whatever default value L<DBD::mysql> chooses.
756              
757             Returns the value of this attribute in the L<dbh|Rose::DB/dbh>, if one exists, or the value that will be set when the L<dbh|Rose::DB/dbh> is next created.
758              
759             See the L<DBD::mysql|DBD::mysql/mysql_ssl_cipher> documentation to learn more about this attribute.
760              
761             =item B<mysql_ssl_client_cert [STRING]>
762              
763             Get or set the L<mysql_ssl_client_cert|DBD::mysql/mysql_ssl_client_cert> database handle attribute. This is set directly on the L<dbh|Rose::DB/dbh>, if one exists. Otherwise, it will be set when the L<dbh|Rose::DB/dbh> is created. If no value for this attribute is defined (the default) then it will not be set when the L<dbh|Rose::DB/dbh> is created, deferring instead to whatever default value L<DBD::mysql> chooses.
764              
765             Returns the value of this attribute in the L<dbh|Rose::DB/dbh>, if one exists, or the value that will be set when the L<dbh|Rose::DB/dbh> is next created.
766              
767             See the L<DBD::mysql|DBD::mysql/mysql_ssl_client_cert> documentation to learn more about this attribute.
768              
769             =item B<mysql_ssl_client_key [STRING]>
770              
771             Get or set the L<mysql_ssl_client_key|DBD::mysql/mysql_ssl_client_key> database handle attribute. This is set directly on the L<dbh|Rose::DB/dbh>, if one exists. Otherwise, it will be set when the L<dbh|Rose::DB/dbh> is created. If no value for this attribute is defined (the default) then it will not be set when the L<dbh|Rose::DB/dbh> is created, deferring instead to whatever default value L<DBD::mysql> chooses.
772              
773             Returns the value of this attribute in the L<dbh|Rose::DB/dbh>, if one exists, or the value that will be set when the L<dbh|Rose::DB/dbh> is next created.
774              
775             See the L<DBD::mysql|DBD::mysql/mysql_ssl_client_key> documentation to learn more about this attribute.
776              
777             =item B<mysql_use_result [BOOL]>
778              
779             Get or set the L<mysql_use_result|DBD::mysql/mysql_use_result> database handle attribute. This is set directly on the L<dbh|Rose::DB/dbh>, if one exists. Otherwise, it will be set when the L<dbh|Rose::DB/dbh> is created. If no value for this attribute is defined (the default) then it will not be set when the L<dbh|Rose::DB/dbh> is created, deferring instead to whatever default value L<DBD::mysql> chooses.
780              
781             Returns the value of this attribute in the L<dbh|Rose::DB/dbh>, if one exists, or the value that will be set when the L<dbh|Rose::DB/dbh> is next created.
782              
783             See the L<DBD::mysql|DBD::mysql/mysql_use_result> documentation to learn more about this attribute.
784              
785             =back
786              
787             =head2 Value Parsing and Formatting
788              
789             =over 4
790              
791             =item B<format_array ARRAYREF | LIST>
792              
793             Given a reference to an array or a list of values, return a specially formatted string. Undef is returned if ARRAYREF points to an empty array or if LIST is not passed. The array or list must not contain undefined values.
794              
795             If the resulting string is longer than L<max_array_characters|/max_array_characters>, a fatal error will occur.
796              
797             =item B<format_interval DURATION>
798              
799             Given a L<DateTime::Duration> object, return a string formatted according to the rules of PostgreSQL's "INTERVAL" column type. If DURATION is undefined, a L<DateTime::Duration> object, a valid interval keyword (according to L<validate_interval_keyword|Rose::DB/validate_interval_keyword>), or if it looks like a function call (matches C</^\w+\(.*\)$/>) and L<keyword_function_calls|Rose::DB/keyword_function_calls> is true, then it is returned unmodified.
800              
801             If the resulting string is longer than L<max_interval_characters|/max_interval_characters>, a fatal error will occur.
802              
803             =item B<format_set ARRAYREF | LIST>
804              
805             Given a reference to an array or a list of values, return a string formatted according to the rules of MySQL's "SET" data type. Undef is returned if ARRAYREF points to an empty array or if LIST is not passed. If the array or list contains undefined values, a fatal error will occur.
806              
807             =item B<parse_array STRING | LIST | ARRAYREF>
808              
809             Parse STRING and return a reference to an array. STRING should be formatted according to the MySQL array data type emulation format returned by L<format_array()|/format_array>. Undef is returned if STRING is undefined.
810              
811             If a LIST of more than one item is passed, a reference to an array containing the values in LIST is returned.
812              
813             If a an ARRAYREF is passed, it is returned as-is.
814              
815             =item B<parse_interval STRING>
816              
817             Parse STRING and return a L<DateTime::Duration> object. STRING should be formatted according to the PostgreSQL native "interval" (years, months, days, hours, minutes, seconds) data type.
818              
819             If STRING is a L<DateTime::Duration> object, a valid interval keyword (according to L<validate_interval_keyword|Rose::DB/validate_interval_keyword>), or if it looks like a function call (matches C</^\w+\(.*\)$/>) and L<keyword_function_calls|Rose::DB/keyword_function_calls> is true, then it is returned unmodified. Otherwise, undef is returned if STRING could not be parsed as a valid "interval" value.
820              
821             =item B<parse_set STRING | LIST | ARRAYREF>
822              
823             Parse STRING and return a reference to an array. STRING should be formatted according to MySQL's "SET" data type. Undef is returned if STRING is undefined.
824              
825             If a LIST of more than one item is passed, a reference to an array containing the values in LIST is returned.
826              
827             If a an ARRAYREF is passed, it is returned as-is.
828              
829             =item B<validate_date_keyword STRING>
830              
831             Returns true if STRING is a valid keyword for the MySQL "date" data type. Valid (case-insensitive) date keywords are:
832              
833             curdate()
834             current_date
835             current_date()
836             now()
837             sysdate()
838             00000-00-00
839              
840             Any string that looks like a function call (matches /^\w+\(.*\)$/) is also considered a valid date keyword if L<keyword_function_calls|Rose::DB/keyword_function_calls> is true.
841              
842             =item B<validate_datetime_keyword STRING>
843              
844             Returns true if STRING is a valid keyword for the MySQL "datetime" data type, false otherwise. Valid (case-insensitive) datetime keywords are:
845              
846             curdate()
847             current_date
848             current_date()
849             current_time
850             current_time()
851             current_timestamp
852             current_timestamp()
853             curtime()
854             now()
855             sysdate()
856             0000-00-00 00:00:00
857              
858             Any string that looks like a function call (matches /^\w+\(.*\)$/) is also considered a valid datetime keyword if L<keyword_function_calls|Rose::DB/keyword_function_calls> is true.
859              
860             =item B<validate_timestamp_keyword STRING>
861              
862             Returns true if STRING is a valid keyword for the MySQL "timestamp" data type, false otherwise. Valid (case-insensitive) timestamp keywords are:
863              
864             curdate()
865             current_date
866             current_date()
867             current_time
868             current_time()
869             current_timestamp
870             current_timestamp()
871             curtime()
872             now()
873             sysdate()
874             0000-00-00 00:00:00
875             00000000000000
876              
877             Any string that looks like a function call (matches /^\w+\(.*\)$/) is also considered a valid timestamp keyword if L<keyword_function_calls|Rose::DB/keyword_function_calls> is true.
878              
879             =back
880              
881             =head1 AUTHOR
882              
883             John C. Siracusa (siracusa@gmail.com)
884              
885             =head1 LICENSE
886              
887             Copyright (c) 2010 by John C. Siracusa. All rights reserved. This program is
888             free software; you can redistribute it and/or modify it under the same terms
889             as Perl itself.