refac: migration crash, real-database tests, site deleted during create, ruels out of the repo, lists
This commit is contained in:
1 parent
680b9a1308
commit
9d284e65a9
62 files changed
+1858
-987
No files matched your search
@@ -375,10 +375,7 @@ func (a *ArticleRepository) Create(article domain.Article) (domain.Article, erro
|
||||
return err
|
||||
}
|
||||
}
|
||||
if err := ensureStoryLanguageFree(tx, created.StoryID, created.Lang); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := ensureSlugFree(tx, created.SiteID, created.Lang, created.Slug, 0); err != nil {
|
||||
if err := requireStory(tx, created.StoryID); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := openStory(tx, &created); err != nil {
|
||||
@@ -390,12 +387,12 @@ func (a *ArticleRepository) Create(article domain.Article) (domain.Article, erro
|
||||
return replaceCredits(tx, created.ID, authordomain.BylineIDs(article.Authors))
|
||||
})
|
||||
if err != nil {
|
||||
return domain.Article{}, a.explainSlugFailure(created.SiteID, created.Lang, created.Slug, 0, err)
|
||||
return domain.Article{}, a.explainUniqueViolation(created, 0, err)
|
||||
}
|
||||
return a.withAuthorsOne(a.db, mappers.ArticleToDomain(created))
|
||||
}
|
||||
|
||||
func ensureStoryLanguageFree(tx *gorm.DB, storyID uint32, lang string) error {
|
||||
func requireStory(tx *gorm.DB, storyID uint32) error {
|
||||
if storyID == 0 {
|
||||
return nil
|
||||
}
|
||||
@@ -406,13 +403,6 @@ func ensureStoryLanguageFree(tx *gorm.DB, storyID uint32, lang string) error {
|
||||
if stories == 0 {
|
||||
return domain.ErrArticleNotFound
|
||||
}
|
||||
var versions int64
|
||||
if err := tx.Model(&entity.Article{}).Where("story_id = ? AND lang = ?", storyID, lang).Count(&versions).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
if versions > 0 {
|
||||
return domain.ErrLanguageTaken
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -434,26 +424,21 @@ func articleSlugInLanguage(db *gorm.DB, siteID uint32, lang string, slug string,
|
||||
return total > 0, err
|
||||
}
|
||||
|
||||
func ensureSlugFree(db *gorm.DB, siteID uint32, lang string, slug string, exceptID uint32) error {
|
||||
if slug == "" {
|
||||
return nil
|
||||
}
|
||||
taken, err := articleSlugInLanguage(db, siteID, lang, slug, exceptID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if taken {
|
||||
return domain.ErrSlugTaken
|
||||
}
|
||||
return nil
|
||||
func storyLanguageInUse(db *gorm.DB, storyID uint32, lang string, exceptID uint32) (bool, error) {
|
||||
var total int64
|
||||
err := db.Unscoped().Model(&entity.Article{}).Where("story_id = ? AND lang = ? AND retired_id = ? AND id <> ?", storyID, lang, 0, exceptID).Count(&total).Error
|
||||
return total > 0, err
|
||||
}
|
||||
|
||||
func (a *ArticleRepository) explainSlugFailure(siteID uint32, lang string, slug string, exceptID uint32, cause error) error {
|
||||
if errors.Is(cause, domain.ErrSlugTaken) {
|
||||
func (a *ArticleRepository) explainUniqueViolation(written entity.Article, exceptID uint32, cause error) error {
|
||||
if !database.IsUniqueViolation(a.db, cause) {
|
||||
return cause
|
||||
}
|
||||
if err := ensureSlugFree(a.db, siteID, lang, slug, exceptID); err != nil && errors.Is(err, domain.ErrSlugTaken) {
|
||||
return err
|
||||
if taken, err := articleSlugInLanguage(a.db, written.SiteID, written.Lang, written.Slug, exceptID); err == nil && taken {
|
||||
return domain.ErrSlugTaken
|
||||
}
|
||||
if taken, err := storyLanguageInUse(a.db, written.StoryID, written.Lang, exceptID); err == nil && taken {
|
||||
return domain.ErrLanguageTaken
|
||||
}
|
||||
return cause
|
||||
}
|
||||
@@ -528,11 +513,6 @@ func (a *ArticleRepository) updateAt(id uint32, update domain.Update, probedSite
|
||||
}
|
||||
before := localArticle
|
||||
applyUpdate(&localArticle, update)
|
||||
if update.Slug != nil || update.SiteID != nil {
|
||||
if err := ensureSlugFree(tx, localArticle.SiteID, localArticle.Lang, localArticle.Slug, id); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
authorsChanged, err := authorsDiffer(tx, id, update.AuthorIDs)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -554,7 +534,7 @@ func (a *ArticleRepository) updateAt(id uint32, update domain.Update, probedSite
|
||||
return domain.Article{}, err
|
||||
}
|
||||
if err != nil {
|
||||
return domain.Article{}, a.explainSlugFailure(localArticle.SiteID, localArticle.Lang, localArticle.Slug, id, err)
|
||||
return domain.Article{}, a.explainUniqueViolation(localArticle, id, err)
|
||||
}
|
||||
return a.withAuthorsOne(a.db, mappers.ArticleToDomain(localArticle))
|
||||
}
|
||||
@@ -722,15 +702,13 @@ func (a *ArticleRepository) ListByStory(storyID uint32) ([]domain.Article, error
|
||||
}
|
||||
|
||||
func (a *ArticleRepository) MoveToSite(ids []uint32, siteID uint32) error {
|
||||
return a.db.Transaction(func(tx *gorm.DB) error {
|
||||
var moving entity.Article
|
||||
err := a.db.Transaction(func(tx *gorm.DB) error {
|
||||
for _, id := range ids {
|
||||
var moving entity.Article
|
||||
moving = entity.Article{}
|
||||
if err := tx.First(&moving, id).Error; err != nil {
|
||||
return mapNotFoundErr(err, domain.ErrArticleNotFound)
|
||||
}
|
||||
if err := ensureSlugFree(tx, siteID, moving.Lang, moving.Slug, id); err != nil {
|
||||
return err
|
||||
}
|
||||
moved := map[string]any{"site_id": siteID, "edit_revision": gorm.Expr("edit_revision + 1")}
|
||||
if err := tx.Model(&entity.Article{}).Where("id = ?", id).Updates(moved).Error; err != nil {
|
||||
return err
|
||||
@@ -738,6 +716,11 @@ func (a *ArticleRepository) MoveToSite(ids []uint32, siteID uint32) error {
|
||||
}
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
moving.SiteID = siteID
|
||||
return a.explainUniqueViolation(moving, moving.ID, err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (a *ArticleRepository) FindByBodyContaining(filename string) ([]domain.Article, error) {
|
||||
|
||||
Reference in new issue
Block a user