Files
golib/database/README.md
nabbar 9e8179374b README:
- Add some README file to give missing documentations or update existing documentation file

Package Archive:
- Add some comments to godoc information
- Moving NopWriterCloser interface to ioutils package

Package IOUtils:
- New package NopWriterCloser to implement interfac like NopReader

Package Database:
- KVMap: fix missing function following update of kvdriver

Package Duration:
- Rename BDD testing

Package Context/Gin:
- Moving function New between model & interface file

Package AWS:
- rework Walk function to use more generic with standard walk caller function
- func walk will now no more return and include error (can be catched into the given func)
- func walk will now return a bool to continue or stop the loop
- func walk with many input function will now stop when all given function return false
- func walk will now return error only about main process and not given function

Package errors:
- Add interface error into interface Error

Package IOUtils:
- Moving IOWrapper as subPackage and optimize process + allow thread safe
2025-05-25 06:29:25 +02:00

16 KiB

golib database

This package provides helpers for database management, including a GORM helper and a generic Key-Value (KV) database abstraction. It is designed to simplify database operations and provide a unified interface for both relational and KV stores.

Sub-packages Overview

1. gorm

  • Purpose: Helper for GORM ORM.
  • Features:
    • Configuration struct for GORM options (transactions, connection pool, logger, etc.).
    • Database initialization and health check.
    • Context and logger registration.
    • Monitoring integration.
  • Usage:
    Use the Config struct to configure your GORM connection, then use the New function to instantiate a database connection.
    Example:
    import "github.com/nabbar/golib/database/gorm"
    
    cfg := &gorm.Config{ /* ... */ }
    db, err := gorm.New(cfg)
    
  • See gorm Subpackage for more details.

2. kvdriver

  • Purpose: Generic driver interface for Key-Value databases.
  • Features:
    • Define comparison functions for keys (equality, contains, empty).
    • Abstracts the basic operations: Get, Set, Delete, List, Search, Walk.
    • Allows custom driver implementations by providing function pointers.
  • Usage:
    Implement the required functions and use kvdriver.New to create a driver instance.
  • See kvdriver Subpackage for more details.

3. kvmap

  • Purpose: Implements a KV driver using a map[comparable]any transformation.
  • Features:
    • Serializes/deserializes models to/from map[comparable]any using JSON.
    • Useful for stores where data is naturally represented as maps.
  • Usage:
    Use kvmap.New to create a driver, providing serialization logic and storage functions.
  • See kvmap Subpackage for more details.

4. kvtable

  • Purpose: Table abstraction for KV stores, providing higher-level operations.
  • Features:
    • Operations: Get, Delete, List, Search, Walk.
    • Each table is backed by a KV driver.
  • Usage:
    Create a table with kvtable.New(driver) and use the table interface for record management.
  • See kvtable Subpackage for more details.

5. kvitem

  • Purpose: Represents a single record/item in a KV table.
  • Features:
    • Load, store, remove, and clean a record.
    • Change detection between loaded and stored state.
  • Usage:
    Use kvitem.New(driver, key) to create an item, then use its methods to manipulate the record.
  • See kvitem Subpackage for more details.

6. kvtypes

  • Purpose: Defines generic types and interfaces for KV drivers, items, and tables.
  • Features:
    • KVDriver: Interface for drivers.
    • KVItem: Interface for single records.
    • KVTable: Interface for table operations.
    • Type aliases for walk functions.

Example Usage

import (
    "github.com/nabbar/golib/database/kvdriver"
    "github.com/nabbar/golib/database/kvtable"
    "github.com/nabbar/golib/database/kvitem"
)

// Define your key and model types
type Key string
type Model struct { /* ... */ }

// Implement required functions for your storage backend
// ...

// Create a driver
driver := kvdriver.New(compare, newFunc, getFunc, setFunc, delFunc, listFunc, searchFunc, walkFunc)

// Create a table
table := kvtable.New(driver)

