This commit is contained in:
@@ -3,10 +3,10 @@ package controllers
|
||||
import (
|
||||
"kontor-api-gin/pkg/globals"
|
||||
"kontor-api-gin/pkg/helpers"
|
||||
"log"
|
||||
"net/http"
|
||||
|
||||
"github.com/gin-contrib/sessions"
|
||||
"github.com/gin-contrib/slog"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
@@ -14,10 +14,13 @@ import (
|
||||
func LoginGetHandler(c *gin.Context) {
|
||||
session := sessions.Default(c)
|
||||
user := session.Get(globals.UserKey)
|
||||
logger := slog.Get(c)
|
||||
logger.Info("LoginGetHandler", "user", user)
|
||||
if user != nil {
|
||||
c.HTML(http.StatusBadRequest, "login.tmpl", gin.H{
|
||||
"title": "Kontor Gin",
|
||||
"version": "0.4.0",
|
||||
"login": globals.LoginUrl,
|
||||
"content": "Please logout first",
|
||||
"user": user,
|
||||
})
|
||||
@@ -26,6 +29,7 @@ func LoginGetHandler(c *gin.Context) {
|
||||
c.HTML(http.StatusOK, "login.tmpl", gin.H{
|
||||
"title": "Kontor Gin",
|
||||
"version": "0.4.0",
|
||||
"login": globals.LoginUrl,
|
||||
"content": "",
|
||||
"user": user,
|
||||
})
|
||||
@@ -34,10 +38,13 @@ func LoginGetHandler(c *gin.Context) {
|
||||
func LoginPostHandler(c *gin.Context) {
|
||||
session := sessions.Default(c)
|
||||
user := session.Get(globals.UserKey)
|
||||
logger := slog.Get(c)
|
||||
logger.Info("LoginPostHandler", "user", user)
|
||||
if user != nil {
|
||||
c.HTML(http.StatusBadRequest, "login.tmpl", gin.H{
|
||||
"title": "Kontor Gin",
|
||||
"version": "0.4.0",
|
||||
"login": globals.LoginUrl,
|
||||
"content": "Please logout first",
|
||||
})
|
||||
return
|
||||
@@ -50,6 +57,7 @@ func LoginPostHandler(c *gin.Context) {
|
||||
c.HTML(http.StatusBadRequest, "login.tmpl", gin.H{
|
||||
"title": "Kontor Gin",
|
||||
"version": "0.4.0",
|
||||
"login": globals.LoginUrl,
|
||||
"content": "Parameters can't be empty",
|
||||
})
|
||||
}
|
||||
@@ -58,6 +66,7 @@ func LoginPostHandler(c *gin.Context) {
|
||||
c.HTML(http.StatusUnauthorized, "login.tmpl", gin.H{
|
||||
"title": "Kontor Gin",
|
||||
"version": "0.4.0",
|
||||
"login": globals.LoginUrl,
|
||||
"content": "Incorrect username or password",
|
||||
})
|
||||
}
|
||||
@@ -67,10 +76,12 @@ func LoginPostHandler(c *gin.Context) {
|
||||
c.HTML(http.StatusInternalServerError, "login.tmpl", gin.H{
|
||||
"title": "Kontor Gin",
|
||||
"version": "0.4.0",
|
||||
"login": globals.LoginUrl,
|
||||
"content": "Failed to save session",
|
||||
})
|
||||
return
|
||||
}
|
||||
logger.Info("LoginGetHandler: redirect to index")
|
||||
|
||||
c.Redirect(http.StatusMovedPermanently, "/")
|
||||
}
|
||||
@@ -78,16 +89,17 @@ func LoginPostHandler(c *gin.Context) {
|
||||
func LogoutGetHandler(c *gin.Context) {
|
||||
session := sessions.Default(c)
|
||||
user := session.Get(globals.UserKey)
|
||||
log.Printf("logging out user %v", user)
|
||||
logger := slog.Get(c)
|
||||
logger.Info("LogoutGetHandler", "user", user)
|
||||
if user == nil {
|
||||
log.Println("Invalid session token")
|
||||
logger.Info("Invalid session token")
|
||||
return
|
||||
}
|
||||
session.Delete(globals.UserKey)
|
||||
if err := session.Save(); err != nil {
|
||||
log.Printf("Failed to save session: %v", err)
|
||||
logger.Info("Failed to save session", "error", err)
|
||||
return
|
||||
}
|
||||
|
||||
logger.Info("LogoutGetHandler: redirect to index page")
|
||||
c.Redirect(http.StatusMovedPermanently, "/")
|
||||
}
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
package controllers
|
||||
|
||||
import (
|
||||
"kontor-api-gin/pkg/globals"
|
||||
"kontor-api-gin/pkg/schema"
|
||||
"net/http"
|
||||
|
||||
"github.com/gin-contrib/sessions"
|
||||
"github.com/gin-contrib/slog"
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
func ListComicsGetHandler(c *gin.Context) {
|
||||
session := sessions.Default(c)
|
||||
user := session.Get(globals.UserKey)
|
||||
logger := slog.Get(c)
|
||||
|
||||
var comics []schema.Comic
|
||||
|
||||
result := schema.DB.Find(&comics)
|
||||
logger.Info("found Comics", "count", result.RowsAffected)
|
||||
c.HTML(http.StatusOK, "comic_comics.tmpl", gin.H{
|
||||
"title": "Kontor Comics",
|
||||
"version": "0.4.0",
|
||||
"content": "Media Files...",
|
||||
"comics": comics,
|
||||
"user": user,
|
||||
})
|
||||
|
||||
}
|
||||
@@ -0,0 +1,92 @@
|
||||
package controllers
|
||||
|
||||
import (
|
||||
"kontor-api-gin/pkg/schema"
|
||||
"net/http"
|
||||
|
||||
"github.com/gin-contrib/slog"
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
func ListComics(c *gin.Context) {
|
||||
var comics []schema.Comic
|
||||
|
||||
logger := slog.Get(c)
|
||||
// query := schema.DB.Model(&schema.MediaFile{})
|
||||
// result := query.Find(&files)
|
||||
result := schema.DB.Find(&comics)
|
||||
logger.Info("found Comics", "count", result.RowsAffected)
|
||||
c.JSON(http.StatusOK, comics)
|
||||
}
|
||||
|
||||
func ListComicPublishers(c *gin.Context) {
|
||||
var publishers []schema.Publisher
|
||||
|
||||
logger := slog.Get(c)
|
||||
result := schema.DB.Find(&publishers)
|
||||
logger.Info("found Comic Publishers", "count", result.RowsAffected)
|
||||
c.JSON(http.StatusOK, publishers)
|
||||
}
|
||||
|
||||
func ListComicArtists(c *gin.Context) {
|
||||
var artists []schema.Artist
|
||||
|
||||
logger := slog.Get(c)
|
||||
result := schema.DB.Find(&artists)
|
||||
logger.Info("found Comic Artists", "count", result.RowsAffected)
|
||||
c.JSON(http.StatusOK, artists)
|
||||
}
|
||||
|
||||
func ListComicIssues(c *gin.Context) {
|
||||
var issues []schema.Issue
|
||||
|
||||
logger := slog.Get(c)
|
||||
result := schema.DB.Find(&issues)
|
||||
logger.Info("found Comic Issues", "count", result.RowsAffected)
|
||||
c.JSON(http.StatusOK, issues)
|
||||
}
|
||||
|
||||
func ListComicWorkTypes(c *gin.Context) {
|
||||
var worktypes []schema.WorkType
|
||||
|
||||
logger := slog.Get(c)
|
||||
result := schema.DB.Find(&worktypes)
|
||||
logger.Info("found Comic WorkTypes", "count", result.RowsAffected)
|
||||
c.JSON(http.StatusOK, worktypes)
|
||||
}
|
||||
|
||||
func ListComicVolumes(c *gin.Context) {
|
||||
var items []schema.Volume
|
||||
|
||||
logger := slog.Get(c)
|
||||
result := schema.DB.Find(&items)
|
||||
logger.Info("found Comic Volumes", "count", result.RowsAffected)
|
||||
c.JSON(http.StatusOK, items)
|
||||
}
|
||||
|
||||
func ListComicStoryArcs(c *gin.Context) {
|
||||
var items []schema.StoryArc
|
||||
|
||||
logger := slog.Get(c)
|
||||
result := schema.DB.Find(&items)
|
||||
logger.Info("found Comic StoryArcs", "count", result.RowsAffected)
|
||||
c.JSON(http.StatusOK, items)
|
||||
}
|
||||
|
||||
func ListComicWorks(c *gin.Context) {
|
||||
var items []schema.ComicWork
|
||||
|
||||
logger := slog.Get(c)
|
||||
result := schema.DB.Find(&items)
|
||||
logger.Info("found Comic ComicWorks", "count", result.RowsAffected)
|
||||
c.JSON(http.StatusOK, items)
|
||||
}
|
||||
|
||||
func ListComicIssueWorks(c *gin.Context) {
|
||||
var items []schema.IssueWork
|
||||
|
||||
logger := slog.Get(c)
|
||||
result := schema.DB.Find(&items)
|
||||
logger.Info("found Comic IssueWorks", "count", result.RowsAffected)
|
||||
c.JSON(http.StatusOK, items)
|
||||
}
|
||||
@@ -5,16 +5,20 @@ import (
|
||||
"net/http"
|
||||
|
||||
"github.com/gin-contrib/sessions"
|
||||
"github.com/gin-contrib/slog"
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
func IndexGetHandler(c *gin.Context) {
|
||||
session := sessions.Default(c)
|
||||
user := session.Get(globals.UserKey)
|
||||
logger := slog.Get(c)
|
||||
logger.Info("IndexGetHandler", "user", user)
|
||||
c.HTML(http.StatusOK, "index.tmpl", gin.H{
|
||||
"title": "Kontor Gin",
|
||||
"version": "0.4.0",
|
||||
"content": "This is an index page...",
|
||||
"logout": globals.LogoutUrl,
|
||||
"user": user,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
package controllers
|
||||
|
||||
import (
|
||||
"kontor-api-gin/pkg/globals"
|
||||
"net/http"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
func HealthGetHandler(c *gin.Context) {
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"status": "healthy",
|
||||
"version": globals.Version,
|
||||
})
|
||||
}
|
||||
@@ -1,10 +1,13 @@
|
||||
package controllers
|
||||
|
||||
import (
|
||||
"kontor-api-gin/pkg/globals"
|
||||
"kontor-api-gin/pkg/schema"
|
||||
"log"
|
||||
"net/http"
|
||||
|
||||
"github.com/gin-contrib/sessions"
|
||||
"github.com/gin-contrib/slog"
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
@@ -32,3 +35,59 @@ func ListMediaLoFis(c *gin.Context) {
|
||||
// "lofis": lofis,
|
||||
// })
|
||||
}
|
||||
|
||||
func ListMediaActorsGetHandler(c *gin.Context) {
|
||||
session := sessions.Default(c)
|
||||
user := session.Get(globals.UserKey)
|
||||
|
||||
var actors []schema.MediaActor
|
||||
|
||||
result := schema.DB.Find(&actors)
|
||||
log.Printf("found %d MediaActors", result.RowsAffected)
|
||||
c.HTML(http.StatusOK, "media_actor.tmpl", gin.H{
|
||||
"title": "Kontor Gin",
|
||||
"version": "0.4.0",
|
||||
"content": "Media Actors...",
|
||||
"actors": actors,
|
||||
"user": user,
|
||||
})
|
||||
}
|
||||
|
||||
func ListMediaFilesGetHandler(c *gin.Context) {
|
||||
session := sessions.Default(c)
|
||||
user := session.Get(globals.UserKey)
|
||||
logger := slog.Get(c)
|
||||
|
||||
var files []schema.MediaFile
|
||||
|
||||
result := schema.DB.Find(&files)
|
||||
logger.Info("found MediaFiles", "count", result.RowsAffected)
|
||||
c.HTML(http.StatusOK, "media_files.tmpl", gin.H{
|
||||
"title": "Kontor Gin",
|
||||
"version": "0.4.0",
|
||||
"content": "Media Files...",
|
||||
"files": files,
|
||||
"user": user,
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
func ListMediaLoFisGetHandler(c *gin.Context) {
|
||||
session := sessions.Default(c)
|
||||
user := session.Get(globals.UserKey)
|
||||
logger := slog.Get(c)
|
||||
|
||||
var lofis []schema.MediaLoFi
|
||||
|
||||
result := schema.DB.Find(&lofis)
|
||||
logger.Info("found MediaActors", "count", result.RowsAffected)
|
||||
c.HTML(http.StatusOK, "media_lofi.tmpl", gin.H{
|
||||
"title": "Kontor Gin",
|
||||
"version": "0.4.0",
|
||||
"content": "Media LoFis...",
|
||||
"lofis": lofis,
|
||||
"logout": globals.LogoutUrl,
|
||||
"user": user,
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
@@ -3,3 +3,9 @@ package globals
|
||||
var Secret = []byte("secret")
|
||||
|
||||
const UserKey = "user"
|
||||
|
||||
const Version = "0.4.0"
|
||||
|
||||
const LoginUrl = "/login"
|
||||
|
||||
const LogoutUrl = "/exit"
|
||||
|
||||
@@ -1,20 +1,22 @@
|
||||
package middleware
|
||||
|
||||
import (
|
||||
"log"
|
||||
"kontor-api-gin/pkg/globals"
|
||||
"net/http"
|
||||
|
||||
"github.com/gin-contrib/sessions"
|
||||
"github.com/gin-contrib/slog"
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
func AuthRequired(c *gin.Context) {
|
||||
session := sessions.Default(c)
|
||||
user := session.Get("user")
|
||||
log.Printf("current user %v", user)
|
||||
user := session.Get(globals.UserKey)
|
||||
logger := slog.Get(c)
|
||||
logger.Info("AuthRequired", globals.UserKey, user)
|
||||
if user == nil {
|
||||
log.Println("User not logged in")
|
||||
c.Redirect(http.StatusMovedPermanently, "/auth/login")
|
||||
logger.Info("User not logged in")
|
||||
c.Redirect(http.StatusMovedPermanently, globals.LoginUrl)
|
||||
c.Abort()
|
||||
return
|
||||
}
|
||||
|
||||
@@ -8,10 +8,12 @@ import (
|
||||
|
||||
// corsMiddleware adds CORS headers for cross-origin requests
|
||||
func CorsMiddleware(c *gin.Context) {
|
||||
c.Writer.Header().Set("Access-Control-Allow-Origin", "*")
|
||||
c.Writer.Header().Set("Access-Control-Allow-Methods", "GET, POST, PATCH, DELETE, OPTIONS")
|
||||
c.Writer.Header().Set("Access-Control-Allow-Headers", "Content-Type, Authorization")
|
||||
c.Header("Access-Control-Allow-Origin", "*")
|
||||
c.Header("Access-Control-Allow-Methods", "GET, POST, PUT, PATCH, DELETE, OPTIONS")
|
||||
c.Header("Access-Control-Allow-Headers", "Content-Type, Authorization")
|
||||
c.Header("Access-Control-Allow-Credentials", "true")
|
||||
|
||||
// Handle preflight requests
|
||||
if c.Request.Method == "OPTIONS" {
|
||||
c.AbortWithStatus(http.StatusNoContent)
|
||||
return
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
package routes
|
||||
|
||||
import (
|
||||
"kontor-api-gin/pkg/controllers"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
func SetupComicRoutes(router *gin.RouterGroup) {
|
||||
comic := router.Group("/comics")
|
||||
|
||||
comics := comic.Group("/comics")
|
||||
comics.GET("", controllers.ListComics)
|
||||
publishers := comic.Group("/publishers")
|
||||
publishers.GET("", controllers.ListComicPublishers)
|
||||
artists := comic.Group("/artists")
|
||||
artists.GET("/", controllers.ListComicArtists)
|
||||
issues := comic.Group("/issues")
|
||||
issues.GET("", controllers.ListComicIssues)
|
||||
worktypes := comic.Group("/worktypes")
|
||||
worktypes.GET("", controllers.ListComicWorkTypes)
|
||||
volumes := comic.Group("/volumes")
|
||||
volumes.GET("", controllers.ListComicVolumes)
|
||||
storyarcs := comic.Group("/storyarcs")
|
||||
storyarcs.GET("", controllers.ListComicStoryArcs)
|
||||
comicworks := comic.Group("/comicworks")
|
||||
comicworks.GET("", controllers.ListComicWorks)
|
||||
issueworks := comic.Group("/issueworks")
|
||||
issueworks.GET("", controllers.ListComicIssueWorks)
|
||||
}
|
||||
@@ -10,12 +10,8 @@ func SetupMediaRoutes(router *gin.RouterGroup) {
|
||||
media := router.Group("/media")
|
||||
|
||||
files := media.Group("/files")
|
||||
{
|
||||
files.GET("", controllers.ListMediaFiles)
|
||||
}
|
||||
files.GET("", controllers.ListMediaFiles)
|
||||
|
||||
lofi := media.Group("/lofi")
|
||||
{
|
||||
lofi.GET("", controllers.ListMediaLoFis)
|
||||
}
|
||||
lofi.GET("/", controllers.ListMediaLoFis)
|
||||
}
|
||||
|
||||
@@ -2,20 +2,22 @@ package routes
|
||||
|
||||
import (
|
||||
"kontor-api-gin/pkg/controllers"
|
||||
"kontor-api-gin/pkg/globals"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
func PublicRoutes(g *gin.RouterGroup) {
|
||||
g.GET("/auth/login", controllers.LoginGetHandler)
|
||||
g.POST("/auth/login", controllers.LoginPostHandler)
|
||||
g.GET("/", controllers.IndexGetHandler)
|
||||
g.GET("/health", controllers.HealthGetHandler)
|
||||
g.GET(globals.LoginUrl, controllers.LoginGetHandler)
|
||||
g.POST(globals.LoginUrl, controllers.LoginPostHandler)
|
||||
g.GET("/comic/comics", controllers.ListComicsGetHandler)
|
||||
g.GET("", controllers.IndexGetHandler)
|
||||
}
|
||||
|
||||
func ProtectedRoutes(g *gin.RouterGroup) {
|
||||
g.GET("/media/actors", controllers.IndexGetHandler)
|
||||
g.GET("/comic/comics", controllers.IndexGetHandler)
|
||||
g.GET("/media/files", controllers.IndexGetHandler)
|
||||
g.GET("/media/lofis", controllers.IndexGetHandler)
|
||||
g.GET("/auth/logout", controllers.LogoutGetHandler)
|
||||
g.GET(globals.LogoutUrl, controllers.LogoutGetHandler)
|
||||
g.GET("/media/actors", controllers.ListMediaActorsGetHandler)
|
||||
// g.GET("/media/files", controllers.ListMediaFilesGetHandler)
|
||||
g.GET("/media/lofis", controllers.ListMediaLoFisGetHandler)
|
||||
}
|
||||
|
||||
@@ -0,0 +1,151 @@
|
||||
package schema
|
||||
|
||||
import (
|
||||
"time"
|
||||
)
|
||||
|
||||
type Publisher struct {
|
||||
Base
|
||||
|
||||
Name string `gorm:"uniqueIndex" json:"name"`
|
||||
WebLink string `json:"weblink"`
|
||||
ParentPublisherID *string `json:"parent_publisher_id"`
|
||||
ParentPublisher *Publisher `gorm:"foreignKey:ParentPublisherID"`
|
||||
Imprints []Publisher `gorm:"foreignKey:ParentPublisherID"`
|
||||
Comics []Comic `gorm:"foreignKey:PublisherID"`
|
||||
}
|
||||
|
||||
func (publisher *Publisher) TableName() string {
|
||||
return "publisher"
|
||||
}
|
||||
|
||||
type Comic struct {
|
||||
Base
|
||||
|
||||
Title string `gorm:"uniqueIndex" json:"title"`
|
||||
CurrentOrder bool `json:"current_order"`
|
||||
Completed bool `json:"completed"`
|
||||
WebLink string `json:"weblink"`
|
||||
PublisherID *string `json:"publisher_id"`
|
||||
Publisher *Publisher `gorm:"foreignKey:PublisherID"`
|
||||
Issues []Issue `gorm:"foreignKey:ComicID"`
|
||||
StoryArcs []StoryArc `gorm:"foreignKey:ComicID"`
|
||||
TradePaperbacks []TradePaperback `gorm:"foreignKey:ComicID"`
|
||||
Volumes []Volume `gorm:"foreignKey:ComicID"`
|
||||
ComicWorks []ComicWork `gorm:"foreignKey:ComicID"`
|
||||
}
|
||||
|
||||
func (comic *Comic) TableName() string {
|
||||
return "comic"
|
||||
}
|
||||
|
||||
type Artist struct {
|
||||
Base
|
||||
|
||||
Name string `gorm:"uniqueIndex" json:"name"`
|
||||
WebLink string `json:"weblink"`
|
||||
}
|
||||
|
||||
func (artist *Artist) TableName() string {
|
||||
return "artist"
|
||||
}
|
||||
|
||||
type Issue struct {
|
||||
Base
|
||||
|
||||
InStock bool `json:"in_stock"`
|
||||
IsRead bool `json:"is_read"`
|
||||
IssueNumber string `json:"issue_number"`
|
||||
Title string `json:"title"`
|
||||
PublishedOn time.Time `json:"published_on"`
|
||||
ComicID *string `json:"comic_id"`
|
||||
Comic *Comic `gorm:"foreignKey:ComicID"`
|
||||
StoryArcID *string `json:"story_arc_id"`
|
||||
StoryArc *StoryArc `gorm:"foreignKey:StoryArcID"`
|
||||
VolumeID *string `json:"volume_id"`
|
||||
Volume *Volume `gorm:"foreignKey:VolumeID"`
|
||||
}
|
||||
|
||||
func (issue *Issue) TableName() string {
|
||||
return "issue"
|
||||
}
|
||||
|
||||
type StoryArc struct {
|
||||
Base
|
||||
|
||||
Name string `gorm:"uniqueIndex" json:"name"`
|
||||
ComicID *string `json:"comic_id"`
|
||||
Comic *Comic `gorm:"foreignKey:ComicID"`
|
||||
VolumeID *string `json:"volume_id"`
|
||||
Volume *Volume `gorm:"foreignKey:VolumeID"`
|
||||
}
|
||||
|
||||
func (story_arc *StoryArc) TableName() string {
|
||||
return "story_arc"
|
||||
}
|
||||
|
||||
type TradePaperback struct {
|
||||
Base
|
||||
|
||||
Name string `gorm:"uniqueIndex" json:"name"`
|
||||
IssueStart int `json:"issue_start"`
|
||||
IssueEnd int `json:"issue_end"`
|
||||
ComicID *string `json:"comic_id"`
|
||||
Comic *Comic `gorm:"foreignKey:ComicID"`
|
||||
}
|
||||
|
||||
func (trade_paperback *TradePaperback) TableName() string {
|
||||
return "trade_paperback"
|
||||
}
|
||||
|
||||
type Volume struct {
|
||||
Base
|
||||
|
||||
Name string `gorm:"uniqueIndex" json:"name"`
|
||||
ComicID *string `json:"comic_id"`
|
||||
Comic *Comic `gorm:"foreignKey:ComicID"`
|
||||
}
|
||||
|
||||
func (volume *Volume) TableName() string {
|
||||
return "volume"
|
||||
}
|
||||
|
||||
type WorkType struct {
|
||||
Base
|
||||
|
||||
Name string `gorm:"uniqueIndex" json:"name"`
|
||||
}
|
||||
|
||||
func (worktype *WorkType) TableName() string {
|
||||
return "worktype"
|
||||
}
|
||||
|
||||
type ComicWork struct {
|
||||
Base
|
||||
|
||||
ArtistID *string `json:"artist_id"`
|
||||
Artist *Artist `gorm:"foreignKey:ArtistID"`
|
||||
ComicID *string `json:"comic_id"`
|
||||
Comic *Comic `gorm:"foreignKey:ComicID"`
|
||||
WorkTypeID *string `json:"work_type_id"`
|
||||
WorkType *WorkType `gorm:"foreignKey:WorkTypeID"`
|
||||
}
|
||||
|
||||
func (comic_work *ComicWork) TableName() string {
|
||||
return "comic_work"
|
||||
}
|
||||
|
||||
type IssueWork struct {
|
||||
Base
|
||||
|
||||
ArtistID *string `json:"artist_id"`
|
||||
Artist *Artist `gorm:"foreignKey:ArtistID"`
|
||||
IssueID *string `json:"issue_id"`
|
||||
Issue *Issue `gorm:"foreignKey:IssueID"`
|
||||
WorkTypeID *string `json:"work_type_id"`
|
||||
WorkType *WorkType `gorm:"foreignKey:WorkTypeID"`
|
||||
}
|
||||
|
||||
func (issue_work *IssueWork) TableName() string {
|
||||
return "issue_work"
|
||||
}
|
||||
@@ -1,69 +1,69 @@
|
||||
package schema
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
"time"
|
||||
"fmt"
|
||||
"log"
|
||||
"log/slog"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"gorm.io/driver/postgres"
|
||||
"gorm.io/gorm"
|
||||
"gorm.io/gorm/logger"
|
||||
|
||||
"gorm.io/driver/postgres"
|
||||
"gorm.io/gorm"
|
||||
"gorm.io/gorm/logger"
|
||||
)
|
||||
|
||||
var DB *gorm.DB
|
||||
|
||||
func Connect() {
|
||||
// Build the connection string from environment variables
|
||||
// This keeps sensitive credentials out of the codebase
|
||||
dsn := fmt.Sprintf(
|
||||
"host=%s user=%s password=%s dbname=%s port=%s sslmode=disable",
|
||||
os.Getenv("DB_HOST"),
|
||||
os.Getenv("DB_USER"),
|
||||
os.Getenv("DB_PASSWORD"),
|
||||
os.Getenv("DB_NAME"),
|
||||
os.Getenv("DB_PORT"),
|
||||
)
|
||||
// Build the connection string from environment variables
|
||||
// This keeps sensitive credentials out of the codebase
|
||||
dsn := fmt.Sprintf(
|
||||
"host=%s user=%s password=%s dbname=%s port=%s sslmode=disable",
|
||||
os.Getenv("DB_HOST"),
|
||||
os.Getenv("DB_USER"),
|
||||
os.Getenv("DB_PASSWORD"),
|
||||
os.Getenv("DB_NAME"),
|
||||
os.Getenv("DB_PORT"),
|
||||
)
|
||||
|
||||
// Configure GORM with custom settings
|
||||
// The logger helps with debugging SQL queries during development
|
||||
db, err := gorm.Open(postgres.Open(dsn), &gorm.Config{
|
||||
Logger: logger.Default.LogMode(logger.Info),
|
||||
})
|
||||
if err != nil {
|
||||
log.Fatal("Failed to connect to database:", err)
|
||||
}
|
||||
// Configure GORM with custom settings
|
||||
// The logger helps with debugging SQL queries during development
|
||||
db, err := gorm.Open(postgres.Open(dsn), &gorm.Config{
|
||||
Logger: logger.Default.LogMode(logger.Info),
|
||||
})
|
||||
if err != nil {
|
||||
log.Fatal("Failed to connect to database:", err)
|
||||
}
|
||||
|
||||
// Get the underlying SQL database connection for pool configuration
|
||||
sqlDB, err := db.DB()
|
||||
if err != nil {
|
||||
log.Fatal("Failed to get database instance:", err)
|
||||
}
|
||||
// Get the underlying SQL database connection for pool configuration
|
||||
sqlDB, err := db.DB()
|
||||
if err != nil {
|
||||
log.Fatal("Failed to get database instance:", err)
|
||||
}
|
||||
|
||||
// Configure connection pool settings
|
||||
// MaxIdleConns: number of connections kept open when idle
|
||||
sqlDB.SetMaxIdleConns(10)
|
||||
// MaxOpenConns: maximum total connections to the database
|
||||
sqlDB.SetMaxOpenConns(100)
|
||||
// ConnMaxLifetime: how long a connection can be reused
|
||||
sqlDB.SetConnMaxLifetime(time.Hour)
|
||||
// Configure connection pool settings
|
||||
// MaxIdleConns: number of connections kept open when idle
|
||||
sqlDB.SetMaxIdleConns(10)
|
||||
// MaxOpenConns: maximum total connections to the database
|
||||
sqlDB.SetMaxOpenConns(100)
|
||||
// ConnMaxLifetime: how long a connection can be reused
|
||||
sqlDB.SetConnMaxLifetime(time.Hour)
|
||||
|
||||
DB = db
|
||||
log.Println("Database connected successfully")
|
||||
DB = db
|
||||
slog.Info("Database connected successfully")
|
||||
}
|
||||
|
||||
func RunMigrations() {
|
||||
// AutoMigrate creates tables, missing columns, and missing indexes
|
||||
// It will NOT delete unused columns to protect your data
|
||||
err := DB.AutoMigrate(
|
||||
&MediaActor{},
|
||||
&MediaFile{},
|
||||
&MediaActorFile{},
|
||||
)
|
||||
if err != nil {
|
||||
log.Fatal("Migration failed:", err)
|
||||
}
|
||||
// AutoMigrate creates tables, missing columns, and missing indexes
|
||||
// It will NOT delete unused columns to protect your data
|
||||
err := DB.AutoMigrate(
|
||||
&MediaActor{},
|
||||
&MediaFile{},
|
||||
&MediaActorFile{},
|
||||
)
|
||||
if err != nil {
|
||||
log.Fatal("Migration failed:", err)
|
||||
}
|
||||
|
||||
log.Println("Database migration completed")
|
||||
slog.Info("Database migration completed")
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user