First commit
This commit is contained in:
commit
13d40ff872
4 files changed
+291
No files matched your search
@@ -0,0 +1,212 @@
|
|||||||
|
package driver
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"io/ioutil"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
"sync"
|
||||||
|
|
||||||
|
"github.com/google/uuid"
|
||||||
|
"github.com/jcelliott/lumber"
|
||||||
|
)
|
||||||
|
|
||||||
|
const Version = "1.0.1"
|
||||||
|
const parentDir = "C:/local-go-db/"
|
||||||
|
|
||||||
|
type (
|
||||||
|
Logger interface {
|
||||||
|
Fatal(string, ...interface{})
|
||||||
|
Error(string, ...interface{})
|
||||||
|
Info(string, ...interface{})
|
||||||
|
Warn(string, ...interface{})
|
||||||
|
Debug(string, ...interface{})
|
||||||
|
Trace(string, ...interface{})
|
||||||
|
}
|
||||||
|
|
||||||
|
Driver struct {
|
||||||
|
mutex sync.Mutex
|
||||||
|
mutexes map[string]*sync.Mutex
|
||||||
|
dir string
|
||||||
|
log Logger
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
type Options struct {
|
||||||
|
Logger
|
||||||
|
}
|
||||||
|
|
||||||
|
type Data struct {
|
||||||
|
ID string
|
||||||
|
Object interface{}
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewConnection(dbName string, options *Options) (*Driver, error) {
|
||||||
|
if dbName == "" {
|
||||||
|
return nil, fmt.Errorf("Cannot create Nameless database - No name given")
|
||||||
|
}
|
||||||
|
dir := parentDir + dbName
|
||||||
|
dir = filepath.Clean(dir)
|
||||||
|
|
||||||
|
opts := Options{}
|
||||||
|
if options != nil {
|
||||||
|
opts = *options
|
||||||
|
}
|
||||||
|
|
||||||
|
if opts.Logger == nil {
|
||||||
|
opts.Logger = lumber.NewConsoleLogger((lumber.INFO))
|
||||||
|
}
|
||||||
|
|
||||||
|
driver := Driver{
|
||||||
|
dir: dir,
|
||||||
|
mutexes: make(map[string]*sync.Mutex),
|
||||||
|
log: opts.Logger,
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, err := os.Stat(dir); err == nil {
|
||||||
|
opts.Logger.Debug("Using '%s' (database already exists)\n", dir)
|
||||||
|
return &driver, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
opts.Logger.Debug("Creating the database at '%s'...\n", dir)
|
||||||
|
return &driver, os.MkdirAll(dir, 0755)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *Driver) InsertOne(collection string, v interface{}) error {
|
||||||
|
|
||||||
|
if collection == "" {
|
||||||
|
return fmt.Errorf("Missing collection - no place to save record!")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create new uuid for object and append object to database
|
||||||
|
|
||||||
|
var data Data
|
||||||
|
data.ID = uuid.New().String()
|
||||||
|
data.Object = v
|
||||||
|
|
||||||
|
mutex := d.getOrCreateMutex(collection)
|
||||||
|
mutex.Lock()
|
||||||
|
defer mutex.Unlock()
|
||||||
|
|
||||||
|
dir := filepath.Join(d.dir, collection)
|
||||||
|
fnlPath := filepath.Join(dir, data.ID+".json")
|
||||||
|
tmpPath := fnlPath + ".tmp"
|
||||||
|
|
||||||
|
if err := os.MkdirAll(dir, 0755); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
b, err := json.MarshalIndent(data, "", "\t")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
b = append(b, byte('\n'))
|
||||||
|
|
||||||
|
if err := ioutil.WriteFile(tmpPath, b, 0644); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return os.Rename(tmpPath, fnlPath)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *Driver) InsertMany(collection, resource string) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *Driver) FindOne(collection, id string) (interface{}, error) {
|
||||||
|
if collection == "" {
|
||||||
|
return nil, fmt.Errorf("Missing collection - unable to read!")
|
||||||
|
}
|
||||||
|
|
||||||
|
record := filepath.Join(d.dir, collection, id)
|
||||||
|
|
||||||
|
if _, err := stat(record); err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
return nil, fmt.Errorf("The object you're searching for cannot be found")
|
||||||
|
}
|
||||||
|
|
||||||
|
b, err := ioutil.ReadFile(record + ".json")
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
var v Data
|
||||||
|
json.Unmarshal(b, &v)
|
||||||
|
|
||||||
|
return v, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *Driver) FindAll(collection string) ([]string, error) {
|
||||||
|
|
||||||
|
if collection == "" {
|
||||||
|
return nil, fmt.Errorf("Missing collection - unable to read!")
|
||||||
|
}
|
||||||
|
dir := filepath.Join(d.dir, collection)
|
||||||
|
|
||||||
|
if _, err := stat(dir); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
files, _ := ioutil.ReadDir(dir)
|
||||||
|
|
||||||
|
var records []string
|
||||||
|
|
||||||
|
for _, file := range files {
|
||||||
|
b, err := ioutil.ReadFile(filepath.Join(dir, file.Name()))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
records = append(records, string(b))
|
||||||
|
}
|
||||||
|
return records, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *Driver) Delete(collection, id string) error {
|
||||||
|
|
||||||
|
path := filepath.Join(collection, id)
|
||||||
|
mutex := d.getOrCreateMutex(collection)
|
||||||
|
mutex.Lock()
|
||||||
|
defer mutex.Unlock()
|
||||||
|
|
||||||
|
dir := filepath.Join(d.dir, path)
|
||||||
|
|
||||||
|
switch fi, err := stat(dir); {
|
||||||
|
case fi == nil, err != nil:
|
||||||
|
return fmt.Errorf("Unable to find file or directory name %v\n", path)
|
||||||
|
|
||||||
|
case fi.Mode().IsDir():
|
||||||
|
return os.RemoveAll(dir)
|
||||||
|
|
||||||
|
case fi.Mode().IsRegular():
|
||||||
|
return os.RemoveAll(dir + ".json")
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *Driver) getOrCreateMutex(collection string) *sync.Mutex {
|
||||||
|
|
||||||
|
d.mutex.Lock()
|
||||||
|
defer d.mutex.Unlock()
|
||||||
|
m, ok := d.mutexes[collection]
|
||||||
|
|
||||||
|
if !ok {
|
||||||
|
m = &sync.Mutex{}
|
||||||
|
d.mutexes[collection] = m
|
||||||
|
}
|
||||||
|
|
||||||
|
return m
|
||||||
|
}
|
||||||
|
|
||||||
|
func stat(path string) (fi os.FileInfo, err error) {
|
||||||
|
if fi, err = os.Stat(path); os.IsNotExist(err) {
|
||||||
|
fi, err = os.Stat(path + ".json")
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
type User struct {
|
||||||
|
Name string
|
||||||
|
Age json.Number
|
||||||
|
}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
module github.com/SowinskiBraeden/local-go-db
|
||||||
|
|
||||||
|
go 1.17
|
||||||
|
|
||||||
|
require (
|
||||||
|
github.com/google/uuid v1.3.0
|
||||||
|
github.com/jcelliott/lumber v0.0.0-20160324203708-dd349441af25
|
||||||
|
)
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
|
||||||
|
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||||
|
github.com/jcelliott/lumber v0.0.0-20160324203708-dd349441af25 h1:EFT6MH3igZK/dIVqgGbTqWVvkZ7wJ5iGN03SVtvvdd8=
|
||||||
|
github.com/jcelliott/lumber v0.0.0-20160324203708-dd349441af25/go.mod h1:sWkGw/wsaHtRsT9zGQ/WyJCotGWG/Anow/9hsAcBWRw=
|
||||||
@@ -0,0 +1,67 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/SowinskiBraeden/local-go-db/driver"
|
||||||
|
)
|
||||||
|
|
||||||
|
type User struct {
|
||||||
|
Name string
|
||||||
|
Age json.Number
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
database, err := driver.NewConnection("mytestdb", nil)
|
||||||
|
// database, err := driver.Connect("mytestdb", nil)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println("Error: ", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// users := []User{
|
||||||
|
// {"John Doe", "25"},
|
||||||
|
// {"Mike Tyson", "50"},
|
||||||
|
// }
|
||||||
|
|
||||||
|
// for _, value := range users {
|
||||||
|
// database.InsertOne("users", User{
|
||||||
|
// Name: value.Name,
|
||||||
|
// Age: value.Age,
|
||||||
|
// })
|
||||||
|
// }
|
||||||
|
|
||||||
|
// err = database.InsertOne("users", User{
|
||||||
|
// Name: "Test User",
|
||||||
|
// Age: "19",
|
||||||
|
// })
|
||||||
|
// if err != nil {
|
||||||
|
// fmt.Println("Error: ", err)
|
||||||
|
// }
|
||||||
|
|
||||||
|
record, findErr := database.FindOne("users", "54d65722-1a2e-455c-a75d-38f9026e8f97") // <-- Pass in the ID of the object generated
|
||||||
|
if findErr != nil {
|
||||||
|
fmt.Println("Error: ", findErr)
|
||||||
|
}
|
||||||
|
fmt.Println(record)
|
||||||
|
|
||||||
|
// records, err := database.ReadAll("users")
|
||||||
|
// if err != nil {
|
||||||
|
// fmt.Println("Error: ", err)
|
||||||
|
// }
|
||||||
|
// fmt.Println(records)
|
||||||
|
|
||||||
|
// allUsers := []User{}
|
||||||
|
|
||||||
|
// for _, f := range records {
|
||||||
|
// userFound := User{}
|
||||||
|
// if err := json.Unmarshal([]byte(f), &userFound); err != nil {
|
||||||
|
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// delErr := database.Delete("users", "44516cb3-eacd-49d6-9816-30f317e2dd5d")
|
||||||
|
// if delErr != nil {
|
||||||
|
// fmt.Println("Error: ", err)
|
||||||
|
// }
|
||||||
|
}
|
||||||
Reference in new issue
Block a user