// Get an item
item, err := table.Get("myKey")
if err == nil {
    model := item.Get()
    // ...
}

kvdriver Subpackage

The kvdriver package provides a generic, extensible driver interface for Key-Value (KV) databases. It allows you to define custom drivers by supplying function pointers for all core operations, and supports advanced key comparison logic.

Features

  • Generic driver interface for any key (comparable) and model type
  • Customizable comparison functions for keys (equality, contains, empty)
  • Abstracts basic KV operations: Get, Set, Delete, List, Search, Walk
  • Error codes and messages integrated with the liberr package
  • Optional support for advanced search and walk operations

Main Types & Functions

Comparison Functions

Define how keys are compared and matched:

  • CompareEqual[K]: func(ref, part K) bool
  • CompareContains[K]: func(ref, part K) bool
  • CompareEmpty[K]: func(part K) bool

Create a comparison instance:

cmp := kvdriver.NewCompare(eqFunc, containsFunc, emptyFunc)

Driver Functions

Implement the following function types for your backend:

  • FuncNew[K, M]: Create a new driver instance
  • FuncGet[K, M]: Get a model by key
  • FuncSet[K, M]: Set a model by key
  • FuncDel[K]: Delete a model by key
  • FuncList[K]: List all keys
  • FuncSearch[K]: (Optional) Search keys by pattern
  • FuncWalk[K, M]: (Optional) Walk through all records

Creating a Driver

Instantiate a driver by providing all required functions:

driver := kvdriver.New(
    cmp,      // Compare[K]
    newFunc,  // FuncNew[K, M]
    getFunc,  // FuncGet[K, M]
    setFunc,  // FuncSet[K, M]
    delFunc,  // FuncDel[K]
    listFunc, // FuncList[K]
    searchFunc, // FuncSearch[K] (optional)
    walkFunc,   // FuncWalk[K, M] (optional)
)

The returned driver implements the KVDriver[K, M] interface from kvtypes.


Example

import (
    "github.com/nabbar/golib/database/kvdriver"
    "github.com/nabbar/golib/database/kvtypes"
)

type Key string
type Model struct { /* ... */ }

// Define comparison functions
eq := func(a, b Key) bool { return a == b }
contains := func(a, b Key) bool { return strings.Contains(string(a), string(b)) }
empty := func(a Key) bool { return a == "" }
cmp := kvdriver.NewCompare(eq, contains, empty)

// Implement storage functions (get, set, etc.)
// ...

driver := kvdriver.New(cmp, newFunc, getFunc, setFunc, delFunc, listFunc, nil, nil)

Error Handling

All errors are returned as liberr.Error with specific codes (e.g., ErrorBadInstance, ErrorGetFunction). Always check errors after each operation.


Notes

  • The package is fully generic and requires Go 1.18+.
  • If FuncSearch or FuncWalk are not provided, default implementations are used (based on List and Get).
  • Integrates with the kvtypes package for type definitions.

Voici une documentation en anglais pour le package github.com/nabbar/golib/database/kvmap, à inclure dans votre README.md ou documentation technique.


kvmap Subpackage

The kvmap package provides a generic Key-Value (KV) driver implementation using a map[comparable]any as the underlying storage. It serializes and deserializes models to and from maps using JSON, making it suitable for stores where data is naturally represented as maps.

Features

  • Generic driver for any key (comparable) and model type
  • Serializes/deserializes models to map[comparable]any via JSON
  • Customizable storage, retrieval, and management functions
  • Supports advanced operations: Get, Set, Delete, List, Search, Walk
  • Integrates with the kvtypes and kvdriver packages

Main Types & Functions

Function Types

  • FuncNew[K, M]: Creates a new driver instance
  • FuncGet[K, MK]: Retrieves a map for a given key
  • FuncSet[K, MK]: Stores a map for a given key
  • FuncDel[K]: Deletes a key
  • FuncList[K]: Lists all keys
  • FuncSearch[K]: (Optional) Searches keys by prefix/pattern
  • FuncWalk[K, M]: (Optional) Walks through all records

