Documentation
¶
Overview ¶
Example (Clustered) ¶
Example_clustered demonstrates how to use the Database in Clustered mode. This mode uses Redis for caching and assumes a shared filesystem (or just local for this demo).
package main
import (
"context"
"fmt"
"os"
"github.com/sharedcode/sop"
"github.com/sharedcode/sop/adapters/redis"
"github.com/sharedcode/sop/database"
)
func main() {
// 1. Initialize Redis connection (Required for Clustered mode).
// In a real app, this is done once at startup.
redisOpts := redis.Options{
Address: "localhost:6379",
DB: 0,
}
if _, err := redis.OpenConnection(redisOpts); err != nil {
// If Redis is not available, we skip this example or handle error.
fmt.Println("Redis not available, skipping clustered example.")
return
}
defer redis.CloseConnection()
// 2. Define storage path.
storagePath, _ := os.MkdirTemp("", "sop_clustered_example")
defer os.RemoveAll(storagePath)
// 3. Initialize Database in Clustered mode.
// This will use the registered Redis cache.
db, _ := database.ValidateOptions(sop.DatabaseOptions{
Type: sop.Clustered,
StoresFolders: []string{storagePath},
CacheType: sop.Redis,
})
// 4. Start a transaction.
ctx := context.Background()
tx, err := database.BeginTransaction(ctx, db, sop.ForWriting)
if err != nil {
fmt.Printf("Failed to begin transaction: %v\n", err)
return
}
// 5. Create a B-Tree.
store, err := database.NewBtree[string, string](ctx, db, "products", tx, nil)
if err != nil {
fmt.Printf("Failed to create btree: %v\n", err)
tx.Rollback(ctx)
return
}
// 6. Add data.
if _, err := store.Add(ctx, "p1", "Laptop"); err != nil {
fmt.Printf("Failed to add item: %v\n", err)
tx.Rollback(ctx)
return
}
// 7. Commit.
if err := tx.Commit(ctx); err != nil {
fmt.Printf("Failed to commit: %v\n", err)
return
}
fmt.Println("Clustered transaction committed successfully.")
}
Output:
Example (Infs_direct) ¶
Example_infs_direct demonstrates how to use the infs package directly. This gives you full control over the transaction options and cache.
package main
import (
"context"
"fmt"
"os"
"github.com/sharedcode/sop"
"github.com/sharedcode/sop/infs"
)
func main() {
// 1. Define storage path.
storagePath, _ := os.MkdirTemp("", "sop_infs_direct_example")
defer os.RemoveAll(storagePath)
// 2. Create Transaction Options.
// Here we explicitly choose InMemory cache.
opts := sop.TransactionOptions{
StoresFolders: []string{storagePath},
CacheType: sop.InMemory,
Mode: sop.ForWriting,
}
// 3. Start a transaction.
ctx := context.Background()
tx, err := infs.NewTransaction(ctx, opts)
if err != nil {
fmt.Printf("Failed to create transaction: %v\n", err)
return
}
if err := tx.Begin(ctx); err != nil {
fmt.Printf("Failed to begin transaction: %v\n", err)
return
}
// 4. Create a strongly-typed B-Tree.
// Unlike Database.NewBtree which returns BtreeInterface[any, any],
// infs.NewBtree allows specific types.
so := sop.StoreOptions{
Name: "scores",
SlotLength: 100,
IsUnique: true,
IsValueDataInNodeSegment: true,
}
store, err := infs.NewBtree[string, int](ctx, so, tx, nil)
if err != nil {
fmt.Printf("Failed to create btree: %v\n", err)
tx.Rollback(ctx)
return
}
// 5. Add data.
if _, err := store.Add(ctx, "Player1", 100); err != nil {
fmt.Printf("Failed to add item: %v\n", err)
tx.Rollback(ctx)
return
}
// 6. Commit.
if err := tx.Commit(ctx); err != nil {
fmt.Printf("Failed to commit: %v\n", err)
return
}
fmt.Println("Direct infs transaction committed successfully.")
}
Output: Direct infs transaction committed successfully.
Example (Standalone) ¶
Example_standalone demonstrates how to use the Database in Standalone mode. This mode uses an in-memory cache and local filesystem storage.
package main
import (
"context"
"fmt"
"os"
"github.com/sharedcode/sop"
"github.com/sharedcode/sop/database"
)
func main() {
// 1. Define storage path.
storagePath, _ := os.MkdirTemp("", "sop_standalone_example")
defer os.RemoveAll(storagePath) // Clean up previous run
// 1. Initialize Database (Standalone or Clustered)
// Standalone uses in-memory caching; Clustered uses Redis.
db, _ := database.ValidateOptions(sop.DatabaseOptions{
Type: sop.Standalone,
StoresFolders: []string{storagePath},
CacheType: sop.InMemory,
}) // 3. Start a transaction.
ctx := context.Background()
// You can pass options, but defaults are usually sufficient for standalone.
tx, err := database.BeginTransaction(ctx, db, sop.ForWriting)
if err != nil {
fmt.Printf("Failed to begin transaction: %v\n", err)
return
}
// 4. Create or Open a B-Tree.
// Using the generic NewBtree helper from Database.
store, err := database.NewBtree[string, string](ctx, db, "users", tx, nil)
if err != nil {
fmt.Printf("Failed to create btree: %v\n", err)
tx.Rollback(ctx)
return
}
// 5. Perform operations.
// Note: The generic store uses 'any' for Key and Value.
// For strict typing, use infs.NewBtree[K, V] directly with the transaction.
if _, err := store.Add(ctx, "user1", "Alice"); err != nil {
fmt.Printf("Failed to add item: %v\n", err)
tx.Rollback(ctx)
return
}
// 6. Commit the transaction.
if err := tx.Commit(ctx); err != nil {
fmt.Printf("Failed to commit: %v\n", err)
return
}
fmt.Println("Standalone transaction committed successfully.")
// Verify data
tx, _ = database.BeginTransaction(ctx, db, sop.ForReading)
store, _ = database.OpenBtree[string, string](ctx, db, "users", tx, nil)
found, _ := store.Find(ctx, "user1", false)
if found {
val, _ := store.GetCurrentValue(ctx)
fmt.Printf("Found user1: %v\n", val)
}
tx.Commit(ctx)
}
Output: Standalone transaction committed successfully. Found user1: Alice
Index ¶
- func BeginTransaction(ctx context.Context, config sop.DatabaseOptions, mode sop.TransactionMode, ...) (sop.Transaction, error)
- func CursorOnOpenedBtree[TK btree.Ordered, TV any](ctx context.Context, config sop.DatabaseOptions, name string, ...) (btree.BtreeInterface[TK, TV], error)
- func GetOptions(ctx context.Context, folderPath string) (sop.DatabaseOptions, error)
- func IsDatabasePath(path string) (bool, bool)
- func NewBtree[TK btree.Ordered, TV any](ctx context.Context, config sop.DatabaseOptions, name string, ...) (btree.BtreeInterface[TK, TV], error)
- func OpenBtree[TK btree.Ordered, TV any](ctx context.Context, config sop.DatabaseOptions, name string, ...) (btree.BtreeInterface[TK, TV], error)
- func OpenBtreeCursor[TK btree.Ordered, TV any](ctx context.Context, config sop.DatabaseOptions, name string, ...) (btree.BtreeInterface[TK, TV], error)
- func ReinstateFailedDrives(ctx context.Context, config sop.DatabaseOptions) error
- func Remove(ctx context.Context, dbPath string) error
- func RemoveBtree(ctx context.Context, config sop.DatabaseOptions, name string) error
- func RemoveBtrees(ctx context.Context, config sop.DatabaseOptions) error
- func ValidateCassandraOptions(config sop.DatabaseOptions) (sop.DatabaseOptions, error)
- func ValidateOptions(config sop.DatabaseOptions) (sop.DatabaseOptions, error)
- type DatabaseOptions
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func BeginTransaction ¶
func BeginTransaction(ctx context.Context, config sop.DatabaseOptions, mode sop.TransactionMode, maxTime ...time.Duration) (sop.Transaction, error)
BeginTransaction starts a new transaction.
func CursorOnOpenedBtree ¶
func CursorOnOpenedBtree[TK btree.Ordered, TV any](ctx context.Context, config sop.DatabaseOptions, name string, t sop.Transaction) (btree.BtreeInterface[TK, TV], error)
CursorOnOpenedBtree opens a cursor wrapper for a given opened Btree.
func GetOptions ¶
GetOptions reads the database options from the specified folder.
func IsDatabasePath ¶
IsDatabasePath returns true (hasDBOptions), true (hasRegHashMod) if folder path has necessary ingredients of a SOP DB.
func NewBtree ¶
func NewBtree[TK btree.Ordered, TV any](ctx context.Context, config sop.DatabaseOptions, name string, t sop.Transaction, comparer btree.ComparerFunc[TK], options ...sop.StoreOptions) (btree.BtreeInterface[TK, TV], error)
NewBtree will open an existing one or create a new general purpose B-Tree store.
func OpenBtree ¶
func OpenBtree[TK btree.Ordered, TV any](ctx context.Context, config sop.DatabaseOptions, name string, t sop.Transaction, comparer btree.ComparerFunc[TK]) (btree.BtreeInterface[TK, TV], error)
OpenBtree opens a general purpose B-Tree store. This allows the Database to manage standard Key-Value stores alongside AI stores.
func OpenBtreeCursor ¶
func OpenBtreeCursor[TK btree.Ordered, TV any](ctx context.Context, config sop.DatabaseOptions, name string, t sop.Transaction, comparer btree.ComparerFunc[TK]) (btree.BtreeInterface[TK, TV], error)
OpenBtreeCursor opens a cursor wrapper for a given Btree. It opens it if it is not yet.
func ReinstateFailedDrives ¶
func ReinstateFailedDrives(ctx context.Context, config sop.DatabaseOptions) error
ReinstateFailedDrives asks the replication tracker to reinstate failed passive targets. This API is only applicable for infs backend.
func RemoveBtree ¶
RemoveBtree removes a B-Tree store from the database. This is a destructive operation and cannot be undone.
func RemoveBtrees ¶
func RemoveBtrees(ctx context.Context, config sop.DatabaseOptions) error
RemoveBtrees removes all B-Trees (stores) in the database. This is a destructive operation and cannot be undone. This function ensures a clean removal of all stores and their metadata (e.g. Redis keys).
func ValidateCassandraOptions ¶
func ValidateCassandraOptions(config sop.DatabaseOptions) (sop.DatabaseOptions, error)
ValidateCassandraOptions validates and prepares the database options for Cassandra.
func ValidateOptions ¶
func ValidateOptions(config sop.DatabaseOptions) (sop.DatabaseOptions, error)
ValidateOptions validates and prepares the database options. It infers CacheType if not set.
Types ¶
type DatabaseOptions ¶
type DatabaseOptions = sop.DatabaseOptions
DatabaseOptions holds the configuration for the database. Deprecated: Use sop.DatabaseOptions instead.
func Setup ¶
func Setup(ctx context.Context, opts sop.DatabaseOptions) (DatabaseOptions, error)
Setup persists the database options to the stores folders. This is a one-time setup operation for the database. It ensures the options are saved to all StoresFolders.