Starting work on server
This commit is contained in:
parent
d569c17220
commit
e6fb690fc3
2
boltrest-server/.gitignore
vendored
Normal file
2
boltrest-server/.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
# Server Binary
|
||||||
|
boltrest-server
|
53
boltrest-server/main.go
Normal file
53
boltrest-server/main.go
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"math/rand"
|
||||||
|
"os"
|
||||||
|
|
||||||
|
"github.com/br0xen/boltrest"
|
||||||
|
)
|
||||||
|
|
||||||
|
var adminDB *boltrest.DB
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
initialize()
|
||||||
|
adminDB = boltrest.Open("admin.db")
|
||||||
|
}
|
||||||
|
|
||||||
|
func initialize() error {
|
||||||
|
// Make sure that the necessary files/directories are in place
|
||||||
|
var tstDir *os.File
|
||||||
|
var tstDirInfo os.FileInfo
|
||||||
|
var err error
|
||||||
|
if tstDir, err = os.Open("dbs"); err != nil {
|
||||||
|
if err = os.Mkdir("dbs", 0755); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if tstDir, err = os.Open("dbs"); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if tstDirInfo, err = tstDir.Stat(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if !tstDirInfo.IsDir() {
|
||||||
|
return errors.New("'dbs' exists and is not a directory")
|
||||||
|
}
|
||||||
|
// We were able to open the db path and it was a directory
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
const keyChars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
|
||||||
|
|
||||||
|
func generateAPIKey() string {
|
||||||
|
b := make([]byte, 34)
|
||||||
|
for i := range b {
|
||||||
|
if i%5 == 4 {
|
||||||
|
b[i] = '-'
|
||||||
|
} else {
|
||||||
|
b[i] = keyChars[rand.Int63()%int64(len(keyChars))]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return string(b)
|
||||||
|
}
|
128
boltrest.go
128
boltrest.go
@ -1,4 +1,4 @@
|
|||||||
package boltrest/lib
|
package boltrest
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
@ -16,9 +16,6 @@ import (
|
|||||||
// in a local bolt db and a remote db through a
|
// in a local bolt db and a remote db through a
|
||||||
// rest api.
|
// rest api.
|
||||||
|
|
||||||
// Custom BoltRest DB keys:
|
|
||||||
// __BR_LastUpdate: <RFC3339 Timestamp>
|
|
||||||
|
|
||||||
// DB is a struct for accomplishing this
|
// DB is a struct for accomplishing this
|
||||||
type DB struct {
|
type DB struct {
|
||||||
localFile string
|
localFile string
|
||||||
@ -68,8 +65,7 @@ func (b *DB) GetValue(path []string, key string) (string, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// SetValue sets the value at path to val
|
// SetValue sets the value at path to val
|
||||||
// path is a '/' separated list of tokens
|
// path is a slice of tokens
|
||||||
// the last token is a key, all others are buckets
|
|
||||||
func (b *DB) SetValue(path []string, key, val string) error {
|
func (b *DB) SetValue(path []string, key, val string) error {
|
||||||
var err error
|
var err error
|
||||||
b.localDB.Update(func(tx *bolt.Tx) error {
|
b.localDB.Update(func(tx *bolt.Tx) error {
|
||||||
@ -146,12 +142,128 @@ func (b *DB) SetTimestamp(path []string, key string, val time.Time) error {
|
|||||||
return b.SetValue(path, key, val.Format(time.RFC3339))
|
return b.SetValue(path, key, val.Format(time.RFC3339))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetBucketList returns a list of all sub-buckets at path
|
||||||
|
func (b *DB) GetBucketList(path []string) ([]string, error) {
|
||||||
|
var err error
|
||||||
|
var ret []string
|
||||||
|
// TODO: Make sure local db is fresh (or offline)
|
||||||
|
|
||||||
|
err = b.localDB.Update(func(tx *bolt.Tx) error {
|
||||||
|
bkt := tx.Bucket([]byte(path[0]))
|
||||||
|
if bkt == nil {
|
||||||
|
return fmt.Errorf("Couldn't find bucket " + path[0])
|
||||||
|
}
|
||||||
|
var newBkt *bolt.Bucket
|
||||||
|
for idx := 1; idx < len(path); idx++ {
|
||||||
|
newBkt = bkt.Bucket([]byte(path[idx]))
|
||||||
|
if newBkt == nil {
|
||||||
|
return fmt.Errorf("Couldn't find bucket " + strings.Join(path[:idx], "/"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// newBkt should have the last bucket in the path
|
||||||
|
berr := newBkt.ForEach(func(k, v []byte) error {
|
||||||
|
if v == nil {
|
||||||
|
// Must be a bucket
|
||||||
|
ret = append(ret, string(k))
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
return berr
|
||||||
|
})
|
||||||
|
return ret, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetKeyList returns a list of all keys at path
|
||||||
|
func (b *DB) GetKeyList(path []string) ([]string, error) {
|
||||||
|
var err error
|
||||||
|
var ret []string
|
||||||
|
// TODO: Make sure local db is fresh (or offline)
|
||||||
|
|
||||||
|
err = b.localDB.Update(func(tx *bolt.Tx) error {
|
||||||
|
bkt := tx.Bucket([]byte(path[0]))
|
||||||
|
if bkt == nil {
|
||||||
|
return fmt.Errorf("Couldn't find bucket " + path[0])
|
||||||
|
}
|
||||||
|
var newBkt *bolt.Bucket
|
||||||
|
for idx := 1; idx < len(path); idx++ {
|
||||||
|
newBkt = bkt.Bucket([]byte(path[idx]))
|
||||||
|
if newBkt == nil {
|
||||||
|
return fmt.Errorf("Couldn't find bucket " + strings.Join(path[:idx], "/"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// newBkt should have the last bucket in the path
|
||||||
|
berr := newBkt.ForEach(func(k, v []byte) error {
|
||||||
|
if v != nil {
|
||||||
|
// Not a bucket
|
||||||
|
ret = append(ret, string(k))
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
return berr
|
||||||
|
})
|
||||||
|
return ret, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeletePair deletes the pair with key at path
|
||||||
|
func (b *DB) DeletePair(path []string, key string) error {
|
||||||
|
var err error
|
||||||
|
// TODO: Make sure local db is fresh (or offline)
|
||||||
|
|
||||||
|
err = b.localDB.Update(func(tx *bolt.Tx) error {
|
||||||
|
bkt := tx.Bucket([]byte(path[0]))
|
||||||
|
if bkt == nil {
|
||||||
|
return fmt.Errorf("Couldn't find bucket " + path[0])
|
||||||
|
}
|
||||||
|
var newBkt *bolt.Bucket
|
||||||
|
for idx := 1; idx < len(path); idx++ {
|
||||||
|
newBkt = bkt.Bucket([]byte(path[idx]))
|
||||||
|
if newBkt == nil {
|
||||||
|
return fmt.Errorf("Couldn't find bucket " + strings.Join(path[:idx], "/"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// newBkt should have the last bucket in the path
|
||||||
|
// Test to make sure that key is a pair, if so, delete it
|
||||||
|
if tst := newBkt.Bucket([]byte(key)); tst == nil {
|
||||||
|
return newBkt.Delete([]byte(key))
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeleteBucket deletes the bucket key at path
|
||||||
|
func (b *DB) DeleteBucket(path []string, key string) error {
|
||||||
|
var err error
|
||||||
|
// TODO: Make sure local db is fresh (or offline)
|
||||||
|
|
||||||
|
err = b.localDB.Update(func(tx *bolt.Tx) error {
|
||||||
|
bkt := tx.Bucket([]byte(path[0]))
|
||||||
|
if bkt == nil {
|
||||||
|
return fmt.Errorf("Couldn't find bucket " + path[0])
|
||||||
|
}
|
||||||
|
var newBkt *bolt.Bucket
|
||||||
|
for idx := 1; idx < len(path); idx++ {
|
||||||
|
newBkt = bkt.Bucket([]byte(path[idx]))
|
||||||
|
if newBkt == nil {
|
||||||
|
return fmt.Errorf("Couldn't find bucket " + strings.Join(path[:idx], "/"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// newBkt should have the last bucket in the path
|
||||||
|
// Test to make sure that key is a bucket, if so, delete it
|
||||||
|
if tst := newBkt.Bucket([]byte(key)); tst != nil {
|
||||||
|
return newBkt.Delete([]byte(key))
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
type setURLResponse struct {
|
type setURLResponse struct {
|
||||||
dbMD5 string
|
dbMD5 string
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetURL sets the DB's remote URL
|
// SetDBURL sets the DB's remote URL
|
||||||
func (b *DB) SetURL(url string) (bool, string) {
|
func (b *DB) SetDBURL(url string) (bool, string) {
|
||||||
resp, err := http.Get(url)
|
resp, err := http.Get(url)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, ""
|
return false, ""
|
||||||
|
Loading…
Reference in New Issue
Block a user