From c913a62778ae30331b883b47c559783fb47e54ca Mon Sep 17 00:00:00 2001 From: Max Date: Mon, 13 Jun 2022 20:43:36 +0800 Subject: [PATCH] [add] dump command --- cmd/dump.go | 200 ++++++++++++++++++++++++++++++++++++++++++++++++++++ cmd/root.go | 1 + 2 files changed, 201 insertions(+) create mode 100644 cmd/dump.go diff --git a/cmd/dump.go b/cmd/dump.go new file mode 100644 index 00000000..539c09de --- /dev/null +++ b/cmd/dump.go @@ -0,0 +1,200 @@ +package cmd + +import ( + "archive/zip" + "fmt" + "io/ioutil" + "os" + "path/filepath" + "strings" + "time" + + "github.com/fatih/color" + "github.com/spf13/cobra" + "github.com/yaoapp/gou" + "github.com/yaoapp/kun/exception" + "github.com/yaoapp/yao/config" + "github.com/yaoapp/yao/engine" +) + +var dumpModel string +var dumpCmd = &cobra.Command{ + Use: "dump", + Short: L("Dump the application data"), + Long: L("Dump the application data"), + Run: func(cmd *cobra.Command, args []string) { + defer func() { + err := exception.Catch(recover()) + if err != nil { + fmt.Println(color.RedString(L("Fatal: %s"), err.Error())) + } + }() + + Boot() + + path, err := filepath.Abs(".") + if err != nil { + fmt.Println(color.RedString(L("Fatal: %s"), err.Error())) + os.Exit(1) + } + + output := filepath.Join(fmt.Sprintf("%s-%s.zip", filepath.Base(path), time.Now().Format("20060102150405"))) + if len(args) > 0 { + output = args[0] + } + + output, err = filepath.Abs(output) + if err != nil { + fmt.Println(color.RedString(L("Fatal: %s"), err.Error())) + os.Exit(1) + } + + // Load model + err = engine.Load(config.Conf) + if err != nil { + fmt.Println(color.RedString(L("Fatal: %s"), err.Error())) + os.Exit(1) + } + + if dumpModel != "" { + mod, has := gou.Models[dumpModel] + if has { + mod.Migrate(true) + } + return + } + + // Export models + files := []string{} + for _, mod := range gou.Models { + + fmt.Printf("\r%s", color.GreenString(L("Export the models: %s (%s)"), mod.Name, mod.MetaData.Table.Name)) + jsonfiles, err := mod.Export(5000, func(curr, total int) { + fmt.Printf("\r%s", strings.Repeat(" ", 80)) + fmt.Printf("\r%s", color.GreenString(L("Export the models: %s (%s) %d/%d"), mod.Name, mod.MetaData.Table.Name, curr, total)) + }) + + if err != nil { + fmt.Println(color.RedString(L("Fatal: %s"), err.Error())) + os.Exit(1) + } + files = append(files, jsonfiles...) + } + fmt.Printf("\r%s", strings.Repeat(" ", 80)) + fmt.Printf("\r%s\n", color.GreenString(L("Export the models: ✨DONE✨"))) + + // Compress files + err = zipfiles(files, output, func(file string) { + fmt.Printf("\r%s", strings.Repeat(" ", 80)) + fmt.Printf("\r%s", color.GreenString(L("Compress the files: %s"), file)) + }) + fmt.Printf("\r%s", strings.Repeat(" ", 80)) + fmt.Printf("\r%s\n", color.GreenString(L("Compress the files: ✨DONE✨"))) + + if err != nil { + fmt.Println(color.RedString(L("Fatal: %s"), err.Error())) + os.Exit(1) + } + + fmt.Println(color.GreenString("File: %s", output)) + }, +} + +func init() { + dumpCmd.PersistentFlags().StringVarP(&dumpModel, "name", "n", "", L("Model name")) +} + +// gzipfiles +func zipfiles(files []string, output string, process func(file string)) error { + outpath := filepath.Dir(output) + os.MkdirAll(outpath, 0755) + + outfile, err := os.Create(output) + if err != nil { + fmt.Println(color.RedString(L("Fatal: %s"), err.Error())) + os.Exit(1) + } + defer outfile.Close() + + w := zip.NewWriter(outfile) + defer func() { + w.Close() + if err != nil { + fmt.Println(color.RedString(L("Fatal: %s"), err.Error())) + os.Exit(1) + } + }() + + for _, file := range files { + addFile(w, file, "model", process) + } + + // Add data path + dataPath := filepath.Join(config.Conf.Root, "data") + _, err = os.Stat(dataPath) + if err == nil { + addFolder(w, dataPath, "data", process) + } + + return nil +} + +func addFile(w *zip.Writer, file, baseInZip string, process func(file string)) { + process(filepath.Join(baseInZip, filepath.Base(file))) + dat, err := ioutil.ReadFile(file) + if err != nil { + fmt.Println(color.RedString(L("Fatal: %s"), err.Error())) + os.Exit(1) + } + + // Add some files to the archive. + f, err := w.Create(filepath.Join(baseInZip, filepath.Base(file))) + if err != nil { + fmt.Println(color.RedString(L("Fatal: %s"), err.Error())) + os.Exit(1) + } + _, err = f.Write(dat) + if err != nil { + fmt.Println(color.RedString(L("Fatal: %s"), err.Error())) + os.Exit(1) + } + + os.Remove(file) +} + +func addFolder(w *zip.Writer, basePath, baseInZip string, process func(file string)) { + + // Open the Directory + files, err := ioutil.ReadDir(basePath) + if err != nil { + fmt.Println(color.RedString(L("Fatal: %s"), err.Error())) + os.Exit(1) + } + + for _, file := range files { + process(filepath.Join(baseInZip, file.Name())) + if !file.IsDir() { + dat, err := ioutil.ReadFile(filepath.Join(basePath, file.Name())) + if err != nil { + fmt.Println(color.RedString(L("Fatal: %s"), err.Error())) + os.Exit(1) + } + + // Add some files to the archive. + f, err := w.Create(filepath.Join(baseInZip, file.Name())) + if err != nil { + fmt.Println(color.RedString(L("Fatal: %s"), err.Error())) + os.Exit(1) + } + _, err = f.Write(dat) + if err != nil { + fmt.Println(color.RedString(L("Fatal: %s"), err.Error())) + os.Exit(1) + } + } else if file.IsDir() { + // Recurse + newBase := filepath.Join(basePath, file.Name()) + addFolder(w, newBase, filepath.Join(baseInZip, file.Name()), process) + } + } +} diff --git a/cmd/root.go b/cmd/root.go index 1106e555..0da3979d 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -92,6 +92,7 @@ func init() { runCmd, initCmd, serviceCmd, + dumpCmd, ) // rootCmd.SetHelpCommand(helpCmd) rootCmd.PersistentFlags().StringVarP(&appPath, "app", "a", "", L("Application directory"))