DBIx-Custom / lib / DBIx / Custom.pm /
Newer Older
1347 lines | 34.015kb
packaging one directory
yuki-kimoto authored on 2009-11-16
1
use 5.008001;
2

            
3
package DBIx::Custom;
4
use Object::Simple;
5

            
version 0.0901
yuki-kimoto authored on 2009-12-17
6
our $VERSION = '0.0901';
packaging one directory
yuki-kimoto authored on 2009-11-16
7

            
8
use Carp 'croak';
9
use DBI;
10
use DBIx::Custom::Result;
11
use DBIx::Custom::SQL::Template;
12

            
13

            
bind_filter argument is chan...
yuki-kimoto authored on 2009-11-19
14
### Accessors
packaging one directory
yuki-kimoto authored on 2009-11-16
15
sub user        : ClassObjectAttr { initialize => {clone => 'scalar'} }
16
sub password    : ClassObjectAttr { initialize => {clone => 'scalar'} }
17
sub data_source : ClassObjectAttr { initialize => {clone => 'scalar'} }
version 0.0901
yuki-kimoto authored on 2009-12-17
18

            
19
sub options : ClassObjectAttr {
20
    type       => 'hash',
21
    initialize => {clone => 'hash', default => sub { {} }}
22
}
23

            
24
sub database     : ClassObjectAttr { initialize => {clone => 'scalar'} }
25
sub host         : ClassObjectAttr { initialize => {clone => 'scalar'} }
26
sub port         : ClassObjectAttr { initialize => {clone => 'scalar'} }
packaging one directory
yuki-kimoto authored on 2009-11-16
27

            
28
sub bind_filter  : ClassObjectAttr { initialize => {clone => 'scalar'} }
29
sub fetch_filter : ClassObjectAttr { initialize => {clone => 'scalar'} }
30

            
version 0.0901
yuki-kimoto authored on 2009-12-17
31
sub no_bind_filters : ClassObjectAttr {
32
    type       => 'array',
33
    initialize => {clone => 'array', default => sub { [] }}
34
}
35

            
36
sub no_fetch_filters : ClassObjectAttr {
37
    type => 'array',
38
    initialize => {clone => 'array', default => sub { [] }}
39
}
packaging one directory
yuki-kimoto authored on 2009-11-16
40

            
41
sub filters : ClassObjectAttr {
42
    type => 'hash',
43
    deref => 1,
44
    initialize => {
45
        clone   => 'hash',
46
        default => sub { {} }
47
    }
48
}
49

            
50
sub formats : ClassObjectAttr {
51
    type => 'hash',
52
    deref => 1,
53
    initialize => {
54
        clone   => 'hash',
55
        default => sub { {} }
56
    }
57
}
58

            
59
sub result_class : ClassObjectAttr {
60
    initialize => {
61
        clone   => 'scalar',
62
        default => 'DBIx::Custom::Result'
63
    }
64
}
65

            
version 0.0901
yuki-kimoto authored on 2009-12-17
66
sub sql_tmpl : ClassObjectAttr {
packaging one directory
yuki-kimoto authored on 2009-11-16
67
    initialize => {
68
        clone   => sub {$_[0] ? $_[0]->clone : undef},
69
        default => sub {DBIx::Custom::SQL::Template->new}
70
    }
71
}
72

            
bind_filter argument is chan...
yuki-kimoto authored on 2009-11-19
73
sub dbh : Attr {}
packaging one directory
yuki-kimoto authored on 2009-11-16
74

            
75

            
76
### Methods
77

            
78
sub add_filter {
79
    my $invocant = shift;
80
    
81
    my %old_filters = $invocant->filters;
82
    my %new_filters = ref $_[0] eq 'HASH' ? %{$_[0]} : @_;
83
    $invocant->filters(%old_filters, %new_filters);
84
    return $invocant;
85
}
86

            
87
sub add_format{
88
    my $invocant = shift;
89
    
90
    my %old_formats = $invocant->formats;
91
    my %new_formats = ref $_[0] eq 'HASH' ? %{$_[0]} : @_;
92
    $invocant->formats(%old_formats, %new_formats);
93
    return $invocant;
94
}
95

            
96
sub _auto_commit {
97
    my $self = shift;
98
    
99
    croak("Not yet connect to database") unless $self->dbh;
100
    
101
    if (@_) {
102
        $self->dbh->{AutoCommit} = $_[0];
103
        return $self;
104
    }
105
    return $self->dbh->{AutoCommit};
106
}
107

            
108
sub connect {
109
    my $self = shift;
110
    my $data_source = $self->data_source;
111
    my $user        = $self->user;
112
    my $password    = $self->password;
version 0.0901
yuki-kimoto authored on 2009-12-17
113
    my $options     = $self->options;
packaging one directory
yuki-kimoto authored on 2009-11-16
114
    
115
    my $dbh = eval{DBI->connect(
116
        $data_source,
117
        $user,
118
        $password,
119
        {
120
            RaiseError => 1,
121
            PrintError => 0,
122
            AutoCommit => 1,
version 0.0901
yuki-kimoto authored on 2009-12-17
123
            %{$options || {} }
packaging one directory
yuki-kimoto authored on 2009-11-16
124
        }
125
    )};
126
    
127
    croak $@ if $@;
128
    
129
    $self->dbh($dbh);
130
    return $self;
131
}
132

            
133
sub DESTROY {
134
    my $self = shift;
135
    $self->disconnect if $self->connected;
136
}
137

            
138
sub connected {
139
    my $self = shift;
140
    return ref $self->{dbh} eq 'DBI::db';
141
}
142

            
143
sub disconnect {
144
    my $self = shift;
145
    if ($self->connected) {
146
        $self->dbh->disconnect;
147
        delete $self->{dbh};
148
    }
149
}
150

            
151
sub reconnect {
152
    my $self = shift;
153
    $self->disconnect if $self->connected;
154
    $self->connect;
155
}
156

            
157
sub prepare {
158
    my ($self, $sql) = @_;
159
    
160
    # Connect if not
161
    $self->connect unless $self->connected;
162
    
163
    # Prepare
164
    my $sth = eval{$self->dbh->prepare($sql)};
165
    
166
    # Error
167
    croak("$@<Your SQL>\n$sql") if $@;
168
    
169
    return $sth;
170
}
171

            
172
sub do{
173
    my ($self, $sql, @bind_values) = @_;
174
    
175
    # Connect if not
176
    $self->connect unless $self->connected;
177
    
178
    # Do
version 0.0901
yuki-kimoto authored on 2009-12-17
179
    my $affected = eval{$self->dbh->do($sql, @bind_values)};
packaging one directory
yuki-kimoto authored on 2009-11-16
180
    
181
    # Error
182
    if ($@) {
183
        my $error = $@;
184
        require Data::Dumper;
185
        
186
        my $bind_value_dump
187
          = Data::Dumper->Dump([\@bind_values], ['*bind_valuds']);
188
        
189
        croak("$error<Your SQL>\n$sql\n<Your bind values>\n$bind_value_dump\n");
190
    }
version 0.0901
yuki-kimoto authored on 2009-12-17
191
    
192
    return $affected;
packaging one directory
yuki-kimoto authored on 2009-11-16
193
}
194

            
195
sub create_query {
196
    my ($self, $template) = @_;
197
    my $class = ref $self;
198
    
199
    # Create query from SQL template
version 0.0901
yuki-kimoto authored on 2009-12-17
200
    my $sql_tmpl = $self->sql_tmpl;
packaging one directory
yuki-kimoto authored on 2009-11-16
201
    
202
    # Try to get cached query
fix timeformat tests
yuki-kimoto authored on 2009-11-23
203
    my $cached_query = $class->_query_caches->{$template};
packaging one directory
yuki-kimoto authored on 2009-11-16
204
    
205
    # Create query
fix timeformat tests
yuki-kimoto authored on 2009-11-23
206
    my $query;
207
    if ($query) {
208
        $query = $self->new(sql       => $cached_query->sql, 
209
                            key_infos => $cached_query->key_infos);
210
    }
211
    else {
version 0.0901
yuki-kimoto authored on 2009-12-17
212
        $query = eval{$sql_tmpl->create_query($template)};
packaging one directory
yuki-kimoto authored on 2009-11-16
213
        croak($@) if $@;
214
        
215
        $class->_add_query_cache($template, $query);
216
    }
217
    
218
    # Connect if not
219
    $self->connect unless $self->connected;
220
    
221
    # Prepare statement handle
222
    my $sth = $self->prepare($query->{sql});
223
    
224
    # Set statement handle
225
    $query->sth($sth);
226
    
227
    # Set bind filter
228
    $query->bind_filter($self->bind_filter);
229
    
230
    # Set no filter keys when binding
231
    $query->no_bind_filters($self->no_bind_filters);
232
    
233
    # Set fetch filter
234
    $query->fetch_filter($self->fetch_filter);
235
    
236
    # Set no filter keys when fetching
237
    $query->no_fetch_filters($self->no_fetch_filters);
238
    
239
    return $query;
240
}
241

            
version 0.0901
yuki-kimoto authored on 2009-12-17
242
sub query{
packaging one directory
yuki-kimoto authored on 2009-11-16
243
    my ($self, $query, $params)  = @_;
244
    $params ||= {};
245
    
246
    # First argument is SQL template
247
    if (!ref $query) {
248
        my $template = $query;
249
        $query = $self->create_query($template);
250
        my $query_edit_cb = $_[3];
251
        $query_edit_cb->($query) if ref $query_edit_cb eq 'CODE';
252
    }
253
    
254
    # Create bind value
255
    my $bind_values = $self->_build_bind_values($query, $params);
256
    
257
    # Execute
version 0.0901
yuki-kimoto authored on 2009-12-17
258
    my $sth      = $query->sth;
259
    my $affected = eval{$sth->execute(@$bind_values)};
packaging one directory
yuki-kimoto authored on 2009-11-16
260
    
261
    # Execute error
262
    if (my $execute_error = $@) {
263
        require Data::Dumper;
264
        my $sql              = $query->{sql} || '';
265
        my $key_infos_dump   = Data::Dumper->Dump([$query->key_infos], ['*key_infos']);
266
        my $params_dump      = Data::Dumper->Dump([$params], ['*params']);
267
        
268
        croak("$execute_error" . 
269
              "<Your SQL>\n$sql\n" . 
270
              "<Your parameters>\n$params_dump");
271
    }
272
    
273
    # Return resultset if select statement is executed
274
    if ($sth->{NUM_OF_FIELDS}) {
275
        
276
        # Get result class
277
        my $result_class = $self->result_class;
278
        
279
        # Create result
280
        my $result = $result_class->new({
bind_filter argument is chan...
yuki-kimoto authored on 2009-11-19
281
            _dbi             => $self,
packaging one directory
yuki-kimoto authored on 2009-11-16
282
            sth              => $sth,
283
            fetch_filter     => $query->fetch_filter,
284
            no_fetch_filters => $query->no_fetch_filters
285
        });
286
        return $result;
287
    }
version 0.0901
yuki-kimoto authored on 2009-12-17
288
    return $affected;
packaging one directory
yuki-kimoto authored on 2009-11-16
289
}
290

            
291
sub _build_bind_values {
292
    my ($self, $query, $params) = @_;
293
    my $key_infos           = $query->key_infos;
294
    my $bind_filter         = $query->bind_filter;
295
    my $no_bind_filters_map = $query->_no_bind_filters_map || {};
296
    
297
    # binding values
298
    my @bind_values;
299
    
300
    # Create bind values
301
    KEY_INFOS :
302
    foreach my $key_info (@$key_infos) {
303
        # Set variable
304
        my $access_keys  = $key_info->{access_keys};
305
        my $original_key = $key_info->{original_key} || '';
306
        my $table        = $key_info->{table}        || '';
307
        my $column       = $key_info->{column}       || '';
308
        
309
        # Key is found?
310
        my $found;
311
        
312
        # Build bind values
313
        ACCESS_KEYS :
314
        foreach my $access_key (@$access_keys) {
315
            # Root parameter
316
            my $root_params = $params;
317
            
318
            # Search corresponding value
319
            for (my $i = 0; $i < @$access_key; $i++) {
320
                # Current key
321
                my $current_key = $access_key->[$i];
322
                
323
                # Last key
324
                if ($i == @$access_key - 1) {
325
                    # Key is array reference
326
                    if (ref $current_key eq 'ARRAY') {
327
                        # Filtering 
328
                        if ($bind_filter &&
329
                            !$no_bind_filters_map->{$original_key})
330
                        {
331
                            push @bind_values, 
332
                                 $bind_filter->($root_params->[$current_key->[0]], 
bind_filter argument is chan...
yuki-kimoto authored on 2009-11-19
333
                                                $original_key, $self,
334
                                                {table => $table, column => $column});
packaging one directory
yuki-kimoto authored on 2009-11-16
335
                        }
336
                        # Not filtering
337
                        else {
338
                            push @bind_values,
339
                                 scalar $root_params->[$current_key->[0]];
340
                        }
341
                    }
342
                    # Key is string
343
                    else {
344
                        # Key is not found
345
                        next ACCESS_KEYS
346
                          unless exists $root_params->{$current_key};
347
                        
348
                        # Filtering
349
                        if ($bind_filter &&
350
                            !$no_bind_filters_map->{$original_key}) 
351
                        {
352
                            push @bind_values,
353
                                 $bind_filter->($root_params->{$current_key},
bind_filter argument is chan...
yuki-kimoto authored on 2009-11-19
354
                                                $original_key, $self,
355
                                                {table => $table, column => $column});
packaging one directory
yuki-kimoto authored on 2009-11-16
356
                        }
357
                        # Not filtering
358
                        else {
359
                            push @bind_values,
360
                                 scalar $root_params->{$current_key};
361
                        }
362
                    }
363
                    
364
                    # Key is found
365
                    $found = 1;
366
                    next KEY_INFOS;
367
                }
368
                # First or middle key
369
                else {
370
                    # Key is array reference
371
                    if (ref $current_key eq 'ARRAY') {
372
                        # Go next key
373
                        $root_params = $root_params->[$current_key->[0]];
374
                    }
375
                    # Key is string
376
                    else {
377
                        # Not found
378
                        next ACCESS_KEYS
379
                          unless exists $root_params->{$current_key};
380
                        
381
                        # Go next key
382
                        $root_params = $root_params->{$current_key};
383
                    }
384
                }
385
            }
386
        }
387
        
388
        # Key is not found
389
        unless ($found) {
390
            require Data::Dumper;
391
            my $key_info_dump  = Data::Dumper->Dump([$key_info], ['*key_info']);
392
            my $params_dump    = Data::Dumper->Dump([$params], ['*params']);
393
            croak("Corresponding key is not found in your parameters\n" . 
394
                  "<Key information>\n$key_info_dump\n\n" .
395
                  "<Your parameters>\n$params_dump\n");
396
        }
397
    }
398
    return \@bind_values;
399
}
400

            
401
sub run_transaction {
402
    my ($self, $transaction) = @_;
403
    
404
    # Check auto commit
405
    croak("AutoCommit must be true before transaction start")
406
      unless $self->_auto_commit;
407
    
408
    # Auto commit off
409
    $self->_auto_commit(0);
410
    
411
    # Run transaction
bind_filter argument is chan...
yuki-kimoto authored on 2009-11-19
412
    eval {$transaction->($self)};
packaging one directory
yuki-kimoto authored on 2009-11-16
413
    
414
    # Tranzaction error
415
    my $transaction_error = $@;
416
    
417
    # Tranzaction is failed.
418
    if ($transaction_error) {
419
        # Rollback
420
        eval{$self->dbh->rollback};
421
        
422
        # Rollback error
423
        my $rollback_error = $@;
424
        
425
        # Auto commit on
426
        $self->_auto_commit(1);
427
        
428
        if ($rollback_error) {
429
            # Rollback is failed
430
            croak("${transaction_error}Rollback is failed : $rollback_error");
431
        }
432
        else {
433
            # Rollback is success
434
            croak("${transaction_error}Rollback is success");
435
        }
436
    }
437
    # Tranzaction is success
438
    else {
439
        # Commit
440
        eval{$self->dbh->commit};
441
        my $commit_error = $@;
442
        
443
        # Auto commit on
444
        $self->_auto_commit(1);
445
        
446
        # Commit is failed
447
        croak($commit_error) if $commit_error;
448
    }
449
}
450

            
451
sub last_insert_id {
452
    my $self = shift;
add Oracle, DB2, Pg,
yuki-kimoto authored on 2009-11-16
453
    my $class = ref $self;
454
    croak "'$class' do not suppert 'last_insert_id'";
packaging one directory
yuki-kimoto authored on 2009-11-16
455
}
456

            
version 0.0901
yuki-kimoto authored on 2009-12-17
457

            
458
sub create_table {
459
    my ($self, $table, @column_definitions) = @_;
460
    
461
    # Create table
462
    my $sql = "create table $table (\n";
463
    
464
    # Column definitions
465
    foreach my $column_definition (@column_definitions) {
466
        $sql .= "\t$column_definition,\n";
467
    }
468
    $sql =~ s/,\n$//;
469
    
470
    # End
471
    $sql .= "\n);";
472
    
473
    # Do query
474
    return $self->do($sql);
475
}
476

            
477
sub drop_table {
478
    my ($self, $table) = @_;
479
    
480
    # Drop table
481
    my $sql = "drop table $table;";
482

            
483
    # Do query
484
    return $self->do($sql);
485
}
486

            
packaging one directory
yuki-kimoto authored on 2009-11-16
487
sub insert {
insert, update, delete appnd...
yuki-kimoto authored on 2009-11-16
488
    my $self             = shift;
489
    my $table            = shift || '';
490
    my $insert_params    = shift || {};
491
    my $append_statement = shift unless ref $_[0];
492
    my $query_edit_cb    = shift;
packaging one directory
yuki-kimoto authored on 2009-11-16
493
    
494
    # Insert keys
495
    my @insert_keys = keys %$insert_params;
496
    
497
    # Not exists insert keys
498
    croak("Key-value pairs for insert must be specified to 'insert' second argument")
499
      unless @insert_keys;
500
    
501
    # Templte for insert
502
    my $template = "insert into $table {insert " . join(' ', @insert_keys) . '}';
insert, update, delete appnd...
yuki-kimoto authored on 2009-11-16
503
    $template .= " $append_statement" if $append_statement;
packaging one directory
yuki-kimoto authored on 2009-11-16
504
    # Create query
505
    my $query = $self->create_query($template);
506
    
507
    # Query edit callback must be code reference
508
    croak("Query edit callback must be code reference")
509
      if $query_edit_cb && ref $query_edit_cb ne 'CODE';
510
    
511
    # Query edit if need
512
    $query_edit_cb->($query) if $query_edit_cb;
513
    
514
    # Execute query
version 0.0901
yuki-kimoto authored on 2009-12-17
515
    my $ret_val = $self->query($query, $insert_params);
packaging one directory
yuki-kimoto authored on 2009-11-16
516
    
517
    return $ret_val;
518
}
519

            
520
sub update {
insert, update, delete appnd...
yuki-kimoto authored on 2009-11-16
521
    my $self             = shift;
522
    my $table            = shift || '';
523
    my $update_params    = shift || {};
524
    my $where_params     = shift || {};
525
    my $append_statement = shift unless ref $_[0];
526
    my $query_edit_cb    = shift;
527
    my $options          = shift;
packaging one directory
yuki-kimoto authored on 2009-11-16
528
    
529
    # Update keys
530
    my @update_keys = keys %$update_params;
531
    
532
    # Not exists update kyes
533
    croak("Key-value pairs for update must be specified to 'update' second argument")
534
      unless @update_keys;
535
    
536
    # Where keys
537
    my @where_keys = keys %$where_params;
538
    
539
    # Not exists where keys
540
    croak("Key-value pairs for where clause must be specified to 'update' third argument")
541
      if !@where_keys && !$options->{allow_update_all};
542
    
543
    # Update clause
544
    my $update_clause = '{update ' . join(' ', @update_keys) . '}';
545
    
546
    # Where clause
547
    my $where_clause = '';
548
    if (@where_keys) {
549
        $where_clause = 'where ';
550
        foreach my $where_key (@where_keys) {
551
            $where_clause .= "{= $where_key} and ";
552
        }
553
        $where_clause =~ s/ and $//;
554
    }
555
    
556
    # Template for update
557
    my $template = "update $table $update_clause $where_clause";
insert, update, delete appnd...
yuki-kimoto authored on 2009-11-16
558
    $template .= " $append_statement" if $append_statement;
packaging one directory
yuki-kimoto authored on 2009-11-16
559
    
560
    # Create query
561
    my $query = $self->create_query($template);
562
    
563
    # Query edit callback must be code reference
564
    croak("Query edit callback must be code reference")
565
      if $query_edit_cb && ref $query_edit_cb ne 'CODE';
566
    
567
    # Query edit if need
568
    $query_edit_cb->($query) if $query_edit_cb;
569
    
570
    # Rearrange parammeters
571
    my $params = {'#update' => $update_params, %$where_params};
572
    
573
    # Execute query
version 0.0901
yuki-kimoto authored on 2009-12-17
574
    my $ret_val = $self->query($query, $params);
packaging one directory
yuki-kimoto authored on 2009-11-16
575
    
576
    return $ret_val;
577
}
578

            
579
sub update_all {
insert, update, delete appnd...
yuki-kimoto authored on 2009-11-16
580
    my $self             = shift;
581
    my $table            = shift || '';
582
    my $update_params    = shift || {};
583
    my $append_statement = shift unless ref $_[0];
584
    my $query_edit_cb    = shift;
585
    my $options          = {allow_update_all => 1};
586
    
587
    return $self->update($table, $update_params, {}, $append_statement,
588
                         $query_edit_cb, $options);
packaging one directory
yuki-kimoto authored on 2009-11-16
589
}
590

            
591
sub delete {
insert, update, delete appnd...
yuki-kimoto authored on 2009-11-16
592
    my $self             = shift;
593
    my $table            = shift || '';
594
    my $where_params     = shift || {};
595
    my $append_statement = shift unless ref $_[0];
596
    my $query_edit_cb    = shift;
597
    my $options          = shift;
packaging one directory
yuki-kimoto authored on 2009-11-16
598
    
599
    # Where keys
600
    my @where_keys = keys %$where_params;
601
    
602
    # Not exists where keys
603
    croak("Key-value pairs for where clause must be specified to 'delete' second argument")
604
      if !@where_keys && !$options->{allow_delete_all};
605
    
606
    # Where clause
607
    my $where_clause = '';
608
    if (@where_keys) {
609
        $where_clause = 'where ';
610
        foreach my $where_key (@where_keys) {
611
            $where_clause .= "{= $where_key} and ";
612
        }
613
        $where_clause =~ s/ and $//;
614
    }
615
    
616
    # Template for delete
617
    my $template = "delete from $table $where_clause";
insert, update, delete appnd...
yuki-kimoto authored on 2009-11-16
618
    $template .= " $append_statement" if $append_statement;
packaging one directory
yuki-kimoto authored on 2009-11-16
619
    
620
    # Create query
621
    my $query = $self->create_query($template);
622
    
623
    # Query edit callback must be code reference
624
    croak("Query edit callback must be code reference")
625
      if $query_edit_cb && ref $query_edit_cb ne 'CODE';
626
    
627
    # Query edit if need
628
    $query_edit_cb->($query) if $query_edit_cb;
629
    
630
    # Execute query
version 0.0901
yuki-kimoto authored on 2009-12-17
631
    my $ret_val = $self->query($query, $where_params);
packaging one directory
yuki-kimoto authored on 2009-11-16
632
    
633
    return $ret_val;
634
}
635

            
636
sub delete_all {
insert, update, delete appnd...
yuki-kimoto authored on 2009-11-16
637
    my $self             = shift;
638
    my $table            = shift || '';
639
    my $append_statement = shift unless ref $_[0];
640
    my $query_edit_cb    = shift;
641
    my $options          = {allow_delete_all => 1};
642
    
643
    return $self->delete($table, {}, $append_statement, $query_edit_cb,
644
                         $options);
packaging one directory
yuki-kimoto authored on 2009-11-16
645
}
646

            
647
sub _select_usage { return << 'EOS' }
648
Your select arguments is wrong.
649
select usage:
650
$dbi->select(
651
    $table,                # must be string or array ref
version 0.0901
yuki-kimoto authored on 2009-12-17
652
    [@$columns],           # must be array reference. this can be ommited
653
    {%$where_params},      # must be hash reference.  this can be ommited
654
    $append_statement,     # must be string.          this can be ommited
655
    $query_edit_callback   # must be code reference.  this can be ommited
packaging one directory
yuki-kimoto authored on 2009-11-16
656
);
657
EOS
658

            
659
sub select {
660
    my $self = shift;
661
    
662
    # Check argument
663
    croak($self->_select_usage) unless @_;
664
    
665
    # Arguments
666
    my $tables = shift || '';
667
    $tables    = [$tables] unless ref $tables;
668
    
669
    my $columns          = ref $_[0] eq 'ARRAY' ? shift : [];
670
    my $where_params     = ref $_[0] eq 'HASH'  ? shift : {};
671
    my $append_statement = $_[0] && !ref $_[0]  ? shift : '';
672
    my $query_edit_cb    = shift if ref $_[0] eq 'CODE';
673
    
674
    # Check rest argument
675
    croak($self->_select_usage) if @_;
676
    
677
    # SQL template for select statement
678
    my $template = 'select ';
679
    
680
    # Join column clause
681
    if (@$columns) {
682
        foreach my $column (@$columns) {
683
            $template .= "$column, ";
684
        }
685
        $template =~ s/, $/ /;
686
    }
687
    else {
688
        $template .= '* ';
689
    }
690
    
691
    # Join table
692
    $template .= 'from ';
693
    foreach my $table (@$tables) {
694
        $template .= "$table, ";
695
    }
696
    $template =~ s/, $/ /;
697
    
698
    # Where clause keys
699
    my @where_keys = keys %$where_params;
700
    
701
    # Join where clause
702
    if (@where_keys) {
703
        $template .= 'where ';
704
        foreach my $where_key (@where_keys) {
705
            $template .= "{= $where_key} and ";
706
        }
707
    }
708
    $template =~ s/ and $//;
709
    
710
    # Append something to last of statement
711
    if ($append_statement =~ s/^where //) {
712
        if (@where_keys) {
713
            $template .= " and $append_statement";
714
        }
715
        else {
716
            $template .= " where $append_statement";
717
        }
718
    }
719
    else {
720
        $template .= " $append_statement";
721
    }
722
    
723
    # Create query
724
    my $query = $self->create_query($template);
725
    
726
    # Query edit
727
    $query_edit_cb->($query) if $query_edit_cb;
728
    
729
    # Execute query
version 0.0901
yuki-kimoto authored on 2009-12-17
730
    my $result = $self->query($query, $where_params);
packaging one directory
yuki-kimoto authored on 2009-11-16
731
    
732
    return $result;
733
}
734

            
735
sub _query_caches     : ClassAttr { type => 'hash',
736
                                    auto_build => sub {shift->_query_caches({}) } }
