This repository has been archived by the owner on Dec 10, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmdb.go
136 lines (119 loc) · 2.62 KB
/
mdb.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
package mdb
import (
"crypto/rand"
"encoding/json"
"fmt"
"io"
"os"
"time"
)
// Document is an entry in the database
type Document struct {
Created string `json:"created"`
Edited string `json:"edited"`
Doc string `json:"doc"`
}
// Database is the database in memory
type Database struct {
Data map[string]Document `json:"data"`
}
// NewDatabase creates a new empty Database struct
func NewDatabase() *Database {
return &Database{
Data: map[string]Document{},
}
}
// Load loads database file into a Database instance
func Load(db *Database, fn string) error {
var err error
var f *os.File
// if file does not exist, create
if _, err = os.Stat(fn); err != nil {
f, err = os.Create(fn)
if err != nil {
return err
}
} else {
f, err = os.Open(fn)
if err != nil {
return err
}
}
defer f.Close()
decoder := json.NewDecoder(f)
for {
if err := decoder.Decode(db); err == io.EOF {
break
} else if err != nil {
return err
}
}
return nil
}
// Commit writes the Database instance in memory to file
func Commit(db *Database, fn string) error {
f, err := os.OpenFile(fn, os.O_RDWR|os.O_CREATE|os.O_TRUNC, os.ModePerm)
if err != nil {
return err
}
defer f.Close()
encoder := json.NewEncoder(f)
if err = encoder.Encode(db); err != nil {
return err
}
return nil
}
// Get fetches a single document from a Database instance
func Get(db *Database, id string) (*Document, error) {
if val, ok := db.Data[id]; ok {
return &val, nil
} else {
return nil, fmt.Errorf("document id doesn't exist: %s", id)
}
}
// Put inserts a new Document into a Database
func Put(db *Database, doc string) (string, error) {
pid, err := uuid()
if err != nil {
return "", err
}
db.Data[pid] = Document{
Created: time.Now().UTC().String(),
Edited: time.Now().UTC().String(),
Doc: doc,
}
return pid, nil
}
// Update updates an existing document in a Database
func Update(db *Database, id, doc string) error {
currData, err := Get(db, id)
if err != nil {
return err
}
currData.Edited = time.Now().UTC().String()
currData.Doc = doc
db.Data[id] = *currData
return nil
}
// Delete removes a Document from a Database
func Delete(db *Database, id string) error {
if _, err := Get(db, id); err != nil {
return err
}
delete(db.Data, id)
return nil
}
// uuid creates a pseudo uuid V4 string
func uuid() (u string, err error) {
b := make([]byte, 16)
_, err = rand.Read(b)
if err != nil {
return
}
// 13th character is "4"
b[6] = (b[6] | 0x40) & 0x4F
// 17th character is 8, 9, a, or b
b[8] = (b[8] | 0x80) & 0xBF
u = fmt.Sprintf("%X-%X-%X-%X-%X", b[0:4], b[4:6], b[6:8], b[8:10], b[10:])
return
}