1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
|
use strict;
use DBI;
use Carp;
package DBHandler;
#our $dbh = undef;
use vars qw ($DB_CONNECTION);
sub getConnection {
my ($dsn, $user, $pass) = @_;
#return $DB_CONNECTION if ($DB_CONNECTION);
$DB_CONNECTION = DBI->connect($dsn, $user, $pass);
$DB_CONNECTION->{AutoCommit} = 1;
$DB_CONNECTION->{RaiseError} = 1;
return $DB_CONNECTION;
}
# #############
# Simple statement
package Statement;
sub new {
my ( $this, $dbh, $sql, $is_trans ) = @_;
# @@@ sql should be tested OK, so here just die
my $sth = $dbh->prepare($sql) || Carp::croak( $dbh->errstr );
my %fields = (
dbh => $dbh,
sql => $sql,
sth => $sth,
is_trans => $is_trans,
);
return bless \%fields, $this;
}
sub exec {
my ( $this, @param ) = @_;
my $dbh = $this->{dbh};
my $sth = $this->{sth};
my $sql = $this->{sql};
if ( !$sth->execute(@param) ) {
if ( $this->{is_trans} ) {
$dbh->rollback();
}
Carp::croak( $dbh->errstr );
}
my @ret = ();
if ( $sql =~ /^select/i ) {
# @@@ get result object
while ( my $res = $sth->fetchrow_hashref() ) {
push @ret, $res;
}
}
# @@@ $sth->finish();
return \@ret;
}
sub last_id {
my $this = shift;
my $dbh = $this->{dbh};
return $dbh->last_insert_id(undef, undef, undef, undef);
}
sub DESTROY {
my $this = shift;
my $sth = $this->{sth};
$sth->finish();
}
# #############
# Transaction
package Transaction;
my $IS_TRANS = 1;
sub new {
my ( $this, $dbh ) = @_;
# @@@ fatal error, just die
$dbh->begin_work() || Carp::croak( $dbh->errstr );
my %fields = (
dbh => $dbh,
Active => 1,
);
return bless \%fields, $this;
}
sub createStatement {
my ( $this, $sql) = @_;
# @@@ fatal error, just die
Carp::croak("transaction not begin") if ( !$this->{Active} );
my $dbh = $this->{dbh};
return new Statement($dbh, $sql, $IS_TRANS);
}
sub commit {
my $this = shift;
my $dbh = $this->{dbh};
if ( $this->{Active} && !$dbh->{AutoCommit} ) {
$dbh->commit || Carp::croak( $dbh->errstr );
}
$this->{Active} = 0;
}
sub rollback {
my $this = shift;
my $dbh = $this->{dbh};
if ( $this->{Active} && !$dbh->{AutoCommit} ) {
$dbh->rollback || Carp::croak( $dbh->errstr );
}
$this->{Active} = 0;
}
sub DESTROY {
my $this = shift;
$this->rollback;
}
1;
|