[DBD::Pg] Quick dump of lo_truncate support. Not working yet.

dbdpg-commits-gENoVmVU/[email protected] Mon, 21 Oct 2013 12:38:41 -0400
Newsgroups gmane.comp.db.postgresql.dbdpg.cvs
Message-ID <[email protected]>
Committed by Greg Sabino Mullane <greg-O9fzpki4YnJWk0Htik3J/[email protected]>

Quick dump of lo_truncate support. Not working yet.

---
 Pg.pm          |  8 ++++++++
 Pg.xs          | 10 ++++++++++
 dbdimp.c       | 26 ++++++++++++++++++++++++++
 dbdimp.h       |  2 ++
 t/03dbmethod.t | 17 ++++++++++++++++-
 5 files changed, 62 insertions(+), 1 deletion(-)

diff --git a/Pg.pm b/Pg.pm
index 5c67128..a6ee67f 100644
--- a/Pg.pm
+++ b/Pg.pm
@@ -153,6 +153,7 @@ use 5.008001;
 			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_truncate');
 			DBD::Pg::db->install_method('pg_lo_close');
 			DBD::Pg::db->install_method('pg_lo_unlink');
 			DBD::Pg::db->install_method('pg_lo_import');
@@ -2144,6 +2145,13 @@ location and C<undef> upon failure. This function cannot be used if AutoCommit i
 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_truncate
+
+  $loc = $dbh->pg_lo_truncate($lobj_fd, $len);
+
+Truncates the given large object to the new size. Returns C<undef> on failure, and 0 on success.
+This function cannot be used if AutoCommit is enabled.
+
 =item lo_close
 
   $lobj_fd = $dbh->pg_lo_close($lobj_fd);
diff --git a/Pg.xs b/Pg.xs
index 8e7fc9b..13d7779 100644
--- a/Pg.xs
+++ b/Pg.xs
@@ -475,6 +475,16 @@ pg_lo_tell(dbh, fd)
 
 
 void
+pg_lo_truncate(dbh, fd, len)
+	SV * dbh
+	int fd
+    size_t len
+	CODE:
+		const int ret = pg_db_lo_truncate(dbh, fd, len);
+		ST(0) = (ret >= 0) ? sv_2mortal(newSViv(ret)) : &PL_sv_undef;
+
+
+void
 pg_lo_close(dbh, fd)
 	SV * dbh
 	int fd
diff --git a/dbdimp.c b/dbdimp.c
index 3fa6a42..0792b86 100644
--- a/dbdimp.c
+++ b/dbdimp.c
@@ -4477,6 +4477,7 @@ int pg_db_lo_lseek (SV * dbh, int fd, int offset, int whence)
 
 }
 
+
 /* ================================================================== */
 int pg_db_lo_tell (SV * dbh, int fd)
 {
@@ -4502,6 +4503,31 @@ int pg_db_lo_tell (SV * dbh, int fd)
 }
 
 /* ================================================================== */
+int pg_db_lo_truncate (SV * dbh, int fd, size_t len)
+{
+
+	dTHX;
+	D_imp_dbh(dbh);
+
+	if (TSTART_slow) TRC(DBILOGFP, "%sBegin pg_db_lo_truncate (fd: %d length: %d)\n",
+						 THEADER_slow, fd, (int)len);
+
+	if (DBIc_has(imp_dbh, DBIcf_AutoCommit)) {
+		croak("Cannot call pg_lo_truncate when AutoCommit is on");
+	}
+
+	if (!pg_db_start_txn(aTHX_ dbh,imp_dbh))
+		return -1;
+
+	if (TLIBPQ_slow) {
+		TRC(DBILOGFP, "%slo_truncate\n", THEADER_slow);
+	}
+
+	return lo_truncate(imp_dbh->conn, fd, len); /* 0 success, <0 on error */
+
+}
+
+/* ================================================================== */
 int pg_db_lo_unlink (SV * dbh, unsigned int lobjId)
 {
 
diff --git a/dbdimp.h b/dbdimp.h
index 6058ff1..380890e 100644
--- a/dbdimp.h
+++ b/dbdimp.h
@@ -232,6 +232,8 @@ int pg_db_lo_lseek (SV *dbh, int fd, int offset, int whence);
 
 int pg_db_lo_tell (SV *dbh, int fd);
 
+int pg_db_lo_truncate (SV *dbh, int fd, size_t len);
+
 int pg_db_lo_unlink (SV *dbh, unsigned int lobjId);
 
 unsigned int pg_db_lo_import (SV *dbh, char *filename);
diff --git a/t/03dbmethod.t b/t/03dbmethod.t
index c831175..e86d0de 100644
--- a/t/03dbmethod.t
+++ b/t/03dbmethod.t
@@ -1424,7 +1424,7 @@ $t='DB handle method "pg_lo_tell" works';
 $result = $dbh->pg_lo_tell($handle);
 is ($result, 11, $t);
 
-$t='DB handle method "pg_lo_read" read back the same data that was written';
+$t='DB handle method "pg_lo_read" reads back the same data that was written';
 $dbh->pg_lo_lseek($handle, 0, 0);
 my ($buf2,$data) = ('','');
 while ($dbh->pg_lo_read($handle, $data, 513)) {
@@ -1432,6 +1432,21 @@ while ($dbh->pg_lo_read($handle, $data, 513)) {
 }
 is (length($buf), length($buf2), $t);
 
+SKIP: {
+
+	$pgversion < 80300 and skip ('Server version 8.3 or greater needed for pg_lo_truncate tests', 2);
+	$t='DB handle method "pg_lo_truncate" works';
+	$result = $dbh->pg_lo_truncate($handle, 4);
+	is ($result, 0, $t);
+
+	$dbh->pg_lo_lseek($handle, 0, 0);
+	($buf2,$data) = ('','');
+	while ($dbh->pg_lo_read($handle, $data, 100)) {
+		$buf2 .= $data;
+	}
+	is (length($buf2), 4, $t);
+}
+
 $t='DB handle method "pg_lo_close" works after read';
 $result = $dbh->pg_lo_close($handle);
 ok ($result, $t);
-- 
1.8.4