Committed by Greg Sabino Mullane <[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

Reply via email to