You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@shardingsphere.apache.org by mi...@apache.org on 2023/02/22 09:17:38 UTC

[shardingsphere-on-cloud] branch main updated: feat(pitr):cli storage,write to file by json extension (#222)

This is an automated email from the ASF dual-hosted git repository.

miaoliyao pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/shardingsphere-on-cloud.git


The following commit(s) were added to refs/heads/main by this push:
     new fb02f71  feat(pitr):cli storage,write to file by json extension (#222)
fb02f71 is described below

commit fb02f715daec22d1a79659f16b8dd89f3b750f19
Author: lltgo <ll...@outlook.com>
AuthorDate: Wed Feb 22 17:17:33 2023 +0800

    feat(pitr):cli storage,write to file by json extension (#222)
    
    * feat(pitr):cli storage,write to file by json extension
    
    * chore:update comments
---
 pitr/cli/internal/pkg/local-storage.go             | 100 ++++++++++++++++++---
 pitr/cli/internal/pkg/local-storage_test.go        |  32 +++++--
 .../stringutil/rand_string.go}                     |  53 +++++++----
 .../stringutil/rand_string_test.go}                |  35 +++-----
 .../stringutil/strutil_test.go}                    |  23 ++---
 5 files changed, 167 insertions(+), 76 deletions(-)

diff --git a/pitr/cli/internal/pkg/local-storage.go b/pitr/cli/internal/pkg/local-storage.go
index 141bfda..329fa76 100644
--- a/pitr/cli/internal/pkg/local-storage.go
+++ b/pitr/cli/internal/pkg/local-storage.go
@@ -18,51 +18,123 @@
 package pkg
 
 import (
+	"encoding/json"
 	"fmt"
 	"os"
+	"strings"
+	"time"
+
+	strutil "github.com/apache/shardingsphere-on-cloud/pitr/cli/pkg/stringutil"
 )
 
 type (
-	localStorage struct{}
+	localStorage struct {
+		rootDir   string
+		backupDir string
+	}
 
 	ILocalStorage interface {
-		Init(dirName string) error
+		init() error
+		WriteByJSON(name string, contents anyStruct) error
+		GenFilename(extn extension) string
 	}
+
+	anyStruct any
+
+	extension string
 )
 
