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; }
/* Read the client encoding from the connection. * * Store the encoding in the pgconn->encoding field and the name of the * matching python codec in codec. The buffers are allocated on the Python * heap. * * Return 0 on success, else nonzero. */ RAISES_NEG static int conn_read_encoding(connectionObject *self, PGconn *pgconn) { char *enc = NULL, *codec = NULL; const char *tmp; int rv = -1; tmp = PQparameterStatus(pgconn, "client_encoding"); Dprintf("conn_connect: client encoding: %s", tmp ? tmp : "(none)"); if (!tmp) { PyErr_SetString(OperationalError, "server didn't return client encoding"); goto exit; } if (0 > clear_encoding_name(tmp, &enc)) { goto exit; } /* Look for this encoding in Python codecs. */ if (0 > conn_encoding_to_codec(enc, &codec)) { goto exit; } /* Good, success: store the encoding/codec in the connection. */ PyMem_Free(self->encoding); self->encoding = enc; enc = NULL; PyMem_Free(self->codec); self->codec = codec; codec = NULL; rv = 0; exit: PyMem_Free(enc); PyMem_Free(codec); return rv; }
/* Return the Python encoding from a PostgreSQL encoding. * * Optionally return the clean version of the postgres encoding too */ PyObject * conn_pgenc_to_pyenc(const char *encoding, char **clean_encoding) { char *pgenc = NULL; PyObject *rv = NULL; if (0 > clear_encoding_name(encoding, &pgenc)) { goto exit; } if (!(rv = PyDict_GetItemString(psycoEncodings, pgenc))) { PyErr_Format(OperationalError, "no Python encoding for PostgreSQL encoding '%s'", pgenc); goto exit; } Py_INCREF(rv); if (clean_encoding) { *clean_encoding = pgenc; } else { PyMem_Free(pgenc); } exit: return rv; }
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; }