DBIx-Custom / lib / DBIx / Custom.pm /
Newer Older
936 lines | 22.964kb
cleanup
yuki-kimoto authored on 2009-12-22
1
package DBIx::Custom;
2

            
3
use strict;
4
use warnings;
5

            
remove run_transaction().
yuki-kimoto authored on 2010-01-30
6
use base 'Object::Simple';
many change
yuki-kimoto authored on 2010-02-11
7

            
packaging one directory
yuki-kimoto authored on 2009-11-16
8
use Carp 'croak';
9
use DBI;
10
use DBIx::Custom::Result;
many many changes
yuki-kimoto authored on 2010-04-30
11
use DBIx::Custom::SQLTemplate;
cleanup
yuki-kimoto authored on 2010-02-11
12
use DBIx::Custom::Query;
update document
yuki-kimoto authored on 2010-05-27
13
use Encode qw/encode_utf8 decode_utf8/;
packaging one directory
yuki-kimoto authored on 2009-11-16
14

            
catch up with Object::Simple...
yuki-kimoto authored on 2010-01-18
15
__PACKAGE__->attr('dbh');
cleanup
yuki-kimoto authored on 2010-04-28
16
__PACKAGE__->attr([qw/user password data_source/]);
update document
yuki-kimoto authored on 2010-05-27
17
__PACKAGE__->attr([qw/default_query_filter default_fetch_filter/]);
packaging one directory
yuki-kimoto authored on 2009-11-16
18

            
removed register_format()
yuki-kimoto authored on 2010-05-26
19
__PACKAGE__->dual_attr('filters', default => sub { {} },
20
                                  inherit => 'hash_copy');
21
__PACKAGE__->register_filter(
update document
yuki-kimoto authored on 2010-05-27
22
    encode_utf8 => sub { encode_utf8($_[0]) },
23
    decode_utf8 => sub { decode_utf8($_[0]) }
removed register_format()
yuki-kimoto authored on 2010-05-26
24
);
packaging one directory
yuki-kimoto authored on 2009-11-16
25

            
cleanup
yuki-kimoto authored on 2010-04-28
26
__PACKAGE__->attr(result_class => 'DBIx::Custom::Result');
removed register_format()
yuki-kimoto authored on 2010-05-26
27
__PACKAGE__->attr(sql_template => sub { DBIx::Custom::SQLTemplate->new });
28

            
packaging one directory
yuki-kimoto authored on 2009-11-16
29
sub connect {
removed register_format()
yuki-kimoto authored on 2010-05-26
30
    my $proto = shift;
31
    
32
    # Create
33
    my $self = ref $proto ? $proto : $proto->new(@_);
update document
yuki-kimoto authored on 2010-01-30
34
    
35
    # Information
packaging one directory
yuki-kimoto authored on 2009-11-16
36
    my $data_source = $self->data_source;
37
    my $user        = $self->user;
38
    my $password    = $self->password;
39
    
update document
yuki-kimoto authored on 2010-01-30
40
    # Connect
select, insert, update, upda...
yuki-kimoto authored on 2010-06-14
41
    my $dbh = eval {DBI->connect(
packaging one directory
yuki-kimoto authored on 2009-11-16
42
        $data_source,
43
        $user,
44
        $password,
45
        {
46
            RaiseError => 1,
47
            PrintError => 0,
48
            AutoCommit => 1,
49
        }
50
    )};
51
    
update document
yuki-kimoto authored on 2010-01-30
52
    # Connect error
packaging one directory
yuki-kimoto authored on 2009-11-16
53
    croak $@ if $@;
54
    
update document
yuki-kimoto authored on 2010-01-30
55
    # Database handle
packaging one directory
yuki-kimoto authored on 2009-11-16
56
    $self->dbh($dbh);
update document
yuki-kimoto authored on 2010-01-30
57
    
packaging one directory
yuki-kimoto authored on 2009-11-16
58
    return $self;
59
}
60

            
61
sub disconnect {
62
    my $self = shift;
update document
yuki-kimoto authored on 2010-01-30
63
    
removed reconnect method
yuki-kimoto authored on 2010-05-28
64
    # Disconnect
select, insert, update, upda...
yuki-kimoto authored on 2010-06-14
65
    my $ret = eval { $self->dbh->disconnect };
66
    croak $@ if $@;
removed reconnect method
yuki-kimoto authored on 2010-05-28
67
    $self->dbh(undef);
update document
yuki-kimoto authored on 2010-01-30
68
    
select, insert, update, upda...
yuki-kimoto authored on 2010-06-14
69
    return $ret;
packaging one directory
yuki-kimoto authored on 2009-11-16
70
}
71

            
removed register_format()
yuki-kimoto authored on 2010-05-26
72
our %VALID_INSERT_ARGS = map { $_ => 1 } qw/table param append filter/;
cleanup insert
yuki-kimoto authored on 2010-04-28
73

            
packaging one directory
yuki-kimoto authored on 2009-11-16
74
sub insert {
select, insert, update, upda...
yuki-kimoto authored on 2010-06-14
75
    my ($self, %args) = @_;
removed register_format()
yuki-kimoto authored on 2010-05-26
76

            
cleanup insert
yuki-kimoto authored on 2010-04-28
77
    # Check arguments
select, insert, update, upda...
yuki-kimoto authored on 2010-06-14
78
    foreach my $name (keys %args) {
cleanup insert
yuki-kimoto authored on 2010-04-28
79
        croak "\"$name\" is invalid name"
80
          unless $VALID_INSERT_ARGS{$name};
81
    }
82
    
removed register_format()
yuki-kimoto authored on 2010-05-26
83
    # Arguments
select, insert, update, upda...
yuki-kimoto authored on 2010-06-14
84
    my $table  = $args{table} || '';
85
    my $param  = $args{param} || {};
86
    my $append = $args{append} || '';
87
    my $filter = $args{filter};
packaging one directory
yuki-kimoto authored on 2009-11-16
88
    
89
    # Insert keys
removed register_format()
yuki-kimoto authored on 2010-05-26
90
    my @insert_keys = keys %$param;
packaging one directory
yuki-kimoto authored on 2009-11-16
91
    
92
    # Not exists insert keys
93
    croak("Key-value pairs for insert must be specified to 'insert' second argument")
94
      unless @insert_keys;
95
    
96
    # Templte for insert
97
    my $template = "insert into $table {insert " . join(' ', @insert_keys) . '}';
removed register_format()
yuki-kimoto authored on 2010-05-26
98
    $template .= " $append" if $append;
packaging one directory
yuki-kimoto authored on 2009-11-16
99
    
100
    # Execute query
removed register_format()
yuki-kimoto authored on 2010-05-26
101
    my $ret_val = $self->execute($template, param  => $param, 
102
                                            filter => $filter);
packaging one directory
yuki-kimoto authored on 2009-11-16
103
    
104
    return $ret_val;
105
}
106

            
cleanup update and update_al...
yuki-kimoto authored on 2010-04-28
107
our %VALID_UPDATE_ARGS
removed register_format()
yuki-kimoto authored on 2010-05-26
108
  = map { $_ => 1 } qw/table param where append filter allow_update_all/;
