static void overwrite(PGconn *conn, Oid lobjId, int start, int len) { int lobj_fd; char *buf; int nbytes; int nwritten; int i; lobj_fd = lo_open(conn, lobjId, INV_WRITE); if (lobj_fd < 0) fprintf(stderr, "cannot open large object %u", lobjId); lo_lseek(conn, lobj_fd, start, SEEK_SET); buf = malloc(len + 1); for (i = 0; i < len; i++) buf[i] = 'X'; buf[i] = '\0'; nwritten = 0; while (len - nwritten > 0) { nbytes = lo_write(conn, lobj_fd, buf + nwritten, len - nwritten); nwritten += nbytes; if (nbytes <= 0) { fprintf(stderr, "\nWRITE FAILED!\n"); break; } } free(buf); fprintf(stderr, "\n"); lo_close(conn, lobj_fd); }
static void pickout(PGconn *conn, Oid lobjId, pg_int64 start, int len) { int lobj_fd; char *buf; int nbytes; int nread; lobj_fd = lo_open(conn, lobjId, INV_READ); if (lobj_fd < 0) fprintf(stderr, "cannot open large object %u", lobjId); if (lo_lseek64(conn, lobj_fd, start, SEEK_SET) < 0) fprintf(stderr, "error in lo_lseek64: %s", PQerrorMessage(conn)); if (lo_tell64(conn, lobj_fd) != start) fprintf(stderr, "error in lo_tell64: %s", PQerrorMessage(conn)); buf = malloc(len + 1); nread = 0; while (len - nread > 0) { nbytes = lo_read(conn, lobj_fd, buf, len - nread); buf[nbytes] = '\0'; fprintf(stderr, ">>> %s", buf); nread += nbytes; if (nbytes <= 0) break; /* no more data? */ } free(buf); fprintf(stderr, "\n"); lo_close(conn, lobj_fd); }
CAMLprim value lo_open_stub(value v_conn, value v_oid) { CAMLparam1(v_conn); PGconn *conn = get_conn(v_conn); value v_res; caml_enter_blocking_section(); v_res = Val_int(lo_open(conn, Int_val(v_oid), INV_READ | INV_WRITE)); caml_leave_blocking_section(); CAMLreturn(v_res); }
static void my_truncate(PGconn *conn, Oid lobjId, pg_int64 len) { int lobj_fd; lobj_fd = lo_open(conn, lobjId, INV_READ | INV_WRITE); if (lobj_fd < 0) fprintf(stderr, "cannot open large object %u", lobjId); if (lo_truncate64(conn, lobj_fd, len) < 0) fprintf(stderr, "error in lo_truncate64: %s", PQerrorMessage(conn)); lo_close(conn, lobj_fd); }
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; } } }
/* * exportFile - * export large object "lobjOid" to file "out_filename" * */ static void exportFile(PGconn *conn, Oid lobjId, char *filename) { int lobj_fd; char buf[BUFSIZE]; int nbytes, tmp; int fd; /* * open the large object */ lobj_fd = lo_open(conn, lobjId, INV_READ); if (lobj_fd < 0) fprintf(stderr, "cannot open large object %u", lobjId); /* * open the file to be written to */ fd = open(filename, O_CREAT | O_WRONLY | O_TRUNC, 0666); if (fd < 0) { /* error */ fprintf(stderr, "cannot open unix file\"%s\"", filename); } /* * read in from the inversion file and write to the Unix file */ while ((nbytes = lo_read(conn, lobj_fd, buf, BUFSIZE)) > 0) { tmp = write(fd, buf, nbytes); if (tmp < nbytes) { fprintf(stderr, "error while writing \"%s\"", filename); } } lo_close(conn, lobj_fd); close(fd); return; }
/* * 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; }
/* ************************************************************************* */ int pg_lo_open(ClipMachine* mp, SQLCONN* c, unsigned int OID, int mode){ PG_CONN *conn = (PG_CONN*)c; int oid_fd; int lo_mode=0; if ((mode&1) == 1) lo_mode |= INV_READ; if ((mode&2) == 2) lo_mode |= INV_WRITE; if(!conn->at){ _clip_trap_err(mp,0,0,0,subsys,ER_START,er_start); return 1; } oid_fd = lo_open(conn->conn, OID, lo_mode); if (oid_fd < 0){ _clip_trap_err(mp,0,0,0,subsys,ER_START,er_blob_open); return 1; } _clip_retni(mp,oid_fd); return 0; }
int lobject_open(lobjectObject *self, connectionObject *conn, Oid oid, int mode, Oid new_oid, const char *new_file) { int retvalue = -1; PGresult *pgres = NULL; char *error = NULL; Py_BEGIN_ALLOW_THREADS; pthread_mutex_lock(&(self->conn->lock)); retvalue = pq_begin_locked(self->conn, &pgres, &error); 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_name */ if (oid == InvalidOid) { if (new_file) self->oid = lo_import(self->conn->pgconn, new_file); else self->oid = lo_create(self->conn->pgconn, new_oid); 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 = INV_WRITE; } else { self->oid = oid; if (mode == 0) mode = INV_READ; } /* if the oid is a real one we try to open with the given mode, unless the mode is -1, meaning "don't open!" */ if (mode != -1) { self->fd = lo_open(self->conn->pgconn, self->oid, mode); Dprintf("lobject_open: large object opened with fd = %d", self->fd); if (self->fd == -1) { collect_error(self->conn, &error); retvalue = -1; goto end; } } /* set the mode for future reference */ switch (mode) { case -1: self->smode = "n"; break; case INV_READ: self->smode = "r"; break; case INV_WRITE: self->smode = "w"; break; case INV_READ+INV_WRITE: self->smode = "rw"; break; } retvalue = 0; end: pthread_mutex_unlock(&(self->conn->lock)); Py_END_ALLOW_THREADS; if (retvalue < 0) pq_complete_error(self->conn, &pgres, &error); return retvalue; }
static int pgsql_stmt_get_col(pdo_stmt_t *stmt, int colno, char **ptr, zend_ulong *len, int *caller_frees ) { pdo_pgsql_stmt *S = (pdo_pgsql_stmt*)stmt->driver_data; struct pdo_column_data *cols = stmt->columns; size_t tmp_len; if (!S->result) { return 0; } /* We have already increased count by 1 in pgsql_stmt_fetch() */ if (PQgetisnull(S->result, S->current_row - 1, colno)) { /* Check if we got NULL */ *ptr = NULL; *len = 0; } else { *ptr = PQgetvalue(S->result, S->current_row - 1, colno); *len = PQgetlength(S->result, S->current_row - 1, colno); switch (cols[colno].param_type) { case PDO_PARAM_INT: ZEND_ATOL(S->cols[colno].intval, *ptr); *ptr = (char *) &(S->cols[colno].intval); *len = sizeof(zend_long); break; case PDO_PARAM_BOOL: S->cols[colno].boolval = **ptr == 't' ? 1: 0; *ptr = (char *) &(S->cols[colno].boolval); *len = sizeof(zend_bool); break; case PDO_PARAM_LOB: if (S->cols[colno].pgsql_type == OIDOID) { /* ooo, a real large object */ char *end_ptr; Oid oid = (Oid)strtoul(*ptr, &end_ptr, 10); int loid = lo_open(S->H->server, oid, INV_READ); if (loid >= 0) { *ptr = (char*)pdo_pgsql_create_lob_stream(&stmt->database_object_handle, loid, oid); *len = 0; return *ptr ? 1 : 0; } *ptr = NULL; *len = 0; return 0; } else { char *tmp_ptr = (char *)PQunescapeBytea((unsigned char *)*ptr, &tmp_len); if (!tmp_ptr) { /* PQunescapeBytea returned an error */ *len = 0; return 0; } if (!tmp_len) { /* Empty string, return as empty stream */ *ptr = (char *)php_stream_memory_open(TEMP_STREAM_READONLY, "", 0); PQfreemem(tmp_ptr); *len = 0; } else { *ptr = estrndup(tmp_ptr, tmp_len); PQfreemem(tmp_ptr); *len = tmp_len; *caller_frees = 1; } } break; case PDO_PARAM_NULL: case PDO_PARAM_STR: case PDO_PARAM_STMT: case PDO_PARAM_INPUT_OUTPUT: case PDO_PARAM_ZVAL: default: break; } } return 1; }
/* * lo_export - * exports an (inversion) large object. * returns -1 upon failure, 1 if OK */ int lo_export(PGconn *conn, Oid lobjId, const char *filename) { int result = 1; int fd; int nbytes, tmp; char buf[LO_BUFSIZE]; int lobj; char sebuf[256]; /* * open the large object. */ lobj = lo_open(conn, lobjId, INV_READ); if (lobj == -1) { /* we assume lo_open() already set a suitable error message */ return -1; } /* * create the file to be written to */ fd = open(filename, O_CREAT | O_WRONLY | O_TRUNC | 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))); (void) lo_close(conn, lobj); return -1; } /* * read in from the large object and write to the file */ while ((nbytes = lo_read(conn, lobj, buf, LO_BUFSIZE)) > 0) { tmp = write(fd, buf, nbytes); if (tmp != nbytes) { printfPQExpBuffer(&conn->errorMessage, libpq_gettext("could not write to file \"%s\": %s\n"), filename, pqStrerror(errno, sebuf, sizeof(sebuf))); (void) lo_close(conn, lobj); (void) close(fd); return -1; } } /* * If lo_read() 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 skip lo_close() if we got a * failure result. */ if (nbytes < 0 || lo_close(conn, lobj) != 0) { /* assume lo_read() or lo_close() left a suitable error message */ result = -1; } if (close(fd)) { printfPQExpBuffer(&conn->errorMessage, libpq_gettext("could not write to file \"%s\": %s\n"), filename, pqStrerror(errno, sebuf, sizeof(sebuf))); result = -1; } return result; }
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; }
int Pg_lo_open(ClientData cData, Tcl_Interp *interp, int argc, CONST84 char *argv[]) { PGconn *conn; int lobjId; int mode; int fd; if (argc != 4) { Tcl_AppendResult(interp, "Wrong # of arguments\n", "pg_lo_open connection lobjOid mode", 0); return TCL_ERROR; } conn = PgGetConnectionId(interp, argv[1], (Pg_ConnectionId **) NULL); if (conn == (PGconn *) NULL) return TCL_ERROR; lobjId = atoi(argv[2]); if (strlen(argv[3]) < 1 || strlen(argv[3]) > 2) { Tcl_AppendResult(interp, "mode argument must be 'r', 'w', or 'rw'", 0); return TCL_ERROR; } switch (argv[3][0]) { case 'r': case 'R': mode = INV_READ; break; case 'w': case 'W': mode = INV_WRITE; break; default: Tcl_AppendResult(interp, "mode argument must be 'r', 'w', or 'rw'", 0); return TCL_ERROR; } switch (argv[3][1]) { case '\0': break; case 'r': case 'R': mode |= INV_READ; break; case 'w': case 'W': mode |= INV_WRITE; break; default: Tcl_AppendResult(interp, "mode argument must be 'r', 'w', or 'rw'", 0); return TCL_ERROR; } fd = lo_open(conn, lobjId, mode); sprintf(interp->result, "%d", fd); return TCL_OK; }
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; }