优化结构
This commit is contained in:
@@ -26,6 +26,73 @@ type ConfigPO struct {
|
||||
|
||||
func (ConfigPO) TableName() string { return "sys_integration_configs" }
|
||||
|
||||
// ConfigRow is one integration configuration row without its PO: the parent
|
||||
// data package owns the storage and email upgrade paths, but the table shape
|
||||
// stays private here.
|
||||
type ConfigRow struct {
|
||||
Provider string
|
||||
Enabled bool
|
||||
Config string
|
||||
}
|
||||
|
||||
// HasConfigTable reports whether the integration configuration table exists,
|
||||
// which callers use to tell "not migrated yet" from "no rows".
|
||||
func HasConfigTable(db *gorm.DB) bool {
|
||||
return db != nil && cleanSession(db).Migrator().HasTable(&ConfigPO{})
|
||||
}
|
||||
|
||||
// ListConfigs returns every row of a kind in insertion order.
|
||||
func ListConfigs(db *gorm.DB, kind string) ([]ConfigRow, error) {
|
||||
var rows []ConfigPO
|
||||
if err := cleanSession(db).Where("kind = ?", kind).Order("id ASC").Find(&rows).Error; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result := make([]ConfigRow, 0, len(rows))
|
||||
for _, row := range rows {
|
||||
result = append(result, ConfigRow{Provider: row.Provider, Enabled: row.Enabled, Config: row.Config})
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// FindConfig returns one row and whether it exists. A missing row is not an
|
||||
// error because every caller treats it as "fall back to the legacy value".
|
||||
func FindConfig(db *gorm.DB, kind, provider string) (ConfigRow, bool, error) {
|
||||
var row ConfigPO
|
||||
err := cleanSession(db).Where("kind = ? AND provider = ?", kind, provider).First(&row).Error
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
return ConfigRow{}, false, nil
|
||||
}
|
||||
if err != nil {
|
||||
return ConfigRow{}, false, err
|
||||
}
|
||||
return ConfigRow{Provider: row.Provider, Enabled: row.Enabled, Config: row.Config}, true, nil
|
||||
}
|
||||
|
||||
// UpsertConfigs writes every given row of a kind in one transaction, inserting
|
||||
// the ones that do not exist yet and updating the rest in place.
|
||||
func UpsertConfigs(db *gorm.DB, kind string, rows []ConfigRow) error {
|
||||
return cleanSession(db).Transaction(func(tx *gorm.DB) error {
|
||||
for _, item := range rows {
|
||||
var current ConfigPO
|
||||
err := tx.Where("kind = ? AND provider = ?", kind, item.Provider).First(¤t).Error
|
||||
switch {
|
||||
case errors.Is(err, gorm.ErrRecordNotFound):
|
||||
err = tx.Create(&ConfigPO{Kind: kind, Provider: item.Provider, Enabled: item.Enabled, Config: item.Config}).Error
|
||||
case err == nil:
|
||||
err = tx.Model(¤t).Updates(map[string]any{"enabled": item.Enabled, "config": item.Config}).Error
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
// cleanSession drops conditions inherited from the caller's handle so a scoped
|
||||
// query cannot leak a WHERE clause into these statements.
|
||||
func cleanSession(db *gorm.DB) *gorm.DB { return db.Session(&gorm.Session{NewDB: true}) }
|
||||
|
||||
type integrationConfigRepo struct{ data Provider }
|
||||
|
||||
type paymentConfigReader struct{ data Provider }
|
||||
|
||||
Reference in New Issue
Block a user