cleanup update and update_al...
yuki-kimoto authored on 2010-04-28
109

            
packaging one directory
yuki-kimoto authored on 2009-11-16
110
sub update {
select, insert, update, upda...
yuki-kimoto authored on 2010-06-14
111
    my ($self, %args) = @_;
cleanup update and update_al...
yuki-kimoto authored on 2010-04-28
112
    
113
    # Check arguments
select, insert, update, upda...
yuki-kimoto authored on 2010-06-14
114
    foreach my $name (keys %args) {
cleanup update and update_al...
yuki-kimoto authored on 2010-04-28
115
        croak "\"$name\" is invalid name"
116
          unless $VALID_UPDATE_ARGS{$name};
117
    }
118
    
119
    # Arguments
select, insert, update, upda...
yuki-kimoto authored on 2010-06-14
120
    my $table            = $args{table} || '';
121
    my $param            = $args{param} || {};
122
    my $where            = $args{where} || {};
123
    my $append_statement = $args{append} || '';
124
    my $filter           = $args{filter};
125
    my $allow_update_all = $args{allow_update_all};
packaging one directory
yuki-kimoto authored on 2009-11-16
126
    
127
    # Update keys
removed register_format()
yuki-kimoto authored on 2010-05-26
128
    my @update_keys = keys %$param;
packaging one directory
yuki-kimoto authored on 2009-11-16
129
    
130
    # Not exists update kyes
131
    croak("Key-value pairs for update must be specified to 'update' second argument")
132
      unless @update_keys;
133
    
134
    # Where keys
removed register_format()
yuki-kimoto authored on 2010-05-26
135
    my @where_keys = keys %$where;
packaging one directory
yuki-kimoto authored on 2009-11-16
136
    
137
    # Not exists where keys
138
    croak("Key-value pairs for where clause must be specified to 'update' third argument")
cleanup update and update_al...
yuki-kimoto authored on 2010-04-28
139
      if !@where_keys && !$allow_update_all;
packaging one directory
yuki-kimoto authored on 2009-11-16
140
    
141
    # Update clause
142
    my $update_clause = '{update ' . join(' ', @update_keys) . '}';
143
    
144
    # Where clause
145
    my $where_clause = '';
simplify filtering system
yuki-kimoto authored on 2010-05-01
146
    my $new_where = {};
many change
yuki-kimoto authored on 2010-04-30
147
    
packaging one directory
yuki-kimoto authored on 2009-11-16
148
    if (@where_keys) {
149
        $where_clause = 'where ';
150
        foreach my $where_key (@where_keys) {
simplify filtering system
yuki-kimoto authored on 2010-05-01
151
            
152
            $where_clause .= "{= $where_key} and ";
packaging one directory
yuki-kimoto authored on 2009-11-16
153
        }
154
        $where_clause =~ s/ and $//;
155
    }
156
    
157
    # Template for update
158
    my $template = "update $table $update_clause $where_clause";
insert, update, delete appnd...
yuki-kimoto authored on 2009-11-16
159
    $template .= " $append_statement" if $append_statement;
packaging one directory
yuki-kimoto authored on 2009-11-16
160
    
161
    # Rearrange parammeters
removed register_format()
yuki-kimoto authored on 2010-05-26
162
    foreach my $wkey (@where_keys) {
simplify filtering system
yuki-kimoto authored on 2010-05-01
163
        
removed register_format()
yuki-kimoto authored on 2010-05-26
164
        if (exists $param->{$wkey}) {
165
            $param->{$wkey} = [$param->{$wkey}]
166
              unless ref $param->{$wkey} eq 'ARRAY';
simplify filtering system
yuki-kimoto authored on 2010-05-01
167
            
removed register_format()
yuki-kimoto authored on 2010-05-26
168
            push @{$param->{$wkey}}, $where->{$wkey};
simplify filtering system
yuki-kimoto authored on 2010-05-01
169
        }
add tests
yuki-kimoto authored on 2010-05-01
170
        else {
removed register_format()
yuki-kimoto authored on 2010-05-26
171
            $param->{$wkey} = $where->{$wkey};
add tests
yuki-kimoto authored on 2010-05-01
172
        }
simplify filtering system
yuki-kimoto authored on 2010-05-01
173
    }
packaging one directory
yuki-kimoto authored on 2009-11-16
174
    
175
    # Execute query
removed register_format()
yuki-kimoto authored on 2010-05-26
176
    my $ret_val = $self->execute($template, param  => $param, 
177
                                            filter => $filter);
packaging one directory
yuki-kimoto authored on 2009-11-16
178
    
179
    return $ret_val;
180
}
181

            
select, insert, update, upda...
yuki-kimoto authored on 2010-06-14
182
sub update_all { shift->update(allow_update_all => 1, @_) };
packaging one directory
yuki-kimoto authored on 2009-11-16
183

            
refactoring delete and delet...
yuki-kimoto authored on 2010-04-28
184
our %VALID_DELETE_ARGS
removed register_format()
yuki-kimoto authored on 2010-05-26
185
  = map { $_ => 1 } qw/table where append filter allow_delete_all/;
