#pragma once

/**
 * On both systems we load the PostgreSQL library on demand.
 *
 * Note that 32-bit builds of the client libraries for Windows are only available up to version
 * 10.23.
 *
 * The library has some backwards compatibility. In particular, version 17 introduced a new function
 * in the client library that we utilize if it is available. We do have a fallback for older
 * versions to support at least version 16.
 *
 * The following files need to be placed in the same directory as sql.dll or storm.exe for postgres
 * to work:
 * - libpq.dll
 * - libcrypto-*.dll
 * - libiconv-*.dll
 * - libintl-*.dll
 * - libssl-*.dll
 *
 * On Linux, we use libpq.so.5. On Debian, the package is named libpq5.
 */


namespace sql {

	// Postgres connection.
	struct PGconn;

	// Postgres result object.
	struct PGresult;

	// Old-style cancellation interface.
	struct PGcancel;

	// New-style cancellation interface.
	struct PGcancelConn;

	// Connection status.
	enum ConnStatusType {
		CONNECTION_OK,
		CONNECTION_BAD,

		// There are more in the pgsql headers, but they seem to be internal
	};

	enum ExecStatusType {
		PGRES_EMPTY_QUERY = 0,
		PGRES_COMMAND_OK,
		PGRES_TUPLES_OK,
		PGRES_COPY_OUT,
		PGRES_COPY_IN,
		PGRES_BAD_RESPONSE,
		PGRES_NONFATAL_ERROR,
		PGRES_FATAL_ERROR,
		PGRES_COPY_BOTH,
		PGRES_SINGLE_TUPLE
	};

	// Oid
	typedef unsigned int Oid;

	// Notice receiver.
	typedef void (*PQnoticeReceiver)(void *arg, const PGresult *res);

#ifdef WINDOWS
#define PG_IMPORT __cdecl // based on the code in the 32-bit DLLs.
#else
#define PG_IMPORT
#endif
#define PG_FUNCTION(name, result, ...)			\
	typedef result (PG_IMPORT *Ptr ## name)(__VA_ARGS__); \
	Ptr ## name name;
#define PG_OPTIONAL_FUNCTION(name, result, ...) PG_FUNCTION(name, result, __VA_ARGS__)

	struct PGDriver {
#include "DriverFns.inc"
	};

#undef PG_FUNCTION
#undef PG_OPTIONAL_FUNCTION

	const PGDriver *createPGDriver(Engine &e);

	void destroyPGDriver(const PGDriver *driver);

}
