diff --git a/.gitignore b/.gitignore index 23b4539..516a1a0 100644 --- a/.gitignore +++ b/.gitignore @@ -25,3 +25,5 @@ nourybot-api Nourybot-Web nourybot-web docker-compose.yml + +db/ diff --git a/cmd/nourybot/main.go b/cmd/nourybot/main.go index 9da3ef1..b42b667 100644 --- a/cmd/nourybot/main.go +++ b/cmd/nourybot/main.go @@ -10,6 +10,9 @@ import ( "time" "github.com/gempir/go-twitch-irc/v4" + "github.com/golang-migrate/migrate/v4" + _ "github.com/golang-migrate/migrate/v4/database/postgres" + _ "github.com/golang-migrate/migrate/v4/source/file" "github.com/jakecoffman/cron" "github.com/joho/godotenv" _ "github.com/lib/pq" @@ -27,6 +30,7 @@ type config struct { twitchClientSecret string eventSubSecret string twitchID string + migrate string wolframAlphaAppID string commandPrefix string env string @@ -60,7 +64,7 @@ func main() { } } -func run(ctx context.Context, w io.Writer, args []string) error { +func run(_ context.Context, _ io.Writer, _ []string) error { var cfg config logger := zap.NewExample() @@ -85,6 +89,7 @@ func run(ctx context.Context, w io.Writer, args []string) error { cfg.twitchOauth = os.Getenv("TWITCH_OAUTH") cfg.twitchClientId = os.Getenv("TWITCH_CLIENT_ID") cfg.twitchClientSecret = os.Getenv("TWITCH_CLIENT_SECRET") + cfg.migrate = os.Getenv("MIGRATE") cfg.eventSubSecret = os.Getenv("EVENTSUB_SECRET") cfg.wolframAlphaAppID = os.Getenv("WOLFRAMALPHA_APP_ID") cfg.twitchID = os.Getenv("TWITCH_ID") @@ -93,10 +98,10 @@ func run(ctx context.Context, w io.Writer, args []string) error { switch cfg.env { case "dev": - cfg.db.dsn = os.Getenv("DEV_DSN") + cfg.db.dsn = os.Getenv("DSN") cfg.commandPrefix = "!!" case "prod": - cfg.db.dsn = os.Getenv("PROD_DSN") + cfg.db.dsn = os.Getenv("DSN") cfg.commandPrefix = "()" } // Database config variables @@ -104,6 +109,16 @@ func run(ctx context.Context, w io.Writer, args []string) error { cfg.db.maxIdleConns = 25 cfg.db.maxIdleTime = "15m" + if cfg.migrate != "no" { + sugar.Infow("Running database migration", + "direction", cfg.migrate) + if cfg.migrate == "up" { + migrateDB("up", cfg.db.dsn, sugar) + } else if cfg.migrate == "down" { + migrateDB("down", cfg.db.dsn, sugar) + } + } + // Initialize a new Helix Client, request a new AppAccessToken // and set the token on the client. helixClient, err := helix.NewClient(&helix.Options{ @@ -214,7 +229,6 @@ func run(ctx context.Context, w io.Writer, args []string) error { "Database", db.Stats(), "Helix", helixResp, ) - }) // Start status page @@ -262,3 +276,31 @@ func openDB(cfg config) (*sql.DB, error) { return db, nil } + +func migrateDB(direction string, dsn string, logger *zap.SugaredLogger) { + defer os.Exit(69) + m, err := migrate.New( + "file://migrations/prod", + dsn) + if err != nil { + logger.Fatal(err) + } + + switch direction { + case "up": + if err := m.Up(); err != nil { + logger.Fatalw("Error migrating database", + "err", err) + } + logger.Infow("Database migration successful", + "direction", direction) + case "down": + if err := m.Down(); err != nil { + logger.Fatalw("Error migrating database", + "err", err) + } + logger.Infow("Database migration successful", + "direction", direction) + default: + } +} diff --git a/cmd/nourybot/router.go b/cmd/nourybot/router.go index 784e536..aca1ab8 100644 --- a/cmd/nourybot/router.go +++ b/cmd/nourybot/router.go @@ -12,9 +12,9 @@ import ( "sort" "github.com/julienschmidt/httprouter" + "github.com/nicklaw5/helix/v2" "github.com/nouryxd/nourybot/internal/data" "github.com/nouryxd/nourybot/pkg/common" - "github.com/nicklaw5/helix/v2" ) func (app *application) startRouter() { diff --git a/go.mod b/go.mod index 1ac8336..5245bd1 100644 --- a/go.mod +++ b/go.mod @@ -4,7 +4,7 @@ go 1.20 require ( github.com/gempir/go-twitch-irc/v4 v4.0.0 - github.com/google/uuid v1.3.1 + github.com/google/uuid v1.4.0 github.com/jakecoffman/cron v0.0.0-20190106200828-7e2009c226a5 github.com/lib/pq v1.10.9 github.com/nicklaw5/helix/v2 v2.25.1 @@ -15,8 +15,11 @@ require ( ) require ( - github.com/aws/aws-sdk-go v1.38.20 // indirect - github.com/golang-jwt/jwt/v4 v4.0.0 // indirect + github.com/aws/aws-sdk-go v1.49.6 // indirect + github.com/golang-jwt/jwt/v4 v4.4.2 // indirect + github.com/golang-migrate/migrate/v4 v4.17.1 // indirect + github.com/hashicorp/errwrap v1.1.0 // indirect + github.com/hashicorp/go-multierror v1.1.1 // indirect github.com/jmespath/go-jmespath v0.4.0 // indirect github.com/u2takey/go-utils v0.3.1 // indirect go.uber.org/atomic v1.7.0 // indirect diff --git a/go.sum b/go.sum index 635966c..c83ff38 100644 --- a/go.sum +++ b/go.sum @@ -1,5 +1,7 @@ github.com/aws/aws-sdk-go v1.38.20 h1:QbzNx/tdfATbdKfubBpkt84OM6oBkxQZRw6+bW2GyeA= github.com/aws/aws-sdk-go v1.38.20/go.mod h1:hcU610XS61/+aQV88ixoOzUoG7v3b31pl2zKMmprdro= +github.com/aws/aws-sdk-go v1.49.6 h1:yNldzF5kzLBRvKlKz1S0bkvc2+04R1kt13KfBWQBfFA= +github.com/aws/aws-sdk-go v1.49.6/go.mod h1:LF8svs817+Nz+DmiMQKTO3ubZ/6IaTpq3TjupRn3Eqk= github.com/benbjohnson/clock v1.1.0 h1:Q92kusRqC1XV2MjkWETPvjJVqKetz1OzxZB7mHJLju8= github.com/briandowns/openweathermap v0.19.0 h1:nkopLMEtZLxbZI1th6dOG6xkajpszofqf53r5K8mT9k= github.com/briandowns/openweathermap v0.19.0/go.mod h1:0GLnknqicWxXnGi1IqoOaZIw+kIe5hkt+YM5WY3j8+0= @@ -18,10 +20,21 @@ github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7 github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= github.com/golang-jwt/jwt/v4 v4.0.0 h1:RAqyYixv1p7uEnocuy8P1nru5wprCh/MH2BIlW5z5/o= github.com/golang-jwt/jwt/v4 v4.0.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg= +github.com/golang-jwt/jwt/v4 v4.4.2 h1:rcc4lwaZgFMCZ5jxF9ABolDcIHdBytAFgqFPbSJQAYs= +github.com/golang-jwt/jwt/v4 v4.4.2/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= +github.com/golang-migrate/migrate/v4 v4.17.1 h1:4zQ6iqL6t6AiItphxJctQb3cFqWiSpMnX7wLTPnnYO4= +github.com/golang-migrate/migrate/v4 v4.17.1/go.mod h1:m8hinFyWBn0SA4QKHuKh175Pm9wjmxj3S2Mia7dbXzM= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.3.1 h1:KjJaJ9iWZ3jOFZIf1Lqf4laDRCasjl0BCmnEGxkdLb4= github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.4.0 h1:MtMxsa51/r9yyhkyLsVeVt0B+BGQZzpQiTQ4eHZ8bc4= +github.com/google/uuid v1.4.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= +github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I= +github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= +github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo= +github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= github.com/jakecoffman/cron v0.0.0-20190106200828-7e2009c226a5 h1:kCvm3G3u+eTRbjfLPyfsfznJtraYEfZer/UvQ6CaQhI= github.com/jakecoffman/cron v0.0.0-20190106200828-7e2009c226a5/go.mod h1:6DM2KNNK69jRu0lAHmYK9LYxmqpNjYHOaNp/ZxttD4U=