refactoring delete and delet...
yuki-kimoto authored on 2010-04-28
186

            
packaging one directory
yuki-kimoto authored on 2009-11-16
187
sub delete {
select, insert, update, upda...
yuki-kimoto authored on 2010-06-14
188
    my ($self, %args) = @_;
refactoring delete and delet...
yuki-kimoto authored on 2010-04-28
189
    
190
    # Check arguments
select, insert, update, upda...
yuki-kimoto authored on 2010-06-14
191
    foreach my $name (keys %args) {
refactoring delete and delet...
yuki-kimoto authored on 2010-04-28
192
        croak "\"$name\" is invalid name"
193
          unless $VALID_DELETE_ARGS{$name};
194
    }
195
    
196
    # Arguments
select, insert, update, upda...
yuki-kimoto authored on 2010-06-14
197
    my $table            = $args{table} || '';
198
    my $where            = $args{where} || {};
199
    my $append_statement = $args{append};
200
    my $filter           = $args{filter};
201
    my $allow_delete_all = $args{allow_delete_all};
packaging one directory
yuki-kimoto authored on 2009-11-16
202
    
203
    # Where keys
removed register_format()
yuki-kimoto authored on 2010-05-26
204
    my @where_keys = keys %$where;
packaging one directory
yuki-kimoto authored on 2009-11-16
205
    
206
    # Not exists where keys
207
    croak("Key-value pairs for where clause must be specified to 'delete' second argument")
refactoring delete and delet...
yuki-kimoto authored on 2010-04-28
208
      if !@where_keys && !$allow_delete_all;
packaging one directory
yuki-kimoto authored on 2009-11-16
209
    
210
    # Where clause
211
    my $where_clause = '';
212
    if (@where_keys) {
213
        $where_clause = 'where ';
removed register_format()
yuki-kimoto authored on 2010-05-26
214
        foreach my $wkey (@where_keys) {
215
            $where_clause .= "{= $wkey} and ";
packaging one directory
yuki-kimoto authored on 2009-11-16
216
        }
217
        $where_clause =~ s/ and $//;
218
    }
219
    
220
    # Template for delete
221
    my $template = "delete from $table $where_clause";
insert, update, delete appnd...
yuki-kimoto authored on 2009-11-16
222
    $template .= " $append_statement" if $append_statement;
packaging one directory
yuki-kimoto authored on 2009-11-16
223
    
224
    # Execute query
removed register_format()
yuki-kimoto authored on 2010-05-26
225
    my $ret_val = $self->execute($template, param  => $where, 
226
                                            filter => $filter);
packaging one directory
yuki-kimoto authored on 2009-11-16
227
    
228
    return $ret_val;
229
}
230

            
select, insert, update, upda...
yuki-kimoto authored on 2010-06-14
231
sub delete_all { shift->delete(allow_delete_all => 1, @_) }
packaging one directory
yuki-kimoto authored on 2009-11-16
232

            
refactoring select
yuki-kimoto authored on 2010-04-28
233
our %VALID_SELECT_ARGS
added commit method
yuki-kimoto authored on 2010-05-27
234
  = map { $_ => 1 } qw/table column where append relation filter param/;
