package main

import (
	"context"
	"database/sql"
	"database/sql/driver"

	moderncsqlite "modernc.org/sqlite"
)

func init() {
	// mautrix dbutil opens sqlite as "sqlite3"; register the pure-Go driver
	// under that name. We add a connection hook that sets WAL mode and a
	// busy timeout on every connection to prevent SQLITE_BUSY crashes during
	// concurrent writes (crypto store sync + memory store).
	d := &moderncsqlite.Driver{}
	d.RegisterConnectionHook(sqlitePragmaHook)
	sql.Register("sqlite3", d)
}

// sqlitePragmaHook sets WAL journal mode and a 5-second busy timeout on
// every new SQLite connection. This prevents SQLITE_BUSY errors when
// multiple goroutines write concurrently (e.g. mautrix crypto sync +
// memory/knowledge stores).
func sqlitePragmaHook(conn moderncsqlite.ExecQuerierContext, _ string) error {
	ctx := context.Background()
	pragmas := []string{
		"PRAGMA journal_mode=WAL",
		"PRAGMA busy_timeout=5000",
	}
	for _, p := range pragmas {
		if _, err := conn.ExecContext(ctx, p, []driver.NamedValue{}); err != nil {
			return err
		}
	}
	return nil
}
