aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBobby <[email protected]>2026-02-09 13:38:49 +0530
committerBobby <[email protected]>2026-02-09 13:38:49 +0530
commitdd17b2c4ccf8f2cfc38a02a15d33ba8b40b665ac (patch)
treeb9d867b3e41261807311732cb1d1b3d0cade09c5
parent185d84e2dbe18dca60592bb33f491c5cd3d09403 (diff)
downloadmetachan-dd17b2c4ccf8f2cfc38a02a15d33ba8b40b665ac.tar.xz
metachan-dd17b2c4ccf8f2cfc38a02a15d33ba8b40b665ac.zip
Refactor BatchCreateProducers: implement transaction handling and improve error logging; add title and external URL associations
-rw-r--r--repositories/producer.go47
-rw-r--r--tasks/producersync.task.go39
2 files changed, 75 insertions, 11 deletions
diff --git a/repositories/producer.go b/repositories/producer.go
index 946d873..53deefe 100644
--- a/repositories/producer.go
+++ b/repositories/producer.go
@@ -5,7 +5,6 @@ import (
"metachan/entities"
"metachan/utils/logger"
- "gorm.io/gorm"
"gorm.io/gorm/clause"
)
@@ -30,17 +29,43 @@ func BatchCreateProducers(producers []entities.Producer) error {
return nil
}
- result := DB.Session(&gorm.Session{FullSaveAssociations: true}).Clauses(clause.OnConflict{
- Columns: []clause.Column{{Name: "mal_id"}},
- DoUpdates: clause.AssignmentColumns([]string{
- "url", "favorites", "count", "established", "about", "image_id",
- }),
- }).CreateInBatches(&producers, 100)
+ tx := DB.Begin()
+ defer func() {
+ if r := recover(); r != nil {
+ tx.Rollback()
+ }
+ }()
- if result.Error != nil {
- logger.Errorf("Producer", "Failed to batch create producers: %v", result.Error)
- return errors.New("failed to batch create producers")
+ for i := range producers {
+ result := tx.Clauses(clause.OnConflict{
+ Columns: []clause.Column{{Name: "mal_id"}},
+ DoUpdates: clause.AssignmentColumns([]string{
+ "url", "favorites", "count", "established", "about", "image_id",
+ }),
+ }).Omit("Titles", "ExternalURLs").Create(&producers[i])
+
+ if result.Error != nil {
+ tx.Rollback()
+ logger.Errorf("Producer", "Failed to create producer %d: %v", producers[i].MALID, result.Error)
+ return errors.New("failed to batch create producers")
+ }
+
+ if len(producers[i].Titles) > 0 {
+ if err := tx.Model(&producers[i]).Association("Titles").Replace(producers[i].Titles); err != nil {
+ tx.Rollback()
+ logger.Errorf("Producer", "Failed to associate titles for producer %d: %v", producers[i].MALID, err)
+ return errors.New("failed to batch create producers")
+ }
+ }
+
+ if len(producers[i].ExternalURLs) > 0 {
+ if err := tx.Model(&producers[i]).Association("ExternalURLs").Replace(producers[i].ExternalURLs); err != nil {
+ tx.Rollback()
+ logger.Errorf("Producer", "Failed to associate external URLs for producer %d: %v", producers[i].MALID, err)
+ return errors.New("failed to batch create producers")
+ }
+ }
}
- return nil
+ return tx.Commit().Error
}
diff --git a/tasks/producersync.task.go b/tasks/producersync.task.go
index 6949e70..8c8bb79 100644
--- a/tasks/producersync.task.go
+++ b/tasks/producersync.task.go
@@ -94,6 +94,25 @@ func ProducerSync() error {
}
}
+ titleMap := make(map[string]entities.SimpleTitle)
+ for _, pd := range producersData {
+ for _, title := range pd.producer.Titles {
+ key := title.Type + ":" + title.Title
+ titleMap[key] = title
+ }
+ }
+
+ if len(titleMap) > 0 {
+ titles := make([]entities.SimpleTitle, 0, len(titleMap))
+ for _, title := range titleMap {
+ titles = append(titles, title)
+ }
+ if err := repositories.BatchCreateSimpleTitles(titles); err != nil {
+ logger.Errorf("ProducerSync", "Failed to batch insert titles: %v", err)
+ return err
+ }
+ }
+
var dbImages []entities.SimpleImage
if err := repositories.DB.Select("id, image_url").Find(&dbImages).Error; err != nil {
logger.Errorf("ProducerSync", "Failed to query images: %v", err)
@@ -105,6 +124,18 @@ func ProducerSync() error {
imageIDMap[img.ImageURL] = img.ID
}
+ var dbTitles []entities.SimpleTitle
+ if err := repositories.DB.Select("id, type, title").Find(&dbTitles).Error; err != nil {
+ logger.Errorf("ProducerSync", "Failed to query titles: %v", err)
+ return err
+ }
+
+ titleIDMap := make(map[string]uint)
+ for _, title := range dbTitles {
+ key := title.Type + ":" + title.Title
+ titleIDMap[key] = title.ID
+ }
+
producers := make([]entities.Producer, 0, len(producersData))
for _, pd := range producersData {
if pd.imageURL != "" {
@@ -112,6 +143,14 @@ func ProducerSync() error {
pd.producer.ImageID = &id
}
}
+
+ for i := range pd.producer.Titles {
+ key := pd.producer.Titles[i].Type + ":" + pd.producer.Titles[i].Title
+ if id, exists := titleIDMap[key]; exists {
+ pd.producer.Titles[i].ID = id
+ }
+ }
+
producers = append(producers, pd.producer)
}