100 lines
3.1 KiB
Go
100 lines
3.1 KiB
Go
package archivable
|
|
|
|
import (
|
|
"context"
|
|
|
|
"github.com/tech/sendico/pkg/db/repository"
|
|
"github.com/tech/sendico/pkg/db/storable"
|
|
"github.com/tech/sendico/pkg/mlogger"
|
|
"github.com/tech/sendico/pkg/model"
|
|
"github.com/tech/sendico/pkg/mutil/mzap"
|
|
"go.mongodb.org/mongo-driver/bson/primitive"
|
|
"go.uber.org/zap"
|
|
)
|
|
|
|
// ArchivableDB implements archive management for entities with model.Archivable embedded
|
|
type ArchivableDB[T storable.Storable] struct {
|
|
repo repository.Repository
|
|
logger mlogger.Logger
|
|
createEmpty func() T
|
|
getArchivable func(T) model.Archivable
|
|
}
|
|
|
|
// NewArchivableDB creates a new ArchivableDB instance
|
|
func NewArchivableDB[T storable.Storable](
|
|
repo repository.Repository,
|
|
logger mlogger.Logger,
|
|
createEmpty func() T,
|
|
getArchivable func(T) model.Archivable,
|
|
) *ArchivableDB[T] {
|
|
return &ArchivableDB[T]{
|
|
repo: repo,
|
|
logger: logger,
|
|
createEmpty: createEmpty,
|
|
getArchivable: getArchivable,
|
|
}
|
|
}
|
|
|
|
// SetArchived sets the archived status of an entity
|
|
func (db *ArchivableDB[T]) SetArchived(ctx context.Context, objectRef primitive.ObjectID, archived bool) error {
|
|
// Get current object to check current archived status
|
|
obj := db.createEmpty()
|
|
if err := db.repo.Get(ctx, objectRef, obj); err != nil {
|
|
db.logger.Warn("Failed to get object for setting archived status",
|
|
zap.Error(err),
|
|
mzap.ObjRef("object_ref", objectRef),
|
|
zap.Bool("archived", archived))
|
|
return err
|
|
}
|
|
|
|
// Extract archivable from the object
|
|
archivable := db.getArchivable(obj)
|
|
currentArchived := archivable.IsArchived()
|
|
if currentArchived == archived {
|
|
db.logger.Debug("No change needed - same archived status",
|
|
mzap.ObjRef("object_ref", objectRef),
|
|
zap.Bool("archived", archived))
|
|
return nil // No change needed
|
|
}
|
|
|
|
// Set the archived status
|
|
patch := repository.Patch().Set(repository.IsArchivedField(), archived)
|
|
if err := db.repo.Patch(ctx, objectRef, patch); err != nil {
|
|
db.logger.Warn("Failed to set archived status on object",
|
|
zap.Error(err),
|
|
mzap.ObjRef("object_ref", objectRef),
|
|
zap.Bool("archived", archived))
|
|
return err
|
|
}
|
|
|
|
db.logger.Debug("Successfully set archived status on object",
|
|
mzap.ObjRef("object_ref", objectRef),
|
|
zap.Bool("archived", archived))
|
|
return nil
|
|
}
|
|
|
|
// IsArchived checks if an entity is archived
|
|
func (db *ArchivableDB[T]) IsArchived(ctx context.Context, objectRef primitive.ObjectID) (bool, error) {
|
|
obj := db.createEmpty()
|
|
|
|
if err := db.repo.Get(ctx, objectRef, obj); err != nil {
|
|
db.logger.Warn("Failed to get object for checking archived status",
|
|
zap.Error(err),
|
|
mzap.ObjRef("object_ref", objectRef))
|
|
return false, err
|
|
}
|
|
|
|
archivable := db.getArchivable(obj)
|
|
return archivable.IsArchived(), nil
|
|
}
|
|
|
|
// Archive archives an entity (sets archived to true)
|
|
func (db *ArchivableDB[T]) Archive(ctx context.Context, objectRef primitive.ObjectID) error {
|
|
return db.SetArchived(ctx, objectRef, true)
|
|
}
|
|
|
|
// Unarchive unarchives an entity (sets archived to false)
|
|
func (db *ArchivableDB[T]) Unarchive(ctx context.Context, objectRef primitive.ObjectID) error {
|
|
return db.SetArchived(ctx, objectRef, false)
|
|
}
|