This commit is contained in:
@@ -0,0 +1,121 @@
|
||||
package schema
|
||||
|
||||
import (
|
||||
"kontor-api-gin/internal/helpers"
|
||||
"time"
|
||||
|
||||
"golang.org/x/crypto/bcrypt"
|
||||
)
|
||||
|
||||
func VerifyPassword(password, hashedPassword string) error {
|
||||
return bcrypt.CompareHashAndPassword([]byte(hashedPassword), []byte(password))
|
||||
}
|
||||
|
||||
func LoginCheck(email string, password string) (string, error) {
|
||||
|
||||
var err error
|
||||
|
||||
profile := Profile{}
|
||||
|
||||
err = DB.Model(Profile{}).Where("email = ?", email).Take(&profile).Error
|
||||
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
err = VerifyPassword(password, profile.Password)
|
||||
|
||||
if err != nil && err == bcrypt.ErrMismatchedHashAndPassword {
|
||||
return "", err
|
||||
}
|
||||
|
||||
token, err := helpers.GenerateToken(profile.ID)
|
||||
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return token, nil
|
||||
|
||||
}
|
||||
|
||||
type Profile struct {
|
||||
ID string `gorm:"type:string;primary_key;"`
|
||||
Created_Date time.Time `json:"created_date"`
|
||||
Last_Modified_date time.Time `json:"last_modified_date"`
|
||||
Deleted_Date *time.Time `json:"deleted_date"`
|
||||
Version int `gorm:"default:0" json:"version"`
|
||||
First_Name *string `json:"first_name"`
|
||||
Last_Name *string `json:"last_name"`
|
||||
User_Name string `json:"user_name"`
|
||||
Email string `json:"email"`
|
||||
Password string `json:"password"`
|
||||
Enabled bool `json:"enabled"`
|
||||
|
||||
Assignments []Assignment `gorm:"foreignKey:ProfileID" json:"assignments"`
|
||||
Tokens []Token `gorm:"foreignKey:ProfileID" json:"tokens"`
|
||||
}
|
||||
|
||||
func (profile *Profile) TableName() string {
|
||||
return "profile"
|
||||
}
|
||||
|
||||
func (profile *Profile) GetFullName() string {
|
||||
full_name := ""
|
||||
if profile.First_Name != nil {
|
||||
full_name += *profile.First_Name
|
||||
}
|
||||
if profile.Last_Name != nil {
|
||||
full_name += " "
|
||||
full_name += *profile.Last_Name
|
||||
}
|
||||
return full_name
|
||||
}
|
||||
|
||||
type Token struct {
|
||||
ID string `gorm:"type:string;primary_key;"`
|
||||
Created_Date time.Time `json:"created_date"`
|
||||
Last_Modified_date time.Time `json:"last_modified_date"`
|
||||
Deleted_Date *time.Time `json:"deleted_date"`
|
||||
Version int `gorm:"default:0" json:"version"`
|
||||
Token string `gorm:"uniqueIndex" json:"token"`
|
||||
Name string `json:"name"`
|
||||
Last_Used_date time.Time `json:"last_used_date"`
|
||||
Enabled bool `json:"enabled"`
|
||||
ProfileID *string `json:"profile_id"`
|
||||
Profile *Profile `gorm:"foreignKey:ProfileID" json:"profile"`
|
||||
}
|
||||
|
||||
func (token *Token) TableName() string {
|
||||
return "token"
|
||||
}
|
||||
|
||||
type Permission struct {
|
||||
ID string `gorm:"type:string;primary_key;"`
|
||||
Created_Date time.Time `json:"created_date"`
|
||||
Last_Modified_date time.Time `json:"last_modified_date"`
|
||||
Deleted_Date *time.Time `json:"deleted_date"`
|
||||
Version int `gorm:"default:0" json:"version"`
|
||||
Name string `json:"name"`
|
||||
Assignments []Assignment `gorm:"foreignKey:PermissionID" json:"assignments"`
|
||||
}
|
||||
|
||||
func (permission *Permission) TableName() string {
|
||||
return "permission"
|
||||
}
|
||||
|
||||
type Assignment struct {
|
||||
ID string `gorm:"type:string;primary_key;"`
|
||||
Created_Date time.Time `json:"created_date"`
|
||||
Last_Modified_date time.Time `json:"last_modified_date"`
|
||||
Deleted_Date *time.Time `json:"deleted_date"`
|
||||
Version int `gorm:"default:0" json:"version"`
|
||||
ProfileID *string `json:"profile_id"`
|
||||
Profile *Profile `gorm:"foreignKey:ProfileID" json:"profile"`
|
||||
PermissionID *string `json:"permission_id"`
|
||||
Permission *Profile `gorm:"foreignKey:PermissionID" json:"permission"`
|
||||
}
|
||||
|
||||
func (assignment *Assignment) TableName() string {
|
||||
return "assignment"
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
package schema
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
type Base struct {
|
||||
ID string `gorm:"type:string;primary_key;"`
|
||||
CreatedAt time.Time `json:"created_date"`
|
||||
UpdatedAt time.Time `json:"last_modified_date"`
|
||||
DeletedAt *time.Time `json:"deleted_date"`
|
||||
Version int `gorm:"default:0" json:"version"`
|
||||
}
|
||||
|
||||
// BeforeCreate will set a UUID rather than numeric ID.
|
||||
func (b *Base) BeforeCreate(tx *gorm.DB) (err error) {
|
||||
b.ID = uuid.New().String()
|
||||
return
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
package schema
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"log/slog"
|
||||
"time"
|
||||
|
||||
"github.com/spf13/viper"
|
||||
|
||||
"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=%d sslmode=disable",
|
||||
viper.GetString("db.host"),
|
||||
viper.GetString("db.user"),
|
||||
viper.GetString("db.password"),
|
||||
viper.GetString("db.name"),
|
||||
viper.GetInt("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)
|
||||
}
|
||||
|
||||
// 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)
|
||||
|
||||
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()
|
||||
if err != nil {
|
||||
log.Fatal("Migration failed:", err)
|
||||
}
|
||||
|
||||
slog.Info("Database migration completed")
|
||||
}
|
||||
@@ -0,0 +1,107 @@
|
||||
package schema
|
||||
|
||||
import "time"
|
||||
|
||||
type MediaLoFi struct {
|
||||
ID string `gorm:"type:string;primary_key;"`
|
||||
Created_Date time.Time `json:"created_date"`
|
||||
Last_Modified_date time.Time `json:"last_modified_date"`
|
||||
Deleted_Date *time.Time `json:"deleted_date"`
|
||||
Version int `gorm:"default:0" json:"version"`
|
||||
Url string `gorm:"uniqueIndex" json:"url"`
|
||||
Review bool `json:"review"`
|
||||
ShouldDownload bool `json:"should_download"`
|
||||
Title string `gorm:"size:300" json:"title"`
|
||||
FileName string `json:"file_name"`
|
||||
}
|
||||
|
||||
func (media_lofi *MediaLoFi) TableName() string {
|
||||
return "media_lofi"
|
||||
}
|
||||
|
||||
type MediaFile struct {
|
||||
ID string `gorm:"type:string;primary_key;"`
|
||||
Created_Date time.Time `json:"created_date"`
|
||||
Last_Modified_date time.Time `json:"last_modified_date"`
|
||||
Deleted_Date *time.Time `json:"deleted_date"`
|
||||
Version int `gorm:"default:0" json:"version"`
|
||||
CloudLink string `gorm:"column:cloud_link" json:"cloud_link"`
|
||||
FileName string `json:"file_name"`
|
||||
Path string `json:"path"`
|
||||
Review bool `json:"review"`
|
||||
Title string `gorm:"size:300" json:"title"`
|
||||
WebLink string `gorm:"column:url" json:"url"`
|
||||
ShouldDownload bool `json:"should_download"`
|
||||
|
||||
MediaActorFiles []MediaActorFile `gorm:"foreignKey:MediaFileID" json:"media_actor_files"`
|
||||
}
|
||||
|
||||
func (media_file *MediaFile) TableName() string {
|
||||
return "media_file"
|
||||
}
|
||||
|
||||
type MediaActor struct {
|
||||
ID string `gorm:"type:string;primary_key;"`
|
||||
Created_Date time.Time `json:"created_date"`
|
||||
Last_Modified_date time.Time `json:"last_modified_date"`
|
||||
Deleted_Date *time.Time `json:"deleted_date"`
|
||||
Version int `gorm:"default:0" json:"version"`
|
||||
Name string `json:"name"`
|
||||
Url string `json:"url"`
|
||||
|
||||
MediaActorFiles []MediaActorFile `gorm:"foreignKey:MediaActorID" json:"media_actor_files"`
|
||||
}
|
||||
|
||||
func (media_actor *MediaActor) TableName() string {
|
||||
return "media_actor"
|
||||
}
|
||||
|
||||
type MediaActorFile struct {
|
||||
ID string `gorm:"type:string;primary_key;"`
|
||||
Created_Date time.Time `json:"created_date"`
|
||||
Last_Modified_date time.Time `json:"last_modified_date"`
|
||||
Deleted_Date *time.Time `json:"deleted_date"`
|
||||
Version int `gorm:"default:0" json:"version"`
|
||||
MediaActorID *string `json:"media_actor_id"`
|
||||
MediaActor *MediaActor `gorm:"foreignKey:MediaActorID" json:"media_actor"`
|
||||
MediaFileID *string `json:"media_file_id"`
|
||||
MediaFile *MediaFile `gorm:"foreignKey:MediaFileID" json:"media_file"`
|
||||
}
|
||||
|
||||
func (media_file *MediaActorFile) TableName() string {
|
||||
return "media_actor_file"
|
||||
}
|
||||
|
||||
type MediaArticle struct {
|
||||
ID string `gorm:"type:string;primary_key;"`
|
||||
Created_Date time.Time `json:"created_date"`
|
||||
Last_Modified_date time.Time `json:"last_modified_date"`
|
||||
Deleted_Date *time.Time `json:"deleted_date"`
|
||||
Version int `gorm:"default:0" json:"version"`
|
||||
Review bool `json:"review"`
|
||||
Title string `gorm:"size:300" json:"title"`
|
||||
Url string `gorm:"uniqueIndex" json:"url"`
|
||||
}
|
||||
|
||||
func (media_article *MediaArticle) TableName() string {
|
||||
return "media_article"
|
||||
}
|
||||
|
||||
type MediaVideo struct {
|
||||
ID string `gorm:"type:string;primary_key;"`
|
||||
Created_Date time.Time `json:"created_date"`
|
||||
Last_Modified_date time.Time `json:"last_modified_date"`
|
||||
Deleted_Date *time.Time `json:"deleted_date"`
|
||||
Version int `gorm:"default:0" json:"version"`
|
||||
CloudLink string `json:"cloud_link"`
|
||||
FileName string `json:"file_name"`
|
||||
Path string `json:"path"`
|
||||
Review bool `json:"review"`
|
||||
Title string `gorm:"size:300" json:"title"`
|
||||
Url string `gorm:"uniqueIndex" json:"url"`
|
||||
ShouldDownload bool `json:"should_download"`
|
||||
}
|
||||
|
||||
func (media_video *MediaVideo) TableName() string {
|
||||
return "media_video"
|
||||
}
|
||||
Reference in New Issue
Block a user