DocumentaciónBases de Datos

Bases de Datos

BLOX incorpora soporte para bases de datos SQLite mediante el tipo SQLITE y la API sqlite.api.

Esto permite:

  • abrir o crear una base de datos
  • ejecutar sentencias SQL
  • consultar datos y recibirlos como TABLA
  • persistir tablas planas de BLOX
  • recuperar esas tablas más adelante

En otras palabras, BLOX ya no depende solo de archivos de texto o JSON para conservar información: también puede trabajar con una base de datos real.

Tipo de dato SQLITE

Una variable de tipo SQLITE representa una conexión abierta a una base de datos SQLite.

ejemplo.blox
SQLITE db

db = sqlite.abrir("datos.db")

Ese valor no contiene los datos directamente.
Contiene un handle de conexión que luego se usa para ejecutar sentencias o traer resultados.

API básica

La API principal actual es:

  • sqlite.abrir(archivo)
  • sqlite.cerrar(db)
  • sqlite.ejecutar(db, sql)
  • sqlite.consulta(db, sql)
  • sqlite.importar(db, nombre_tabla, tabla)
  • sqlite.exportar(db, sql)

Abrir y cerrar una base

ejemplo.blox
INCLUIR "sqlite.api"

FUNCION PRINCIPAL
INICIO

    SQLITE db

    db = sqlite.abrir("mi_base.db")

    // ... trabajo con la base ...

    sqlite.cerrar(db)

FINAL

Qué hace sqlite.abrir()

  • si el archivo existe, lo abre
  • si no existe, lo crea
  • retorna un valor de tipo SQLITE

Qué hace sqlite.cerrar()

  • cierra la conexión
  • libera recursos internos

Ejecutar SQL sin resultado tabular

Usa sqlite.ejecutar() para sentencias como:

  • CREATE TABLE
  • INSERT
  • UPDATE
  • DELETE
  • DROP
ejemplo.blox
INCLUIR "sqlite.api"

FUNCION PRINCIPAL
INICIO

    SQLITE db

    db = sqlite.abrir("personas.db")

    sqlite.ejecutar(db, "CREATE TABLE IF NOT EXISTS personas (id INTEGER, nombre TEXT);")
    sqlite.ejecutar(db, "INSERT INTO personas VALUES (1, 'Ana');")
    sqlite.ejecutar(db, "INSERT INTO personas VALUES (2, 'Luis');")

    sqlite.cerrar(db)

FINAL

Consultar datos con sqlite.consulta()

Cuando una sentencia SQL devuelve filas, BLOX las recibe como una TABLA.

ejemplo.blox
INCLUIR "sqlite.api"
INCLUIR "tablas.api"

FUNCION PRINCIPAL
INICIO

    SQLITE db
    TABLA t

    db = sqlite.abrir("personas.db")

    t = sqlite.consulta(db, "SELECT id, nombre FROM personas ORDER BY id;")

    tablas.imprimir(t)

    sqlite.cerrar(db)

FINAL

Resultado

La consulta retorna una TABLA BLOX con tipado por celda.

Ejemplo conceptual:

ejemplo.blox
{
    id = 1,
    nombre = "Ana"
}

Persistir tablas con sqlite.importar()

Si ya tienes una TABLA en memoria, puedes enviarla a SQLite.

ejemplo.blox
INCLUIR "sqlite.api"

FUNCION PRINCIPAL
INICIO

    SQLITE db
    TABLA t

    t = {id = 1, nombre = "Ana", saldo = 10.5}
    t = {id = 2, nombre = "Luis", saldo = 7.0, nota = "ok"}

    db = sqlite.abrir("personas.db")

    sqlite.importar(db, "personas", t)

    sqlite.cerrar(db)

FINAL

Comportamiento actual

  • recrea la tabla destino
  • soporta campos escalares:
    • NUMERICO
    • LOGICO
    • STRING
    • VACIO
  • los campos faltantes se guardan como NULL

Esto la vuelve especialmente útil para:

  • persistir resultados de programas
  • guardar catálogos o listados
  • conservar datos intermedios
  • mover tablas entre ejecuciones

Recuperar tablas con sqlite.exportar()

sqlite.exportar() es una forma semántica de decir:

  • "sacar datos desde SQLite"
  • "obtenerlos nuevamente como una TABLA BLOX"
ejemplo.blox
INCLUIR "sqlite.api"
INCLUIR "tablas.api"

FUNCION PRINCIPAL
INICIO

    SQLITE db
    TABLA out

    db = sqlite.abrir("personas.db")

    out = sqlite.exportar(db, "SELECT id, nombre, saldo, nota FROM personas ORDER BY id;")

    tablas.imprimir(out)

    sqlite.cerrar(db)

FINAL

Relación con TABLA

SQLite y TABLA se complementan muy bien en BLOX:

  • TABLA sirve para trabajar con los datos en memoria
  • SQLITE sirve para persistirlos y consultarlos

Esto permite flujos como:

  • archivo json/dat -> TABLA
  • TABLA -> SQLite
  • SQLite -> TABLA
  • TABLA -> JSON

Límite actual importante

La versión actual de sqlite.importar/exportar está pensada para tablas planas.

Eso significa:

  • funciona bien con campos escalares
  • no está pensada para normalizar automáticamente subtablas anidadas

Si los datos son jerárquicos o muy anidados, la estrategia correcta es:

  • diseñar varias tablas relacionadas
  • o generar esa base externamente y luego consultarla desde BLOX

NULL

Cuando SQLite devuelve un valor NULL, BLOX hoy lo representa como un valor nulo interno y lo imprime como:

ejemplo.blox
NULL

Esto permite distinguirlo de:

  • 0
  • ""
  • FALSO

Caso de uso típico

Una secuencia muy natural en BLOX es esta:

  1. cargar datos externos a una TABLA
  2. persistirlos con sqlite.importar()
  3. hacer consultas SQL
  4. recuperar resultados como TABLA
  5. imprimir, filtrar, graficar o exportar

Un ejemplo resumido

ejemplo.blox
INCLUIR "sqlite.api"
INCLUIR "tablas.api"

FUNCION PRINCIPAL
INICIO

    SQLITE db
    TABLA t, out

    t = {id = 1, nombre = "Ana", saldo = 10.5}
    t = {id = 2, nombre = "Luis", saldo = 7.0}

    db = sqlite.abrir("demo.db")

    sqlite.importar(db, "personas", t)

    out = sqlite.exportar(db, "SELECT nombre, saldo FROM personas ORDER BY nombre;")

    tablas.imprimir(out)

    sqlite.cerrar(db)

FINAL

Conclusión

Con SQLite, BLOX da un paso importante hacia programas con persistencia real.

Ya no se trata solo de calcular o procesar datos en memoria.
Ahora también puede:

  • guardar
  • recuperar
  • consultar
  • reorganizar
  • reutilizar información entre ejecuciones

Esto convierte a TABLA y SQLITE en una combinación muy poderosa para aplicaciones prácticas.