add db connection, refactor code, add db migration files

This commit is contained in:
lbenedar
2026-04-03 18:59:15 +03:00
parent d5577f10d7
commit a16edb9b61
28 changed files with 587 additions and 345 deletions

View File

@@ -1,15 +1,13 @@
package main
import (
"fmt"
"net/http"
"gitea.local.lab/Lbenedar/foundry_helper_service/internal/foundry/models"
)
func (app *application) ShowText(w http.ResponseWriter, r *http.Request) {
msg := app.foundryApp.CreateWSMessageByPage("/join")
data, err := app.foundryApp.HandleWebsocketRequest(msg)
data, err := app.foundryApp.HandleWSRequest("/join")
if err != nil {
app.slogger.Error("", "error", err)
w.Write([]byte(err.Error()))
@@ -29,8 +27,7 @@ func (app *application) ShowText(w http.ResponseWriter, r *http.Request) {
}
func (app *application) WhenNextSession(w http.ResponseWriter, r *http.Request) {
msg := app.foundryApp.CreateWSMessageByPage("/setup")
data, err := app.foundryApp.HandleWebsocketRequest(msg)
data, err := app.foundryApp.HandleWSRequest("/setup")
if err != nil {
app.slogger.Error("", "error", err)
w.Write([]byte(err.Error()))
@@ -50,7 +47,7 @@ func (app *application) WhenNextSession(w http.ResponseWriter, r *http.Request)
w.Write([]byte(err.Error()))
return
}
fmt.Printf("JSON msg: %s\n", nextSession)
app.slogger.Info("Next session data is ready to send", "sessionTime", nextSession)
w.Write([]byte(nextSession.Local().String()))
}

10
cmd/api/logger.go Normal file
View File

@@ -0,0 +1,10 @@
package main
import "log/slog"
var StringToLogLevel = map[string]slog.Leveler{
"debug": slog.LevelDebug,
"info": slog.LevelInfo,
"warn": slog.LevelWarn,
"error": slog.LevelError,
}

View File

@@ -1,8 +1,9 @@
package main
import (
"context"
"database/sql"
"flag"
"fmt"
"log"
"log/slog"
"net/http"
@@ -10,6 +11,9 @@ import (
"time"
"gitea.local.lab/Lbenedar/foundry_helper_service/internal/foundry"
"gitea.local.lab/Lbenedar/foundry_helper_service/internal/foundry/requests"
_ "github.com/mattn/go-sqlite3"
)
type service_mode string
@@ -21,10 +25,15 @@ const (
)
type config struct {
mode service_mode
port string
foundryHost string
foundryPass string
mode service_mode
port string
db struct {
dsn string
maxOpenConns int
maxIdleConns int
maxIdleTime string
}
}
type application struct {
@@ -34,84 +43,120 @@ type application struct {
logger *log.Logger
}
func openDB(cfg config) (*sql.DB, error) {
db, err := sql.Open("sqlite3", cfg.db.dsn)
if err != nil {
return nil, err
}
db.SetMaxIdleConns(cfg.db.maxIdleConns)
db.SetMaxOpenConns(cfg.db.maxOpenConns)
duration, err := time.ParseDuration(cfg.db.maxIdleTime)
if err != nil {
return nil, err
}
db.SetConnMaxIdleTime(duration)
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
err = db.PingContext(ctx)
if err != nil {
return nil, err
}
return db, nil
}
// TODO: change default values
func (app *application) parseFlags() {
var mode string
flag.StringVar(&mode, "service_mode", "api", "Type of service mode(api|discord|tg)")
flag.StringVar(&app.cfg.port, "port", ":9090", "Service port")
flag.StringVar(&app.cfg.foundryHost, "foundry_host", "127.0.0.1", "Address to connect to Foundry")
flag.StringVar(&app.cfg.foundryPass, "foundry_pass", "", "Password to connect to Foundry")
flag.StringVar(&app.cfg.db.dsn, "db-dsn", "file:db/default.db?cache=shared", "PostgreSQL DSN")
flag.IntVar(&app.cfg.db.maxOpenConns, "db-max-open-conns", 25, "PostgreSQL max open connections")
flag.IntVar(&app.cfg.db.maxIdleConns, "db-max-idle-conns", 25, "PostgreSQL max idle connections")
flag.StringVar(&app.cfg.db.maxIdleTime, "db-max-idle-time", "15m", "PostgreSQL max connection idle time")
var mode string
flag.StringVar(&mode, "service_mode", "api", "Type of service mode(api|discord|tg)")
foundryConfig := requests.Config{SessionID: ""}
flag.StringVar(&foundryConfig.Host, "foundry_host", "127.0.0.1", "Address to connect to Foundry")
flag.StringVar(&foundryConfig.Password, "foundry_pass", "", "Password to connect to Foundry")
var logLevelStr string
flag.StringVar(&logLevelStr, "log_level", "info", "Password to connect to Foundry(debug|info|warn|error)")
flag.Parse()
app.cfg.mode = service_mode(mode)
app.foundryApp.SetConfig(&foundryConfig)
logLevel, ok := StringToLogLevel[logLevelStr]
if !ok {
logLevel = slog.LevelInfo
}
app.slogger = slog.New(slog.NewJSONHandler(os.Stdout, &slog.HandlerOptions{Level: logLevel}))
if !ok {
app.slogger.Warn("Wrong log level. Started with log_level=info", "received", logLevelStr)
}
}
func (app *application) ConnectToFoundry(foundryHost, foundryPass string) error {
// TODO: Handle application exit if wrong data
func (app *application) StartListenFoundry() {
var err error
if app.foundryApp == nil {
app.foundryApp, err = foundry.NewFoundry(foundryHost)
if err != nil {
return err
}
}
fmt.Printf("Foundry1: %v\n", app.foundryApp)
ok, err := app.foundryApp.CheckSessionToken(foundryHost)
if err != nil {
return err
}
fmt.Printf("Foundry2: %v\n", app.foundryApp)
if foundryPass != "" && !ok {
err := app.foundryApp.Authenticate(foundryPass)
if err != nil {
return err
}
}
fmt.Printf("Foundry3: %v\n", app.foundryApp)
return nil
}
func (app *application) StartListenFoundry() {
for {
err := app.ConnectToFoundry(app.cfg.foundryHost, app.cfg.foundryPass)
if !app.foundryApp.HasSessionId() {
err = app.foundryApp.SetUpSessionId()
if err != nil {
app.slogger.Error("Error raised", "err", err.Error())
return
}
}
err = app.foundryApp.ConnectToFoundry()
if err != nil {
app.logger.Println(err)
app.slogger.Error("Error raised", "err", err.Error())
return
}
err = foundry.ConnectToWebSocket(app.foundryApp)
err = app.foundryApp.ConnectToWebSocket()
if err != nil {
app.logger.Println(err)
app.slogger.Error("Error raised", "err", err.Error())
return
}
err = app.foundryApp.StartListen()
if err != nil && err != foundry.ListenIsDone {
app.logger.Println(err)
app.slogger.Error("Error raised", "err", err.Error())
return
}
}
}
func main() {
app := application{foundryApp: nil}
app := application{foundryApp: foundry.NewFoundry()}
app.parseFlags()
app.slogger = slog.New(slog.NewJSONHandler(os.Stdout, &slog.HandlerOptions{Level: slog.LevelInfo}))
app.logger = slog.NewLogLogger(app.slogger.Handler(), slog.LevelInfo)
app.foundryApp.SetLogger(app.slogger)
db, err := openDB(app.cfg)
if err != nil {
app.slogger.Error("Error when opening database connection", "err", err)
return
}
defer db.Close()
app.slogger.Info("Database connection pool established")
go app.StartListenFoundry()
errLog := slog.NewLogLogger(app.slogger.Handler(), slog.LevelError)
server := &http.Server{
Addr: app.cfg.port,
Handler: app.routes(),
ErrorLog: app.logger,
ErrorLog: errLog,
// TLSConfig: tlsConfig,
IdleTimeout: time.Minute,
ReadTimeout: 5 * time.Second,