737
                                    
738
sub _query_cache_keys : ClassAttr { type => 'array',
739
                                    auto_build => sub {shift->_query_cache_keys([])} }
740
                                    
741
sub query_cache_max   : ClassAttr { auto_build => sub {shift->query_cache_max(50)} }
742

            
743
sub _add_query_cache {
744
    my ($class, $template, $query) = @_;
745
    my $query_cache_keys = $class->_query_cache_keys;
746
    my $query_caches     = $class->_query_caches;
747
    
748
    return $class if $query_caches->{$template};
749
    
750
    $query_caches->{$template} = $query;
751
    push @$query_cache_keys, $template;
752
    
753
    my $overflow = @$query_cache_keys - $class->query_cache_max;
754
    
755
    for (my $i = 0; $i < $overflow; $i++) {
756
        my $template = shift @$query_cache_keys;
757
        delete $query_caches->{$template};
758
    }
759
    
760
    return $class;
761
}
762

            
763
sub filter_off {
764
    my $self = shift;
765
    
766
    # filter off
767
    $self->bind_filter(undef);
768
    $self->fetch_filter(undef);
769
    
770
    return $self;
771
}
772

            
773
Object::Simple->build_class;
774

            
775
=head1 NAME
776

            
version 0.0901
yuki-kimoto authored on 2009-12-17
777
DBIx::Custom - Customizable DBI
packaging one directory
yuki-kimoto authored on 2009-11-16
778

            
version 0.0901
yuki-kimoto authored on 2009-12-17
779
=head1 VERSION
packaging one directory
yuki-kimoto authored on 2009-11-16
780

            
version 0.0901
yuki-kimoto authored on 2009-12-17
781
Version 0.0801
packaging one directory
yuki-kimoto authored on 2009-11-16
782

            
version 0.0901
yuki-kimoto authored on 2009-12-17
783
=head1 SYNOPSYS
784
    
