Nessun risultato. Prova con un altro termine.
Guide
Notizie
Software
Tutorial
  • Lezione 50 di 58
  • livello intermedio
Indice lezioni

C/C++: API per l'accesso al DB

Utilizzare le API di C e C++ per interagire con un database relazionale basato su MySQL, sfruttando il MySQL Connector/C.
Utilizzare le API di C e C++ per interagire con un database relazionale basato su MySQL, sfruttando il MySQL Connector/C.
Link copiato negli appunti

In questa lezione impareremo ad interagire con MySQL utilizzando due dei linguaggi in assoluto più noti, diffusi ed utilizzati al mondo: C e C++. Dal momento che la sintassi ed il connector sono compatibili con entrambi i linguaggi, quello che vedremo di seguito potrà essere applicato indistintamente sia ad applicazioni scritte in C, sia a quelle sviluppate in C++.

Installazione del Connector

Come già accennato in precedenza, prima di passare al codice vero e proprio dovremo necessariamente installare un connector che ci permetterà di dialogare direttamente con il database. Per C e C++, generalmente si fa riferimento al connector ufficiale, che è MySQL Connector/C.

L'installazione è estremamente semplice: scarichiamo MySQL Connector/C dal sito ufficiale, scegliando la versione più adatta al nostro sistema operativo. Possiamo optare per un pacchetto .msi autoinstallante, o per un archivio .zip. Sebbene la prima opzione sia quella consigliata, nel caso in cui scegliessimo l'archivio .zip, dovremo estrarne il contenuto in C:\Program Files\MySQL\MySQL Connector C X.X, dove X.X è la versione del connector appena scaricata (ad esempio, 6.1).

Completata l'installazione, non resta che imparare ad interagire con il database direttamente dal codice.

API per l'interfacciamento con il database

Una volta installato il connector, l'uso delle API è abbastanza immediato. Vediamo subito un semplice programma di esempio:

#include <stdio.h>
#include <windows.h>
#include <mysql.h>
MYSQL *conn;
int version = 1;
int main (int argc, char *argv[])
{
    conn = mysql_init (NULL);
    mysql_real_connect(conn, "localhost", "root",
            "password", "test", 3308, NULL, 0);
	version = mysql_get_server_version(conn);
	printf("\nVersione MySQL: %d\n",version);
    mysql_close(conn);
    return 0;
}

Per prima cosa, tutti i programmi devono includere l'header file <mysql.h>. Inoltre, sarà necessario definire un puntatore a MYSQL (che in questo caso di chiama conn), inizializzato tramite il metodo mysql_init(NULL), e che deve essere l'unica variabile di questo genere. Utilizzando tale puntatore sarà quindi possibile effettuare la connessione al nostro database MySQL.

Prima dell'effettiva connessione, possiamo specificare eventuali opzioni tramite la funzione mysql_options(). Nel nostro caso, non abbiamo bisogno di specificare nulla, e di conseguenza abbiamo omesso questa chiamata (che andrebbe subito dopo l'inizializzazione di conn).

Effettuiamo quindi la connessione al database tramite la funzione mysql_real_connect(), che accetta come parametri proprio l'oggetto conn, seguito dall'indirizzo IP del database (in questo caso localhost), il nome utente (root), la password, il nome del database (test) e la porta (3308). In linea di massima, possiamo impostare gli ultimi due parametri (rappresentanti rispettivamente la socket UNIX ed i flag) a NULL e 0.

Nell'esempio precedente, ci siamo limitati a stampare la versione di MySQL, utilizzando la funzione mysql_get_server_version(). Abbiamo poi terminato la connessione tramite la funzione mysql_close(conn), che va sempre richiamata quando terminiamo di dialogare con il database. Vedremo nel seguito come effettuare qualche semplice query.

Creare e modificare un database

Il codice che segue mostra come creare un database MySQL:

