unified storage
- Go 99.9%
- Nix 0.1%
| _examples | feat: dlht driver & watch | |
| drivers | feat: dlht driver & watch | |
| server | feat: dlht driver & watch | |
| .gitignore | chore: init | |
| devenv.lock | feat: dlht driver & watch | |
| devenv.nix | chore: init | |
| devenv.yaml | chore: init | |
| driver.go | feat: dlht driver & watch | |
| go.mod | feat: dlht driver & watch | |
| go.sum | feat: dlht driver & watch | |
| keys.go | feat: mount drivers | |
| LICENSE | Initial commit | |
| meta.go | feat: base interface | |
| README.md | chore: readme | |
| snapshot.go | feat: snapshot & fs driver | |
| storage.go | feat: dlht driver & watch | |
storage
unified key-value storage for go.
keys are normalized: colons become slashes, uppercase becomes lowercase, so
user:aliceandUSER/Aliceboth end up asuser/alice.
you can plug in different backends through a common interface:
- memory — everything stays in ram, gone when the program exits
- fs — each key is a file on disk, metadata lives in sidecar json files
- dlht — backed by a concurrent hash map
- http — talks to a remote storage server over http
basic usage
import"codeberg.org/ungo/storage"import"codeberg.org/ungo/storage/drivers/memory"s:=storage.New(memory.New())// store and retrieve typed values (json in/out)s.SetItem(ctx,"users/1",User{Name:"alice"})varuUsers.GetItem(ctx,"users/1",&u)// or store raw bytess.SetRaw(ctx,"images/icon.png",pngBytes)data,_:=s.GetRaw(ctx,"images/icon.png")mounts
you can mount multiple backends under key prefixes. lookups go through mounts in reverse order (last mount wins):
s:=storage.New(memory.New())s.Mount("files",fs.New("./data"))s.Mount("cache",memory.New())s.SetRaw(ctx,"files/doc.txt",content)// goes to fs drivers.SetRaw(ctx,"cache/temp.json",data)// goes to memory drivers.SetRaw(ctx,"settings.json",cfg)// goes to root memory driverwatching changes
backends that support it can notify you of changes in real time:
events,_:=s.Watch(ctx,"")fore:=rangeevents{// e.event is "update" or "remove", e.key is the changed key}snapshot and restore
export and re-import all data for backups or migration:
snap,_:=s.Snapshot(ctx,"")fresh:=storage.New(memory.New())fresh.Hydrate(ctx,snap)http server
the server package exposes a storage over http with rest endpoints and real-time updates via server-sent events:
s:=storage.New(memory.New())srv:=server.New(s,server.Options{})http.ListenAndServe(":8080",srv.Handler())then use the http driver from any client:
client:=storage.New(httpdriver.New(httpdriver.Options{Base:"http://localhost:8080",}))drivers
| driver | import path | description |
|---|---|---|
| memory | drivers/memory |
in-memory map, fast, ephemeral |
| fs | drivers/fs |
filesystem-backed, persistent |
| dlht | drivers/dlht |
concurrent hash map backend |
| http | drivers/http |
remote storage via http |
you can implement custom drivers using the Driver interface anyways.
see _examples/ for runnable code.