refactoring select
yuki-kimoto authored on 2010-04-28
235

            
packaging one directory
yuki-kimoto authored on 2009-11-16
236
sub select {
select, insert, update, upda...
yuki-kimoto authored on 2010-06-14
237
    my ($self, %args) = @_;
packaging one directory
yuki-kimoto authored on 2009-11-16
238
    
refactoring select
yuki-kimoto authored on 2010-04-28
239
    # Check arguments
select, insert, update, upda...
yuki-kimoto authored on 2010-06-14
240
    foreach my $name (keys %args) {
refactoring select
yuki-kimoto authored on 2010-04-28
241
        croak "\"$name\" is invalid name"
242
          unless $VALID_SELECT_ARGS{$name};
243
    }
packaging one directory
yuki-kimoto authored on 2009-11-16
244
    
refactoring select
yuki-kimoto authored on 2010-04-28
245
    # Arguments
select, insert, update, upda...
yuki-kimoto authored on 2010-06-14
246
    my $tables = $args{table} || [];
removed register_format()
yuki-kimoto authored on 2010-05-26
247
    $tables = [$tables] unless ref $tables eq 'ARRAY';
select, insert, update, upda...
yuki-kimoto authored on 2010-06-14
248
    my $columns  = $args{column} || [];
249
    my $where    = $args{where} || {};
250
    my $relation = $args{relation};
251
    my $append   = $args{append};
252
    my $filter   = $args{filter};
253
    my $param    = $args{param} || {};
packaging one directory
yuki-kimoto authored on 2009-11-16
254
    
255
    # SQL template for select statement
256
    my $template = 'select ';
257
    
added commit method
yuki-kimoto authored on 2010-05-27
258
    # Column clause
packaging one directory
yuki-kimoto authored on 2009-11-16
259
    if (@$columns) {
260
        foreach my $column (@$columns) {
261
            $template .= "$column, ";
262
        }
263
        $template =~ s/, $/ /;
264
    }
265
    else {
266
        $template .= '* ';
267
    }
268
    
added commit method
yuki-kimoto authored on 2010-05-27
269
    # Table
packaging one directory
yuki-kimoto authored on 2009-11-16
270
    $template .= 'from ';
271
    foreach my $table (@$tables) {
272
        $template .= "$table, ";
273
    }
274
    $template =~ s/, $/ /;
275
    
added commit method
yuki-kimoto authored on 2010-05-27
276
    # Where clause
277
    my @where_keys = keys %$where;
packaging one directory
yuki-kimoto authored on 2009-11-16
278
    if (@where_keys) {
279
        $template .= 'where ';
280
        foreach my $where_key (@where_keys) {
compile success
yuki-kimoto authored on 2010-05-01
281
            $template .= "{= $where_key} and ";
packaging one directory
yuki-kimoto authored on 2009-11-16
282
        }
283
    }
284
    $template =~ s/ and $//;
285
    
added commit method
yuki-kimoto authored on 2010-05-27
286
    # Relation
287
    if ($relation) {
288
        $template .= @where_keys ? "and " : "where ";
289
        foreach my $rkey (keys %$relation) {
290
            $template .= "$rkey = " . $relation->{$rkey} . " and ";
packaging one directory
yuki-kimoto authored on 2009-11-16
291
        }
292
    }
added commit method
yuki-kimoto authored on 2010-05-27
293
    $template =~ s/ and $//;
294
    
295
    # Append some statement
296
    $template .= " $append" if $append;
packaging one directory
yuki-kimoto authored on 2009-11-16
297
    
298
    # Execute query
added commit method
yuki-kimoto authored on 2010-05-27
299
    my $result = $self->execute($template, param  => $where, 
removed register_format()
yuki-kimoto authored on 2010-05-26
300
                                           filter => $filter);
packaging one directory
yuki-kimoto authored on 2009-11-16
301
    
302
    return $result;
303
}
304

            
removed reconnect method
yuki-kimoto authored on 2010-05-28
305
sub create_query {
306
    my ($self, $template) = @_;
version 0.0901
yuki-kimoto authored on 2009-12-17
307
    
removed reconnect method
yuki-kimoto authored on 2010-05-28
308
    # Create query from SQL template
309
    my $sql_template = $self->sql_template;
removed register_format()
yuki-kimoto authored on 2010-05-26
310
    
removed reconnect method
yuki-kimoto authored on 2010-05-28
311
    # Get cached query
312
    my $cache = $self->{_cache}->{$template};
version 0.0901
yuki-kimoto authored on 2009-12-17
313
    
removed reconnect method
yuki-kimoto authored on 2010-05-28
314
    # Create query
315
    my $query;
316
    if ($cache) {
317
        $query = DBIx::Custom::Query->new(
318
            sql       => $cache->sql,
319
            columns   => $cache->columns
320
        );
321
    }
322
    else {
323
        $query = eval{$sql_template->create_query($template)};
324
        croak($@) if $@;
325
        
326
        $self->{_cache}->{$template} = $query
327
          unless $self->{_cache}->{$template};
328
    }
version 0.0901
yuki-kimoto authored on 2009-12-17
329
    
removed reconnect method
yuki-kimoto authored on 2010-05-28
330
    # Prepare statement handle
select, insert, update, upda...
yuki-kimoto authored on 2010-06-14
331
    my $sth = eval {$self->dbh->prepare($query->{sql})};
332
    croak $@ if $@;
renamed fetch_rows to fetch_...
yuki-kimoto authored on 2010-05-01
333
    
removed reconnect method
yuki-kimoto authored on 2010-05-28
334
    # Set statement handle
335
    $query->sth($sth);
336
    
337
    return $query;
338
}
339

            
340
our %VALID_EXECUTE_ARGS = map { $_ => 1 } qw/param filter/;
341

            
342
sub execute{
select, insert, update, upda...
yuki-kimoto authored on 2010-06-14
343
    my ($self, $query, %args)  = @_;
removed reconnect method
yuki-kimoto authored on 2010-05-28
344
    
345
    # Check arguments
select, insert, update, upda...
yuki-kimoto authored on 2010-06-14
346
    foreach my $name (keys %args) {
removed reconnect method
yuki-kimoto authored on 2010-05-28
347
        croak "\"$name\" is invalid name"
348
          unless $VALID_EXECUTE_ARGS{$name};
349
    }
350
    
select, insert, update, upda...
yuki-kimoto authored on 2010-06-14
351
    my $params = $args{param} || {};
removed reconnect method
yuki-kimoto authored on 2010-05-28
352
    
353
    # First argument is SQL template
354
    unless (ref $query eq 'DBIx::Custom::Query') {
355
        my $template;
356
        
357
        if (ref $query eq 'ARRAY') {
358
            $template = $query->[0];
359
        }
360
        else { $template = $query }
361
        
362
        $query = $self->create_query($template);
363
    }
364
    
select, insert, update, upda...
yuki-kimoto authored on 2010-06-14
365
    my $filter = $args{filter} || $query->filter || {};
removed reconnect method
yuki-kimoto authored on 2010-05-28
366
    
367
    # Create bind value
368
    my $bind_values = $self->_build_bind_values($query, $params, $filter);
369
    
370
    # Execute
371
    my $sth      = $query->sth;
select, insert, update, upda...
yuki-kimoto authored on 2010-06-14
372
    my $affected = eval {$sth->execute(@$bind_values)};
373
    croak $@ if $@;
removed reconnect method
yuki-kimoto authored on 2010-05-28
374
    
375
    # Return resultset if select statement is executed
376
    if ($sth->{NUM_OF_FIELDS}) {
377
        
378
        # Get result class
379
        my $result_class = $self->result_class;
380
        
381
        # Create result
382
        my $result = $result_class->new({
383
            sth             => $sth,
384
            default_filter  => $self->default_fetch_filter,
385
            filters         => $self->filters
386
        });
387
        return $result;
388
    }
389
    return $affected;
390
}
391

            
392
sub _build_bind_values {
393
    my ($self, $query, $params, $filter) = @_;
394
    
395
    # binding values
396
    my @bind_values;
397
    
398
    # Build bind values
399
    my $count = {};
400
    foreach my $column (@{$query->columns}) {
401
        
402
        croak "\"$column\" is not exists in params"
403
          unless exists $params->{$column};
404
        
405
        # Value
406
        my $value = ref $params->{$column} eq 'ARRAY'
407
                  ? $params->{$column}->[$count->{$column} || 0]
408
                  : $params->{$column};
409
        
410
        # Filter
411
        $filter ||= {};
412
        
413
        # Filter name
414
        my $fname = $filter->{$column} || $self->default_query_filter || '';
415
        
416
        my $filter_func;
417
        if ($fname) {
418
            
419
            if (ref $fname eq 'CODE') {
420
                $filter_func = $fname;
421
            }
422
            else {
423
                my $filters = $self->filters;
424
                croak "Not exists filter \"$fname\"" unless exists $filters->{$fname};
425
                $filter_func = $filters->{$fname};
426
            }            
427
        }
428
        
429
        push @bind_values, $filter_func
430
                         ? $filter_func->($value)
431
                         : $value;
432
        
433
        # Count up 
434
        $count->{$column}++;
435
    }
436
    
437
    return \@bind_values;
438
}
439

            
440
sub register_filter {
441
    my $invocant = shift;
442
    
443
    # Add filter
444
    my $filters = ref $_[0] eq 'HASH' ? $_[0] : {@_};
445
    $invocant->filters({%{$invocant->filters}, %$filters});
446
    
447
    return $invocant;
448
}
449

            
450
sub auto_commit {
451
    my $self = shift;
452
    
select, insert, update, upda...
yuki-kimoto authored on 2010-06-14
453
    # Not connected
454
    croak "Not connected" unless $self->dbh;
455
    
removed reconnect method
yuki-kimoto authored on 2010-05-28
456
    if (@_) {
457
        
458
        # Set AutoCommit
459
        $self->dbh->{AutoCommit} = $_[0];
460
        
461
        return $self;
462
    }
463
    return $self->dbh->{AutoCommit};
464
}
465

            
select, insert, update, upda...
yuki-kimoto authored on 2010-06-14
466
sub commit   { 
467
    my $ret = eval { shift->dbh->commit };
468
    croak $@ if $@;
469
    return $ret;
470
}
471
sub rollback {
472
    my $ret = eval { shift->dbh->rollback };
473
    croak $@ if $@;
474
    return $ret;
475
}
removed reconnect method
yuki-kimoto authored on 2010-05-28
476

            
477
sub DESTROY {
478
    my $self = shift;
479
    
480
    # Disconnect
481
    $self->disconnect if $self->dbh;
482
}
483

            
484
=head1 NAME
485

            
486
DBIx::Custom - DBI with hash parameter binding and filtering system
487

            
488
=head1 VERSION
489

            
490
Version 0.1503
491

            
492
=cut
493

            
494
our $VERSION = '0.1503';
495
$VERSION = eval $VERSION;
496

            
497
=head1 STABILITY
498

            
499
This module is not stable. Method name and functionality will be change.
500

            
501
=head1 SYNOPSYS
502
    
