]> git.ipfire.org Git - thirdparty/psycopg.git/commitdiff
perf(c): add Cython UUID dumper and loader
authorhenadzit <henadzi.tsaryk@gmail.com>
Mon, 27 Jan 2025 18:26:00 +0000 (19:26 +0100)
committerDaniele Varrazzo <daniele.varrazzo@gmail.com>
Thu, 20 Feb 2025 10:15:41 +0000 (11:15 +0100)
psycopg_c/psycopg_c/_psycopg.pyx
psycopg_c/psycopg_c/types/uuid.pyx [new file with mode: 0644]

index f8fb04273274cf25971f59dd4021e7ec93198930..731ba581c4c60fde811e243d623feaf13978ca31 100644 (file)
@@ -53,3 +53,4 @@ include "types/numeric.pyx"
 include "types/bool.pyx"
 include "types/numpy.pyx"
 include "types/string.pyx"
+include "types/uuid.pyx"
diff --git a/psycopg_c/psycopg_c/types/uuid.pyx b/psycopg_c/psycopg_c/types/uuid.pyx
new file mode 100644 (file)
index 0000000..0c391da
--- /dev/null
@@ -0,0 +1,59 @@
+cimport cython
+
+import uuid
+from cpython.bytes cimport PyBytes_AsString
+
+cdef extern from "Python.h":
+    # PyUnicode_AsUTF8 was added to cpython.unicode in 3.1.x but we still
+    # support 3.0.x
+    const char *PyUnicode_AsUTF8(object unicode) except NULL
+
+from libc.stdio cimport printf
+
+
+#cdef extern from "Python.h":
+#    Py_ssize_t PyLong_AsNativeBytes(PyObject* vv, void* buffer, Py_ssize_t n, int flags)
+
+
+@cython.final
+cdef class UUIDDumper(CDumper):
+    format = PQ_TEXT
+    oid = oids.UUID_OID
+
+    cdef Py_ssize_t cdump(self, obj, bytearray rv, Py_ssize_t offset) except -1:
+        cdef const char *src = PyUnicode_AsUTF8(obj.hex)
+        cdef char *buf = CDumper.ensure_size(rv, offset, 32)
+        memcpy(buf, src, 32)
+        return 32
+
+
+@cython.final
+cdef class UUIDBinaryDumper(CDumper):
+    format = PQ_BINARY
+    oid = oids.UUID_OID
+
+    cdef Py_ssize_t cdump(self, obj, bytearray rv, Py_ssize_t offset) except -1:
+        cdef const char *src = PyBytes_AsString(obj.bytes)
+        cdef char *buf = CDumper.ensure_size(rv, offset, 16)
+        memcpy(buf, src, 16)
+        return 16
+        #cdef PyObject *pyobj = <PyObject*>obj.int
+        #cdef char *buf = CDumper.ensure_size(rv, offset, 16)
+        #PyLong_AsNativeBytes(pyobj, buf, 16, 4)
+        #return 16
+
+
+@cython.final
+cdef class UUIDLoader(CLoader):
+    format = PQ_TEXT
+
+    cdef object cload(self, const char *data, size_t length):
+        return uuid.UUID(hex=data[:length].decode())
+
+
+@cython.final
+cdef class UUIDBinaryLoader(CLoader):
+    format = PQ_BINARY
+
+    cdef object cload(self, const char *data, size_t length):
+        return uuid.UUID(bytes=data[:length])