785
    # New
786
    my $dbi = DBIx::Custom->new(data_source => "dbi:mysql:database=books"
787
                                user => 'ken', password => '!LFKD%$&');
788
    
789
    # Query
790
    $dbi->query("select title from books");
791
    
792
    # Query with parameters
793
    $dbi->query("select id from books where {= author} && {like title}",
794
                {author => 'ken', title => '%Perl%'});
795
    
796
    # Insert 
797
    $dbi->insert('books', {title => 'perl', author => 'Ken'});
798
    
799
    # Update 
800
    $dbi->update('books', {title => 'aaa', author => 'Ken'}, {id => 5});
801
    
802
    # Delete
803
    $dbi->delete('books', {author => 'Ken'});
804
    
805
    # Select
806
    $dbi->select('books');
807
    $dbi->select('books', {author => 'taro'}); 
808
    $dbi->select('books', [qw/author title/], {author => 'Ken'});
809
    $dbi->select('books', [qw/author title/], {author => 'Ken'},
810
                 'order by id limit 1');
packaging one directory
yuki-kimoto authored on 2009-11-16
811

            
bind_filter argument is chan...
yuki-kimoto authored on 2009-11-19
812
=head1 Accessors
packaging one directory
yuki-kimoto authored on 2009-11-16
813

            
814
=head2 user
815

            
bind_filter argument is chan...
yuki-kimoto authored on 2009-11-19
816
Set and get database user name
817
    
