DBIx-Custom / lib / DBI / Custom.pm /
Newer Older
518 lines | 12.743kb
first commit
yuki-kimoto authored on 2009-10-13
1
package DBI::Custom;
2
use Object::Simple;
add test
yuki-kimoto authored on 2009-10-16
3

            
4
our $VERSION = '0.0101';
5

            
6
use Carp 'croak';
add some method
yuki-kimoto authored on 2009-10-14
7
use DBI;
add tests
yuki-kimoto authored on 2009-10-25
8
use DBI::Custom::SQL::Template;
add tests
yuki-kimoto authored on 2009-10-25
9
use DBI::Custom::Result;
cleanup
yuki-kimoto authored on 2009-10-29
10
use DBI::Custom::Query;
add tests
yuki-kimoto authored on 2009-10-25
11

            
12
### Class-Object Accessors
update document
yuki-kimoto authored on 2009-10-27
13
sub user        : ClassObjectAttr { initialize => {clone => 'scalar'} }
14
sub password    : ClassObjectAttr { initialize => {clone => 'scalar'} }
15
sub data_source : ClassObjectAttr { initialize => {clone => 'scalar'} }
add various thins
yuki-kimoto authored on 2009-10-29
16
sub database    : ClassObjectAttr { initialize => {clone => 'scalar'} }
catch up Object::Simple upda...
yuki-kimoto authored on 2009-10-26
17

            
cleanup
yuki-kimoto authored on 2009-10-29
18
sub dbi_options : ClassObjectAttr { initialize => {clone => 'hash', 
update document
yuki-kimoto authored on 2009-10-27
19
                                                  default => sub { {} } } }
