]> git.ipfire.org Git - thirdparty/psycopg.git/commitdiff
Baby steps registering c optimised adapters
authorDaniele Varrazzo <daniele.varrazzo@gmail.com>
Mon, 4 May 2020 18:26:26 +0000 (06:26 +1200)
committerDaniele Varrazzo <daniele.varrazzo@gmail.com>
Fri, 8 May 2020 12:28:57 +0000 (00:28 +1200)
Just registered some so far, not using the map yet

.travis.yml
psycopg3/__init__.py
psycopg3/_psycopg3.pyx
psycopg3/adapt.pxd [new file with mode: 0644]
psycopg3/adapt.pyx [new file with mode: 0644]
psycopg3/transform.pyx
psycopg3/types/numeric.pxd [new file with mode: 0644]

index 89e1e56424acbd5ac7718b548886f76f75a6e6a1..91bdee98ee5be4cfb419e918c566bc47c748e6b4 100644 (file)
@@ -81,3 +81,9 @@ install:
 
 script:
   - tox
+
+
+# This branch is still far from passing tests
+branches:
+  except:
+  - cython
index 23488315c62ec9c257de7c49c64f0a93ea36ce27..09c7fa1733910e21d2f31f74f62a6082d0493443 100644 (file)
@@ -4,6 +4,7 @@ psycopg3 -- PostgreSQL database adapter for Python
 
 # Copyright (C) 2020 The Psycopg Team
 
+from . import pq
 from .consts import VERSION as __version__  # noqa
 from .connection import AsyncConnection, Connection
 
@@ -20,9 +21,6 @@ from .errors import (
     NotSupportedError,
 )
 
-# register default adapters
-from . import types  # noqa
-
 from .dbapi20 import BINARY, DATETIME, NUMBER, ROWID, STRING
 from .dbapi20 import Binary, Date, DateFromTicks, Time, TimeFromTicks
 from .dbapi20 import Timestamp, TimestampFromTicks
@@ -33,6 +31,17 @@ apilevel = "2.0"
 threadsafety = 2
 paramstyle = "pyformat"
 
+
+# register default adapters
+from . import types  # noqa
+
+# Override adapters with fast version if available
+if pq.__impl__ == "c":
+    from ._psycopg3 import register_builtin_c_loaders
+
+    register_builtin_c_loaders()
+
+
 __all__ = (
     ["Warning", "Error", "InterfaceError", "DatabaseError", "DataError"]
     + ["OperationalError", "IntegrityError", "InternalError"]
index 007af0a480f8faaf148c2952054c07d23d6a9cb9..0ab2fa969fcca673a2139523f52d7e2228a29e24 100644 (file)
@@ -1,3 +1,4 @@
 include "types/numeric.pyx"
 include "types/text.pyx"
+include "adapt.pyx"
 include "transform.pyx"
diff --git a/psycopg3/adapt.pxd b/psycopg3/adapt.pxd
new file mode 100644 (file)
index 0000000..feb1097
--- /dev/null
@@ -0,0 +1,5 @@
+
+ctypedef object (*cloader_func)(const char *data, size_t length, void *context)
+# ctypedef void * (*get_context_func)(PGconn_ptr conn)
+
+cdef void register_c_loader(object pyloader, cloader_func cloader)
diff --git a/psycopg3/adapt.pyx b/psycopg3/adapt.pyx
new file mode 100644 (file)
index 0000000..aa35c8d
--- /dev/null
@@ -0,0 +1,46 @@
+from psycopg3.adapt cimport cloader_func
+
+from psycopg3.types cimport numeric
+
+
+import logging
+logger = logging.getLogger("psycopg3.adapt")
+
+
+cdef class CLoader:
+    cdef object pyloader
+    cdef cloader_func cloader
+
+
+cloaders = {}
+
+cdef void register_c_loader(object pyloader, cloader_func cloader):
+    """
+    Map a python loader to an optimised C version.
+
+    Whenever the python loader would be used the C version may be chosen in
+    preference.
+    """
+    cdef CLoader cl = CLoader()
+    cl.pyloader = pyloader
+    cl.cloader = cloader
+    cloaders[pyloader] = cl
+
+
+def register_builtin_c_loaders():
+    if cloaders:
+        logger.warning("c loaders already registered")
+        return
+
+    logger.debug("registering optimised c loaders")
+    register_numeric_c_loaders()
+
+
+cdef void register_numeric_c_loaders():
+    logger.debug("registering optimised numeric c loaders")
+    from psycopg3.types import numeric
+    register_c_loader(numeric.load_int, load_int_text)
+    register_c_loader(numeric.load_int2_binary, load_int2_binary)
+    register_c_loader(numeric.load_int4_binary, load_int4_binary)
+    register_c_loader(numeric.load_int8_binary, load_int8_binary)
+    register_c_loader(numeric.load_oid_binary, load_oid_binary)
index 52eb9d4e883e29cb8a1743498298b29faa350a49..3967d815baa787d5e9fea44ab4b84f9de448b636 100644 (file)
@@ -9,6 +9,7 @@ from typing import Any, Dict, Iterable, List, Optional, Tuple
 
 from psycopg3.pq cimport libpq
 from psycopg3.pq.pq_cython cimport PGresult
+from psycopg3.adapt cimport cloader_func
 
 from psycopg3 import errors as e
 from psycopg3.pq.enums import Format
@@ -17,7 +18,6 @@ from psycopg3.pq.enums import Format
 TEXT_OID = 25
 
 
-ctypedef object (*cloader_func)(const char *data, size_t length, void *context)
 
 cdef struct RowLoader:
     PyObject *pyloader  # borrowed
diff --git a/psycopg3/types/numeric.pxd b/psycopg3/types/numeric.pxd
new file mode 100644 (file)
index 0000000..dce56be
--- /dev/null
@@ -0,0 +1,6 @@
+cdef object load_int_text(const char *data, size_t length, void *context)
+cdef object load_int2_binary(const char *data, size_t length, void *context)
+cdef object load_int4_binary(const char *data, size_t length, void *context)
+cdef object load_int8_binary(const char *data, size_t length, void *context)
+cdef object load_oid_binary(const char *data, size_t length, void *context)
+cdef object load_bool_binary(const char *data, size_t length, void *context)