From: Daniele Varrazzo Date: Fri, 15 Jan 2021 17:26:04 +0000 (+0100) Subject: Better integration between C copy functions and C transformer X-Git-Tag: 3.0.dev0~153 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=6ace0fa3be3daa1d94f2dc63acce606d17d608e8;p=thirdparty%2Fpsycopg.git Better integration between C copy functions and C transformer --- diff --git a/psycopg3_c/psycopg3_c/_psycopg3/copy.pyx b/psycopg3_c/psycopg3_c/_psycopg3/copy.pyx index 43f7e854b..0e57934d9 100644 --- a/psycopg3_c/psycopg3_c/_psycopg3/copy.pyx +++ b/psycopg3_c/psycopg3_c/_psycopg3/copy.pyx @@ -46,22 +46,25 @@ def format_row_binary( cdef uint32_t besize cdef char *buf cdef int i - fmt = PG_BINARY + cdef PyObject *fmt = 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(item, fmt) + if (row_dumper).cdumper is not None: # A cdumper can resize if necessary and copy in place - size = (dumper).cdump(item, out, pos + sizeof(besize)) + size = (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, &besize, sizeof(besize)) else: # A Python dumper, gotta call it and extract its juices - b = PyObject_CallFunctionObjArgs(dumper.dump, item, NULL) + b = PyObject_CallFunctionObjArgs( + (row_dumper).dumpfunc, 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 = 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(item, fmt) + if (row_dumper).cdumper is not None: # A cdumper can resize if necessary and copy in place - size = (dumper).cdump(item, out, pos + with_tab) + size = (row_dumper).cdumper.cdump( + item, out, pos + with_tab) target = PyByteArray_AS_STRING(out) + pos else: # A Python dumper, gotta call it and extract its juices - b = PyObject_CallFunctionObjArgs(dumper.dump, item, NULL) + b = PyObject_CallFunctionObjArgs( + (row_dumper).dumpfunc, item, NULL) _buffer_as_string_and_size(b, &buf, &size) target = CDumper.ensure_size(out, pos, size + with_tab) memcpy(target + with_tab, buf, size) diff --git a/psycopg3_c/psycopg3_c/_psycopg3/transform.pyx b/psycopg3_c/psycopg3_c/_psycopg3/transform.pyx index 741c2c2c9..da88d9334 100644 --- a/psycopg3_c/psycopg3_c/_psycopg3/transform.pyx +++ b/psycopg3_c/psycopg3_c/_psycopg3/transform.pyx @@ -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( obj, format) return (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(subobj, fmt) + sub_dumper = self.get_row_dumper(subobj, fmt) tmp = Pg3Format.from_pq((sub_dumper).format) fmt = 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( param, format) Py_INCREF(dumper_ptr) PyList_SET_ITEM(dumpers, i, dumper_ptr)