Creating a Driver

Instantiate a driver by providing all required functions:

import "github.com/nabbar/golib/database/kvmap"

driver := kvmap.New(
    cmp,      // Compare[K]
    newFunc,  // FuncNew[K, M]
    getFunc,  // FuncGet[K, MK]
    setFunc,  // FuncSet[K, MK]
    delFunc,  // FuncDel[K]
    listFunc, // FuncList[K]
    searchFunc, // FuncSearch[K] (optional)
    walkFunc,   // FuncWalk[K, M] (optional)
)

The returned driver implements the KVDriver[K, M] interface.


Example

import (
    "github.com/nabbar/golib/database/kvmap"
    "github.com/nabbar/golib/database/kvdriver"
)

type Key string
type Model struct { /* ... */ }

// Define comparison functions
cmp := kvdriver.NewCompare(eqFunc, containsFunc, emptyFunc)

// Implement storage functions (get, set, etc.)
// ...

driver := kvmap.New(cmp, newFunc, getFunc, setFunc, delFunc, listFunc, nil, nil)

Error Handling

All errors are returned as liberr.Error with specific codes (e.g., ErrorBadInstance, ErrorGetFunction). Always check errors after each operation.


Notes

  • The package is fully generic and requires Go 1.18+.
  • If FuncSearch or FuncWalk are not provided, default implementations are used (based on List and Get).
  • Serialization and deserialization use JSON under the hood.
  • Integrates with the kvtypes and kvdriver packages for type definitions and comparison logic.

Voici une documentation en anglais pour le package github.com/nabbar/golib/database/kvtable, à inclure dans votre README.md ou documentation technique.


kvtable Subpackage

The kvtable package provides a high-level table abstraction for Key-Value (KV) stores, built on top of a generic KV driver. It simplifies record management by exposing table-like operations and returning item wrappers for each record.

Features

  • Table abstraction for any key (comparable) and model type
  • Operations: Get, Delete, List, Search, Walk
  • Each table is backed by a pluggable KV driver
  • Returns KVItem wrappers for each record, enabling further manipulation
  • Integrates with the kvtypes and kvitem packages

Main Types & Functions

Creating a Table

Instantiate a table by providing a KV driver:

import (
    "github.com/nabbar/golib/database/kvtable"
    "github.com/nabbar/golib/database/kvtypes"
)

driver := /* your KVDriver[K, M] implementation */
table := kvtable.New(driver)

Table Operations

  • Get(key K) (KVItem[K, M], error): Retrieve an item by key.
  • Del(key K) error: Delete an item by key.
  • List() ([]KVItem[K, M], error): List all items in the table.
  • Search(pattern K) ([]KVItem[K, M], error): Search items by pattern.
  • Walk(fct FuncWalk[K, M]) error: Walk through all items, applying a function.

Example usage:

item, err := table.Get("myKey")
if err == nil {
    model := item.Get()
    // ...
}

Error Handling

All operations return errors as liberr.Error with specific codes (e.g., ErrorBadDriver). Always check errors after each operation.


Notes

  • The package is fully generic and requires Go 1.18+.
  • Each table instance is backed by a driver implementing the KVDriver interface.
  • Returned KVItem wrappers allow further operations like load, store, and change detection.

Voici une documentation en anglais pour le package github.com/nabbar/golib/database/kvitem, à inclure dans votre README.md ou documentation technique.


kvitem Subpackage

The kvitem package provides a generic wrapper for managing a single record (item) in a Key-Value (KV) store. It is designed to work with any key and model type, and relies on a pluggable KV driver for storage operations. The package offers change detection, atomic state management, and error handling.

Features

  • Generic item wrapper for any key (comparable) and model type
  • Load, store, remove, and clean a record
  • Change detection between loaded and stored state
  • Atomic operations for thread safety
  • Integrates with the kvtypes package for driver abstraction
  • Custom error codes and messages