version 0.0901
yuki-kimoto authored on 2009-12-17
818
    $dbi  = $dbi->user('Ken');
819
    $user = $dbi->user;
bind_filter argument is chan...
yuki-kimoto authored on 2009-11-19
820
    
packaging one directory
yuki-kimoto authored on 2009-11-16
821
=head2 password
822

            
bind_filter argument is chan...
yuki-kimoto authored on 2009-11-19
823
Set and get database password
824
    
version 0.0901
yuki-kimoto authored on 2009-12-17
825
    $dbi      = $dbi->password('lkj&le`@s');
826
    $password = $dbi->password;
packaging one directory
yuki-kimoto authored on 2009-11-16
827

            
828
=head2 data_source
829

            
bind_filter argument is chan...
yuki-kimoto authored on 2009-11-19
830
Set and get database data source
831
    
version 0.0901
yuki-kimoto authored on 2009-12-17
832
    $dbi         = $dbi->data_source("dbi:mysql:dbname=$database");
833
    $data_source = $dbi->data_source;
packaging one directory
yuki-kimoto authored on 2009-11-16
834
    
version 0.0901
yuki-kimoto authored on 2009-12-17
835
If you know data source more, See also L<DBI>.
836

            
packaging one directory
yuki-kimoto authored on 2009-11-16
837
=head2 database
838

            
bind_filter argument is chan...
yuki-kimoto authored on 2009-11-19
839
Set and get database name
840

            
version 0.0901
yuki-kimoto authored on 2009-12-17
841
    $dbi      = $dbi->database('books');
