updated per #21 (all credit to https://github.com/edermanoel94)
This commit is contained in:
parent
f5079229c3
commit
4116320640
51
scribble.go
51
scribble.go
@ -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()
|
||||||
|
Loading…
Reference in New Issue
Block a user