Last active
March 15, 2024 20:11
-
-
Save lbe/c22fb6d9a5edaedd80711608e2b7a479 to your computer and use it in GitHub Desktop.
Go demo code lazy initialization with sync.OnceValue
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
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