mirror of
https://github.com/lyx0/nourybot.git
synced 2024-11-13 19:49:55 +01:00
112 lines
2.1 KiB
Go
112 lines
2.1 KiB
Go
|
package main
|
||
|
|
||
|
import (
|
||
|
"context"
|
||
|
"database/sql"
|
||
|
"fmt"
|
||
|
"log"
|
||
|
"net/http"
|
||
|
"os"
|
||
|
"time"
|
||
|
|
||
|
"github.com/joho/godotenv"
|
||
|
_ "github.com/lib/pq"
|
||
|
"github.com/lyx0/nourybot/internal/data"
|
||
|
"go.uber.org/zap"
|
||
|
)
|
||
|
|
||
|
type config struct {
|
||
|
port int
|
||
|
db struct {
|
||
|
dsn string
|
||
|
maxOpenConns int
|
||
|
maxIdleConns int
|
||
|
maxIdleTime string
|
||
|
}
|
||
|
}
|
||
|
|
||
|
type application struct {
|
||
|
Logger *zap.SugaredLogger
|
||
|
Db *sql.DB
|
||
|
Models data.Models
|
||
|
}
|
||
|
|
||
|
func main() {
|
||
|
var cfg config
|
||
|
|
||
|
// Initialize a new sugared logger that we'll pass on
|
||
|
// down through the application.
|
||
|
sugar := zap.NewExample().Sugar()
|
||
|
defer sugar.Sync()
|
||
|
|
||
|
err := godotenv.Load()
|
||
|
if err != nil {
|
||
|
log.Fatal("Error loading .env file")
|
||
|
}
|
||
|
|
||
|
// Database
|
||
|
cfg.db.dsn = os.Getenv("DB_DSN")
|
||
|
cfg.port = 3000
|
||
|
cfg.db.maxOpenConns = 25
|
||
|
cfg.db.maxIdleConns = 25
|
||
|
cfg.db.maxIdleTime = "15m"
|
||
|
|
||
|
// Establish database connection
|
||
|
db, err := openDB(cfg)
|
||
|
if err != nil {
|
||
|
sugar.Fatal(err)
|
||
|
}
|
||
|
|
||
|
// Initialize Application
|
||
|
app := &application{
|
||
|
Logger: sugar,
|
||
|
Db: db,
|
||
|
Models: data.NewModels(db),
|
||
|
}
|
||
|
|
||
|
srv := &http.Server{
|
||
|
Addr: fmt.Sprintf(":%d", cfg.port),
|
||
|
Handler: app.routes(),
|
||
|
IdleTimeout: time.Minute,
|
||
|
ReadTimeout: 10 * time.Second,
|
||
|
WriteTimeout: 10 * time.Second,
|
||
|
}
|
||
|
|
||
|
err = srv.ListenAndServe()
|
||
|
sugar.Fatal(err)
|
||
|
|
||
|
}
|
||
|
|
||
|
// openDB returns the sql.DB connection pool.
|
||
|
func openDB(cfg config) (*sql.DB, error) {
|
||
|
// sql.Open() creates an empty connection pool with the provided DSN
|
||
|
db, err := sql.Open("postgres", cfg.db.dsn)
|
||
|
if err != nil {
|
||
|
return nil, err
|
||
|
}
|
||
|
|
||
|
// Set database restraints.
|
||
|
db.SetMaxOpenConns(cfg.db.maxOpenConns)
|
||
|
db.SetMaxIdleConns(cfg.db.maxIdleConns)
|
||
|
|
||
|
// Parse the maxIdleTime string into an actual duration and set it.
|
||
|
duration, err := time.ParseDuration(cfg.db.maxIdleTime)
|
||
|
if err != nil {
|
||
|
return nil, err
|
||
|
}
|
||
|
db.SetConnMaxIdleTime(duration)
|
||
|
|
||
|
// Create a new context with a 5 second timeout.
|
||
|
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
|
||
|
defer cancel()
|
||
|
|
||
|
// db.PingContext() is needed to actually check if the
|
||
|
// connection to the database was successful.
|
||
|
err = db.PingContext(ctx)
|
||
|
if err != nil {
|
||
|
return nil, err
|
||
|
}
|
||
|
|
||
|
return db, nil
|
||
|
}
|