package main import ( "database/sql" "fmt" "log" "net/http" "os" _ "github.com/lib/pq" ) var db *sql.DB func getenv(key, fallback string) string { if v := os.Getenv(key); v != "" { return v } return fallback } func initDB() { dsn := fmt.Sprintf( "host=%s dbname=%s user=%s password=%s sslmode=disable", getenv("DB_HOST", "db"), getenv("DB_NAME", "visitcount"), getenv("DB_USER", "app"), getenv("DB_PASSWORD", "secret"), ) var err error db, err = sql.Open("postgres", dsn) if err != nil { log.Fatal(err) } if err = db.Ping(); err != nil { log.Fatal(err) } _, err = db.Exec( `CREATE TABLE IF NOT EXISTS visits (count INTEGER DEFAULT 0);` + `INSERT INTO visits SELECT 0 WHERE NOT EXISTS (SELECT 1 FROM visits);`, ) if err != nil { log.Fatal(err) } } func handleIndex(w http.ResponseWriter, r *http.Request) { var count int err := db.QueryRow("UPDATE visits SET count = count + 1 RETURNING count").Scan(&count) if err != nil { http.Error(w, "database error", http.StatusInternalServerError) return } fmt.Fprintf(w, "

VisitCounter

Visited %d times.

", count) } func handleHealth(w http.ResponseWriter, r *http.Request) { if err := db.Ping(); err != nil { http.Error(w, "db unreachable", http.StatusServiceUnavailable) return } fmt.Fprintln(w, "ok") } func main() { initDB() http.HandleFunc("/", handleIndex) http.HandleFunc("/health", handleHealth) log.Println("listening on :8080") log.Fatal(http.ListenAndServe(":8080", nil)) }