cdef class CDumper:
cdef object cls
cdef public libpq.Oid oid
- cdef readonly object connection
cdef pq.PGconn _pgconn
def __init__(self, cls: type, context: Optional[AdaptContext] = None):
self.cls = cls
- self.connection = context.connection if context is not None else None
- self._pgconn = (
- self.connection.pgconn if self.connection is not None else None
- )
+ conn = context.connection if context is not None else None
+ self._pgconn = conn.pgconn if conn is not None else None
# default oid is implicitly set to 0, subclasses may override it
# PG 9.6 goes a bit bonker sending unknown oids, so use text instead
@cython.freelist(8)
cdef class CLoader:
cdef public libpq.Oid oid
- cdef readonly connection
+ cdef pq.PGconn _pgconn
def __init__(self, int oid, context: Optional[AdaptContext] = None):
self.oid = oid
- self.connection = context.connection if context is not None else None
+ conn = context.connection if context is not None else None
+ self._pgconn = conn.pgconn if conn is not None else None
cdef object cload(self, const char *data, size_t length):
raise NotImplementedError()
)
from psycopg3_c.pq cimport libpq, Escaping, _buffer_as_string_and_size
+from psycopg3.encodings import pg2py
cdef extern from "Python.h":
const char *PyUnicode_AsUTF8AndSize(unicode obj, Py_ssize_t *size)
self.is_utf8 = 0
self.encoding = "utf-8"
+ cdef const char *pgenc
- conn = self.connection
- if conn is not None:
- self._bytes_encoding = conn.client_encoding.encode("utf-8")
- self.encoding = PyBytes_AsString(self._bytes_encoding)
- if (
- self._bytes_encoding == b"utf-8"
- or self._bytes_encoding == b"ascii"
- ):
+ if self._pgconn is not None:
+ pgenc = libpq.PQparameterStatus(self._pgconn.pgconn_ptr, b"client_encoding")
+ if pgenc == NULL or pgenc == b"UTF8":
+ self._bytes_encoding = b"utf-8"
self.is_utf8 = 1
+ else:
+ self._bytes_encoding = pg2py(pgenc).encode("utf-8")
+ if self._bytes_encoding == b"ascii":
+ self.is_utf8 = 1
+ self.encoding = PyBytes_AsString(self._bytes_encoding)
cdef Py_ssize_t cdump(self, obj, bytearray rv, Py_ssize_t offset) except -1:
# the server will raise DataError subclass if the string contains 0x00
self.is_utf8 = 0
self.encoding = "utf-8"
+ cdef const char *pgenc
- conn = self.connection
- if conn is not None:
- self._bytes_encoding = conn.client_encoding.encode("utf-8")
- self.encoding = PyBytes_AsString(self._bytes_encoding)
- if self._bytes_encoding == b"utf-8":
+ if self._pgconn is not None:
+ pgenc = libpq.PQparameterStatus(self._pgconn.pgconn_ptr, b"client_encoding")
+ if pgenc == NULL or pgenc == b"UTF8":
+ self._bytes_encoding = b"utf-8"
self.is_utf8 = 1
- elif self._bytes_encoding == b"ascii":
+ else:
+ self._bytes_encoding = pg2py(pgenc).encode("utf-8")
+
+ if pgenc == b"SQL_ASCII":
self.encoding = NULL
+ else:
+ self.encoding = PyBytes_AsString(self._bytes_encoding)
cdef object cload(self, const char *data, size_t length):
if self.is_utf8: