func (m *SQLModel) DeleteList(id string) error {
	_, err := m.db.Exec("UPDATE lists SET time_deleted = CURRENT_TIMESTAMP WHERE id = ?", id)
	return err
}
DeleteList (soft) deletes the given list (its items actually remain
untouched). It's not an error if the list doesn't exist.
package main
import (
	"database/sql"
	"encoding/hex"
	"math/rand"
	"strconv"
	"time"
)
type List struct {
	ID          string
	TimeCreated time.Time
	Name        string
	Items       []*Item
}
type Item struct {
	ID          string
	Description string
	Done        bool
}
type SQLModel struct {
	db  *sql.DB
	rnd *rand.Rand
}
func NewSQLModel(db *sql.DB) (*SQLModel, error) {
	rnd := rand.New(rand.NewSource(time.Now().UnixNano()))
	model := &SQLModel{db, rnd}
	_, err := model.db.Exec(`
		CREATE TABLE IF NOT EXISTS lists (
			id VARCHAR(10) NOT NULL PRIMARY KEY,
			time_created TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
			name VARCHAR(255) NOT NULL,
		    time_deleted TIMESTAMP
		);
		CREATE TABLE IF NOT EXISTS items (
			id INTEGER NOT NULL PRIMARY KEY,
			list_id INTEGER NOT NULL REFERENCES lists(id),
			time_created TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
			description VARCHAR(255) NOT NULL,
		    done BOOLEAN NOT NULL DEFAULT FALSE,
		    time_deleted TIMESTAMP
		);
		CREATE INDEX IF NOT EXISTS items_list_id ON items(list_id);
		CREATE TABLE IF NOT EXISTS sign_ins (
		    id VARCHAR(64) NOT NULL PRIMARY KEY,
			time_created TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
		);
		`)
	return model, err
}
func (m *SQLModel) GetLists() ([]*List, error) {
	rows, err := m.db.Query(`
		SELECT id, name, time_created
		FROM lists
		WHERE time_deleted IS NULL
		ORDER BY time_created DESC
		`)
	if err != nil {
		return nil, err
	}
	defer rows.Close()
	var lists []*List
	for rows.Next() {
		var list List
		err = rows.Scan(&list.ID, &list.Name, &list.TimeCreated)
		if err != nil {
			return nil, err
		}
		lists = append(lists, &list)
	}
	return lists, rows.Err()
}
func (m *SQLModel) CreateList(name string) (string, error) {
	id := m.makeListID(10)
	timeCreated := time.Now().In(time.UTC).Format(time.RFC3339Nano)
	_, err := m.db.Exec("INSERT INTO lists (id, name, time_created) VALUES (?, ?, ?)",
		id, name, timeCreated)
	return id, err
}
var listIDChars = "bcdfghjklmnpqrstvwxyz"  
func (m *SQLModel) makeListID(n int) string {
	id := make([]byte, n)
	for i := 0; i < n; i++ {
		index := m.rnd.Intn(len(listIDChars))
		id[i] = listIDChars[index]
	}
	return string(id)
}