diff options
| author | Bobby <[email protected]> | 2026-02-09 13:38:49 +0530 |
|---|---|---|
| committer | Bobby <[email protected]> | 2026-02-09 13:38:49 +0530 |
| commit | dd17b2c4ccf8f2cfc38a02a15d33ba8b40b665ac (patch) | |
| tree | b9d867b3e41261807311732cb1d1b3d0cade09c5 | |
| parent | 185d84e2dbe18dca60592bb33f491c5cd3d09403 (diff) | |
| download | metachan-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.go | 47 | ||||
| -rw-r--r-- | tasks/producersync.task.go | 39 |
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) } |