#include <my_global.h>
#include <mysql.h>
MYSQL *conn;
int main(int argc, char **argv)
{
  con = mysql_init(NULL);
  if (con == NULL)
  {
      fprintf(stderr, "%s\n", mysql_error(con));
      exit(1);
  }
  if (mysql_real_connect(con, "localhost", "root", "root_pswd",
          NULL, 0, NULL, 0) == NULL)
  {
      fprintf(stderr, "%s\n", mysql_error(con));
      mysql_close(con);
      exit(1);
  }  
  if (mysql_query(con, "CREATE DATABASE testdb"))
  {
      fprintf(stderr, "%s\n", mysql_error(con));
      mysql_close(con);
      exit(1);
  }
  mysql_close(con);
  exit(0);
}

In questo caso, abbiamo innanzitutto aggiunto l'header file <my_global.h>, che comprende alcune funzioni di comodo per l'interazione con MySQL. Quindi, avere verificato la correttezza della connessione, utilizziamo la funzione mysql_query() per inviare il comando SQL di creazione del database (in questo caso, CREATE DATABASE testdb).

È facile immaginare l'estensione di questa funzionalità a molte altre operazioni supportate da MySQL. Ad esempio, modificando il secondo parametro della funzione mysql_query(), possiamo facilmente effettuare query di aggiornamento (UPDATE) o inserimento (INSERT), come nel caso seguente:

if (mysql_query(con, "INSERT INTO Cars VALUES(5,'Audi',350000)")) {
      fprintf(stderr, "%s\n", mysql_error(con));
      mysql_close(con);
      exit(1);
  }

Leggere dati dal database

Non ci resta che capire come leggere i dati dal database. Per farlo, vedremo un esempio di utilizzo di una query di selezione, e come utilizzare i risultati da essa ottenuti.

#include <my_global.h>
#include <mysql.h>
void finish_with_error(MYSQL *con)
{
  fprintf(stderr, "%s\n", mysql_error(con));
  mysql_close(con);
  exit(1);
}
MYSQL *con;
int main(int argc, char **argv)
{
  con = mysql_init(NULL);
  if (con == NULL)
  {
      fprintf(stderr, "mysql_init() failed\n");
      exit(1);
  }  
  if (mysql_real_connect(con, "localhost", "user12", "34klq*",
          "testdb", 0, NULL, 0) == NULL)
  {
      finish_with_error(con);
  }    
  if (mysql_query(con, "SELECT * FROM Cars"))
  {
      finish_with_error(con);
  }
  MYSQL_RES *result = mysql_store_result(con);
  if (result == NULL)
  {
      finish_with_error(con);
  }
  int num_fields = mysql_num_fields(result);
  MYSQL_ROW row;
  while ((row = mysql_fetch_row(result)))
  {
      for(int i = 0; i < num_fields; i++)
      {
          printf("%s ", row[i] ? row[i] : "NULL");
      }
          printf("\n");
  }
  mysql_free_result(result);
  mysql_close(con);
  exit(0);
}

Tralasciando le operazioni di connessione già viste in precedenza, focalizziamo la nostra attenzione sulla riga:

MYSQL_RES *result = mysql_store_result(con);

Dopo avere eseguito la funzione mysql_query(), infatti, gli eventuali risultati della query (che in questo caso consisteva in un'operazione di selezione) possono essere ottenuti richiamando la funzione mysql_store_result(), che restituisce un puntatore a MYSQL_RES. Utilizzando questo puntatore, unitamente alle funzioni mysql_num_fields() e mysql_fetch_row(), potremo effettuare un classico ciclo for o while per leggere tutti i valori, come mostrato in maniera abbastanza autoesplicativa nel codice precedente.

Conclusioni

Chiaramente si potrebbe continuare a lungo ad approfondire le funzionalità messe a disposizione dalle API MySQL per C. Per un maggiore approfondimento, si rimanda quindi a questa guida dettagliata.

Ti consigliamo anche