package store import ( "context" "github.com/alcionai/clues" "github.com/kopia/kopia/repo/manifest" "github.com/alcionai/corso/src/internal/model" "github.com/alcionai/corso/src/pkg/backup" "github.com/alcionai/corso/src/pkg/path" ) type queryFilters struct { tags map[string]string } type FilterOption func(*queryFilters) func (q *queryFilters) populate(qf ...FilterOption) { if len(qf) == 0 { return } q.tags = map[string]string{} for _, fn := range qf { fn(q) } } // Service ensures the retrieved backups only match // the specified service. func Service(pst path.ServiceType) FilterOption { return func(qf *queryFilters) { qf.tags[model.ServiceTag] = pst.String() } } type ( BackupWrapper interface { BackupGetterDeleter GetBackups( ctx context.Context, filters ...FilterOption, ) ([]*backup.Backup, error) } BackupGetterDeleter interface { BackupGetter BackupDeleter } BackupGetter interface { GetBackup(ctx context.Context, backupID model.StableID) (*backup.Backup, error) } BackupDeleter interface { DeleteBackup(ctx context.Context, backupID model.StableID) error } ModelDeleter interface { DeleteWithModelStoreIDs(ctx context.Context, ids ...manifest.ID) error } BackupGetterModelDeleter interface { BackupGetter ModelDeleter } Storer interface { Delete(ctx context.Context, s model.Schema, id model.StableID) error Get(ctx context.Context, s model.Schema, id model.StableID, data model.Model) error GetIDsForType(ctx context.Context, s model.Schema, tags map[string]string) ([]*model.BaseModel, error) GetWithModelStoreID(ctx context.Context, s model.Schema, id manifest.ID, data model.Model) error Put(ctx context.Context, s model.Schema, m model.Model) error Update(ctx context.Context, s model.Schema, m model.Model) error ModelDeleter } BackupStorer interface { Storer BackupWrapper } ) type wrapper struct { Storer } func NewWrapper(s Storer) *wrapper { return &wrapper{Storer: s} } // GetBackup gets a single backup by id. func (w wrapper) GetBackup(ctx context.Context, backupID model.StableID) (*backup.Backup, error) { b := backup.Backup{} err := w.Get(ctx, model.BackupSchema, backupID, &b) if err != nil { return nil, clues.Wrap(err, "getting backup") } return &b, nil } // GetDetailsFromBackupID retrieves all backups in the model store. func (w wrapper) GetBackups( ctx context.Context, filters ...FilterOption, ) ([]*backup.Backup, error) { q := &queryFilters{} q.populate(filters...) bms, err := w.GetIDsForType(ctx, model.BackupSchema, q.tags) if err != nil { return nil, err } bs := make([]*backup.Backup, len(bms)) for i, bm := range bms { b := &backup.Backup{} err := w.GetWithModelStoreID(ctx, model.BackupSchema, bm.ModelStoreID, b) if err != nil { return nil, err } bs[i] = b } return bs, nil } // DeleteBackup deletes the backup and its details entry from the model store. func (w wrapper) DeleteBackup(ctx context.Context, backupID model.StableID) error { return w.Delete(ctx, model.BackupSchema, backupID) }