catch up Object::Simple upda...
yuki-kimoto authored on 2009-10-26
20

            
update document
yuki-kimoto authored on 2009-10-27
21
sub bind_filter  : ClassObjectAttr { initialize => {clone => 'scalar'} }
22
sub fetch_filter : ClassObjectAttr { initialize => {clone => 'scalar'} }
catch up Object::Simple upda...
yuki-kimoto authored on 2009-10-26
23

            
add various thins
yuki-kimoto authored on 2009-10-29
24
sub no_filters   : ClassObjectAttr { initialize => {clone => 'array'} }
25

            
catch up Object::Simple upda...
yuki-kimoto authored on 2009-10-26
26
sub filters : ClassObjectAttr {
27
    type => 'hash',
28
    deref => 1,
29
    initialize => {
add tests
yuki-kimoto authored on 2009-10-25
30
        clone   => 'hash',
31
        default => sub { {} }
catch up Object::Simple upda...
yuki-kimoto authored on 2009-10-26
32
    }
33
}
first commit
yuki-kimoto authored on 2009-10-13
34

            
catch up Object::Simple upda...
yuki-kimoto authored on 2009-10-26
35
sub result_class : ClassObjectAttr {
36
    initialize => {
add tests
yuki-kimoto authored on 2009-10-25
37
        clone   => 'scalar',
38
        default => 'DBI::Custom::Result'
catch up Object::Simple upda...
yuki-kimoto authored on 2009-10-26
39
    }
40
}
cleanup
yuki-kimoto authored on 2009-10-14
41

            
catch up Object::Simple upda...
yuki-kimoto authored on 2009-10-26
42
sub sql_template : ClassObjectAttr {
43
    initialize => {
update document
yuki-kimoto authored on 2009-10-27
44
        clone   => sub {$_[0] ? $_[0]->clone : undef},
catch up Object::Simple upda...
yuki-kimoto authored on 2009-10-26
45
        default => sub {DBI::Custom::SQL::Template->new}
46
    }
47
}
cleanup
yuki-kimoto authored on 2009-10-15
48

            
add tests
yuki-kimoto authored on 2009-10-25
49
### Object Accessor
add tests
yuki-kimoto authored on 2009-10-18
50
sub dbh          : Attr {}
add tests
yuki-kimoto authored on 2009-10-25
51

            
52

            
53
### Methods
add various thins
yuki-kimoto authored on 2009-10-29
54

            
add tests
yuki-kimoto authored on 2009-10-25
55
# Add filter
56
sub add_filter {
57
    my $invocant = shift;
58
    
59
    my %old_filters = $invocant->filters;
60
    my %new_filters = ref $_[0] eq 'HASH' ? %{$_[0]} : @_;
61
    $invocant->filters(%old_filters, %new_filters);
update document
yuki-kimoto authored on 2009-10-27
62
    return $invocant;
add tests
yuki-kimoto authored on 2009-10-25
63
}
add various
yuki-kimoto authored on 2009-10-18
64

            
65
# Auto commit
update document
yuki-kimoto authored on 2009-10-27
66
sub _auto_commit {
add various
yuki-kimoto authored on 2009-10-18
67
    my $self = shift;
68
    
69
    croak("Cannot change AutoCommit becouse of not connected")
70
        unless $self->dbh;
71
    
72
    if (@_) {
73
        $self->dbh->{AutoCommit} = $_[0];
74
        return $self;
75
    }
76
    return $self->dbh->{AutoCommit};
77
}
add test
yuki-kimoto authored on 2009-10-16
78

            
add various things
yuki-kimoto authored on 2009-10-17
79
# Connect
add some method
yuki-kimoto authored on 2009-10-14
80
sub connect {
81
    my $self = shift;
update document
yuki-kimoto authored on 2009-10-27
82
    my $data_source = $self->data_source;
83
    my $user        = $self->user;
84
    my $password    = $self->password;
cleanup
yuki-kimoto authored on 2009-10-29
85
    my $dbi_options  = $self->dbi_options;
add test
yuki-kimoto authored on 2009-10-16
86
    
add some method
yuki-kimoto authored on 2009-10-14
87
    my $dbh = DBI->connect(
update document
yuki-kimoto authored on 2009-10-27
88
        $data_source,
89
        $user,
90
        $password,
add some method
yuki-kimoto authored on 2009-10-14
91
        {
92
            RaiseError => 1,
93
            PrintError => 0,
94
            AutoCommit => 1,
cleanup
yuki-kimoto authored on 2009-10-29
95
            %{$dbi_options || {} }
add some method
yuki-kimoto authored on 2009-10-14
96
        }
97
    );
98
    
99
    $self->dbh($dbh);
add various
yuki-kimoto authored on 2009-10-18
100
    return $self;
add some method
yuki-kimoto authored on 2009-10-14
101
}
first commit
yuki-kimoto authored on 2009-10-13
102

            
add tests
yuki-kimoto authored on 2009-10-25
103
# DESTROY
add tests
yuki-kimoto authored on 2009-10-18
104
sub DESTROY {
105
    my $self = shift;
add tests
yuki-kimoto authored on 2009-10-18
106
    $self->disconnect if $self->connected;
add tests
yuki-kimoto authored on 2009-10-18
107
}
108

            
add various things
yuki-kimoto authored on 2009-10-17
109
# Is connected?
110
sub connected {
111
    my $self = shift;
add tests
yuki-kimoto authored on 2009-10-18
112
    return exists $self->{dbh} && eval {$self->{dbh}->can('prepare')};
add various things
yuki-kimoto authored on 2009-10-17
113
}
114

            
115
# Disconnect
116
sub disconnect {
117
    my $self = shift;
add tests
yuki-kimoto authored on 2009-10-18
118
    if ($self->connected) {
add various things
yuki-kimoto authored on 2009-10-17
119
        $self->dbh->disconnect;
120
        delete $self->{dbh};
121
    }
122
}
123

            
124
# Reconnect
125
sub reconnect {
126
    my $self = shift;
add tests
yuki-kimoto authored on 2009-10-18
127
    $self->disconnect if $self->connected;
add various things
yuki-kimoto authored on 2009-10-17
128
    $self->connect;
129
}
130

            
try various
yuki-kimoto authored on 2009-10-21
131
# Run tranzaction
132
sub run_tranzaction {
133
    my ($self, $tranzaction) = @_;
134
    
update document
yuki-kimoto authored on 2009-10-27
135
    $self->_auto_commit(0);
try various
yuki-kimoto authored on 2009-10-21
136
    
137
    eval {
138
        $tranzaction->();
139
        $self->dbh->commit;
140
    };
141
    
142
    if ($@) {
143
        my $tranzaction_error = $@;
144
        
145
        $self->dbh->rollback or croak("$@ and rollback also failed");
146
        croak("$tranzaction_error");
147
    }
update document
yuki-kimoto authored on 2009-10-27
148
    $self->_auto_commit(1);
add tests
yuki-kimoto authored on 2009-10-18
149
}
150

            
add various thins
yuki-kimoto authored on 2009-10-29
151
sub create_query {
152
    my ($self, $template) = @_;
add test
yuki-kimoto authored on 2009-10-17
153
    
add various thins
yuki-kimoto authored on 2009-10-29
154
    # Create query from SQL template
155
    my $query = $self->sql_template->create_query($template);
add test
yuki-kimoto authored on 2009-10-17
156
    
add various thins
yuki-kimoto authored on 2009-10-29
157
    # Create Query object;
cleanup
yuki-kimoto authored on 2009-10-29
158
    $query = DBI::Custom::Query->new($query);
add various thins
yuki-kimoto authored on 2009-10-29
159
    
160
    # connect if not
161
    $self->connect unless $self->connected;
try varioud way
yuki-kimoto authored on 2009-10-17
162
    
add various thins
yuki-kimoto authored on 2009-10-29
163
    # Prepare statement handle
164
    my $sth = $self->dbh->prepare($query->{sql});
add tests
yuki-kimoto authored on 2009-10-18
165
    
add various thins
yuki-kimoto authored on 2009-10-29
166
    $query->sth($sth);
add tests
yuki-kimoto authored on 2009-10-18
167
    
add various thins
yuki-kimoto authored on 2009-10-29
168
    return $query;
169
}
170

            
171
sub execute {
172
    my ($self, $query, $params)  = @_;
try varioud way
yuki-kimoto authored on 2009-10-17
173
    
add various thins
yuki-kimoto authored on 2009-10-29
174
    # Create query if First argument is template
175
    if (!ref $query) {
176
        my $template = $query;
cleanup
yuki-kimoto authored on 2009-10-29
177
        $query = $self->create_query($template);
add various thins
yuki-kimoto authored on 2009-10-29
178
    }
add tests
yuki-kimoto authored on 2009-10-18
179
    
add various thins
yuki-kimoto authored on 2009-10-29
180
    # Set bind filter
181
    $query->bind_filter($self->bind_filter) unless $query->bind_filter;
add tests
yuki-kimoto authored on 2009-10-18
182
    
add various thins
yuki-kimoto authored on 2009-10-29
183
    # Set no filter keys
184
    $query->no_filters($self->no_filters) unless $query->no_filters;
add tests
yuki-kimoto authored on 2009-10-18
185
    
add various thins
yuki-kimoto authored on 2009-10-29
186
    # Create bind value
187
    my $bind_values = $self->_build_bind_values($query, $params);
add tests
yuki-kimoto authored on 2009-10-18
188
    
cleanup
yuki-kimoto authored on 2009-10-18
189
    # Execute
cleanup
yuki-kimoto authored on 2009-10-29
190
    my $sth = $query->sth;
191
    my $ret_val = $sth->execute(@$bind_values);
add various things
yuki-kimoto authored on 2009-10-17
192
    
cleanup
yuki-kimoto authored on 2009-10-18
193
    # Return resultset if select statement is executed
add various things
yuki-kimoto authored on 2009-10-17
194
    if ($sth->{NUM_OF_FIELDS}) {
195
        my $result_class = $self->result_class;
add various
yuki-kimoto authored on 2009-10-18
196
        my $result = $result_class->new({
197
            sth => $sth,
198
            fetch_filter => $self->fetch_filter
199
        });
add various things
yuki-kimoto authored on 2009-10-17
200
        return $result;
201
    }
add tests
yuki-kimoto authored on 2009-10-18
202
    return $ret_val;
add test
yuki-kimoto authored on 2009-10-17
203
}
204

            
add various thins
yuki-kimoto authored on 2009-10-29
205
sub _build_bind_values {
206
    my ($self, $query, $params) = @_;
cleanup
yuki-kimoto authored on 2009-10-29
207
    
208
    my $key_infos      = $query->key_infos;
209
    my $bind_filter    = $query->bind_filter;
210
    my $no_filters_map = $query->_no_filters_map || {};
cleanup
yuki-kimoto authored on 2009-10-18
211
    
add various thins
yuki-kimoto authored on 2009-10-29
212
    # binding values
213
    my @bind_values;
cleanup
yuki-kimoto authored on 2009-10-18
214
    
add various thins
yuki-kimoto authored on 2009-10-29
215
    # Filter and sdd bind values
cleanup
yuki-kimoto authored on 2009-10-29
216
    foreach my $key_info (@$key_infos) {
217
        my $filtering_key = $key_info->{key};
218
        my $access_keys = $key_info->{access_keys};
add various thins
yuki-kimoto authored on 2009-10-29
219
        
cleanup
yuki-kimoto authored on 2009-10-29
220
        my $original_key = $key_info->{original_key} || '';
221
        my $table        = $key_info->{table}        || '';
222
        my $column       = $key_info->{column}       || '';
add various thins
yuki-kimoto authored on 2009-10-29
223
        
224
        ACCESS_KEYS :
225
        foreach my $access_key (@$access_keys) {
226
            my $root_params = $params;
227
            for (my $i = 0; $i < @$access_key; $i++) {
228
                my $key = $access_key->[$i];
229
                
230
                croak("'access_keys' each value must be string or array reference")
231
                  unless (ref $key eq 'ARRAY' || ($key && !ref $key));
232
                
233
                if ($i == @$access_key - 1) {
234
                    if (ref $key eq 'ARRAY') {
235
                        if ($bind_filter && !$no_filters_map->{$original_key}) {
236
                            push @bind_values, $bind_filter->($root_params->[$key->[0]], $original_key, $table, $column);
237
                        }
238
                        else {
239
                            push @bind_values, scalar $root_params->[$key->[0]];
240
                        }
241
                    }
242
                    else {
243
                        next ACCESS_KEYS unless exists $root_params->{$key};
244
                        if ($bind_filter && !$no_filters_map->{$original_key}) {
245
                            push @bind_values, scalar $bind_filter->($root_params->{$key}, $original_key, $table, $column);
246
                        }
247
                        else {
248
                            push @bind_values, scalar $root_params->{$key};
249
                        }
250
                    }
251
                    return @bind_values;
252
                }
253
                
254
                if ($key eq 'ARRAY') {
255
                    $root_params = $root_params->[$key->[0]];
256
                }
257
                else {
258
                    next ACCESS_KEYS unless exists $root_params->{$key};
259
                    $root_params = $root_params->{$key};
260
                }
261
            }
262
        }
263
        croak("Cannot find key");
update document
yuki-kimoto authored on 2009-10-27
264
    }
add test
yuki-kimoto authored on 2009-10-17
265
}
266

            
add various thins
yuki-kimoto authored on 2009-10-29
267

            
add test
yuki-kimoto authored on 2009-10-17
268
Object::Simple->build_class;
269

            
first commit
yuki-kimoto authored on 2009-10-13
270
=head1 NAME
271

            
add test
yuki-kimoto authored on 2009-10-17
272
DBI::Custom - Customizable simple DBI
first commit
yuki-kimoto authored on 2009-10-13
273

            
274
=head1 VERSION
275

            
add test
yuki-kimoto authored on 2009-10-16
276
Version 0.0101
first commit
yuki-kimoto authored on 2009-10-13
277

            
278
=cut
279

            
280
=head1 SYNOPSIS
281

            
add test
yuki-kimoto authored on 2009-10-16
282
  my $dbi = DBI::Custom->new;
