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; }
RAISES_NEG int conn_switch_isolation_level(connectionObject *self, int level) { PGresult *pgres = NULL; char *error = NULL; int curr_level; int ret = -1; /* use only supported levels on older PG versions */ if (self->server_version < 80000) { if (level == ISOLATION_LEVEL_READ_UNCOMMITTED) level = ISOLATION_LEVEL_READ_COMMITTED; else if (level == ISOLATION_LEVEL_REPEATABLE_READ) level = ISOLATION_LEVEL_SERIALIZABLE; } if (-1 == (curr_level = conn_get_isolation_level(self))) { return -1; } if (curr_level == level) { /* no need to change level */ return 0; } /* Emulate the previous semantic of set_isolation_level() using the * functions currently available. */ Py_BEGIN_ALLOW_THREADS; pthread_mutex_lock(&self->lock); /* terminate the current transaction if any */ if ((ret = pq_abort_locked(self, &pgres, &error, &_save))) { goto endlock; } if (level == 0) { if ((ret = pq_set_guc_locked(self, "default_transaction_isolation", "default", &pgres, &error, &_save))) { goto endlock; } self->autocommit = 1; } else { /* find the name of the requested level */ const IsolationLevel *isolevel = conn_isolevels; while ((++isolevel)->name) { if (level == isolevel->value) { break; } } if (!isolevel->name) { ret = -1; error = strdup("bad isolation level value"); goto endlock; } if ((ret = pq_set_guc_locked(self, "default_transaction_isolation", isolevel->name, &pgres, &error, &_save))) { goto endlock; } self->autocommit = 0; } Dprintf("conn_switch_isolation_level: switched to level %d", level); endlock: pthread_mutex_unlock(&self->lock); Py_END_ALLOW_THREADS; if (ret < 0) { pq_complete_error(self, &pgres, &error); } return ret; }
RAISES_NEG int conn_set_client_encoding(connectionObject *self, const char *enc) { PGresult *pgres = NULL; char *error = NULL; int res = -1; char *codec = NULL; char *clean_enc = NULL; /* If the current encoding is equal to the requested one we don't issue any query to the backend */ if (strcmp(self->encoding, enc) == 0) return 0; /* We must know what python codec this encoding is. */ if (0 > clear_encoding_name(enc, &clean_enc)) { goto exit; } if (0 > conn_encoding_to_codec(clean_enc, &codec)) { goto exit; } Py_BEGIN_ALLOW_THREADS; pthread_mutex_lock(&self->lock); /* abort the current transaction, to set the encoding ouside of transactions */ if ((res = pq_abort_locked(self, &pgres, &error, &_save))) { goto endlock; } if ((res = pq_set_guc_locked(self, "client_encoding", clean_enc, &pgres, &error, &_save))) { goto endlock; } /* no error, we can proceeed and store the new encoding */ { char *tmp = self->encoding; self->encoding = clean_enc; PyMem_Free(tmp); clean_enc = NULL; } /* Store the python codec too. */ { char *tmp = self->codec; self->codec = codec; PyMem_Free(tmp); codec = NULL; } Dprintf("conn_set_client_encoding: set encoding to %s (codec: %s)", self->encoding, self->codec); endlock: pthread_mutex_unlock(&self->lock); Py_END_ALLOW_THREADS; if (res < 0) pq_complete_error(self, &pgres, &error); exit: PyMem_Free(clean_enc); PyMem_Free(codec); return res; }