This commit is contained in:
Steve Domino 2019-10-24 13:41:53 -06:00
parent f5079229c3
commit 4116320640
1 changed files with 35 additions and 16 deletions

View File

@ -3,6 +3,7 @@ package scribble
import ( import (
"encoding/json" "encoding/json"
"errors"
"fmt" "fmt"
"io/ioutil" "io/ioutil"
"os" "os"
@ -15,8 +16,12 @@ import (
// Version is the current version of the project // Version is the current version of the project
const Version = "1.0.4" const Version = "1.0.4"
type ( var (
ErrMissingResource = errors.New("missing resource - unable to save record")
ErrMissingCollection = errors.New("missing collection - no place to save record")
)
type (
// Logger is a generic logger interface // Logger is a generic logger interface
Logger interface { Logger interface {
Fatal(string, ...interface{}) Fatal(string, ...interface{})
@ -86,12 +91,12 @@ func (d *Driver) Write(collection, resource string, v interface{}) error {
// ensure there is a place to save record // ensure there is a place to save record
if collection == "" { if collection == "" {
return fmt.Errorf("Missing collection - no place to save record!") return ErrMissingCollection
} }
// ensure there is a resource (name) to save record as // ensure there is a resource (name) to save record as
if resource == "" { if resource == "" {
return fmt.Errorf("Missing resource - unable to save record (no name)!") return ErrMissingResource
} }
mutex := d.getOrCreateMutex(collection) mutex := d.getOrCreateMutex(collection)
@ -103,27 +108,29 @@ func (d *Driver) Write(collection, resource string, v interface{}) error {
fnlPath := filepath.Join(dir, resource+".json") fnlPath := filepath.Join(dir, resource+".json")
tmpPath := fnlPath + ".tmp" tmpPath := fnlPath + ".tmp"
return write(dir, tmpPath, fnlPath, v)
}
func write(dir, tmpPath, dstPath string, v interface{}) error {
// create collection directory // create collection directory
if err := os.MkdirAll(dir, 0755); err != nil { if err := os.MkdirAll(dir, 0755); err != nil {
return err return err
} }
// // marshal the pointer to a non-struct and indent with tab
b, err := json.MarshalIndent(v, "", "\t") b, err := json.MarshalIndent(v, "", "\t")
if err != nil { if err != nil {
return err return err
} }
// add newline to the end
b = append(b, byte('\n'))
// write marshaled data to the temp file // write marshaled data to the temp file
if err := ioutil.WriteFile(tmpPath, b, 0644); err != nil { if err := ioutil.WriteFile(tmpPath, b, 0644); err != nil {
return err return err
} }
// move final file into place // move final file into place
return os.Rename(tmpPath, fnlPath) return os.Rename(tmpPath, dstPath)
} }
// Read a record from the database // Read a record from the database
@ -131,12 +138,12 @@ func (d *Driver) Read(collection, resource string, v interface{}) error {
// ensure there is a place to save record // ensure there is a place to save record
if collection == "" { if collection == "" {
return fmt.Errorf("Missing collection - no place to save record!") return ErrMissingCollection
} }
// ensure there is a resource (name) to save record as // ensure there is a resource (name) to save record as
if resource == "" { if resource == "" {
return fmt.Errorf("Missing resource - unable to save record (no name)!") return ErrMissingResource
} }
// //
@ -148,7 +155,13 @@ func (d *Driver) Read(collection, resource string, v interface{}) error {
} }
// read record from database // read record from database
return read(record, v)
}
func read(record string, v interface{}) error {
b, err := ioutil.ReadFile(record + ".json") b, err := ioutil.ReadFile(record + ".json")
if err != nil { if err != nil {
return err return err
} }
@ -159,11 +172,11 @@ func (d *Driver) Read(collection, resource string, v interface{}) error {
// ReadAll records from a collection; this is returned as a slice of strings because // ReadAll records from a collection; this is returned as a slice of strings because
// there is no way of knowing what type the record is. // there is no way of knowing what type the record is.
func (d *Driver) ReadAll(collection string) ([]string, error) { func (d *Driver) ReadAll(collection string) ([][]byte, error) {
// ensure there is a collection to read // ensure there is a collection to read
if collection == "" { if collection == "" {
return nil, fmt.Errorf("Missing collection - unable to record location!") return nil, ErrMissingCollection
} }
// //
@ -178,19 +191,25 @@ func (d *Driver) ReadAll(collection string) ([]string, error) {
// the collection is either empty or doesn't exist // the collection is either empty or doesn't exist
files, _ := ioutil.ReadDir(dir) files, _ := ioutil.ReadDir(dir)
return readAll(files, dir)
}
func readAll(files []os.FileInfo, dir string) ([][]byte, error) {
// the files read from the database // the files read from the database
var records []string var records [][]byte
// iterate over each of the files, attempting to read the file. If successful // iterate over each of the files, attempting to read the file. If successful
// append the files to the collection of read files // append the files to the collection of read
for _, file := range files { for _, file := range files {
b, err := ioutil.ReadFile(filepath.Join(dir, file.Name())) b, err := ioutil.ReadFile(filepath.Join(dir, file.Name()))
if err != nil { if err != nil {
return nil, err return nil, err
} }
// append read file // append read file
records = append(records, string(b)) records = append(records, b)
} }
// unmarhsal the read files as a comma delimeted byte array // unmarhsal the read files as a comma delimeted byte array
@ -239,7 +258,7 @@ func stat(path string) (fi os.FileInfo, err error) {
} }
// getOrCreateMutex creates a new collection specific mutex any time a collection // getOrCreateMutex creates a new collection specific mutex any time a collection
// is being modfied to avoid unsafe operations // is being modified to avoid unsafe operations
func (d *Driver) getOrCreateMutex(collection string) *sync.Mutex { func (d *Driver) getOrCreateMutex(collection string) *sync.Mutex {
d.mutex.Lock() d.mutex.Lock()