Skip to content

Instantly share code, notes, and snippets.

@lbe
Last active March 15, 2024 20:11
Show Gist options
  • Save lbe/c22fb6d9a5edaedd80711608e2b7a479 to your computer and use it in GitHub Desktop.
Save lbe/c22fb6d9a5edaedd80711608e2b7a479 to your computer and use it in GitHub Desktop.
Go demo code lazy initialization with sync.OnceValue
/*
This code is released under the MIT license - https://opensource.org/license/mit
*/
package main
import (
"database/sql"
"log"
"sync"
_ "github.com/mattn/go-sqlite3"
)
type tDB struct {
dsn string
db func() *sql.DB
stmt map[string]func() *sql.Stmt
}
func newServer(dbFn string) *tDB {
dsn := dbFn
return &tDB{
dsn: dsn,
db: sync.OnceValue(func() *sql.DB {
db, err := sql.Open("sqlite3", dsn)
if err != nil {
log.Fatal(err)
}
log.Println("Database connection opened")
return db
}),
stmt: make(map[string]func() *sql.Stmt),
}
}
func (d *tDB) createSchema() {
sql := "CREATE TABLE IF NOT EXISTS user (id text NOT NULL, name text NOT NULL);"
_, err := d.db().Exec(sql)
if err != nil {
log.Fatalf("%+v", err)
}
log.Println("Schema created")
}
func (d *tDB) prepareStmtOnce(name string, s string) func() *sql.Stmt {
return sync.OnceValue(func() *sql.Stmt {
stmt, err := d.db().Prepare(s)
if err != nil {
log.Fatal(err)
}
log.Printf("Prepared Statement Created with name: %s", name)
return stmt
})
}
func (d *tDB) loadPrepStmtSql(name string, s string) {
d.stmt[name] = d.prepareStmtOnce(name, s)
}
func (d *tDB) preparedStmt(name string) *sql.Stmt {
return d.stmt[name]()
}
func main() {
dbFn := ":memory:"
d := newServer(dbFn)
d.createSchema() // Opens database connection via d.db
d.loadPrepStmtSql("selectUser", "SELECT * FROM user")
for i := 0; i < 10; i++ {
log.Println(i)
db := d.db() // log msg not printed since database was already open
_ = db
stmt := d.preparedStmt("selectUser") // log msg only printed on first time through
_ = stmt
_ = 1
}
log.Println("Finished")
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment