]> git.ipfire.org Git - thirdparty/psycopg.git/commitdiff
Better integration between C copy functions and C transformer
authorDaniele Varrazzo <daniele.varrazzo@gmail.com>
Fri, 15 Jan 2021 17:26:04 +0000 (18:26 +0100)
committerDaniele Varrazzo <daniele.varrazzo@gmail.com>
Sat, 16 Jan 2021 01:06:57 +0000 (02:06 +0100)
psycopg3_c/psycopg3_c/_psycopg3/copy.pyx
psycopg3_c/psycopg3_c/_psycopg3/transform.pyx

index 43f7e854bd936b4268f57a1a8b92075b246cd7b4..0e57934d95e2ceb8a1797428651fb9ff8ef230ee 100644 (file)
@@ -46,22 +46,25 @@ def format_row_binary(
     cdef uint32_t besize
     cdef char *buf
     cdef int i
-    fmt = PG_BINARY
+    cdef PyObject *fmt = <PyObject *>PG_BINARY
+    cdef PyObject *row_dumper
 
     for i in range(rowlen):
         item = row[i]
         if item is not None:
-            dumper = tx.get_dumper(item, fmt)
-            if isinstance(dumper, CDumper):
+            row_dumper = tx.get_row_dumper(<PyObject *>item, fmt)
+            if (<RowDumper>row_dumper).cdumper is not None:
                 # A cdumper can resize if necessary and copy in place
-                size = (<CDumper>dumper).cdump(item, out, pos + sizeof(besize))
+                size = (<RowDumper>row_dumper).cdumper.cdump(
+                    item, out, pos + sizeof(besize))
                 # Also add the size of the item, before the item
                 besize = endian.htobe32(size)
                 target = PyByteArray_AS_STRING(out)  # might have been moved by cdump
                 memcpy(target + pos, <void *>&besize, sizeof(besize))
             else:
                 # A Python dumper, gotta call it and extract its juices
-                b = PyObject_CallFunctionObjArgs(dumper.dump, <PyObject *>item, NULL)
+                b = PyObject_CallFunctionObjArgs(
+                    (<RowDumper>row_dumper).dumpfunc, <PyObject *>item, NULL)
                 _buffer_as_string_and_size(b, &buf, &size)
                 target = CDumper.ensure_size(out, pos, size + sizeof(besize))
                 besize = endian.htobe32(size)
@@ -103,7 +106,8 @@ def format_row_text(
     cdef unsigned char *target
     cdef int nesc = 0
     cdef int with_tab
-    fmt = PG_TEXT
+    cdef PyObject *fmt = <PyObject *>PG_TEXT
+    cdef PyObject *row_dumper
 
     for i in range(rowlen):
         # Include the tab before the data, so it gets included in the resizes
@@ -121,14 +125,16 @@ def format_row_text(
                 pos += 2
             continue
 
-        dumper = tx.get_dumper(item, fmt)
-        if isinstance(dumper, CDumper):
+        row_dumper = tx.get_row_dumper(<PyObject *>item, fmt)
+        if (<RowDumper>row_dumper).cdumper is not None:
             # A cdumper can resize if necessary and copy in place
-            size = (<CDumper>dumper).cdump(item, out, pos + with_tab)
+            size = (<RowDumper>row_dumper).cdumper.cdump(
+                item, out, pos + with_tab)
             target = <unsigned char *>PyByteArray_AS_STRING(out) + pos
         else:
             # A Python dumper, gotta call it and extract its juices
-            b = PyObject_CallFunctionObjArgs(dumper.dump, <PyObject *>item, NULL)
+            b = PyObject_CallFunctionObjArgs(
+                (<RowDumper>row_dumper).dumpfunc, <PyObject *>item, NULL)
             _buffer_as_string_and_size(b, &buf, &size)
             target = <unsigned char *>CDumper.ensure_size(out, pos, size + with_tab)
             memcpy(target + with_tab, buf, size)
index 741c2c2c90e09ee77e62e1ed7197e51958cafe0e..da88d933407c7fde4acb1ec9a57d4df361ca6c74 100644 (file)
@@ -147,11 +147,11 @@ cdef class Transformer:
         self._row_loaders = loaders
 
     def get_dumper(self, obj, format) -> "Dumper":
-        cdef PyObject *row_dumper = self._c_get_dumper(
+        cdef PyObject *row_dumper = self.get_row_dumper(
             <PyObject *>obj, <PyObject *>format)
         return (<RowDumper>row_dumper).pydumper
 
-    cdef PyObject *_c_get_dumper(self, PyObject *obj, PyObject *fmt) except NULL:
+    cdef PyObject *get_row_dumper(self, PyObject *obj, PyObject *fmt) except NULL:
         """
         Return a borrowed reference to the RowDumper for the given obj/fmt.
         """
@@ -202,7 +202,7 @@ cdef class Transformer:
             # If we are dumping a list it's the sub-object which should dictate
             # what format to use.
             else:
-                sub_dumper = self._c_get_dumper(<PyObject *>subobj, fmt)
+                sub_dumper = self.get_row_dumper(<PyObject *>subobj, fmt)
                 tmp = Pg3Format.from_pq((<RowDumper>sub_dumper).format)
                 fmt = <PyObject *>tmp
 
@@ -252,7 +252,7 @@ cdef class Transformer:
                 dumper_ptr = PyList_GET_ITEM(dumpers, i)
                 if dumper_ptr == NULL:
                     format = formats[i]
-                    dumper_ptr = self._c_get_dumper(
+                    dumper_ptr = self.get_row_dumper(
                         <PyObject *>param, <PyObject *>format)
                     Py_INCREF(<object>dumper_ptr)
                     PyList_SET_ITEM(dumpers, i, <object>dumper_ptr)