Create your module
With Go 1.26 or later installed, make a new application directory:
mkdir zeedb-app
cd zeedb-app
go mod init example.com/zeedb-app
go get github.com/Berlindraft/ZeeDB
These commands create your own application module. They are separate from running the existing repository examples. If repository access is private, use your normal Git/Go private-module configuration.
Create main.go
This complete program opens ./data, commits two records together, reads one, scans the range, and closes while preserving errors. Its data directory persists between runs.
package main
import (
"context"
"errors"
"fmt"
"os"
zeedb "github.com/Berlindraft/ZeeDB"
)
func main() {
if err := run(); err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
}
func run() (err error) {
db, err := zeedb.Open("./data", zeedb.Options{
Durability: zeedb.Durable,
})
if err != nil {
return err
}
defer func() { err = errors.Join(err, db.Close()) }()
ctx := context.Background()
if err := db.WriteBatch(ctx, []zeedb.Mutation{
{Collection: "users", Key: []byte("1024"), Value: []byte(`{"name":"Ada"}`)},
{Collection: "users", Key: []byte("1025"), Value: []byte(`{"name":"Grace"}`)},
}); err != nil {
return err
}
value, err := db.Get(ctx, "users", []byte("1024"))
if errors.Is(err, zeedb.ErrNotFound) {
return errors.New("expected user 1024 is absent")
}
if err != nil {
return err
}
fmt.Println(string(value))
records, err := db.Scan(ctx, "users", zeedb.ScanOptions{
Start: []byte("1024"),
End: []byte("1026"),
Limit: 2,
})
if err != nil {
return err
}
for _, record := range records {
fmt.Printf("%s: %s (version %d)\n",
record.Key, record.Value, record.Version)
}
return nil
}
Run it
go run .
The first output line is {"name":"Ada"}. The scan prints keys 1024 and 1025 with their values and shared batch version. Rerunning replaces the same keys and advances the commit sequence; versions are not fixed example IDs.
There is no need to run a server or call Flush after each mutation. Default durable acknowledgement follows WAL sync. Close syncs pending writes and releases the directory lock.
Understand the example’s boundaries
- The byte values happen to contain JSON; no schema validation happens inside the engine.
- The batch is atomic. The later Get and Scan are separate read snapshots.
- The deferred close error is joined with any earlier application error.
- A write/checkpoint I/O error can be indeterminate; reopen and reconcile before retrying non-idempotent work.
- Only this process may own the
./datadirectory while the program is open.
The program intentionally keeps its data. Unlike the temporary repository examples, it never removes the application’s directory.
Next steps
Use a typed JSON repository for application validation, coordinated writes for read-modify-write invariants, and bounded pagination for larger collections. Review deployment before selecting real filesystem paths and budgets.