SQLite
es una biblioteca ANSI C
que implementa un motor de bases de datos
pequeño, rápido, autocontenido, de alta fiabilidad, y de funcionalidad SQL
completa.
La base de datos SQLite
es un archivo de formato estable, multi plataforma, y
retro compatible, usada comúnmente para transferir contenido entre sistemas. No
requiere configuración adicional ni servidores dedicados.
SQLite
es uno de los motores de bases de datos relacionales más conocidos; su
compatibilidad y portabilidad la hacen una herramienta ampliamente usada. Un
archivo de base de datos SQLite
se puede copiar libremente entre sistemas de
32 y 64 bits, así como entre arquitecturas big-endian y little-endian.
SQLite con Conan
Hay múltiples maneras de incluir SQLite en un proyecto; personalmente considero
que la forma más sencilla de usar una biblioteca de terceros es por medio
de Conan
, siempre y cuando esté disponible. En esta publicación sobre
Conan como administrador de paquetes
se puede ver más sobre cómo usar Conan
.
Para incluir SQLite
versión 3.33
en un proyecto CMake
se crea un archivo
conanfile.txt
usando el generador cmake_find_package
:
# conanfile.txt
[requires]
sqlite3/3.33.0
[generators]
cmake_find_package
Se ajusta el CMakeLists.txt
para encontrar el paquete, y se enlaza la
biblioteca:
# CMakeLists.txt
#...
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_BINARY_DIR})
find_package(SQLite3 REQUIRED)
#...
target_link_libraries(${PROJECT_NAME} PRIVATE SQLite::SQLite3)
target_compile_features(${PROJECT_NAME} PUBLIC cxx_std_17)
Y se incluye el archivo de cabecera:
#include <sqlite3.h>
Conan
se encarga de la descarga e instalación, por lo cual los esfuerzos se
pueden enfocar más en el proyecto, y menos en el manejo de dependencias.
Un ejemplo básico de su uso es crear una tabla, poblarla, y consultarla.
Sentencias SQL
El primer paso es crear la base de datos lo cual se puede hacer desde un terminal o consola ejecutando:
sqlite3 database.sqlite3
Con el comando anterior se crea el archivo database.sqlite3
.
En los siguientes pasos se crea una tabla, después se le insertan valores, y
finalmente se consultan esos valores.
DROP TABLE dual;
CREATE TABLE dual
(
Col1 varchar2(255),
Col2 int
);
INSERT INTO "dual" VALUES('valor',10);
SELECT * FROM dual;
Suponiendo que se va a crear solamente una tabla llamada “dual”
primero hay que asegurarse de que no exista: DROP
se encarga de borrarla si
existe.
Luego se crea la tabla dual con las columnas Col1 y Col2.
Se le insertan los valores.
Finalmente se consultan.
SQLite en C++
Para seguir los mismos pasos anteriores en C++:
-
Se crea la base de datos indicándole un nombre y un handler. Si ya existe la reabre:
sqlite3* dbHandler = nullptr; auto result = sqlite3_open("database.sqlite3", &dbHandler);
Se puede crear una función auxiliar para ejecutar las sentencias
int runStatement(const char* statement) { return sqlite3_exec(dbHandler, statement, printCallback, static_cast<void*>(data), &errorMessage); }
-
Se verifica que la tabla dual no exista:
if (runStatement("DROP TABLE dual") != SQLITE_OK) { std::cerr << "SQL error: " << errorMessage << '\n'; sqlite3_free(errorMessage); }
-
Se crea la tabla:
const auto create = "CREATE TABLE dual (Col1 varchar2(255), Col2 int);"; if (runStatement(create) != SQLITE_OK) { std::cerr << "SQL error: " << errorMessage << '\n'; sqlite3_free(errorMessage); }
-
Se le insertan valores:
const auto insert = "INSERT INTO dual VALUES('valor',10);"; if (runStatement(insert) != SQLITE_OK) { std::cerr << "SQL error: " << errorMessage << '\n'; sqlite3_free(errorMessage); }
-
Se consulta el contenido de la tabla:
const auto select = "SELECT * FROM dual;"; if (runStatement(select) != SQLITE_OK) { std::cerr << "SQL error: " << errorMessage << '\n'; sqlite3_free(errorMessage); }
-
Finalmente se cierra la base de datos:
sqlite3_close(dbHandler);
La base de datos
Al crear la base de datos database.sqlite3
se genera el esquema main con la
tabla sqlite_master de manera automática.
Al crear la tabla dual esta queda dentro de ese mismo esquema.
Conclusiones
Es bastante útil y sencillo usar sqlite3
para crear una base de datos, y
vincularla al proyecto es fácil usando Conan; no obstante, el código es más C
que C++
y podría tornarse particularmente complejo en sentencias más
elaboradas, por ejemplo, al intentar recuperar valores individuales de una
columna en particular.
Por fortuna existe una biblioteca llamada SOCI la cual envuelve sqlite3
para hacer más sencilla e intuitiva la programación de SQL
en C++
dando la ilusión de que el código queda incrustado, y de la cual se puede ver un
ejemplo en la publicación
SQL incrustado usando SOCI
Deja un comentario