our
$VERSION
=
'0.1.0'
;
use
5.008;
Hide Show 62 lines of Pod
my
$singleton
;
END {
if
(
defined
$singleton
&& @{
$singleton
->{loaded} } ) {
$singleton
->clear;
}
}
Hide Show 18 lines of Pod
sub
new {
my
$class
=
shift
;
my
(
$dbh
,
%options
) =
@_
;
my
$self
=
defined
$singleton
?
$singleton
: {};
$self
= {
dbh
=>
$dbh
,
loaded
=> [],
keynames
=>
undef
,
Keep
=> !!
$options
{Keep},
DeleteBeforeInsert
=> !!
$options
{DeleteBeforeInsert},
};
bless
$self
,
$class
;
$singleton
=
$self
;
return
$self
;
}
Hide Show 21 lines of Pod
sub
add {
my
$self
=
shift
;
my
(
$table_name
,
$data_id
,
$data_href
,
$key_aref
) =
@_
;
carp
"already exists $table_name : $data_id"
if
(
exists
$self
->{data} &&
exists
$self
->{data}->{
$table_name
}->{
$data_id
} );
$self
->{data}->{
$table_name
}->{
$data_id
} = {
data
=>
$data_href
,
key
=>
$key_aref
};
}
Hide Show 19 lines of Pod
sub
load {
my
$self
=
shift
;
my
(
$table_name
,
$data_id
,
$option_href
) =
@_
;
my
%data
=
$self
->_data_with_option(
$table_name
,
$data_id
,
$option_href
);
my
$keynames_aref
=
$self
->_get_keys(
$table_name
,
$data_id
);
return
$self
->_load(
$table_name
,
$keynames_aref
,
%data
);
}
sub
_get_keys {
my
$self
=
shift
;
my
(
$table_name
,
$data_id
) =
@_
;
my
$keynames_aref
=
$self
->{data}->{
$table_name
}->{
$data_id
}->{key};
if
(
$self
->_aref_is_empty(
$keynames_aref
) ) {
$keynames_aref
=
$self
->{keynames}->{
$table_name
};
}
return
$keynames_aref
;
}
sub
_data_with_option {
my
$self
=
shift
;
my
(
$table_name
,
$data_id
,
$option_href
) =
@_
;
my
%data
= %{
$self
->_data(
$table_name
,
$data_id
)};
if
(
defined
$option_href
) {
for
my
$key
(
keys
%{
$option_href
} ) {
$data
{
$key
} =
$option_href
->{
$key
};
}
}
return
%data
;
}
Hide Show 21 lines of Pod
sub
load_direct {
my
$self
=
shift
;
my
(
$table_name
,
$data_href
,
$keynames_aref
) =
@_
;
my
%data
= %{
$data_href
};
if
(
$self
->_aref_is_empty(
$keynames_aref
) ) {
$keynames_aref
=
$self
->{keynames}->{
$table_name
};
}
return
$self
->_load(
$table_name
,
$keynames_aref
,
%data
);
}
sub
_load {
my
$self
=
shift
;
my
(
$table_name
,
$keynames_aref
,
%data
) =
@_
;
croak
"primary keys are not defined\n"
if
(
$self
->_aref_is_empty(
$keynames_aref
) );
if
(
$self
->{DeleteBeforeInsert} &&
$self
->_data_for_key_exists(
$keynames_aref
,
%data
) ) {
$self
->_delete(
$table_name
, \
%data
,
$keynames_aref
);
}
$self
->_do_insert(
$table_name
,
%data
);
my
$keys
=
$self
->_primary_keys(
$keynames_aref
, \
%data
);
$self
->{dbh}->
do
(
'commit'
);
push
@{
$self
->{loaded}}, [
$table_name
, \
%data
,
$keynames_aref
];
return
$keys
;
}
sub
_aref_is_empty {
my
$self
=
shift
;
my
(
$keynames_aref
) =
@_
;
return
!
defined
$keynames_aref
|| !@{
$keynames_aref
};
}
sub
_data_for_key_exists {
my
$self
=
shift
;
my
(
$keynames_aref
,
%data
) =
@_
;
for
my
$key
( @{
$keynames_aref
} ) {
return
0
if
( !
exists
$data
{
$key
} );
}
return
1;
}
sub
_do_insert {
my
$self
=
shift
;
my
(
$table_name
,
%data
) =
@_
;
my
$dbh
=
$self
->{dbh};
my
$sth
=
$dbh
->prepare(
$self
->_insert_sql(
$table_name
,
%data
)) || croak
$dbh
->errstr;
my
$i
=1;
for
my
$column
(
sort
keys
%data
) {
$sth
->bind_param(
$i
++,
$data
{
$column
});
}
$sth
->execute() || croak
$dbh
->errstr;
$sth
->finish;
}
Hide Show 10 lines of Pod
sub
load_file {
my
$self
=
shift
;
my
(
$filename
) =
@_
;
require
$filename
;
croak(
"can't read $filename"
)
if
( $@ );
}
Hide Show 9 lines of Pod
sub
init {
my
$class
=
shift
;
my
$self
= {};
if
(
defined
$singleton
) {
$self
=
$singleton
;
}
else
{
bless
$self
,
$class
;
$singleton
=
$self
;
}
return
$self
;
}
Hide Show 5 lines of Pod
sub
set_keys {
my
$self
=
shift
;
my
(
$table_name
,
$keynames_aref
) =
@_
;
$self
->{keynames}->{
$table_name
} =
$keynames_aref
;
}
sub
_primary_keys {
my
$self
=
shift
;
my
(
$keynames_aref
,
$data_href
) =
@_
;
my
$result
;
for
my
$key
( @{
$keynames_aref
} ) {
if
( !
defined
$data_href
->{
$key
} ) {
$data_href
->{
$key
} =
$self
->_last_insert_id() ||
undef
;
}
$result
->{
$key
} =
$data_href
->{
$key
}
}
return
$result
;
}
sub
_last_insert_id {
my
$self
=
shift
;
my
$dbh
=
$self
->{dbh};
my
$sth
=
$dbh
->prepare(
"select LAST_INSERT_ID() from dual"
) || croak
$dbh
->errstr;
$sth
->execute() || croak
$dbh
->errstr;
if
(
my
@id
=
$sth
->fetchrow_array ) {
return
$id
[0];
}
return
;
}
Hide Show 10 lines of Pod
sub
do_select {
my
$self
=
shift
;
my
(
$table
,
$condition
) =
@_
;
my
$dbh
=
$self
->{dbh};
croak(
"Error: condition undefined"
)
if
!
defined
$condition
;
my
$sth
=
$dbh
->prepare(
"select * from $table where $condition"
);
$sth
->execute();
my
@result
;
while
(
my
$item
=
$sth
->fetchrow_hashref ) {
push
@result
,
$item
;
}
$sth
->finish();
return
@result
if
wantarray
;
return
$result
[0];
}
sub
_insert_sql {
my
$self
=
shift
;
my
(
$table_name
,
%data
) =
@_
;
my
$sql
=
sprintf
(
"insert into %s set "
,
$table_name
);
$sql
.=
join
(
','
,
map
{
"$_=?"
}
sort
keys
%data
);
return
$sql
;
}
sub
_data {
my
$self
=
shift
;
my
(
$table_name
,
$data_id
) =
@_
;
croak
"$table_name not found"
if
( !
exists
$self
->{data}->{
$table_name
} );
croak
"$data_id for $table_name not found"
if
( !
exists
$self
->{data}->{
$table_name
}->{
$data_id
} );
return
$self
->{data}->{
$table_name
}->{
$data_id
}->{data};
}
sub
DESTROY {
my
$self
=
shift
;
if
( @{
$self
->{loaded} } ) {
carp
"clear was not called in $0"
;
$self
->clear;
}
}
Hide Show 6 lines of Pod
sub
clear {
my
$self
=
shift
;
my
$dbh
=
$self
->{dbh};
if
(
$self
->{Keep} || !
defined
$dbh
) {
$self
->{loaded} = [];
return
;
}
for
my
$loaded
(
reverse
@{
$self
->{loaded} } ) {
$self
->_delete_loaded(
$loaded
);
}
$dbh
->
do
(
'commit'
);
$self
->{loaded} = [];
}
sub
_delete_loaded {
my
$self
=
shift
;
my
(
$loaded
) =
@_
;
my
(
$table_name
,
$data_href
,
$keynames_aref
) = @{
$loaded
};
$self
->_delete(
$table_name
,
$data_href
,
$keynames_aref
);
}
sub
_delete {
my
$self
=
shift
;
my
(
$table_name
,
$data_href
,
$keynames_aref
) =
@_
;
my
$dbh
=
$self
->{dbh};
my
%data
= %{
$data_href
};
my
@keys
= @{
$keynames_aref
};
my
$condition
=
join
(
' And '
,
map
{
defined
$data
{
$_
} ?
"$_=?"
:
"$_ IS NULL"
}
@keys
);
my
$sth
=
$dbh
->prepare(
"delete from $table_name where $condition"
);
my
$i
=1;
for
my
$key
(
@keys
) {
$sth
->bind_param(
$i
++,
$data
{
$key
});
}
$sth
->execute() || croak
$dbh
->errstr;
}
1;
Hide Show 19 lines of Pod