go-ayo/common을 gocommon으로 분리

This commit is contained in:
2023-05-24 15:10:15 +09:00
commit e95efa06a6
21 changed files with 4389 additions and 0 deletions

View File

@ -0,0 +1,179 @@
package document
import (
"encoding/json"
"fmt"
"os"
"path"
"strings"
)
func getDocumentFilepath(owner string) string {
return fmt.Sprintf("./docs/%s.json", owner)
}
type fileDocument struct {
owner string
root map[string]interface{}
dirty bool
}
// LoadFileDocument : 파일로 도큐먼트 로딩
func LoadFileDocument(owner string) (Document, error) {
bt, err := os.ReadFile(getDocumentFilepath(owner))
if err != nil && !os.IsNotExist(err) {
return nil, err
}
if len(bt) == 0 {
return &fileDocument{
owner: owner,
root: make(map[string]interface{}),
dirty: false,
}, nil
}
var doc map[string]interface{}
err = json.Unmarshal(bt, &doc)
if err != nil {
return nil, err
}
return &fileDocument{
owner: owner,
root: doc,
dirty: false,
}, nil
}
func findNodeInterface(doc map[string]interface{}, path string) (interface{}, error) {
if doc == nil {
return nil, ErrDocumentNotExist
}
parent := doc
for {
idx := strings.IndexRune(path, '/')
var nodename string
if idx < 0 {
nodename = path
path = ""
} else {
nodename = path[:idx]
path = path[idx+1:]
}
child, ok := parent[nodename]
if !ok {
return nil, ErrDocumentPathNotExist
}
if len(path) == 0 {
return child, nil
}
if parent, ok = child.(map[string]interface{}); !ok {
return nil, ErrDocumentPathTypeMismatch
}
}
}
func findEdgeContainer(doc map[string]interface{}, path string) (map[string]interface{}, string) {
parent := doc
for {
idx := strings.IndexRune(path, '/')
var nodename string
if idx < 0 {
nodename = path
path = ""
} else {
nodename = path[:idx]
path = path[idx+1:]
}
if len(path) == 0 {
return parent, nodename
}
child, ok := parent[nodename]
if !ok {
child = make(map[string]interface{})
parent[nodename] = child
}
parent = child.(map[string]interface{})
}
}
// ReadBool :
func (doc *fileDocument) ReadBool(path string) (bool, error) {
val, err := findNodeInterface(doc.root, path)
if err != nil {
return false, err
}
out, ok := val.(bool)
if !ok {
return false, ErrDocumentPathTypeMismatch
}
return out, nil
}
// ReadString :
func (doc *fileDocument) ReadString(path string) (string, error) {
val, err := findNodeInterface(doc.root, path)
if err != nil {
return "", err
}
out, ok := val.(string)
if !ok {
return "", ErrDocumentPathTypeMismatch
}
return out, nil
}
// Read :
func (doc *fileDocument) Read(path string) (interface{}, error) {
return findNodeInterface(doc.root, path)
}
// WriteBool :
func (doc *fileDocument) Write(path string, val interface{}) {
container, edge := findEdgeContainer(doc.root, path)
container[edge] = val
doc.dirty = true
}
// Serialize :
func (doc *fileDocument) Serialize() error {
if !doc.dirty {
return nil
}
bt, err := json.Marshal(doc.root)
if err != nil {
return err
}
filepath := getDocumentFilepath(doc.owner)
if err := os.WriteFile(filepath, bt, 0644); err != nil {
if _, patherr := err.(*os.PathError); !patherr {
return err
}
dir := path.Dir(filepath)
if err = os.MkdirAll(dir, 0755); err != nil {
return err
}
if err = os.WriteFile(filepath, bt, 0644); err != nil {
return err
}
}
doc.dirty = false
return nil
}