File Coverage

blib/lib/DBIx/Custom.pm
Criterion Covered Total %
statement 749 856 87.5
branch 304 394 77.1
condition 105 155 67.7
subroutine 76 89 85.3
pod 35 41 85.3
total 1269 1535 82.6


line stmt bran cond sub pod time code
1 16     16   473840 use 5.008007;
  16         150  
2             package DBIx::Custom;
3 16     16   6865 use Object::Simple -base;
  16         16684  
  16         85  
4              
5             our $VERSION = '0.43';
6              
7 16     16   1495 use Carp 'confess';
  16         25  
  16         605  
8 16     16   18811 use DBI;
  16         232459  
  16         869  
9 16     16   7688 use DBIx::Custom::Result;
  16         36  
  16         113  
10 16     16   6645 use DBIx::Custom::Where;
  16         32  
  16         93  
11 16     16   6419 use DBIx::Custom::Model;
  16         36  
  16         104  
12 16     16   6256 use DBIx::Custom::Order;
  16         36  
  16         80  
13 16     16   466 use DBIx::Custom::Util qw/_array_to_hash _subname _deprecate/;
  16         27  
  16         660  
14 16     16   5961 use DBIx::Custom::Mapper;
  16         33  
  16         247  
15 16     16   438 use DBIx::Custom::NotExists;
  16         25  
  16         255  
16 16     16   5781 use DBIx::Custom::Query;
  16         35  
  16         105  
17 16     16   7560 use DBIx::Connector;
  16         49661  
  16         490  
18              
19 16     16   7134 use Encode qw/encode encode_utf8 decode_utf8/;
  16         129223  
  16         987  
20 16     16   105 use Scalar::Util qw/weaken/;
  16         28  
  16         144242  
