Hosszú kihagyás után újra, a megújult deadlime.project-en először végre kézbe veszem a billentyűzetem és egy (szerintem) érdekes témával folytatom itteni pályafutásom.
Ez a téma nem lenne más, mint a PostgreSQL adatbázis-kezelő elérése C/C++ programokból.
Az adatbázis eléréséhez a libpq áll a rendelkezésünkre. Próbáltam a libpqxx könyvtárat is, de rengeteg gond volt vele, ezért a "gyártó" által biztosított C-s lib-nél maradtam.
Ha forrásból telepítjük a PgSql-t, vagy windowson a megfelelő helyen pipálunk, akkor azonnal a rendelkezésünkre áll ez a könyvtár. Csak a fordítónak kell megadnunk az elérési utakat. Beállítástól függően #include <libpq-fe.h> vagy #include "libpq-fe.h" formában kell behúzni a forrásfájlunkba.
Nem célom, hogy minden függvényt bemutassak, arra megfelelőbb a PostgreSQL saját dokumentációja. Csupán azokat szeretném megemlíteni, melyek használat közben a legfontosabbak.

Tehát akkor egy kis kód:

#include <iostream>
#include <string>
#include <libpq-fe.h>

int main()
{
	// kapcsolódáshoz szükséges adatok
	const std::string	conninfo = "host=localhost port=5432 dbname=polaa user=polaa password=";
	// a kapcsolatmutató
	PGconn			*conn;
	// az eredménymutató
	PGresult		*res;

	/* kapcsolódás */
	conn = PQconnectdb(conninfo.c_str());
	if (PQstatus(conn) != CONNECTION_OK) 
	{
		std::cout << "Kapcsolódási hiba: " << PQerrorMessage(conn) << std::endl;
		PQfinish(conn);
		return 1;
	}
	
	/* ... */
}

Először is be kell vezetnünk néhány elengedhetetlen változót. Az adatbázishoz a PGconn *PQconnectdb(const *conninfo) függvénnyel kapcsolódhatunk hasonló módon, mint PHP-ban. A következő ellenőrzés szerintem magáért beszél.
A ConnStatusType PQstatus(const PGconn *conn) függvénnyel a kapcsolat aktuális állapotáról kaphatunk információt.
A void PQfinish(const PGconn *conn) függvény szerepe, hogy lezárja a kapcsolatot és felszabadítsa a PGconn által lefoglalt memóriát.

/* ... */
int main()
{
	/* ... */

	/* parancs */
	res = PQexec(conn, "INSERT INTO teszt VALUES (5, 10)");
	if (PQresultStatus(res) != PGRES_COMMAND_OK)
	{
		std::cout << "Parancsvégrehajtási hiba: " << PQerrorMessage(conn) << std::endl;
		PQclear(res);
		PQfinish(conn);
		return 1;
	}
	PQclear(res);
	
	/* ... */
}

A következő fontos függvény a PGresult *PQexec(PGconn *conn, const char *query), mely egy kérést küld a szervernek és egy Pgresult-ban tárolja az eredményt.
Ezt az eredményt a ExecStatusType PQresultStatus(const PGresult *res) függvénnyel ellenőrizhetjük.
A PGresult által lefoglalt memóriát a void PQclear(const PGresult *res) függvénnyel szabadíthatjuk fel. Fontos minden alkalommal meghívni, hogy még véletlenül se maradjon memória szemét hátra a programunk után.

/* ... */
int main()
{
	/* ... */

	/* lekérdezés */
	res = PQexec(conn, "SELECT * FROM teszt");
	if (PQresultStatus(res) != PGRES_TUPLES_OK)
	{
		std::cout << "Lekérdezés hiba: " << PQerrorMessage(conn) << std::endl;
		PQclear(res);
		PQfinish(conn);
		return 1;
	}
	/* lekérdezés feldolgozása */
	int rowNum, fieldNum;
	int i, j;

	rowNum		= PQntuples(res);
	fieldNum	= PQnfields(res);

	for (i = 0; i < fieldNum; i++)
	{
		std::cout << PQfname(res, i) << "\t";
	}
	std::cout << std::endl;

	for (i = 0; i < rowNum; i++)
	{
		for (j = 0; j < fieldNum; j++)
		{
			std::cout << PQgetvalue(res, i, j) << "\t";
		}
		std::cout << std::endl;
	}
	PQclear(res);

	PQfinish(conn);
	return 0;
}

A bemutató forrás végére hagytam a lekérdezést. Az eredménytáblában történő navigálást számos függvény könnyíti meg.
A sorok, illetve oszlopok számát az int PQntuples(const PGresult *res), illetve az int PQnfields(const PGresult *res) függvények adják vissza.
Az egyes oszlopok nevét a char *PQfname(const PGresult *res, int field_num) adja meg az oszlop indexe alapján (ami természetesen 0-ról indul). Az egyes mezők tartalmát a char *PQgetvalue(const PGresult *res, int tup_num, int field_num) függvény adja meg a PQfname-hez hasonló módon.

Ezekkel az alapfüggvényekkel már nyugodtan lehet kisebb-nagyobb adatbázis műveleteket végezni. Az objektum-orientált megoldást majd egy következő bejegyzésben részletezem.
A fenti kódot csak windowson próbáltam, mert csak. Fontos megjegyezni, hogy ott a lefordult exe mellé a következő dll-eket kell másolni még a PgSql-ünk bin nevü könyvtárából: comerr32.dll, krb5_32.dll, libiconv-2.dll, libintl-2.dll, libpq.dll.