503
    # Connect
504
    my $dbi = DBIx::Custom->connect(data_source => "dbi:mysql:database=books",
505
                                    user => 'ken', password => '!LFKD%$&');
506
    
507
    # Disconnect
508
    $dbi->disconnect
509

            
510
    # Insert 
511
    $dbi->insert(table  => 'books',
512
                 param  => {title => 'perl', author => 'Ken'},
513
                 filter => {title => 'encode_utf8'});
514
    
515
    # Update 
516
    $dbi->update(table  => 'books', 
517
                 param  => {title => 'aaa', author => 'Ken'}, 
518
                 where  => {id => 5},
519
                 filter => {title => 'encode_utf8'});
520
    
521
    # Update all
522
    $dbi->update_all(table  => 'books',
523
                     param  => {title => 'aaa'},
524
                     filter => {title => 'encode_utf8'});
525
    
526
    # Delete
527
    $dbi->delete(table  => 'books',
528
                 where  => {author => 'Ken'},
529
                 filter => {title => 'encode_utf8'});
530
    
531
    # Delete all
532
    $dbi->delete_all(table => 'books');
533
    
534
    # Select
535
    my $result = $dbi->select(table => 'books');
renamed fetch_rows to fetch_...
yuki-kimoto authored on 2010-05-01
536
    
removed register_format()
yuki-kimoto authored on 2010-05-26
537
    # Select(more complex)
renamed fetch_rows to fetch_...
yuki-kimoto authored on 2010-05-01
538
    my $result = $dbi->select(
update document
yuki-kimoto authored on 2010-05-27
539
        table  => 'books',
540
        column => [qw/author title/],
541
        where  => {author => 'Ken'},
542
        append => 'order by id limit 1',
543
        filter => {tilte => 'encode_utf8'}
renamed fetch_rows to fetch_...
yuki-kimoto authored on 2010-05-01
544
    );
added commit method
yuki-kimoto authored on 2010-05-27
545
    
546
    # Select(Join table)
547
    my $result = $dbi->select(
548
        table => ['books', 'rental'],
549
        column => ['books.name as book_name']
550
        relation => {'books.id' => 'rental.book_id'}
551
    );
removed reconnect method
yuki-kimoto authored on 2010-05-28
552
    
removed register_format()
yuki-kimoto authored on 2010-05-26
553
    # Execute SQL
554
    $dbi->execute("select title from books");
555
    
556
    # Execute SQL with parameters and filter
557
    $dbi->execute("select id from books where {= author} && {like title}",
558
                  param  => {author => 'ken', title => '%Perl%'},
559
                  filter => {tilte => 'encode_utf8'});
removed reconnect method
yuki-kimoto authored on 2010-05-28
560

            
561
    # Create query and execute it
562
    my $query = $dbi->create_query(
563
        "select id from books where {= author} && {like title}"
564
    );
565
    $dbi->execute($query, param => {author => 'ken', title => '%Perl%'})
removed register_format()
yuki-kimoto authored on 2010-05-26
566
    
567
    # Default filter
568
    $dbi->default_query_filter('encode_utf8');
569
    $dbi->default_fetch_filter('decode_utf8');
570
    
571
    # Fetch
572
    while (my $row = $result->fetch) {
573
        # ...
574
    }
575
    
576
    # Fetch hash
577
    while (my $row = $result->fetch_hash) {
578
        
579
    }
580
    
update document
yuki-kimoto authored on 2010-05-27
581
    # DBI instance
582
    my $dbh = $dbi->dbh;
removed reconnect method
yuki-kimoto authored on 2010-05-28
583

            
584
=head1 DESCRIPTION
585

            
586
L<DBIx::Custom> is useful L<DBI> extention.
587
This module have hash parameter binding and filtering system.
588

            
589
Normally, binding parameter is array.
590
L<DBIx::Custom> enable you to pass binding parameter as hash.
591

            
592
This module also provide filtering system.
593
You can filter the binding parameter
594
or the value of fetching row.
595

            
596
And have useful method such as insert(), update(), delete(), and select().
597

            
598
=head2 Features
599

            
600
=over 4
601

            
602
=item 1. Hash parameter binding.
603

            
604
=item 2. Value filtering.
605

            
606
=item 3. Useful methos such as insert(), update(), delete(), and select().
607

            
608
=back
609

            
update document
yuki-kimoto authored on 2010-01-30
610
=head1 ATTRIBUTES
packaging one directory
yuki-kimoto authored on 2009-11-16
611

            
612
=head2 user
613

            
update document
yuki-kimoto authored on 2010-05-27
614
Database user name.
bind_filter argument is chan...
yuki-kimoto authored on 2009-11-19
615
    
version 0.0901
yuki-kimoto authored on 2009-12-17
616
    $dbi  = $dbi->user('Ken');