21              
22             has [qw/dsn password quote user exclude_table user_table_info
23             user_column_info safety_character/];
24             has connector => 1;
25             has option => sub { {} };
26             has default_option => sub {
27             {
28             RaiseError => 1,
29             PrintError => 0,
30             AutoCommit => 1
31             }
32             };
33             has filters => sub {
34             {
35             encode_utf8 => sub { encode_utf8($_[0]) },
36             decode_utf8 => sub { decode_utf8($_[0]) }
37             }
38             };
39             has last_sql => '';
40             has models => sub { {} };
41             has now => sub {
42             sub {
43             my ($sec, $min, $hour, $mday, $mon, $year) = localtime;
44             $mon++;
45             $year += 1900;
46             my $now = sprintf("%04d-%02d-%02d %02d:%02d:%02d",
47             $year, $mon, $mday, $hour, $min, $sec);
48             return $now;
49             }
50             };
51             has result_class => 'DBIx::Custom::Result';
52             has separator => '.';
53              
54             has mytable_symbol => '__MY__';
55              
56             sub create_result {
57 0     0 0 0 my ($self, $sth) = @_;
58            
59 0         0 return $self->result_class->new(sth => $sth, dbi => $self);
60             }
61              
62             sub column {
63 70     70 1 214 my $self = shift;
64 70 100       162 my $option = pop if ref $_[-1] eq 'HASH';
65 70         96 my $real_table = shift;
66 70         106 my $columns = shift;
67 70   66     216 my $table = $option->{alias} || $real_table;
68            
69             # Columns
70 70 100 100     256 if (!defined $columns || $columns eq '*') {
71 30         57 $columns = $self->model($real_table)->columns;
72             }
73            
74             # Separator
75 70         1535 my $separator = $self->separator;
76            
77             # . is replaced
78 70         425 my $t = $table;
79 70         142 $t =~ s/\./$separator/g;
80            
81             # Column clause
82 70         88 my @column;
83 70   50     134 $columns ||= [];
84             push @column, $self->_tq($table) . "." . $self->q($_) .
85             " as " . $self->q("${t}${separator}$_")
86 70         178 for @$columns;
87            
88 70         619 return join (', ', @column);
89             }
90              
91             sub connect {
92 511     511 1 694442 my $self;
93            
94 511 100       1137 if (ref $_[0]) {
95 3         15 $self = shift;
96             }
97             else {
98 508         1231 $self = shift->new(@_);
99             }
100            
101 511         10808 my $connector = $self->connector;
102            
103 511 50 33     4954 if (!ref $connector && $connector) {
104 511         7472 my $dsn = $self->dsn;
105 511         9768 my $user = $self->user;
106 511         9210 my $password = $self->password;
107 511         9135 my $option = $self->option;
108             my $connector = DBIx::Connector->new($dsn, $user, $password,
109 511         867 {%{$self->default_option} , %$option});
  511         6823  
110 511         12098 $self->connector($connector);
111             }
112            
113             # Connect
114 511         3414 $self->dbh;
115            
116 505         1206 return $self;
117             }
118              
119             sub dbh {
120 4064     4064 1 10505 my $self = shift;
121            
122             # Set
123 4064 50       7298 if (@_) {
124 0         0 $self->{dbh} = $_[0];
125            
126 0         0 return $self;
127             }
128            
129             # Get
130             else {
131             # From Connction manager
132 4064 50       60307 if (my $connector = $self->connector) {
133 4064 50 33     38264 confess "connector must have dbh() method " . _subname
134             unless ref $connector && $connector->can('dbh');
135            
136 4064         9336 $self->{dbh} = $connector->dbh;
137             }
138            
139             # Connect
140 4058   33     354119 $self->{dbh} ||= $self->_connect;
141            
142             # Quote
143 4058 100       49274 if (!defined $self->quote) {
144 330         2223 my $driver = $self->_driver;
145 330 50       1237 my $quote = $driver eq 'odbc' ? '[]'
    50          
    50          
146             : $driver eq 'ado' ? '[]'
147             : $driver eq 'mysql' ? '`'
148             : '"';
149 330         4653 $self->quote($quote);
150             }
151            
152 4058         28707 return $self->{dbh};
153             }
154             }
155              
156             sub delete {
157 74     74 1 2815 my ($self, %opt) = @_;
158            
159             # Don't allow delete all rows
160             confess qq{delete method where or id option must be specified } . _subname
161 74 100 100     378 if !$opt{where} && !defined $opt{id} && !$opt{allow_delete_all};
      100        
162            
163             # Where
164 71         102 my $where;
165 71 100       132 if (defined $opt{id}) {
166 15         47 $where = $self->_id_to_param($opt{id}, $opt{primary_key}, $opt{table}) ;
167             }
168             else {
169 56         86 $where = $opt{where};
170             }
171 71         151 my $w = $self->_where_clause_and_param($where);
172            
173             # Delete statement
174 71         106 my $sql = "delete ";
175 71 100       169 $sql .= "$opt{prefix} " if defined $opt{prefix};
176 71         177 $sql .= "from " . $self->_tq($opt{table}) . " $w->{clause} ";
177            
178             # Execute query
179 71         305 $self->execute($sql, $w->{param}, %opt);
180             }
181              
182 27     27 1 13458 sub delete_all { shift->delete(@_, allow_delete_all => 1) }
183              
184             sub create_model {
185 221     221 1 994 my $self = shift;
186            
187 221         262 my $opt;
188 221 100 100     944 if (@_ % 2 != 0 && !ref $_[0]) {
189 3         13 $opt = {table => shift, @_};
190             }
191             else {
192 218 100       582 $opt = ref $_[0] eq 'HASH' ? $_[0] : {@_};
193             }
194            
195             # Options
196 221         358 $opt->{dbi} = $self;
197 221   100     558 my $model_class = delete $opt->{model_class} || 'DBIx::Custom::Model';
198 221         317 my $model_name = delete $opt->{name};
199 221         281 my $model_table = delete $opt->{table};
200 221   66     503 $model_name ||= $model_table;
201            
202             # Create model
203 221         886 my $model = $model_class->new($opt);
204 221         663 weaken $model->{dbi};
205 221 100       2918 $model->table($model_table) unless $model->table;
206 221         6906 $model->name($model_name);
207              
208 221 50 33     3778 if (!$model->columns || !@{$model->columns}) {
  221         3764  
209 221         3846 $model->columns($self->get_columns_from_db($model->table));
210             }
211            
212             # Set model
213 221         1809 $self->model($model_name, $model);
214            
215 221         3014 return $self->model($model->name);
216             }
217              
218             sub execute {
219 3197     3197 1 151928 my $self = shift;
220 3197         4235 my $sql = shift;
221            
222             # Options
223 3197         3448 my $param;
224 3197 100       6736 $param = shift if @_ % 2;
225 3197   100     7900 $param ||= {};
226 3197         6102 my %opt = @_;
227            
228             # Append
229 3197 100       5807 $sql .= $opt{append} if defined $opt{append};
230              
231             # Parse named place holder
232 3197         4395 my $safe_char = $self->{safety_character};
233 3197 50       10538 my $place_holder_re = $safe_char eq 'a-zA-Z0-9_'
234             ? qr/(.*?[^\\]):([$safe_char\.]+)(?:\{(.*?)\})?(.*)/so
235             : qr/(.*?[^\\]):([$safe_char\.]+)(?:\{(.*?)\})?(.*)/s;
236 3197         4375 my $source_sql = $sql;
237 3197         6121 $source_sql =~ s/([0-9]):/$1\\:/g;
238 3197         3698 my $parsed_sql = '';
239 3197         3611 my $columns;
240 3197         17244 while ($source_sql =~ /$place_holder_re/) {
241 2593         5835 push @$columns, $2;
242 2593 100       14786 ($parsed_sql, $source_sql) = defined $3 ?
243             ($parsed_sql . "$1$2 $3 ?", " $4") : ($parsed_sql . "$1?", " $4");
244             }
245 3197         5248 $parsed_sql .= $source_sql;
246 3197 100       6510 $parsed_sql =~ s/\\:/:/g if index($parsed_sql, "\\:") != -1;
247            
248             # Edit SQL after building
249 3197         4117 my $after_build_sql = $opt{after_build_sql};
250 3197 100       4589 $parsed_sql = $after_build_sql->($parsed_sql) if $after_build_sql;
251            
252             # Type rule
253 3197         3369 my $type_filters;
254 3197 100       5093 if ($self->{_type_rule_is_called}) {
255 149         198 $type_filters = {};
256 149 100       277 unless ($opt{type_rule_off}) {
257 134   100     246 my $tables = $opt{table} || [];
258 134 100       305 $tables = [$tables] unless ref $tables eq 'ARRAY';
259              
260             # Tables
261 134         158 my $main_table = @{$tables}[-1];
  134         234  
262            
263             my $type_rule_off_parts = {
264             1 => $opt{type_rule1_off},
265             2 => $opt{type_rule2_off}
266 134         306 };
267 134         218 for my $i (1, 2) {
268 268 100       445 unless ($type_rule_off_parts->{$i}) {
269 262         363 $type_filters->{$i} = {};
270 262   100     615 my $table_alias = $opt{table_alias} || {};
271 262         461 for my $alias (keys %$table_alias) {
272 12         16 my $table = $table_alias->{$alias};
273            
274 12 100       16 for my $column (keys %{$self->{"_into$i"}{key}{$table} || {}}) {
  12         56  
275 6         25 $type_filters->{$i}->{"$alias.$column"} = $self->{"_into$i"}{key}{$table}{$column};
276             }
277             }
278 262 100       383 $type_filters->{$i} = {%{$type_filters->{$i}}, %{$self->{"_into$i"}{key}{$main_table} || {}}}
  240 100       345  
  240         1158  
279             if $main_table;
280             }
281             }
282             }
283             }
284            
285             # Replace filter name to code
286 3197         3938 my $filter = $opt{filter};
287 3197 100       5062 if (defined $filter) {
288 42 50       118 if (ref $opt{filter} eq 'ARRAY') {
289 0         0 $filter = _array_to_hash($filter);
290             }
291            
292 42         133 for my $column (keys %$filter) {
293 42         67 my $name = $filter->{$column};
294 42 50       151 if (!defined $name) {
    100          
295 0         0 $filter->{$column} = undef;
296             }
297             elsif (ref $name ne 'CODE') {
298             confess qq{Filter "$name" is not registered" } . _subname
299 21 100       335 unless exists $self->filters->{$name};
300 18         334 $filter->{$column} = $self->filters->{$name};
301             }
302             }
303             }
304            
305             # Bind type
306 3194         3654 my $bind_type = $opt{bind_type};
307 3194 100       5179 $bind_type = _array_to_hash($bind_type) if ref $bind_type eq 'ARRAY';
308            
309             # Create query
310 3194         8248 my $query = DBIx::Custom::Query->new;
311 3194         65616 $query->param($param);
312 3194         56490 $query->sql($parsed_sql);
313 3194         55076 $query->columns($columns);
314 3194         53020 $query->bind_type($bind_type);
315            
316 3194         16639 $query->{_filter} = $filter;
317 3194         4081 $query->{_type_filters} = $type_filters;
318 3194         4437 $query->{_into1} = $self->{_into1};
319 3194         6300 $query->{_into2} = $self->{_into2};
320            
321             # Has filter
322 3194   100     10005 $query->{_f} = defined $filter || defined $type_filters;
323            
324             # Build bind values
325 3194         7692 $query->build;
326            
327             # Statement handle
328 3194         4421 my $sth;
329             my $reuse_sth;
330 3194 100       5215 $reuse_sth = $opt{reuse}->{$parsed_sql} if $opt{reuse};
331 3194 100       4591 if ($reuse_sth) {
332 18         26 $sth = $reuse_sth;
333             }
334             else {
335             # Prepare statement handle
336 3176         3894 eval { $sth = $self->dbh->prepare($parsed_sql) };
  3176         5787  
337 3176 100       198178 if ($@) {
338 582         2445 $self->_confess($@, qq{. Following SQL is executed.\n}
339             . qq{$parsed_sql\n} . _subname);
340             }
341 2594 100       5808 $opt{reuse}->{$parsed_sql} = $sth if $opt{reuse};
342             }
343            
344             # Execute
345 2612         3049 my $affected;
346 2612         3129 eval {
347 2612         50098 my $bind_values = $query->bind_values;
348 2612 100       14284 if ($bind_type) {
349 4         54 my $bind_value_types = $query->bind_value_types;
350             $sth->bind_param($_ + 1, $bind_values->[$_],
351             $bind_value_types->[$_] ? $bind_value_types->[$_] : ())
352 4 100       59 for (0 .. @$bind_values - 1);
353 4         68 $affected = $sth->execute;
354             }
355 2608         68121 else { $affected = $sth->execute(@$bind_values) }
356            
357             # Save sql
358 2609         7516 $self->{last_sql} = $parsed_sql;
359            
360             # DEBUG message
361 2609 100       6516 if ($ENV{DBIX_CUSTOM_DEBUG}) {
362 2         21 warn "SQL:\n" . $parsed_sql . "\n";
363 2         13 my @output;
364 2         6 for my $value (@$bind_values) {
365 0 0       0 $value = 'undef' unless defined $value;
366 0 0 0     0 $value = encode($ENV{DBIX_CUSTOM_DEBUG_ENCODING} || 'UTF-8', $value)
367             if utf8::is_utf8($value);
368 0         0 push @output, $value;
369             }
370 2         13 warn "Bind values: " . join(', ', @output) . "\n\n";
371             }
372             };
373            
374 2612 100       4285 $self->_confess($@, qq{. Following SQL is executed.\n}
375             . qq{$parsed_sql\n} . _subname) if $@;
376            
377             # Reulst of select statement
378 2609 100       16611 if ($sth->{NUM_OF_FIELDS}) {
379             # Result
380 921         15308 my $result = $self->result_class->new(
381             sth => $sth,
382             dbi => $self,
383             );
384            
385 921 100       12208 if ($self->{_type_rule_is_called}) {
386             $result->type_rule({
387             from1 => $self->type_rule->{from1},
388             from2 => $self->type_rule->{from2}
389 94         207 });
390 94         142 $result->{_has_filter} = 1;
391             }
392            
393 921         7726 return $result;
394             }
395             # Affected of insert, update, or delete
396             else {
397 1688         14885 return $affected
398             }
399             }
400              
401             sub include_model {
402 60     60 1 1479 my ($self, $name_space, $model_infos) = @_;
403            
404             # Name space
405 60   50     164 $name_space ||= '';
406            
407             # Get Model information
408 60 100       144 unless ($model_infos) {
409              
410             # Load name space module
411 30 50       128 confess qq{"$name_space" is invalid class name } . _subname
412             if $name_space =~ /[^\w:]/;
413 30     3   1964 eval "use $name_space";
  3     3   1108  
  3     3   450  
  3     3   26  
  3     3   1272  
  3     3   464  
  3     3   27  
  3     3   1246  
  3     3   465  
  3     3   28  
  3         19  
  3         5  
  3         12  
  3         22  
  3         6  
  3         18  
  3         21  
  3         6  
  3         14  
  3         24  
  3         6  
  3         18  
  3         1286  
  3         457  
  3         26  
  3         19  
  3         3  
  3         11  
  3         1037  
  3         421  
  3         26  
414 30 50       433 confess qq{Name space module "$name_space.pm" is needed. $@ } . _subname
415             if $@;
416            
417             # Search model modules
418 30         58 my $name_space_dir = $name_space;
419 30         70 $name_space_dir =~ s/::/\//g;
420 30         92 my $path = $INC{"$name_space_dir.pm"};
421 30         126 $path =~ s/\.pm$//;
422 30 50       1407 opendir my $dh, $path
423             or confess qq{Can't open directory "$path": $! } . _subname
424             my @modules;
425 30         872 while (my $file = readdir $dh) {
426 132         302 my $file_abs = "$path/$file";
427 132 100       1984 if (-d $file_abs) {
    50          
428 80 100 100     570 next if $file eq '.' || $file eq '..';
429 20 50       469 opendir my $fq_dh, $file_abs
430             or confess qq{Can't open directory "$file_abs": $! } . _subname;
431 20         298 while (my $fq_file = readdir $fq_dh) {
432 92         197 my $fq_file_abs = "$file_abs/$fq_file";
433 92 100       1419 push @modules, "${file}::$fq_file" if -f $fq_file_abs;
434             }
435 20         311 close $fq_dh;
436             }
437 52         346 elsif(-f $file_abs) { push @modules, $file }
438             }
439 30         95 close $dh;
440            
441 30         61 $model_infos = [];
442 30         73 for my $module (@modules) {
443 600 100       1180 if ($module =~ s/\.pm$//) { push @$model_infos, $module }
  104         627  
444             }
445             }
446            
447             # Include models
448 60         149 for my $model_info (@$model_infos) {
449            
450             # Load model
451 164         335 my $model_class;
452             my $model_name;
453 164         0 my $model_table;
454 164 100       353 if (ref $model_info eq 'HASH') {
455 9         15 $model_class = $model_info->{class};
456 9         14 $model_name = $model_info->{name};
457 9         14 $model_table = $model_info->{table};
458            
459 9   33     18 $model_name ||= $model_class;
460 9   33     30 $model_table ||= $model_name;
461             }
462             else {
463 155         218 $model_class = $model_name = $model_table = $model_info;
464             }
465              
466 164         295 $model_class =~ s/\./::/g;
467 164         302 $model_name =~ s/::/./;
468 164         239 $model_table =~ s/::/./;
469              
470 164         313 my $mclass = "${name_space}::$model_class";
471 164 50       447 confess qq{"$mclass" is invalid class name } . _subname
472             if $mclass =~ /[^\w:]/;
473 164 100       971 unless ($mclass->can('new')) {
474 54         2479 eval "require $mclass";
475 54 50       18138 confess "$@ " . _subname if $@;
476             }
477            
478             # Create model
479 164         319 my $opt = {};
480 164 50       430 $opt->{model_class} = $mclass if $mclass;
481 164 50       342 $opt->{name} = $model_name if $model_name;
482 164 50       296 $opt->{table} = $model_table if $model_table;
483            
484 164         401 $self->create_model($opt);
485 164         1139 1;
486             }
487            
488 60         151 return $self;
489             }
490              
491 3     3 1 14 sub like_value { sub { "%$_[0]%" } }
  3     3   29  
492              
493             sub mapper {
494 81     81 1 13048 my $self = shift;
495 81         235 return DBIx::Custom::Mapper->new(@_);
496             }
497              
498             sub merge_param {
499 818     818 1 1412 my ($self, $param1, $param2) = @_;
500            
501             # Merge parameters
502 818         1357 my $merged_param = {%$param1};
503 818         1495 for my $column (keys %$param2) {
504 384 100       639 if (exists $merged_param->{$column}) {
505             $merged_param->{$column} = [$merged_param->{$column}]
506 51 100       144 unless ref $merged_param->{$column} eq 'ARRAY';
507 51         142 push @{$merged_param->{$column}},
508 51 100       63 ref $param2->{$column} eq 'ARRAY' ? @{$param2->{$column}} : $param2->{$column};
  6         15  
509             }
510 333         565 else { $merged_param->{$column} = $param2->{$column} }
511             }
512            
513 818         1554 return $merged_param;
514             }
515              
516             sub model {
517 595     595 1 10131 my ($self, $name, $model) = @_;
518            
519             # Set model
520 595 100       1003 if ($model) {
521 221         3186 $self->models->{$name} = $model;
522 221         896 return $self;
523             }
524            
525             # Check model existence
526             confess qq{Model "$name" is not yet created } . _subname
527 374 50       5214 unless $self->models->{$name};
528            
529             # Get model
530 374         6385 return $self->models->{$name};
531             }
532              
533             sub mycolumn {
534 33     33 1 168 my ($self, $table, $columns) = @_;
535            
536 33 100 66     129 if (!$columns || $columns eq '*') {
537 9         20 $columns = $self->model($table)->columns;
538             }
539              
540             # Create column clause
541 33         217 my @column;
542             push @column, $self->_tq($table) . "." . $self->q($_) . " as " . $self->q($_)
543 33         92 for @$columns;
544            
545 33         418 return join (', ', @column);
546             }
547              
548             sub new {
549 522     522 1 78434 my $self = shift;
550            
551             # Same as DBI connect argument
552 522 100 66     2471 if (@_ > 0 && !ref $_[0] && $_[0] =~ /:/) {
      100        
553 3         21 my $dsn = shift;
554 3         7 my $user = shift;
555 3         4 my $password = shift;
556 3   50     12 my $dbi_option = shift || {};
557 3   50     9 my $attrs = shift || {};
558 3         8 $attrs->{dsn} = $dsn;
559 3         7 $attrs->{user} = $user;
560 3         6 $attrs->{password} = $password;
561 3         6 $attrs->{option} = $dbi_option;
562 3         10 $self = $self->SUPER::new($attrs);
563             }
564             else {
565 519         1359 $self = $self->SUPER::new(@_);
566             }
567            
568             # Check attributes
569 522         3446 my @attrs = keys %$self;
570 522         950 for my $attr (@attrs) {
571 32 50       103 confess qq{Invalid attribute: "$attr" } . _subname
572             unless $self->can($attr);
573             }
574            
575             $self->{safety_character} = 'a-zA-Z0-9_'
576 522 50       1347 unless exists $self->{safety_character};
577            
578 522         877 return $self;
579             }
580              
581 60     60 1 2511 sub not_exists { DBIx::Custom::NotExists->singleton }
582              
583             sub order {
584 3     3 1 32 my $self = shift;
585 3         32 return DBIx::Custom::Order->new(dbi => $self, @_);
586             }
587              
588 640     640 1 1334 sub q { shift->_tq($_[0], $_[1], whole => 1) }
589              
590             sub _tq {
591 2714     2714   5271 my ($self, $value, $quotemeta, %opt) = @_;
592            
593 2714   50     6214 my $quote = $self->{quote} || $self->quote || '';
594            
595 2714   50     7607 my $q = substr($quote, 0, 1) || '';
596 2714         2850 my $p;
597 2714 100 66     6893 if (defined $quote && length $quote > 1) {
598 927         1225 $p = substr($quote, 1, 1);
599             }
600 1787         2213 else { $p = $q }
601            
602 2714 50       3938 if ($quotemeta) {
603 0         0 $q = quotemeta($q);
604 0         0 $p = quotemeta($p);
605             }
606            
607 2714 100       3805 if ($opt{whole}) { return "$q$value$p" }
  640         1911  
608             else {
609 2074         4808 my @values = split /\./, $value;
610 2074 50       4020 push @values, '' unless @values;
611 2074         3089 for my $v (@values) { $v = "$q$v$p" }
  2717         4488  
612 2074         6668 return join '.', @values;
613             }
614             }
615              
616             sub register_filter {
617 36     36 1 5327 my $self = shift;
618            
619             # Register filter
620 36 50       144 my $filters = ref $_[0] eq 'HASH' ? $_[0] : {@_};
621 36         59 $self->filters({%{$self->filters}, %$filters});
  36         709  
622            
623 36         285 return $self;
624             }
625              
626             sub select {
627 742     742 1 87605 my $self = shift;
628 742 100       1729 my $column = shift if @_ % 2;
629 742         1917 my %opt = @_;
630 742 100       1376 $opt{column} = $column if defined $column;
631              
632             # Table
633 742         1020 my $table = $opt{table};
634            
635             # Found tables;
636 742         994 my $found_tables = [];
637 742 100       1782 push @$found_tables, $table if defined $table;
638            
639 742   100     2387 my $param = delete $opt{param} || {};
640            
641             # Select statement
642 742         1311 my $sql = 'select ';
643            
644             # Prefix
645 742 100       1310 $sql .= "$opt{prefix} " if defined $opt{prefix};
646            
647             # Column
648 742 100       1319 if (defined $opt{column}) {
649             my $columns
650 176 100       461 = ref $opt{column} eq 'ARRAY' ? $opt{column} : [$opt{column}];
651 176         311 for my $column (@$columns) {
652 233 100       473 if (ref $column eq 'HASH') {
653 52   66     877 my $mytable_symbol = $opt{mytable_symbol} || $self->mytable_symbol;
654 52         460 my $table = (keys %$column)[0];
655 52         82 my $columns = $column->{$table};
656            
657 52 100       108 if ($table eq $mytable_symbol) {
658 9         18 $column = $self->mycolumn($found_tables->[0] => $columns);
659             }
660             else {
661 43         103 $column = $self->column($table => $columns);
662             }
663             }
664 233 100       432 unshift @$found_tables, @{$self->_search_tables($column)} if $table;
  226         406  
665 233         522 $sql .= "$column, ";
666             }
667 176         699 $sql =~ s/, $/ /;
668             }
669 566         850 else { $sql .= '* ' }
670              
671             # Execute query without table
672 742 100       1266 return $self->execute($sql, {}, %opt) unless $table;
673              
674             # Table
675 735         863 $sql .= 'from ';
676 735   50     1704 $sql .= $self->_tq($found_tables->[-1] || '') . ' ';
677 735         1358 $sql =~ s/, $/ /;
678              
679             # Add tables in parameter
680 735   100     916 unshift @$found_tables, @{$self->_search_tables(join(' ', keys %$param) || '')};
  735         2801  
681            
682             # Where
683 735         934 my $where;
684 735 100       1281 if (defined $opt{id}) {
685 49 50       176 $where = $self->_id_to_param($opt{id}, $opt{primary_key}, @$found_tables ? $found_tables->[-1] : undef) ;
686             }
687             else {
688 686         969 $where = $opt{where};
689             }
690 735         1943 my $w = $self->_where_clause_and_param($where, $opt{id});
691 729         1790 $param = $self->merge_param($param, $w->{param});
692            
693             # Search table names in where clause
694 729         990 unshift @$found_tables, @{$self->_search_tables($w->{clause})};
  729         1193  
695            
696             # Search table names in append option
697 729 100       1619 if (defined(my $append = $opt{append})) {
698 20         32 unshift @$found_tables, @{$self->_search_tables($append)};
  20         36  
699             }
700            
701             # Join statement
702 729         1041 my $join = [];
703 729 100       1280 if (defined $opt{join}) {
704 133         207 my $opt_join = $opt{join};
705 133 100       286 if (ref $opt_join eq 'ARRAY') {
706 127         263 push @$join, @$opt_join;
707             }
708 6         12 else { push @$join, $opt_join }
709             }
710 729 100       1298 if (defined $w->{join}) {
711 18         22 my $where_join = $w->{join};
712 18 50       36 if (ref $where_join eq 'ARRAY') {
713 18         28 push @$join, @$where_join;
714             }
715 0         0 else { push @$join, $where_join }
716             }
717 729 100       1398 $self->_push_join(\$sql, $join, $found_tables) if @$join;
718            
719             # Add where clause
720 729         1181 $sql .= "$w->{clause} ";
721            
722             # Execute query
723 729         2095 return $self->execute($sql, $param, %opt);
724             }
725              
726             sub setup_model {
727 24     24 0 209 my ($self, %opt) = @_;
728            
729 24         80 _deprecate('0.39', "DBIx::Custom::setup method is DEPRECATED! columns is automatically set when create_model or include_model is called");
730            
731 24         46 return $self;
732             }
733              
734             sub insert {
735 824     824 1 15129 my $self = shift;
736            
737             # Options
738 824 50       1850 my $params = @_ % 2 ? shift : undef;
739 824         2048 my %opt = @_;
740 824   50     1616 $params ||= {};
741              
742             # Insert statement
743 824         1106 my $sql = "insert ";
744 824 100       1539 $sql .= "$opt{prefix} " if defined $opt{prefix};
745 824         1737 $sql .= "into " . $self->_tq($opt{table}) . " ";
746              
747 824         1059 my $multi;
748 824 100       1535 if (ref $params eq 'ARRAY') { $multi = 1 }
  9         13  
749 815         1306 else { $params = [$params] }
750            
751             # Created time and updated time
752 824 100 100     2661 if (defined $opt{ctime} || defined $opt{mtime}) {
753            
754 33         49 for my $param (@$params) {
755 36         162 $param = {%$param};
756             }
757 33         585 my $now = $self->now;
758 33 100       142 $now = $now->() if ref $now eq 'CODE';
759 33 100       87 if (defined $opt{ctime}) {
760 23         80 $_->{$opt{ctime}} = $now for @$params;
761             }
762 33 100       65 if (defined $opt{mtime}) {
763 27         70 $_->{$opt{mtime}} = $now for @$params;
764             }
765             }
766            
767             # Merge id to parameter
768 824 100 66     1681 if (defined $opt{id} && !$multi) {
769            
770 38         121 _deprecate('0.39', "DBIx::Custom::insert method's id option is DEPRECATED!");
771            
772 38         432 for my $param (@$params) {
773 38         135 $param = {%$param};
774             }
775            
776             confess "insert id option must be specified with primary_key option"
777 38 50       90 unless $opt{primary_key};
778 38 100       101 $opt{primary_key} = [$opt{primary_key}] unless ref $opt{primary_key} eq 'ARRAY';
779 38 100       94 $opt{id} = [$opt{id}] unless ref $opt{id} eq 'ARRAY';
780 38         60 for (my $i = 0; $i < @{$opt{primary_key}}; $i++) {
  97         241  
781 59         83 my $key = $opt{primary_key}->[$i];
782 59 100       407 next if exists $params->[0]->{$key};
783 56         123 $params->[0]->{$key} = $opt{id}->[$i];
784             }
785             }
786            
787 824 50       1246 if ($opt{bulk_insert}) {
788 0         0 $sql .= $self->_multi_values_clause($params, {wrap => $opt{wrap}}) . " ";
789 0         0 my $new_param = {};
790 0         0 $new_param->{$_} = [] for keys %{$params->[0]};
  0         0  
791 0         0 for my $param (@$params) {
792 0         0 push @{$new_param->{$_}}, $param->{$_} for keys %$param;
  0         0  
793             }
794 0         0 $params = [$new_param];
795             }
796             else {
797 824         2423 $sql .= $self->values_clause($params->[0], {wrap => $opt{wrap}}) . " ";
798             }
799            
800             # Execute query
801 821 100       1921 if (@$params > 1) {
802 9         16 for my $param (@$params) {
803 18         53 $self->execute($sql, $param, %opt);
804             }
805             }
806             else {
807 812         2285 $self->execute($sql, $params->[0], %opt);
808             }
809             }
810              
811             sub update {
812 89     89 1 10462 my $self = shift;
813              
814             # Options
815 89 100       233 my $param = @_ % 2 ? shift : undef;
816 89         278 my %opt = @_;
817 89   100     193 $param ||= {};
818            
819             # Don't allow update all rows
820             confess qq{update method where option must be specified } . _subname
821 89 100 100     251 if !$opt{where} && !defined $opt{id} && !$opt{allow_update_all};
      100        
822            
823             # Created time and updated time
824 86 100       191 if (defined $opt{mtime}) {
825 9         25 $param = {%$param};
826 9         160 my $now = $self->now;
827 9 50       35 $now = $now->() if ref $now eq 'CODE';
828 9         172 $param->{$opt{mtime}} = $self->now->();
829             }
830              
831             # Assign clause
832 86         251 my $assign_clause = $self->assign_clause($param, {wrap => $opt{wrap}});
833            
834             # Where
835 83         944 my $where;
836 83 100       158 if (defined $opt{id}) {
837 15         45 $where = $self->_id_to_param($opt{id}, $opt{primary_key}, $opt{table}) ;
838             }
839             else {
840 68         152 $where = $opt{where};
841             }
842            
843 83         198 my $w = $self->_where_clause_and_param($where);
844            
845             # Merge update parameter with where parameter
846 83         207 $param = $self->merge_param($param, $w->{param});
847            
848             # Update statement
849 83         120 my $sql = "update ";
850 83 50       1024 $sql .= "$opt{prefix} " if defined $opt{prefix};
851 83         161 $sql .= $self->_tq($opt{table}) . " set $assign_clause $w->{clause} ";
852            
853             # Execute query
854 83         249 $self->execute($sql, $param, %opt);
855             }
856              
857 3     3 1 28 sub update_all { shift->update(@_, allow_update_all => 1) };
858              
859             sub values_clause {
860 827     827 1 1365 my ($self, $param, $opts) = @_;
861            
862 827   100     2168 my $wrap = $opts->{wrap} || {};
863            
864             # Create insert parameter tag
865 827         1566 my ($q, $p) = $self->_qp;
866            
867 827         15624 my $safety_character = $self->safety_character;
868            
869 827         4452 my @columns;
870             my @place_holders;
871 827         3378 for my $column (sort keys %$param) {
872 1949 100       6989 confess qq{"$column" is not safety column name in values clause} . _subname
873             unless $column =~ /^[$safety_character\.]+$/;
874              
875 1946         3550 push @columns, "$q$column$p";
876 35         79 push @place_holders, ref $param->{$column} eq 'SCALAR' ? ${$param->{$column}} :
877 1946 100       5254 $wrap->{$column} ? $wrap->{$column}->(":$column") :
    100          
878             ":$column";
879             }
880            
881 824         2355 my $values_clause = '(' . join(', ', @columns) . ') values (' . join(', ', @place_holders) . ')';
882            
883 824         2382 return $values_clause;
884             }
885              
886             sub assign_clause {
887 95     95 1 310 my ($self, $param, $opts) = @_;
888            
889 95   100     306 my $wrap = $opts->{wrap} || {};
890 95         198 my ($q, $p) = $self->_qp;
891              
892 95         1752 my $safety_character = $self->safety_character;
893              
894 95         498 my @set_values;
895 95         333 for my $column (sort keys %$param) {
896 113 100       626 confess qq{"$column" is not safety column name in assign clause} . _subname
897             unless $column =~ /^[$safety_character\.]+$/;
898            
899 3         11 push @set_values, ref $param->{$column} eq 'SCALAR' ? "$q$column$p = " . ${$param->{$column}}
900 110 100       556 : $wrap->{$column} ? "$q$column$p = " . $wrap->{$column}->(":$column")
    100          
901             : "$q$column$p = :$column";
902             }
903            
904 92         235 my $assign_clause = join(', ', @set_values);
905            
906 92         221 return $assign_clause;
907             }
908              
909 186     186 1 80820 sub where { DBIx::Custom::Where->new(dbi => shift, @_) }
910              
911             sub type_rule {
912 262     262 1 4593 my $self = shift;
913              
914 262         363 $self->{_type_rule_is_called} = 1;
915            
916 262 100       433 if (@_) {
917 74 50       261 my $type_rule = ref $_[0] eq 'HASH' ? $_[0] : {@_};
918            
919             # Into
920 74         159 for my $i (1 .. 2) {
921 142         490 my $into = "into$i";
922 142         209 my $exists_into = exists $type_rule->{$into};
923 142         413 $type_rule->{$into} = _array_to_hash($type_rule->{$into});
924 142         254 $self->{type_rule} = $type_rule;
925 142         299 $self->{"_$into"} = {};
926 142 100       175 for my $type_name (keys %{$type_rule->{$into} || {}}) {
  142         540  
927 78 100       444 confess qq{type name of $into section must be lower case}
928             if $type_name =~ /[A-Z]/;
929             }
930            
931             $self->each_column(sub {
932 1909     1909   2652 my ($dbi, $table, $column, $column_info) = @_;
933            
934 1909         2269 my $type_name = lc $column_info->{TYPE_NAME};
935 1909 100 100     6014 if ($type_rule->{$into} &&
936             (my $filter = $type_rule->{$into}->{$type_name}))
937             {
938 75 50       141 return unless exists $type_rule->{$into}->{$type_name};
939 75 100 66     253 if (defined $filter && ref $filter ne 'CODE')
940             {
941 9         14 my $fname = $filter;
942             confess qq{Filter "$fname" is not registered" } . _subname
943 9 100       150 unless exists $self->filters->{$fname};
944            
945 6         111 $filter = $self->filters->{$fname};
946             }
947            
948 72         134 my $schema = $column_info->{TABLE_SCHEM};
949 72         227 $self->{"_$into"}{key}{$table}{$column} = $filter;
950 72         196 $self->{"_$into"}{dot}{"$table.$column"} = $filter;
951            
952 72         189 $self->{"_$into"}{key}{"$schema.$table"}{$column} = $filter;
953 72         253 $self->{"_$into"}{dot}{"$schema.$table.$column"} = $filter;
954             }
955 139         657 });
956             }
957              
958             # From
959 68         337 for my $i (1 .. 2) {
960 133         386 $type_rule->{"from$i"} = _array_to_hash($type_rule->{"from$i"});
961 133 100       172 for my $data_type (keys %{$type_rule->{"from$i"} || {}}) {
  133         485  
962 65 100       407 confess qq{data type of from$i section must be lower case or number}
963             if $data_type =~ /[A-Z]/;
964 62         107 my $fname = $type_rule->{"from$i"}{$data_type};
965 62 100 66     232 if (defined $fname && ref $fname ne 'CODE') {
966             confess qq{Filter "$fname" is not registered" } . _subname
967 3 50       48 unless exists $self->filters->{$fname};
968            
969 3         59 $type_rule->{"from$i"}{$data_type} = $self->filters->{$fname};
970             }
971             }
972             }
973            
974 65         137 return $self;
975             }
976            
977 188   50     605 return $self->{type_rule} || {};
978             }
979              
980             sub get_table_info {
981 3     3 1 110 my ($self, %opt) = @_;
982            
983 3         7 my $exclude = delete $opt{exclude};
984 3         12 confess qq/"$_" is wrong option/ for keys %opt;
985            
986 3         7 my $table_info = [];
987             $self->each_table(
988 15     15   174 sub { push @$table_info, {table => $_[1], info => $_[2] } },
989 3         19 exclude => $exclude
990             );
991            
992 3         41 return [sort {$a->{table} cmp $b->{table} } @$table_info];
  24         50  
993             }
994              
995             sub get_column_info {
996 3     3 1 2892 my ($self, %opt) = @_;
997            
998 3         9 my $exclude_table = delete $opt{exclude_table};
999 3         12 confess qq/"$_" is wrong option/ for keys %opt;
1000            
1001 3         7 my $column_info = [];
1002             $self->each_column(
1003 42     42   255 sub { push @$column_info, {table => $_[1], column => $_[2], info => $_[3] } },
1004 3         19 exclude_table => $exclude_table
1005             );
1006            
1007             return [
1008 3 50       124 sort {$a->{table} cmp $b->{table} || $a->{column} cmp $b->{column} }
  105         179  
1009             @$column_info];
1010             }
1011              
1012             sub each_column {
1013 145     145 1 315 my ($self, $cb, %options) = @_;
1014            
1015 145         2357 my $user_column_info = $self->user_column_info;
1016            
1017 145 100       817 if ($user_column_info) {
1018 129         350 $self->$cb($_->{table}, $_->{column}, $_->{info}) for @$user_column_info;
1019             }
1020             else {
1021 16   33     229 my $re = $self->exclude_table || $options{exclude_table};
1022             # Tables
1023 16         122 my $tables = {};
1024             $self->each_table(sub {
1025 53     53   83 my ($dbi, $table, $table_info) = @_;
1026 53         75 my $schema = $table_info->{TABLE_SCHEM};
1027 53         576 $tables->{$schema}{$table}++;
1028 16         78 });
1029              
1030             # Iterate all tables
1031 16         191 for my $schema (sort keys %$tables) {
1032 32         653 for my $table (sort keys %{$tables->{$schema}}) {
  32         109  
1033            
1034             # Iterate all columns
1035 53         843 my $sth_columns;
1036 53         71 eval {$sth_columns = $self->dbh->column_info(undef, $schema, $table, '%')};
  53         114  
1037 53 50       35450 next if $@;
1038 53         393 while (my $column_info = $sth_columns->fetchrow_hashref) {
1039 196         3336 my $column = $column_info->{COLUMN_NAME};
1040 196         305 $self->$cb($table, $column, $column_info);
1041             }
1042             }
1043             }
1044             }
1045             }
1046              
1047             sub get_columns_from_db {
1048 224     224 0 1309 my ($self, $schema_table) = @_;
1049            
1050 224         305 my $schema;
1051             my $table;
1052 224 100       565 if ($schema_table =~ /^(.+)\.(.*)$/) {
1053 90         150 $schema = $1;
1054 90         125 $table = $2;
1055             }
1056             else {
1057 134         181 $schema = undef;
1058 134         175 $table = $schema_table;
1059             }
1060            
1061 224         265 my $sth_columns;
1062 224         284 eval {$sth_columns = $self->dbh->column_info(undef, $schema, $table, "%") };
  224         452  
1063 224 50       145274 if ($@) {
1064 0         0 return;
1065             }
1066            
1067 224         329 my $columns;
1068 224         1632 while (my $column_info = $sth_columns->fetchrow_hashref) {
1069 351   100     7272 $columns ||= [];
1070 351         492 my $column = $column_info->{COLUMN_NAME};
1071 351         2304 push @$columns, $column;
1072             }
1073            
1074 224         12419 return $columns;
1075             }
1076              
1077             sub each_table {
1078 25     25 1 239 my ($self, $cb, %option) = @_;
1079            
1080 25         397 my $user_table_infos = $self->user_table_info;
1081            
1082             # Iterate tables
1083 25 100       207 if ($user_table_infos) {
1084 6         24 $self->$cb($_->{table}, $_->{info}) for @$user_table_infos;
1085             }
1086             else {
1087 19   33     267 my $re = $self->exclude_table || $option{exclude};
1088 19         157 my $sth_tables = $self->dbh->table_info;
1089 19         4647 while (my $table_info = $sth_tables->fetchrow_hashref) {
1090             # Table
1091 65         276 my $table = $table_info->{TABLE_NAME};
1092 65 50 33     136 next if defined $re && $table =~ /$re/;
1093 65         115 $self->$cb($table, $table_info);
1094             }
1095             }
1096             }
1097              
1098             sub available_datatype {
1099 0     0 1 0 my $self = shift;
1100            
1101 0         0 my $data_types = '';
1102 0         0 for my $i (-1000 .. 1000) {
1103 0         0 my $type_info = $self->dbh->type_info($i);
1104 0         0 my $data_type = $type_info->{DATA_TYPE};
1105 0         0 my $type_name = $type_info->{TYPE_NAME};
1106 0 0       0 $data_types .= "$data_type ($type_name)\n"
1107             if defined $data_type;
1108             }
1109 0 0       0 return "Data Type maybe equal to Type Name" unless $data_types;
1110 0         0 $data_types = "Data Type (Type name)\n" . $data_types;
1111 0         0 return $data_types;
1112             }
1113              
1114             sub available_typename {
1115 0     0 1 0 my $self = shift;
1116            
1117             # Type Names
1118 0         0 my $type_names = {};
1119             $self->each_column(sub {
1120 0     0   0 my ($self, $table, $column, $column_info) = @_;
1121             $type_names->{$column_info->{TYPE_NAME}} = 1
1122 0 0       0 if $column_info->{TYPE_NAME};
1123 0         0 });
1124 0         0 my @output = sort keys %$type_names;
1125 0         0 unshift @output, "Type Name";
1126 0         0 return join "\n", @output;
1127             }
1128              
1129             sub show_datatype {
1130 0     0 1 0 my ($self, $table) = @_;
1131 0 0       0 confess "Table name must be specified" unless defined $table;
1132 0         0 print "$table\n";
1133            
1134 0         0 my $result = $self->select(table => $table, where => "'0' <> '0'");
1135 0         0 my $sth = $result->sth;
1136              
1137 0         0 my $columns = $sth->{NAME};
1138 0         0 my $data_types = $sth->{TYPE};
1139            
1140 0         0 for (my $i = 0; $i < @$columns; $i++) {
1141 0         0 my $column = $columns->[$i];
1142 0         0 my $data_type = lc $data_types->[$i];
1143 0         0 print "$column: $data_type\n";
1144             }
1145             }
1146              
1147             sub show_typename {
1148 0     0 1 0 my ($self, $t) = @_;
1149 0 0       0 confess "Table name must be specified" unless defined $t;
1150 0         0 print "$t\n";
1151            
1152             $self->each_column(sub {
1153 0     0   0 my ($self, $table, $column, $infos) = @_;
1154 0 0       0 return unless $table eq $t;
1155 0         0 my $typename = lc $infos->{TYPE_NAME};
1156 0         0 print "$column: $typename\n";
1157 0         0 });
1158            
1159 0         0 return $self;
1160             }
1161              
1162             sub show_tables {
1163 0     0 1 0 my $self = shift;
1164            
1165 0         0 my %tables;
1166 0     0   0 $self->each_table(sub { $tables{$_[1]}++ });
  0         0  
1167 0         0 print join("\n", sort keys %tables) . "\n";
1168 0         0 return $self;
1169             }
1170              
1171             sub _qp {
1172 2635     2635   5382 my ($self, %opt) = @_;
1173              
1174 2635   50     5657 my $quote = $self->{quote} || $self->quote || '';
1175            
1176 2635   50     6822 my $q = substr($quote, 0, 1) || '';
1177 2635         2781 my $p;
1178 2635 100 66     6599 if (defined $quote && length $quote > 1) {
1179 904         1152 $p = substr($quote, 1, 1);
1180             }
1181 1731         2137 else { $p = $q }
1182            
1183 2635 100       4285 if ($opt{quotemeta}) {
1184 1710         2198 $q = quotemeta($q);
1185 1710         1881 $p = quotemeta($p);
1186             }
1187            
1188 2635         6465 return ($q, $p);
1189             }
1190              
1191             sub _multi_values_clause {
1192 0     0   0 my ($self, $params, $opts) = @_;
1193            
1194 0   0     0 my $wrap = $opts->{wrap} || {};
1195            
1196             # Create insert parameter tag
1197 0         0 my ($q, $p) = $self->_qp;
1198            
1199 0         0 my $safety_character = $self->safety_character;
1200            
1201 0         0 my $first_param = $params->[0];
1202            
1203 0         0 my @columns;
1204             my @columns_quoted;
1205 0         0 for my $column (keys %$first_param) {
1206 0 0       0 confess qq{"$column" is not safety column name in multi values clause} . _subname
1207             unless $column =~ /^[$safety_character\.]+$/;
1208            
1209 0         0 push @columns, $column;
1210 0         0 push @columns_quoted, "$q$column$p";
1211             }
1212              
1213             # Multi values clause
1214 0         0 my $multi_values_clause = '(' . join(', ', @columns_quoted) . ') values ';
1215              
1216 0         0 for my $param (@$params) {
1217 0         0 my @place_holders;
1218 0         0 for my $column (@columns) {
1219 0         0 push @place_holders, ref $param->{$column} eq 'SCALAR' ? ${$param->{$column}} :
1220 0 0       0 $wrap->{$column} ? $wrap->{$column}->(":$column") :
    0          
1221             ":$column";
1222             }
1223 0         0 $multi_values_clause .= '(' . join(', ', @place_holders) . '), ';
1224             }
1225 0         0 $multi_values_clause =~ s/, $//;
1226            
1227 0         0 return $multi_values_clause;
1228             }
1229              
1230             sub _id_to_param {
1231 79     79   159 my ($self, $id, $primary_keys, $table) = @_;
1232            
1233             # Check primary key
1234 79 50       142 confess "primary_key option " .
1235             "must be specified when id option is used" . _subname
1236             unless defined $primary_keys;
1237 79 100       217 $primary_keys = [$primary_keys] unless ref $primary_keys eq 'ARRAY';
1238            
1239 79         239 _deprecate('0.39', "DBIx::Custom::select,update,delete method's id and primary_key option is DEPRECATED!");
1240            
1241             # Create parameter
1242 79         834 my $param = {};
1243 79 50       146 if (defined $id) {
1244 79 100       164 $id = [$id] unless ref $id eq 'ARRAY';
1245 79         188 for(my $i = 0; $i < @$id; $i++) {
1246 106         149 my $key = $primary_keys->[$i];
1247 106 50       255 $key = "$table." . $key if $table;
1248 106         305 $param->{$key} = $id->[$i];
1249             }
1250             }
1251            
1252 79         149 return $param;
1253             }
1254              
1255             sub _connect {
1256 0     0   0 my $self = shift;
1257            
1258             # Attributes
1259 0         0 my $dsn = $self->dsn;
1260 0 0       0 confess qq{"dsn" must be specified } . _subname
1261             unless $dsn;
1262 0         0 my $user = $self->user;
1263 0         0 my $password = $self->password;
1264 0         0 my $option = $self->option;
1265 0         0 $option = {%{$self->default_option}, %$option};
  0         0  
1266            
1267             # Connect
1268 0         0 my $dbh;
1269 0         0 eval { $dbh = DBI->connect($dsn, $user, $password, $option) };
  0         0  
1270            
1271             # Connect error
1272 0 0       0 confess "$@ " . _subname if $@;
1273            
1274 0         0 return $dbh;
1275             }
1276              
1277             sub _confess {
1278 585     585   1352 my ($self, $error, $append) = @_;
1279            
1280             # Append
1281 585   50     1029 $append ||= "";
1282            
1283             # Verbose
1284 585 100       1154 if ($Carp::Verbose) { confess $error }
  6         530  
1285            
1286             # Not verbose
1287             else {
1288             # Remove line and module information
1289 579         976 my $at_pos = rindex($error, ' at ');
1290 579         992 $error = substr($error, 0, $at_pos);
1291 579         2516 $error =~ s/\s+$//;
1292 579         51871 confess "$error$append";
1293             }
1294             }
1295              
1296 330     330   2219 sub _driver { lc shift->{dbh}->{Driver}->{Name} }
1297              
1298             sub _need_tables {
1299 375     375   536 my ($self, $tree, $need_tables, $tables) = @_;
1300            
1301             # Get needed tables
1302 375         479 for my $table (@$tables) {
1303 809 100       1458 if ($tree->{$table}) {
1304 245         311 $need_tables->{$table} = 1;
1305 245         531 $self->_need_tables($tree, $need_tables, [$tree->{$table}{parent}])
1306             }
1307             }
1308             }
1309              
1310             sub _push_join {
1311 130     130   243 my ($self, $sql, $join, $join_tables) = @_;
1312            
1313             # Push join clause
1314 130         174 my $tree = {};
1315 130         291 for (my $i = 0; $i < @$join; $i++) {
1316            
1317             # Arrange
1318 157         223 my $join_clause;;
1319             my $option;
1320 157 100       341 if (ref $join->[$i] eq 'HASH') {
1321 6         10 $join_clause = $join->[$i]->{clause};
1322 6         18 $option = {table => $join->[$i]->{table}};
1323             }
1324             else {
1325 151         199 $join_clause = $join->[$i];
1326 151         195 $option = {};
1327             };
1328              
1329             # Find tables in join clause
1330 157         230 my $table1;
1331             my $table2;
1332 157 100       284 if (my $table = $option->{table}) {
1333 6         11 $table1 = $table->[0];
1334 6         9 $table2 = $table->[1];
1335             }
1336             else {
1337 151         281 my $q = $self->_quote;
1338 151         1368 my $j_clause = (split /\s+on\s+/, $join_clause)[-1];
1339 151         320 $j_clause =~ s/'.+?'//g;
1340 151         219 my $q_re = quotemeta($q);
1341 151         393 $j_clause =~ s/[$q_re]//g;
1342            
1343 151         465 my @j_clauses = reverse split /\s(and|on)\s/, $j_clause;
1344 151         247 my $c = $self->{safety_character};
1345 151         992 my $join_re = qr/((?:[$c]+?\.[$c]+?)|(?:[$c]+?))\.[$c]+[^$c].*?((?:[$c]+?\.[$c]+?)|(?:[$c]+?))\.[$c]+/sm;
1346 151         260 for my $clause (@j_clauses) {
1347 167 100       1036 if ($clause =~ $join_re) {
1348 151         290 $table1 = $1;
1349 151         200 $table2 = $2;
1350 151         419 last;
1351             }
1352             }
1353             }
1354 157 50 33     521 confess qq{join clause must have two table name after "on" keyword. } .
1355             qq{"$join_clause" is passed } . _subname
1356             unless defined $table1 && defined $table2;
1357             confess qq{right side table of "$join_clause" must be unique } . _subname
1358 157 50       279 if exists $tree->{$table2};
1359 157 50       280 confess qq{Same table "$table1" is specified} . _subname
1360             if $table1 eq $table2;
1361 157         764 $tree->{$table2}
1362             = {position => $i, parent => $table1, join => $join_clause};
1363             }
1364            
1365             # Search need tables
1366 130         178 my $need_tables = {};
1367 130         306 $self->_need_tables($tree, $need_tables, $join_tables);
1368 130         402 my @need_tables = sort { $tree->{$a}{position} <=> $tree->{$b}{position} }
  18         76  
1369             keys %$need_tables;
1370            
1371             # Add join clause
1372 130         651 $$sql .= $tree->{$_}{join} . ' ' for @need_tables;
1373             }
1374              
1375             sub _quote {
1376 316     316   1005 my $self = shift;
1377 316   50     3181 return $self->quote || '';
1378             }
1379              
1380             sub _remove_duplicate_table {
1381 0     0   0 my ($self, $tables, $main_table) = @_;
1382            
1383             # Remove duplicate table
1384 0 0       0 my %tables = map {defined $_ ? ($_ => 1) : ()} @$tables;
  0         0  
1385 0 0       0 delete $tables{$main_table} if $main_table;
1386            
1387 0 0       0 my $new_tables = [keys %tables, $main_table ? $main_table : ()];
1388 0 0       0 if (my $q = $self->_quote) {
1389 0         0 $q = quotemeta($q);
1390 0         0 $_ =~ s/[$q]//g for @$new_tables;
1391             }
1392              
1393 0         0 return $new_tables;
1394             }
1395              
1396             sub _search_tables {
1397 1710     1710   2749 my ($self, $source) = @_;
1398            
1399             # Search tables
1400 1710         2283 my $tables = [];
1401 1710         2865 my ($q, $p) = $self->_qp(quotemeta => 1);
1402 1710         3956 $source =~ s/$q//g;
1403 1710         2452 $source =~ s/$p//g;
1404 1710         27617 my $c = $self->safety_character;
1405            
1406 1710         13840 while ($source =~ /((?:[$c]+?\.[$c]+?)|(?:[$c]+?))\.[$c]+/g) {
1407 538         2972 push @$tables, $1;
1408             }
1409 1710         3442 return $tables;
1410             }
1411              
1412             sub _where_clause_and_param {
1413 889     889   1935 my ($self, $where) = @_;
1414            
1415 889   100     2635 $where ||= {};
1416 889         1222 my $w = {};
1417            
1418 889 100       1879 if (ref $where eq 'HASH') {
    50          
    0          
1419 766         11231 my $safety_character = $self->safety_character;
1420            
1421 766         3632 my $clause = [];
1422 766         1021 my $column_join = '';
1423 766         2009 for my $column (sort keys %$where) {
1424            
1425 293 100       1311 confess qq{"$column" is not safety column name in where clause} . _subname
1426             unless $column =~ /^[$safety_character\.]+$/;
1427            
1428 290         429 $column_join .= $column;
1429 290         359 my $table;
1430             my $c;
1431 290 50       888 if ($column =~ /(?:(.*)\.)?(.*)/) {
1432 290         473 $table = $1;
1433 290         434 $c = $2;
1434             }
1435            
1436 290         326 my $table_quote;
1437 290 100       600 $table_quote = $self->_tq($table) if defined $table;
1438 290         567 my $column_quote = $self->q($c);
1439 290 100       672 $column_quote = $table_quote . '.' . $column_quote
1440             if defined $table_quote;
1441 290 100       527 if (ref $where->{$column} eq 'ARRAY') {
1442 6         14 my $c = join(', ', (":$column") x @{$where->{$column}});
  6         84  
1443 6 100       9 if (@{$where->{$column}}) {
  6         14  
1444 3         14 push @$clause, "$column_quote in ( $c )";
1445             }
1446 3         11 else { push @$clause, '1 <> 1' }
1447             }
1448 284         769 else { push @$clause, "$column_quote = :$column" }
1449             }
1450            
1451 763 100       2113 $w->{clause} = @$clause ? "where ( " . join(' and ', @$clause) . " ) " : '' ;
1452 763         1427 $w->{param} = $where;
1453             }
1454             elsif (ref $where) {
1455 123         133 my $obj;
1456              
1457 123 100       254 if (ref $where eq 'DBIx::Custom::Where') { $obj = $where }
  84 50       103  
1458             elsif (ref $where eq 'ARRAY') {
1459 39         108 $obj = $self->where(clause => $where->[0], param => $where->[1], join => $where->[2]);
1460             }
1461            
1462             # Check where argument
1463 123 50       257 confess qq{"where" must be hash reference or DBIx::Custom::Where object}
1464             . qq{or array reference, which contains where clause and parameter}
1465             . _subname
1466             unless ref $obj eq 'DBIx::Custom::Where';
1467              
1468 123         242 $w->{clause} = $obj->to_string;
1469 120         1812 $w->{param} = $obj->param;
1470 120         782 $w->{join} = $obj->{join};
1471             }
1472             elsif ($where) {
1473 0         0 $w->{clause} = "where $where";
1474             }
1475            
1476 883         1359 return $w;
1477             }
1478              
1479             # DEPRECATED
1480             our $AUTOLOAD;
1481             sub AUTOLOAD {
1482 39     39   6447 my $self = shift;
1483            
1484 39         109 _deprecate('0.39', "DBIx::Custom AUTOLOAD feature is DEPRECATED!");
1485            
1486             # Method name
1487 39         239 my ($package, $mname) = $AUTOLOAD =~ /^([\w\:]+)\:\:(\w+)$/;
1488              
1489             # Call method
1490 39   100     134 $self->{_methods} ||= {};
1491 39 100 66     143 if (my $method = $self->{_methods}->{$mname}) {
    100          
1492 9         29 return $self->$method(@_)
1493             }
1494             elsif ($self->{dbh} && (my $dbh_method = $self->dbh->can($mname))) {
1495 27         48 $self->dbh->$dbh_method(@_);
1496             }
1497             else {
1498 3         18 confess qq{Can't locate object method "$mname" via "$package" }
1499             . _subname;
1500             }
1501             }
1502       0     sub DESTROY {}
1503              
1504             # DEPRECATED
1505             sub helper {
1506 9     9 0 60 my $self = shift;
1507            
1508 9         24 _deprecate('0.39', "DBIx::Custom::helper method is DEPRECATED!");
1509            
1510             # Register method
1511 9 100       30 my $methods = ref $_[0] eq 'HASH' ? $_[0] : {@_};
1512 9 100       14 $self->{_methods} = {%{$self->{_methods} || {}}, %$methods};
  9         45  
1513            
1514 9         53 return $self;
1515             }
1516              
1517             # DEPRECATED
1518             sub update_or_insert {
1519              
1520 18     18 0 5191 _deprecate('0.39', "DBIx::Custom::update_or_insert method is DEPRECATED!");
1521              
1522 18         56 my ($self, $param, %opt) = @_;
1523             confess "update_or_insert method need primary_key and id option "
1524 18 100 66     363 unless defined $opt{id} && defined $opt{primary_key};
1525 15   50     42 my $statement_opt = $opt{option} || {};
1526              
1527 15 50       34 my $rows = $self->select(%opt, %{$statement_opt->{select} || {}})->all;
  15         64  
1528 15 100       154 if (@$rows == 0) {
    100          
1529 6 50       17 return $self->insert($param, %opt, %{$statement_opt->{insert} || {}});
  6         35  
1530             }
1531             elsif (@$rows == 1) {
1532 6 100       32 return 0 unless keys %$param;
1533 3 50       11 return $self->update($param, %opt, %{$statement_opt->{update} || {}});
  3         23  
1534             }
1535 3         14 else { confess "selected row must be one " . _subname }
1536             }
1537              
1538             # DEPRECATED
1539             sub count {
1540 15     15 0 292 _deprecate('0.39', "DBIx::Custom::count method is DEPRECATED!");
1541 15         43 shift->select(column => 'count(*)', @_)->fetch_one->[0]
1542             }
1543              
1544             1;
1545              
1546             =head1 NAME
1547              
1548             DBIx::Custom - DBI extension to execute insert, update, delete, and select easily
1549              
1550             =head1 SYNOPSIS
1551              
1552             use DBIx::Custom;
1553            
1554             # Connect
1555             my $dbi = DBIx::Custom->connect(
1556             "dbi:mysql:database=dbname",
1557             'ken',
1558             '!LFKD%$&',
1559             {mysql_enable_utf8 => 1}
1560             );
1561            
1562             # Create model
1563             $dbi->create_model('book');
1564            
1565             # Insert
1566             $dbi->model('book')->insert({title => 'Perl', author => 'Ken'});
1567            
1568             # Update
1569             $dbi->model('book')->update({title => 'Perl', author => 'Ken'}, where => {id => 5});
1570            
1571             # Delete
1572             $dbi->model('book')->delete(where => {author => 'Ken'});
1573            
1574             # Select
1575             my $result = $dbi->model('book')->select(['title', 'author'], where => {author => 'Ken'});
1576            
1577             # Select, more complex
1578             # select book.title as book.title,
1579             # book.author as book.author,
1580             # comnapy.name as company.name
1581             # form book
1582             # left outer join company on book.company_id = company.id
1583             # where book.author = ?
1584             # order by id limit 0, 5
1585             my $result = $dbi->model('book')->select(
1586             [
1587             {book => [qw/title author/]},
1588             {company => ['name']}
1589             ],
1590             where => {'book.author' => 'Ken'},
1591             join => ['left outer join company on book.company_id = company.id'],
1592             append => 'order by id limit 0, 5'
1593             );
1594            
1595             # Get all rows or only one row
1596             my $rows = $result->all;
1597             my $row = $result->one;
1598            
1599             # Execute SQL with named place holder
1600             my $result = $dbi->execute(
1601             "select id from book where author = :author and title like :title",
1602             {author => 'ken', title => '%Perl%'}
1603             );
1604            
1605             =head1 DESCRIPTION
1606              
1607             L is L wrapper module to execute SQL easily.
1608             This module have the following features.
1609              
1610             =over 4
1611              
1612             =item *
1613              
1614             Execute C, C, C, or C
1615              
1616             =item *
1617              
1618             Create C clause flexibly
1619              
1620             =item *
1621              
1622             Named place holder support
1623              
1624             =item *
1625              
1626             Model support
1627              
1628             =item *
1629              
1630             Connection manager support
1631              
1632             =item *
1633              
1634             Choice your favorite relational database management system,
1635             C, C, C, C,
1636             C, C, C or anything,
1637              
1638             =item *
1639              
1640             Filtering by data type or column name
1641              
1642             =item *
1643              
1644             Create C clause flexibly
1645              
1646             =back
1647              
1648             =head1 WEB SITE
1649              
1650             L
1651              
1652             =head1 DOCUMENTS
1653              
1654             L
1655              
1656             L
1657              
1658             =head1 ATTRIBUTES
1659              
1660             =head2 connector
1661              
1662             my $connector = $dbi->connector;
1663             $dbi = $dbi->connector($connector);
1664              
1665             Connection manager object. if C is set, you can get C
1666             through connection manager. Conection manager object must have C method.
1667              
1668             This is L example. Please pass
1669             C to L C method.
1670              
1671             my $connector = DBIx::Connector->new(
1672             "dbi:mysql:database=$database",
1673             $user,
1674             $password,
1675             DBIx::Custom->new->default_option
1676             );
1677            
1678             my $dbi = DBIx::Custom->connect(connector => $connector);
1679              
1680             If C is set to 1 when connect method is called,
1681             L is automatically set to C
1682              
1683             my $dbi = DBIx::Custom->connect(
1684             dsn => $dsn, user => $user, password => $password, connector => 1);
1685            
1686             my $connector = $dbi->connector; # DBIx::Connector
1687              
1688             Note that L must be installed.
1689              
1690             =head2 dsn
1691              
1692             my $dsn = $dbi->dsn;
1693             $dbi = $dbi->dsn("DBI:mysql:database=dbname");
1694              
1695             Data source name, used when C method is executed.
1696              
1697             =head2 default_option
1698              
1699             my $default_option = $dbi->default_option;
1700             $dbi = $dbi->default_option($default_option);
1701              
1702             L default option, used when C method is executed,
1703             default to the following values.
1704              
1705             {
1706             RaiseError => 1,
1707             PrintError => 0,
1708             AutoCommit => 1,
1709             }
1710              
1711             =head2 exclude_table
1712              
1713             my $exclude_table = $dbi->exclude_table;
1714             $dbi = $dbi->exclude_table(qr/pg_/);
1715              
1716             Excluded table regex.
1717             C, C, C
1718              
1719             =head2 filters
1720              
1721             my $filters = $dbi->filters;
1722             $dbi = $dbi->filters(\%filters);
1723              
1724             Filters, registered by C method.
1725              
1726             =head2 last_sql
1727              
1728             my $last_sql = $dbi->last_sql;
1729             $dbi = $dbi->last_sql($last_sql);
1730              
1731             Get last succeeded SQL executed by C method.
1732              
1733             =head2 now
1734              
1735             my $now = $dbi->now;
1736             $dbi = $dbi->now($now);
1737              
1738             Code reference which return current time, default to the following code reference.
1739              
1740             sub {
1741             my ($sec, $min, $hour, $mday, $mon, $year) = localtime;
1742             $mon++;
1743             $year += 1900;
1744             return sprintf("%04d-%02d-%02d %02d:%02d:%02d");
1745             }
1746              
1747             This return the time like C<2011-10-14 05:05:27>.
1748              
1749             This is used by C method's C option and C option,
1750             and C method's C option.
1751              
1752             =head2 models
1753              
1754             my $models = $dbi->models;
1755             $dbi = $dbi->models(\%models);
1756              
1757             Models, included by C method.
1758              
1759             =head2 mytable_symbol
1760              
1761             Symbol to specify own columns in select method column option, default to '__MY__'.
1762              
1763             $dbi->table('book')->select({__MY__ => '*'});
1764              
1765             =head2 option
1766              
1767             my $option = $dbi->option;
1768             $dbi = $dbi->option($option);
1769              
1770             L option, used when C method is executed.
1771             Each value in option override the value of C.
1772              
1773             =head2 password
1774              
1775             my $password = $dbi->password;
1776             $dbi = $dbi->password('lkj&le`@s');
1777              
1778             Password, used when C method is executed.
1779              
1780             =head2 quote
1781              
1782             my quote = $dbi->quote;
1783             $dbi = $dbi->quote('"');
1784              
1785             Reserved word quote.
1786             Default to double quote '"' except for mysql.
1787             In mysql, default to back quote '`'
1788              
1789             You can set quote pair.
1790              
1791             $dbi->quote('[]');
1792              
1793             =head2 result_class
1794              
1795             my $result_class = $dbi->result_class;
1796             $dbi = $dbi->result_class('DBIx::Custom::Result');
1797              
1798             Result class, default to L.
1799              
1800             =head2 safety_character
1801              
1802             my $safety_character = $dbi->safety_character;
1803             $dbi = $dbi->safety_character($character);
1804              
1805             Regex of safety character for table and column name, default to 'a-zA-Z_'.
1806             Note that you don't have to specify like '[a-zA-Z_]'.
1807              
1808             =head2 separator
1809              
1810             my $separator = $dbi->separator;
1811             $dbi = $dbi->separator('-');
1812              
1813             Separator which join table name and column name.
1814             This have effect to C and C method,
1815             and C
1816              
1817             Default to C<.>.
1818              
1819             =head2 user
1820              
1821             my $user = $dbi->user;
1822             $dbi = $dbi->user('Ken');
1823              
1824             User name, used when C method is executed.
1825              
1826             =head2 user_column_info
1827              
1828             my $user_column_info = $dbi->user_column_info;
1829             $dbi = $dbi->user_column_info($user_column_info);
1830              
1831             You can set the date like the following one.
1832              
1833             [
1834             {table => 'book', column => 'title', info => {...}},
1835             {table => 'author', column => 'name', info => {...}}
1836             ]
1837              
1838             Usually, you set return value of C.
1839              
1840             my $user_column_info
1841             = $dbi->get_column_info(exclude_table => qr/^system/);
1842             $dbi->user_column_info($user_column_info);
1843              
1844             If C is set, C use C
1845             to find column info. this is very fast.
1846              
1847             =head2 user_table_info
1848              
1849             my $user_table_info = $dbi->user_table_info;
1850             $dbi = $dbi->user_table_info($user_table_info);
1851              
1852             You can set the following data.
1853              
1854             [
1855             {table => 'book', info => {...}},
1856             {table => 'author', info => {...}}
1857             ]
1858              
1859             Usually, you can set return value of C.
1860              
1861             my $user_table_info = $dbi->get_table_info(exclude => qr/^system/);
1862             $dbi->user_table_info($user_table_info);
1863              
1864             If C is set, C use C
1865             to find table info.
1866              
1867             =head1 METHODS
1868              
1869             L inherits all methods from L
1870             and use all methods of L
1871             and implements the following new ones.
1872              
1873             =head2 available_datatype
1874              
1875             print $dbi->available_datatype;
1876              
1877             Get available data types. You can use these data types
1878             in C's C and C section.
1879              
1880             =head2 available_typename
1881              
1882             print $dbi->available_typename;
1883              
1884             Get available type names. You can use these type names in
1885             C's C and C section.
1886              
1887             =head2 assign_clause
1888              
1889             my $assign_clause = $dbi->assign_clause({title => 'a', age => 2});
1890              
1891             Create assign clause
1892              
1893             title = :title, author = :author
1894              
1895             This is used to create update clause.
1896              
1897             "update book set " . $dbi->assign_clause({title => 'a', age => 2});
1898              
1899             =head2 column
1900              
1901             my $column = $dbi->column(book => ['author', 'title']);
1902              
1903             Create column clause. The following column clause is created.
1904              
1905             book.author as "book.author",
1906             book.title as "book.title"
1907              
1908             You can change separator by C attribute.
1909              
1910             # Separator is hyphen
1911             $dbi->separator('-');
1912            
1913             book.author as "book-author",
1914             book.title as "book-title"
1915            
1916             =head2 connect
1917            
1918             # DBI compatible arguments
1919             my $dbi = DBIx::Custom->connect(
1920             "dbi:mysql:database=dbname",
1921             'ken',
1922             '!LFKD%$&',
1923             {mysql_enable_utf8 => 1}
1924             );
1925            
1926             # pass DBIx::Custom attributes
1927             my $dbi = DBIx::Custom->connect(
1928             dsn => "dbi:mysql:database=dbname",
1929             user => 'ken',
1930             password => '!LFKD%$&',
1931             option => {mysql_enable_utf8 => 1}
1932             );
1933              
1934             Connect to the database and create a new L object.
1935              
1936             L is a wrapper of L.
1937             C and C options are true,
1938             and C option is false by default.
1939              
1940             =head2 create_model
1941            
1942             $dbi->create_model('book');
1943             $dbi->create_model(
1944             'book',
1945             join => [
1946             'inner join company on book.comparny_id = company.id'
1947             ]
1948             );
1949             $dbi->create_model(
1950             table => 'book',
1951             join => [
1952             'inner join company on book.comparny_id = company.id'
1953             ],
1954             );
1955              
1956             Create L object and initialize model.
1957             Model columns attribute is automatically set.
1958             You can use this model by using C method.
1959              
1960             $dbi->model('book')->select(...);
1961              
1962             You can use model name which different from table name
1963              
1964             $dbi->create_model(name => 'book1', table => 'book');
1965             $dbi->model('book1')->select(...);
1966            
1967             =head2 dbh
1968              
1969             my $dbh = $dbi->dbh;
1970              
1971             Get L database handle. if C is set, you can get
1972             database handle through C object.
1973              
1974             =head2 delete
1975              
1976             $dbi->delete(table => 'book', where => {title => 'Perl'});
1977              
1978             Execute delete statement.
1979              
1980             The following options are available.
1981              
1982             B
1983              
1984             C method use all of C method's options,
1985             and use the following new ones.
1986              
1987             =over 4
1988              
1989             =item prefix
1990              
1991             prefix => 'some'
1992              
1993             prefix before table name section.
1994              
1995             delete some from book
1996              
1997             =item table
1998              
1999             table => 'book'
2000              
2001             Table name.
2002              
2003             =item where
2004              
2005             Same as C
2006              
2007             =back
2008              
2009             =head2 delete_all
2010              
2011             $dbi->delete_all(table => $table);
2012              
2013             Execute delete statement for all rows.
2014             Options is same as C.
2015              
2016             =head2 each_column
2017              
2018             $dbi->each_column(
2019             sub {
2020             my ($dbi, $table, $column, $column_info) = @_;
2021            
2022             my $type = $column_info->{TYPE_NAME};
2023            
2024             if ($type eq 'DATE') {
2025             # ...
2026             }
2027             }
2028             );
2029              
2030             Iterate all column informations in database.
2031             Argument is callback which is executed when one column is found.
2032             Callback receive four arguments. C, C,
2033             C, and C.
2034              
2035             If C is set, C method use C
2036             information, you can improve the performance of C in
2037             the following way.
2038              
2039             my $column_infos = $dbi->get_column_info(exclude_table => qr/^system_/);
2040             $dbi->user_column_info($column_info);
2041             $dbi->each_column(sub { ... });
2042              
2043             =head2 each_table
2044              
2045             $dbi->each_table(
2046             sub {
2047             my ($dbi, $table, $table_info) = @_;
2048            
2049             my $table_name = $table_info->{TABLE_NAME};
2050             }
2051             );
2052              
2053             Iterate all table information from in database.
2054             Argument is callback which is executed when one table is found.
2055             Callback receive three arguments, C, C,
2056             C.
2057              
2058             If C is set, C method use C
2059             information, you can improve the performance of C in
2060             the following way.
2061              
2062             my $table_infos = $dbi->get_table_info(exclude => qr/^system_/);
2063             $dbi->user_table_info($table_info);
2064             $dbi->each_table(sub { ... });
2065              
2066             =head2 execute
2067              
2068             my $result = $dbi->execute(
2069             "select * from book where title = :title and author like :author",
2070             {title => 'Perl', author => '%Ken%'}
2071             );
2072              
2073             my $result = $dbi->execute(
2074             "select * from book where title = :book.title and author like :book.author",
2075             {'book.title' => 'Perl', 'book.author' => '%Ken%'}
2076             );
2077              
2078             Execute SQL. SQL can contain column parameter such as :author and :title.
2079             You can append table name to column name such as :book.title and :book.author.
2080             Second argument is data, embedded into column parameter.
2081             Return value is L object when select statement is executed,
2082             or the count of affected rows when insert, update, delete statement is executed.
2083              
2084             Named placeholder such as C<:title> is replaced by placeholder C.
2085            
2086             # Original
2087             select * from book where title = :title and author like :author
2088            
2089             # Replaced
2090             select * from where title = ? and author like ?;
2091              
2092             You can specify operator with named placeholder
2093             by C syntax.
2094              
2095             # Original
2096             select * from book where :title{=} and :author{like}
2097            
2098             # Replaced
2099             select * from where title = ? and author like ?;
2100              
2101             Note that colons in time format such as 12:13:15 is an exception,
2102             it is not parsed as named placeholder.
2103             If you want to use colon generally, you must escape it by C<\\>
2104              
2105             select * from where title = "aa\\:bb";
2106              
2107             B
2108              
2109             The following options are available.
2110              
2111             =over 4
2112              
2113             =item after_build_sql
2114              
2115             You can filter sql after the sql is build.
2116              
2117             after_build_sql => $code_ref
2118              
2119             The following one is one example.
2120              
2121             $dbi->select(
2122             table => 'book',
2123             column => 'distinct(name)',
2124             after_build_sql => sub {
2125             "select count(*) from ($_[0]) as t1"
2126             }
2127             );
2128              
2129             The following SQL is executed.
2130              
2131             select count(*) from (select distinct(name) from book) as t1;
2132              
2133             =item append
2134              
2135             append => 'order by name'
2136              
2137             Append some statement after SQL.
2138              
2139             =item bind_type
2140              
2141             Specify database bind data type.
2142            
2143             bind_type => {image => DBI::SQL_BLOB}
2144             bind_type => [image => DBI::SQL_BLOB]
2145             bind_type => [[qw/image audio/] => DBI::SQL_BLOB]
2146              
2147             This is used to bind parameter by C of statement handle.
2148              
2149             $sth->bind_param($pos, $value, DBI::SQL_BLOB);
2150              
2151             =item filter
2152            
2153             filter => {
2154             title => sub { uc $_[0] }
2155             author => sub { uc $_[0] }
2156             }
2157              
2158             # Filter name
2159             filter => {
2160             title => 'upper_case',
2161             author => 'upper_case'
2162             }
2163            
2164             # At once
2165             filter => [
2166             [qw/title author/] => sub { uc $_[0] }
2167             ]
2168              
2169             Filter. You can set subroutine or filter name
2170             registered by C.
2171             This filter is executed before data is saved into database.
2172             and before type rule filter is executed.
2173              
2174             =item reuse
2175            
2176             reuse => $hash_ref
2177              
2178             Reuse statement handle in same SQL.
2179            
2180             my $reuse = {};
2181             $dbi->execute($sql, $param, reuse => $reuse);
2182              
2183             This will improved performance when you want to execute same sql repeatedly.
2184              
2185             =item table
2186            
2187             table => 'author'
2188              
2189             If you want to omit table name in column name
2190             and enable C and C type filter,
2191             You must set C option.
2192              
2193             $dbi->execute("select * from book where title = :title and author = :author",
2194             {title => 'Perl', author => 'Ken', table => 'book');
2195              
2196             # Same
2197             $dbi->execute(
2198             "select * from book where title = :book.title and author = :book.author",
2199             {title => 'Perl', author => 'Ken');
2200              
2201             =item table_alias
2202              
2203             table_alias => {worker => 'user'} # {ALIAS => TABLE}
2204              
2205             Table alias. Key is alias table name, value is real table name, .
2206             If you set C, you can enable C and C type rule
2207             on alias table name.
2208              
2209             =item type_rule_off
2210              
2211             type_rule_off => 1
2212              
2213             Turn C and C type rule off.
2214              
2215             =item type_rule1_off
2216              
2217             type_rule1_off => 1
2218              
2219             Turn C type rule off.
2220              
2221             =item type_rule2_off
2222              
2223             type_rule2_off => 1
2224              
2225             Turn C type rule off.
2226              
2227             =item prepare_attr
2228              
2229             prepare_attr => {mysql_use_result => 1}
2230              
2231             Statemend handle attributes,
2232             this is L's C method second argument.
2233              
2234             =head2 get_column_info
2235              
2236             my $column_infos = $dbi->get_column_info(exclude_table => qr/^system_/);
2237              
2238             get column information except for one which match C pattern.
2239              
2240             [
2241             {table => 'book', column => 'title', info => {...}},
2242             {table => 'author', column => 'name' info => {...}}
2243             ]
2244              
2245             =head2 get_table_info
2246              
2247             my $table_infos = $dbi->get_table_info(exclude => qr/^system_/);
2248              
2249             get table information except for one which match C pattern.
2250              
2251             [
2252             {table => 'book', info => {...}},
2253             {table => 'author', info => {...}}
2254             ]
2255              
2256             You can set this value to C.
2257              
2258             =head2 insert
2259              
2260             $dbi->insert({title => 'Perl', author => 'Ken'}, table => 'book');
2261              
2262             Execute insert statement. First argument is row data. Return value is
2263             affected row count.
2264              
2265             If you want to set constant value to row data, use scalar reference
2266             as parameter value.
2267              
2268             {date => \"NOW()"}
2269              
2270             You can pass multiple parameters, this is very fast.
2271              
2272             $dbi->insert(
2273             [
2274             {title => 'Perl', author => 'Ken'},
2275             {title => 'Ruby', author => 'Tom'}
2276             ],
2277             table => 'book'
2278             );
2279              
2280             In multiple insert, you can't use C option.
2281             and only first parameter is used to create sql.
2282              
2283             B
2284              
2285             C method use all of C method's options,
2286             and use the following new ones.
2287              
2288             =over 4
2289              
2290             =item bulk_insert
2291              
2292             bulk_insert => 1
2293              
2294             bulk insert is executed if database support bulk insert and
2295             multiple parameters is passed to C.
2296             The SQL like the following one is executed.
2297              
2298             insert into book (id, title) values (?, ?), (?, ?);
2299              
2300             =item ctime
2301              
2302             ctime => 'created_time'
2303              
2304             Created time column name. time when row is created is set to the column.
2305             default time format is "YYYY-mm-dd HH:MM:SS", which can be changed by
2306             C attribute.
2307              
2308             =item prefix
2309              
2310             prefix => 'or replace'
2311              
2312             prefix before table name section
2313              
2314             insert or replace into book
2315              
2316             =item table
2317              
2318             table => 'book'
2319              
2320             Table name.
2321              
2322             =item mtime
2323              
2324             This option is same as C method C option.
2325              
2326             =item wrap
2327              
2328             wrap => {price => sub { "max($_[0])" }}
2329              
2330             placeholder wrapped string.
2331              
2332             If the following statement
2333              
2334             $dbi->insert({price => 100}, table => 'book',
2335             {price => sub { "$_[0] + 5" }});
2336              
2337             is executed, the following SQL is executed.
2338              
2339             insert into book price values ( ? + 5 );
2340              
2341             =back
2342              
2343             =over 4
2344              
2345             =head2 include_model
2346              
2347             $dbi->include_model('MyModel');
2348              
2349             Include models from specified namespace,
2350             the following layout is needed to include models.
2351              
2352             lib / MyModel.pm
2353             / MyModel / book.pm
2354             / company.pm
2355              
2356             Name space module, extending L.
2357              
2358             B
2359              
2360             package MyModel;
2361             use DBIx::Custom::Model -base;
2362            
2363             1;
2364              
2365             Model modules, extending name space module.
2366              
2367             B
2368              
2369             package MyModel::book;
2370             use MyModel -base;
2371            
2372             1;
2373              
2374             B
2375              
2376             package MyModel::company;
2377             use MyModel -base;
2378            
2379             1;
2380            
2381             MyModel::book and MyModel::company is included by C.
2382              
2383             You can get model object by C.
2384              
2385             my $book_model = $dbi->model('book');
2386             my $company_model = $dbi->model('company');
2387              
2388             You can include full-qualified table name like C
2389              
2390             lib / MyModel.pm
2391             / MyModel / main / book.pm
2392             / company.pm
2393              
2394             my $main_book = $self->model('main.book');
2395              
2396             See L to know model features.
2397              
2398             =head2 like_value
2399              
2400             my $like_value = $dbi->like_value
2401              
2402             Code reference which return a value for the like value.
2403              
2404             sub { "%$_[0]%" }
2405              
2406             =head2 mapper
2407              
2408             my $mapper = $dbi->mapper(param => $param);
2409              
2410             Create a new L object.
2411              
2412             =head2 merge_param
2413              
2414             my $param = $dbi->merge_param({key1 => 1}, {key1 => 1, key2 => 2});
2415              
2416             Merge parameters. The following new parameter is created.
2417              
2418             {key1 => [1, 1], key2 => 2}
2419              
2420             If same keys contains, the value is converted to array reference.
2421              
2422             =head2 model
2423              
2424             my $model = $dbi->model('book');
2425              
2426             Get a L object
2427             create by C or C
2428              
2429             =head2 mycolumn
2430              
2431             my $column = $dbi->mycolumn(book => ['author', 'title']);
2432              
2433             Create column clause for myself. The following column clause is created.
2434              
2435             book.author as author,
2436             book.title as title
2437              
2438             =head2 new
2439              
2440             my $dbi = DBIx::Custom->new(
2441             dsn => "dbi:mysql:database=dbname",
2442             user => 'ken',
2443             password => '!LFKD%$&',
2444             option => {mysql_enable_utf8 => 1}
2445             );
2446              
2447             Create a new L object.
2448              
2449             =head2 not_exists
2450              
2451             my $not_exists = $dbi->not_exists;
2452              
2453             DBIx::Custom::NotExists object, indicating the column is not exists.
2454             This is used in C of L .
2455              
2456             =head2 order
2457              
2458             my $order = $dbi->order;
2459              
2460             Create a new L object.
2461              
2462             =head2 q
2463              
2464             my $quooted = $dbi->q("title");
2465              
2466             Quote string by value of C.
2467              
2468             =head2 register_filter
2469              
2470             $dbi->register_filter(
2471             # Time::Piece object to database DATE format
2472             tp_to_date => sub {
2473             my $tp = shift;
2474             return $tp->strftime('%Y-%m-%d');
2475             },
2476             # database DATE format to Time::Piece object
2477             date_to_tp => sub {
2478             my $date = shift;
2479             return Time::Piece->strptime($date, '%Y-%m-%d');
2480             }
2481             );
2482            
2483             Register filters, used by C option of many methods.
2484              
2485             =head2 select
2486              
2487             my $result = $dbi->select(
2488             column => ['author', 'title'],
2489             table => 'book',
2490             where => {author => 'Ken'},
2491             );
2492            
2493             Execute select statement.
2494              
2495             You can pass odd number arguments. first argument is C.
2496              
2497             my $result = $dbi->select(['author', 'title'], table => 'book');
2498              
2499             B
2500              
2501             C
2502             and use the following new ones.
2503              
2504             =over 4
2505              
2506             =item column
2507            
2508             column => 'author'
2509             column => ['author', 'title']
2510              
2511             Column clause.
2512            
2513             if C is not specified, '*' is set.
2514              
2515             column => '*'
2516              
2517             You can specify hash of array reference.
2518              
2519             column => [
2520             {book => [qw/author title/]},
2521             {person => [qw/name age/]}
2522             ]
2523              
2524             This is expanded to the following one by using C method.
2525              
2526             book.author as "book.author",
2527             book.title as "book.title",
2528             person.name as "person.name",
2529             person.age as "person.age"
2530              
2531             You can specify own column by C<__MY__>.
2532              
2533             column => [
2534             {__MY__ => [qw/author title/]},
2535             ]
2536              
2537             This is expanded to the following one by using C method.
2538              
2539             book.author as "author",
2540             book.title as "title",
2541              
2542             C<__MY__> can be changed by C attribute.
2543              
2544             =item param
2545              
2546             param => {'table2.key3' => 5}
2547              
2548             Parameter shown before where clause.
2549            
2550             For example, if you want to contain named placeholder in join clause,
2551             you can pass parameter by C option.
2552              
2553             join => ['inner join (select * from table2 where table2.key3 = :table2.key3)' .
2554             ' as table2 on table1.key1 = table2.key1']
2555              
2556             =item prefix
2557              
2558             prefix => 'SQL_CALC_FOUND_ROWS'
2559              
2560             Prefix of column clause
2561              
2562             select SQL_CALC_FOUND_ROWS title, author from book;
2563              
2564             =item join
2565              
2566             join => [
2567             'left outer join company on book.company_id = company_id',
2568             'left outer join location on company.location_id = location.id'
2569             ]
2570            
2571             Join clause. If column clause or where clause contain table name like "company.name",
2572             join clauses needed when SQL is created is used automatically.
2573              
2574             $dbi->select(
2575             table => 'book',
2576             column => ['company.location_id as location_id'],
2577             where => {'company.name' => 'Orange'},
2578             join => [
2579             'left outer join company on book.company_id = company.id',
2580             'left outer join location on company.location_id = location.id'
2581             ]
2582             );
2583              
2584             In above select, column and where clause contain "company" table,
2585             the following SQL is created
2586              
2587             select company.location_id as location_id
2588             from book
2589             left outer join company on book.company_id = company.id
2590             where company.name = ?;
2591              
2592             You can specify two table by yourself. This is useful when join parser can't parse
2593             the join clause correctly.
2594              
2595             $dbi->select(
2596             table => 'book',
2597             column => ['company.location_id as location_id'],
2598             where => {'company.name' => 'Orange'},
2599             join => [
2600             {
2601             clause => 'left outer join location on company.location_id = location.id',
2602             table => ['company', 'location']
2603             }
2604             ]
2605             );
2606              
2607             =item table
2608              
2609             table => 'book'
2610              
2611             Table name.
2612              
2613             =item where
2614            
2615             # (1) Hash reference
2616             where => {author => 'Ken', 'title' => ['Perl', 'Ruby']}
2617             # -> where author = 'Ken' and title in ('Perl', 'Ruby')
2618            
2619             # (2) DBIx::Custom::Where object
2620             where => $dbi->where(
2621             clause => ['and', ':author{=}', ':title{like}'],
2622             param => {author => 'Ken', title => '%Perl%'}
2623             )
2624             # -> where author = 'Ken' and title like '%Perl%'
2625            
2626             # (3) Array reference[where clause, parameters, join(optional)]
2627             where => [
2628             ['and', ':author{=}', ':title{like}'],
2629             {author => 'Ken', title => '%Perl%'},
2630             ["left outer join table2 on table1.key1 = table2.key1"]
2631             ]
2632             # -> where author = 'Ken' and title like '%Perl%'
2633            
2634             # (4) Array reference[String, Hash reference]
2635             where => [
2636             ':author{=} and :title{like}',
2637             {author => 'Ken', title => '%Perl%'}
2638             ]
2639             # -> where author = 'Ken' and title like '%Perl%'
2640            
2641             # (5) String
2642             where => 'title is null'
2643             # -> where title is null
2644              
2645             Where clause.
2646             See also L to know how to create where clause.
2647            
2648             =back
2649              
2650             =head2 type_rule
2651              
2652             $dbi->type_rule(
2653             into1 => {
2654             date => sub { ... },
2655             datetime => sub { ... }
2656             },
2657             into2 => {
2658             date => sub { ... },
2659             datetime => sub { ... }
2660             },
2661             from1 => {
2662             # DATE
2663             9 => sub { ... },
2664             # DATETIME or TIMESTAMP
2665             11 => sub { ... },
2666             }
2667             from2 => {
2668             # DATE
2669             9 => sub { ... },
2670             # DATETIME or TIMESTAMP
2671             11 => sub { ... },
2672             }
2673             );
2674              
2675             Filtering rule when data is send into and get from database.
2676             This has a little complex problem.
2677              
2678             In C and C you can specify
2679             type name as same as type name defined
2680             by create table, such as C or C.
2681              
2682             Note that type name and data type don't contain upper case.
2683             If these contain upper case character, you convert it to lower case.
2684              
2685             C is executed after C.
2686              
2687             Type rule of C and C is enabled on the following
2688             column name.
2689              
2690             =over 4
2691              
2692             =item 1. column name
2693              
2694             issue_date
2695             issue_datetime
2696              
2697             This need C option in each method.
2698              
2699             =item 2. table name and column name, separator is dot
2700              
2701             book.issue_date
2702             book.issue_datetime
2703              
2704             =back
2705              
2706             You get all type name used in database by C.
2707              
2708             print $dbi->available_typename;
2709              
2710             In C and C you specify data type, not type name.
2711             C is executed after C.
2712             You get all data type by C.
2713              
2714             print $dbi->available_datatype;
2715              
2716             You can also specify multiple types at once.
2717              
2718             $dbi->type_rule(
2719             into1 => [
2720             [qw/DATE DATETIME/] => sub { ... },
2721             ],
2722             );
2723              
2724             =head2 update
2725              
2726             $dbi->update({title => 'Perl'}, table => 'book', where => {id => 4});
2727              
2728             Execute update statement. First argument is update row data.
2729              
2730             If you want to set constant value to row data, use scalar reference
2731             as parameter value.
2732              
2733             {date => \"NOW()"}
2734              
2735             B
2736              
2737             C method use all of C method's options,
2738             and use the following new ones.
2739              
2740             =over 4
2741              
2742             =item prefix
2743              
2744             prefix => 'or replace'
2745              
2746             prefix before table name section
2747              
2748             update or replace book
2749              
2750             =item table
2751              
2752             table => 'book'
2753              
2754             Table name.
2755              
2756             =item where
2757              
2758             Same as C
2759              
2760             =item wrap
2761              
2762             wrap => {price => sub { "max($_[0])" }}
2763              
2764             placeholder wrapped string.
2765              
2766             If the following statement
2767              
2768             $dbi->update({price => 100}, table => 'book',
2769             {price => sub { "$_[0] + 5" }});
2770              
2771             is executed, the following SQL is executed.
2772              
2773             update book set price = ? + 5;
2774              
2775             =item mtime
2776              
2777             mtime => 'modified_time'
2778              
2779             Modified time column name. time row is updated is set to the column.
2780             default time format is C, which can be changed by
2781             C attribute.
2782              
2783             =back
2784              
2785             =head2 update_all
2786              
2787             $dbi->update_all({title => 'Perl'}, table => 'book', );
2788              
2789             Execute update statement for all rows.
2790             Options is same as C method.
2791              
2792             =over 4
2793              
2794             =item option
2795              
2796             option => {
2797             select => {
2798             append => '...'
2799             },
2800             insert => {
2801             prefix => '...'
2802             },
2803             update => {
2804             filter => {}
2805             }
2806             }
2807              
2808             If you want to pass option to each method,
2809             you can use C
2810              
2811             =over 4
2812              
2813             =item select_option
2814              
2815             select_option => {append => 'for update'}
2816              
2817             select method option,
2818             select method is used to check the row is already exists.
2819              
2820             =head2 show_datatype
2821              
2822             $dbi->show_datatype($table);
2823              
2824             Show data type of the columns of specified table.
2825              
2826             book
2827             title: 5
2828             issue_date: 91
2829              
2830             This data type is used in C's C and C.
2831              
2832             =head2 show_tables
2833              
2834             $dbi->show_tables;
2835              
2836             Show tables.
2837              
2838             =head2 show_typename
2839              
2840             $dbi->show_typename($table);
2841              
2842             Show type name of the columns of specified table.
2843              
2844             book
2845             title: varchar
2846             issue_date: date
2847              
2848             This type name is used in C's C and C.
2849              
2850             =head2 values_clause
2851              
2852             my $values_clause = $dbi->values_clause({title => 'a', age => 2});
2853              
2854             Create values clause.
2855              
2856             (title, author) values (title = :title, age = :age);
2857              
2858             You can use this in insert statement.
2859              
2860             my $insert_sql = "insert into book $values_clause";
2861              
2862             =head2 where
2863              
2864             my $where = $dbi->where;
2865             $where->clause(['and', 'title = :title', 'author = :author']);
2866             $where->param({title => 'Perl', author => 'Ken'});
2867             $where->join(['left join author on book.author = author.id]);
2868              
2869             Create a new L object.
2870             See L to know how to create where clause.
2871              
2872             =head1 ENVIRONMENTAL VARIABLES
2873              
2874             =head2 DBIX_CUSTOM_DEBUG
2875              
2876             If environment variable C is set to true,
2877             executed SQL and bind values are printed to STDERR.
2878              
2879             =head2 DBIX_CUSTOM_DEBUG_ENCODING
2880              
2881             DEBUG output encoding. Default to UTF-8.
2882              
2883             =head2 DBIX_CUSTOM_SUPPRESS_DEPRECATION
2884              
2885             $ENV{DBIX_CUSTOM_SUPPRESS_DEPRECATION} = '0.25';
2886              
2887             Suppress deprecation warnings before specified version.
2888              
2889             =head1 DEPRECATED FUNCTIONALITY
2890              
2891             L
2892              
2893             # Methods
2894             DBIx::Custom AUTOLOAD feature # will be removed at 2022/5/1
2895             DBIx::Custom::helper method # will be removed at 2022/5/1
2896             DBIx::Custom::update_or_insert method is DEPRECATED! # will be removed at 2022/5/1
2897             DBIx::Custom::count method # will be removed at 2022/5/1
2898             DBIx::Custom::select,update,delete method's primary_key option is DEPRECATED! # will be removed at 2022/5/1
2899             DBIx::Custom::select,update,delete method's id option is DEPRECATED! # will be removed at 2022/5/1
2900             DBIx::Custom::setup method is DEPRECATED! # will be removed at 2022/5/1
2901              
2902             L
2903            
2904             # Options
2905             kv method's multi option (from 0.28) # will be removed at 2018/3/1
2906              
2907             L
2908              
2909             DBIx::Custom::Model AUTOLOAD feature # will be removed at 2022/5/1
2910             DBIx::Custom::Model::helper method is DEPRECATED! # will be removed at 2022/5/1
2911             DBIx::Custom::Model::update_or_insert method is DEPRECATED! # will be removed at 2022/5/1
2912             DBIx::Custom::Model::count method # will be removed at 2022/5/1
2913             DBIx::Custom::Model::primary_key attribute is DEPRECATED! # will be removed at 2022/5/1
2914              
2915             =head1 BACKWARDS COMPATIBILITY POLICY
2916              
2917             If a feature is DEPRECATED, you can know it by DEPRECATED warnings.
2918             DEPRECATED feature is removed after C,
2919             but if at least one person use the feature and tell me that thing
2920             I extend one year each time he tell me it.
2921              
2922             DEPRECATION warnings can be suppressed by C
2923             environment variable.
2924              
2925             EXPERIMENTAL features will be changed or deleted without warnings.
2926              
2927             =head1 BUGS
2928              
2929             Please tell me bugs if you find bug.
2930              
2931             C<< >>
2932              
2933             L
2934              
2935             =head1 AUTHOR
2936              
2937             Yuki Kimoto, C<< >>
2938              
2939             =head1 COPYRIGHT & LICENSE
2940              
2941             Copyright 2009-2019 Yuki Kimoto, all rights reserved.
2942              
2943             This program is free software; you can redistribute it and/or modify it
2944             under the same terms as Perl itself.
2945              
2946             =cut