842
    $database = $dbi->database;
packaging one directory
yuki-kimoto authored on 2009-11-16
843

            
add port and host method
yuki-kimoto authored on 2009-11-16
844
=head2 host
845

            
bind_filter argument is chan...
yuki-kimoto authored on 2009-11-19
846
Set and get host name
847

            
version 0.0901
yuki-kimoto authored on 2009-12-17
848
    $dbi  = $dbi->host('somehost.com');
849
    $host = $dbi->host;
bind_filter argument is chan...
yuki-kimoto authored on 2009-11-19
850

            
version 0.0901
yuki-kimoto authored on 2009-12-17
851
You can also set IP address like '127.03.45.12'.
add port and host method
yuki-kimoto authored on 2009-11-16
852

            
853
=head2 port
854

            
bind_filter argument is chan...
yuki-kimoto authored on 2009-11-19
855
Set and get port
856

            
version 0.0901
yuki-kimoto authored on 2009-12-17
857
    $dbi  = $dbi->port(1198);
858
    $port = $dbi->port;
add port and host method
yuki-kimoto authored on 2009-11-16
859

            
version 0.0901
yuki-kimoto authored on 2009-12-17
860
=head2 options
packaging one directory
yuki-kimoto authored on 2009-11-16
861

            
bind_filter argument is chan...
yuki-kimoto authored on 2009-11-19
862
Set and get DBI option
packaging one directory
yuki-kimoto authored on 2009-11-16
863

            
version 0.0901
yuki-kimoto authored on 2009-12-17
864
    $dbi     = $dbi->options({PrintError => 0, RaiseError => 1});
865
    $options = $dbi->options;
packaging one directory
yuki-kimoto authored on 2009-11-16
866

            
version 0.0901
yuki-kimoto authored on 2009-12-17
867
=head2 sql_tmpl
packaging one directory
yuki-kimoto authored on 2009-11-16
868

            
bind_filter argument is chan...
yuki-kimoto authored on 2009-11-19
869
Set and get SQL::Template object
packaging one directory
yuki-kimoto authored on 2009-11-16
870

            
version 0.0901
yuki-kimoto authored on 2009-12-17
871
    $dbi      = $dbi->sql_tmpl(DBIx::Cutom::SQL::Template->new);
872
    $sql_tmpl = $dbi->sql_tmpl;
packaging one directory
yuki-kimoto authored on 2009-11-16
873

            
version 0.0901
yuki-kimoto authored on 2009-12-17
874
See also L<DBIx::Custom::SQL::Template>.
packaging one directory
yuki-kimoto authored on 2009-11-16
875

            
bind_filter argument is chan...
yuki-kimoto authored on 2009-11-19
876
=head2 filters
packaging one directory
yuki-kimoto authored on 2009-11-16
877

            
bind_filter argument is chan...
yuki-kimoto authored on 2009-11-19
878
Set and get filters
packaging one directory
yuki-kimoto authored on 2009-11-16
879

            
version 0.0901
yuki-kimoto authored on 2009-12-17
880
    $dbi     = $dbi->filters({filter1 => sub { }, filter2 => sub {}});
881
    $filters = $dbi->filters;
packaging one directory
yuki-kimoto authored on 2009-11-16
882
    
version 0.0901
yuki-kimoto authored on 2009-12-17
883
This method is generally used to get a filter.
884

            
885
    $filter = $dbi->filters->{encode_utf8};
886

            
887
If you add filter, use add_filter method.
packaging one directory
yuki-kimoto authored on 2009-11-16
888

            
bind_filter argument is chan...
yuki-kimoto authored on 2009-11-19
889
=head2 formats
packaging one directory
yuki-kimoto authored on 2009-11-16
890

            
bind_filter argument is chan...
yuki-kimoto authored on 2009-11-19
891
Set and get formats
packaging one directory
yuki-kimoto authored on 2009-11-16
892

            
version 0.0901
yuki-kimoto authored on 2009-12-17
893
    $dbi     = $dbi->formats({format1 => sub { }, format2 => sub {}});
894
    $formats = $dbi->formats;
bind_filter argument is chan...
yuki-kimoto authored on 2009-11-19
895

            
version 0.0901
yuki-kimoto authored on 2009-12-17
896
This method is generally used to get a format.
bind_filter argument is chan...
yuki-kimoto authored on 2009-11-19
897

            
version 0.0901
yuki-kimoto authored on 2009-12-17
898
    $filter = $dbi->formats->{datetime};
899

            
900
If you add format, use add_format method.
packaging one directory
yuki-kimoto authored on 2009-11-16
901

            
902
=head2 bind_filter
903

            
bind_filter argument is chan...
yuki-kimoto authored on 2009-11-19
904
Set and get binding filter
packaging one directory
yuki-kimoto authored on 2009-11-16
905

            
version 0.0901
yuki-kimoto authored on 2009-12-17
906
    $dbi         = $dbi->bind_filter($bind_filter);
907
    $bind_filter = $dbi->bind_filter
packaging one directory
yuki-kimoto authored on 2009-11-16
908

            
version 0.0901
yuki-kimoto authored on 2009-12-17
909
The following is bind filter sample
bind_filter argument is chan...
yuki-kimoto authored on 2009-11-19
910

            
911
    $dbi->bind_filter(sub {
912
        my ($value, $key, $dbi, $infos) = @_;
913
        
914
        # edit $value
915
        
916
        return $value;
917
    });
packaging one directory
yuki-kimoto authored on 2009-11-16
918

            
version 0.0901
yuki-kimoto authored on 2009-12-17
919
Bind filter arguemts is
920

            
921
    1. $value : Value
922
    2. $key   : Key
923
    3. $dbi   : DBIx::Custom object
924
    4. $infos : {table => $table, column => $column}
925

            
packaging one directory
yuki-kimoto authored on 2009-11-16
926
=head2 fetch_filter
927

            
bind_filter argument is chan...
yuki-kimoto authored on 2009-11-19
928
Set and get Fetch filter
929

            
version 0.0901
yuki-kimoto authored on 2009-12-17
930
    $dbi          = $dbi->fetch_filter($fetch_filter);
931
    $fetch_filter = $dbi->fetch_filter;
