mirror of
https://github.com/psycopg/psycopg2.git
synced 2024-11-11 03:26:37 +03:00
Store python encoding and decoding functions in the connection
Unused for now: will be used instead of 'pyenc', which is to be dropped.
This commit is contained in:
parent
17a74cc771
commit
a255e4e1c6
|
@ -83,6 +83,7 @@ struct connectionObject {
|
||||||
char *dsn; /* data source name */
|
char *dsn; /* data source name */
|
||||||
char *critical; /* critical error on this connection */
|
char *critical; /* critical error on this connection */
|
||||||
char *encoding; /* current backend encoding */
|
char *encoding; /* current backend encoding */
|
||||||
|
/* TODO: drop */
|
||||||
char *pyenc; /* connection encoding python name */
|
char *pyenc; /* connection encoding python name */
|
||||||
|
|
||||||
long int closed; /* 1 means connection has been closed;
|
long int closed; /* 1 means connection has been closed;
|
||||||
|
@ -125,6 +126,9 @@ struct connectionObject {
|
||||||
|
|
||||||
/* Pointer to a decoding function, e.g. PyUnicode_DecodeUTF8 */
|
/* Pointer to a decoding function, e.g. PyUnicode_DecodeUTF8 */
|
||||||
PyObject *(*cdecoder)(const char *, Py_ssize_t, const char *);
|
PyObject *(*cdecoder)(const char *, Py_ssize_t, const char *);
|
||||||
|
|
||||||
|
PyObject *pyencoder; /* python codec encoding function */
|
||||||
|
PyObject *pydecoder; /* python codec decoding function */
|
||||||
};
|
};
|
||||||
|
|
||||||
/* map isolation level values into a numeric const */
|
/* map isolation level values into a numeric const */
|
||||||
|
|
|
@ -364,7 +364,7 @@ exit:
|
||||||
|
|
||||||
/* set fast access functions according to the currently selected encoding
|
/* set fast access functions according to the currently selected encoding
|
||||||
*/
|
*/
|
||||||
void
|
static void
|
||||||
conn_set_fast_codec(connectionObject *self)
|
conn_set_fast_codec(connectionObject *self)
|
||||||
{
|
{
|
||||||
Dprintf("conn_set_fast_codec: encoding=%s", self->pyenc);
|
Dprintf("conn_set_fast_codec: encoding=%s", self->pyenc);
|
||||||
|
@ -386,21 +386,72 @@ conn_set_fast_codec(connectionObject *self)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Convert a Postgres encoding into Python encoding and decoding functions.
|
||||||
|
*
|
||||||
|
* Return 0 on success, else -1 and set an exception.
|
||||||
|
*/
|
||||||
|
RAISES_NEG static int
|
||||||
|
conn_get_python_codec(const char *encoding, PyObject **pyenc, PyObject **pydec)
|
||||||
|
{
|
||||||
|
int rv = -1;
|
||||||
|
char *pgenc = NULL;
|
||||||
|
PyObject *encname = NULL;
|
||||||
|
PyObject *m = NULL, *f = NULL, *codec = NULL;
|
||||||
|
PyObject *enc_tmp = NULL, *dec_tmp = NULL;
|
||||||
|
|
||||||
|
if (0 > clear_encoding_name(encoding, &pgenc)) { goto exit; }
|
||||||
|
|
||||||
|
/* Find the Py encoding name from the PG encoding */
|
||||||
|
if (!(encname = PyDict_GetItemString(psycoEncodings, pgenc))) {
|
||||||
|
PyErr_Format(OperationalError,
|
||||||
|
"no Python encoding for PostgreSQL encoding '%s'", pgenc);
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
Py_INCREF(encname);
|
||||||
|
|
||||||
|
/* Look up the python codec */
|
||||||
|
if (!(m = PyImport_ImportModule("codecs"))) { goto exit; }
|
||||||
|
if (!(f = PyObject_GetAttrString(m, "lookup"))) { goto exit; }
|
||||||
|
if (!(codec = PyObject_CallFunctionObjArgs(f, encname, NULL))) { goto exit; }
|
||||||
|
if (!(enc_tmp = PyObject_GetAttrString(codec, "encode"))) { goto exit; }
|
||||||
|
if (!(dec_tmp = PyObject_GetAttrString(codec, "decode"))) { goto exit; }
|
||||||
|
|
||||||
|
/* success */
|
||||||
|
*pyenc = enc_tmp; enc_tmp = NULL;
|
||||||
|
*pydec = dec_tmp; dec_tmp = NULL;
|
||||||
|
rv = 0;
|
||||||
|
|
||||||
|
exit:
|
||||||
|
Py_XDECREF(enc_tmp);
|
||||||
|
Py_XDECREF(dec_tmp);
|
||||||
|
Py_XDECREF(codec);
|
||||||
|
Py_XDECREF(f);
|
||||||
|
Py_XDECREF(m);
|
||||||
|
Py_XDECREF(encname);
|
||||||
|
PyMem_Free(pgenc);
|
||||||
|
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Store the encoding in the pgconn->encoding field and set the other related
|
/* Store the encoding in the pgconn->encoding field and set the other related
|
||||||
* encoding fields in the connection structure.
|
* encoding fields in the connection structure.
|
||||||
*
|
*
|
||||||
* Return 0 on success, else -1.
|
* Return 0 on success, else -1 and set an exception.
|
||||||
*/
|
*/
|
||||||
RAISES_NEG static int
|
RAISES_NEG static int
|
||||||
conn_set_encoding(connectionObject *self, const char *encoding)
|
conn_set_encoding(connectionObject *self, const char *encoding)
|
||||||
{
|
{
|
||||||
int rv = -1;
|
int rv = -1;
|
||||||
char *pgenc = NULL, *pyenc = NULL;
|
char *pgenc = NULL, *pyenc = NULL;
|
||||||
|
PyObject *enc_tmp = NULL, *dec_tmp = NULL;
|
||||||
|
|
||||||
if (0 > clear_encoding_name(encoding, &pgenc)) { goto exit; }
|
if (0 > clear_encoding_name(encoding, &pgenc)) { goto exit; } /* TODO: drop */
|
||||||
|
|
||||||
/* Look for this encoding in Python codecs. */
|
/* Look for this encoding in Python codecs. */
|
||||||
if (0 > conn_pgenc_to_pyenc(pgenc, &pyenc)) { goto exit; }
|
if (0 > conn_pgenc_to_pyenc(pgenc, &pyenc)) { goto exit; } /* TODO: drop */
|
||||||
|
|
||||||
|
if (0 > conn_get_python_codec(encoding, &enc_tmp, &dec_tmp)) { goto exit; }
|
||||||
|
|
||||||
/* Good, success: store the encoding/pyenc in the connection. */
|
/* Good, success: store the encoding/pyenc in the connection. */
|
||||||
{
|
{
|
||||||
|
@ -411,17 +462,28 @@ conn_set_encoding(connectionObject *self, const char *encoding)
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
|
/* TODO: drop */
|
||||||
char *tmp = self->pyenc;
|
char *tmp = self->pyenc;
|
||||||
self->pyenc = pyenc;
|
self->pyenc = pyenc;
|
||||||
PyMem_Free(tmp);
|
PyMem_Free(tmp);
|
||||||
pyenc = NULL;
|
pyenc = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Py_CLEAR(self->pyencoder);
|
||||||
|
self->pyencoder = enc_tmp;
|
||||||
|
enc_tmp = NULL;
|
||||||
|
|
||||||
|
Py_CLEAR(self->pydecoder);
|
||||||
|
self->pydecoder = dec_tmp;
|
||||||
|
dec_tmp = NULL;
|
||||||
|
|
||||||
conn_set_fast_codec(self);
|
conn_set_fast_codec(self);
|
||||||
|
|
||||||
rv = 0;
|
rv = 0;
|
||||||
|
|
||||||
exit:
|
exit:
|
||||||
|
Py_XDECREF(enc_tmp);
|
||||||
|
Py_XDECREF(dec_tmp);
|
||||||
PyMem_Free(pgenc);
|
PyMem_Free(pgenc);
|
||||||
PyMem_Free(pyenc);
|
PyMem_Free(pyenc);
|
||||||
return rv;
|
return rv;
|
||||||
|
|
|
@ -1141,6 +1141,9 @@ connection_clear(connectionObject *self)
|
||||||
Py_CLEAR(self->notifies);
|
Py_CLEAR(self->notifies);
|
||||||
Py_CLEAR(self->string_types);
|
Py_CLEAR(self->string_types);
|
||||||
Py_CLEAR(self->binary_types);
|
Py_CLEAR(self->binary_types);
|
||||||
|
Py_CLEAR(self->cursor_factory);
|
||||||
|
Py_CLEAR(self->pyencoder);
|
||||||
|
Py_CLEAR(self->pydecoder);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1216,6 +1219,9 @@ connection_traverse(connectionObject *self, visitproc visit, void *arg)
|
||||||
Py_VISIT(self->notifies);
|
Py_VISIT(self->notifies);
|
||||||
Py_VISIT(self->string_types);
|
Py_VISIT(self->string_types);
|
||||||
Py_VISIT(self->binary_types);
|
Py_VISIT(self->binary_types);
|
||||||
|
Py_VISIT(self->cursor_factory);
|
||||||
|
Py_VISIT(self->pyencoder);
|
||||||
|
Py_VISIT(self->pydecoder);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user