139 lines
5.6 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package data
import (
"context"
"database/sql"
"time"
"rag/file-system/internal/conf"
"github.com/go-kratos/kratos/v2/log"
"github.com/google/wire"
"gorm.io/driver/postgres"
"gorm.io/gorm"
)
// Data holds the GORM database connection and provides transaction support.
type Data struct {
db *gorm.DB
log *log.Helper
}
// contextTxKey is the context key for storing the current transaction.
type contextTxKey struct{}
// NewData creates a new Data instance with GORM connected to PostgreSQL.
func NewData(c *conf.Data, logger log.Logger) (*Data, func(), error) {
helper := log.NewHelper(logger)
db, err := gorm.Open(postgres.Open(c.Database.Source), &gorm.Config{})
if err != nil {
return nil, nil, err
}
sqlDB, err := db.DB()
if err != nil {
return nil, nil, err
}
sqlDB.SetMaxOpenConns(25)
sqlDB.SetMaxIdleConns(5)
if err := db.AutoMigrate(&FolderPO{}, &FileMetaPO{}, &ShareLinkPO{}); err != nil {
return nil, nil, err
}
helper.Info("connected to PostgreSQL via GORM")
cleanup := func() {
sqlDB.Close()
}
return &Data{db: db, log: helper}, cleanup, nil
}
// SqlDB returns the underlying *sql.DB for use by Watermill.
func (d *Data) SqlDB() (*sql.DB, error) {
return d.db.DB()
}
// DB returns the *gorm.DB for the given context. If a transaction is active
// in the context, it returns the transaction DB; otherwise the global DB.
func (d *Data) DB(ctx context.Context) *gorm.DB {
tx, ok := ctx.Value(contextTxKey{}).(*gorm.DB)
if ok {
return tx
}
return d.db.WithContext(ctx)
}
// Transaction is the interface for executing operations within a database transaction.
type Transaction interface {
InTx(ctx context.Context, fn func(ctx context.Context) error) error
}
// InTx executes fn inside a database transaction.
func (d *Data) InTx(ctx context.Context, fn func(ctx context.Context) error) error {
return d.db.WithContext(ctx).Transaction(func(tx *gorm.DB) error {
ctx = context.WithValue(ctx, contextTxKey{}, tx)
return fn(ctx)
})
}
// ProviderSet is the Wire provider set for the data layer.
var ProviderSet = wire.NewSet(NewData, NewFileRepo, NewFolderRepo, NewFileMetaRepo, NewShareRepo)
// --- GORM Models (Persistence Objects) ---
// FolderPO maps to the "folders" table.
type FolderPO struct {
ID string `gorm:"primaryKey;type:uuid;default:gen_random_uuid();comment:主键ID"`
ParentID *string `gorm:"type:uuid;index:idx_folders_parent;comment:父文件夹ID"`
Name string `gorm:"type:varchar(255);not null;comment:文件夹名称"`
OwnerID string `gorm:"type:varchar(36);not null;index:idx_folders_owner;comment:所有者ID"`
CreatedBy string `gorm:"type:varchar(36);not null;default:'';comment:创建人ID"`
CreatedAt time.Time `gorm:"autoCreateTime;comment:创建时间"`
UpdatedBy string `gorm:"type:varchar(36);not null;default:'';comment:更新人ID"`
UpdatedAt time.Time `gorm:"autoUpdateTime;comment:更新时间"`
IsDeleted bool `gorm:"not null;default:false;comment:是否软删除"`
OperatorIP string `gorm:"type:varchar(500);comment:操作人IP地址"`
}
func (FolderPO) TableName() string { return "folders" }
// FileMetaPO maps to the "files" table.
type FileMetaPO struct {
ID string `gorm:"primaryKey;type:uuid;default:gen_random_uuid();comment:主键ID"`
FolderID string `gorm:"type:uuid;index:idx_files_folder;comment:所属文件夹ID"`
Name string `gorm:"type:varchar(255);not null;comment:文件名称"`
S3Key string `gorm:"type:varchar(512);not null;index:idx_files_s3_key;comment:S3对象键"`
S3Bucket string `gorm:"type:varchar(255);not null;comment:S3存储桶名称"`
Size int64 `gorm:"default:0;comment:文件大小(字节)"`
ContentType string `gorm:"type:varchar(255);default:'application/octet-stream';comment:文件MIME类型"`
OwnerID string `gorm:"type:varchar(36);not null;index:idx_files_owner;comment:所有者ID"`
CreatedBy string `gorm:"type:varchar(36);not null;default:'';comment:创建人ID"`
CreatedAt time.Time `gorm:"autoCreateTime;comment:创建时间"`
UpdatedBy string `gorm:"type:varchar(36);not null;default:'';comment:更新人ID"`
UpdatedAt time.Time `gorm:"autoUpdateTime;comment:更新时间"`
IsDeleted bool `gorm:"not null;default:false;comment:是否软删除"`
OperatorIP string `gorm:"type:varchar(500);comment:操作人IP地址"`
}
func (FileMetaPO) TableName() string { return "files" }
// ShareLinkPO maps to the "share_links" table.
type ShareLinkPO struct {
ID string `gorm:"primaryKey;type:uuid;default:gen_random_uuid();comment:主键ID"`
ResourceType string `gorm:"type:varchar(10);not null;comment:资源类型folder/file"`
ResourceID string `gorm:"type:uuid;not null;comment:资源ID"`
Token string `gorm:"type:varchar(32);not null;uniqueIndex:idx_share_token;comment:分享令牌"`
Password *string `gorm:"type:varchar(255);comment:访问密码"`
ExpiresAt *time.Time `gorm:"type:timestamptz;comment:过期时间"`
DownloadCount int `gorm:"default:0;comment:下载次数"`
MaxDownloads *int `gorm:"comment:最大下载次数"`
CreatedBy string `gorm:"type:varchar(36);not null;comment:创建人ID"`
CreatedAt time.Time `gorm:"autoCreateTime;comment:创建时间"`
UpdatedBy string `gorm:"type:varchar(36);not null;default:'';comment:更新人ID"`
UpdatedAt time.Time `gorm:"autoUpdateTime;comment:更新时间"`
IsDeleted bool `gorm:"not null;default:false;comment:是否软删除"`
OperatorIP string `gorm:"type:varchar(500);comment:操作人IP地址"`
}
func (ShareLinkPO) TableName() string { return "share_links" }