add various thins
yuki-kimoto authored on 2009-10-29
283
  
284
  my $query = $dbi->create_query($template);
285
  $dbi->execute($query);
first commit
yuki-kimoto authored on 2009-10-13
286

            
update document
yuki-kimoto authored on 2009-10-27
287
=head1 CLASS-OBJECT ACCESSORS
first commit
yuki-kimoto authored on 2009-10-13
288

            
update document
yuki-kimoto authored on 2009-10-27
289
=head2 user
290

            
291
    # Set and get database user name
292
    $self = $dbi->user($user);
293
    $user = $dbi->user;
294
    
295
    # Sample
296
    $dbi->user('taro');
297

            
298
=head2 password
299

            
300
    # Set and get database password
301
    $self     = $dbi->password($password);
302
    $password = $dbi->password;
303
    
304
    # Sample
305
    $dbi->password('lkj&le`@s');
306

            
307
=head2 data_source
308

            
309
    # Set and get database data source
310
    $self        = $dbi->data_source($data_soruce);
311
    $data_source = $dbi->data_source;
312
    
313
    # Sample(SQLite)
314
    $dbi->data_source(dbi:SQLite:dbname=$database);
315
    
316
    # Sample(MySQL);
317
    $dbi->data_source("dbi:mysql:dbname=$database");
