use
vars
qw($VERSION $LOB_MAX_SIZE)
;
$VERSION
= 0.04;
$LOB_MAX_SIZE
= (1024 * 1024 * 1024);
sub
sequence_value {
my
(
$class
,
$sequence_name
) =
@_
;
"SELECT ${sequence_name}.NEXTVAL as val FROM dual"
}
sub
reset_sequence {
my
(
$class
,
$sequence_name
,
$restart_with
,
$increment_by
) =
@_
;
$restart_with
||= 1;
$increment_by
||= 1;
(
"DROP SEQUENCE ${sequence_name}"
,
"CREATE SEQUENCE ${sequence_name} START WITH ${restart_with} INCREMENT BY ${increment_by}"
);
}
sub
has_sequence {
my
(
$class
) =
@_
;
"SELECT sequence_name FROM user_sequences WHERE sequence_name = UPPER(?)"
}
sub
has_table {
my
(
$class
,
$connection
,
$table_name
) =
@_
;
my
$result
;
my
$sql
=
"SELECT table_name FROM user_tables WHERE table_name = UPPER(?)"
;
my
$record
=
$connection
->record(
$sql
,
$table_name
);
$result
= [
undef
,
$connection
->name,
$record
->{table_name},
undef
]
if
$record
->{table_name};
$result
}
sub
primary_key_info {
my
(
$class
,
$schema
) =
@_
;
$schema
? "SELECT LOWER(cl.column_name) AS column_name, cs.constraint_name AS pk_name, LOWER(cs.table_name) AS table_name FROM all_cons_columns cl
JOIN all_constraints cs
ON (cl.owner = cs. owner AND cl.constraint_name = cs. constraint_name AND constraint_type=
'P'
AND cs.table_name = UPPER(?) AND cs.owner = UPPER(?))
ORDER BY position"
: "SELECT LOWER(cl.column_name) AS column_name, cs.constraint_name, LOWER(cs.table_name) AS table_name FROM user_cons_columns cl
JOIN user_constraints cs
ON (cl.constraint_name = cs. constraint_name AND constraint_type=
'P'
AND cs.table_name = UPPER(?))
ORDER BY position";
}
sub
set_session_variables {
my
(
$class
,
$connection
,
$db_session_variables
) =
@_
;
my
$plsql
=
"BEGIN\n"
;
$plsql
.=
"execute immediate 'alter session set "
.
$_
.
"=''"
.
$db_session_variables
->{
$_
} .
"''';\n"
for
keys
%$db_session_variables
;
$plsql
.=
"END;"
;
$connection
->
do
(
$plsql
);
}
sub
update_lob {
my
(
$class
,
$connection
,
$table_name
,
$lob_column_name
,
$lob
,
$primary_key_values
,
$lob_size_column_name
) =
@_
;
confess
"missing primary key for lob update on ${table_name}.${lob_column_name}"
if
(!
$primary_key_values
|| ! (
%$primary_key_values
));
my
$sql
=
"UPDATE ${table_name} SET ${lob_column_name} = ? "
;
$sql
.= (
$lob_size_column_name
?
", ${lob_size_column_name} = ? "
:
''
)
.
$connection
->_where_clause(
$primary_key_values
);
my
$clas
=
'DBD::Oracle'
;
my
$ora_type
=
$clas
->can(
'SQLT_BIN'
) ?
$class
->SQLT_BIN :
$clas
->ORA_BLOB;
my
$bind_counter
= 1;
my
$sth
=
$connection
->dbh->prepare(
$sql
);
$sth
->bind_param(
$bind_counter
++ ,
$lob
, {
ora_type
=>
$ora_type
});
$sth
->bind_param(
$bind_counter
++ ,
length
(
$lob
||
''
))
if
$lob_size_column_name
;
for
my
$k
(
sort
keys
%$primary_key_values
) {
$sth
->bind_param(
$bind_counter
++ ,
$primary_key_values
->{
$k
});
}
$sth
->execute();
}
{
my
%long_read_cache
;
sub
fetch_lob {
my
(
$class
,
$connection
,
$table_name
,
$lob_column_name
,
$primary_key_values
,
$lob_size_column_name
) =
@_
;
confess
"missing primary key for lob update on ${table_name}.${lob_column_name}"
if
(!
$primary_key_values
|| ! (
%$primary_key_values
));
my
$dbh
=
$connection
->dbh;
if
(!
exists
(
$long_read_cache
{
"_"
.
$dbh
})){
$dbh
->{LongReadLen} =
$LOB_MAX_SIZE
;
$long_read_cache
{
"_"
.
$dbh
} = 1;
}
else
{
$dbh
->{LongReadLen} =
$class
->_get_lob_size(
$connection
,
$table_name
,
$primary_key_values
,
$lob_size_column_name
);
}
my
$sql
=
"SELECT ${lob_column_name} as lob_content FROM ${table_name} "
.
$connection
->_where_clause(
$primary_key_values
);
my
$record
=
$connection
->record(
$sql
,
map
{
$primary_key_values
->{
$_
}}
sort
keys
%$primary_key_values
);
$record
->{lob_content};
}
}
sub
_get_lob_size {
my
(
$class
,
$connection
,
$table_name
,
$primary_key_values
,
$lob_size_column_name
) =
@_
;
my
$resut
;
if
(
$lob_size_column_name
) {
my
$sql
=
"SELECT ${lob_size_column_name} as lob_size FROM ${table_name} "
.
$connection
->_where_clause(
$primary_key_values
);
my
(
$record
) =
$connection
->record(
$sql
,
map
{
$primary_key_values
->{
$_
}}
sort
keys
%$primary_key_values
);
$resut
=
$record
->{lob_size};
}
$resut
||
$LOB_MAX_SIZE
;
}
1;