// Package server implements the server. package server import ( "context" "database/sql" "fmt" "io/fs" "mime" "net/http" // The sqlite db and migration driver. _ "github.com/golang-migrate/migrate/v4/database/sqlite" "git.lyda.ie/kevin/boxes/api" "git.lyda.ie/kevin/boxes/database" "git.lyda.ie/kevin/boxes/web" "github.com/golang-migrate/migrate/v4" "github.com/golang-migrate/migrate/v4/source/iofs" "github.com/labstack/echo/v4" "github.com/labstack/echo/v4/middleware" "github.com/spf13/cobra" "modernc.org/sqlite" ) func init() { mime.AddExtensionType(".ico", "image/vnd.microsoft.icon") } // Run starts the metrics and API servers. func Run(cmd *cobra.Command, _ []string) { // Get configuration and basic pieces. listen, err := cmd.Flags().GetString("listen") cobra.CheckErr(err) dbfile, err := cmd.Flags().GetString("database") cobra.CheckErr(err) // Get the web server up. e := echo.New() e.Use(middleware.LoggerWithConfig(middleware.LoggerConfig{})) // Connect and configure the database. // See https://theitsolutions.io/blog/modernc.org-sqlite-with-go const pragmas = ` PRAGMA foreign_keys = ON; ` ctx := context.TODO() sqlite.RegisterConnectionHook(func(conn sqlite.ExecQuerierContext, _ string) error { _, err = conn.ExecContext(ctx, pragmas, nil) return err }) migrationFS, err := iofs.New(database.MigrationsFS, "migrations") cobra.CheckErr(err) migration, err := migrate.NewWithSourceInstance("iofs", migrationFS, "sqlite://"+dbfile) cobra.CheckErr(err) err = migration.Up() if err != nil && err != migrate.ErrNoChange { cobra.CheckErr(err) } db, err := sql.Open("sqlite", dbfile) cobra.CheckErr(err) // Get the static files served. filesTree, err := fs.Sub(web.Files, "files") cobra.CheckErr(err) filesHandler := http.FileServer(http.FS(filesTree)) e.GET("/", echo.WrapHandler(filesHandler)) e.GET("/*.*", echo.WrapHandler(filesHandler)) //e.GET("/images/*", echo.WrapHandler(http.StripPrefix("/images/", filesHandler))) // Get the endpoint handler set up. endpoints := NewEndpoints(db) server := api.NewStrictHandler(endpoints, nil) api.RegisterHandlers(e, server) // Put it all together. fmt.Printf("Server exited with: %+v\n", e.Start(listen)) }