158 lines
3.5 KiB
Go
158 lines
3.5 KiB
Go
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()
|
|
}
|
|
}
|
|
|
|
func Reason(service path.ServiceType, category path.CategoryType) FilterOption {
|
|
return func(qf *queryFilters) {
|
|
qf.tags[backup.ServiceCatString(service, category)] = backup.DefaultTagValue
|
|
}
|
|
}
|
|
|
|
func Tenant(tenant string) FilterOption {
|
|
return func(qf *queryFilters) {
|
|
qf.tags[backup.TenantIDKey] = tenant
|
|
}
|
|
}
|
|
|
|
func ProtectedResource(resourceID string) FilterOption {
|
|
return func(qf *queryFilters) {
|
|
qf.tags[backup.ResourceIDKey] = resourceID
|
|
}
|
|
}
|
|
|
|
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)
|
|
}
|