617
    $user = $dbi->user;
bind_filter argument is chan...
yuki-kimoto authored on 2009-11-19
618
    
packaging one directory
yuki-kimoto authored on 2009-11-16
619
=head2 password
620

            
update document
yuki-kimoto authored on 2010-05-27
621
Database password.
bind_filter argument is chan...
yuki-kimoto authored on 2009-11-19
622
    
version 0.0901
yuki-kimoto authored on 2009-12-17
623
    $dbi      = $dbi->password('lkj&le`@s');
624
    $password = $dbi->password;
packaging one directory
yuki-kimoto authored on 2009-11-16
625

            
626
=head2 data_source
627

            
update document
yuki-kimoto authored on 2010-05-27
628
Database data source.
bind_filter argument is chan...
yuki-kimoto authored on 2009-11-19
629
    
version 0.0901
yuki-kimoto authored on 2009-12-17
630
    $dbi         = $dbi->data_source("dbi:mysql:dbname=$database");
631
    $data_source = $dbi->data_source;
packaging one directory
yuki-kimoto authored on 2009-11-16
632
    
removed reconnect method
yuki-kimoto authored on 2010-05-28
633
=head2 dbh
packaging one directory
yuki-kimoto authored on 2009-11-16
634

            
removed reconnect method
yuki-kimoto authored on 2010-05-28
635
Database handle. This is the innstance of L<DBI>
636
    
637
    $dbi = $dbi->dbh($dbh);
638
    $dbh = $dbi->dbh;
packaging one directory
yuki-kimoto authored on 2009-11-16
639

            
removed reconnect method
yuki-kimoto authored on 2010-05-28
640
You can use all methods of L<DBI>
packaging one directory
yuki-kimoto authored on 2009-11-16
641

            
removed reconnect method
yuki-kimoto authored on 2010-05-28
642
    my $sth    = $dbi->dbh->prepare("...");
643
    my $errstr = $dbi->dbh->errstr;
644
    
bind_filter argument is chan...
yuki-kimoto authored on 2009-11-19
645
=head2 filters
packaging one directory
yuki-kimoto authored on 2009-11-16
646

            
update document
yuki-kimoto authored on 2010-01-30
647
Filters
packaging one directory
yuki-kimoto authored on 2009-11-16
648

            
update document
yuki-kimoto authored on 2010-05-27
649
    $dbi     = $dbi->filters({%filters});
version 0.0901
yuki-kimoto authored on 2009-12-17
650
    $filters = $dbi->filters;
651

            
update document
yuki-kimoto authored on 2010-05-27
652
encode_utf8 and decode_utf8 is set to this attribute by default.
version 0.0901
yuki-kimoto authored on 2009-12-17
653

            
update document
yuki-kimoto authored on 2010-05-27
654
    $encode_utf8 = $dbi->filters->{encode_utf8};
655
    $decode_utf8 = $dbi->filters->{decode_utf8};
packaging one directory
yuki-kimoto authored on 2009-11-16
656

            
rename bind_filter to query_...
yuki-kimoto authored on 2010-04-28
657
=head2 default_query_filter
packaging one directory
yuki-kimoto authored on 2009-11-16
658

            
update document
yuki-kimoto authored on 2010-05-27
659
Default query filter.
packaging one directory
yuki-kimoto authored on 2009-11-16
660

            
update document
yuki-kimoto authored on 2010-05-27
661
    $dbi                  = $dbi->default_query_filter('encode_utf8');
rename bind_filter to query_...
yuki-kimoto authored on 2010-04-28
662
    $default_query_filter = $dbi->default_query_filter
packaging one directory
yuki-kimoto authored on 2009-11-16
663

            
cleanup
yuki-kimoto authored on 2010-04-28
664
=head2 default_fetch_filter
packaging one directory
yuki-kimoto authored on 2009-11-16
665

            
update document
yuki-kimoto authored on 2010-05-27
666
Fetching filter.
bind_filter argument is chan...
yuki-kimoto authored on 2009-11-19
667

            
update document
yuki-kimoto authored on 2010-05-27
668
    $dbi                  = $dbi->default_fetch_filter('decode_utf8');
cleanup
yuki-kimoto authored on 2010-04-28
669
    $default_fetch_filter = $dbi->default_fetch_filter;
bind_filter argument is chan...
yuki-kimoto authored on 2009-11-19
670

            
packaging one directory
yuki-kimoto authored on 2009-11-16
671
=head2 result_class
672

            
update document
yuki-kimoto authored on 2010-05-27
673
Result class.
bind_filter argument is chan...
yuki-kimoto authored on 2009-11-19
674

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

            
update document
yuki-kimoto authored on 2010-05-27
678
L<DBIx::Custom::Result> is set to this attribute by default.
update document
yuki-kimoto authored on 2010-01-30
679

            
removed reconnect method
yuki-kimoto authored on 2010-05-28
680
=head2 sql_template
added commit method
yuki-kimoto authored on 2010-05-27
681

            
removed reconnect method
yuki-kimoto authored on 2010-05-28
682
SQLTemplate instance. sql_template attribute must be 
683
the instance of L<DBIx::Cutom::SQLTemplate> subclass.
added commit method
yuki-kimoto authored on 2010-05-27
684

            
removed reconnect method
yuki-kimoto authored on 2010-05-28
685
    $dbi          = $dbi->sql_template(DBIx::Cutom::SQLTemplate->new);
686
    $sql_template = $dbi->sql_template;
added commit method
yuki-kimoto authored on 2010-05-27
687

            
removed reconnect method
yuki-kimoto authored on 2010-05-28
688
the instance of DBIx::Cutom::SQLTemplate is set to 
689
this attribute by default.
added commit method
yuki-kimoto authored on 2010-05-27
690

            
removed reconnect method
yuki-kimoto authored on 2010-05-28
691
=head1 METHODS
added commit method
yuki-kimoto authored on 2010-05-27
692

            
removed reconnect method
yuki-kimoto authored on 2010-05-28
693
This class is L<Object::Simple> subclass.
694
You can use all methods of L<Object::Simple>
added commit method
yuki-kimoto authored on 2010-05-27
695

            
packaging one directory
yuki-kimoto authored on 2009-11-16
696
=head2 connect
697

            
update document
yuki-kimoto authored on 2010-05-27
698
Connect to database.
699
    