Main Types & Functions

Creating an Item

Instantiate a new item by providing a KV driver and a key:

import (
    "github.com/nabbar/golib/database/kvitem"
    "github.com/nabbar/golib/database/kvtypes"
)

driver := /* your KVDriver[K, M] implementation */
item := kvitem.New(driver, key)

Item Operations

  • Set(model M): Set the model value to be stored.
  • Get() M: Get the current model (from store or last loaded).
  • Load() error: Load the model from the backend.
  • Store(force bool) error: Store the model to the backend. If force is true, always writes even if unchanged.
  • Remove() error: Remove the item from the backend.
  • Clean(): Reset the loaded and stored model to zero value.
  • HasChange() bool: Returns true if the stored model differs from the loaded model.
  • Key() K: Returns the item's key.

Example Usage

item := kvitem.New(driver, "user:123")
err := item.Load()
if err == nil {
    model := item.Get()
    // modify model...
    item.Set(model)
    if item.HasChange() {
        _ = item.Store(false)
    }
}

Error Handling

All operations return errors as liberr.Error with specific codes (e.g., ErrorLoadFunction, ErrorStoreFunction). Always check errors after each operation.


Notes

  • The package is fully generic and requires Go 1.18+.
  • Uses atomic values for thread-safe state management.
  • Integrates with the kvtypes package for driver and item interfaces.
  • Change detection is based on deep equality of loaded and stored models.

Voici une documentation en anglais pour le package github.com/nabbar/golib/database/gorm, à inclure dans votre README.md ou documentation technique.


gorm Subpackage

The gorm package provides helpers for configuring, initializing, and managing GORM database connections in Go applications. It offers advanced configuration options, context and logger integration, connection pooling, and monitoring support.

Features

  • Configuration struct for all GORM options (driver, DSN, transactions, pooling, etc.)
  • Database initialization and health checking
  • Context and logger registration
  • Monitoring integration for health and metrics
  • Error codes and messages for robust error handling
  • Support for multiple database drivers (MySQL, PostgreSQL, SQLite, SQL Server, ClickHouse)

Main Types & Functions

Config Struct

Defines all configuration options for a GORM database connection:

  • Driver: Database driver (mysql, psql, sqlite, sqlserver, clickhouse)
  • Name: Instance name for status/monitoring
  • DSN: Data Source Name (connection string)
  • Transaction, pooling, and migration options
  • Monitoring configuration

Example Usage

import (
    "github.com/nabbar/golib/database/gorm"
)

cfg := &gorm.Config{
    Driver: gorm.DriverMysql,
    Name:   "main-db",
    DSN:    "user:pass@tcp(localhost:3306)/dbname",
    EnableConnectionPool: true,
    PoolMaxIdleConns: 5,
    PoolMaxOpenConns: 10,
    // ... other options
}

db, err := gorm.New(cfg)
if err != nil {
    // handle error
}
defer db.Close()

Registering Logger and Context

import (
    "github.com/nabbar/golib/logger"
    "github.com/nabbar/golib/context"
)

cfg.RegisterLogger(func() logger.Logger { /* ... */ }, false, 200*time.Millisecond)
cfg.RegisterContext(func() context.Context { /* ... */ })

Monitoring

You can enable monitoring and health checks for your database instance:

mon, err := db.Monitor(version)
if err != nil {
    // handle error
}

Error Handling

All errors are returned as liberr.Error with specific codes (e.g., ErrorDatabaseOpen, ErrorValidatorError). Always check errors after each operation.


Supported Drivers

  • MySQL
  • PostgreSQL
  • SQLite
  • SQL Server
  • ClickHouse

Select the driver using the Driver field in the config.


Notes

  • The package is thread-safe and uses atomic values for state management.
  • Integrates with the liberr, liblog, and libctx packages for error, logging, and context management.
  • Monitoring is based on the monitor subpackage and can be customized via the config.