318
    
319
    # Sample(PostgreSQL)
320
    $dbi->data_source("dbi:Pg:dbname=$database");
cleanup
yuki-kimoto authored on 2009-10-29
321
    
322
=head2 database
323

            
324
    # Set and get database name
325
    $self     = $dbi->database($database);
326
    $database = $dbi->database;
update document
yuki-kimoto authored on 2009-10-27
327

            
cleanup
yuki-kimoto authored on 2009-10-29
328
=head2 dbi_options
update document
yuki-kimoto authored on 2009-10-27
329

            
330
    # Set and get DBI option
cleanup
yuki-kimoto authored on 2009-10-29
331
    $self       = $dbi->dbi_options({$options => $value, ...});
332
    $dbi_options = $dbi->dbi_options;
update document
yuki-kimoto authored on 2009-10-27
333

            
334
    # Sample
cleanup
yuki-kimoto authored on 2009-10-29
335
    $dbi->dbi_options({PrintError => 0, RaiseError => 1});
update document
yuki-kimoto authored on 2009-10-27
336

            
cleanup
yuki-kimoto authored on 2009-10-29
337
dbi_options is used when you connect database by using connect.
update document
yuki-kimoto authored on 2009-10-27
338

            
339
=head2 sql_template
340

            
341
    # Set and get SQL::Template object
