Ukázka použití API knihovny glib-sql-wrapper

K napsání knihovny glib-sql-wrapper mě vedla potřeba velmi jednoduchého a čistého API pro komunikaci s různými DB, u kterého by se programátor neutrápil k smrti zbytečným psaním a ošetřováním chyb.
Redukovat frustraci je pro kreativní lidi velmi hodnotné, protože to uvolňuje energii na užitečnější věci.
Když se zadíváte na kód uvedený níže, asi vás napadne, že tam chybí ošetření chyb a uvolnění paměti a proto to vypadá tak přehledně a jednoduše. Naštěstí se mýlíte. Kód má ošetření runtime chyb a správu paměti naprosto v pořádku. A v tom právě spočívá krása glib-sql-wrapper.
Pokud dojde k chybě, volání jakýchkoliv dalších funkcí bude glib-sql-wrapper ignorovat. Představte si například, že dojde k chybě hned při volání gs_connect(). Veškerá následující volání budou ignorována, gs_finish() vrátí –1 a ukázkový kód vypíše hlášku o selhání připojení k DB.
API se skládá z velmi malého jádra základních funkcí: vytvoření dotazu, předání dat dotazu, získání dat z dotazu, zrušení dotazu a z těchto funkcí jsou složeny všechny ostatní (např. gs_exec). Jednoduchost jádra knihovny také znamená, že lze knihovnu snadno doplnit o podporu pro další databázové API.
/* * Written by Ondřej Jirman <megous@megous.com>, 2008. */ #include <stdio.h> #include <unistd.h> #include "gsqlw.h" //#define DSN "pgsql:dbname=test host=localhost user=postgres password=heslo" #define DSN "sqlite:.test.db" int main(int ac, char* av[]) { gs_conn* conn; gs_query* q; char* username; char* password; /* connect */ conn = gs_connect(DSN); /* begin transaction */ gs_begin(conn); /* exec some simple queries */ gs_exec(c, "CREATE TABLE users (username TEXT PRIMARY KEY, password TEXT NOT NULL)", NULL); gs_exec(c, "INSERT INTO users (username, password) VALUES ($1, $2)", "ss", "bob", "qwe"); /* prepared query example */ q = gs_query_new(conn, "INSERT INTO users (username, password) VALUES ($1, $2)"); gs_query_put(q, "ss", "joe", "joe's secret"); gs_query_put(q, "ss", "jim", "jim's secret"); gs_query_put(q, "ss", "jane", "jane's secret"); gs_query_free(q); /* select example */ q = gs_query_new(conn, "SELECT username, password FROM users WHERE username LIKE $1"); gs_query_put(q, "s", "%j"); while (gs_query_get(q, "ss", &username, &password) == 0) g_print("user %s has password '%s'", username, password); gs_query_free(q); /* commit or handle errors */ if (gs_finish(c) < 0) g_printerr("ERROR: %s\n", gs_get_errmsg(c)); /* close connection */ gs_disconnect(conn); return 0; }
No není to krása? Máme dva objekty: připojení a dotaz. Připojení může být ve dvou stavech: v transakci a mimo. Dotazu můžeme data předávat a získávat je z něj. Vidíte to také? Každá funkce má svoje místo a žádná není zbytečná.
