CAMLprim value lo_creat_stub(value v_conn) { CAMLparam1(v_conn); PGconn *conn = get_conn(v_conn); value v_res; caml_enter_blocking_section(); v_res = Val_int(lo_creat(conn, INV_READ | INV_WRITE)); caml_leave_blocking_section(); CAMLreturn(v_res); }
/* ************************************************************************* */ int pg_lo_create(ClipMachine* mp, SQLCONN* c, unsigned int OID){ PG_CONN *conn = (PG_CONN*)c; Oid lobjId; if(!conn->at){ _clip_trap_err(mp,0,0,0,subsys,ER_START,er_start); return 1; } lobjId = lo_creat(conn->conn, OID); if (lobjId == 0){ _clip_trap_err(mp,0,0,0,subsys,ER_START,er_blob_create); return 1; } _clip_retni(mp, lobjId); return 0; }
virtual void bind(int col,std::istream &in) { check(col); if(blob_ == bytea_type) { std::ostringstream ss; ss << in.rdbuf(); params_values_[col-1]=ss.str(); params_set_[col-1]=binary_param; } else { Oid id = 0; int fd = -1; try { id = lo_creat(conn_, INV_READ|INV_WRITE); if(id == 0) throw pqerror(conn_,"failed to create large object"); fd = lo_open(conn_,id,INV_READ | INV_WRITE); if(fd < 0) throw pqerror(conn_,"failed to open large object for writing"); char buf[4096]; for(;;) { in.read(buf,sizeof(buf)); int bytes_read = in.gcount(); if(bytes_read > 0) { int n = lo_write(conn_,fd,buf,bytes_read); if(n < 0) { throw pqerror(conn_,"failed writing to large object"); } } if(bytes_read < int(sizeof(buf))) break; } int r = lo_close(conn_,fd); fd=-1; if(r < 0) throw pqerror(conn_,"error closing large object after write"); bind(col,id); } catch(...) { if(fd<-1) lo_close(conn_,fd); if(id!=0) lo_unlink(conn_,id); throw; } } }
/* * importFile - * import file "in_filename" into database as large object "lobjOid" * */ static Oid importFile(PGconn *conn, char *filename) { Oid lobjId; int lobj_fd; char buf[BUFSIZE]; int nbytes, tmp; int fd; /* * open the file to be read in */ fd = open(filename, O_RDONLY, 0666); if (fd < 0) { /* error */ fprintf(stderr, "cannot open unix file\"%s\"\n", filename); } /* * create the large object */ lobjId = lo_creat(conn, INV_READ | INV_WRITE); if (lobjId == 0) fprintf(stderr, "cannot create large object"); lobj_fd = lo_open(conn, lobjId, INV_WRITE); /* * read in from the Unix file and write to the inversion file */ while ((nbytes = read(fd, buf, BUFSIZE)) > 0) { tmp = lo_write(conn, lobj_fd, buf, nbytes); if (tmp < nbytes) fprintf(stderr, "error while reading \"%s\"", filename); } close(fd); lo_close(conn, lobj_fd); return lobjId; }
static Oid lo_import_internal(PGconn *conn, const char *filename, const Oid oid) { int fd; int nbytes, tmp; char buf[LO_BUFSIZE]; Oid lobjOid; int lobj; char sebuf[256]; /* * open the file to be read in */ fd = open(filename, O_RDONLY | PG_BINARY, 0666); if (fd < 0) { /* error */ printfPQExpBuffer(&conn->errorMessage, libpq_gettext("could not open file \"%s\": %s\n"), filename, pqStrerror(errno, sebuf, sizeof(sebuf))); return InvalidOid; } /* * create an inversion object */ if (oid == InvalidOid) lobjOid = lo_creat(conn, INV_READ | INV_WRITE); else lobjOid = lo_create(conn, oid); if (lobjOid == InvalidOid) { /* we assume lo_create() already set a suitable error message */ (void) close(fd); return InvalidOid; } lobj = lo_open(conn, lobjOid, INV_WRITE); if (lobj == -1) { /* we assume lo_open() already set a suitable error message */ (void) close(fd); return InvalidOid; } /* * read in from the file and write to the large object */ while ((nbytes = read(fd, buf, LO_BUFSIZE)) > 0) { tmp = lo_write(conn, lobj, buf, nbytes); if (tmp != nbytes) { /* * If lo_write() failed, we are now in an aborted transaction so * there's no need for lo_close(); furthermore, if we tried it * we'd overwrite the useful error result with a useless one. So * just nail the doors shut and get out of town. */ (void) close(fd); return InvalidOid; } } if (nbytes < 0) { printfPQExpBuffer(&conn->errorMessage, libpq_gettext("could not read from file \"%s\": %s\n"), filename, pqStrerror(errno, sebuf, sizeof(sebuf))); lobjOid = InvalidOid; } (void) close(fd); if (lo_close(conn, lobj) != 0) { /* we assume lo_close() already set a suitable error message */ return InvalidOid; } return lobjOid; }
RAISES_NEG int lobject_open(lobjectObject *self, connectionObject *conn, Oid oid, const char *smode, Oid new_oid, const char *new_file) { int retvalue = -1; PGresult *pgres = NULL; char *error = NULL; int pgmode = 0; int mode; if (0 > (mode = _lobject_parse_mode(smode))) { return -1; } Py_BEGIN_ALLOW_THREADS; pthread_mutex_lock(&(self->conn->lock)); retvalue = pq_begin_locked(self->conn, &pgres, &error, &_save); if (retvalue < 0) goto end; /* if the oid is InvalidOid we create a new lob before opening it or we import a file from the FS, depending on the value of new_file */ if (oid == InvalidOid) { if (new_file) self->oid = lo_import(self->conn->pgconn, new_file); else { /* Use lo_creat when possible to be more middleware-friendly. See ticket #88. */ if (new_oid != InvalidOid) self->oid = lo_create(self->conn->pgconn, new_oid); else self->oid = lo_creat(self->conn->pgconn, INV_READ | INV_WRITE); } Dprintf("lobject_open: large object created with oid = %d", self->oid); if (self->oid == InvalidOid) { collect_error(self->conn, &error); retvalue = -1; goto end; } mode = (mode & ~LOBJECT_READ) | LOBJECT_WRITE; } else { self->oid = oid; } /* if the oid is a real one we try to open with the given mode */ if (mode & LOBJECT_READ) { pgmode |= INV_READ; } if (mode & LOBJECT_WRITE) { pgmode |= INV_WRITE; } if (pgmode) { self->fd = lo_open(self->conn->pgconn, self->oid, pgmode); Dprintf("lobject_open: large object opened with mode = %i fd = %d", pgmode, self->fd); if (self->fd == -1) { collect_error(self->conn, &error); retvalue = -1; goto end; } } /* set the mode for future reference */ self->mode = mode; Py_BLOCK_THREADS; self->smode = _lobject_unparse_mode(mode); Py_UNBLOCK_THREADS; if (NULL == self->smode) { retvalue = 1; /* exception already set */ goto end; } retvalue = 0; end: pthread_mutex_unlock(&(self->conn->lock)); Py_END_ALLOW_THREADS; if (retvalue < 0) pq_complete_error(self->conn, &pgres, &error); /* if retvalue > 0, an exception is already set */ return retvalue; }