Updated Sync functions to perform proper synchronizations instead of pure downloads. This means that if something is deleted on the server, it will be deleted on the client as well, instead of just left hanging. The SyncProclamations function was also updated to perform this way, but while retaining the user's saved list.
100 lines
2.9 KiB
Go
100 lines
2.9 KiB
Go
package sync
|
|
|
|
import (
|
|
"regexp"
|
|
|
|
"gorm.io/gorm"
|
|
"rhemawavetech.com/rhemawave/internal/db"
|
|
"rhemawavetech.com/rhemawave/internal/logger"
|
|
"rhemawavetech.com/rhemawave/internal/netreq"
|
|
)
|
|
|
|
var htmlRegex = regexp.MustCompile(`<[^>]*>`)
|
|
|
|
// SyncProclamations fetches data from the API, cleans it, and updates the local DB.
|
|
// It returns the slice of proclamations so the UI can update immediately.
|
|
func SyncProclamations(database *gorm.DB) ([]db.Proclamation, error) {
|
|
fullURL := "https://portal.rhemawavetech.com/api/v1/proclamations"
|
|
logger.Debug("Syncronizing proclamations. URL: %s", fullURL)
|
|
|
|
proclamations, err := netreq.GetJSON[db.Proclamation](fullURL)
|
|
if err != nil {
|
|
// If we're offline or API is down, we log it but don't crash.
|
|
// The UI can still use whatever is currently in the DB.
|
|
logger.Error("Proclamation sync failed, skipping update: %v", err)
|
|
return nil, err
|
|
}
|
|
logger.Debug("Request Granted")
|
|
|
|
for i := range proclamations {
|
|
proclamations[i].Content = htmlRegex.ReplaceAllString(proclamations[i].Content, "")
|
|
}
|
|
|
|
var storedProclamationSettings []db.Proclamation
|
|
database.Select("ID", "Selected").Find(&storedProclamationSettings)
|
|
// [ID]Selected
|
|
stash := make(map[string]bool)
|
|
for _, row := range storedProclamationSettings {
|
|
stash[row.ID] = row.Selected
|
|
}
|
|
|
|
for i := range proclamations {
|
|
proclamations[i].Selected = stash[proclamations[i].ID]
|
|
}
|
|
|
|
err = database.Transaction(func(tx *gorm.DB) error {
|
|
// Clear the database
|
|
// Where "1 = 1" because batch Delete() requires a condition
|
|
// 'Where "1 = 1"' is like saying "while true be true" and tricks GORM into deleting everything
|
|
if err := tx.Where("1 = 1").Delete(db.Proclamation{}).Error; err != nil {
|
|
return err
|
|
}
|
|
// Then re-populate the database
|
|
if err := tx.Save(&proclamations).Error; err != nil {
|
|
return err
|
|
}
|
|
// Old sync code
|
|
// if err := tx.Omit("selected").Save(&proclamations).Error; err != nil {
|
|
// return err
|
|
// }
|
|
return nil
|
|
})
|
|
|
|
logger.Debug("Proclamations stored to database")
|
|
|
|
if err != nil {
|
|
logger.Error("Failed to save synced proclamations: %v", err)
|
|
return nil, err
|
|
}
|
|
|
|
logger.Info("Successfully synced proclamations: %d", len(proclamations))
|
|
return proclamations, nil
|
|
}
|
|
|
|
func SyncCategories(database *gorm.DB) ([]db.ProclamationCategory, error) {
|
|
fullURL := "https://portal.rhemawavetech.com/api/v1/categories"
|
|
categories, err := netreq.GetJSON[db.ProclamationCategory](fullURL)
|
|
if err != nil {
|
|
logger.Error("Category sync failed, skipping update: %v", err)
|
|
return nil, err
|
|
}
|
|
|
|
err = database.Transaction(func(tx *gorm.DB) error {
|
|
if err := tx.Where("1 = 1").Delete(&db.ProclamationCategory{}).Error; err != nil {
|
|
return err
|
|
}
|
|
if err := tx.Save(&categories).Error; err != nil {
|
|
return err
|
|
}
|
|
return nil
|
|
})
|
|
|
|
if err != nil {
|
|
logger.Error("failed to sync proclamation categories: %v", err)
|
|
return nil, err
|
|
}
|
|
|
|
logger.Info("Successfully synced proclamation categories: %d", len(categories))
|
|
return categories, nil
|
|
}
|