Newer
Older
"github.com/jmoiron/sqlx"
"modernc.org/ql"
_ "modernc.org/ql/driver"
)
//go:embed templates/*.tpl
var templateFS embed.FS
//go:embed static/*
var staticFS embed.FS
func httpError(w http.ResponseWriter, msg string, err error, status int) {
if err != nil {
msg += ": " + err.Error()
}
log.Println(msg)
http.Error(w, msg, status)
func logRequest(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
start := time.Now()
defer func() {
d := time.Since(start)
log.Println("handled", r.Method, r.URL, "from", r.RemoteAddr, "by", auth.Get(r), "in", d)
}()
next.ServeHTTP(w, r)
})
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
func openQLdb(path string) (*sqlx.DB, error) {
var retried bool
path += ".ql"
retry:
db, err := sqlx.Open("ql2", path)
if err != nil {
return nil, err
}
log.Println("running test-select on db")
_, err = db.Exec(`SELECT count(*) FROM __Table`)
if err != nil && !retried {
log.Println("got err:", err)
retried = true
// WAL may be corrupted. Manually remove it and re-try open. See
// https://gitlab.com/cznic/ql/-/issues/227 for more info.
err := os.Remove(ql.WalName(path))
if err != nil {
return nil, err
}
goto retry
}
if err != nil {
return nil, err
}
return db, nil
}
dbPath := flag.String("db", "vino", "Path to database file")
listenAddr := flag.String("listen", "127.0.0.1:7878", "Listening address")
flag.Parse()
sqlDB, err := openQLdb(*dbPath)
if err != nil {
log.Fatalln("can't open DB:", err)
}
defer sqlDB.Close()
db, err := bolt.Open(*dbPath+".db", 0644, nil)
if err != nil {
log.Fatalln("can't open DB:", err)
}
defer db.Close()
err = initSQLdb(context.TODO(), sqlDB)
if err != nil {
log.Fatalln("can't initalize DB:", err, ql.WalName(*dbPath+".ql"))
}
err = initBoltDB(db)
if err != nil {
log.Fatalln("can't initialize DB:", err)
}
err = migrateBoltToQL(context.TODO(), db, sqlDB)
if err != nil {
log.Fatalln("can't migrate bolt to sql db:", err)
}
http.HandleFunc("/favicon.ico", http.NotFound)
http.Handle("/static/", logRequest(http.FileServer(http.FS(staticFS))))
http.Handle("/details/img", auth.Require(logRequest(handler.img()), ap))
http.Handle("/details/", auth.Require(logRequest(handler.details()), ap))
http.Handle("/user/", auth.Require(logRequest(handler.user()), ap))
http.Handle("/", auth.Require(logRequest(handler.index()), ap))
log.Printf("here we go, listening on http://%s", *listenAddr)
err = http.ListenAndServe(*listenAddr, nil)