342
    $self         = $dbi->sql_template($sql_template);
343
    $sql_template = $dbi->sql_template;
344
    
345
    # Sample
346
    $dbi->sql_template(DBI::Cutom::SQL::Template->new);
347

            
348
=head2 filters
349

            
350
    # Set and get filters
351
    $self    = $dbi->filters($filters);
352
    $filters = $dbi->filters;
first commit
yuki-kimoto authored on 2009-10-13
353

            
add test
yuki-kimoto authored on 2009-10-16
354
=head2 bind_filter
first commit
yuki-kimoto authored on 2009-10-13
355

            
update document
yuki-kimoto authored on 2009-10-27
356
    # Set and get binding filter
357
    $self        = $dbi->bind_filter($bind_filter);
358
    $bind_filter = $dbi->bind_filter
first commit
yuki-kimoto authored on 2009-10-13
359

            
update document
yuki-kimoto authored on 2009-10-27
360
    # Sample
361
    $dbi->bind_filter($self->filters->{default_bind_filter});
362
    
first commit
yuki-kimoto authored on 2009-10-13
363

            
update document
yuki-kimoto authored on 2009-10-27
364
you can get DBI database handle if you need.
first commit
yuki-kimoto authored on 2009-10-13
365

            
add test
yuki-kimoto authored on 2009-10-16
366
=head2 fetch_filter
first commit
yuki-kimoto authored on 2009-10-13
367

            
update document
yuki-kimoto authored on 2009-10-27
368
    # Set and get Fetch filter
369
    $self         = $dbi->fetch_filter($fetch_filter);
370
    $fetch_filter = $dbi->fetch_filter;
first commit
yuki-kimoto authored on 2009-10-13
371

            
update document
yuki-kimoto authored on 2009-10-27
372
    # Sample
373
    $dbi->fetch_filter($self->filters->{default_fetch_filter});
add test
yuki-kimoto authored on 2009-10-16
374

            
cleanup
yuki-kimoto authored on 2009-10-29
375
=head2 no_filters
376

            
377
    # Set and get no filter keys
378
    $self       = $dbi->no_filters($no_filters);
379
    $no_filters = $dbi->no_filters;
380

            
update document
yuki-kimoto authored on 2009-10-27
381
=head2 result_class
first commit
yuki-kimoto authored on 2009-10-13
382

            
update document
yuki-kimoto authored on 2009-10-27
383
    # Set and get resultset class
384
    $self         = $dbi->result_class($result_class);
385
    $result_class = $dbi->result_class;
386
    
387
    # Sample
388
    $dbi->result_class('DBI::Custom::Result');
add test
yuki-kimoto authored on 2009-10-17
389

            
update document
yuki-kimoto authored on 2009-10-27
390
=head2 dbh
add test
yuki-kimoto authored on 2009-10-17
391

            
update document
yuki-kimoto authored on 2009-10-27
392
    # Get database handle
393
    $dbh = $self->dbh;
add test
yuki-kimoto authored on 2009-10-17
394

            
update document
yuki-kimoto authored on 2009-10-27
395
=head1 METHODS
add tests
yuki-kimoto authored on 2009-10-18
396

            
update document
yuki-kimoto authored on 2009-10-27
397
=head2 connect
398

            
399
    # Connect to database
400
    $self = $dbi->connect;
401
    
402
    # Sample
403
    $dbi = DBI::Custom->new(user => 'taro', password => 'lji8(', 
404
                            data_soruce => "dbi:mysql:dbname=$database");
405
    $dbi->connect;
