DBIx-Custom / lib / DBI / Custom.pm /
Newer Older
307 lines | 7.112kb
first commit
yuki-kimoto authored on 2009-10-13
1
package DBI::Custom;
2
use Object::Simple;
add some method
yuki-kimoto authored on 2009-10-14
3
use DBI;
4
use SQL::Abstract;
first commit
yuki-kimoto authored on 2009-10-13
5

            
cleanup
yuki-kimoto authored on 2009-10-15
6
# Model
7
sub model : ClassAttr { auto_build => \&_inherit_model }
first commit
yuki-kimoto authored on 2009-10-13
8

            
cleanup
yuki-kimoto authored on 2009-10-15
9
# Inherit super class model
10
sub _inherit_model {
11
    $class = shict;
12
    my $super = do {
13
        no strict 'refs';
14
        ${"${class}::ISA"}[0];
15
    };
16
    my $model = eval{$super->can('model')}
17
                         ? $super->model->clone
18
                         : $class->Object::Simple::new;
cleanup
yuki-kimoto authored on 2009-10-14
19
    
20
    $class->model($model);
first commit
yuki-kimoto authored on 2009-10-13
21
}
22

            
cleanup
yuki-kimoto authored on 2009-10-15
23
# New
24
sub new {
25
    my $self = shift->Object::Simple::new(@_);
26
    my $class = ref $self;
27
    return bless {%{$class->model->clone}, %{$self}}, $class;
first commit
yuki-kimoto authored on 2009-10-13
28
}
29

            
cleanup
yuki-kimoto authored on 2009-10-15
30
# Initialize modle
31
sub initialize_model {
32
    my ($class, $callback) = @_;
first commit
yuki-kimoto authored on 2009-10-13
33
    
cleanup
yuki-kimoto authored on 2009-10-15
34
    # Callback to initialize model
35
    $callback->($class->model);
first commit
yuki-kimoto authored on 2009-10-13
36
}
37

            
cleanup
yuki-kimoto authored on 2009-10-15
38
# Clone
39
sub clone {
cleanup
yuki-kimoto authored on 2009-10-14
40
    my $self = shift;
cleanup
yuki-kimoto authored on 2009-10-15
41
    my $new = $self->Object::Simple::new;
42
    $new->connect_infos(%{$self->connect_infos || {}});
43
    $new->filters(%{$self->filters || {}});
cleanup
yuki-kimoto authored on 2009-10-14
44
    
cleanup
yuki-kimoto authored on 2009-10-15
45
    $new->global_bind_rules(@{$self->global_bind_rules || []});
46
    $new->global_fetch_rules(@{$self->global_fetch_rules || []});
cleanup
yuki-kimoto authored on 2009-10-14
47
    
cleanup
yuki-kimoto authored on 2009-10-15
48
    foreach my $method (qw/bind_rules fetch_rules/) {
49
        my $new_rules = [];
50
        foreach my $rule (@{$self->method}) {
51
            my $new_rule = {};
52
            foreach my $key ($rule) {
53
                if ($key eq 'filter') {
54
                    my $new_filters = [];
55
                    foreach my $filter (@{$rule->{$key} || []}) {
56
                        push @$new_filters, $filter
57
                    }
58
                    $new_rule->{$key} = $new_filters;
59
                }
60
                else {
61
                     $new_rule->{$key} = $rule->{$key};
62
                }
63
            }
64
            push @$new_rules, $new_rule;
65
        }
66
        $self->$method($new_rules);
cleanup
yuki-kimoto authored on 2009-10-14
67
    }
68
}
69

            
cleanup
yuki-kimoto authored on 2009-10-15
70
# Attribute
71
sub connect_info       : Attr { type => 'hash',  auto_build => sub { shift->connect_info({}) } }
cleanup
yuki-kimoto authored on 2009-10-15
72

            
cleanup
yuki-kimoto authored on 2009-10-15
73
sub global_bind_rules  : Attr { type => 'array', auto_build => sub { shift->global_bind_rules([]) } }
cleanup
yuki-kimoto authored on 2009-10-15
74
sub add_global_bind_rule { shift->global_bind_rules(@_) }
75

            
cleanup
yuki-kimoto authored on 2009-10-15
76
sub global_fetch_rules : Attr { type => 'array', auto_build => sub { shift->global_fetch_rules([]) } }
cleanup
yuki-kimoto authored on 2009-10-15
77
sub add_global_fetch_rules { shift->global_fetch_rules(@_) }
78

            
79
sub bind_rules : Attr { type => 'hash',  auto_build => sub { shift->bind_rules({}) }
80
sub add_bind_rule { shift->bind_rules(@_) }
81

            
82
sub fetch_rules : Attr { type => 'hash',  auto_build => sub { shift->fetch_rules({}) }
83
sub add_fetch_rule { shift->fetch_rules(@_) }
84

            
85
sub filters : Attr { type => 'hash', deref => 1, default => sub { {} } }
86
sub add_filter { shift->filters(@_) }
87

            
cleanup
yuki-kimoto authored on 2009-10-15
88

            
89
sub dbh          : Attr { auto_build => sub { shift->connect } }
90
sub sql_abstract : Attr { auto_build => sub { shift->sql_abstract(SQL::Abstract->new) }}
cleanup
yuki-kimoto authored on 2009-10-14
91

            
add some method
yuki-kimoto authored on 2009-10-14
92
sub connect {
93
    my $self = shift;
94
    my $connect_info = $self->connect_info;
95
    
96
    my $dbh = DBI->connect(
97
        $connect_info->{dsn},
98
        $connect_info->{user},
99
        $connect_info->{password},
100
        {
101
            RaiseError => 1,
102
            PrintError => 0,
103
            AutoCommit => 1,
104
            %{$connect_info->{options} || {} }
105
        }
106
    );
107
    
108
    $self->dbh($dbh);
109
}
first commit
yuki-kimoto authored on 2009-10-13
110

            
add some method
yuki-kimoto authored on 2009-10-14
111
sub reconnect {
112
    my $self = shift;
113
    $self->dbh(undef);
114
    $self->connect;
115
}
first commit
yuki-kimoto authored on 2009-10-13
116

            
add some method
yuki-kimoto authored on 2009-10-14
117
sub query {
118
    my ($self, $query, @binds) = @_;
119
    $self->{success} = 0;
120

            
121
    $self->_replace_omniholder(\$query, \@binds);
122

            
123
    my $st;
124
    my $sth;
125

            
126
    my $old = $old_statements{$self};
127

            
128
    if (my $i = (grep $old->[$_][0] eq $query, 0..$#$old)[0]) {
129
        $st = splice(@$old, $i, 1)->[1];
130
        $sth = $st->{sth};
131
    } else {
132
        eval { $sth = $self->{dbh}->prepare($query) } or do {
133
            if ($@) {
134
                $@ =~ s/ at \S+ line \d+\.\n\z//;
135
                Carp::croak($@);
136
            }
137
            $self->{reason} = "Prepare failed ($DBI::errstr)";
138
            return _dummy;
139
        };
140

            
141
        # $self is quoted on purpose, to pass along the stringified version,
142
        # and avoid increasing reference count.
143
        $st = bless {
144
            db    => "$self",
145
            sth   => $sth,
146
            query => $query
147
        }, 'DBIx::Simple::Statement';
148
        $statements{$self}{$st} = $st;
149
    }
first commit
yuki-kimoto authored on 2009-10-13
150

            
add some method
yuki-kimoto authored on 2009-10-14
151
    eval { $sth->execute(@binds) } or do {
152
        if ($@) {
153
            $@ =~ s/ at \S+ line \d+\.\n\z//;
154
            Carp::croak($@);
155
        }
first commit
yuki-kimoto authored on 2009-10-13
156

            
add some method
yuki-kimoto authored on 2009-10-14
157
        $self->{reason} = "Execute failed ($DBI::errstr)";
158
	return _dummy;
159
    };
160

            
161
    $self->{success} = 1;
162

            
163
    return bless { st => $st, lc_columns => $self->{lc_columns} }, $self->{result_class};
164
}
165

            
166
sub query {
167
    my ($self, $sql) = @_;
168
    my $sth = $self->dbh->prepare($sql);
169
    $sth->execute(@bind);
170
}
171

            
172
sub select {
173
    my ($table, $column_names, $where, $order) = @_;
first commit
yuki-kimoto authored on 2009-10-13
174
    
add some method
yuki-kimoto authored on 2009-10-14
175
    my ($stmt, @bind) = $self->sql_abstract->select($table, $column_names, $where, $order);
176
    my $sth = $self->dbh->prepare($stmt);
177
    $sth->execute(@bind);
178
}
179

            
180
sub insert {
181
    my ($self, $table, $values) = @_;
first commit
yuki-kimoto authored on 2009-10-13
182
    
add some method
yuki-kimoto authored on 2009-10-14
183
    my ($stmt, @bind) = $self->sql_abstract->insert($table, $values);
184
    my $sth = $self->dbh->prepare($stmt);
185
    $sth->execute(@bind);
186
}
187

            
188
sub update {
189
    my ($self, $values, $where) = @_;
190
    my ($stmt, @bind) = $self->sql_abstract->update($table, $values, $where);
191
    my $sth = $self->dbh->prepare($stmt);
192
    $sth->execute(@bind);
first commit
yuki-kimoto authored on 2009-10-13
193
}
194

            
add some method
yuki-kimoto authored on 2009-10-14
195
sub delete {
196
    my ($self, $where) = @_;
197
    my ($stmt, @bind) = $self->sql_abstract->delete($table, $where);
198
    my $sth = $self->dbh->prepare($stmt);
199
    $sth->execute(@bind);
200
}
201

            
202

            
first commit
yuki-kimoto authored on 2009-10-13
203

            
204
Object::Simple->build_class;
205

            
206
=head1 NAME
207

            
208
DBI::Custom - The great new DBI::Custom!
209

            
210
=head1 VERSION
211

            
212
Version 0.01
213

            
214
=cut
215

            
216
our $VERSION = '0.01';
217

            
218

            
219
=head1 SYNOPSIS
220

            
221
Quick summary of what the module does.
222

            
223
Perhaps a little code snippet.
224

            
225
    use DBI::Custom;
226

            
227
    my $foo = DBI::Custom->new();
228
    ...
229

            
230
=head1 EXPORT
231

            
232
A list of functions that can be exported.  You can delete this section
233
if you don't export anything, such as for a purely object-oriented module.
234

            
235
=head1 FUNCTIONS
236

            
237
=head2 function1
238

            
239
=cut
240

            
241
sub function1 {
242
}
243

            
244
=head2 function2
245

            
246
=cut
247

            
248
sub function2 {
249
}
250

            
251
=head1 AUTHOR
252

            
253
Yuki Kimoto, C<< <kimoto.yuki at gmail.com> >>
254

            
255
=head1 BUGS
256

            
257
Please report any bugs or feature requests to C<bug-dbi-custom at rt.cpan.org>, or through
258
the web interface at L<http://rt.cpan.org/NoAuth/ReportBug.html?Queue=DBI-Custom>.  I will be notified, and then you'll
259
automatically be notified of progress on your bug as I make changes.
260

            
261

            
262

            
263

            
264
=head1 SUPPORT
265

            
266
You can find documentation for this module with the perldoc command.
267

            
268
    perldoc DBI::Custom
269

            
270

            
271
You can also look for information at:
272

            
273
=over 4
274

            
275
=item * RT: CPAN's request tracker
276

            
277
L<http://rt.cpan.org/NoAuth/Bugs.html?Dist=DBI-Custom>
278

            
279
=item * AnnoCPAN: Annotated CPAN documentation
280

            
281
L<http://annocpan.org/dist/DBI-Custom>
282

            
283
=item * CPAN Ratings
284

            
285
L<http://cpanratings.perl.org/d/DBI-Custom>
286

            
287
=item * Search CPAN
288

            
289
L<http://search.cpan.org/dist/DBI-Custom/>
290

            
291
=back
292

            
293

            
294
=head1 ACKNOWLEDGEMENTS
295

            
296

            
297
=head1 COPYRIGHT & LICENSE
298

            
299
Copyright 2009 Yuki Kimoto, all rights reserved.
300

            
301
This program is free software; you can redistribute it and/or modify it
302
under the same terms as Perl itself.
303

            
304

            
305
=cut
306

            
307
1; # End of DBI::Custom