Connecting to a Database (Asynchronously) ========================================= Connect to a database called **sandbox** on a vnode called **loathing**. .. NOTE:: Basic knowledge of ``asyncio`` is assumed for this example. OpenAPI functions are invoked using **await** to yield to the ``asyncio`` event-loop pending completion of the functions. Other runnable tasks are allowed to execute while the OpenAPI operation is being completed in the background. :download:`Download <./examples/connect-async.py>` .. LITERALINCLUDE:: ./examples/connect-async.py :linenos: :download:`Download <./examples/connect-async.py>` Start by importing ``pyngres.asyncio``. .. CODE:: import pyngres.asyncio as py Initialize the OpenAPI. .. CODE:: # use the latest version of the OpenAPI inp = py.IIAPI_INITPARM() inp.in_timeout = -1 inp.in_version = py.IIAPI_VERSION status = inp.in_status if status != py.IIAPI_ST_SUCCESS: print('could not initialize the OpenAPI') quit() # note the envHandle for use when connecting envHandle = inp.in_envHandle Construct the target name as a NUL-terminated array of bytes (i.e. a C string) by encoding :attr:`!dbname` (which is a Python ``str`` and hence meaningless to the OpenAPI). .. CODE:: # use a target of the form vnode::database dbname = 'loathing::sandbox' target = dbname.encode() To participate in cooperative multitasking all OpenAPI applications have to be structured using coroutines. .. CODE:: # define the main coroutine async def main(target): '''control the overall application''' Allocate a control block for :func:`!Iiapi_connect`. Initialize it with the database target name; the OpenAPI environment handle; the :attr:`py.!IIAPI_CT_SQL` constant to indicate this will be an SQL session, and set the timeout to -1 so the OpenAPI will wait indefinitely for the connection to be established. .. CODE:: # blah blah blah cop = py.IIAPI_CONNPARM() cop.co_target = target cop.co_connHandle = envHandle cop.co_type = py.IIAPI_CT_SQL cop.co_timeout = -1 Invoke :func:`!IIapi_connect` by awaiting it. ``asyncio`` will hand control to any other runnable task(s) that are pending. Control will return to this task only after it becomes pending because the database connection request completed. .. CODE:: await py.IIapi_connect(cop) The request can be completed successfully or it might fail for some reason, such as an invalid database name. .. CODE:: status = cop.co_status if status != py.IIAPI_ST_SUCCESS: print('could not connect to the database') quit() (See :ref:`error-handling-example` for an illustration of how to fully report an error.) When the connection is successfully established the returned connection handle must be noted for future use in other OpenAPI function invokations. The OpenAPI uses connection handles to allows it to interact correctly with multiple simultaneous database connections in the same application. .. CODE:: connHandle = cop.co_connHandle Once the connection is established the application can start sending SQL statements to be executed, fetching query results, and controlling the session behaviour (e.g. committing transactions, setting lockmodes, changing display formats.)