700
    my $dbi = DBIx::Custom->connect(data_source => "dbi:mysql:database=books",
701
                                    user => 'ken', password => '!LFKD%$&');
bind_filter argument is chan...
yuki-kimoto authored on 2009-11-19
702

            
update document
yuki-kimoto authored on 2010-05-27
703
"AutoCommit" and "RaiseError" option is true, 
704
and "PrintError" option is false by dfault.
packaging one directory
yuki-kimoto authored on 2009-11-16
705

            
706
=head2 disconnect
707

            
update document
yuki-kimoto authored on 2010-05-27
708
Disconnect database.
bind_filter argument is chan...
yuki-kimoto authored on 2009-11-19
709

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

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

            
714
=head2 insert
715

            
added commit method
yuki-kimoto authored on 2010-05-27
716
Insert row.
bind_filter argument is chan...
yuki-kimoto authored on 2009-11-19
717

            
removed register_format()
yuki-kimoto authored on 2010-05-26
718
    $affected = $dbi->insert(table  => $table, 
719
                             param  => {%param},
720
                             append => $append,
721
                             filter => {%filter});
update document
yuki-kimoto authored on 2009-11-19
722

            
added commit method
yuki-kimoto authored on 2010-05-27
723
Retruned value is affected rows count.
packaging one directory
yuki-kimoto authored on 2009-11-16
724
    
removed reconnect method
yuki-kimoto authored on 2010-05-28
725
Example:
version 0.0901
yuki-kimoto authored on 2009-12-17
726

            
removed register_format()
yuki-kimoto authored on 2010-05-26
727
    # insert
728
    $dbi->insert(table  => 'books', 
729
                 param  => {title => 'Perl', author => 'Taro'},
730
                 append => "some statement",
731
                 filter => {title => 'encode_utf8'})
version 0.0901
yuki-kimoto authored on 2009-12-17
732

            
packaging one directory
yuki-kimoto authored on 2009-11-16
733
=head2 update
734

            
added commit method
yuki-kimoto authored on 2010-05-27
735
Update rows.
update document
yuki-kimoto authored on 2009-11-19
736

            
removed register_format()
yuki-kimoto authored on 2010-05-26
737
    $affected = $dbi->update(table  => $table, 
738
                             param  => {%params},
739
                             where  => {%where},
740
                             append => $append,
741
                             filter => {%filter})
version 0.0901
yuki-kimoto authored on 2009-12-17
742

            
added commit method
yuki-kimoto authored on 2010-05-27
743
Retruned value is affected rows count
update document
yuki-kimoto authored on 2009-11-19
744

            
removed reconnect method
yuki-kimoto authored on 2010-05-28
745
Example:
bind_filter argument is chan...
yuki-kimoto authored on 2009-11-19
746

            
removed register_format()
yuki-kimoto authored on 2010-05-26
747
    #update
748
    $dbi->update(table  => 'books',
749
                 param  => {title => 'Perl', author => 'Taro'},
750
                 where  => {id => 5},
751
                 append => "some statement",
added commit method
yuki-kimoto authored on 2010-05-27
752
                 filter => {title => 'encode_utf8'});
version 0.0901
yuki-kimoto authored on 2009-12-17
753

            
packaging one directory
yuki-kimoto authored on 2009-11-16
754
=head2 update_all
755

            
added commit method
yuki-kimoto authored on 2010-05-27
756
Update all rows.
bind_filter argument is chan...
yuki-kimoto authored on 2009-11-19
757

            
removed register_format()
yuki-kimoto authored on 2010-05-26
758
    $affected = $dbi->update_all(table  => $table, 
759
                                 param  => {%params},
760
                                 filter => {%filter},
761
                                 append => $append);
update document
yuki-kimoto authored on 2009-11-19
762

            
added commit method
yuki-kimoto authored on 2010-05-27
763
Retruned value is affected rows count.
version 0.0901
yuki-kimoto authored on 2009-12-17
764

            
removed reconnect method
yuki-kimoto authored on 2010-05-28
765
Example:
update document
yuki-kimoto authored on 2009-11-19
766

            
removed register_format()
yuki-kimoto authored on 2010-05-26
767
    # update_all
768
    $dbi->update_all(table  => 'books', 
769
                     param  => {author => 'taro'},
770
                     filter => {author => 'encode_utf8'});
packaging one directory
yuki-kimoto authored on 2009-11-16
771

            
772
=head2 delete
773

            
added commit method
yuki-kimoto authored on 2010-05-27
774
Delete rows.
update document
yuki-kimoto authored on 2009-11-19
775

            
removed register_format()
yuki-kimoto authored on 2010-05-26
776
    $affected = $dbi->delete(table  => $table,
777
                             where  => {%where},
added commit method
yuki-kimoto authored on 2010-05-27
778
                             append => $append,
removed register_format()
yuki-kimoto authored on 2010-05-26
779
                             filter => {%filter});
bind_filter argument is chan...
yuki-kimoto authored on 2009-11-19
780

            
version 0.0901
yuki-kimoto authored on 2009-12-17
781
Retrun value is affected rows count
packaging one directory
yuki-kimoto authored on 2009-11-16
782
    
removed reconnect method
yuki-kimoto authored on 2010-05-28
783
Example:
packaging one directory
yuki-kimoto authored on 2009-11-16
784

            
removed register_format()
yuki-kimoto authored on 2010-05-26
785
    # delete
786
    $dbi->delete(table  => 'books',
787
                 where  => {id => 5},
788
                 append => 'some statement',
removed reconnect method
yuki-kimoto authored on 2010-05-28
789
                 filter => {id => 'encode_utf8'});
version 0.0901
yuki-kimoto authored on 2009-12-17
790

            
packaging one directory
yuki-kimoto authored on 2009-11-16
791
=head2 delete_all
792

            
added commit method
yuki-kimoto authored on 2010-05-27
793
Delete all rows.
bind_filter argument is chan...
yuki-kimoto authored on 2009-11-19
794

            
removed register_format()
yuki-kimoto authored on 2010-05-26
795
    $affected = $dbi->delete_all(table => $table);
