File Coverage

blib/lib/Rose/DB/MariaDB.pm
Criterion Covered Total %
statement 36 224 16.0
branch 0 110 0.0
condition 0 79 0.0
subroutine 12 65 18.4
pod 26 52 50.0
total 74 530 13.9


line stmt bran cond sub pod time code
1             package Rose::DB::MariaDB;
2              
3 16     16   112 use strict;
  16         36  
  16         468  
4              
5 16     16   81 use Carp();
  16         30  
  16         255  
6              
7 16     16   73 use DateTime::Format::MySQL;
  16         33  
  16         290  
8 16     16   77 use SQL::ReservedWords::MySQL();
  16         33  
  16         607  
9              
10             TRY:
11             {
12             local $@;
13             eval { require DBD::MariaDB }; # Ignore errors
14             }
15              
16 16     16   80 use Rose::DB;
  16         30  
  16         783  
17              
18             our $VERSION = '0.780';
19              
20             our $Debug = 0;
21              
22             use Rose::Class::MakeMethods::Generic
23             (
24 16         116 inheritable_scalar =>
25             [
26             'supports_schema',
27             'coerce_autoincrement_to_serial',
28             ]
29 16     16   97 );
  16         30  
30              
31             __PACKAGE__->supports_schema(1);
32             __PACKAGE__->coerce_autoincrement_to_serial(1);
33              
34             #
35             # Object methods
36             #
37              
38 0     0 0   sub registration_schema { shift->database }
39              
40             sub build_dsn
41             {
42 0     0 0   my($self_or_class, %args) = @_;
43              
44 0           my %info;
45              
46 0   0       $info{'database'} = $args{'db'} || $args{'database'};
47 0           $info{'host'} = $args{'host'};
48 0           $info{'port'} = $args{'port'};
49              
50             return
51             "dbi:MariaDB:" .
52 0           join(';', map { "$_=$info{$_}" } grep { defined $info{$_} }
  0            
  0            
53             qw(database host port));
54             }
55              
56 0     0 0   sub dbi_driver { 'MariaDB' }
57              
58 0     0 1   sub mariadb_auto_reconnect { shift->dbh_attribute_boolean('mariadb_auto_reconnect', @_) }
59 0     0 1   sub mariadb_client_found_rows { shift->dbh_attribute_boolean('mariadb_client_found_rows', @_) }
60 0     0 1   sub mariadb_compression { shift->dbh_attribute_boolean('mariadb_compression', @_) }
61 0     0 1   sub mariadb_connect_timeout { shift->dbh_attribute_boolean('mariadb_connect_timeout', @_) }
62 0     0 1   sub mariadb_embedded_groups { shift->dbh_attribute('mariadb_embedded_groups', @_) }
63 0     0 1   sub mariadb_embedded_options { shift->dbh_attribute('mariadb_embedded_options', @_) }
64 0     0 1   sub mariadb_local_infile { shift->dbh_attribute('mariadb_local_infile', @_) }
65 0     0 1   sub mariadb_multi_statements { shift->dbh_attribute_boolean('mariadb_multi_statements', @_) }
66 0     0 1   sub mariadb_read_default_file { shift->dbh_attribute('mariadb_read_default_file', @_) }
67 0     0 1   sub mariadb_read_default_group { shift->dbh_attribute('mariadb_read_default_group', @_) }
68 0     0 1   sub mariadb_socket { shift->dbh_attribute('mariadb_socket', @_) }
69 0     0 1   sub mariadb_ssl { shift->dbh_attribute_boolean('mariadb_ssl', @_) }
70 0     0 1   sub mariadb_ssl_ca_file { shift->dbh_attribute('mariadb_ssl_ca_file', @_) }
71 0     0 1   sub mariadb_ssl_ca_path { shift->dbh_attribute('mariadb_ssl_ca_path', @_) }
72 0     0 1   sub mariadb_ssl_cipher { shift->dbh_attribute('mariadb_ssl_cipher', @_) }
73 0     0 1   sub mariadb_ssl_client_cert { shift->dbh_attribute('mariadb_ssl_client_cert', @_) }
74 0     0 1   sub mariadb_ssl_client_key { shift->dbh_attribute('mariadb_ssl_client_key', @_) }
75 0     0 1   sub mariadb_use_result { shift->dbh_attribute_boolean('mariadb_use_result', @_) }
76 0     0 1   sub mariadb_bind_type_guessing { shift->dbh_attribute_boolean('mariadb_bind_type_guessing', @_) }
77              
78             sub mariadb_enable_utf8
79             {
80 0     0 1   my($self) = shift;
81 0 0 0       $self->dbh->do('SET NAMES utf8') if(@_ && $self->has_dbh);
82 0           $self->dbh_attribute_boolean('mariadb_enable_utf8', @_)
83             }
84              
85             sub mariadb_enable_utf8mb4
86             {
87 0     0 1   my($self) = shift;
88 0 0 0       $self->dbh->do('SET NAMES utf8mb4') if(@_ && $self->has_dbh);
89 0           $self->dbh_attribute_boolean('mariadb_enable_utf8mb4', @_)
90             }
91              
92             sub database_version
93             {
94 0     0 0   my($self) = shift;
95 0 0         return $self->{'database_version'} if(defined $self->{'database_version'});
96              
97 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         if($vers =~ /^(\d+)\.(\d+)(?:\.(\d+))?/)
101             {
102 0   0       $vers = sprintf('%d%03d%03d', $1, $2, $3 || 0);
103             }
104              
105 0           return $self->{'database_version'} = $vers;
106             }
107              
108             sub init_dbh
109             {
110 0     0 0   my($self) = shift;
111              
112 0           $self->{'supports_on_duplicate_key_update'} = undef;
113              
114 0           my $method = ref($self)->parent_class . '::init_dbh';
115              
116 16     16   17919 no strict 'refs';
  16         42  
  16         14769  
117 0           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 { 'mariadb_insertid' }
185              
186 0     0 0   sub last_insertid_from_sth { $_[1]->{'mariadb_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   132 no warnings;
  16         44  
  16         4040  
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   121 no warnings;
  16         34  
  16         3347  
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   185 no warnings;
  16         36  
  16         4724  
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   122 no warnings 'uninitialized';
  16         35  
  16         12927  
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   157 no strict 'refs';
  16         43  
  16         9197  
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->{'mariadb_values'};
446             }
447             elsif($col_info->{'TYPE_NAME'} eq 'enum')
448             {
449 0           $col_info->{'RDBO_ENUM_VALUES'} = $col_info->{'mariadb_values'};
450             }
451              
452             # Consider (big)int autoincrement to be (big)serial
453 0 0 0       if($col_info->{'mariadb_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             1;
542              
543             __END__
544              
545             =head1 NAME
546              
547             Rose::DB::MariaDB - MariaDB driver class for Rose::DB.
548              
549             =head1 SYNOPSIS
550              
551             use Rose::DB;
552              
553             Rose::DB->register_db(
554             domain => 'development',
555             type => 'main',
556             driver => 'mariadb',
557             database => 'dev_db',
558             host => 'localhost',
559             username => 'devuser',
560             password => 'mysecret',
561             );
562              
563              
564             Rose::DB->default_domain('development');
565             Rose::DB->default_type('main');
566             ...
567              
568             # Set max length of varchar columns used to emulate the array data type
569             Rose::DB::MariaDB->max_array_characters(128);
570              
571             $db = Rose::DB->new; # $db is really a Rose::DB::MariaDB-derived object
572             ...
573              
574             =head1 DESCRIPTION
575              
576             L<Rose::DB> blesses objects into a class derived from L<Rose::DB::MariaDB> when the L<driver|Rose::DB/driver> is "mariadb". 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.
577              
578             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.
579              
580             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.
581              
582             =head1 CLASS METHODS
583              
584             =over 4
585              
586             =item B<coerce_autoincrement_to_serial [BOOL]>
587              
588             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.
589              
590             This setting comes into play when L<Rose::DB::Object::Loader> is used to auto-create column metadata based on an existing database schema.
591              
592             =item B<max_array_characters [INT]>
593              
594             Get or set the maximum length of varchar columns used to emulate the array data type. The default value is 255.
595              
596             MariaDB 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.
597              
598             =item B<max_interval_characters [INT]>
599              
600             Get or set the maximum length of varchar columns used to emulate the interval data type. The default value is 255.
601              
602             MariaDB 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.
603              
604             =back
605              
606             =head1 OBJECT METHODS
607              
608             =over 4
609              
610             =item B<mariadb_auto_reconnect [BOOL]>
611              
612             Get or set the L<mariadb_auto_reconnect|DBD::MariaDB/mariadb_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::MariaDB> chooses.
613              
614             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.
615              
616             See the L<DBD::MariaDB|DBD::MariaDB/mariadb_auto_reconnect> documentation to learn more about this attribute.
617              
618             =item B<mariadb_bind_type_guessing [BOOL]>
619              
620             Get or set the L<mariadb_bind_type_guessing|DBD::MariaDB/mariadb_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::MariaDB> chooses.
621              
622             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.
623              
624             See the L<DBD::MariaDB|DBD::MariaDB/mariadb_bind_type_guessing> documentation to learn more about this attribute.
625              
626             =item B<mariadb_client_found_rows [BOOL]>
627              
628             Get or set the L<mariadb_client_found_rows|DBD::MariaDB/mariadb_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::MariaDB> chooses.
629              
630             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.
631              
632             See the L<DBD::MariaDB|DBD::MariaDB/mariadb_client_found_rows> documentation to learn more about this attribute.
633              
634             =item B<mariadb_compression [BOOL]>
635              
636             Get or set the L<mariadb_compression|DBD::MariaDB/mariadb_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::MariaDB> chooses.
637              
638             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.
639              
640             See the L<DBD::MariaDB|DBD::MariaDB/mariadb_compression> documentation to learn more about this attribute.
641              
642             =item B<mariadb_connect_timeout [BOOL]>
643              
644             Get or set the L<mariadb_connect_timeout|DBD::MariaDB/mariadb_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::MariaDB> chooses.
645              
646             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.
647              
648             See the L<DBD::MariaDB|DBD::MariaDB/mariadb_connect_timeout> documentation to learn more about this attribute.
649              
650             =item B<mariadb_embedded_groups [STRING]>
651              
652             Get or set the L<mariadb_embedded_groups|DBD::MariaDB/mariadb_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::MariaDB> chooses.
653              
654             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.
655              
656             See the L<DBD::MariaDB|DBD::MariaDB/mariadb_embedded_groups> documentation to learn more about this attribute.
657              
658             =item B<mariadb_embedded_options [STRING]>
659              
660             Get or set the L<mariadb_embedded_options|DBD::MariaDB/mariadb_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::MariaDB> chooses.
661              
662             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.
663              
664             See the L<DBD::MariaDB|DBD::MariaDB/mariadb_embedded_options> documentation to learn more about this attribute.
665              
666             =item B<mariadb_enable_utf8 [BOOL]>
667              
668             Get or set the L<mariadb_enable_utf8|DBD::MariaDB/mariadb_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::MariaDB> chooses.
669              
670             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.
671              
672             See the L<DBD::MariaDB|DBD::MariaDB/mariadb_enable_utf8> documentation to learn more about this attribute.
673              
674             =item B<mariadb_enable_utf8mb4 [BOOL]>
675              
676             Get or set the L<mariadb_enable_utf8mb4|DBD::MariaDB/mariadb_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::MariaDB> chooses.
677              
678             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.
679              
680             See the L<DBD::MariaDB|DBD::MariaDB/mariadb_enable_utf8mb4> documentation to learn more about this attribute.
681              
682             =item B<mariadb_local_infile [STRING]>
683              
684             Get or set the L<mariadb_local_infile|DBD::MariaDB/mariadb_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::MariaDB> chooses.
685              
686             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.
687              
688             See the L<DBD::MariaDB|DBD::MariaDB/mariadb_local_infile> documentation to learn more about this attribute.
689              
690             =item B<mariadb_multi_statements [BOOL]>
691              
692             Get or set the L<mariadb_multi_statements|DBD::MariaDB/mariadb_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::MariaDB> chooses.
693              
694             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.
695              
696             See the L<DBD::MariaDB|DBD::MariaDB/mariadb_multi_statements> documentation to learn more about this attribute.
697              
698             =item B<mariadb_read_default_file [STRING]>
699              
700             Get or set the L<mariadb_read_default_file|DBD::MariaDB/mariadb_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::MariaDB> chooses.
701              
702             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.
703              
704             See the L<DBD::MariaDB|DBD::MariaDB/mariadb_read_default_file> documentation to learn more about this attribute.
705              
706             =item B<mariadb_read_default_group [STRING]>
707              
708             Get or set the L<mariadb_read_default_group|DBD::MariaDB/mariadb_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::MariaDB> chooses.
709              
710             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.
711              
712             See the L<DBD::MariaDB|DBD::MariaDB/mariadb_read_default_group> documentation to learn more about this attribute.
713              
714             =item B<mariadb_socket [STRING]>
715              
716             Get or set the L<mariadb_socket|DBD::MariaDB/mariadb_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::MariaDB> chooses.
717              
718             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.
719              
720             See the L<DBD::MariaDB|DBD::MariaDB/mariadb_socket> documentation to learn more about this attribute.
721              
722             =item B<mariadb_ssl [BOOL]>
723              
724             Get or set the L<mariadb_ssl|DBD::MariaDB/mariadb_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::MariaDB> chooses.
725              
726             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.
727              
728             See the L<DBD::MariaDB|DBD::MariaDB/mariadb_ssl> documentation to learn more about this attribute.
729              
730             =item B<mariadb_ssl_ca_file [STRING]>
731              
732             Get or set the L<mariadb_ssl_ca_file|DBD::MariaDB/mariadb_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::MariaDB> chooses.
733              
734             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.
735              
736             See the L<DBD::MariaDB|DBD::MariaDB/mariadb_ssl_ca_file> documentation to learn more about this attribute.
737              
738             =item B<mariadb_ssl_ca_path [STRING]>
739              
740             Get or set the L<mariadb_ssl_ca_path|DBD::MariaDB/mariadb_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::MariaDB> chooses.
741              
742             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.
743              
744             See the L<DBD::MariaDB|DBD::MariaDB/mariadb_ssl_ca_path> documentation to learn more about this attribute.
745              
746             =item B<mariadb_ssl_cipher [STRING]>
747              
748             Get or set the L<mariadb_ssl_cipher|DBD::MariaDB/mariadb_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::MariaDB> chooses.
749              
750             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.
751              
752             See the L<DBD::MariaDB|DBD::MariaDB/mariadb_ssl_cipher> documentation to learn more about this attribute.
753              
754             =item B<mariadb_ssl_client_cert [STRING]>
755              
756             Get or set the L<mariadb_ssl_client_cert|DBD::MariaDB/mariadb_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::MariaDB> chooses.
757              
758             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.
759              
760             See the L<DBD::MariaDB|DBD::MariaDB/mariadb_ssl_client_cert> documentation to learn more about this attribute.
761              
762             =item B<mariadb_ssl_client_key [STRING]>
763              
764             Get or set the L<mariadb_ssl_client_key|DBD::MariaDB/mariadb_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::MariaDB> chooses.
765              
766             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.
767              
768             See the L<DBD::MariaDB|DBD::MariaDB/mariadb_ssl_client_key> documentation to learn more about this attribute.
769              
770             =item B<mariadb_use_result [BOOL]>
771              
772             Get or set the L<mariadb_use_result|DBD::MariaDB/mariadb_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::MariaDB> chooses.
773              
774             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.
775              
776             See the L<DBD::MariaDB|DBD::MariaDB/mariadb_use_result> documentation to learn more about this attribute.
777              
778             =back
779              
780             =head2 Value Parsing and Formatting
781              
782             =over 4
783              
784             =item B<format_array ARRAYREF | LIST>
785              
786             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.
787              
788             If the resulting string is longer than L<max_array_characters|/max_array_characters>, a fatal error will occur.
789              
790             =item B<format_interval DURATION>
791              
792             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.
793              
794             If the resulting string is longer than L<max_interval_characters|/max_interval_characters>, a fatal error will occur.
795              
796             =item B<format_set ARRAYREF | LIST>
797              
798             Given a reference to an array or a list of values, return a string formatted according to the rules of MariaDB'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.
799              
800             =item B<parse_array STRING | LIST | ARRAYREF>
801              
802             Parse STRING and return a reference to an array. STRING should be formatted according to the MariaDB array data type emulation format returned by L<format_array()|/format_array>. Undef is returned if STRING is undefined.
803              
804             If a LIST of more than one item is passed, a reference to an array containing the values in LIST is returned.
805              
806             If a an ARRAYREF is passed, it is returned as-is.
807              
808             =item B<parse_interval STRING>
809              
810             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.
811              
812             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.
813              
814             =item B<parse_set STRING | LIST | ARRAYREF>
815              
816             Parse STRING and return a reference to an array. STRING should be formatted according to MariaDB's "SET" data type. Undef is returned if STRING is undefined.
817              
818             If a LIST of more than one item is passed, a reference to an array containing the values in LIST is returned.
819              
820             If a an ARRAYREF is passed, it is returned as-is.
821              
822             =item B<validate_date_keyword STRING>
823              
824             Returns true if STRING is a valid keyword for the MariaDB "date" data type. Valid (case-insensitive) date keywords are:
825              
826             curdate()
827             current_date
828             current_date()
829             now()
830             sysdate()
831             00000-00-00
832              
833             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.
834              
835             =item B<validate_datetime_keyword STRING>
836              
837             Returns true if STRING is a valid keyword for the MariaDB "datetime" data type, false otherwise. Valid (case-insensitive) datetime keywords are:
838              
839             curdate()
840             current_date
841             current_date()
842             current_time
843             current_time()
844             current_timestamp
845             current_timestamp()
846             curtime()
847             now()
848             sysdate()
849             0000-00-00 00:00:00
850              
851             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.
852              
853             =item B<validate_timestamp_keyword STRING>
854              
855             Returns true if STRING is a valid keyword for the MariaDB "timestamp" data type, false otherwise. Valid (case-insensitive) timestamp keywords are:
856              
857             curdate()
858             current_date
859             current_date()
860             current_time
861             current_time()
862             current_timestamp
863             current_timestamp()
864             curtime()
865             now()
866             sysdate()
867             0000-00-00 00:00:00
868             00000000000000
869              
870             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.
871              
872             =back
873              
874             =head1 AUTHOR
875              
876             John C. Siracusa (siracusa@gmail.com)
877              
878             =head1 LICENSE
879              
880             Copyright (c) 2020 by John C. Siracusa. All rights reserved. This program is
881             free software; you can redistribute it and/or modify it under the same terms
882             as Perl itself.