Esercitazione sulle libpq - libreria C per PostgreSQL Roberto Tronci roberto.tronci@diee.unica.it Basi di Dati A.A. 2007/2008 Tronci ( roberto.tronci@diee.unica.it ) 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 ( roberto.tronci@diee.unica.it ) 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 ( roberto.tronci@diee.unica.it ) 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 ( roberto.tronci@diee.unica.it ) 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 ( roberto.tronci@diee.unica.it ) 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 ( roberto.tronci@diee.unica.it ) 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 ( roberto.tronci@diee.unica.it ) 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 ( roberto.tronci@diee.unica.it ) 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 ( roberto.tronci@diee.unica.it ) 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 ( roberto.tronci@diee.unica.it ) 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 ( roberto.tronci@diee.unica.it ) 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 ( roberto.tronci@diee.unica.it ) 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; // output field headings and row count pqbool align; // fill align the fields pqbool standard; // old brain dead format pqbool html3; // output HTML tables pqbool expanded; // expand tables pqbool pager; // use pager for output if needed char *fieldsep; // field separator char *tableopt; // attributes for HTML table element char *caption; // HTML table caption char **fieldname; // array of replacement field names } PQprintOpt; Tronci ( roberto.tronci@diee.unica.it ) Esercitazione libpq Basi di Dati 2007/2008 13 / 13