RAISES_NEG int conn_set_session(connectionObject *self, const char *isolevel, const char *readonly, const char *deferrable, int autocommit) { PGresult *pgres = NULL; char *error = NULL; int res = -1; Py_BEGIN_ALLOW_THREADS; pthread_mutex_lock(&self->lock); if (isolevel) { Dprintf("conn_set_session: setting isolation to %s", isolevel); if ((res = pq_set_guc_locked(self, "default_transaction_isolation", isolevel, &pgres, &error, &_save))) { goto endlock; } } if (readonly) { Dprintf("conn_set_session: setting read only to %s", readonly); if ((res = pq_set_guc_locked(self, "default_transaction_read_only", readonly, &pgres, &error, &_save))) { goto endlock; } } if (deferrable) { Dprintf("conn_set_session: setting deferrable to %s", deferrable); if ((res = pq_set_guc_locked(self, "default_transaction_deferrable", deferrable, &pgres, &error, &_save))) { goto endlock; } } if (self->autocommit != autocommit) { Dprintf("conn_set_session: setting autocommit to %d", autocommit); self->autocommit = autocommit; } res = 0; endlock: pthread_mutex_unlock(&self->lock); Py_END_ALLOW_THREADS; if (res < 0) { pq_complete_error(self, &pgres, &error); } return res; }
RAISES_NEG int conn_setup(connectionObject *self) { int rv = -1; self->equote = conn_get_standard_conforming_strings(self->pgconn); self->server_version = conn_get_server_version(self->pgconn); self->protocol = conn_get_protocol_version(self->pgconn); if (3 != self->protocol) { PyErr_SetString(InterfaceError, "only protocol 3 supported"); goto exit; } if (0 > conn_read_encoding(self, self->pgconn)) { goto exit; } if (0 > conn_setup_cancel(self, self->pgconn)) { goto exit; } Py_BEGIN_ALLOW_THREADS; pthread_mutex_lock(&self->lock); Py_BLOCK_THREADS; if (!dsn_has_replication(self->dsn) && !conn_is_datestyle_ok(self->pgconn)) { int res; Py_UNBLOCK_THREADS; res = pq_set_guc_locked(self, "datestyle", "ISO", &_save); Py_BLOCK_THREADS; if (res < 0) { pq_complete_error(self); goto unlock; } } /* for reset */ self->autocommit = 0; self->isolevel = ISOLATION_LEVEL_DEFAULT; self->readonly = STATE_DEFAULT; self->deferrable = STATE_DEFAULT; /* success */ rv = 0; unlock: Py_UNBLOCK_THREADS; pthread_mutex_unlock(&self->lock); Py_END_ALLOW_THREADS; exit: return rv; }
RAISES_NEG int conn_setup(connectionObject *self, PGconn *pgconn) { PGresult *pgres = NULL; char *error = NULL; self->equote = conn_get_standard_conforming_strings(pgconn); self->server_version = conn_get_server_version(pgconn); self->protocol = conn_get_protocol_version(self->pgconn); if (3 != self->protocol) { PyErr_SetString(InterfaceError, "only protocol 3 supported"); return -1; } if (0 > conn_read_encoding(self, pgconn)) { return -1; } self->cancel = conn_get_cancel(self->pgconn); if (self->cancel == NULL) { PyErr_SetString(OperationalError, "can't get cancellation key"); return -1; } Py_BEGIN_ALLOW_THREADS; pthread_mutex_lock(&self->lock); Py_BLOCK_THREADS; if (psyco_green() && (0 > pq_set_non_blocking(self, 1))) { return -1; } if (!conn_is_datestyle_ok(self->pgconn)) { int res; Py_UNBLOCK_THREADS; res = pq_set_guc_locked(self, "datestyle", "ISO", &pgres, &error, &_save); Py_BLOCK_THREADS; if (res < 0) { pq_complete_error(self, &pgres, &error); return -1; } } /* for reset */ self->autocommit = 0; Py_UNBLOCK_THREADS; pthread_mutex_unlock(&self->lock); Py_END_ALLOW_THREADS; return 0; }
RAISES_NEG int conn_set_client_encoding(connectionObject *self, const char *pgenc) { PGresult *pgres = NULL; char *error = NULL; int res = -1; char *clean_enc = NULL; /* We must know what python encoding this encoding is. */ if (0 > clear_encoding_name(pgenc, &clean_enc)) { goto exit; } /* If the current encoding is equal to the requested one we don't issue any query to the backend */ if (strcmp(self->encoding, clean_enc) == 0) return 0; 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; } endlock: pthread_mutex_unlock(&self->lock); Py_END_ALLOW_THREADS; if (res < 0) { pq_complete_error(self, &pgres, &error); goto exit; } res = conn_store_encoding(self, pgenc); Dprintf("conn_set_client_encoding: encoding set to %s", self->encoding); exit: PyMem_Free(clean_enc); return res; }
/* Change the state of the session */ RAISES_NEG int conn_set_session(connectionObject *self, int autocommit, int isolevel, int readonly, int deferrable) { int rv = -1; int want_autocommit = autocommit == SRV_STATE_UNCHANGED ? self->autocommit : autocommit; if (deferrable != SRV_STATE_UNCHANGED && self->server_version < 90100) { PyErr_SetString(ProgrammingError, "the 'deferrable' setting is only available" " from PostgreSQL 9.1"); goto exit; } /* Promote an isolation level to one of the levels supported by the server */ if (self->server_version < 80000) { if (isolevel == ISOLATION_LEVEL_READ_UNCOMMITTED) { isolevel = ISOLATION_LEVEL_READ_COMMITTED; } else if (isolevel == ISOLATION_LEVEL_REPEATABLE_READ) { isolevel = ISOLATION_LEVEL_SERIALIZABLE; } } Py_BEGIN_ALLOW_THREADS; pthread_mutex_lock(&self->lock); if (want_autocommit) { /* we are or are going in autocommit state, so no BEGIN will be issued: * configure the session with the characteristics requested */ if (isolevel != SRV_STATE_UNCHANGED) { if (0 > pq_set_guc_locked(self, "default_transaction_isolation", srv_isolevels[isolevel], &_save)) { goto endlock; } } if (readonly != SRV_STATE_UNCHANGED) { if (0 > pq_set_guc_locked(self, "default_transaction_read_only", srv_state_guc[readonly], &_save)) { goto endlock; } } if (deferrable != SRV_STATE_UNCHANGED) { if (0 > pq_set_guc_locked(self, "default_transaction_deferrable", srv_state_guc[deferrable], &_save)) { goto endlock; } } } else if (self->autocommit) { /* we are moving from autocommit to not autocommit, so revert the * characteristics to defaults to let BEGIN do its work */ if (self->isolevel != ISOLATION_LEVEL_DEFAULT) { if (0 > pq_set_guc_locked(self, "default_transaction_isolation", "default", &_save)) { goto endlock; } } if (self->readonly != STATE_DEFAULT) { if (0 > pq_set_guc_locked(self, "default_transaction_read_only", "default", &_save)) { goto endlock; } } if (self->server_version >= 90100 && self->deferrable != STATE_DEFAULT) { if (0 > pq_set_guc_locked(self, "default_transaction_deferrable", "default", &_save)) { goto endlock; } } } if (autocommit != SRV_STATE_UNCHANGED) { self->autocommit = autocommit; } if (isolevel != SRV_STATE_UNCHANGED) { self->isolevel = isolevel; } if (readonly != SRV_STATE_UNCHANGED) { self->readonly = readonly; } if (deferrable != SRV_STATE_UNCHANGED) { self->deferrable = deferrable; } rv = 0; endlock: pthread_mutex_unlock(&self->lock); Py_END_ALLOW_THREADS; if (rv < 0) { pq_complete_error(self); goto exit; } Dprintf( "conn_set_session: autocommit %d, isolevel %d, readonly %d, deferrable %d", autocommit, isolevel, readonly, deferrable); exit: return rv; }
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 proceed 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; }