From 4a22289ae2ce80af7a339bde66f080720ee1a9b3 Mon Sep 17 00:00:00 2001 From: Ian Gulliver Date: Tue, 15 Mar 2022 04:43:03 +0000 Subject: [PATCH] Initial Store implementation --- .gitignore | 3 +- go.mod | 5 ++++ go.sum | 2 ++ main.go | 24 ++++++++++++++++ store.go | 79 +++++++++++++++++++++++++++++++++++++++++++++++++++++ template.go | 14 ++++++++++ 6 files changed, 125 insertions(+), 2 deletions(-) create mode 100644 go.mod create mode 100644 go.sum create mode 100644 main.go create mode 100644 store.go create mode 100644 template.go diff --git a/.gitignore b/.gitignore index 66fd13c..92d74a2 100644 --- a/.gitignore +++ b/.gitignore @@ -11,5 +11,4 @@ # Output of the go coverage tool, specifically when used with LiteIDE *.out -# Dependency directories (remove the comment below to include it) -# vendor/ +foo/ diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..7ee7405 --- /dev/null +++ b/go.mod @@ -0,0 +1,5 @@ +module github.com/firestuff/checky + +go 1.16 + +require github.com/google/uuid v1.3.0 diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..3dfe1c9 --- /dev/null +++ b/go.sum @@ -0,0 +1,2 @@ +github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= +github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= diff --git a/main.go b/main.go new file mode 100644 index 0000000..f730b9a --- /dev/null +++ b/main.go @@ -0,0 +1,24 @@ +package main + +import "fmt" + +import "github.com/google/uuid" + +func main() { + store := NewStore("foo") + + out := &Template{ + Id: uuid.NewString(), + Test: "round trip", + } + + store.Write(out) + + in := &Template{ + Id: out.Id, + } + + store.Read(in) + + fmt.Printf("%+v\n", in) +} diff --git a/store.go b/store.go new file mode 100644 index 0000000..c1d1104 --- /dev/null +++ b/store.go @@ -0,0 +1,79 @@ +package main + +import "encoding/hex" +import "encoding/json" +import "fmt" +import "os" +import "path/filepath" + +type Storable interface { + GetType() string + GetId() string +} + +type Store struct { + root string +} + +func NewStore(root string) *Store { + return &Store{ + root: root, + } +} + +func (s *Store) Write(obj Storable) error { + dir := filepath.Join(s.root, obj.GetType()) + filename := hex.EncodeToString([]byte(obj.GetId())) + + err := os.MkdirAll(dir, 0700) + if err != nil { + return err + } + + tmp, err := os.CreateTemp(dir, fmt.Sprintf("%s.*", filename)) + if err != nil { + return err + } + defer tmp.Close() + + enc := json.NewEncoder(tmp) + enc.SetEscapeHTML(false) + + err = enc.Encode(obj) + if err != nil { + return err + } + + err = tmp.Close() + if err != nil { + return err + } + + err = os.Rename(tmp.Name(), filepath.Join(dir, filename)) + if err != nil { + return err + } + + return nil +} + +func (s *Store) Read(obj Storable) error { + dir := filepath.Join(s.root, obj.GetType()) + filename := hex.EncodeToString([]byte(obj.GetId())) + + fh, err := os.Open(filepath.Join(dir, filename)) + if err != nil { + return err + } + defer fh.Close() + + dec := json.NewDecoder(fh) + dec.DisallowUnknownFields() + + err = dec.Decode(obj) + if err != nil { + return err + } + + return nil +} diff --git a/template.go b/template.go new file mode 100644 index 0000000..35f6d29 --- /dev/null +++ b/template.go @@ -0,0 +1,14 @@ +package main + +type Template struct { + Id string + Test string +} + +func (t *Template) GetType() string { + return "template" +} + +func (t *Template) GetId() string { + return t.Id +}