package main import ( "database/sql" "flag" "log/slog" "net/http" "regexp" "os" "snippetbox.chaosfem.tw/internal/models" _ "github.com/go-sql-driver/mysql" ) // for application wide dependencies type application struct { logger *slog.Logger snippets *models.SnippetModel } // main it's the snippetbox webapp func main() { // configuration addr := flag.String("addr", ":4000", "HTTP network address") dsn := flag.String("dsn", "web:dbpass@/snippetbox?parseTime=true", "DB data source name") logfmt := flag.String("logfmt", "text", "Log output format") loglevel := flag.String("loglevel", "INFO", "Log level: DEBUG, INFO, WARN, or ERROR") flag.Parse() logger := loggerBuilder(logfmt, loglevel) db, err := openDB(*dsn, logger) if err != nil { logger.Error(err.Error()) os.Exit(1) } defer db.Close() // setup the application app := &application{ logger: logger, snippets: &models.SnippetModel{DB: db}, } logger.Info("starting server", slog.String("addr", *addr)) err = http.ListenAndServe(*addr, app.routes()) logger.Error(err.Error()) os.Exit(1) } func openDB(dsn string, logger *slog.Logger) (*sql.DB, error) { db, err := sql.Open("mysql", dsn) if err != nil { return nil, err } err = db.Ping() if err != nil { db.Close() return nil, err } passRegexp := regexp.MustCompile(":\\S+@") logger.Info("Opened DB connection pool", slog.String("adapter", "mysql"), slog.String("dsn", passRegexp.ReplaceAllString(dsn, ":@"))) return db, nil }