/*
$Id: large_object.c,v 1.6 2005/01/03 15:23:49 turnstep Exp $
Copyright (c) 2003-2005 PostgreSQL Global Development Group
You may distribute under the terms of either the GNU General Public
License or the Artistic License, as specified in the Perl README file.
*/
int
pg_db_lo_open (dbh, lobjId, mode)
SV *dbh;
unsigned int lobjId;
int mode;
{
D_imp_dbh(dbh);
return lo_open(imp_dbh->conn, lobjId, mode);
}
int
pg_db_lo_close (dbh, fd)
SV *dbh;
int fd;
{
D_imp_dbh(dbh);
return lo_close(imp_dbh->conn, fd);
}
int
pg_db_lo_read (dbh, fd, buf, len)
SV *dbh;
int fd;
char *buf;
int len;
{
D_imp_dbh(dbh);
return lo_read(imp_dbh->conn, fd, buf, len);
}
int
pg_db_lo_write (dbh, fd, buf, len)
SV *dbh;
int fd;
char *buf;
int len;
{
D_imp_dbh(dbh);
return lo_write(imp_dbh->conn, fd, buf, len);
}
int
pg_db_lo_lseek (dbh, fd, offset, whence)
SV *dbh;
int fd;
int offset;
int whence;
{
D_imp_dbh(dbh);
return lo_lseek(imp_dbh->conn, fd, offset, whence);
}
unsigned int
pg_db_lo_creat (dbh, mode)
SV *dbh;
int mode;
{
D_imp_dbh(dbh);
return lo_creat(imp_dbh->conn, mode);
}
int
pg_db_lo_tell (dbh, fd)
SV *dbh;
int fd;
{
D_imp_dbh(dbh);
return lo_tell(imp_dbh->conn, fd);
}
int
pg_db_lo_unlink (dbh, lobjId)
SV *dbh;
unsigned int lobjId;
{
D_imp_dbh(dbh);
return lo_unlink(imp_dbh->conn, lobjId);
}
unsigned int
pg_db_lo_import (dbh, filename)
SV *dbh;
char *filename;
{
D_imp_dbh(dbh);
return lo_import(imp_dbh->conn, filename);
}
int
pg_db_lo_export (dbh, lobjId, filename)
SV *dbh;
unsigned int lobjId;
char *filename;
{
D_imp_dbh(dbh);
return lo_export(imp_dbh->conn, lobjId, filename);
}
int
dbd_st_blob_read (sth, imp_sth, lobjId, offset, len, destrv, destoffset)
SV *sth;
imp_sth_t *imp_sth;
int lobjId;
long offset;
long len;
SV *destrv;
long destoffset;
{
D_imp_dbh_from_sth;
int ret, lobj_fd, nbytes, nread;
/* PGresult* result;
ExecStatusType status; */
SV *bufsv;
char *tmp;
if (dbis->debug >= 1) { PerlIO_printf(DBILOGFP, "dbd_st_blob_read\n"); }
/* safety check */
if (lobjId <= 0) {
pg_error(sth, -1, "dbd_st_blob_read: lobjId <= 0");
return 0;
}
if (offset < 0) {
pg_error(sth, -1, "dbd_st_blob_read: offset < 0");
return 0;
}
if (len < 0) {
pg_error(sth, -1, "dbd_st_blob_read: len < 0");
return 0;
}
if (! SvROK(destrv)) {
pg_error(sth, -1, "dbd_st_blob_read: destrv not a reference");
return 0;
}
if (destoffset < 0) {
pg_error(sth, -1, "dbd_st_blob_read: destoffset < 0");
return 0;
}
/* dereference destination and ensure it's writable string */
bufsv = SvRV(destrv);
if (! destoffset) {
sv_setpvn(bufsv, "", 0);
}
/* execute begin
result = PQexec(imp_dbh->conn, "begin");
status = result ? PQresultStatus(result) : -1;
PQclear(result);
if (status != PGRES_COMMAND_OK) {
pg_error(sth, status, PQerrorMessage(imp_dbh->conn));
return 0;
}
*/
/* open large object */
lobj_fd = lo_open(imp_dbh->conn, lobjId, INV_READ);
if (lobj_fd < 0) {
pg_error(sth, -1, PQerrorMessage(imp_dbh->conn));
return 0;
}
/* seek on large object */
if (offset > 0) {
ret = lo_lseek(imp_dbh->conn, lobj_fd, offset, SEEK_SET);
if (ret < 0) {
pg_error(sth, -1, PQerrorMessage(imp_dbh->conn));
return 0;
}
}
/* read from large object */
nread = 0;
SvGROW(bufsv, destoffset + nread + BUFSIZ + 1);
tmp = (SvPVX(bufsv)) + destoffset + nread;
while ((nbytes = lo_read(imp_dbh->conn, lobj_fd, tmp, BUFSIZ)) > 0) {
nread += nbytes;
/* break if user wants only a specified chunk */
if (len > 0 && nread > len) {
nread = len;
break;
}
SvGROW(bufsv, destoffset + nread + BUFSIZ + 1);
tmp = (SvPVX(bufsv)) + destoffset + nread;
}
/* terminate string */
SvCUR_set(bufsv, destoffset + nread);
*SvEND(bufsv) = '\0';
/* close large object */
ret = lo_close(imp_dbh->conn, lobj_fd);
if (ret < 0) {
pg_error(sth, -1, PQerrorMessage(imp_dbh->conn));
return 0;
}
/* execute end
result = PQexec(imp_dbh->conn, "end");
status = result ? PQresultStatus(result) : -1;
PQclear(result);
if (status != PGRES_COMMAND_OK) {
pg_error(sth, status, PQerrorMessage(imp_dbh->conn));
return 0;
}
*/
return nread;
}
/* end of large_object.c */