Re: libpg: large object problems - Mailing list pgsql-novice

From Seth Nickell
Subject Re: libpg: large object problems
Date
Msg-id 1051999914.16826.26.camel@beauty.stanford.edu
Whole thread Raw
In response to Re: libpg: large object problems  (greg@turnstep.com)
Responses Re: libpg: large object problems
Re: libpg: large object problems
List pgsql-novice
> > I'm trying to figure out how to get large objects working using libpg.
> > The problem is that whenever I do an lo_open on an object, I get back
> > "-1" as the file descriptor (and of course, an lo_read on that fails).
>
> Large object operations must be done within a transaction. Try issuing
> a "begin" before you call lo_creat:

Oh! Thanks Greg. I shouldn't have missed that in the docs.

I'm unfortunately still having problems :-( Can I only do one lo_
operation per transaction? e.g. is this valid?

  PQexec(dbConn, "begin")
  id = lo_creat(...)
  fd = lo_open(id, ...)
  lo_write(fd, ...)
  PQexec(dbConn, "end")

If I only put one lo_ operation per transaction, I get back "0" for the
fd (is this a valid fd?). I guess this is an improvement over -1 ;-) It
seems I can do an lo_write at this point, but lo_read still doesn't let
me read anything.

I've pasted the test code I'm using below. When I run it on my computer,
I get:

id is: 567036
WRITE fd is 0
Wrote 68 bytes
READ fd is 0
object size is 0
Read 0 bytes
Buffer Contents {

}

Thanks,

-Seth

-------------Test Source Code--------------

#include <stdio.h>
#include <libpq-fe.h> //in /usr/include
#include <libpq/libpq-fs.h>
#include <string.h>

static PGconn *dbConn = NULL;

static int writeData (PGconn *dbConn) {
  Oid id;
  char *buffer;
  PGresult *res;
  int bytes_written, fd;

  res = PQexec(dbConn, "begin");
  PQclear(res);

  id = lo_creat (dbConn, INV_READ | INV_WRITE);
  printf ("id is: %d\n", id);

  res = PQexec(dbConn, "end");
  PQclear(res);

  res = PQexec(dbConn, "begin");
  PQclear(res);

  fd = lo_open (dbConn, id, INV_WRITE);
  printf ("WRITE fd is %d\n", fd);

  buffer = "Test, test test. Test of the emergency broadcast
system.\nTest test!\n";
  bytes_written = lo_write(dbConn, fd, buffer, strlen(buffer));
  printf ("Wrote %d bytes\n", bytes_written);

  lo_close(dbConn, id);

  res = PQexec(dbConn, "end");
  PQclear(res);

  return id;
}

static void readData (PGconn *dbConn, Oid id) {
  PGresult *res;
  char *buffer;
  int bytes_read, fd, object_size;

  res = PQexec(dbConn, "begin");
  PQclear(res);

  fd = lo_open (dbConn, id, INV_WRITE);
  printf ("READ fd is %d\n", fd);

  /* Get the Object's Size by seeking to the end and back */
  lo_lseek(dbConn, fd, 0, SEEK_END);
  object_size = lo_tell(dbConn, fd);
  printf ("object size is %d\n", object_size);
  lo_lseek(dbConn, fd, 0, SEEK_SET);

  /* Do the read */
  buffer = (char *)malloc (sizeof(char) * (object_size + 1));
  buffer[0] = '\0';
  bytes_read = lo_read(dbConn, fd, buffer, object_size);

  res = PQexec(dbConn, "end");
  PQclear(res);

  printf ("Read %d bytes\n", bytes_read);
  printf ("Buffer Contents {\n%s\n}\n", buffer);
}

int main(int argc, char **argv) {
  char * error;
  Oid id;

  dbConn = PQconnectdb("");
  error = PQerrorMessage(dbConn);

  if(strlen(error) > 0){
    fprintf(stderr, "DB connection error to gargamel: %s\n", error);
    return -1;
  }

  id = writeData(dbConn);
  readData(dbConn, id);

  PQfinish(dbConn);

  return 0;
}


pgsql-novice by date:

Previous
From: "Israel Calderon"
Date:
Subject: Error Uninstalling 7.2.2 on Mandrake 9.0
Next
From: Joseph Healy
Date:
Subject: Re: Error Uninstalling 7.2.2 on Mandrake 9.0