Removed directory storage
This commit is contained in:
parent
f37a2bd74b
commit
235679a913
@ -71,8 +71,3 @@ Suppose `n` is the number of write requests and `io` is the time it takes for on
|
||||
You should use `storage.File` if you have a permanently running process such as a web server where end users expect quick responses and background work can happen after the user request has already been dealt with.
|
||||
|
||||
Make sure you `defer collection.Sync()` to ensure that queued writes will be handled when the process ends.
|
||||
|
||||
### storage.Directory
|
||||
|
||||
`storage.Directory` creates a directory for your records and saves each record in a separate file.
|
||||
The performance of this method heavily depends on the file system you are using but in general `storage.File` should be preferred as it provides much better performance.
|
||||
|
@ -1,117 +0,0 @@
|
||||
package storage
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"git.akyoto.dev/go/ocean"
|
||||
)
|
||||
|
||||
// Directory creates a directory and stores every record in a separate file.
|
||||
type Directory[T any] struct {
|
||||
collection ocean.StorageData
|
||||
directory string
|
||||
}
|
||||
|
||||
// Init loads all existing records from the directory.
|
||||
func (ds *Directory[T]) Init(c ocean.StorageData) error {
|
||||
ds.collection = c
|
||||
ds.directory = filepath.Join(c.Root(), c.Name())
|
||||
err := os.Mkdir(ds.directory, 0700)
|
||||
|
||||
if err != nil && !os.IsExist(err) {
|
||||
return err
|
||||
}
|
||||
|
||||
return ds.read()
|
||||
}
|
||||
|
||||
// Set saves the value in a file.
|
||||
func (ds *Directory[T]) Set(key string, value *T) error {
|
||||
return ds.writeFile(key, value)
|
||||
}
|
||||
|
||||
// Delete deletes the file for the given key.
|
||||
func (ds *Directory[T]) Delete(key string) error {
|
||||
err := os.Remove(ds.keyFile(key))
|
||||
|
||||
if os.IsNotExist(err) {
|
||||
return nil
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
// Sync does nothing when using directory storage.
|
||||
func (ds *Directory[T]) Sync() {}
|
||||
|
||||
// read loads the collection data from the disk.
|
||||
func (ds *Directory[T]) read() error {
|
||||
dir, err := os.Open(ds.directory)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
defer dir.Close()
|
||||
files, err := dir.Readdirnames(0)
|
||||
|
||||
for _, fileName := range files {
|
||||
fileError := ds.readFile(fileName)
|
||||
|
||||
if fileError != nil {
|
||||
return fileError
|
||||
}
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
// readFile loads a single file from the disk.
|
||||
func (ds *Directory[T]) readFile(fileName string) error {
|
||||
filePath := filepath.Join(ds.directory, fileName)
|
||||
file, err := os.Open(filePath)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
defer file.Close()
|
||||
value := new(T)
|
||||
decoder := NewDecoder(file)
|
||||
err = decoder.Decode(value)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
key := strings.TrimSuffix(fileName, ".json")
|
||||
ds.collection.Data().Store(key, value)
|
||||
return nil
|
||||
}
|
||||
|
||||
// writeFile writes the value for the key to disk as a JSON file.
|
||||
func (ds *Directory[T]) writeFile(key string, value any) error {
|
||||
fileName := ds.keyFile(key)
|
||||
file, err := os.OpenFile(fileName, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0600)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
encoder := NewEncoder(file)
|
||||
err = encoder.Encode(value)
|
||||
|
||||
if err != nil {
|
||||
file.Close()
|
||||
return err
|
||||
}
|
||||
|
||||
return file.Close()
|
||||
}
|
||||
|
||||
// keyFile returns the file path for the given key.
|
||||
func (ds *Directory[T]) keyFile(key string) string {
|
||||
return filepath.Join(ds.directory, key+".json")
|
||||
}
|
@ -1,42 +0,0 @@
|
||||
package storage_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"git.akyoto.dev/go/assert"
|
||||
"git.akyoto.dev/go/ocean"
|
||||
"git.akyoto.dev/go/ocean/storage"
|
||||
)
|
||||
|
||||
var _ ocean.Storage[string] = (*storage.Directory[string])(nil)
|
||||
|
||||
func TestDirectoryPersistence(t *testing.T) {
|
||||
users, err := ocean.New[User]("test", &storage.Directory[User]{})
|
||||
assert.Nil(t, err)
|
||||
|
||||
defer users.Sync()
|
||||
defer users.Clear()
|
||||
|
||||
users.Set("1", &User{Name: "User 1"})
|
||||
users.Set("2", &User{Name: "User 2"})
|
||||
users.Set("3", &User{Name: "User 3"})
|
||||
users.Sync()
|
||||
|
||||
reload, err := ocean.New[User]("test", &storage.Directory[User]{})
|
||||
assert.Nil(t, err)
|
||||
|
||||
user, err := reload.Get("1")
|
||||
assert.Nil(t, err)
|
||||
assert.NotNil(t, user)
|
||||
assert.Equal(t, user.Name, "User 1")
|
||||
|
||||
user, err = reload.Get("2")
|
||||
assert.Nil(t, err)
|
||||
assert.NotNil(t, user)
|
||||
assert.Equal(t, user.Name, "User 2")
|
||||
|
||||
user, err = reload.Get("3")
|
||||
assert.Nil(t, err)
|
||||
assert.NotNil(t, user)
|
||||
assert.Equal(t, user.Name, "User 3")
|
||||
}
|
Loading…
Reference in New Issue
Block a user