configuration baby
This commit is contained in:
parent
888244daaa
commit
8c0d983297
8 changed files with 315 additions and 33 deletions
|
@ -10,7 +10,7 @@ Why? Because I can. And because I wanted to learn how to write a web application
|
||||||
- [x] Web server is up and running
|
- [x] Web server is up and running
|
||||||
- [x] Basic API routes
|
- [x] Basic API routes
|
||||||
- [x] Database migrations (only for sqlite)
|
- [x] Database migrations (only for sqlite)
|
||||||
- [ ] Configurable database connection
|
- [x] Configurable database connection
|
||||||
- [ ] Automatic database migrations (will be probably only supported for Docker deployments or with a guide)
|
- [ ] Automatic database migrations (will be probably only supported for Docker deployments or with a guide)
|
||||||
- [ ] Tests
|
- [ ] Tests
|
||||||
- [ ] Frontend using templates
|
- [ ] Frontend using templates
|
||||||
|
|
|
@ -2,23 +2,50 @@ package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"database/sql"
|
"database/sql"
|
||||||
|
"flag"
|
||||||
"git.katuwoss.dev/JustScreaMy/secret-santa/internal/app"
|
"git.katuwoss.dev/JustScreaMy/secret-santa/internal/app"
|
||||||
"git.katuwoss.dev/JustScreaMy/secret-santa/internal/config"
|
"git.katuwoss.dev/JustScreaMy/secret-santa/internal/config"
|
||||||
|
_ "github.com/go-sql-driver/mysql"
|
||||||
|
_ "github.com/jackc/pgx/v5/stdlib"
|
||||||
_ "github.com/mattn/go-sqlite3"
|
_ "github.com/mattn/go-sqlite3"
|
||||||
"log"
|
"log"
|
||||||
|
"os"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
var (
|
||||||
dbConnection, err := sql.Open("sqlite3", "./test.db")
|
configPath string
|
||||||
if err != nil {
|
)
|
||||||
log.Fatal(err)
|
|
||||||
|
func init() {
|
||||||
|
flag.StringVar(&configPath, "config", "config.yaml", "path to config file")
|
||||||
|
flag.Parse()
|
||||||
|
|
||||||
|
// Check if the config file exists
|
||||||
|
if _, err := os.Stat(configPath); os.IsNotExist(err) {
|
||||||
|
log.Fatalf("Config file not found: %s", configPath)
|
||||||
}
|
}
|
||||||
|
log.Printf("Using config file: %s", configPath)
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
appConfig, err := config.ParseConfig(configPath)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("Failed to parse config: %s", err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
dbConnection, err := sql.Open(appConfig.DB.GetDriver(), appConfig.DB.GenerateDSN())
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("Database connection failed: %s", err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
if dbConnection.Ping() != nil {
|
||||||
|
log.Fatalf("Database connection failed: unable to ping database")
|
||||||
|
}
|
||||||
|
|
||||||
log.Println("Database sucessfully connected")
|
log.Println("Database sucessfully connected")
|
||||||
|
application := app.NewApp(dbConnection, &appConfig.App, nil)
|
||||||
|
|
||||||
appConfig := config.NewAppConfig(nil, nil)
|
log.Printf("Listening on http://%s", appConfig.App.GenerateIP())
|
||||||
application := app.NewApp(dbConnection, &appConfig, nil)
|
|
||||||
|
|
||||||
log.Printf("Listening on http://%s", appConfig.GenerateIP())
|
|
||||||
|
|
||||||
log.Fatal(application.Start())
|
log.Fatal(application.Start())
|
||||||
}
|
}
|
||||||
|
|
14
go.mod
14
go.mod
|
@ -3,6 +3,8 @@ module git.katuwoss.dev/JustScreaMy/secret-santa
|
||||||
go 1.23.2
|
go 1.23.2
|
||||||
|
|
||||||
require (
|
require (
|
||||||
|
github.com/go-sql-driver/mysql v1.6.0
|
||||||
|
github.com/jackc/pgx/v5 v5.5.4
|
||||||
github.com/mattn/go-sqlite3 v1.14.24
|
github.com/mattn/go-sqlite3 v1.14.24
|
||||||
github.com/rubenv/sql-migrate v1.7.0
|
github.com/rubenv/sql-migrate v1.7.0
|
||||||
github.com/stretchr/testify v1.9.0
|
github.com/stretchr/testify v1.9.0
|
||||||
|
@ -25,13 +27,21 @@ require (
|
||||||
github.com/docker/go-connections v0.5.0 // indirect
|
github.com/docker/go-connections v0.5.0 // indirect
|
||||||
github.com/docker/go-units v0.5.0 // indirect
|
github.com/docker/go-units v0.5.0 // indirect
|
||||||
github.com/felixge/httpsnoop v1.0.4 // indirect
|
github.com/felixge/httpsnoop v1.0.4 // indirect
|
||||||
|
github.com/gabriel-vasile/mimetype v1.4.3 // indirect
|
||||||
github.com/go-gorp/gorp/v3 v3.1.0 // indirect
|
github.com/go-gorp/gorp/v3 v3.1.0 // indirect
|
||||||
github.com/go-logr/logr v1.4.1 // indirect
|
github.com/go-logr/logr v1.4.1 // indirect
|
||||||
github.com/go-logr/stdr v1.2.2 // indirect
|
github.com/go-logr/stdr v1.2.2 // indirect
|
||||||
github.com/go-ole/go-ole v1.2.6 // indirect
|
github.com/go-ole/go-ole v1.2.6 // indirect
|
||||||
|
github.com/go-playground/locales v0.14.1 // indirect
|
||||||
|
github.com/go-playground/universal-translator v0.18.1 // indirect
|
||||||
|
github.com/go-playground/validator/v10 v10.23.0 // indirect
|
||||||
github.com/gogo/protobuf v1.3.2 // indirect
|
github.com/gogo/protobuf v1.3.2 // indirect
|
||||||
github.com/google/uuid v1.6.0 // indirect
|
github.com/google/uuid v1.6.0 // indirect
|
||||||
|
github.com/jackc/pgpassfile v1.0.0 // indirect
|
||||||
|
github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a // indirect
|
||||||
|
github.com/jackc/puddle/v2 v2.2.1 // indirect
|
||||||
github.com/klauspost/compress v1.17.4 // indirect
|
github.com/klauspost/compress v1.17.4 // indirect
|
||||||
|
github.com/leodido/go-urn v1.4.0 // indirect
|
||||||
github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 // indirect
|
github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 // indirect
|
||||||
github.com/magiconair/properties v1.8.7 // indirect
|
github.com/magiconair/properties v1.8.7 // indirect
|
||||||
github.com/moby/docker-image-spec v1.3.1 // indirect
|
github.com/moby/docker-image-spec v1.3.1 // indirect
|
||||||
|
@ -42,6 +52,7 @@ require (
|
||||||
github.com/morikuni/aec v1.0.0 // indirect
|
github.com/morikuni/aec v1.0.0 // indirect
|
||||||
github.com/opencontainers/go-digest v1.0.0 // indirect
|
github.com/opencontainers/go-digest v1.0.0 // indirect
|
||||||
github.com/opencontainers/image-spec v1.1.0 // indirect
|
github.com/opencontainers/image-spec v1.1.0 // indirect
|
||||||
|
github.com/pelletier/go-toml/v2 v2.2.3 // indirect
|
||||||
github.com/pkg/errors v0.9.1 // indirect
|
github.com/pkg/errors v0.9.1 // indirect
|
||||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||||
github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c // indirect
|
github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c // indirect
|
||||||
|
@ -56,6 +67,9 @@ require (
|
||||||
go.opentelemetry.io/otel/metric v1.24.0 // indirect
|
go.opentelemetry.io/otel/metric v1.24.0 // indirect
|
||||||
go.opentelemetry.io/otel/trace v1.24.0 // indirect
|
go.opentelemetry.io/otel/trace v1.24.0 // indirect
|
||||||
golang.org/x/crypto v0.24.0 // indirect
|
golang.org/x/crypto v0.24.0 // indirect
|
||||||
|
golang.org/x/net v0.26.0 // indirect
|
||||||
|
golang.org/x/sync v0.7.0 // indirect
|
||||||
golang.org/x/sys v0.21.0 // indirect
|
golang.org/x/sys v0.21.0 // indirect
|
||||||
|
golang.org/x/text v0.16.0 // indirect
|
||||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||||
)
|
)
|
||||||
|
|
14
go.sum
14
go.sum
|
@ -31,6 +31,8 @@ github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4
|
||||||
github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
|
github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
|
||||||
github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg=
|
github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg=
|
||||||
github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
|
github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
|
||||||
|
github.com/gabriel-vasile/mimetype v1.4.3 h1:in2uUcidCuFcDKtdcBxlR0rJ1+fsokWf+uqxgUFjbI0=
|
||||||
|
github.com/gabriel-vasile/mimetype v1.4.3/go.mod h1:d8uq/6HKRL6CGdk+aubisF/M5GcPfT7nKyLpA0lbSSk=
|
||||||
github.com/go-gorp/gorp/v3 v3.1.0 h1:ItKF/Vbuj31dmV4jxA1qblpSwkl9g1typ24xoe70IGs=
|
github.com/go-gorp/gorp/v3 v3.1.0 h1:ItKF/Vbuj31dmV4jxA1qblpSwkl9g1typ24xoe70IGs=
|
||||||
github.com/go-gorp/gorp/v3 v3.1.0/go.mod h1:dLEjIyyRNiXvNZ8PSmzpt1GsWAUK8kjVhEpjH8TixEw=
|
github.com/go-gorp/gorp/v3 v3.1.0/go.mod h1:dLEjIyyRNiXvNZ8PSmzpt1GsWAUK8kjVhEpjH8TixEw=
|
||||||
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
|
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
|
||||||
|
@ -40,6 +42,12 @@ github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
|
||||||
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
|
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
|
||||||
github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY=
|
github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY=
|
||||||
github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0=
|
github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0=
|
||||||
|
github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA=
|
||||||
|
github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY=
|
||||||
|
github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY=
|
||||||
|
github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY=
|
||||||
|
github.com/go-playground/validator/v10 v10.23.0 h1:/PwmTwZhS0dPkav3cdK9kV1FsAmrL8sThn8IHr/sO+o=
|
||||||
|
github.com/go-playground/validator/v10 v10.23.0/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM=
|
||||||
github.com/go-sql-driver/mysql v1.6.0 h1:BCTh4TKNUYmOmMUcQ3IipzF5prigylS7XXjEkfCHuOE=
|
github.com/go-sql-driver/mysql v1.6.0 h1:BCTh4TKNUYmOmMUcQ3IipzF5prigylS7XXjEkfCHuOE=
|
||||||
github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
|
github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
|
||||||
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
|
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
|
||||||
|
@ -68,6 +76,8 @@ github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
|
||||||
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
|
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
|
||||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||||
|
github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ=
|
||||||
|
github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI=
|
||||||
github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw=
|
github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw=
|
||||||
github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
|
github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
|
||||||
github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 h1:6E+4a0GO5zZEnZ81pIr0yLvtUWk2if982qA3F3QD6H4=
|
github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 h1:6E+4a0GO5zZEnZ81pIr0yLvtUWk2if982qA3F3QD6H4=
|
||||||
|
@ -92,6 +102,9 @@ github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8
|
||||||
github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=
|
github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=
|
||||||
github.com/opencontainers/image-spec v1.1.0 h1:8SG7/vwALn54lVB/0yZ/MMwhFrPYtpEHQb2IpWsCzug=
|
github.com/opencontainers/image-spec v1.1.0 h1:8SG7/vwALn54lVB/0yZ/MMwhFrPYtpEHQb2IpWsCzug=
|
||||||
github.com/opencontainers/image-spec v1.1.0/go.mod h1:W4s4sFTMaBeK1BQLXbG4AdM2szdn85PY75RI83NrTrM=
|
github.com/opencontainers/image-spec v1.1.0/go.mod h1:W4s4sFTMaBeK1BQLXbG4AdM2szdn85PY75RI83NrTrM=
|
||||||
|
github.com/pelletier/go-toml v1.9.5 h1:4yBQzkHv+7BHq2PQUZF3Mx0IYxG7LsP222s7Agd3ve8=
|
||||||
|
github.com/pelletier/go-toml/v2 v2.2.3 h1:YmeHyLY8mFWbdkNWwpr+qIL2bEqT0o95WSdkNHvL12M=
|
||||||
|
github.com/pelletier/go-toml/v2 v2.2.3/go.mod h1:MfCQTFTvCcUyyvvwm1+G6H/jORL20Xlb6rzQu9GuUkc=
|
||||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||||
|
@ -117,6 +130,7 @@ github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSS
|
||||||
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
|
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
|
||||||
github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY=
|
github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY=
|
||||||
github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA=
|
github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA=
|
||||||
|
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||||
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||||
|
|
29
internal/config/app_config.go
Normal file
29
internal/config/app_config.go
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
package config
|
||||||
|
|
||||||
|
import "fmt"
|
||||||
|
|
||||||
|
type AppConfig struct {
|
||||||
|
ListenIP string `json:"listen_ip" yaml:"listen_ip" toml:"listen_ip" validate:"required,ip"`
|
||||||
|
ListenPort int `json:"listen_port" yaml:"listen_port" toml:"listen_port" validate:"required"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *AppConfig) GenerateIP() string {
|
||||||
|
return fmt.Sprintf("%s:%d", c.ListenIP, c.ListenPort)
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewAppConfig(port *int, ip *string) AppConfig {
|
||||||
|
defaultPort := 8080
|
||||||
|
defaultIp := "127.0.0.1"
|
||||||
|
|
||||||
|
if port == nil {
|
||||||
|
port = &defaultPort
|
||||||
|
}
|
||||||
|
if ip == nil {
|
||||||
|
ip = &defaultIp
|
||||||
|
}
|
||||||
|
|
||||||
|
return AppConfig{
|
||||||
|
ListenIP: *ip,
|
||||||
|
ListenPort: *port,
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,29 +1,22 @@
|
||||||
package config
|
package config
|
||||||
|
|
||||||
import "fmt"
|
type Config struct {
|
||||||
|
App AppConfig `json:"app" yaml:"app" toml:"app" validate:"required"`
|
||||||
type AppConfig struct {
|
DB DatabaseConfig `json:"database" yaml:"database" toml:"database" validate:"required"`
|
||||||
ListenIP string `json:"listen_ip"`
|
|
||||||
ListenPort int `json:"listen_port"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *AppConfig) GenerateIP() string {
|
// NewConfig will create a new Config struct with the given AppConfig and DatabaseConfig.
|
||||||
return fmt.Sprintf("%s:%d", c.ListenIP, c.ListenPort)
|
func NewConfig(app AppConfig, db DatabaseConfig) Config {
|
||||||
}
|
return Config{
|
||||||
|
App: app,
|
||||||
func NewAppConfig(port *int, ip *string) AppConfig {
|
DB: db,
|
||||||
defaultPort := 8080
|
}
|
||||||
defaultIp := "127.0.0.1"
|
}
|
||||||
|
|
||||||
if port == nil {
|
// NewDefaultConfig will create a new Config struct with default values.
|
||||||
port = &defaultPort
|
func NewDefaultConfig() Config {
|
||||||
}
|
return Config{
|
||||||
if ip == nil {
|
App: NewAppConfig(nil, nil),
|
||||||
ip = &defaultIp
|
DB: NewDatabaseConfig(nil, nil, nil, nil, nil, nil),
|
||||||
}
|
|
||||||
|
|
||||||
return AppConfig{
|
|
||||||
ListenIP: *ip,
|
|
||||||
ListenPort: *port,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
99
internal/config/db_config.go
Normal file
99
internal/config/db_config.go
Normal file
|
@ -0,0 +1,99 @@
|
||||||
|
package config
|
||||||
|
|
||||||
|
import "fmt"
|
||||||
|
|
||||||
|
type DriverType string
|
||||||
|
|
||||||
|
const (
|
||||||
|
MySQL DriverType = "mysql"
|
||||||
|
Postgres DriverType = "postgres"
|
||||||
|
SQLite DriverType = "sqlite"
|
||||||
|
)
|
||||||
|
|
||||||
|
// DatabaseConfig will hold the database configuration.
|
||||||
|
//
|
||||||
|
// If the driver is SQLite, the Host field should be the path to the database file.
|
||||||
|
// Other configurations options will be ignored.
|
||||||
|
type DatabaseConfig struct {
|
||||||
|
Driver DriverType `json:"driver" yaml:"driver" toml:"driver" validate:"required"`
|
||||||
|
Host string `json:"host" yaml:"host" toml:"host" validate:"required"`
|
||||||
|
Port int `json:"port" yaml:"port" toml:"port"`
|
||||||
|
User string `json:"user" yaml:"user" toml:"user"`
|
||||||
|
Pass string `json:"pass" yaml:"pass" toml:"pass"`
|
||||||
|
DBName string `json:"db_name" yaml:"db_name" toml:"db_name"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewDatabaseConfig(driver *DriverType, host, user, pass, dbName *string, port *int) DatabaseConfig {
|
||||||
|
defaultDriver := SQLite
|
||||||
|
defaultHost := "./database.db"
|
||||||
|
defaultPort := 0
|
||||||
|
defaultUser := ""
|
||||||
|
defaultPass := ""
|
||||||
|
defaultDBName := ""
|
||||||
|
|
||||||
|
if driver == nil {
|
||||||
|
driver = &defaultDriver
|
||||||
|
}
|
||||||
|
if host == nil {
|
||||||
|
host = &defaultHost
|
||||||
|
}
|
||||||
|
if port == nil {
|
||||||
|
port = &defaultPort
|
||||||
|
}
|
||||||
|
if user == nil {
|
||||||
|
user = &defaultUser
|
||||||
|
}
|
||||||
|
if pass == nil {
|
||||||
|
pass = &defaultPass
|
||||||
|
}
|
||||||
|
if dbName == nil {
|
||||||
|
dbName = &defaultDBName
|
||||||
|
}
|
||||||
|
|
||||||
|
return DatabaseConfig{
|
||||||
|
Driver: *driver,
|
||||||
|
Host: *host,
|
||||||
|
Port: *port,
|
||||||
|
User: *user,
|
||||||
|
Pass: *pass,
|
||||||
|
DBName: *dbName,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// GenerateDSN generates the Data Source Name (DSN) for the database connection.
|
||||||
|
func (c *DatabaseConfig) GenerateDSN() string {
|
||||||
|
switch c.Driver {
|
||||||
|
case MySQL:
|
||||||
|
return c.generateMySQLDSN()
|
||||||
|
case Postgres:
|
||||||
|
return c.generatePostgresDSN()
|
||||||
|
case SQLite:
|
||||||
|
return c.generateSQLiteDSN()
|
||||||
|
default:
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *DatabaseConfig) GetDriver() string {
|
||||||
|
switch c.Driver {
|
||||||
|
case MySQL:
|
||||||
|
return "mysql"
|
||||||
|
case Postgres:
|
||||||
|
return "pgx"
|
||||||
|
case SQLite:
|
||||||
|
return "sqlite3"
|
||||||
|
default:
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
return string(c.Driver)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *DatabaseConfig) generateSQLiteDSN() string {
|
||||||
|
return c.Host
|
||||||
|
}
|
||||||
|
func (c *DatabaseConfig) generateMySQLDSN() string {
|
||||||
|
return fmt.Sprintf("%s:%s@tcp(%s:%d)/%s", c.User, c.Pass, c.Host, c.Port, c.DBName)
|
||||||
|
}
|
||||||
|
func (c *DatabaseConfig) generatePostgresDSN() string {
|
||||||
|
return fmt.Sprintf("postgres://%s:%s@%s:%d/%s", c.User, c.Pass, c.Host, c.Port, c.DBName)
|
||||||
|
}
|
106
internal/config/parse.go
Normal file
106
internal/config/parse.go
Normal file
|
@ -0,0 +1,106 @@
|
||||||
|
package config
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"github.com/go-playground/validator/v10"
|
||||||
|
"io"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
|
||||||
|
"github.com/pelletier/go-toml/v2"
|
||||||
|
"gopkg.in/yaml.v3"
|
||||||
|
)
|
||||||
|
|
||||||
|
type FileType string
|
||||||
|
|
||||||
|
const (
|
||||||
|
YAML FileType = "yaml"
|
||||||
|
TOML FileType = "toml"
|
||||||
|
JSON FileType = "json"
|
||||||
|
)
|
||||||
|
|
||||||
|
// getFileType returns the file type based on the file extension.
|
||||||
|
func getFileType(path string) (FileType, error) {
|
||||||
|
// Get the file extension
|
||||||
|
ext := filepath.Ext(path)
|
||||||
|
|
||||||
|
switch ext {
|
||||||
|
case ".yaml", ".yml":
|
||||||
|
return YAML, nil
|
||||||
|
case ".toml":
|
||||||
|
return TOML, nil
|
||||||
|
case ".json":
|
||||||
|
return JSON, nil
|
||||||
|
default:
|
||||||
|
return "", fmt.Errorf("unsupported file type: %s", ext)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func ParseConfig(path string) (Config, error) {
|
||||||
|
fileType, err := getFileType(path)
|
||||||
|
if err != nil {
|
||||||
|
return Config{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
file, err := os.Open(path)
|
||||||
|
if err != nil {
|
||||||
|
return Config{}, err
|
||||||
|
}
|
||||||
|
defer file.Close()
|
||||||
|
|
||||||
|
data, err := io.ReadAll(file)
|
||||||
|
|
||||||
|
var config Config
|
||||||
|
|
||||||
|
switch fileType {
|
||||||
|
case YAML:
|
||||||
|
config, err = parseYAML(data)
|
||||||
|
case TOML:
|
||||||
|
config, err = parseTOML(data)
|
||||||
|
case JSON:
|
||||||
|
config, err = parseJSON(data)
|
||||||
|
default:
|
||||||
|
return Config{}, fmt.Errorf("unsupported file type: %s", fileType)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return Config{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
validate := validator.New(validator.WithRequiredStructEnabled())
|
||||||
|
err = validate.Struct(config)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return Config{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return config, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func parseTOML(data []byte) (Config, error) {
|
||||||
|
var appConfig Config
|
||||||
|
err := toml.Unmarshal(data, &appConfig)
|
||||||
|
if err != nil {
|
||||||
|
return Config{}, err
|
||||||
|
}
|
||||||
|
return appConfig, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func parseYAML(data []byte) (Config, error) {
|
||||||
|
var appConfig Config
|
||||||
|
err := yaml.Unmarshal(data, &appConfig)
|
||||||
|
if err != nil {
|
||||||
|
return Config{}, err
|
||||||
|
}
|
||||||
|
return appConfig, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func parseJSON(data []byte) (Config, error) {
|
||||||
|
var appConfig Config
|
||||||
|
err := json.Unmarshal(data, &appConfig)
|
||||||
|
if err != nil {
|
||||||
|
return Config{}, err
|
||||||
|
}
|
||||||
|
return appConfig, nil
|
||||||
|
}
|
Loading…
Reference in a new issue