bind_filter argument is chan...
yuki-kimoto authored on 2009-11-19
932

            
version 0.0901
yuki-kimoto authored on 2009-12-17
933
The following is fetch filter sample
packaging one directory
yuki-kimoto authored on 2009-11-16
934

            
bind_filter argument is chan...
yuki-kimoto authored on 2009-11-19
935
    $dbi->fetch_filter(sub {
936
        my ($value, $key, $dbi, $infos) = @_;
937
        
938
        # edit $value
939
        
940
        return $value;
941
    });
packaging one directory
yuki-kimoto authored on 2009-11-16
942

            
version 0.0901
yuki-kimoto authored on 2009-12-17
943
Bind filter arguemts is
944

            
945
    1. $value : Value
946
    2. $key   : Key
947
    3. $dbi   : DBIx::Custom object
948
    4. $infos : {type => $table, sth => $sth, index => $index}
949

            
packaging one directory
yuki-kimoto authored on 2009-11-16
950
=head2 no_bind_filters
951

            
bind_filter argument is chan...
yuki-kimoto authored on 2009-11-19
952
Set and get no filter keys when binding
953
    
version 0.0901
yuki-kimoto authored on 2009-12-17
954
    $dbi             = $dbi->no_bind_filters(qw/title author/);
955
    $no_bind_filters = $dbi->no_bind_filters;
packaging one directory
yuki-kimoto authored on 2009-11-16
956

            
957
=head2 no_fetch_filters
958

            
bind_filter argument is chan...
yuki-kimoto authored on 2009-11-19
959
Set and get no filter keys when fetching
960

            
version 0.0901
yuki-kimoto authored on 2009-12-17
961
    $dbi              = $dbi->no_fetch_filters(qw/title author/);
962
    $no_fetch_filters = $dbi->no_fetch_filters;
packaging one directory
yuki-kimoto authored on 2009-11-16
963

            
964
=head2 result_class
965

            
bind_filter argument is chan...
yuki-kimoto authored on 2009-11-19
966
Set and get resultset class
967

            
version 0.0901
yuki-kimoto authored on 2009-12-17
968
    $dbi          = $dbi->result_class('DBIx::Custom::Result');
packaging one directory
yuki-kimoto authored on 2009-11-16
969
    $result_class = $dbi->result_class;
970

            
971
=head2 dbh
972

            
bind_filter argument is chan...
yuki-kimoto authored on 2009-11-19
973
Get database handle
974
    
version 0.0901
yuki-kimoto authored on 2009-12-17
975
    $dbi = $dbi->dbh($dbh);
976
    $dbh = $dbi->dbh;
bind_filter argument is chan...
yuki-kimoto authored on 2009-11-19
977
    
978
=head2 query_cache_max
979

            
980
Set and get query cache max
981

            
version 0.0901
yuki-kimoto authored on 2009-12-17
982
    $class           = DBIx::Custom->query_cache_max(50);
983
    $query_cache_max = DBIx::Custom->query_cache_max;
984

            
985
Default value is 50
986

            
987
=head2 Accessor summary
988

            
989
                       Accessor type       Variable type
990
    user               class and object    scalar(string)
991
    password           class and object    scalar(string)
992
    data_source        class and object    scalar(string)
993
    database           class and object    scalar(string)
994
    host               class and object    scalar(string)
995

            
996
    port               class and object    scalar(int)
997
    options            class and object    hash(string)
998
    sql_tmpl           class and object    scalar(DBIx::Custom::SQL::Template)
999
    filters            class and object    hash(code ref)
1000
    formats            class and object    hash(string)
packaging one directory
yuki-kimoto authored on 2009-11-16
1001

            
version 0.0901
yuki-kimoto authored on 2009-12-17
1002
    bind_filter        class and object    scalar(code ref)
1003
    fetch_filter       class and object    scalar(code ref)
1004
    no_bind_filters    class and object    array(string)
1005
    no_fetch_filters   class and object    array(string)
1006
    result_class       class and object    scalar(string)
bind_filter argument is chan...
yuki-kimoto authored on 2009-11-19
1007

            
version 0.0901
yuki-kimoto authored on 2009-12-17
1008
    dbh                object              scalar(DBI)
1009
    query_cache_max    class               scalar(int)
bind_filter argument is chan...
yuki-kimoto authored on 2009-11-19
1010

            
1011
=head1 Methods
packaging one directory
yuki-kimoto authored on 2009-11-16
1012

            
1013
=head2 connect
1014

            
bind_filter argument is chan...
yuki-kimoto authored on 2009-11-19
1015
Connect to database
1016

            
packaging one directory
yuki-kimoto authored on 2009-11-16
1017
    $dbi->connect;
1018

            
1019
=head2 disconnect
1020

            
bind_filter argument is chan...
yuki-kimoto authored on 2009-11-19
1021
Disconnect database
1022

            
packaging one directory
yuki-kimoto authored on 2009-11-16
1023
    $dbi->disconnect;
1024

            
version 0.0901
yuki-kimoto authored on 2009-12-17
1025
If database is already disconnected, this method do nothing.
packaging one directory
yuki-kimoto authored on 2009-11-16
1026

            
1027
=head2 reconnect
1028

            
bind_filter argument is chan...
yuki-kimoto authored on 2009-11-19
1029
Reconnect to database
1030

            
packaging one directory
yuki-kimoto authored on 2009-11-16
1031
    $dbi->reconnect;
1032

            
1033
=head2 connected
1034

            
version 0.0901
yuki-kimoto authored on 2009-12-17
1035
Check if database is connected.
bind_filter argument is chan...
yuki-kimoto authored on 2009-11-19
1036
    
version 0.0901
yuki-kimoto authored on 2009-12-17
1037
    $is_connected = $dbi->connected;
packaging one directory
yuki-kimoto authored on 2009-11-16
1038
    
1039
=head2 filter_off
1040

            
bind_filter argument is chan...
yuki-kimoto authored on 2009-11-19
1041
bind_filter and fitch_filter off
1042
    
version 0.0901
yuki-kimoto authored on 2009-12-17
1043
    $dbi->filter_off
packaging one directory
yuki-kimoto authored on 2009-11-16
1044
    
version 0.0901
yuki-kimoto authored on 2009-12-17
1045
This method is equeal to
packaging one directory
yuki-kimoto authored on 2009-11-16
1046
    
bind_filter argument is chan...
yuki-kimoto authored on 2009-11-19
1047
    $dbi->bind_filter(undef);
1048
    $dbi->fetch_filter(undef);
packaging one directory
yuki-kimoto authored on 2009-11-16
1049

            
1050
=head2 add_filter
1051

            
bind_filter argument is chan...
yuki-kimoto authored on 2009-11-19
1052
Resist filter
packaging one directory
yuki-kimoto authored on 2009-11-16
1053
    
version 0.0901
yuki-kimoto authored on 2009-12-17
1054
    $dbi->add_filter($fname1 => $filter1, $fname => $filter2);
bind_filter argument is chan...
yuki-kimoto authored on 2009-11-19
1055
    
version 0.0901
yuki-kimoto authored on 2009-12-17
1056
The following is add_filter sample
1057

            
packaging one directory
yuki-kimoto authored on 2009-11-16
1058
    $dbi->add_filter(
1059
        encode_utf8 => sub {
bind_filter argument is chan...
yuki-kimoto authored on 2009-11-19
1060
            my ($value, $key, $dbi, $infos) = @_;
1061
            utf8::upgrade($value) unless Encode::is_utf8($value);
1062
            return encode('UTF-8', $value);
packaging one directory
yuki-kimoto authored on 2009-11-16
1063
        },
bind_filter argument is chan...
yuki-kimoto authored on 2009-11-19
1064
        decode_utf8 => sub {
1065
            my ($value, $key, $dbi, $infos) = @_;
1066
            return decode('UTF-8', $value)
packaging one directory
yuki-kimoto authored on 2009-11-16
1067
        }
1068
    );
