go-ayo/common을 gocommon으로 분리
This commit is contained in:
179
document/document_filebase.go
Normal file
179
document/document_filebase.go
Normal 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
|
||||
}
|
||||
Reference in New Issue
Block a user