Move all the code to a lib folder
This commit is contained in:
parent
e963d00014
commit
9d1f1ad5c0
31 changed files with 123 additions and 98 deletions
42
lib/storage/dir.go
Normal file
42
lib/storage/dir.go
Normal file
|
@ -0,0 +1,42 @@
|
|||
package storage
|
||||
|
||||
import (
|
||||
p "path"
|
||||
|
||||
"os"
|
||||
)
|
||||
|
||||
const (
|
||||
dir_depth = 2
|
||||
encodeURL = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_"
|
||||
)
|
||||
|
||||
func mkstore(path string) error {
|
||||
return _mkstore(path, dir_depth)
|
||||
}
|
||||
|
||||
func _mkstore(path string, depth int) error {
|
||||
err := os.MkdirAll(path, os.ModePerm)
|
||||
if err != nil || depth == 0 {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, l := range encodeURL {
|
||||
next_path := p.Join(path, string(l))
|
||||
err = _mkstore(next_path, depth-1)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func idPath(storePath string, id string) string {
|
||||
path := storePath
|
||||
for i := 0; i < dir_depth; i++ {
|
||||
dir := string(id[i])
|
||||
path = p.Join(path, dir)
|
||||
}
|
||||
path = p.Join(path, id)
|
||||
return path
|
||||
}
|
63
lib/storage/storage.go
Normal file
63
lib/storage/storage.go
Normal file
|
@ -0,0 +1,63 @@
|
|||
package storage
|
||||
|
||||
import (
|
||||
p "path"
|
||||
|
||||
"io"
|
||||
"os"
|
||||
)
|
||||
|
||||
type Store struct {
|
||||
path string
|
||||
}
|
||||
|
||||
type File interface {
|
||||
io.ReadCloser
|
||||
io.ReaderAt
|
||||
Stat() (fi os.FileInfo, err error)
|
||||
}
|
||||
|
||||
func Init(path string) (*Store, error) {
|
||||
st := new(Store)
|
||||
st.path = path
|
||||
|
||||
_, err := os.Stat(path)
|
||||
if err != nil {
|
||||
err = mkstore(st.path)
|
||||
}
|
||||
return st, err
|
||||
}
|
||||
|
||||
func (st *Store) Create(id string, name string) (io.WriteCloser, error) {
|
||||
path := idPath(st.path, id)
|
||||
err := os.MkdirAll(path, os.ModePerm)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return os.Create(p.Join(path, name))
|
||||
}
|
||||
|
||||
func (st *Store) Store(id string, file io.Reader, name string) (size int64, err error) {
|
||||
dest, err := st.Create(id, name)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
defer dest.Close()
|
||||
|
||||
return io.Copy(dest, file)
|
||||
}
|
||||
|
||||
func (st *Store) Get(id string, name string) (File, error) {
|
||||
path := idPath(st.path, id)
|
||||
return os.Open(p.Join(path, name))
|
||||
}
|
||||
|
||||
func (st *Store) Delete(id string) error {
|
||||
path := idPath(st.path, id)
|
||||
return os.RemoveAll(path)
|
||||
}
|
||||
|
||||
func (st *Store) del() {
|
||||
os.RemoveAll(st.path)
|
||||
}
|
113
lib/storage/storage_test.go
Normal file
113
lib/storage/storage_test.go
Normal file
|
@ -0,0 +1,113 @@
|
|||
package storage
|
||||
|
||||
import "testing"
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"strings"
|
||||
)
|
||||
|
||||
const (
|
||||
test_path = "/tmp/store"
|
||||
test_book = `
|
||||
HARI SELDON-… born in the 11,988th year of the Galactic Era; died
|
||||
12,069. The dates are more commonly given in terms of the current
|
||||
Foundational Era as - 79 to the year 1 F.E. Born to middle-class
|
||||
parents on Helicon, Arcturus sector (where his father, in a legend of
|
||||
doubtful authenticity, was a tobacco grower in the hydroponic plants
|
||||
of the planet), he early showed amazing ability in mathematics.
|
||||
Anecdotes concerning his ability are innumerable, and some are
|
||||
contradictory. At the age of two, he is said to have …`
|
||||
test_id = "1234567890abcdef"
|
||||
)
|
||||
|
||||
func TestInit(t *testing.T) {
|
||||
st, err := Init(test_path)
|
||||
if err != nil {
|
||||
t.Fatal("An error ocurred initializing the store =>", err)
|
||||
}
|
||||
defer st.del()
|
||||
|
||||
info, err := os.Stat(test_path)
|
||||
if err != nil {
|
||||
t.Fatal("An error ocurred =>", err)
|
||||
}
|
||||
if !info.Mode().IsDir() {
|
||||
t.Errorf(test_path, " is not dir.")
|
||||
}
|
||||
|
||||
info, err = os.Stat(test_path + "/a/M")
|
||||
if err != nil {
|
||||
t.Fatal("An error ocurred =>", err)
|
||||
}
|
||||
if !info.Mode().IsDir() {
|
||||
t.Errorf(test_path, " is not dir.")
|
||||
}
|
||||
}
|
||||
|
||||
func TestStore(t *testing.T) {
|
||||
st, err := Init(test_path)
|
||||
defer st.del()
|
||||
|
||||
_, err = st.Store(test_id, strings.NewReader(test_book), "epub")
|
||||
if err != nil {
|
||||
t.Fatal("An error ocurred storing the book =>", err)
|
||||
}
|
||||
book, err := st.Get(test_id, "epub")
|
||||
if err != nil {
|
||||
t.Fatal("An error ocurred getting the book =>", err)
|
||||
}
|
||||
|
||||
content, err := ioutil.ReadAll(book)
|
||||
if err != nil {
|
||||
t.Fatal("An error ocurred reading the book =>", err)
|
||||
}
|
||||
if !bytes.Equal(content, []byte(test_book)) {
|
||||
t.Error("Not the same content")
|
||||
}
|
||||
}
|
||||
|
||||
func TestCreate(t *testing.T) {
|
||||
st, err := Init(test_path)
|
||||
defer st.del()
|
||||
|
||||
f, err := st.Create(test_id, "img")
|
||||
if err != nil {
|
||||
t.Fatal("An error ocurred storing the book =>", err)
|
||||
}
|
||||
io.Copy(f, strings.NewReader(test_book))
|
||||
img, err := st.Get(test_id, "img")
|
||||
if err != nil {
|
||||
t.Fatal("An error ocurred getting the book =>", err)
|
||||
}
|
||||
|
||||
content, err := ioutil.ReadAll(img)
|
||||
if err != nil {
|
||||
t.Fatal("An error ocurred reading the book =>", err)
|
||||
}
|
||||
if !bytes.Equal(content, []byte(test_book)) {
|
||||
t.Error("Not the same content")
|
||||
}
|
||||
}
|
||||
|
||||
func TestDelete(t *testing.T) {
|
||||
st, err := Init(test_path)
|
||||
defer st.del()
|
||||
|
||||
_, err = st.Store(test_id, strings.NewReader(test_book), "epub")
|
||||
if err != nil {
|
||||
t.Fatal("An error ocurred storing the book =>", err)
|
||||
}
|
||||
err = st.Delete(test_id)
|
||||
if err != nil {
|
||||
t.Fatal("An error ocurred deleteing id =>", err)
|
||||
}
|
||||
|
||||
_, err = st.Get(test_id, "epub")
|
||||
if err == nil {
|
||||
t.Fatal("Retrieve book without error.")
|
||||
}
|
||||
}
|
Reference in a new issue