VoidStruct
VoidStruct is a simple Go package that provides a type-safe way to persist Go structs using voidDB Key-Value Database. It handles the serialization (via gob) and compression (via minlz) of types, allowing you to store and retrieve them by a key within their respective struct type "bucket" aka "namespace".
Installation
To install voidstruct, use go get:
go get gitlab.com/figuerom16/voidstruct
Usage
To start using voidstruct, you typically set up a database connection and then obtain a handle to a typed table. For brevity, the following examples assume the User struct and the initial db and users table setup as shown below. Error handling is omitted in individual function examples but should be handled in real applications.
User Struct Definition
First, define your struct (e.g., User):
type User struct {
ID int
Name string
Age int
}
Basic Setup (Opening DB and Creating a Table)
This example shows how to initialize the database and get a table handle. Subsequent examples assume this setup.
package main
import (
"log" // For error handling
"fmt" // For printing output
"gitlab.com/figuerom16/voidstruct"
)
// User struct definition as above
type User struct {
ID int
Name string
Age int
}
func main() {
// Open or create a voidDB instance.
// The first argument "" uses the default path ("voiddb/voidstruct").
// The second argument 0 uses the default capacity (1TB).
db, err := voidstruct.Open("", 0)
if err != nil {
log.Fatalf("Failed to open voidstruct: %v", err)
}
defer db.Close() // Ensure the database is closed when the application exits.
// Get a table handle for the User struct type.
// The 'true' argument enables write-back (mustSync), ensuring data is flushed to disk on commit.
// NewTable returns an error if the type is not supported.
users, err := voidstruct.NewTable[User](db, true)
if err != nil {
log.Fatalf("Failed to get User table: %v", err)
}
// Now you can use the 'users' table to store and retrieve User structs.
// Examples below demonstrate various operations, assuming 'db' and 'users' are already set up.
// Error handling (e.g., `if err != nil { log.Fatalf(...) }`) is omitted for brevity in
// individual function examples but should be handled in real applications.
// Example usage of Set and Get
user1 := &User{ID: 1, Name: "Alice", Age: 30}
users.Set("alice_key", user1)
fmt.Printf("Set user1: %+v\n", user1)
retrievedUser1, _ := users.Get("alice_key")
fmt.Printf("Retrieved user1: %+v\n", retrievedUser1)
}
Working with Data
The following examples demonstrate specific operations on a Table[T] instance (e.g., users from the setup above).
Set and SetValue - Store a single struct
Set stores a value pointed to by v. SetValue stores the value v directly.
user1 := &User{ID: 1, Name: "Alice", Age: 30}
if err := users.Set("alice_key", user1); err != nil { /* handle error */ }
fmt.Printf("Set user1: %+v\n", user1)
user2 := User{ID: 2, Name: "Bob", Age: 25}
if err := users.SetValue("bob_key", user2); err != nil { /* handle error */ }
fmt.Printf("Set user2: %+v\n", user2)
Get and GetValue - Retrieve a single struct by its key
Get retrieves a value and returns a pointer to it. GetValue retrieves a value directly.
retrievedUser1, err := users.Get("alice_key")
if err != nil { /* handle error */ }
fmt.Printf("Retrieved user1: %+v\n", retrievedUser1)
retrievedUser2, err := users.GetValue("bob_key")
if err != nil { /* handle error */ }
fmt.Printf("Retrieved user2: %+v\n", retrievedUser2)
GetMany and GetManyValue - Retrieve multiple structs by their keys
GetMany retrieves multiple values and returns a map of keys to pointers. GetManyValue retrieves multiple values as a map of values. If a key is not found, it is simply omitted from the returned map, no error is returned for missing keys.
// Store some additional users for GetMany demonstration
users.Set("charlie_key", &User{ID: 3, Name: "Charlie", Age: 35})
users.Set("david_key", &User{ID: 4, Name: "David", Age: 40})
// Retrieve multiple users by pointer
keysToGet := []string{"alice_key", "charlie_key", "non_existent_key"}
retrievedUsersPtr, err := users.GetMany(keysToGet...)
if err != nil { /* handle error */ }
fmt.Printf("Retrieved multiple users (ptr): %+v\n", retrievedUsersPtr)
// Output might not include "non_existent_key"
// Retrieve multiple users by value
retrievedUsersValue, err := users.GetManyValue("bob_key", "david_key", "another_non_existent")
if err != nil { /* handle error */ }
fmt.Printf("Retrieved multiple users (value): %+v\n", retrievedUsersValue)
SetMany and SetManyValue - Store multiple key-value pairs
SetMany stores a map of key-value pairs where values are pointers. SetManyValue stores a map where values are structs directly.
usersToSetPtr := map[string]*User{
"charlie_key": {ID: 3, Name: "Charlie", Age: 35},
"david_key": {ID: 4, Name: "David", Age: 40},
}
if err := users.SetMany(usersToSetPtr); err != nil { /* handle error */ }
fmt.Println("Set many users (ptr).")
usersToSetValue := map[string]User{
"eve_key": {ID: 5, Name: "Eve", Age: 28},
}
if err := users.SetManyValue(usersToSetValue); err != nil { /* handle error */ }
fmt.Println("Set many users (value).")
GetAll and GetAllValue - Retrieve all key-value pairs
GetAll retrieves all key-value pairs as a map of pointers. GetAllValue retrieves all key-value pairs as a map of values.
allUsersPtr, err := users.GetAll()
if err != nil { /* handle error */ }
fmt.Printf("All users (ptr): %+v\n", allUsersPtr)
allUsersValue, err := users.GetAllValue()
if err != nil { /* handle error */ }
fmt.Printf("All users (value): %+v\n", allUsersValue)
Keys - Retrieve all keys from the table
Returns a sorted slice of all keys in the table.
allUserKeys := users.Keys()
fmt.Printf("All user keys: %+v\n", allUserKeys)
Has - Check if a key exists in the table
if users.Has("alice_key") {
fmt.Println("Key 'alice_key' exists.")
} else {
fmt.Println("Key 'alice_key' does not exist.")
}
Len - Get the number of keys in the table
fmt.Printf("Number of users in table: %d\n", users.Len())
Del - Delete a key-value pair from the table
if err := users.Del("charlie_key"); err != nil { /* handle error */ }
fmt.Println("Deleted 'charlie_key'.")
Purge - Remove all key-value pairs from the table
if err := users.Purge(); err != nil { /* handle error */ }
fmt.Println("Purged users table.")
// Verify purge
remainingUsers := users.Keys()
fmt.Printf("Keys after purge: %+v (Expected empty)\n", remainingUsers)