From: Daniele Varrazzo Date: Sun, 10 May 2020 15:44:41 +0000 (+1200) Subject: Added c bytea loaders X-Git-Tag: 3.0.dev0~535 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=66561269cad4d34601bf0196ffd8c5a879eb8e5f;p=thirdparty%2Fpsycopg.git Added c bytea loaders --- diff --git a/psycopg3/adapt.pyx b/psycopg3/adapt.pyx index 02cb4e1a5..c71255347 100644 --- a/psycopg3/adapt.pyx +++ b/psycopg3/adapt.pyx @@ -74,5 +74,8 @@ cdef void register_text_c_loaders(): from psycopg3 import adapt from psycopg3.types import text register_c_loader(text.StringLoader.load, load_text, get_context_text) + register_c_loader(text.NameLoader.load, load_text, get_context_text) + register_c_loader(text.load_bytea_text, load_bytea_text) + register_c_loader(text.load_bytea_binary, load_bytea_binary) register_c_loader(adapt.UnknownLoader.load, load_unknown_text) register_c_loader(adapt.load_unknown_binary, load_unknown_binary) diff --git a/psycopg3/types/text.py b/psycopg3/types/text.py index 56d0cf10c..f36ae9e75 100644 --- a/psycopg3/types/text.py +++ b/psycopg3/types/text.py @@ -98,7 +98,7 @@ def dump_bytes(b: bytes) -> Tuple[bytes, int]: @Loader.text(builtins["bytea"].oid) -def load_bytea(data: bytes) -> bytes: +def load_bytea_text(data: bytes) -> bytes: return Escaping().unescape_bytea(data) diff --git a/psycopg3/types/text.pyx b/psycopg3/types/text.pyx index b143d4e4e..dc9b77c98 100644 --- a/psycopg3/types/text.pyx +++ b/psycopg3/types/text.pyx @@ -1,5 +1,6 @@ from cpython.bytes cimport PyBytes_FromStringAndSize from cpython.unicode cimport PyUnicode_DecodeUTF8 +from psycopg3.pq cimport libpq cdef object load_text(const char *data, size_t length, void *context): @@ -20,6 +21,24 @@ cdef void *get_context_text(object loader): return NULL +cdef object load_bytea_text(const char *data, size_t length, void *context): + cdef size_t len_out + cdef unsigned char *out = libpq.PQunescapeBytea( + data, &len_out) + if out is NULL: + raise MemoryError( + f"couldn't allocate for unescape_bytea of {len(data)} bytes" + ) + + rv = out[:len_out] + libpq.PQfreemem(out) + return rv + + +cdef object load_bytea_binary(const char *data, size_t length, void *context): + return data[:length] + + cdef object load_unknown_text(const char *data, size_t length, void *context): # TODO: codec return PyUnicode_DecodeUTF8(data, length, NULL)