feat(migrate): support migrate data to another storage

This commit is contained in:
iyear 2023-12-18 20:00:16 +08:00
parent 6470e57ff5
commit 8d4ce974d6
6 changed files with 90 additions and 23 deletions

View File

@ -1,4 +1,4 @@
package archive
package migrate
import (
"context"

44
app/migrate/migrate.go Normal file
View File

@ -0,0 +1,44 @@
package migrate
import (
"context"
"github.com/AlecAivazis/survey/v2"
"github.com/fatih/color"
"github.com/go-faster/errors"
"github.com/iyear/tdl/pkg/kv"
)
func Migrate(ctx context.Context, to map[string]string) error {
meta, err := kv.From(ctx).MigrateTo()
if err != nil {
return errors.Wrap(err, "read data")
}
dest, err := kv.NewWithMap(to)
if err != nil {
return errors.Wrap(err, "create dest storage")
}
var confirm bool
if err = survey.AskOne(&survey.Confirm{
Message: "It will overwrite the namespace data in the destination storage, continue?",
Default: false,
}, &confirm); err != nil {
return errors.Wrap(err, "confirm")
}
if !confirm {
return nil
}
if err = dest.MigrateFrom(meta); err != nil {
return errors.Wrap(err, "migrate from")
}
color.Green("Migrate successfully.")
for ns := range meta {
color.Green(" - %s", ns)
}
return nil
}

View File

@ -1,4 +1,4 @@
package archive
package migrate
import (
"bytes"

View File

@ -2,11 +2,13 @@ package cmd
import (
"fmt"
"strings"
"time"
"github.com/spf13/cobra"
"github.com/iyear/tdl/app/archive"
"github.com/iyear/tdl/app/migrate"
"github.com/iyear/tdl/pkg/kv"
)
func NewBackup() *cobra.Command {
@ -20,7 +22,7 @@ func NewBackup() *cobra.Command {
dst = fmt.Sprintf("%s.backup.tdl", time.Now().Format("2006-01-02-15_04_05"))
}
return archive.Backup(cmd.Context(), dst)
return migrate.Backup(cmd.Context(), dst)
},
}
@ -36,7 +38,7 @@ func NewRecover() *cobra.Command {
Use: "recover",
Short: "Recover your data",
RunE: func(cmd *cobra.Command, args []string) error {
return archive.Recover(cmd.Context(), file)
return migrate.Recover(cmd.Context(), file)
},
}
@ -50,3 +52,21 @@ func NewRecover() *cobra.Command {
return cmd
}
func NewMigrate() *cobra.Command {
var to map[string]string
cmd := &cobra.Command{
Use: "migrate",
Short: "Migrate your current data to another storage",
RunE: func(cmd *cobra.Command, args []string) error {
return migrate.Migrate(cmd.Context(), to)
},
}
cmd.Flags().StringToStringVar(&to, "to", map[string]string{},
fmt.Sprintf("destination storage options, format: type=driver,key1=value1,key2=value2. Available drivers: [%s]",
strings.Join(kv.DriverNames(), ",")))
return cmd
}

View File

@ -21,8 +21,6 @@ import (
)
func New() *cobra.Command {
driverTypeKey := "type"
cmd := &cobra.Command{
Use: "tdl",
Short: "Telegram Downloader, but more than a downloader",
@ -43,19 +41,7 @@ func New() *cobra.Command {
zap.String("namespace", ns))
}
// check storage flag
storageOpts := viper.GetStringMapString(consts.FlagStorage)
driver, err := kv.ParseDriver(storageOpts[driverTypeKey])
if err != nil {
return errors.Wrap(err, "parse driver")
}
delete(storageOpts, driverTypeKey)
opts := make(map[string]any)
for k, v := range storageOpts {
opts[k] = v
}
storage, err := kv.New(driver, opts)
storage, err := kv.NewWithMap(viper.GetStringMapString(consts.FlagStorage))
if err != nil {
return errors.Wrap(err, "create kv storage")
}
@ -72,11 +58,11 @@ func New() *cobra.Command {
}
cmd.AddCommand(NewVersion(), NewLogin(), NewDownload(), NewForward(),
NewChat(), NewUpload(), NewBackup(), NewRecover(), NewGen())
NewChat(), NewUpload(), NewBackup(), NewRecover(), NewMigrate(), NewGen())
cmd.PersistentFlags().StringToString(consts.FlagStorage, map[string]string{
driverTypeKey: kv.DriverLegacy.String(),
"path": consts.KVPath,
kv.DriverTypeKey: kv.DriverLegacy.String(),
"path": consts.KVPath,
}, fmt.Sprintf("storage options, format: type=driver,key1=value1,key2=value2. Available drivers: [%s]",
strings.Join(kv.DriverNames(), ",")))

View File

@ -13,6 +13,8 @@ import (
// ENUM(legacy, bolt, file)
type Driver string
const DriverTypeKey = "type"
var ErrNotFound = errors.New("key not found")
type Meta map[string]map[string][]byte // namespace, key, value
@ -46,6 +48,21 @@ func New(driver Driver, opts map[string]any) (Storage, error) {
return nil, errors.Errorf("unsupported driver: %s", driver)
}
func NewWithMap(o map[string]string) (Storage, error) {
driver, err := ParseDriver(o[DriverTypeKey])
if err != nil {
return nil, errors.Wrap(err, "parse driver")
}
delete(o, DriverTypeKey)
opts := make(map[string]any)
for k, v := range o {
opts[k] = v
}
return New(driver, opts)
}
type ctxKey struct{}
func With(ctx context.Context, kv Storage) context.Context {