Skip to content

Commit 17a74cc

Browse files
committed
Setting connection encoding refactored
Code paths to read encoding on connection and to store the new connection in the structure after changing it in the backend unified into a single function.
1 parent f439ca6 commit 17a74cc

File tree

1 file changed

+56
-51
lines changed

1 file changed

+56
-51
lines changed

psycopg/connection_int.c

Lines changed: 56 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -362,7 +362,7 @@ conn_pgenc_to_pyenc(const char *pgenc, char **pyenc)
362362
}
363363

364364

365-
/* set fast access functions according to the currently selected codec
365+
/* set fast access functions according to the currently selected encoding
366366
*/
367367
void
368368
conn_set_fast_codec(connectionObject *self)
@@ -386,46 +386,36 @@ conn_set_fast_codec(connectionObject *self)
386386
}
387387

388388

389-
/* Read the client encoding from the connection.
389+
/* Store the encoding in the pgconn->encoding field and set the other related
390+
* encoding fields in the connection structure.
390391
*
391-
* Store the encoding in the pgconn->encoding field and the name of the
392-
* matching python encoding in pyenc. The buffers are allocated on the Python
393-
* heap.
394-
*
395-
* Return 0 on success, else nonzero.
392+
* Return 0 on success, else -1.
396393
*/
397394
RAISES_NEG static int
398-
conn_read_encoding(connectionObject *self, PGconn *pgconn)
395+
conn_set_encoding(connectionObject *self, const char *encoding)
399396
{
400-
char *pgenc = NULL, *pyenc = NULL;
401-
const char *tmp;
402397
int rv = -1;
398+
char *pgenc = NULL, *pyenc = NULL;
403399

404-
tmp = PQparameterStatus(pgconn, "client_encoding");
405-
Dprintf("conn_connect: client encoding: %s", tmp ? tmp : "(none)");
406-
if (!tmp) {
407-
PyErr_SetString(OperationalError,
408-
"server didn't return client encoding");
409-
goto exit;
410-
}
411-
412-
if (0 > clear_encoding_name(tmp, &pgenc)) {
413-
goto exit;
414-
}
400+
if (0 > clear_encoding_name(encoding, &pgenc)) { goto exit; }
415401

416402
/* Look for this encoding in Python codecs. */
417-
if (0 > conn_pgenc_to_pyenc(pgenc, &pyenc)) {
418-
goto exit;
419-
}
403+
if (0 > conn_pgenc_to_pyenc(pgenc, &pyenc)) { goto exit; }
420404

421405
/* Good, success: store the encoding/pyenc in the connection. */
422-
PyMem_Free(self->encoding);
423-
self->encoding = pgenc;
424-
pgenc = NULL;
406+
{
407+
char *tmp = self->encoding;
408+
self->encoding = pgenc;
409+
PyMem_Free(tmp);
410+
pgenc = NULL;
411+
}
425412

426-
PyMem_Free(self->pyenc);
427-
self->pyenc = pyenc;
428-
pyenc = NULL;
413+
{
414+
char *tmp = self->pyenc;
415+
self->pyenc = pyenc;
416+
PyMem_Free(tmp);
417+
pyenc = NULL;
418+
}
429419

430420
conn_set_fast_codec(self);
431421

@@ -438,6 +428,35 @@ conn_read_encoding(connectionObject *self, PGconn *pgconn)
438428
}
439429

440430

431+
/* Read the client encoding from the backend and store it in the connection.
432+
*
433+
* Return 0 on success, else -1.
434+
*/
435+
RAISES_NEG static int
436+
conn_read_encoding(connectionObject *self, PGconn *pgconn)
437+
{
438+
const char *encoding;
439+
int rv = -1;
440+
441+
encoding = PQparameterStatus(pgconn, "client_encoding");
442+
Dprintf("conn_connect: client encoding: %s", encoding ? encoding : "(none)");
443+
if (!encoding) {
444+
PyErr_SetString(OperationalError,
445+
"server didn't return client encoding");
446+
goto exit;
447+
}
448+
449+
if (0 > conn_set_encoding(self, encoding)) {
450+
goto exit;
451+
}
452+
453+
rv = 0;
454+
455+
exit:
456+
return rv;
457+
}
458+
459+
441460
RAISES_NEG int
442461
conn_get_isolation_level(connectionObject *self)
443462
{
@@ -1282,34 +1301,20 @@ conn_set_client_encoding(connectionObject *self, const char *pgenc)
12821301
goto endlock;
12831302
}
12841303

1285-
/* no error, we can proceed and store the new encoding */
1286-
{
1287-
char *tmp = self->encoding;
1288-
self->encoding = clean_enc;
1289-
PyMem_Free(tmp);
1290-
clean_enc = NULL;
1291-
}
1304+
endlock:
1305+
pthread_mutex_unlock(&self->lock);
1306+
Py_END_ALLOW_THREADS;
12921307

1293-
/* Store the python encoding name too. */
1294-
{
1295-
char *tmp = self->pyenc;
1296-
self->pyenc = pyenc;
1297-
PyMem_Free(tmp);
1298-
pyenc = NULL;
1308+
if (res < 0) {
1309+
pq_complete_error(self, &pgres, &error);
1310+
goto exit;
12991311
}
13001312

1301-
conn_set_fast_codec(self);
1313+
res = conn_set_encoding(self, pgenc);
13021314

13031315
Dprintf("conn_set_client_encoding: set encoding to %s (Python: %s)",
13041316
self->encoding, self->pyenc);
13051317

1306-
endlock:
1307-
pthread_mutex_unlock(&self->lock);
1308-
Py_END_ALLOW_THREADS;
1309-
1310-
if (res < 0)
1311-
pq_complete_error(self, &pgres, &error);
1312-
13131318
exit:
13141319
PyMem_Free(clean_enc);
13151320
PyMem_Free(pyenc);

0 commit comments

Comments
 (0)