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.

