Esercitazione sulle libpq - libreria C per PostgreSQL Roberto Tronci [email protected] Basi di Dati A.A. 2007/2008 Tronci ( [email protected] ) Esercitazione libpq Basi di Dati 2007/2008 1 / 13 Introduzione Le libpq è una libreria proprietaria di PostgreSQL per interfacciare programmi scritti in linguaggio C con il server DBMS. Tramite questa libreria è possibile eseguire sulla base di dati sia interrogazioni che comandi (in pratica è possibile fare tutto ciò che è possibile fare tramite l’interfaccia psql). Per utilizzare le libpq è necessario includere il file libpq-fe.h e linkare il programma con le librerie libpq. Si consiglia di compilare il programma facendo includere le librerie nel file. Tronci ( [email protected] ) Esercitazione libpq Basi di Dati 2007/2008 2 / 13 Connessione al database La funzione che si occupa della connessione al database è : PGconn * PQconnectdb(const char * conninfo) Questa funzione restituisce un puntatore ad una struttura dati di tipo PGconn, ovvero il tipo definito in libpq per le connessioni al DB. Come parametro d’ingresso bisogna mettere una stringa conninfo; questa stringa contiene campi del tipo keyword=valore, se una keyword non viene specificata viene preso il valore di default. Le keyword di nostro interesse sono: host: nome dell’host a cui ci si vuole connettere port: porta attraverso la quale ci si connette al server dbname: nome del database a cui ci si vuole collegare user: nome dell’utente PostgreSQL con cui collegarsi al database password: password dell’utente user Tronci ( [email protected] ) Esercitazione libpq Basi di Dati 2007/2008 3 / 13 Stato della connessione, errori e chiusura della connessione Lo stato della connessione si verifica tramite la funzione: ConnStatusType PQstatus(const PGconn * conn) ConnStatusType può essere di due tipi: CONNECTION_OK e CONNECTION_BAD (ATTENZIONE: conn potrebbe anche essere NULL). In caso di errore, la stringa che descrive il tipo di errore la si ottiene usando la funzione: char *PQerrorMessage(const PGconn *conn) La connessione viene chiusa usando la funzione: void PQfinish(PGconn *conn) Tronci ( [email protected] ) Esercitazione libpq Basi di Dati 2007/2008 4 / 13 Esempio di connessione al database Una connessione di esempio è : PGconn *conn; conn = PGconnectdb("host=127.0.0.1 port=5432 dbname=mydb user=postgres password=postpwd"); if (PQstatus(conn) != CONNECTION_OK) { fprintf(stderr, "Connessione al database fallita.\n"); fprintf(stderr, "%s", PQerrorMessage(conn)); PQfinish(conn); } [...] Tronci ( [email protected] ) Esercitazione libpq Basi di Dati 2007/2008 5 / 13 Stato della connessione Altre funzioni per la verifica dello stato della connessione sono: PQdb restituisce il nome del database a cui si è collegati char *PQdb(const PGconn *conn) PQuser restituisce il nome utente con cui si è collegati al database char *PQuser(const PGconn *conn) PQpass restituisce la password dell’utente con cui si è collegati char *PQpass(const PGconn *conn) PQhost restituisce il nome dell’host a cui si è collegati char *PQhost(const PGconn *conn) PQport restituisce la porta a cui si è collegati char *PQport(const PGconn *conn) Tronci ( [email protected] ) Esercitazione libpq Basi di Dati 2007/2008 6 / 13 Esecuzione comandi/query Per eseguire un comando od una query si deve utilizzare la seguente funzione: PGresult *PQexec(PGconn *conn, const char *command) dove conn è la connessione su cui si vuole eseguire il comando, e command è la stringa che contiene il comando da eseguire. Volendo in command possono essere contenuti più comandi/query separati tramite ;. Il puntatore alla struttura PGresult conterrà solo il risultato dell’ultimo comando/query. Un esempio di comando è: res = PGexec(conn,"INSERT INTO socio VALUES (29,’Giuseppe’,’Rossi’)") Un esempio di query è: res = PGexec(conn,"SELECT * FROM socio") Tronci ( [email protected] ) Esercitazione libpq Basi di Dati 2007/2008 7 / 13 Stato dell’esecuzione del comando/query Per la verifica dello stato dell’esecuzione si usa la seguente funzione: ExecStatusType PQresultStatus(const PGresult *res) Alcune delle risposte che si possono avere in uscita sono: PGRES_EMPTY_QUERY la stringa command mandata al server è vuota PGRES_COMMAND_OK Il comando è stato eseguito con successo (da utilizzare con comandi che non restituiscono dati, quali INSERT, DELETE ecc). PGRES_TUPLES_OK Il comando è stato eseguito con successo (da utilizzare con comandi che restituiscono dati, quali SELECT) PGRES_BAD_RESPONSE La risposta del server non è stata capita PGRES_NONFATAL_ERROR Si è verificato un errore non critico PGRES_FATAL_ERROR Si è verificato un errore critico Tronci ( [email protected] ) Esercitazione libpq Basi di Dati 2007/2008 8 / 13 Stato dell’esecuzione del comando/query Per ottenere una stringa che descriva l’errore utilizzare la funzione: char *PQresultErrorMessage(const PGresult *res) Dopo che non è più necessario conservare il risultato dell’esecuzione di un comando/query, bisogna utilizzare la seguente funzione per pulire la memoria: void PQclear(PGresult *res) Tronci ( [email protected] ) Esercitazione libpq Basi di Dati 2007/2008 9 / 13 Recupero dei dati dal risultato di una query Per recuperare il numero di tuple (righe) rstituite dall’interrogazione utilizzare: int PQntuples(const PGresult *res) Per recuperare il numero di attributi (colonne) presenti in ogni tupla restituita usare: int PQnfields(const PGresult *res) Per sapere qual’è il nome associato all’attributo (colonna) utilizzare la seguente funzione, le colonne sono numerate a partire da 0. char *PQfname(const PGresult *res,int columnNumber) Per sapere qual’è il tipo del dato associato ad un dato attributo utilizzare la seguente funzione. Viene restituito un numero intero che è l’identificativo OID del tipo. Oid PQftype(const PGresult *res,int columnNumber) Tronci ( [email protected] ) Esercitazione libpq Basi di Dati 2007/2008 10 / 13 Recupero dei dati dal risultato di una query Per ottenere in uscita una singola tupla di un dato PGresult bisogna usare la seguente funzione. Si ricorda che i numeri di riga e colonna partono da 0. Quello che si ottiene è in pratica un cursore che ci permette di utilizzare i dati recuperati. char *PQgetvalue(const PGresult *res, int row_number, int column_number); I dati sono in formato testuale o binario. Nel caso testuale sono stringhe complete del carattere di fine stringa. Poiché l’ouput è una stringa se i dati sono numerici è necessario convertirli da testo a numeri qualora si debbano fare ulteriori elaborazioni. Se l’attributo ha valore NULL viene restituita una stringa vuota. Tronci ( [email protected] ) Esercitazione libpq Basi di Dati 2007/2008 11 / 13 Recupero dei dati dal risultato di una query Per distinguere se si tratta di una stringa vuota o di un valore NULL bisogna usare la seguente funzione (restituisce 1 nel caso di valori NULL) int PQgetisnull(const PGresult *res, int row_number, int column_number); Tronci ( [email protected] ) Esercitazione libpq Basi di Dati 2007/2008 12 / 13 Recupero dei dati dal risultato di una query Per avere in uscita tutte le righe verso uno stream di output usare: void PQprint(FILE *fout, /* output stream */ const PGresult *res, const PQprintOpt *po); typedef struct { pqbool header; pqbool align; pqbool standard; pqbool html3; pqbool expanded; pqbool pager; char *fieldSep; char *tableOpt; char *caption; char **fieldName; } PQprintOpt; Tronci ( [email protected] ) // // // // // // // // // // output field headings and row count fill align the fields old brain dead format output HTML tables expand tables use pager for output if needed field separator attributes for HTML table element HTML table caption array of replacement field names Esercitazione libpq Basi di Dati 2007/2008 13 / 13