aboutsummaryrefslogtreecommitdiff
path: root/cmd/server/main.go
diff options
context:
space:
mode:
authorFelix Hanley <felix@userspace.com.au>2020-02-09 12:17:30 +0000
committerFelix Hanley <felix@userspace.com.au>2020-02-09 12:17:30 +0000
commitd7cd138025572c59bfc4964e464d899f396b7e41 (patch)
tree02f20073402b7035b19fb343452460d763f1b293 /cmd/server/main.go
parentd60cef9865eb1455ce6448e7fe46226e71a5e2f7 (diff)
downloadsws-d7cd138025572c59bfc4964e464d899f396b7e41.tar.gz
sws-d7cd138025572c59bfc4964e464d899f396b7e41.tar.bz2
Capture current staging state
Diffstat (limited to 'cmd/server/main.go')
-rw-r--r--cmd/server/main.go103
1 files changed, 85 insertions, 18 deletions
diff --git a/cmd/server/main.go b/cmd/server/main.go
index 9b9fa6f..3abca0b 100644
--- a/cmd/server/main.go
+++ b/cmd/server/main.go
@@ -2,47 +2,114 @@ package main
import (
"database/sql"
+ "flag"
"fmt"
"net/http"
"os"
+ "strings"
+ "time"
"github.com/go-chi/chi"
_ "github.com/jackc/pgx/stdlib"
+ "github.com/jmoiron/sqlx"
+ _ "github.com/mattn/go-sqlite3"
+ "src.userspace.com.au/flags"
+ "src.userspace.com.au/go-migrate"
+ "src.userspace.com.au/sws"
)
+// Flags
+var (
+ verbose *bool
+ addr *string
+ dsn *string
+ noMigrate *bool
+)
+
+var log, debug sws.Logger
+
+func init() {
+ verbose = flags.Bool("verbose", "v", false, "VERBOSE", "enable verbose output")
+ addr = flags.String("listen", "l", "localhost:5000", "LISTEN", "listen address")
+ dsn = flags.String("dsn", "", "file:sws.db?cache=shared", "DSN", "database password")
+ noMigrate = flags.Bool("no-migrate", "m", false, "NOMIGRATE", "disable migrations")
+
+ // Default to no log
+ log = func(v ...interface{}) {}
+ debug = func(v ...interface{}) {}
+}
+
func main() {
- db, err := sql.Open(
- "pgx",
- fmt.Sprintf(
- "postgres://%s:%s@%s:5432/%s?sslmode=disable",
- os.Getenv("PG_USER"),
- os.Getenv("PG_PASS"),
- envString("PG_HOST", "localhost"),
- envString("PG_DB", "swa"),
- ),
- )
+ flag.Parse()
+
+ if *verbose {
+ log = func(v ...interface{}) {
+ fmt.Fprintf(os.Stdout, "[%s] ", time.Now().Format(time.RFC3339))
+ fmt.Fprintln(os.Stdout, v...)
+ }
+ }
+ if d := os.Getenv("DEBUG"); d != "" {
+ debug = func(v ...interface{}) {
+ fmt.Fprintf(os.Stdout, "[%s] ", time.Now().Format(time.RFC3339))
+ fmt.Fprintln(os.Stdout, v...)
+ }
+ }
+
+ driver := strings.SplitN(*dsn, ":", 2)[0]
+ if driver == "file" {
+ driver = "sqlite3"
+ }
+ db, err := sqlx.Open(driver, *dsn)
if err != nil {
fmt.Println(err)
os.Exit(1)
}
+ defer db.Close()
if err := db.Ping(); err != nil {
fmt.Println(err)
os.Exit(1)
}
+ if noMigrate == nil || !*noMigrate {
+ version, err := migrateDatabase(db, driver)
+ if err != nil {
+ fmt.Fprintf(os.Stderr, "failed to migrate: %s", err)
+ os.Exit(2)
+ }
+ log("database at version", version)
+ }
+
r := chi.NewRouter()
- r.Get("/page_views", handlePageViews(db))
+ r.Get("/sws.js", handleCounter(*addr))
+ r.Get("/sws.gif", handleHitCounter(db))
+ r.Get("/hits", handleHits(db))
r.Get("/domains", handleDomains(db))
+ r.Get("/test.html", handleTest())
r.Get("/", handleIndex())
- http.ListenAndServe(":5000", r)
+
+ log("listening at", *addr)
+ http.ListenAndServe(*addr, r)
}
-// Get envvar string with default
-func envString(v, d string) string {
- out := os.Getenv(v)
- if out == "" {
- out = d
+func migrateDatabase(db *sql.DB, driver string) (int64, error) {
+ var v int64
+ // Load migrations
+ ms, err := decodeMigrations(driver)
+ if err != nil {
+ return 0, err
+ }
+ debug("found", len(ms), "migrations for driver", driver)
+ migrator, err := migrate.NewStringMigrator(db, ms)
+ if err != nil {
+ return v, fmt.Errorf("failed to initialise: %w", err)
+ }
+
+ err = migrator.Migrate()
+ if err != nil {
+ return v, fmt.Errorf("failed to migrate: %w", err)
}
- return out
+
+ v, err = migrator.Version()
+ return v, nil
}