-func (ls *localStorage) Init(root string) error {
+const (
+	ExtnJSON extension = "JOSN"
+)
+
+func NewLocalStorage(root string) (ILocalStorage, error) {
+	ls := &localStorage{
+		rootDir:   root,
+		backupDir: fmt.Sprintf("%s/%s", root, "backup"),
+	}
+
+	if err := ls.init(); err != nil {
+		return nil, err
+	}
+
+	return ls, nil
+}
+
+func (ls *localStorage) init() error {
 	// root dir
-	fi, err := os.Stat(root)
+	fi, err := os.Stat(ls.rootDir)
 	if err != nil {
 		if os.IsNotExist(err) {
-			if err := os.Mkdir(root, 0777); err != nil {
-				return fmt.Errorf("create root dir failure,dir=%s,err=%s", root, err)
+			if err := os.Mkdir(ls.rootDir, 0777); err != nil {
+				return fmt.Errorf("create root dir failure,dir=%s,err=%s", ls.rootDir, err)
 			}
 		} else if os.IsExist(err) {
 			if !fi.IsDir() {
-				return fmt.Errorf("file has already exist,name=%s", root)
+				return fmt.Errorf("file has already exist,name=%s", ls.rootDir)
 			}
 		} else {
-			return fmt.Errorf("failed to get file info,root dir=%s,err=%s", root, err)
+			return fmt.Errorf("failed to get file info,root dir=%s,err=%s", ls.rootDir, err)
 		}
 	}
 
 	// backup dir
-	backup := fmt.Sprintf("%s/%s", root, "backup")
-	fi, err = os.Stat(backup)
+	fi, err = os.Stat(ls.backupDir)
 	if err != nil {
 		if os.IsNotExist(err) {
-			if err := os.Mkdir(backup, 0777); err != nil {
-				return fmt.Errorf("create root dir failure,dir=%s,err=%s", backup, err)
+			if err := os.Mkdir(ls.backupDir, 0777); err != nil {
+				return fmt.Errorf("create backup dir failure,dir=%s,err=%s", ls.backupDir, err)
 			}
 		} else if os.IsExist(err) {
 			if !fi.IsDir() {
-				return fmt.Errorf("file has already exist,name=%s", backup)
+				return fmt.Errorf("backup:file has already exist,name=%s", ls.backupDir)
 			}
 		} else {
-			return fmt.Errorf("failed to get file info,root dir=%s,err=%s", backup, err)
+			return fmt.Errorf("failed to get file info,backup dir=%s,err=%s", ls.backupDir, err)
 		}
 	}
 
 	return nil
 }
+
+func (ls *localStorage) WriteByJSON(name string, contents anyStruct) error {
+	if !strings.HasSuffix(name, ".json") {
+		return fmt.Errorf("wrong file extension,file name is %s", name)
+	}
+
+	data, err := json.MarshalIndent(contents, "", "  ")
+	if err != nil {
+		return err
+	}
+
+	path := fmt.Sprintf("%s/%s", ls.backupDir, name)
+	fi, err := os.Create(path)
+	if err != nil {
+		return fmt.Errorf("create file failure,file path is %s", path)
+	}
+
+	_, err = fi.Write(data)
+	if err != nil {
+		return fmt.Errorf("write to file failure,err=%s,data is %s", err, data)
+	}
+
+	return nil
+}
+
+/*
+GenFilename gen a filename based on the file extension
+
+	if extn is empty,return a postfix-free filename
+	if extn=JSON,return the JSON filename like **.json
+*/
+func (ls *localStorage) GenFilename(extn extension) string {
+	prefix := time.Now().UTC().Format("20060102150405")
+	suffix := strutil.Random(8)
+
+	switch extn {
+	case ExtnJSON:
+		return fmt.Sprintf("%s_%s.json", prefix, suffix)
+	default:
+		return fmt.Sprintf("%s_%s", prefix, suffix)
+	}
+}
diff --git a/pitr/cli/internal/pkg/local-storage_test.go b/pitr/cli/internal/pkg/local-storage_test.go
index 9b691fc..a691ff1 100644
--- a/pitr/cli/internal/pkg/local-storage_test.go
+++ b/pitr/cli/internal/pkg/local-storage_test.go
@@ -27,14 +27,34 @@ import (
 
 var _ = Describe("ILocalStorage", func() {
 	Context("localStorage", func() {
-		It("Init:Initialize the cli program directory.", func() {
+		It("New:Initialize the cli program directory.", func() {
 			Skip("Manually exec:dependent environment")
-			var (
-				root = fmt.Sprintf("%s/%s", os.Getenv("HOME"), ".gs_pitr")
-				ls   = &localStorage{}
-			)
+			root := fmt.Sprintf("%s/%s", os.Getenv("HOME"), ".gs_pitr")
+			ls, err := NewLocalStorage(root)
+			Expect(err).To(BeNil())
+			Expect(ls).NotTo(BeNil())
+		})
+
+		It("GenFilename and WriteByJSON", func() {
+			Skip("Manually exec:dependent environment")
+			root := fmt.Sprintf("%s/%s", os.Getenv("HOME"), ".gs_pitr")
+			ls, err := NewLocalStorage(root)
+			Expect(err).To(BeNil())
+			Expect(ls).NotTo(BeNil())
+
+			filename := ls.GenFilename(ExtnJSON)
+			Expect(filename).NotTo(BeEmpty())
+
+			type T struct {
+				Name string
+				Age  uint8
+			}
 
-			err := ls.Init(root)
+			contents := T{
+				Name: "Pikachu",
+				Age:  65,
+			}
+			err = ls.WriteByJSON(filename, contents)
 			Expect(err).To(BeNil())
 		})
 	})
diff --git a/pitr/cli/internal/pkg/local-storage_test.go b/pitr/cli/pkg/stringutil/rand_string.go
similarity index 51%
copy from pitr/cli/internal/pkg/local-storage_test.go
copy to pitr/cli/pkg/stringutil/rand_string.go
index 9b691fc..769b7b7 100644
--- a/pitr/cli/internal/pkg/local-storage_test.go
+++ b/pitr/cli/pkg/stringutil/rand_string.go
@@ -15,27 +15,44 @@
 * limitations under the License.
  */
 
-package pkg
+package strutil
 
 import (
-	"fmt"
-	"os"
+	"math/rand"
+	"strconv"
+	"time"
+)
+
+const (
+	charSet  = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
+	charSize = len(charSet)
+)
 
-	. "github.com/onsi/ginkgo/v2"
-	. "github.com/onsi/gomega"
+const (
+	digitSet  = "1234567890"
+	digitSize = len(digitSet)
 )
 
-var _ = Describe("ILocalStorage", func() {
-	Context("localStorage", func() {
-		It("Init:Initialize the cli program directory.", func() {
-			Skip("Manually exec:dependent environment")
-			var (
-				root = fmt.Sprintf("%s/%s", os.Getenv("HOME"), ".gs_pitr")
-				ls   = &localStorage{}
-			)
+func Random(n uint) string {
+	rand.Seed(time.Now().UnixNano())
+	bs := make([]byte, 0, n)
+	for i := uint(0); i < n; i++ {
+		bs = append(bs, charSet[rand.Intn(charSize)])
+	}
+	return string(bs)
+}
+
+func RandomInt(n uint) int64 {
+	rand.Seed(time.Now().UnixNano())
+	bs := make([]byte, 0, n)
+	bs = append(bs, digitSet[rand.Intn(digitSize-1)])
+	for i := uint(0); i < n-1; i++ {
+		bs = append(bs, digitSet[rand.Intn(digitSize)])
+	}
+	v, _ := strconv.ParseInt(string(bs), 10, 64)
+	return v
+}
 
-			err := ls.Init(root)
-			Expect(err).To(BeNil())
-		})
-	})
-})
+func RandomUint(n uint) uint64 {
+	return uint64(RandomInt(n))
+}
diff --git a/pitr/cli/internal/pkg/local-storage_test.go b/pitr/cli/pkg/stringutil/rand_string_test.go
similarity index 63%
copy from pitr/cli/internal/pkg/local-storage_test.go
copy to pitr/cli/pkg/stringutil/rand_string_test.go
index 9b691fc..f2e3720 100644
--- a/pitr/cli/internal/pkg/local-storage_test.go
+++ b/pitr/cli/pkg/stringutil/rand_string_test.go
@@ -15,27 +15,20 @@
 * limitations under the License.
  */
 
-package pkg
+package strutil
 
-import (
-	"fmt"
-	"os"
+import "testing"
 
-	. "github.com/onsi/ginkgo/v2"
-	. "github.com/onsi/gomega"
-)
+func TestRandom(t *testing.T) {
+	one, two := Random(20), Random(20)
+	if one == two {
+		t.Fail()
+	}
+}
 
-var _ = Describe("ILocalStorage", func() {
-	Context("localStorage", func() {
-		It("Init:Initialize the cli program directory.", func() {
-			Skip("Manually exec:dependent environment")
-			var (
-				root = fmt.Sprintf("%s/%s", os.Getenv("HOME"), ".gs_pitr")
-				ls   = &localStorage{}
-			)
-
-			err := ls.Init(root)
-			Expect(err).To(BeNil())
-		})
-	})
-})
+func TestRandomInt(t *testing.T) {
+	one, two := RandomInt(9), RandomInt(9)
+	if one == two {
+		t.Fail()
+	}
+}
diff --git a/pitr/cli/internal/pkg/local-storage_test.go b/pitr/cli/pkg/stringutil/strutil_test.go
similarity index 69%
copy from pitr/cli/internal/pkg/local-storage_test.go
copy to pitr/cli/pkg/stringutil/strutil_test.go
index 9b691fc..50a2a74 100644
--- a/pitr/cli/internal/pkg/local-storage_test.go
+++ b/pitr/cli/pkg/stringutil/strutil_test.go
@@ -15,27 +15,16 @@
 * limitations under the License.
  */
 
-package pkg
+package strutil
 
 import (
-	"fmt"
-	"os"
+	"testing"
 
 	. "github.com/onsi/ginkgo/v2"
 	. "github.com/onsi/gomega"
 )
 
-var _ = Describe("ILocalStorage", func() {
-	Context("localStorage", func() {
-		It("Init:Initialize the cli program directory.", func() {
-			Skip("Manually exec:dependent environment")
-			var (
-				root = fmt.Sprintf("%s/%s", os.Getenv("HOME"), ".gs_pitr")
-				ls   = &localStorage{}
-			)
-
-			err := ls.Init(root)
-			Expect(err).To(BeNil())
-		})
-	})
-})
+func TestStrUtil(t *testing.T) {
+	RegisterFailHandler(Fail)
+	RunSpecs(t, "String util suit")
+}