packaging one directory
yuki-kimoto authored on 2009-11-16
796

            
added commit method
yuki-kimoto authored on 2010-05-27
797
Retruned value is affected rows count.
bind_filter argument is chan...
yuki-kimoto authored on 2009-11-19
798

            
removed reconnect method
yuki-kimoto authored on 2010-05-28
799
Example:
removed register_format()
yuki-kimoto authored on 2010-05-26
800
    
801
    # delete_all
removed reconnect method
yuki-kimoto authored on 2010-05-28
802
    $dbi->delete_all(table => 'books');
packaging one directory
yuki-kimoto authored on 2009-11-16
803

            
804
=head2 select
805
    
added commit method
yuki-kimoto authored on 2010-05-27
806
Select rows.
bind_filter argument is chan...
yuki-kimoto authored on 2009-11-19
807

            
added commit method
yuki-kimoto authored on 2010-05-27
808
    $result = $dbi->select(table    => $table,
809
                           column   => [@column],
810
                           where    => {%where},
811
                           append   => $append,
removed reconnect method
yuki-kimoto authored on 2010-05-28
812
                           relation => {%relation},
added commit method
yuki-kimoto authored on 2010-05-27
813
                           filter   => {%filter});
update document
yuki-kimoto authored on 2009-11-19
814

            
removed reconnect method
yuki-kimoto authored on 2010-05-28
815
Return value is the instance of L<DBIx::Custom::Result>.
update document
yuki-kimoto authored on 2009-11-19
816

            
removed reconnect method
yuki-kimoto authored on 2010-05-28
817
Example:
update document
yuki-kimoto authored on 2009-11-19
818

            
added commit method
yuki-kimoto authored on 2010-05-27
819
    # select * from books;
removed reconnect method
yuki-kimoto authored on 2010-05-28
820
    $result = $dbi->select(table => 'books');
packaging one directory
yuki-kimoto authored on 2009-11-16
821
    
update document
yuki-kimoto authored on 2009-11-19
822
    # select * from books where title = 'Perl';
removed reconnect method
yuki-kimoto authored on 2010-05-28
823
    $result = $dbi->select(table => 'books', where => {title => 1});
update document
yuki-kimoto authored on 2009-11-19
824
    
825
    # select title, author from books where id = 1 for update;
826
    $result = $dbi->select(
removed register_format()
yuki-kimoto authored on 2010-05-26
827
        table  => 'books',
removed reconnect method
yuki-kimoto authored on 2010-05-28
828
        column => ['title', 'author'],
removed register_format()
yuki-kimoto authored on 2010-05-26
829
        where  => {id => 1},
830
        appned => 'for update'
update document
yuki-kimoto authored on 2009-11-19
831
    );
832
    
added commit method
yuki-kimoto authored on 2010-05-27
833
    # select books.name as book_name from books, rental 
834
    # where books.id = rental.book_id;
835
    my $result = $dbi->select(
removed reconnect method
yuki-kimoto authored on 2010-05-28
836
        table    => ['books', 'rental'],
837
        column   => ['books.name as book_name']
added commit method
yuki-kimoto authored on 2010-05-27
838
        relation => {'books.id' => 'rental.book_id'}
update document
yuki-kimoto authored on 2009-11-19
839
    );
840

            
removed reconnect method
yuki-kimoto authored on 2010-05-28
841
=head2 create_query
842
    
843
Create the instance of L<DBIx::Custom::Query>. 
844
This receive the string written by SQL template.
packaging one directory
yuki-kimoto authored on 2009-11-16
845

            
removed reconnect method
yuki-kimoto authored on 2010-05-28
846
    my $query = $dbi->create_query("select * from authors where {= name} and {= age}");
847

            
848
=head2 execute
849

            
850
Execute the instace of L<DBIx::Custom::Query> or
851
the string written by SQL template.
852
Return value is the instance of L<DBIx::Custom::Result>.
853

            
854
    $result = $dbi->execute($query,    param => $params, filter => {%filter});
855
    $result = $dbi->execute($template, param => $params, filter => {%filter});
856

            
857
Example:
858

            
859
    $result = $dbi->execute("select * from authors where {= name} and {= age}", 
860
                            param => {name => 'taro', age => 19});
861
    
862
    while (my $row = $result->fetch) {
863
        # do something
864
    }
865

            
866
See also L<DBIx::Custom::SQLTemplate> to know how to write SQL template.
867

            
868
=head2 register_filter
869

            
870
Resister filter.
871
    
872
    $dbi->register_filter(%filters);
873
    
874
Example:
packaging one directory
yuki-kimoto authored on 2009-11-16
875

            
removed reconnect method
yuki-kimoto authored on 2010-05-28
876
    $dbi->register_filter(
877
        encode_utf8 => sub {
878
            my $value = shift;
879
            
880
            require Encode;
881
            
882
            return Encode::encode('UTF-8', $value);
883
        },
884
        decode_utf8 => sub {
885
            my $value = shift;
886
            
887
            require Encode;
888
            
889
            return Encode::decode('UTF-8', $value)
890
        }
891
    );
892

            
893
=head2 auto_commit
894

            
895
Auto commit.
packaging one directory
yuki-kimoto authored on 2009-11-16
896

            
removed reconnect method
yuki-kimoto authored on 2010-05-28
897
    $self        = $dbi->auto_commit(1);
898
    $auto_commit = $dbi->auto_commit;
899

            
900
This is equal to
901

            
902
    $dbi->dbh->{AutoCommit} = 1;
903
    $auto_commit = $dbi->dbh->{AutoCommit};
904

            
905
=head2 commit
906

            
907
Commit.
908

            
909
    $dbi->commit;
910

            
911
This is equal to
912

            
913
    $dbi->dbh->commit;
914

            
915
=head2 rollback
916

            
917
Rollback.
918

            
919
    $dbi->rollback
920

            
921
This is equal to
922

            
923
    $dbi->dbh->rollback;
924

            
925
=head1 AUTHOR
926

            
927
Yuki Kimoto, C<< <kimoto.yuki at gmail.com> >>
version 0.0901
yuki-kimoto authored on 2009-12-17
928

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

            
931
Copyright 2009 Yuki Kimoto, all rights reserved.
932

            
933
This program is free software; you can redistribute it and/or modify it
934
under the same terms as Perl itself.
935

            
936
=cut