1069

            
1070
=head2 add_format
1071

            
version 0.0901
yuki-kimoto authored on 2009-12-17
1072
Add format
bind_filter argument is chan...
yuki-kimoto authored on 2009-11-19
1073

            
version 0.0901
yuki-kimoto authored on 2009-12-17
1074
    $dbi->add_format($fname1 => $format, $fname2 => $format2);
bind_filter argument is chan...
yuki-kimoto authored on 2009-11-19
1075
    
version 0.0901
yuki-kimoto authored on 2009-12-17
1076
The following is add_format sample.
bind_filter argument is chan...
yuki-kimoto authored on 2009-11-19
1077

            
version 0.0901
yuki-kimoto authored on 2009-12-17
1078
    $dbi->add_format(date => '%Y:%m:%d', datetime => '%Y-%m-%d %H:%M:%S');
bind_filter argument is chan...
yuki-kimoto authored on 2009-11-19
1079

            
version 0.0901
yuki-kimoto authored on 2009-12-17
1080
=head2 create_query
bind_filter argument is chan...
yuki-kimoto authored on 2009-11-19
1081
    
version 0.0901
yuki-kimoto authored on 2009-12-17
1082
Create Query object parsing SQL template
bind_filter argument is chan...
yuki-kimoto authored on 2009-11-19
1083

            
version 0.0901
yuki-kimoto authored on 2009-12-17
1084
    my $query = $dbi->create_query("select * from authors where {= name} and {= age}");
bind_filter argument is chan...
yuki-kimoto authored on 2009-11-19
1085

            
version 0.0901
yuki-kimoto authored on 2009-12-17
1086
$query is <DBIx::Query> object. This is executed by query method as the following
bind_filter argument is chan...
yuki-kimoto authored on 2009-11-19
1087

            
version 0.0901
yuki-kimoto authored on 2009-12-17
1088
    $dbi->query($query, $params);
bind_filter argument is chan...
yuki-kimoto authored on 2009-11-19
1089

            
version 0.0901
yuki-kimoto authored on 2009-12-17
1090
If you know SQL template, see also L<DBIx::Custom::SQL::Template>.
bind_filter argument is chan...
yuki-kimoto authored on 2009-11-19
1091

            
version 0.0901
yuki-kimoto authored on 2009-12-17
1092
=head2 query
packaging one directory
yuki-kimoto authored on 2009-11-16
1093

            
version 0.0901
yuki-kimoto authored on 2009-12-17
1094
Query
bind_filter argument is chan...
yuki-kimoto authored on 2009-11-19
1095

            
version 0.0901
yuki-kimoto authored on 2009-12-17
1096
    $result = $dbi->query($template, $params);
packaging one directory
yuki-kimoto authored on 2009-11-16
1097

            
version 0.0901
yuki-kimoto authored on 2009-12-17
1098
The following is query sample
bind_filter argument is chan...
yuki-kimoto authored on 2009-11-19
1099

            
packaging one directory
yuki-kimoto authored on 2009-11-16
1100
    $result = $dbi->query("select * from authors where {= name} and {= age}", 
1101
                          {author => 'taro', age => 19});
1102
    
1103
    while (my @row = $result->fetch) {
1104
        # do something
1105
    }
1106

            
version 0.0901
yuki-kimoto authored on 2009-12-17
1107
If you now syntax of template, See also L<DBIx::Custom::SQL::Template>
1108

            
1109
Return value of query method is L<DBIx::Custom::Result> object
1110

            
1111
See also L<DBIx::Custom::Result>.
packaging one directory
yuki-kimoto authored on 2009-11-16
1112

            
1113
=head2 run_transaction
1114

            
bind_filter argument is chan...
yuki-kimoto authored on 2009-11-19
1115
Run transaction
1116

            
packaging one directory
yuki-kimoto authored on 2009-11-16
1117
    $dbi->run_transaction(sub {
bind_filter argument is chan...
yuki-kimoto authored on 2009-11-19
1118
        my $dbi = shift;
1119
        
packaging one directory
yuki-kimoto authored on 2009-11-16
1120
        # do something
1121
    });
1122

            
1123
If transaction is success, commit is execute. 
1124
If tranzation is died, rollback is execute.
1125

            
version 0.0901
yuki-kimoto authored on 2009-12-17
1126
=head2 create_table
1127

            
1128
Create table
1129

            
1130
    $dbi->create_table(
1131
        'books',
1132
        'name char(255)',
1133
        'age  int'
1134
    );
1135

            
1136
First argument is table name. Rest arguments is column definition.
1137

            
1138
=head2 drop_table
1139

            
1140
Drop table
1141

            
1142
    $dbi->drop_table('books');
1143

            
packaging one directory
yuki-kimoto authored on 2009-11-16
1144
=head2 insert
1145

            
update document
yuki-kimoto authored on 2009-11-19
1146
Insert row
bind_filter argument is chan...
yuki-kimoto authored on 2009-11-19
1147

            
version 0.0901
yuki-kimoto authored on 2009-12-17
1148
    $affected = $dbi->insert($table, \%$insert_params);
1149
    $affected = $dbi->insert($table, \%$insert_params, $append);
update document
yuki-kimoto authored on 2009-11-19
1150

            
version 0.0901
yuki-kimoto authored on 2009-12-17
1151
Retrun value is affected rows count
packaging one directory
yuki-kimoto authored on 2009-11-16
1152
    
version 0.0901
yuki-kimoto authored on 2009-12-17
1153
The following is insert sample.
1154

            
packaging one directory
yuki-kimoto authored on 2009-11-16
1155
    $dbi->insert('books', {title => 'Perl', author => 'Taro'});
1156

            
version 0.0901
yuki-kimoto authored on 2009-12-17
1157
You can add statement.
1158

            
1159
    $dbi->insert('books', {title => 'Perl', author => 'Taro'}, "some statement");
1160

            
packaging one directory
yuki-kimoto authored on 2009-11-16
1161
=head2 update
1162

            
update document
yuki-kimoto authored on 2009-11-19
1163
Update rows
1164

            
version 0.0901
yuki-kimoto authored on 2009-12-17
1165
    $affected = $dbi->update($table, \%update_params, \%where);
1166
    $affected = $dbi->update($table, \%update_params, \%where, $append);
1167

            
1168
Retrun value is affected rows count
update document
yuki-kimoto authored on 2009-11-19
1169

            
version 0.0901
yuki-kimoto authored on 2009-12-17
1170
The following is update sample.
bind_filter argument is chan...
yuki-kimoto authored on 2009-11-19
1171

            
packaging one directory
yuki-kimoto authored on 2009-11-16
1172
    $dbi->update('books', {title => 'Perl', author => 'Taro'}, {id => 5});
1173

            
version 0.0901
yuki-kimoto authored on 2009-12-17
1174
You can add statement.
1175

            
1176
    $dbi->update('books', {title => 'Perl', author => 'Taro'},
1177
                 {id => 5}, "some statement");
1178

            
packaging one directory
yuki-kimoto authored on 2009-11-16
1179
=head2 update_all
1180

            
bind_filter argument is chan...
yuki-kimoto authored on 2009-11-19
1181
Update all rows
1182

            
version 0.0901
yuki-kimoto authored on 2009-12-17
1183
    $affected = $dbi->update_all($table, \%updat_params);
update document
yuki-kimoto authored on 2009-11-19
1184

            
version 0.0901
yuki-kimoto authored on 2009-12-17
1185
Retrun value is affected rows count
1186

            
1187
The following is update_all sample.
update document
yuki-kimoto authored on 2009-11-19
1188

            
1189
    $dbi->update_all('books', {author => 'taro'});
