138 lines
4.0 KiB
Go
138 lines
4.0 KiB
Go
package persistence
|
|
|
|
import (
|
|
domain "RenewCMS/internal/domain/localization"
|
|
"RenewCMS/internal/infrastructure/persistence/mappers"
|
|
entity "RenewCMS/internal/infrastructure/persistence/models"
|
|
"slices"
|
|
|
|
"gorm.io/gorm"
|
|
)
|
|
|
|
type LocalizationRepository struct {
|
|
db *gorm.DB
|
|
}
|
|
|
|
func NewLocalizationRepository(db *gorm.DB) *LocalizationRepository {
|
|
return &LocalizationRepository{db}
|
|
}
|
|
|
|
type languageTotal struct {
|
|
Lang string
|
|
Total int
|
|
}
|
|
|
|
func (l *LocalizationRepository) Rows(siteID uint32) ([]domain.Row, error) {
|
|
var found []entity.SiteLanguage
|
|
if err := l.db.Where("site_id = ?", siteID).Order("lang ASC").Find(&found).Error; err != nil {
|
|
return nil, err
|
|
}
|
|
rows := make([]domain.Row, 0, len(found))
|
|
for _, row := range found {
|
|
rows = append(rows, mappers.LocalizationRowToDomain(row))
|
|
}
|
|
return rows, nil
|
|
}
|
|
|
|
func (l *LocalizationRepository) ConfirmedSites() (map[uint32]bool, error) {
|
|
var ids []uint32
|
|
err := l.db.Model(&entity.SiteLanguage{}).Where("is_default = ? AND confirmed = ?", true, true).Distinct().Pluck("site_id", &ids).Error
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
confirmed := make(map[uint32]bool, len(ids))
|
|
for _, id := range ids {
|
|
confirmed[id] = true
|
|
}
|
|
return confirmed, nil
|
|
}
|
|
|
|
func (l *LocalizationRepository) VersionCounts(siteID uint32) (map[string]domain.VersionCount, error) {
|
|
totals, err := l.countByLanguage(l.db.Where("site_id = ?", siteID))
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
published, err := l.countByLanguage(l.db.Where("site_id = ? AND is_online = ?", siteID, true))
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
trashed, err := l.countByLanguage(l.db.Unscoped().Where("site_id = ? AND deleted_at IS NOT NULL", siteID))
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
counts := make(map[string]domain.VersionCount, len(totals))
|
|
for lang, total := range totals {
|
|
counts[lang] = domain.VersionCount{Total: total, Published: published[lang]}
|
|
}
|
|
for lang, count := range trashed {
|
|
kept := counts[lang]
|
|
kept.Trashed = count
|
|
counts[lang] = kept
|
|
}
|
|
return counts, nil
|
|
}
|
|
|
|
func (l *LocalizationRepository) countByLanguage(scope *gorm.DB) (map[string]int, error) {
|
|
var totals []languageTotal
|
|
err := scope.Model(&entity.Article{}).Select("lang, COUNT(*) AS total").Group("lang").Scan(&totals).Error
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
counted := make(map[string]int, len(totals))
|
|
for _, total := range totals {
|
|
counted[total.Lang] = total.Total
|
|
}
|
|
return counted, nil
|
|
}
|
|
|
|
func (l *LocalizationRepository) Replace(siteID uint32, rows []domain.Row) error {
|
|
existing, err := l.Rows(siteID)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
known := make(map[string]domain.Row, len(existing))
|
|
for _, row := range existing {
|
|
known[row.Tag] = row
|
|
}
|
|
wanted := make([]string, 0, len(rows))
|
|
for _, row := range rows {
|
|
wanted = append(wanted, row.Tag)
|
|
}
|
|
for _, row := range existing {
|
|
if !slices.Contains(wanted, row.Tag) {
|
|
if err := l.db.Where("site_id = ? AND lang = ?", siteID, row.Tag).Delete(&entity.SiteLanguage{}).Error; err != nil {
|
|
return err
|
|
}
|
|
}
|
|
}
|
|
for _, row := range rows {
|
|
if err := l.save(siteID, row, known); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (l *LocalizationRepository) save(siteID uint32, row domain.Row, known map[string]domain.Row) error {
|
|
before, exists := known[row.Tag]
|
|
if !exists {
|
|
model := mappers.LocalizationRowToModel(siteID, row)
|
|
return l.db.Create(&model).Error
|
|
}
|
|
if before.Equal(row) {
|
|
return nil
|
|
}
|
|
changes := map[string]any{"is_default": row.IsDefault, "enabled": row.Enabled, "confirmed": row.Confirmed, "social_locale": row.SocialLocale}
|
|
return l.db.Model(&entity.SiteLanguage{}).Where("site_id = ? AND lang = ?", siteID, row.Tag).Updates(changes).Error
|
|
}
|
|
|
|
func (l *LocalizationRepository) ConfirmSetup(siteID uint32, tag string) error {
|
|
if err := l.db.Where("site_id = ? AND confirmed = ?", siteID, false).Delete(&entity.SiteLanguage{}).Error; err != nil {
|
|
return err
|
|
}
|
|
confirmed := entity.SiteLanguage{SiteID: siteID, Lang: tag, IsDefault: true, Enabled: true, Confirmed: true}
|
|
return l.db.Create(&confirmed).Error
|
|
}
|
|
|
|
var _ domain.Repository = &LocalizationRepository{}
|