API C per a SQLite3

En aquest post presento un exemple de com fer servir l’API de C per a SQLite3 a Ubuntu 10.04.

L’API de C per a SQLite3 ens proporciona una interfície eficient per a programar aplicacions amb aquesta base de dades.

Per una banda crearé una base de dades nova. Fem servir l’SQLite Database Browser (es pot instal·lar des del Centre de Programari de l’Ubuntu).

Creo la ‘taula1’ amb tres columnes: id, del tipus integer; i valor i traduccio, les dues del tipus varchar.

Informo la taula amb algunes dades de prova:

Desenvolupo l’exemple fent servir la IDE Anjuta (si cal, es pot instal·lar des del centre de programari de l’Ubuntu). Creo un projecte C nou del tipus genèric (mínim).
Fins i tot sent un projecte “mínim” la quantitat de fitxers que genera Anjuta és important. Tanmateix, només ens caldrà modificar-ne dos: el main.c i el Makefile.am.

Li dono la ubicació del projecte i al fitxer main.c hi posem el següent codi


/*
 * main.c
 * Copyright (C) albert 2011 <stsoftlliure@gmail.com>
 *
 * c-sqlite is free software: you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the
 * Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * c-sqlite is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 * See the GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program.  If not, see <http://www.gnu.org/licenses/&gt;.
 */

#include <stdio.h>
#include <sqlite3.h>
int main(void) {
    /* variables */
    sqlite3 *conn;
    sqlite3_stmt *stmtResultSet;
    int iError=0;
    int iComptador=0;
    const char *tail;
   
    /* obre  la connexió a la bd*/
    /* int sqlite3_open(
    /*     const char *filename,   /* Database filename (UTF-8) */
    /*     sqlite3 **ppDb          /* OUT: SQLite db handle */
    /* );
    /*****/
    iError = sqlite3_open(“/home/albert/databases/sqlite3/prova-sqlite2/prova2.db3”,
                          &conn);
    if (iError) {
        puts(“No pot obrir la base de dades”);
        exit(0);
    }
   
    /* crea una instrucció per a executar-la, en aquest cas un update */
    /* int sqlite3_exec(
    /*     sqlite3*,                                  /* An open database */
    /*     const char *sql,                           /* SQL to be evaluated */
    /*     int (*callback)(void*,int,char**,char**),  /* Callback function */
    /*     void *,                                    /* 1st argument to callback */
    /*     char **errmsg                              /* Error msg written here */
    /* );
    /*****/
    iError = sqlite3_exec(conn,
                          “update taula1 set traduccio=\’nova traducció\’ where id=5”,
                          0,0,0);
    if (iError) {
        puts(“Error en fer update”);
        exit(0);
    }
   
    /* fa una query i obté un “resultset” */
    /*
    /* int sqlite3_prepare_v2(
    /*     sqlite3 *db,            /* Database handle */
    /*    const char *zSql,       /* SQL statement, UTF-8 encoded */
    /*    int nByte,              /* Maximum length of zSql in bytes. */
    /*    sqlite3_stmt **ppStmt,  /* OUT: Statement handle */
    /*    const char **pzTail     /* OUT: Pointer to unused portion of zSql */
    /* );
    /*****/
    iError = sqlite3_prepare_v2(conn,
                                “select id, valor, traduccio from taula1 order by id”,
                                1000,
                                &stmtResultSet,
                                &tail);
    if (iError != SQLITE_OK) {
        puts(“No pot obtenir dades”);
        exit(0);
    }
   
    puts(“—————————————“);
   
    /* mostra els resultats obtinguts iterant pas a pas pel pel “ResultSet” */
    /*
        int sqlite3_step(sqlite3_stmt*);
        After a prepared statement has been prepared using either sqlite3_prepare_v2() 
        this function must be called one or more times to evaluate the statement.
        If the SQL statement being executed returns any data,
        then SQLITE_ROW is returned each time a new row of data is ready
        for processing by the caller.
        The values may be accessed using the column access functions.
        sqlite3_step() is called again to retrieve the next row of data.
       
        Result Values From A Query:
        int sqlite3_column_int(sqlite3_stmt*, int iCol);
        const unsigned char *sqlite3_column_text(sqlite3_stmt*, int iCol);
    */                   
    while(sqlite3_step(stmtResultSet) == SQLITE_ROW) {
        /* en la fila actual, obté els valors de les columnes */
        printf(“%d |”, sqlite3_column_int(stmtResultSet, 0)); /* id,  decimal */
        printf(“%s |”, sqlite3_column_text(stmtResultSet, 1)); /* valor, varchar */
        printf(“%s \n”, sqlite3_column_text(stmtResultSet, 2)); /* traducció, varchar */
        iComptador++;
    }
    printf(“Total de registres: %d\n”, iComptador);
   
    /* tanca el resultset */
    /*
    /* int sqlite3_finalize(sqlite3_stmt *pStmt);
    /* The sqlite3_finalize() function is called to delete a prepared statement.
    /*****/
    sqlite3_finalize(stmtResultSet);
   
    /* tanca la connexió */
    /*
    /* int sqlite3_close(sqlite3 *);
    /* The sqlite3_close() routine is the destructor for the sqlite3 object.
    /*****/
    sqlite3_close(conn);
   
    return (0);
}

Per a poder compilar el codi anterior, és necessari enllaçar-lo amb la llibreria de l’SQLite3. Per a fer això, modifico {nom-projecte}_LDFLAGS = -lsqlite3.
Com a alternativa, també hauria pogut generar un makefile particular.

Inclús en tindríem prou amb una instrucció del tipus:
gcc ./main.c -o prova-csqlite.exe -lsqlite3

Finalment, podem compilar i muntar amb l’Anjuta; i executem:

EXECUTING:
/home/albert/wk-c/prova-c-sqlite/c_sqlite
———————————————-
1 |valor1 |traducció 1
2 |valor2 |traducció 2
3 |valor3 |traducció 3
4 |valor4 |traducció 4
5 |valor5 |nova traducció
Total de registres: 5

———————————————-
Program exited successfully with errcode (0)
Press the Enter key to close this terminal …

Com sempre, diposar de la documentació és clau per a poder reeixir en els desenvolupaments. La documentació està disponible al lloc de SQLite a Internet. D’aquesta altre adreça en podem descarregar un zip amb la documentació.

Deixa un comentari