ctypes ****** In Python everything is an object. .. _data-marshalling: Data Marshalling ================ The OpenAPI and the Actian DBMS products exchange data using C structures and C datatypes. The abstract SQL datatypes such as ANSIDATE and DECIMAL are represented as C structures internally; even VARCHARs are structures. Python does not understand C structures and the Actian database management systems don't understand Python objects. In general data has to be marshalled between the two representations using the `ctypes `_ package. ``pyngres`` uses ``ctypes`` to bind to the OpenAPI and wrap the OpenAPI control blocks. It therefore handles certain simple cases automatically, as in this example of assigning a value to an integer member of a control block: .. CODE:: inp.in_timeout = -1 :attr:`!inp` is wrapper around a C structure which has a 32-bit C integer member called :attr:`!in_timeout`. The value :attr:`!-1` is a Python :attr:`!int` object. In this case ``ctypes`` automatically converts the Python value to a C value to assign it in the control block. In a similar way it also automatically handles Python floating point values, byte strings (which get treated as NUL-terminated C strings), :attr:`!True` and :attr:`!False`, and :attr:`!None` (which gets treated as a zero or a null pointer, as appropriate). Handlers must be developed for all the remaining SQL datatypes that get exchanged with ``pyngres``. For example, ANSIDATEs must be converted into :attr:`!datetime.date` instances if they are to be used in Python code. Declaring Arrays ================ The syntax to dynamically declare a ``ctypes`` array (list) is not obvious. Consider an SQL query which returns twenty columns. It requires a twenty element array of :attr:`!IIAPI_DATEVALUE`. To allocate such an array, first create a factory class, then use it to instantiate the array: .. CODE:: ArrayaOf20Factory = py.IIAPI_DATAVALUE * 20 # create the factory class array = ArrayaOf20Factory() # instantiate the array Or more concisely, and without cluttering the namespace with obscure classes: .. CODE:: array = (py.IIAPI_DATAVALUE * 20)() .. NOTE:: ``ctypes`` is complicated and sometimes challenging. There are many tutorials and blogs that discuss how to use it. For the purpose of developing OpenAPI applications it is probably sufficient to follow some of the examples here rather than attempting to master it. Blogs about ``ctypes``, and contributions on *Stackoverflow* or generated by AI, should be read with caution. Much of it is stale or obsolete, or worse.