dsakey proof of concept (needs cleanup)
[epoint] / store / store.go
1 package store
2
3 // persistent key-value store
4 // multiple key-value store can be managed by a single db connection
5 // each store has a name, before usage the name of the store must be
6 // ensured to exist
7 //
8 // TODO: this is a toy implementation
9
10 import (
11         "io/ioutil"
12         "os"
13         "path/filepath"
14 )
15
16 type Conn struct {
17         path string
18 }
19
20 func Open(root string) (c *Conn, err error) {
21         c = new(Conn)
22         c.path, err = filepath.Abs(root)
23         if err != nil {
24                 return
25         }
26         err = os.MkdirAll(c.path, 0755)
27         if err != nil {
28                 return
29         }
30         return
31 }
32
33 func (c *Conn) Get(name, k string) (v []byte, err error) {
34         return ioutil.ReadFile(filepath.Join(c.path, name, k))
35 }
36
37 func (c *Conn) Ensure(name string) (err error) {
38         return os.MkdirAll(filepath.Join(c.path, name), 0755)
39 }
40
41 func (c *Conn) Set(name, k string, v []byte) (err error) {
42         fn := filepath.Join(c.path, name, k)
43         f, err := os.OpenFile(fn+".tmp", os.O_CREATE|os.O_TRUNC|os.O_WRONLY|os.O_SYNC, 0666)
44         if err != nil {
45                 return
46         }
47         defer f.Close()
48         _, err = f.Write(v)
49         if err != nil {
50                 return
51         }
52         err = os.Rename(fn+".tmp", fn)
53         return
54 }
55
56 func (c *Conn) Append(name, k string, v []byte) (err error) {
57         fn := filepath.Join(c.path, name, k)
58         f, err := os.OpenFile(fn, os.O_CREATE|os.O_APPEND|os.O_WRONLY|os.O_SYNC, 0666)
59         if err != nil {
60                 return
61         }
62         defer f.Close()
63         _, err = f.Write(v)
64         return
65 }
66
67 func (c *Conn) Close() (err error) {
68         return
69 }