mirror of
https://github.com/psycopg/psycopg2.git
synced 2025-02-12 07:10:33 +03:00
Don't run a query at connection to detect client encoding.
Use PQparameterStatus() instead. This is only guaranteed in protocol 3.
This commit is contained in:
parent
a88d7ab424
commit
15bba2966f
|
@ -6,6 +6,9 @@
|
||||||
* psycopg/connection_int.c: dropped support for protocol 2 at compile
|
* psycopg/connection_int.c: dropped support for protocol 2 at compile
|
||||||
time and protocol 2-specific code.
|
time and protocol 2-specific code.
|
||||||
|
|
||||||
|
* psycopg/connection_int.c: don't run a query at connection to detect
|
||||||
|
client encoding: use PQparameterStatus() instead.
|
||||||
|
|
||||||
2010-11-11 Daniele Varrazzo <daniele.varrazzo@gmail.com>
|
2010-11-11 Daniele Varrazzo <daniele.varrazzo@gmail.com>
|
||||||
|
|
||||||
* lib/extras.py: build the namedtuple only once per execution, not once
|
* lib/extras.py: build the namedtuple only once per execution, not once
|
||||||
|
|
1
NEWS-2.3
1
NEWS-2.3
|
@ -15,6 +15,7 @@ psycopg 2.3 aims to expose some new features introduced in PostgreSQL 9.0.
|
||||||
|
|
||||||
- Dropped support for protocol 2: Psycopg 2.3 can only connect to PostgreSQL
|
- Dropped support for protocol 2: Psycopg 2.3 can only connect to PostgreSQL
|
||||||
servers with version at least 7.4.
|
servers with version at least 7.4.
|
||||||
|
- don't issue a query at every connection to detect the client encoding.
|
||||||
- `mogrify()` now supports unicode queries.
|
- `mogrify()` now supports unicode queries.
|
||||||
- subclasses of a type that can be adapted are adapted as the superclass.
|
- subclasses of a type that can be adapted are adapted as the superclass.
|
||||||
- `errorcodes` knows a couple of new codes introduced in PostgreSQL 9.0.
|
- `errorcodes` knows a couple of new codes introduced in PostgreSQL 9.0.
|
||||||
|
|
|
@ -45,7 +45,6 @@ extern "C" {
|
||||||
/* async connection building statuses */
|
/* async connection building statuses */
|
||||||
#define CONN_STATUS_CONNECTING 20
|
#define CONN_STATUS_CONNECTING 20
|
||||||
#define CONN_STATUS_DATESTYLE 21
|
#define CONN_STATUS_DATESTYLE 21
|
||||||
#define CONN_STATUS_CLIENT_ENCODING 22
|
|
||||||
|
|
||||||
/* async query execution status */
|
/* async query execution status */
|
||||||
#define ASYNC_DONE 0
|
#define ASYNC_DONE 0
|
||||||
|
@ -65,7 +64,6 @@ extern "C" {
|
||||||
later change it, she must know what she's doing... these are the queries we
|
later change it, she must know what she's doing... these are the queries we
|
||||||
need to issue */
|
need to issue */
|
||||||
#define psyco_datestyle "SET DATESTYLE TO 'ISO'"
|
#define psyco_datestyle "SET DATESTYLE TO 'ISO'"
|
||||||
#define psyco_client_encoding "SHOW client_encoding"
|
|
||||||
#define psyco_transaction_isolation "SHOW default_transaction_isolation"
|
#define psyco_transaction_isolation "SHOW default_transaction_isolation"
|
||||||
|
|
||||||
extern HIDDEN PyTypeObject connectionType;
|
extern HIDDEN PyTypeObject connectionType;
|
||||||
|
@ -118,7 +116,6 @@ typedef struct {
|
||||||
|
|
||||||
/* C-callable functions in connection_int.c and connection_ext.c */
|
/* C-callable functions in connection_int.c and connection_ext.c */
|
||||||
HIDDEN int conn_get_standard_conforming_strings(PGconn *pgconn);
|
HIDDEN int conn_get_standard_conforming_strings(PGconn *pgconn);
|
||||||
HIDDEN char *conn_get_encoding(PGresult *pgres);
|
|
||||||
HIDDEN int conn_get_isolation_level(PGresult *pgres);
|
HIDDEN int conn_get_isolation_level(PGresult *pgres);
|
||||||
HIDDEN int conn_get_protocol_version(PGconn *pgconn);
|
HIDDEN int conn_get_protocol_version(PGconn *pgconn);
|
||||||
HIDDEN void conn_notice_process(connectionObject *self);
|
HIDDEN void conn_notice_process(connectionObject *self);
|
||||||
|
|
|
@ -222,22 +222,36 @@ conn_get_standard_conforming_strings(PGconn *pgconn)
|
||||||
return equote;
|
return equote;
|
||||||
}
|
}
|
||||||
|
|
||||||
char *
|
/* Return a string containing the client_encoding setting.
|
||||||
conn_get_encoding(PGresult *pgres)
|
*
|
||||||
|
* Return a new string allocated by malloc(): use free() to free it.
|
||||||
|
* Return NULL in case of failure.
|
||||||
|
*/
|
||||||
|
static char *
|
||||||
|
conn_get_encoding(PGconn *pgconn)
|
||||||
{
|
{
|
||||||
char *tmp, *encoding;
|
const char *tmp, *i;
|
||||||
size_t i;
|
char *encoding, *j;
|
||||||
|
|
||||||
|
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");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
tmp = PQgetvalue(pgres, 0, 0);
|
|
||||||
encoding = malloc(strlen(tmp)+1);
|
encoding = malloc(strlen(tmp)+1);
|
||||||
if (encoding == NULL) {
|
if (encoding == NULL) {
|
||||||
PyErr_NoMemory();
|
PyErr_NoMemory();
|
||||||
IFCLEARPGRES(pgres);
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
for (i=0 ; i < strlen(tmp) ; i++)
|
|
||||||
encoding[i] = toupper(tmp[i]);
|
/* return in uppercase */
|
||||||
encoding[i] = '\0';
|
i = tmp;
|
||||||
|
j = encoding;
|
||||||
|
while (*i) { *j++ = toupper(*i++); }
|
||||||
|
*j = '\0';
|
||||||
|
|
||||||
return encoding;
|
return encoding;
|
||||||
}
|
}
|
||||||
|
@ -293,6 +307,11 @@ conn_setup(connectionObject *self, PGconn *pgconn)
|
||||||
PyErr_SetString(InterfaceError, "only protocol 3 supported");
|
PyErr_SetString(InterfaceError, "only protocol 3 supported");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
/* conn_get_encoding returns a malloc'd string */
|
||||||
|
self->encoding = conn_get_encoding(pgconn);
|
||||||
|
if (self->encoding == NULL) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
Py_BEGIN_ALLOW_THREADS;
|
Py_BEGIN_ALLOW_THREADS;
|
||||||
pthread_mutex_lock(&self->lock);
|
pthread_mutex_lock(&self->lock);
|
||||||
|
@ -322,33 +341,6 @@ conn_setup(connectionObject *self, PGconn *pgconn)
|
||||||
}
|
}
|
||||||
CLEARPGRES(pgres);
|
CLEARPGRES(pgres);
|
||||||
|
|
||||||
if (!green) {
|
|
||||||
Py_UNBLOCK_THREADS;
|
|
||||||
pgres = PQexec(pgconn, psyco_client_encoding);
|
|
||||||
Py_BLOCK_THREADS;
|
|
||||||
} else {
|
|
||||||
pgres = psyco_exec_green(self, psyco_client_encoding);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pgres == NULL || PQresultStatus(pgres) != PGRES_TUPLES_OK) {
|
|
||||||
PyErr_SetString(OperationalError, "can't fetch client_encoding");
|
|
||||||
IFCLEARPGRES(pgres);
|
|
||||||
Py_UNBLOCK_THREADS;
|
|
||||||
pthread_mutex_unlock(&self->lock);
|
|
||||||
Py_BLOCK_THREADS;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* conn_get_encoding returns a malloc'd string */
|
|
||||||
self->encoding = conn_get_encoding(pgres);
|
|
||||||
if (self->encoding == NULL) {
|
|
||||||
Py_UNBLOCK_THREADS;
|
|
||||||
pthread_mutex_unlock(&self->lock);
|
|
||||||
Py_BLOCK_THREADS;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
CLEARPGRES(pgres);
|
|
||||||
|
|
||||||
if (!green) {
|
if (!green) {
|
||||||
Py_UNBLOCK_THREADS;
|
Py_UNBLOCK_THREADS;
|
||||||
pgres = PQexec(pgconn, psyco_transaction_isolation);
|
pgres = PQexec(pgconn, psyco_transaction_isolation);
|
||||||
|
@ -638,6 +630,11 @@ _conn_poll_setup_async(connectionObject *self)
|
||||||
PyErr_SetString(InterfaceError, "only protocol 3 supported");
|
PyErr_SetString(InterfaceError, "only protocol 3 supported");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
/* conn_get_encoding returns a malloc'd string */
|
||||||
|
self->encoding = conn_get_encoding(self->pgconn);
|
||||||
|
if (self->encoding == NULL) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
/* asynchronous connections always use isolation level 0, the user is
|
/* asynchronous connections always use isolation level 0, the user is
|
||||||
* expected to manage the transactions himself, by sending
|
* expected to manage the transactions himself, by sending
|
||||||
|
@ -667,40 +664,12 @@ _conn_poll_setup_async(connectionObject *self)
|
||||||
}
|
}
|
||||||
CLEARPGRES(pgres);
|
CLEARPGRES(pgres);
|
||||||
|
|
||||||
Dprintf("conn_poll: status -> CONN_STATUS_CLIENT_ENCODING");
|
|
||||||
self->status = CONN_STATUS_CLIENT_ENCODING;
|
|
||||||
if (0 == pq_send_query(self, psyco_client_encoding)) {
|
|
||||||
PyErr_SetString(OperationalError, PQerrorMessage(self->pgconn));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
Dprintf("conn_poll: async_status -> ASYNC_WRITE");
|
|
||||||
self->async_status = ASYNC_WRITE;
|
|
||||||
res = PSYCO_POLL_WRITE;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case CONN_STATUS_CLIENT_ENCODING:
|
|
||||||
res = _conn_poll_query(self);
|
|
||||||
if (res == PSYCO_POLL_OK) {
|
|
||||||
res = PSYCO_POLL_ERROR;
|
|
||||||
pgres = pq_get_last_result(self);
|
|
||||||
if (pgres == NULL || PQresultStatus(pgres) != PGRES_TUPLES_OK) {
|
|
||||||
PyErr_SetString(OperationalError, "can't fetch client_encoding");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* conn_get_encoding returns a malloc'd string */
|
|
||||||
self->encoding = conn_get_encoding(pgres);
|
|
||||||
CLEARPGRES(pgres);
|
|
||||||
if (self->encoding == NULL) { break; }
|
|
||||||
|
|
||||||
Dprintf("conn_poll: status -> CONN_STATUS_READY");
|
Dprintf("conn_poll: status -> CONN_STATUS_READY");
|
||||||
self->status = CONN_STATUS_READY;
|
self->status = CONN_STATUS_READY;
|
||||||
res = PSYCO_POLL_OK;
|
res = PSYCO_POLL_OK;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -732,7 +701,6 @@ conn_poll(connectionObject *self)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CONN_STATUS_DATESTYLE:
|
case CONN_STATUS_DATESTYLE:
|
||||||
case CONN_STATUS_CLIENT_ENCODING:
|
|
||||||
res = _conn_poll_setup_async(self);
|
res = _conn_poll_setup_async(self);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user