Skip to content

Latest commit

 

History

History
149 lines (117 loc) · 5.21 KB

File metadata and controls

149 lines (117 loc) · 5.21 KB

5.3 SQLite

SQLite es una base de datos embebida de código abierto. Es una base de datos contenida en si misma, tiene 0 configuracieon y soporta transacciones. Es altamente portable, fácil de usar, compacta, eficiente y confiable. En la mayoría de los casos solamente se necesita crear una archivo de base de datos para crear conectarse y operar en una base de datos. Si estás buscando una solución embebida, SQLite es una opción para considerar. Se puede decir que SQLite es una versión de código abierto de Access.

Manejadores SQLite

Existen muchos manejadores de bases de datos para SQLite en Go, pero muchos de ellos no soportan los estándares de la interfaz database/sql.

El primer manejador es el único que soporta los estándares de la interfaz database/sql, por esto lo uso en mis proyectos, ya que será mas fácil migrar el código en el futuro si lo necesito.

Ejemplos

Crearemos el siguiente SQL:

	CREATE TABLE `userinfo` (
	    `uid` INTEGER PRIMARY KEY AUTOINCREMENT,
	    `username` VARCHAR(64) NULL,
	    `department` VARCHAR(64) NULL,
	    `created` DATE NULL
	);

Un ejemplo:

	package main

	import (
	    "database/sql"
	    "fmt"
	    "time"
	    _ "github.com/mattn/go-sqlite3"
	)

	func main() {
	    db, err := sql.Open("sqlite3", "./foo.db")
	    checkErr(err)

	    // insertar
	    stmt, err := db.Prepare("INSERT INTO userinfo(username, department, created) values(?,?,?)")
	    checkErr(err)

	    res, err := stmt.Exec("astaxie", "研发部门", "2012-12-09")
	    checkErr(err)

	    id, err := res.LastInsertId()
	    checkErr(err)

	    fmt.Println(id)
	    // actualizar
	    stmt, err = db.Prepare("update userinfo set username=? where uid=?")
	    checkErr(err)

	    res, err = stmt.Exec("astaxieupdate", id)
	    checkErr(err)

	    affect, err := res.RowsAffected()
	    checkErr(err)

	    fmt.Println(affect)

	    // consultar
	    rows, err := db.Query("SELECT * FROM userinfo")
	    checkErr(err)
	    var uid int
	    var username string
	    var department string
	    var created time.Time

	    for rows.Next() {
	        err = rows.Scan(&uid, &username, &department, &created)
	        checkErr(err)
	        fmt.Println(uid)
	        fmt.Println(username)
	        fmt.Println(department)
	        fmt.Println(created)
	    }

	    rows.Close() // Buen hábito cerrar

	    // eliminar
	    stmt, err = db.Prepare("delete from userinfo where uid=?")
	    checkErr(err)

	    res, err = stmt.Exec(id)
	    checkErr(err)

	    affect, err = res.RowsAffected()
	    checkErr(err)

	    fmt.Println(affect)

	    db.Close()

	}

	func checkErr(err error) {
	    if err != nil {
	        panic(err)
	    }
	}

Puedes notar que el código es casi el mismo que en la sección pasada, y es porque solamente cambiamos el nombre del manejador de bases de datos registrado llamando a sql.Open para conectarnos a SQLite de una manera diferente.

Nota que algunas veces no puedes usar la sentencia for porque no tienes mas de una fila, entonces puedes usar la sentencia if:

    if rows.Next() {
        err = rows.Scan(&uid, &username, &department, &created)
        checkErr(err)
        fmt.Println(uid)
        fmt.Println(username)
        fmt.Println(department)
        fmt.Println(created)
    }

También tienes que ahcer un rows.Next() sin usar eso que no puedes obtener en la función Scan.

Transacciones

El ejemplo de arriba muestra como puedes obtener datos de una base de datos, pero cuando quieres escribir aplicaciones web, no solo vas a consultar información de la base de datos sino que también quieres escribir en ella. Para este propósito tu puedes usar transacciones, porque puedes tener múltiples rutinas que accesan a la base de datos, y la base de datos se podría bloquear. Esto no es deseable en una aplicación web y el uso de transacciones es efectivo asegurando que las operaciones sean exitosas en total o fallen completamente, dependiendo de las circunstancias. Es claro que el uso de transacciones puede prevenir un montón de problemas que pueden ocurrir en una aplicación web.

    trashSQL, err := database.Prepare("update task set is_deleted='Y',last_modified_at=datetime() where id=?")
    if err != nil {
        fmt.Println(err)
    }
    tx, err := database.Begin()
    if err != nil {
    	fmt.Println(err)
    }
    _, err = tx.Stmt(trashSQL).Exec(id)
    if err != nil {
    	fmt.Println("doing rollback")
    	tx.Rollback()
    } else {
    	tx.Commit()
    }

Como es claro en el código de arribam primero debes prepara un Statement, después debes ejecutarlo, dependiendo de la salida de esa ejecución, puedes volver atrás o mantenerlo.

Como última nota de esta sección, aquí está una herramienta de mantenimiento para SQLite: http://sqlitebrowser.org

Enlaces