mirror of
https://github.com/psycopg/psycopg2.git
synced 2024-11-23 01:16:34 +03:00
Store a normalized version of the PG encoding in the connection
This way looking up into extensions.encodings will not break.
This commit is contained in:
parent
88803695ac
commit
19653a88ec
|
@ -273,22 +273,19 @@ clean_encoding_name(const char *enc)
|
||||||
*
|
*
|
||||||
* Return a new copy of the codec name allocated on the Python heap,
|
* Return a new copy of the codec name allocated on the Python heap,
|
||||||
* NULL with exception in case of error.
|
* NULL with exception in case of error.
|
||||||
|
*
|
||||||
|
* 'enc' should be already normalized (uppercase, no - or _).
|
||||||
*/
|
*/
|
||||||
static char *
|
static char *
|
||||||
conn_encoding_to_codec(const char *enc)
|
conn_encoding_to_codec(const char *enc)
|
||||||
{
|
{
|
||||||
char *tmp;
|
char *tmp;
|
||||||
Py_ssize_t size;
|
Py_ssize_t size;
|
||||||
char *norm_enc = NULL;
|
|
||||||
PyObject *pyenc = NULL;
|
PyObject *pyenc = NULL;
|
||||||
char *rv = NULL;
|
char *rv = NULL;
|
||||||
|
|
||||||
if (!(norm_enc = clean_encoding_name(enc))) {
|
|
||||||
goto exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Find the Py codec name from the PG encoding */
|
/* Find the Py codec name from the PG encoding */
|
||||||
if (!(pyenc = PyDict_GetItemString(psycoEncodings, norm_enc))) {
|
if (!(pyenc = PyDict_GetItemString(psycoEncodings, enc))) {
|
||||||
PyErr_Format(OperationalError,
|
PyErr_Format(OperationalError,
|
||||||
"no Python codec for client encoding '%s'", enc);
|
"no Python codec for client encoding '%s'", enc);
|
||||||
goto exit;
|
goto exit;
|
||||||
|
@ -308,7 +305,6 @@ conn_encoding_to_codec(const char *enc)
|
||||||
rv = psycopg_strdup(tmp, size);
|
rv = psycopg_strdup(tmp, size);
|
||||||
|
|
||||||
exit:
|
exit:
|
||||||
PyMem_Free(norm_enc);
|
|
||||||
Py_XDECREF(pyenc);
|
Py_XDECREF(pyenc);
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
@ -336,7 +332,7 @@ conn_read_encoding(connectionObject *self, PGconn *pgconn)
|
||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(enc = psycopg_strdup(tmp, 0))) {
|
if (!(enc = clean_encoding_name(tmp))) {
|
||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -998,21 +994,23 @@ conn_set_client_encoding(connectionObject *self, const char *enc)
|
||||||
PGresult *pgres = NULL;
|
PGresult *pgres = NULL;
|
||||||
char *error = NULL;
|
char *error = NULL;
|
||||||
char query[48];
|
char query[48];
|
||||||
int res = 0;
|
int res = 1;
|
||||||
char *codec;
|
char *codec = NULL;
|
||||||
|
char *clean_enc = NULL;
|
||||||
|
|
||||||
/* If the current encoding is equal to the requested one we don't
|
/* If the current encoding is equal to the requested one we don't
|
||||||
issue any query to the backend */
|
issue any query to the backend */
|
||||||
if (strcmp(self->encoding, enc) == 0) return 0;
|
if (strcmp(self->encoding, enc) == 0) return 0;
|
||||||
|
|
||||||
/* We must know what python codec this encoding is. */
|
/* We must know what python codec this encoding is. */
|
||||||
if (!(codec = conn_encoding_to_codec(enc))) { return -1; }
|
if (!(clean_enc = clean_encoding_name(enc))) { goto exit; }
|
||||||
|
if (!(codec = conn_encoding_to_codec(clean_enc))) { goto exit; }
|
||||||
|
|
||||||
Py_BEGIN_ALLOW_THREADS;
|
Py_BEGIN_ALLOW_THREADS;
|
||||||
pthread_mutex_lock(&self->lock);
|
pthread_mutex_lock(&self->lock);
|
||||||
|
|
||||||
/* set encoding, no encoding string is longer than 24 bytes */
|
/* set encoding, no encoding string is longer than 24 bytes */
|
||||||
PyOS_snprintf(query, 47, "SET client_encoding = '%s'", enc);
|
PyOS_snprintf(query, 47, "SET client_encoding = '%s'", clean_enc);
|
||||||
|
|
||||||
/* abort the current transaction, to set the encoding ouside of
|
/* abort the current transaction, to set the encoding ouside of
|
||||||
transactions */
|
transactions */
|
||||||
|
@ -1027,21 +1025,18 @@ conn_set_client_encoding(connectionObject *self, const char *enc)
|
||||||
/* no error, we can proceeed and store the new encoding */
|
/* no error, we can proceeed and store the new encoding */
|
||||||
{
|
{
|
||||||
char *tmp = self->encoding;
|
char *tmp = self->encoding;
|
||||||
self->encoding = NULL;
|
self->encoding = clean_enc;
|
||||||
PyMem_Free(tmp);
|
PyMem_Free(tmp);
|
||||||
}
|
clean_enc = NULL;
|
||||||
if (!(self->encoding = psycopg_strdup(enc, 0))) {
|
|
||||||
res = 1; /* don't call pq_complete_error below */
|
|
||||||
goto endlock;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Store the python codec too. */
|
/* Store the python codec too. */
|
||||||
{
|
{
|
||||||
char *tmp = self->codec;
|
char *tmp = self->codec;
|
||||||
self->codec = NULL;
|
self->codec = codec;
|
||||||
PyMem_Free(tmp);
|
PyMem_Free(tmp);
|
||||||
|
codec = NULL;
|
||||||
}
|
}
|
||||||
self->codec = codec;
|
|
||||||
|
|
||||||
Dprintf("conn_set_client_encoding: set encoding to %s (codec: %s)",
|
Dprintf("conn_set_client_encoding: set encoding to %s (codec: %s)",
|
||||||
self->encoding, self->codec);
|
self->encoding, self->codec);
|
||||||
|
@ -1054,6 +1049,10 @@ endlock:
|
||||||
if (res < 0)
|
if (res < 0)
|
||||||
pq_complete_error(self, &pgres, &error);
|
pq_complete_error(self, &pgres, &error);
|
||||||
|
|
||||||
|
exit:
|
||||||
|
PyMem_Free(clean_enc);
|
||||||
|
PyMem_Free(codec);
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user