packaging one directory
yuki-kimoto authored on 2009-11-16
1190

            
1191
=head2 delete
1192

            
update document
yuki-kimoto authored on 2009-11-19
1193
Delete rows
1194

            
version 0.0901
yuki-kimoto authored on 2009-12-17
1195
    $affected = $dbi->delete($table, \%where);
1196
    $affected = $dbi->delete($table, \%where, $append);
bind_filter argument is chan...
yuki-kimoto authored on 2009-11-19
1197

            
version 0.0901
yuki-kimoto authored on 2009-12-17
1198
Retrun value is affected rows count
packaging one directory
yuki-kimoto authored on 2009-11-16
1199
    
version 0.0901
yuki-kimoto authored on 2009-12-17
1200
The following is delete sample.
1201

            
update document
yuki-kimoto authored on 2009-11-19
1202
    $dbi->delete('books', {id => 5});
packaging one directory
yuki-kimoto authored on 2009-11-16
1203

            
version 0.0901
yuki-kimoto authored on 2009-12-17
1204
You can add statement.
1205

            
1206
    $dbi->delete('books', {id => 5}, "some statement");
1207

            
packaging one directory
yuki-kimoto authored on 2009-11-16
1208
=head2 delete_all
1209

            
bind_filter argument is chan...
yuki-kimoto authored on 2009-11-19
1210
Delete all rows
1211

            
version 0.0901
yuki-kimoto authored on 2009-12-17
1212
    $affected = $dbi->delete_all($table);
packaging one directory
yuki-kimoto authored on 2009-11-16
1213

            
version 0.0901
yuki-kimoto authored on 2009-12-17
1214
Retrun value is affected rows count
bind_filter argument is chan...
yuki-kimoto authored on 2009-11-19
1215

            
version 0.0901
yuki-kimoto authored on 2009-12-17
1216
The following is delete_all sample.
1217

            
1218
    $dbi->delete_all('books');
packaging one directory
yuki-kimoto authored on 2009-11-16
1219

            
1220
=head2 select
1221
    
update document
yuki-kimoto authored on 2009-11-19
1222
Select rows
bind_filter argument is chan...
yuki-kimoto authored on 2009-11-19
1223

            
version 0.0901
yuki-kimoto authored on 2009-12-17
1224
    $resut = $dbi->select(
packaging one directory
yuki-kimoto authored on 2009-11-16
1225
        $table,                # must be string or array;
version 0.0901
yuki-kimoto authored on 2009-12-17
1226
        \@$columns,            # must be array reference. this can be ommited
1227
        \%$where_params,       # must be hash reference.  this can be ommited
1228
        $append_statement,     # must be string.          this can be ommited
1229
        $query_edit_callback   # must be code reference.  this can be ommited
packaging one directory
yuki-kimoto authored on 2009-11-16
1230
    );
update document
yuki-kimoto authored on 2009-11-19
1231

            
version 0.0901
yuki-kimoto authored on 2009-12-17
1232
$reslt is L<DBIx::Custom::Result> object
update document
yuki-kimoto authored on 2009-11-19
1233

            
1234
The following is some select samples
1235

            
1236
    # select * from books;
1237
    $result = $dbi->select('books');
packaging one directory
yuki-kimoto authored on 2009-11-16
1238
    
update document
yuki-kimoto authored on 2009-11-19
1239
    # select * from books where title = 'Perl';
1240
    $result = $dbi->select('books', {title => 1});
1241
    
1242
    # select title, author from books where id = 1 for update;
1243
    $result = $dbi->select(
1244
        'books',              # table
1245
        ['title', 'author'],  # columns
1246
        {id => 1},            # where clause
1247
        'for update',         # append statement
1248
    );
1249

            
1250
You can join multi tables
1251
    
1252
    $result = $dbi->select(
1253
        ['table1', 'table2'],                # tables
1254
        ['table1.id as table1_id', 'title'], # columns (alias is ok)
1255
        {table1.id => 1},                    # where clase
1256
        "where table1.id = table2.id",       # join clause (must start 'where')
1257
    );
1258

            
1259
You can also edit query
1260
        
packaging one directory
yuki-kimoto authored on 2009-11-16
1261
    $dbi->select(
update document
yuki-kimoto authored on 2009-11-19
1262
        'books',
1263
        # column, where clause, append statement,
packaging one directory
yuki-kimoto authored on 2009-11-16
1264
        sub {
1265
            my $query = shift;
1266
            $query->bind_filter(sub {
1267
                # ...
1268
            });
1269
        }
update document
yuki-kimoto authored on 2009-11-19
1270
    }
1271

            
1272

            
1273
=head2 last_insert_id
1274

            
1275
Get last insert id
packaging one directory
yuki-kimoto authored on 2009-11-16
1276

            
update document
yuki-kimoto authored on 2009-11-19
1277
    $last_insert_id = $dbi->last_insert_id;
packaging one directory
yuki-kimoto authored on 2009-11-16
1278

            
update document
yuki-kimoto authored on 2009-11-19
1279
This method is implemented by subclass.
1280

            
version 0.0901
yuki-kimoto authored on 2009-12-17
1281
=head2 prepare
1282

            
1283
Prepare statement handle.
1284

            
1285
    $sth = $dbi->prepare('select * from books;');
1286

            
1287
This method is same as DBI prepare method.
1288

            
1289
See also L<DBI>.
1290

            
1291
=head2 do
1292

            
1293
Execute SQL
1294

            
1295
    $affected = $dbi->do('insert into books (title, author) values (?, ?)',
1296
                        'Perl', 'taro');
1297

            
1298
Retrun value is affected rows count.
1299

            
1300
This method is same as DBI do method.
1301

            
1302
See also L<DBI>
1303

            
1304
=head1 DBIx::Custom default configuration
packaging one directory
yuki-kimoto authored on 2009-11-16
1305

            
update document
yuki-kimoto authored on 2009-11-19
1306
DBIx::Custom have DBI object.
packaging one directory
yuki-kimoto authored on 2009-11-16
1307
This module is work well in the following DBI condition.
1308

            
1309
    1. AutoCommit is true
1310
    2. RaiseError is true
1311

            
1312
By default, Both AutoCommit and RaiseError is true.
1313
You must not change these mode not to damage your data.
1314

            
1315
If you change these mode, 
1316
you cannot get correct error message, 
1317
or run_transaction may fail.
1318

            
version 0.0901
yuki-kimoto authored on 2009-12-17
1319
=head1 Inheritance of DBIx::Custom
1320

            
1321
DBIx::Custom is customizable DBI.
1322
You can inherit DBIx::Custom and custumize attributes.
1323

            
1324
    package DBIx::Custom::Yours;
1325
    use base DBIx::Custom;
1326
    
1327
    my $class = __PACKAGE__;
1328
    
1329
    $class->user('your_name');
1330
    $class->password('your_password');
1331

            
packaging one directory
yuki-kimoto authored on 2009-11-16
1332
=head1 AUTHOR
1333

            
1334
Yuki Kimoto, C<< <kimoto.yuki at gmail.com> >>
1335

            
1336
Github L<http://github.com/yuki-kimoto>
1337

            
version 0.0901
yuki-kimoto authored on 2009-12-17
1338
I develope this module L<http://github.com/yuki-kimoto/DBIx-Custom>
1339

            
packaging one directory
yuki-kimoto authored on 2009-11-16
1340
=head1 COPYRIGHT & LICENSE
1341

            
1342
Copyright 2009 Yuki Kimoto, all rights reserved.
1343

            
1344
This program is free software; you can redistribute it and/or modify it
1345
under the same terms as Perl itself.
1346

            
1347
=cut