package main import ( "encoding/gob" "flag" "fmt" "go-udemy-web-1/internal/config" "go-udemy-web-1/internal/handlers" "go-udemy-web-1/internal/helpers" "go-udemy-web-1/internal/models" "go-udemy-web-1/internal/render" "go-udemy-web-1/internal/repository" "go-udemy-web-1/internal/repository/driverrepo" "log" "net/http" "os" "time" "github.com/alexedwards/scs/redisstore" "github.com/alexedwards/scs/v2" "github.com/gomodule/redigo/redis" ) const portNumber = ":8080" var ( app config.AppConfig session *scs.SessionManager infoLog *log.Logger errorLog *log.Logger ) // main is the main application function func main() { db, err := run() if err != nil { log.Fatal(err) } defer db.SQL.Close() defer close(app.MailChan) fmt.Println("Starting mail listener...") fmt.Printf("Starting application on port %s\n", portNumber) srv := &http.Server{ Addr: portNumber, Handler: routes(&app), } err = srv.ListenAndServe() log.Fatal(err) } func run() (*repository.DB, error) { // what am I going to put in the session gob.Register(models.Reservation{}) gob.Register(models.User{}) gob.Register(models.Room{}) gob.Register(models.Restriction{}) gob.Register(map[string]int{}) // read flags inProduction := flag.Bool("production", true, "Application is in production") useCache := flag.Bool("cache", true, "Use template cache") dbHost := flag.String("dbhost", "localhost", "Database host") dbName := flag.String("dbname", "bookings", "Database name") dbUser := flag.String("dbuser", os.Getenv("PGUSER"), "Database user") dbPass := flag.String("dbpass", os.Getenv("PGPWD"), "Database password") dbPort := flag.String("dbport", "5432", "Database port") dbSSL := flag.String("dbssl", "disable", "Database ssl settings (disable, prefer, require)") flag.Parse() if *dbUser == "" { fmt.Println("Missing required flags") os.Exit(1) } mailChan := make(chan models.MailData) app.MailChan = mailChan listenForMail() // change this to true when in production app.InProduction = *inProduction // Establish connection pool to Redis. pool := &redis.Pool{ MaxIdle: 10, Dial: func() (redis.Conn, error) { return redis.Dial("tcp", "localhost:6379") }, } session = scs.New() session.Store = redisstore.New(pool) session.Lifetime = 24 * time.Hour session.Cookie.Persist = true session.Cookie.SameSite = http.SameSiteLaxMode session.Cookie.Secure = app.InProduction app.Session = session // connect to database log.Println("Connecting to database...") dsn := fmt.Sprintf("host=%s port=%s dbname=%s user=%s password=%s sslmode=%s", *dbHost, *dbPort, *dbName, *dbUser, *dbPass, *dbSSL) dbdriver := driverrepo.NewSqlcRepo() db, err := dbdriver.ConnectSQL(dsn) if err != nil { log.Fatal("Cannot connect to database! Dying...") } log.Println("Connected to database") tc, err := render.CreateTemplateCache() if err != nil { log.Fatalf("cannot create template cache: %s", err) return nil, err } app.TemplateCahce = tc app.UseCache = *useCache infoLog = log.New(os.Stdout, "INFO\t", log.Ldate|log.Ltime) app.InfoLog = infoLog errorLog = log.New(os.Stdout, "ERROR\t", log.Ldate|log.Ltime|log.Lshortfile) app.ErrorLog = errorLog repo := handlers.NewRepo(&app, db) handlers.NewHandlers(repo) helpers.NewHelpers(&app) render.NewRenderer(&app) return db, nil }