add tests
yuki-kimoto authored on 2009-10-18
406

            
407
=head2 disconnect
408

            
update document
yuki-kimoto authored on 2009-10-27
409
    # Disconnect database
410
    $dbi->disconnect;
411

            
412
If database is already disconnected, this method do noting.
413

            
add tests
yuki-kimoto authored on 2009-10-18
414
=head2 reconnect
415

            
update document
yuki-kimoto authored on 2009-10-27
416
    # Reconnect
417
    $dbi->reconnect;
418

            
419
=head2 connected
420

            
421
    # Check connected
422
    $dbi->connected
423

            
424
=head2 add_filter
425

            
426
    # Add filter (hash ref or hash can be recieve)
427
    $self = $dbi->add_filter({$filter_name => $filter, ...});
428
    $self = $dbi->add_filter($filetr_name => $filter, ...);
429
    
430
    # Sample
431
    $dbi->add_filter(
432
        decode_utf8 => sub {
433
            my $value = shift;
434
            return Encode::decode('UTF-8', $value);
435
        },
436
        datetime_to_string => sub {
437
            my $value = shift;
438
            return $value->strftime('%Y-%m-%d %H:%M:%S')
439
        },
440
        default_bind_filter => sub {
441
            my ($value, $key, $filters) = @_;
442
            if (ref $value eq 'Time::Piece') {
443
                return $filters->{datetime_to_string}->($value);
444
            }
445
            else {
446
                return $filters->{decode_utf8}->($value);
447
            }
448
        },
449
        
450
        encode_utf8 => sub {
451
            my $value = shift;
452
            return Encode::encode('UTF-8', $value);
453
        },
454
        string_to_datetime => sub {
455
            my $value = shift;
456
            return DateTime::Format::MySQL->parse_datetime($value);
457
        },
458
        default_fetch_filter => sub {
459
            my ($value, $key, $filters, $type, $sth, $i) = @_;
460
            if ($type eq 'DATETIME') {
461
                return $self->filters->{string_to_datetime}->($value);
462
            }
463
            else {
464
                return $self->filters->{encode_utf8}->($value);
465
            }
466
        }
467
    );
468

            
469
add_filter add filter to filters
add tests
yuki-kimoto authored on 2009-10-18
470

            
cleanup
yuki-kimoto authored on 2009-10-29
471
=head2 create_query
472
    
473
    # Create Query object from SQL template
474
    my $query = $dbi->create_query($template);
475
    
476
=head2 execute
update document
yuki-kimoto authored on 2009-10-27
477

            
478
    # Parse SQL template and execute SQL
cleanup
yuki-kimoto authored on 2009-10-29
479
    $result = $dbi->query($query, $params);
480
    $result = $dbi->query($template, $params); # Shorcut
update document
yuki-kimoto authored on 2009-10-27
481
    
482
    # Sample
483
    $result = $dbi->query("select * from authors where {= name} && {= age}", 
484
                          {author => 'taro', age => 19});
485
    
486
    while (my @row = $result->fetch) {
487
        # do something
488
    }
489

            
490
See also L<DBI::Custom::SQL::Template>
491

            
cleanup
yuki-kimoto authored on 2009-10-22
492
=head2 run_tranzaction
first commit
yuki-kimoto authored on 2009-10-13
493

            
update document
yuki-kimoto authored on 2009-10-27
494
    # Run tranzaction
495
    $dbi->run_tranzaction(sub {
496
        # do something
497
    });
first commit
yuki-kimoto authored on 2009-10-13
498

            
update document
yuki-kimoto authored on 2009-10-27
499
If tranzaction is success, commit is execute. 
500
If tranzation is died, rollback is execute.
first commit
yuki-kimoto authored on 2009-10-13
501

            
cleanup
yuki-kimoto authored on 2009-10-29
502

            
503

            
add various
yuki-kimoto authored on 2009-10-18
504
=head1 AUTHOR
first commit
yuki-kimoto authored on 2009-10-13
505

            
add various
yuki-kimoto authored on 2009-10-18
506
Yuki Kimoto, C<< <kimoto.yuki at gmail.com> >>
first commit
yuki-kimoto authored on 2009-10-13
507

            
508
=head1 COPYRIGHT & LICENSE
509

            
510
Copyright 2009 Yuki Kimoto, all rights reserved.
511

            
512
This program is free software; you can redistribute it and/or modify it
513
under the same terms as Perl itself.
514

            
515

            
516
=cut
517

            
518
1; # End of DBI::Custom