add Database type to cli and server config
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 12s
Gitea Actions Demo / build-and-test (push) Failing after 19m54s

This commit is contained in:
Thomas Peetz
2026-10-29 00:14:54 +01:00
parent ab166fc075
commit 2aeba70906
12 changed files with 143 additions and 134772 deletions
+1
View File
@@ -1,2 +1,3 @@
# Added by goreleaser init:
dist/
data/
+3 -12
View File
@@ -2,7 +2,6 @@ package main
import (
"context"
"fmt"
"kontor-api-gin/internal/config"
"kontor-api-gin/internal/handlers"
"kontor-api-gin/internal/router"
@@ -26,16 +25,8 @@ func main() {
log.Fatalf("Failed to initialize config: %v", err)
}
dsn := fmt.Sprintf(
"host=%s user=%s password=%s dbname=%s port=%d sslmode=disable",
viper.GetString("db.host"),
viper.GetString("db.user"),
viper.GetString("db.password"),
viper.GetString("db.name"),
viper.GetInt("db.port"),
)
db, err := config.NewDB(dsn)
db, err := config.NewDB()
if err != nil {
log.Fatal(err)
}
@@ -45,7 +36,7 @@ func main() {
// Set Gin mode based on environment
// Production mode disables debug output
if viper.GetString("gin.mode") == "release" {
if config.ServerConfig.Gin.Mode == "release" {
gin.SetMode(gin.ReleaseMode)
}
@@ -58,7 +49,7 @@ func main() {
)
srv := &http.Server{
Addr: ":" + strconv.Itoa(viper.GetInt("port")),
Addr: ":" + strconv.Itoa(config.ServerConfig.Server.Port),
Handler: r,
ReadHeaderTimeout: 5 * time.Second,
WriteTimeout: 30 * time.Second,
+2 -2
View File
@@ -50,7 +50,7 @@ type ExportData struct {
MediaFile []models.MediaFileDTO `json:"media_file"`
MediaActor []models.MediaActorDTO `json:"media_actor"`
MediaActorFile []models.MediaActorFileDTO `json:"media_actor_file"`
Profile []models.ProfileDTO `json:"profile"`
Profile models.ProfileDTOList `json:"profile"`
Permission []models.PermissionDTO `json:"permission"`
Assignment []models.AssignmentDTO `json:"assignment"`
Token []models.TokenDTO `json:"token"`
@@ -103,7 +103,7 @@ var (
Mediafiles []models.MediaFileDTO
Medialofis models.MediaLoFiDTOList
MediaMusics models.MediaMusicDTOList
Profiles []models.ProfileDTO
Profiles models.ProfileDTOList
Permissions []models.PermissionDTO
Assignments []models.AssignmentDTO
Tokens []models.TokenDTO
+3
View File
@@ -21,6 +21,9 @@ var importCmd = &cobra.Command{
if err != nil {
slog.Info("Error importing data", "Error", err.Error())
}
slog.Info("importing Profiles", "count", len(data.Profile))
slog.Info("importing Permissions", "count", len(data.Permission))
slog.Info("importing Assignments", "count", len(data.Assignment))
slog.Info("importing MediaFiles", "count", len(data.MediaFile))
slog.Info("importing MediaLofis", "count", len(data.MediaLoFi))
slog.Info("importing MediaLofi", "media_lofi", data.MediaLoFi[0])
+45 -17
View File
@@ -11,14 +11,15 @@ import (
)
var (
CfgFile string
Verbose int
Overwrite bool
ServerName string
Mediatype MediaType
Config CliConfig
DryRun bool
FileName string
CfgFile string
Verbose int
Overwrite bool
ServerName string
Mediatype MediaType
Config CliConfig
ServerConfig ServerConfiguration
DryRun bool
FileName string
)
const (
@@ -61,9 +62,31 @@ type Server struct {
Password string `mapstructure:"password"`
}
type Database struct {
Type string `mapstructure:"type" validate:"required"`
Path string `mapstructure:"path" validate:"required"`
Host string `mapstructure:"host" validate:"required"`
Name string `mapstructure:"name" validate:"required"`
Port int `mapstructure:"port" validate:"required"`
Password string `mapstructure:"password" validate:"required"`
User string `mapstructure:"user" validate:"required"`
}
type CliConfig struct {
ApiVersion string
Server map[string]Server `mapstructure:"server"`
DB Database `mapstructure:"db"`
}
type ServerConfiguration struct {
Server struct {
Port int `mapstructure:"port" validate:"required"`
Host string `mapstructure:"host"`
} `mapstructure:"server"`
DB Database `mapstructure:"db"`
Gin struct {
Mode string `mapstructure:"mode" validate:"required"`
} `mapstructure:"gin"`
}
func InitCliConfig() {
@@ -90,7 +113,7 @@ func InitCliConfig() {
slog.Info("error reading config file", "error", err.Error())
}
} else {
slog.Info("initConfig", "Using config file: ", viper.ConfigFileUsed())
slog.Info("InitCliConfig", "Using config file: ", viper.ConfigFileUsed())
if err := viper.Unmarshal(&Config); err != nil {
slog.Info("parsing of config file failed", "error", err.Error())
}
@@ -98,13 +121,6 @@ func InitCliConfig() {
}
func InitConfig() error {
viper.SetDefault("db.host", "localhost")
viper.SetDefault("db.port", 5432)
viper.SetDefault("db.name", "kontor")
viper.SetDefault("db.user", "kontor")
viper.SetDefault("db.password", "kontor")
viper.SetDefault("port", 8550)
viper.SetDefault("gin.mode", "release")
viper.SetConfigName("kontor-gin")
viper.SetConfigType("yaml")
@@ -114,6 +130,15 @@ func InitConfig() error {
viper.SetEnvKeyReplacer(strings.NewReplacer(".", "_"))
viper.AutomaticEnv()
viper.SetDefault("db.type", "postgres")
viper.SetDefault("db.host", "localhost")
viper.SetDefault("db.port", 5432)
viper.SetDefault("db.name", "kontor")
viper.SetDefault("db.user", "kontor")
viper.SetDefault("db.password", "kontor")
viper.SetDefault("db.path", "data/kontor.db")
viper.SetDefault("server.port", 8550)
viper.SetDefault("gin.mode", "release")
// Read the config file
if err := viper.ReadInConfig(); err != nil {
// Handle the case where config file is not found
@@ -127,7 +152,10 @@ func InitConfig() error {
return fmt.Errorf("error reading config file: %w", err)
}
} else {
slog.Info("initConfig", "Using config file: ", viper.ConfigFileUsed())
slog.Info("InitConfig", "Using config file: ", viper.ConfigFileUsed())
if err := viper.Unmarshal(&ServerConfig); err != nil {
slog.Info("parsing of config file failed", "error", err.Error())
}
}
return nil
+29 -4
View File
@@ -1,17 +1,42 @@
package config
import (
"fmt"
"github.com/spf13/viper"
"gorm.io/driver/postgres"
"gorm.io/driver/sqlite"
"gorm.io/gorm"
"gorm.io/gorm/logger"
"log/slog"
)
func NewDB(dsn string) (*gorm.DB, error) {
func NewDB() (*gorm.DB, error) {
db_type := ServerConfig.DB.Type
slog.Info("using database", "type", db_type)
switch db_type {
case "postgres":
dsn := fmt.Sprintf(
"host=%s user=%s password=%s dbname=%s port=%d sslmode=disable",
viper.GetString("db.host"),
viper.GetString("db.user"),
viper.GetString("db.password"),
viper.GetString("db.name"),
viper.GetInt("db.port"),
)
return gorm.Open(postgres.Open(dsn), &gorm.Config{
Logger: logger.Default.LogMode(logger.Info),
})
case "sqlite":
return gorm.Open(sqlite.Open(viper.GetString("db.path")), &gorm.Config{
Logger: logger.Default.LogMode(logger.Info),
})
default:
return nil, fmt.Errorf("unknown db.type=%s", db_type)
}
// Configure GORM with custom settings
// The logger helps with debugging SQL queries during development
return gorm.Open(postgres.Open(dsn), &gorm.Config{
Logger: logger.Default.LogMode(logger.Info),
})
// if err != nil {
// log.Fatal("Failed to connect to database:", err)
// }
+20 -21
View File
@@ -6,13 +6,13 @@ import (
)
type Article struct {
ID string `gorm:"type:string;primary_key;" json:"id"`
CreatedAt time.Time `gorm:"column:created_date" json:"created_date"`
UpdatedAt time.Time `gorm:"column:last_modified_date" json:"last_modified_date"`
DeletedAt *time.Time `gorm:"column:deleted_date" json:"deleted_date"`
Version int `gorm:"default:0" json:"version"`
Title string `gorm:"uniqueIndex" json:"title"`
ArticleAuthors []ArticleAuthor `gorm:"foreignKey:ArticleID" json:"article_authors"`
ID string `gorm:"type:string;primary_key;" json:"id"`
CreatedAt time.Time `gorm:"column:created_date" json:"created_date"`
UpdatedAt time.Time `gorm:"column:last_modified_date" json:"last_modified_date"`
DeletedAt *time.Time `gorm:"column:deleted_date" json:"deleted_date"`
Version int `gorm:"default:0" json:"version"`
Title string `gorm:"uniqueIndex" json:"title"`
ArticleAuthors []ArticleAuthor `gorm:"foreignKey:ArticleID" json:"article_authors"`
}
func (article *Article) TableName() string {
@@ -20,24 +20,24 @@ func (article *Article) TableName() string {
}
type ArticleDTO struct {
ID string `json:"id" binding:"required"`
CreatedAt helpers.KontorTime `json:"created_date"`
UpdatedAt helpers.KontorTime `json:"last_modified_date"`
DeletedAt *time.Time `json:"deleted_date,omitempty"`
Version int `json:"version"`
Title string `json:"title"`
ID string `json:"id" binding:"required"`
CreatedAt helpers.KontorTime `json:"created_date"`
UpdatedAt helpers.KontorTime `json:"last_modified_date"`
DeletedAt *time.Time `json:"deleted_date,omitempty"`
Version int `json:"version"`
Title string `json:"title"`
}
func ConvertArticlesToDtos(articles []Article) []ArticleDTO {
dtos := make([]ArticleDTO, len(articles))
for i, article := range articles {
dtos[i] = ArticleDTO{
ID: article.ID,
CreatedAt: helpers.KontorTime{Time: article.CreatedAt},
UpdatedAt: helpers.KontorTime{Time: article.UpdatedAt},
DeletedAt: article.DeletedAt,
Version: article.Version,
Title: article.Title,
ID: article.ID,
CreatedAt: helpers.KontorTime{Time: article.CreatedAt},
UpdatedAt: helpers.KontorTime{Time: article.UpdatedAt},
DeletedAt: article.DeletedAt,
Version: article.Version,
Title: article.Title,
}
}
return dtos
@@ -48,6 +48,5 @@ type CreateArticleDTO struct {
}
type UpdateArticleDTO struct {
Title *string `json:"title,omitempty" binding:"omitempty"`
Title *string `json:"title,omitempty" binding:"omitempty"`
}
+2 -2
View File
@@ -22,8 +22,8 @@ func (media_actor *MediaActor) TableName() string {
}
type MediaActorForm struct {
Name string `form:"name" binding:"required"`
Weblink string `form:"weblink" binding:"required"`
Name string `form:"name" binding:"required"`
Weblink string `form:"weblink" binding:"required"`
}
type MediaActorDTO struct {
+2
View File
@@ -76,3 +76,5 @@ type LoginInput struct {
Email string `json:"email" binding:"required"`
Password string `json:"password" binding:"required"`
}
type ProfileDTOList []ProfileDTO
@@ -25,4 +25,3 @@ func (service *MailAccountService) Get(context context.Context, id string) (mode
slog.Info("MailAccountService#Get")
return service.repository.GetById(context, id)
}
File diff suppressed because it is too large Load Diff