Author: turnstep
Date: Mon Mar 23 17:59:45 2009
New Revision: 12626
Modified:
DBD-Pg/trunk/Changes
DBD-Pg/trunk/Pg.pm
DBD-Pg/trunk/Pg.xs
DBD-Pg/trunk/dbdimp.c
DBD-Pg/trunk/t/03dbmethod.t
Log:
Change large object interface from old, non-DBI friendly lo_ to pg_lo_, per
suggestion
on ticket 44467.
Add tests for AutoCommit/lo_import interaction, plus tests for old-style lo_
interface.
Modified: DBD-Pg/trunk/Changes
==============================================================================
--- DBD-Pg/trunk/Changes (original)
+++ DBD-Pg/trunk/Changes Mon Mar 23 17:59:45 2009
@@ -1,9 +1,12 @@
('GSM' is Greg Sabino Mullane, [email protected])
-2.11.9
+2.12.0
+ - Change large object interface from lo_* to pg_lo_* and make them
accessible
+ via direct $dbh calls (e.g. $dbh->pg_lo_import instead of
$dbh->func(..,'pg_lo_import').
+ The use of $dbh->func(... 'lo_*') is deprecated. [GSM] (CPAN bug #44467)
- Throw an exception for large_object functions called when AutoCommit is
on,
- but allow lo_import and lo_export to work. Reported by Kynn Jones.
+ but allow pg_lo_import and pg_lo_export to work. Reported by Kynn Jones.
[GSM] (CPAN bug #44461)
- Fix a memory leak when parsing returned arrays. Reported by Bálint
Szilakszi.
[GSM] (CPAN bug #44225)
Modified: DBD-Pg/trunk/Pg.pm
==============================================================================
--- DBD-Pg/trunk/Pg.pm (original)
+++ DBD-Pg/trunk/Pg.pm Mon Mar 23 17:59:45 2009
@@ -143,6 +143,17 @@
DBD::Pg::st->install_method('pg_result');
DBD::Pg::st->install_method('pg_ready');
+ DBD::Pg::db->install_method('pg_lo_creat');
+ DBD::Pg::db->install_method('pg_lo_open');
+ DBD::Pg::db->install_method('pg_lo_write');
+ DBD::Pg::db->install_method('pg_lo_read');
+ DBD::Pg::db->install_method('pg_lo_lseek');
+ DBD::Pg::db->install_method('pg_lo_tell');
+ DBD::Pg::db->install_method('pg_lo_close');
+ DBD::Pg::db->install_method('pg_lo_unlink');
+ DBD::Pg::db->install_method('pg_lo_import');
+ DBD::Pg::db->install_method('pg_lo_export');
+
return $drh;
} ## end of driver
@@ -2033,20 +2044,20 @@
PRIMARY_KEY flag is_primary_key
REMARKS attribute description
-=item lo_creat
+=item pg_lo_creat
- $lobjId = $dbh->func($mode, 'lo_creat');
+ $lobjId = $dbh->pg_lo_creat($mode);
Creates a new large object and returns the object-id. C<$mode> is a bitmask
describing read and write access to the new object. This setting is ignored
since Postgres version 8.1. For backwards compatibility, however, you should
-set a valid mode anyway (see L</lo_open> for a list of valid modes).
+set a valid mode anyway (see L</pg_lo_open> for a list of valid modes).
Upon failure it returns C<undef>. This function cannot be used if AutoCommit
is enabled.
=item lo_open
- $lobj_fd = $dbh->func($lobjId, $mode, 'lo_open');
+ $lobj_fd = $dbh->pg_lo_open($lobjId, $mode);
Opens an existing large object and returns an object-descriptor for use in
subsequent C<lo_*> calls. C<$mode> is a bitmask describing read and write
@@ -2069,21 +2080,21 @@
=item lo_write
- $nbytes = $dbh->func($lobj_fd, $buffer, $len, 'lo_write');
+ $nbytes = $dbh->pg_lo_write($lobj_fd, $buffer, $len);
Writes C<$len> bytes of c<$buffer> into the large object C<$lobj_fd>. Returns
the number
of bytes written and C<undef> upon failure. This function cannot be used if
AutoCommit is enabled.
=item lo_read
- $nbytes = $dbh->func($lobj_fd, $buffer, $len, 'lo_read');
+ $nbytes = $dbh->pg_lo_read($lobj_fd, $buffer, $len);
Reads C<$len> bytes into c<$buffer> from large object C<$lobj_fd>. Returns the
number of
bytes read and C<undef> upon failure. This function cannot be used if
AutoCommit is enabled.
=item lo_lseek
- $loc = $dbh->func($lobj_fd, $offset, $whence, 'lo_lseek');
+ $loc = $dbh->pg_lo_lseek($lobj_fd, $offset, $whence);
Changes the current read or write location on the large object
C<$obj_id>. Currently C<$whence> can only be 0 (which is L_SET). Returns the
current
@@ -2091,35 +2102,36 @@
=item lo_tell
- $loc = $dbh->func($lobj_fd, 'lo_tell');
+ $loc = $dbh->pg_lo_tell($lobj_fd);
Returns the current read or write location on the large object C<$lobj_fd> and
C<undef> upon failure.
This function cannot be used if AutoCommit is enabled.
=item lo_close
- $lobj_fd = $dbh->func($lobj_fd, 'lo_close');
+ $lobj_fd = $dbh->pg_lo_close($lobj_fd);
Closes an existing large object. Returns true upon success and false upon
failure.
This function cannot be used if AutoCommit is enabled.
=item lo_unlink
- $ret = $dbh->func($lobjId, 'lo_unlink');
+ $ret = $dbh->pg_lo_unlink($lobjId);
Deletes an existing large object. Returns true upon success and false upon
failure.
This function cannot be used if AutoCommit is enabled.
=item lo_import
- $lobjId = $dbh->func($filename, 'lo_import');
+
+ $lobjId = $dbh->pg_lo_import($filename);
Imports a Unix file as a large object and returns the object id of the new
object or C<undef> upon failure.
=item lo_export
- $ret = $dbh->func($lobjId, $filename, 'lo_export');
+ $ret = $dbh->pg_lo_export($lobjId, $filename);
Exports a large object into a Unix file. Returns false upon failure, true
otherwise.
Modified: DBD-Pg/trunk/Pg.xs
==============================================================================
--- DBD-Pg/trunk/Pg.xs (original)
+++ DBD-Pg/trunk/Pg.xs Mon Mar 23 17:59:45 2009
@@ -384,18 +384,16 @@
warn("release ineffective with AutoCommit enabled");
ST(0) = (pg_db_release(dbh, imp_dbh, name)!=0) ? &sv_yes :
&sv_no;
-
void
-lo_creat(dbh, mode)
+pg_lo_creat(dbh, mode)
SV * dbh
int mode
CODE:
const unsigned int ret = pg_db_lo_creat(dbh, mode);
ST(0) = (ret > 0) ? sv_2mortal(newSVuv(ret)) : &sv_undef;
-
void
-lo_open(dbh, lobjId, mode)
+pg_lo_open(dbh, lobjId, mode)
SV * dbh
unsigned int lobjId
int mode
@@ -405,15 +403,18 @@
void
-lo_close(dbh, fd)
+pg_lo_write(dbh, fd, buf, len)
SV * dbh
int fd
+ char * buf
+ size_t len
CODE:
- ST(0) = (pg_db_lo_close(dbh, fd) >= 0) ? &sv_yes : &sv_no;
+ const int ret = pg_db_lo_write(dbh, fd, buf, len);
+ ST(0) = (ret >= 0) ? sv_2mortal(newSViv(ret)) : &sv_undef;
void
-lo_read(dbh, fd, buf, len)
+pg_lo_read(dbh, fd, buf, len)
SV * dbh
int fd
char * buf
@@ -435,6 +436,78 @@
void
+pg_lo_lseek(dbh, fd, offset, whence)
+ SV * dbh
+ int fd
+ int offset
+ int whence
+ CODE:
+ const int ret = pg_db_lo_lseek(dbh, fd, offset, whence);
+ ST(0) = (ret >= 0) ? sv_2mortal(newSViv(ret)) : &sv_undef;
+
+
+void
+pg_lo_tell(dbh, fd)
+ SV * dbh
+ int fd
+ CODE:
+ const int ret = pg_db_lo_tell(dbh, fd);
+ ST(0) = (ret >= 0) ? sv_2mortal(newSViv(ret)) : &sv_undef;
+
+
+void
+pg_lo_close(dbh, fd)
+ SV * dbh
+ int fd
+ CODE:
+ ST(0) = (pg_db_lo_close(dbh, fd) >= 0) ? &sv_yes : &sv_no;
+
+
+void
+pg_lo_unlink(dbh, lobjId)
+ SV * dbh
+ unsigned int lobjId
+ CODE:
+ ST(0) = (pg_db_lo_unlink(dbh, lobjId) >= 1) ? &sv_yes : &sv_no;
+
+
+void
+pg_lo_import(dbh, filename)
+ SV * dbh
+ char * filename
+ CODE:
+ const unsigned int ret = pg_db_lo_import(dbh, filename);
+ ST(0) = (ret > 0) ? sv_2mortal(newSVuv(ret)) : &sv_undef;
+
+
+void
+pg_lo_export(dbh, lobjId, filename)
+ SV * dbh
+ unsigned int lobjId
+ char * filename
+ CODE:
+ ST(0) = (pg_db_lo_export(dbh, lobjId, filename) >= 1) ? &sv_yes
: &sv_no;
+
+
+void
+lo_creat(dbh, mode)
+ SV * dbh
+ int mode
+ CODE:
+ const unsigned int ret = pg_db_lo_creat(dbh, mode);
+ ST(0) = (ret > 0) ? sv_2mortal(newSVuv(ret)) : &sv_undef;
+
+void
+lo_open(dbh, lobjId, mode)
+ SV * dbh
+ unsigned int lobjId
+ int mode
+ CODE:
+ const int ret = pg_db_lo_open(dbh, lobjId, mode);
+ ST(0) = (ret >= 0) ? sv_2mortal(newSViv(ret)) : &sv_undef;
+
+
+void
lo_write(dbh, fd, buf, len)
SV * dbh
int fd
@@ -446,6 +519,28 @@
void
+lo_read(dbh, fd, buf, len)
+ SV * dbh
+ int fd
+ char * buf
+ size_t len
+ PREINIT:
+ SV * const bufsv = SvROK(ST(2)) ? SvRV(ST(2)) : ST(2);
+ int ret;
+ CODE:
+ sv_setpvn(bufsv,"",0); /* Make sure we can grow it safely */
+ buf = SvGROW(bufsv, len + 1);
+ ret = pg_db_lo_read(dbh, fd, buf, len);
+ if (ret > 0) {
+ SvCUR_set(bufsv, ret);
+ *SvEND(bufsv) = '\0';
+ sv_setpvn(ST(2), buf, (unsigned)ret);
+ SvSETMAGIC(ST(2));
+ }
+ ST(0) = (ret >= 0) ? sv_2mortal(newSViv(ret)) : &sv_undef;
+
+
+void
lo_lseek(dbh, fd, offset, whence)
SV * dbh
int fd
@@ -466,6 +561,14 @@
void
+lo_close(dbh, fd)
+ SV * dbh
+ int fd
+ CODE:
+ ST(0) = (pg_db_lo_close(dbh, fd) >= 0) ? &sv_yes : &sv_no;
+
+
+void
lo_unlink(dbh, lobjId)
SV * dbh
unsigned int lobjId
@@ -651,6 +754,7 @@
#endif
+
# -- end of DBD::Pg::db
Modified: DBD-Pg/trunk/dbdimp.c
==============================================================================
--- DBD-Pg/trunk/dbdimp.c (original)
+++ DBD-Pg/trunk/dbdimp.c Mon Mar 23 17:59:45 2009
@@ -4115,7 +4115,7 @@
/* ================================================================== */
/* For lo_import and lo_export functions. Used to commit or rollback a
- transaction, if AutoCommit is on. */
+ transaction, but only if AutoCommit is on. */
static int pg_db_end_txn (pTHX_ SV * dbh, imp_dbh_t * imp_dbh, int commit)
{
int status = -1;
@@ -4123,8 +4123,8 @@
if (TSTART) TRC(DBILOGFP, "%sBegin pg_db_end_txn with %s\n",
THEADER, commit ? "commit" :
"rollback");
- /* If not autocommit, start a new transaction */
status = _result(aTHX_ imp_dbh, commit ? "commit" : "rollback");
+ imp_dbh->done_begin = DBDPG_FALSE;
if (PGRES_COMMAND_OK != status) {
TRACE_PQERRORMESSAGE;
pg_error(aTHX_ dbh, status, PQerrorMessage(imp_dbh->conn));
@@ -4133,9 +4133,8 @@
return 0;
}
- imp_dbh->done_begin = DBDPG_FALSE;
-
if (TEND) TRC(DBILOGFP, "%sEnd pg_db_end_txn\n", THEADER);
+
return 1;
} /* end of pg_db_end_txn */
@@ -4152,7 +4151,7 @@
if (TSTART) TRC(DBILOGFP, "%sBegin pg_db_pg_lo_creat (mode: %d)\n",
THEADER, mode);
if (DBIc_has(imp_dbh, DBIcf_AutoCommit)) {
- croak("Cannot call lo_creat when AutoCommit is on");
+ croak("Cannot call pg_lo_creat when AutoCommit is on");
}
if (!pg_db_start_txn(aTHX_ dbh,imp_dbh)) {
@@ -4178,7 +4177,7 @@
THEADER, mode, lobjId);
if (DBIc_has(imp_dbh, DBIcf_AutoCommit)) {
- croak("Cannot call lo_open when AutoCommit is on");
+ croak("Cannot call pg_lo_open when AutoCommit is on");
}
if (!pg_db_start_txn(aTHX_ dbh,imp_dbh))
@@ -4202,7 +4201,7 @@
if (TSTART) TRC(DBILOGFP, "%sBegin pg_db_lo_close (fd: %d)\n", THEADER,
fd);
if (DBIc_has(imp_dbh, DBIcf_AutoCommit)) {
- croak("Cannot call lo_close when AutoCommit is on");
+ croak("Cannot call pg_lo_close when AutoCommit is on");
}
if (!pg_db_start_txn(aTHX_ dbh,imp_dbh))
@@ -4227,7 +4226,7 @@
THEADER, fd, len);
if (DBIc_has(imp_dbh, DBIcf_AutoCommit)) {
- croak("Cannot call lo_read when AutoCommit is on");
+ croak("Cannot call pg_lo_read when AutoCommit is on");
}
if (!pg_db_start_txn(aTHX_ dbh,imp_dbh))
@@ -4252,7 +4251,7 @@
THEADER, fd, len);
if (DBIc_has(imp_dbh, DBIcf_AutoCommit)) {
- croak("Cannot call lo_write when AutoCommit is on");
+ croak("Cannot call pg_lo_write when AutoCommit is on");
}
if (!pg_db_start_txn(aTHX_ dbh,imp_dbh))
@@ -4277,7 +4276,7 @@
THEADER, fd, offset, whence);
if (DBIc_has(imp_dbh, DBIcf_AutoCommit)) {
- croak("Cannot call lo_lseek when AutoCommit is on");
+ croak("Cannot call pg_lo_lseek when AutoCommit is on");
}
if (!pg_db_start_txn(aTHX_ dbh,imp_dbh))
@@ -4301,7 +4300,7 @@
if (TSTART) TRC(DBILOGFP, "%sBegin pg_db_lo_tell (fd: %d)\n", THEADER,
fd);
if (DBIc_has(imp_dbh, DBIcf_AutoCommit)) {
- croak("Cannot call lo_tell when AutoCommit is on");
+ croak("Cannot call pg_lo_tell when AutoCommit is on");
}
if (!pg_db_start_txn(aTHX_ dbh,imp_dbh))
@@ -4325,7 +4324,7 @@
if (TSTART) TRC(DBILOGFP, "%sBegin pg_db_lo_unlink (objectid: %d)\n",
THEADER, lobjId);
if (DBIc_has(imp_dbh, DBIcf_AutoCommit)) {
- croak("Cannot call lo_unlink when AutoCommit is on");
+ croak("Cannot call pg_lo_unlink when AutoCommit is on");
}
if (!pg_db_start_txn(aTHX_ dbh,imp_dbh))
Modified: DBD-Pg/trunk/t/03dbmethod.t
==============================================================================
--- DBD-Pg/trunk/t/03dbmethod.t (original)
+++ DBD-Pg/trunk/t/03dbmethod.t Mon Mar 23 17:59:45 2009
@@ -2,11 +2,13 @@
## Test of the database handle methods
## The following methods are *not* (explicitly) tested here:
+## "take_imp_data" "pg_server_trace" "pg_server_untrace" "pg_type_info"
## "data_sources" (see 04misc.t)
## "disconnect" (see 01connect.t)
-## "take_imp_data"
-## "pg_savepoint", "pg_release", "pg_rollback_to" (see 20savepoints.t)
-## "pg_putline", "pg_getline", "pg_endcopy" (see 07copy.t)
+## "pg_savepoint" "pg_release" "pg_rollback_to" (see 20savepoints.t)
+## "pg_getline" "pg_endcopy" "pg_getcopydata" "pg_getcopydata_async" (see
07copy.t)
+## "pg_putline" "pg_putcopydata" "pg_putcopydata_async (see 07copy.t)
+## "pg_cancel" "pg_ready" "pg_result" (see 08async.t)
use 5.006;
use strict;
@@ -24,7 +26,7 @@
if (! defined $dbh) {
plan skip_all => 'Connection to database failed, cannot continue
testing';
}
-plan tests => 507;
+plan tests => 521;
isnt ($dbh, undef, 'Connect to database for database handle method testing');
@@ -37,6 +39,7 @@
# Quick simple "tests"
+
$dbh->do(q{}); ## This used to break, so we keep it as a test...
$SQL = q{SELECT '2529DF6AB8F79407E94445B4BC9B906714964AC8' FROM dbd_pg_test
WHERE id=?};
$sth = $dbh->prepare($SQL);
@@ -1290,75 +1293,83 @@
is_deeply (\%missing, {}, $t);
#
-# Test of the "lo_*" database handle methods
+# Test of the "pg_lo_*" database handle methods
#
-$t='DB handle method "lo_creat" returns a valid descriptor for reading';
+$t='DB handle method "pg_lo_creat" returns a valid descriptor for reading';
$dbh->{AutoCommit}=1; $dbh->{AutoCommit}=0; ## Catch error where not in begin
my ($R,$W) = ($dbh->{pg_INV_READ}, $dbh->{pg_INV_WRITE});
my $RW = $R|$W;
-my $object = $dbh->func($R, 'lo_creat');
+my $object;
+
+$t='DB handle method "pg_lo_creat" works with old-school dbh->func() method';
+$object = $dbh->func($W, 'pg_lo_creat');
like ($object, qr/^\d+$/o, $t);
isnt ($object, 0, $t);
-$t='DB handle method "lo_creat" returns a valid descriptor for writing';
+$t='DB handle method "pg_lo_creat" works with deprecated
dbh->func(...lo_creat) method';
$object = $dbh->func($W, 'lo_creat');
like ($object, qr/^\d+$/o, $t);
isnt ($object, 0, $t);
-$t='DB handle method "lo_open" returns a valid descriptor for writing';
-my $handle = $dbh->func($object, $W, 'lo_open');
+$t='DB handle method "pg_lo_creat" returns a valid descriptor for writing';
+$object = $dbh->pg_lo_creat($W);
+like ($object, qr/^\d+$/o, $t);
+isnt ($object, 0, $t);
+
+$t='DB handle method "pg_lo_open" returns a valid descriptor for writing';
+my $handle = $dbh->pg_lo_open($object, $W);
like ($handle, qr/^\d+$/o, $t);
isnt ($object, -1, $t);
-$t='DB handle method "lo_lseek" works when writing';
-$result = $dbh->func($handle, 0, 0, 'lo_lseek');
+$t='DB handle method "pg_lo_lseek" works when writing';
+$result = $dbh->pg_lo_lseek($handle, 0, 0);
is ($result, 0, $t);
isnt ($object, -1, $t);
-$t='DB handle method "lo_write" works';
+$t='DB handle method "pg_lo_write" works';
my $buf = 'tangelo mulberry passionfruit raspberry plantain' x 500;
-$result = $dbh->func($handle, $buf, length($buf), 'lo_write');
+$result = $dbh->pg_lo_write($handle, $buf, length($buf));
is ($result, length($buf), $t);
cmp_ok ($object, '>', 0, $t);
-$t='DB handle method "lo_close" works after write';
-$result = $dbh->func($handle, 'lo_close');
+$t='DB handle method "pg_lo_close" works after write';
+$result = $dbh->pg_lo_close($handle);
ok ($result, $t);
# Reopen for reading
-$t='DB handle method "lo_open" returns a valid descriptor for reading';
-$handle = $dbh->func($object, $R, 'lo_open');
+$t='DB handle method "pg_lo_open" returns a valid descriptor for reading';
+$handle = $dbh->pg_lo_open($object, $R);
like ($handle, qr/^\d+$/o, $t);
cmp_ok ($handle, 'eq', 0, $t);
-$t='DB handle method "lo_lseek" works when reading';
-$result = $dbh->func($handle, 11, 0, 'lo_lseek');
+$t='DB handle method "pg_lo_lseek" works when reading';
+$result = $dbh->pg_lo_lseek($handle, 11, 0);
is ($result, 11, $t);
-$t='DB handle method "lo_tell" works';
-$result = $dbh->func($handle, 'lo_tell');
+$t='DB handle method "pg_lo_tell" works';
+$result = $dbh->pg_lo_tell($handle);
is ($result, 11, $t);
-$t='DB handle method "lo_read" read back the same data that was written';
-$dbh->func($handle, 0, 0, 'lo_lseek');
+$t='DB handle method "pg_lo_read" read back the same data that was written';
+$dbh->pg_lo_lseek($handle, 0, 0);
my ($buf2,$data) = ('','');
-while ($dbh->func($handle, $data, 513, 'lo_read')) {
+while ($dbh->pg_lo_read($handle, $data, 513)) {
$buf2 .= $data;
}
is (length($buf), length($buf2), $t);
-$t='DB handle method "lo_close" works after read';
-$result = $dbh->func($handle, 'lo_close');
+$t='DB handle method "pg_lo_close" works after read';
+$result = $dbh->pg_lo_close($handle);
ok ($result, $t);
-$t='DB handle method "lo_unlink" works';
-$result = $dbh->func($object, 'lo_unlink');
+$t='DB handle method "pg_lo_unlink" works';
+$result = $dbh->pg_lo_unlink($object);
is ($result, 1, $t);
-$t='DB handle method "lo_unlink" fails when called second time';
-$result = $dbh->func($object, 'lo_unlink');
+$t='DB handle method "pg_lo_unlink" fails when called second time';
+$result = $dbh->pg_lo_unlink($object);
ok (!$result, $t);
$dbh->rollback();
@@ -1367,34 +1378,34 @@
eval {
require File::Temp;
};
- $@ and skip ('Must have File::Temp to test lo_import and lo_export', 8);
+ $@ and skip ('Must have File::Temp to test pg_lo_import and
pg_lo_export', 8);
- $t='DB handle method "lo_import" works';
+ $t='DB handle method "pg_lo_import" works';
my ($fh,$filename) = File::Temp::tmpnam();
print $fh "abc\ndef";
close $fh or warn 'Failed to close temporary file';
- my $handle = $dbh->func($filename, 'lo_import');
+ my $handle = $dbh->pg_lo_import($filename);
my $objid = $handle;
ok ($handle, $t);
- $t='DB handle method "lo_import" inserts correct data';
+ $t='DB handle method "pg_lo_import" inserts correct data';
$SQL = "SELECT data FROM pg_largeobject where loid = $handle";
$info = $dbh->selectall_arrayref($SQL)->[0][0];
is_deeply ($info, "abc\ndef", $t);
- $t='DB handle method "lo_open" works after "lo_insert"';
- $handle = $dbh->func($handle, $R, 'lo_open');
+ $t='DB handle method "pg_lo_open" works after "pg_lo_insert"';
+ $handle = $dbh->pg_lo_open($handle, $R);
like ($handle, qr/^\d+$/o, $t);
- $t='DB handle method "lo_read" returns correct data after "lo_import"';
+ $t='DB handle method "pg_lo_read" returns correct data after
"pg_lo_import"';
my $data = '';
- $result = $dbh->func($handle, $data, 100, 'lo_read');
+ $result = $dbh->pg_lo_read($handle, $data, 100);
is ($result, 7, $t);
is ($data, "abc\ndef", $t);
- $t='DB handle method "lo_export" works';
+ $t='DB handle method "pg_lo_export" works';
($fh,$filename) = File::Temp::tmpnam();
- $result = $dbh->func($objid, $filename, 'lo_export');
+ $result = $dbh->pg_lo_export($objid, $filename);
ok (-e $filename, $t);
seek($fh,0,1);
seek($fh,0,0);
@@ -1404,57 +1415,58 @@
close $fh or warn 'Could not close tempfile';
}
-## Same tests, but with AutoCommit on
+## Same pg_lo_* tests, but with AutoCommit on
+
$dbh->{AutoCommit}=1;
-$t='DB handle method "lo_creat" fails when AutoCommit on';
+$t='DB handle method "pg_lo_creat" fails when AutoCommit on';
eval {
- $dbh->func($W, 'lo_creat');
+ $dbh->pg_lo_creat($W);
};
-like ($@, qr{lo_creat when AutoCommit is on}, $t);
+like ($@, qr{pg_lo_creat when AutoCommit is on}, $t);
-$t='DB handle method "lo_open" fails with AutoCommit on';
+$t='DB handle method "pg_lo_open" fails with AutoCommit on';
eval {
- $dbh->func($object, $W, 'lo_open');
+ $dbh->pg_lo_open($object, $W);
};
-like ($@, qr{lo_open when AutoCommit is on}, $t);
+like ($@, qr{pg_lo_open when AutoCommit is on}, $t);
-$t='DB handle method "lo_read" fails with AutoCommit on';
+$t='DB handle method "pg_lo_read" fails with AutoCommit on';
eval {
- $dbh->func($object, $data, 0, 'lo_read');
+ $dbh->pg_lo_read($object, $data, 0);
};
-like ($@, qr{lo_read when AutoCommit is on}, $t);
+like ($@, qr{pg_lo_read when AutoCommit is on}, $t);
-$t='DB handle method "lo_lseek" fails with AutoCommit on';
+$t='DB handle method "pg_lo_lseek" fails with AutoCommit on';
eval {
- $dbh->func($handle, 0, 0, 'lo_lseek');
+ $dbh->pg_lo_lseek($handle, 0, 0);
};
-like ($@, qr{lo_lseek when AutoCommit is on}, $t);
+like ($@, qr{pg_lo_lseek when AutoCommit is on}, $t);
-$t='DB handle method "lo_write" fails with AutoCommit on';
+$t='DB handle method "pg_lo_write" fails with AutoCommit on';
$buf = 'tangelo mulberry passionfruit raspberry plantain' x 500;
eval {
- $dbh->func($handle, $buf, length($buf), 'lo_write');
+ $dbh->pg_lo_write($handle, $buf, length($buf));
};
-like ($@, qr{lo_write when AutoCommit is on}, $t);
+like ($@, qr{pg_lo_write when AutoCommit is on}, $t);
-$t='DB handle method "lo_close" fails with AutoCommit on';
+$t='DB handle method "pg_lo_close" fails with AutoCommit on';
eval {
- $dbh->func($handle, 'lo_close');
+ $dbh->pg_lo_close($handle);
};
-like ($@, qr{lo_close when AutoCommit is on}, $t);
+like ($@, qr{pg_lo_close when AutoCommit is on}, $t);
-$t='DB handle method "lo_tell" fails with AutoCommit on';
+$t='DB handle method "pg_lo_tell" fails with AutoCommit on';
eval {
- $dbh->func($handle, 'lo_tell');
+ $dbh->pg_lo_tell($handle);
};
-like ($@, qr{lo_tell when AutoCommit is on}, $t);
+like ($@, qr{pg_lo_tell when AutoCommit is on}, $t);
-$t='DB handle method "lo_unlink" fails with AutoCommit on';
+$t='DB handle method "pg_lo_unlink" fails with AutoCommit on';
eval {
- $dbh->func($object, 'lo_unlink');
+ $dbh->pg_lo_unlink($object);
};
-like ($@, qr{lo_unlink when AutoCommit is on}, $t);
+like ($@, qr{pg_lo_unlink when AutoCommit is on}, $t);
SKIP: {
@@ -1462,24 +1474,84 @@
eval {
require File::Temp;
};
- $@ and skip ('Must have File::Temp to test lo_import and lo_export', 2);
+ $@ and skip ('Must have File::Temp to test pg_lo_import and
pg_lo_export', 5);
- $t='DB handle method "lo_import" works (AutoCommit on)';
+ $t='DB handle method "pg_lo_import" works (AutoCommit on)';
my ($fh,$filename) = File::Temp::tmpnam();
print $fh "abc\ndef";
close $fh or warn 'Failed to close temporary file';
- my $handle = $dbh->func($filename, 'lo_import');
- my $objid = $handle;
+ my $handle = $dbh->pg_lo_import($filename);
ok ($handle, $t);
- $t='DB handle method "lo_import" inserts correct data (AutoCommit on)';
- $SQL = "SELECT data FROM pg_largeobject where loid = $handle";
- $info = $dbh->selectall_arrayref($SQL)->[0][0];
+ $t='DB handle method "pg_lo_import" inserts correct data (AutoCommit
on, begin_work not called)';
+ $SQL = "SELECT data FROM pg_largeobject where loid = ?";
+ $sth = $dbh->prepare($SQL);
+ $sth->execute($handle);
+ $info = $sth->fetchall_arrayref()->[0][0];
is_deeply ($info, "abc\ndef", $t);
- $t='DB handle method "lo_export" works (AutoCommit on)';
+ $t='DB handle method "pg_lo_import" works (AutoCommit on, begin_work
called, no command)';
+ $dbh->begin_work();
+ $handle = $dbh->pg_lo_import($filename);
+ ok ($handle, $t);
+ $sth->execute($handle);
+ $info = $sth->fetchall_arrayref()->[0][0];
+ is_deeply ($info, "abc\ndef", $t);
+ $dbh->rollback();
+
+ $t='DB handle method "pg_lo_import" works (AutoCommit on, begin_work
called, no command, rollback)';
+ $dbh->begin_work();
+ $handle = $dbh->pg_lo_import($filename);
+ ok ($handle, $t);
+ $dbh->rollback();
+ $sth->execute($handle);
+ $info = $sth->fetchall_arrayref()->[0][0];
+ is_deeply ($info, undef, $t);
+
+ $t='DB handle method "pg_lo_import" works (AutoCommit on, begin_work
called, second command)';
+ $dbh->begin_work();
+ $dbh->do('SELECT 123');
+ $handle = $dbh->pg_lo_import($filename);
+ ok ($handle, $t);
+ $sth->execute($handle);
+ $info = $sth->fetchall_arrayref()->[0][0];
+ is_deeply ($info, "abc\ndef", $t);
+ $dbh->rollback();
+
+ $t='DB handle method "pg_lo_import" works (AutoCommit on, begin_work
called, second command, rollback)';
+ $dbh->begin_work();
+ $dbh->do('SELECT 123');
+ $handle = $dbh->pg_lo_import($filename);
+ ok ($handle, $t);
+ $dbh->rollback();
+ $sth->execute($handle);
+ $info = $sth->fetchall_arrayref()->[0][0];
+ is_deeply ($info, undef, $t);
+
+ $t='DB handle method "pg_lo_import" works (AutoCommit not on, no
command)';
+ $dbh->{AutoCommit} = 0;
+ $dbh->commit();
+ $handle = $dbh->pg_lo_import($filename);
+ ok ($handle, $t);
+ $sth->execute($handle);
+ $info = $sth->fetchall_arrayref()->[0][0];
+ is_deeply ($info, "abc\ndef", $t);
+
+ $t='DB handle method "pg_lo_import" works (AutoCommit not on, second
command)';
+ $dbh->rollback();
+ $dbh->do('SELECT 123');
+ $handle = $dbh->pg_lo_import($filename);
+ ok ($handle, $t);
+ $sth->execute($handle);
+ $info = $sth->fetchall_arrayref()->[0][0];
+ is_deeply ($info, "abc\ndef", $t);
+
+ $dbh->{AutoCommit} = 1;
+
+ my $objid = $handle;
+ $t='DB handle method "pg_lo_export" works (AutoCommit on)';
($fh,$filename) = File::Temp::tmpnam();
- $result = $dbh->func($objid, $filename, 'lo_export');
+ $result = $dbh->pg_lo_export($objid, $filename);
ok (-e $filename, $t);
seek($fh,0,1);
seek($fh,0,0);