7
2
Fork
You've already forked storage
0
unified storage
  • Go 99.9%
  • Nix 0.1%
2026年06月02日 23:16:39 +02:00
_examples feat: dlht driver & watch 2026年06月02日 23:11:58 +02:00
drivers feat: dlht driver & watch 2026年06月02日 23:11:58 +02:00
server feat: dlht driver & watch 2026年06月02日 23:11:58 +02:00
.gitignore chore: init 2026年04月25日 17:58:27 +02:00
devenv.lock feat: dlht driver & watch 2026年06月02日 23:11:58 +02:00
devenv.nix chore: init 2026年04月25日 17:58:27 +02:00
devenv.yaml chore: init 2026年04月25日 17:58:27 +02:00
driver.go feat: dlht driver & watch 2026年06月02日 23:11:58 +02:00
go.mod feat: dlht driver & watch 2026年06月02日 23:11:58 +02:00
go.sum feat: dlht driver & watch 2026年06月02日 23:11:58 +02:00
keys.go feat: mount drivers 2026年04月25日 18:08:24 +02:00
LICENSE Initial commit 2026年04月25日 17:54:54 +02:00
meta.go feat: base interface 2026年04月25日 18:02:09 +02:00
README.md chore: readme 2026年06月02日 23:16:39 +02:00
snapshot.go feat: snapshot & fs driver 2026年04月25日 23:00:44 +02:00
storage.go feat: dlht driver & watch 2026年06月02日 23:11:58 +02:00

storage

unified key-value storage for go.

keys are normalized: colons become slashes, uppercase becomes lowercase, so user:alice and USER/Alice both end up as user/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 driver

watching 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.