stdlib

package module
v0.3.8 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Feb 26, 2025 License: MIT Imports: 22 Imported by: 0

README

Newcore.gg Standard Libraries

Welcome to the Newcore Standard Library, a comprehensive suite of reusable components designed for seamless integration across all Newcore repositories and services. These libraries offer robust functionality, streamline development, and promote consistency throughout projects.

Test Coverage: 11.3%

Overview

The Newcore Standard Library includes key packages for common functionalities such as configuration management, database connections, structured logging, and standardized HTTP responses. Each package is designed to be modular and easy to integrate into different projects.

Docs

Explore the available utilities in docs/ folder

  • configuration: Manage and load application configuration from environment files.
  • database: Establish and manage database connections with support for PostgreSQL, MySQL, and MariaDB.
  • logger: A structured logging package with support for JSON formatting and log file rotation.
  • stdResponses: Simplifies the creation of standardized HTTP responses and error handling for APIs.

Getting Started

Prerequisites

Ensure you have the following in place before using the libraries:

  • Using Fiber version 3.x
  • Go version 1.23 or higher: Ensure you have the latest version of Go installed on your system.
  • .env file: Required for loading configuration details such as database credentials. Refer to the .env.example file in the repository for a template to get started.
Installation

Add the desired libraries to your project using Go modules:

$ go get github.com/newcore-network/go-stdlib

for all libraries

Simple configuration

To set up your application using the configuration library:

  • Create a .env file: This file should contain all necessary environment variables for your application, such as database host, user, password, etc.
  • Load configuration: Use the configuration package to load and manage your application settings.
#Configure the database connection
POSTGRES_HOST=postgres
POSTGRES_USER=postgres
POSTGRES_PASSWORD=admin
POSTGRES_DATABASE=altv
POSTGRES_PORT=5432
POSTGRES_SSLMODE=false

# Configure the redis connection

REDIS_HOST=redis
REDIS_PORT=6379
REDIS_PASSWORD=admin
REDIS_DB=0
Usage in your Go application:
import (
    "github.com/newcore-network/go-stdlib"
)

func main() {
    config := stdlib.LoadCfg(".env")
    // Now you can use the `config` object in your application
    // -> Check the list of libraries to review their documentation and learn how to implement each one... <-
}

Documentation

Index

Constants

View Source
const DISABLE string = "disable"

use for disable status in the .env file

View Source
const ENABLE string = "enable"

use for enable status in the .env file

View Source
const ERRLoading string = "Error loading .env file"

use for error loading response

View Source
const ERRPort string = "failed to get the port"

use for port error

View Source
const POSTGRES_DATABASE string = "POSTGRES_DATABASE"

use for get the DATABASE from the .env file

View Source
const POSTGRES_HOST string = "POSTGRES_HOST"

use for get the HOST from the .env file

View Source
const POSTGRES_PASSWORD string = "POSTGRES_PASSWORD"

use for get the PASSWORD from the .env file

View Source
const POSTGRES_PORT string = "POSTGRES_PORT"

use for get the PORT from the .env file

View Source
const POSTGRES_SSLMODE string = "POSTGRES_SSLMODE"

use for get the SSLMODE from the .env file

View Source
const POSTGRES_USER string = "POSTGRES_USER"

use for get the USER from the .env file

View Source
const REDISDB string = "REDIS_DB"

use for get the REDISDB from the .env file

View Source
const REDISHOST string = "REDIS_HOST"

use for get the REDISHOST from the .env file

View Source
const REDISPORT string = "REDIS_PORT"

use for get the REDISPORT from the .env file

Variables

This section is empty.

Functions

func CaptureError

func CaptureError(err error, msg string, fields map[string]interface{})

CaptureError logs an error message with an additional error object.

func CreateCacheRepository

func CreateCacheRepository[T any](redisClient *redis.Client, ctx context.Context, self AbstractCacheRepository[T]) *abstractCacheRepositoryImpl[T]

CreateCacheRepository initializes a new instance of 'abstractCacheRepositoryImpl' with the given Redis client, context, and an self-reference.

This function serves as a factory for creating a generic cache repository implementation, ensuring proper dependency injection and type management.

Generic Parameters:

  • T: The type of data that will be stored and retrieved from the cache.

Parameters:

  • redisClient (*redis.Client): The Redis client instance used for cache operations. This must not be nil, otherwise the function will panic.
  • ctx (context.Context): The execution context, used for managing timeouts and cancellations in cache operations. This must not be nil, otherwise the function will panic.
  • self (AbstractCacheRepository[T]): A reference to a specific repository implementation. This is used to override or add methods. And is the way to represente your concrete type.

Returns:

  • *abstractCacheRepositoryImpl[T]: A pointer to the newly created cache repository instance.

Panics:

  • If `redisClient` is nil, it panics with the message "[lib] redisClient is nil".
  • If `ctx` is nil, it panics with the message "[lib] ctx is nil".

Example Usage:

type AccountCacheRepository struct {
stdlib.AbstractCacheRepository[*data.Account] // here is your concrete type save (struct pointer)
}

func NewAccountCacheRepository(client *redis.Client, ctx context.Context) *AccountCacheRepository {
	repo := &AccountCacheRepository{} // need to be a pointer to reference your repository
	repo.AbstractCacheRepository = stdlib.CreateCacheRepository(client, ctx, repo)
	return repo
}

func CreateRepository

func CreateRepository[T Identifiable[K], K ID](gormDB *gorm.DB, self AbstractRepository[T, K]) *abstractRepositoryImpl[T, K]

CreateRepository initializes a new instance of `abstractRepositoryImpl` with the provided GORM database instance and a self-reference.

This function acts as a factory method for setting up a generic database repository, ensuring proper dependency injection and type handling.

Generic Parameters:

  • T: The type representing the database entity, which must implement the `Identifiable[K]` interface.
  • K: The type of the entity's primary key (ID), constrained to supported ID types.

Parameters:

  • gormDB (*gorm.DB): The GORM database instance used for entity persistence. This must not be nil, otherwise the function will panic.
  • self (AbstractRepository[T, K]): A reference to the specific repository implementation. This is used to allow method overrides or extensions by the concrete repository.

Returns:

  • *abstractRepositoryImpl[T, K]: A pointer to the newly created repository instance.

Panics:

  • If `gormDB` is nil, it panics with the message "[lib] gormDB is nil".
  • If `self` is nil, it panics with the message "[lib] self is nil".

Example Usage:

// Define the concrete repository type.
type AccountRepository struct {
	stdlib.AbstractRepository[*models.Account, uint]
}

// Implement a constructor function for the repository.
func NewAccountRepository(gormDB *gorm.DB) *AccountRepository {
	repo := &AccountRepository{} // Must be a pointer to reference the repository.
	repo.AbstractRepository = stdlib.CreateRepository(gormDB, repo)
	return repo
}

The `self` parameter ensures that methods defined in the concrete repository (`AccountRepository`) are correctly referenced, enabling method overriding if needed.

func Debug

func Debug(msg string, fields map[string]interface{})

Debug logs a debug message, typically used for low-level system information.

func ErrBadRequest

func ErrBadRequest(c fiber.Ctx, err error) error

ErrBadRequest logs a bad request error and returns a JSON response

func ErrConflict

func ErrConflict(c fiber.Ctx, err error) error

ErrConflict logs a conflict error and returns a JSON response

func ErrEmptyParametersOrArguments

func ErrEmptyParametersOrArguments(c fiber.Ctx) error

ErrEmptyParametersOrArguments logs an error for missing parameters and returns a JSON response

func ErrForbbiden

func ErrForbbiden(c fiber.Ctx, err error) error

ErrForbbiden logs a forbidden error and returns a JSON response

func ErrInternalServer

func ErrInternalServer(c fiber.Ctx, err error) error

ErrInternalServer logs an internal server error and returns a JSON response

func ErrNotFound

func ErrNotFound(c fiber.Ctx) error

ErrNotFound logs a not found error and returns a JSON response

func ErrUUIDParse

func ErrUUIDParse(c fiber.Ctx, id string) error

ErrUUIDParse logs a bad UUID error and returns a JSON response

func ErrUnauthorized

func ErrUnauthorized(c fiber.Ctx, err error) error

ErrUnauthorized logs an unauthorized error and returns a JSON response

func Error

func Error(msg string, fields map[string]interface{})

Error logs an error message, including context such as file and line number.

func Fatal

func Fatal(msg string, fields map[string]interface{})

Fatal logs a fatal error message and exits the application.

func Info

func Info(msg string, fields map[string]interface{})

Info logs an informational message.

func InitLogger

func InitLogger(devMode bool)

func NewRedisConnection

func NewRedisConnection(ctx context.Context, cfg StdLibConfiguration) *redis.Client

NewRedisConnection creates a new Redis client and pings the server to ensure connectivity. If the connection fails, it panics.

func PersonalizedErr

func PersonalizedErr(c fiber.Ctx, message string, status int) error

PersonalizedErr returns an error with a custom message and status code

func RegisterValidatorErr

func RegisterValidatorErr(c fiber.Ctx, errs error) error

RegisterValidatorErr logs validation errors and returns a JSON response

func Standard

func Standard(c fiber.Ctx, message string, data interface{}) error

func StandardCreated

func StandardCreated(c fiber.Ctx, message string, data interface{}) error

func Warn

func Warn(msg string, fields map[string]interface{})

Warn logs a warning message.

Types

type AbstractCacheRepository

type AbstractCacheRepository[T any] interface {

	// Get retrieves a value by its key from the cache.
	// If the value is a struct, it will be deserialized from JSON.
	// Returns a pointer to the value or nil if the key does not exist.
	Get(key string) (valueModel T, err error)

	// GetKeysByPatterns retrieves keys by a pattern from the cache.
	// Returns a slice of keys that match the pattern.
	GetKeysByPatterns(pattern string) (keys []string, err error)

	// Set stores a value in the cache with the specified expiration time.
	// If the value is a struct, it will be serialized to JSON.
	// Returns an error if the operation fails.
	Set(key string, value T, expiration time.Duration) error

	// Del deletes a value from the cache by its key.
	// Returns an error if the operation fails.
	Del(key string) error

	// Exists checks if a key exists in the cache.
	// Returns true if the key exists, false otherwise.
	Exists(key string) (bool, error)

	// HGet retrieves a single field value from a hash in Redis.
	// The method returns the value associated with the specified field
	// and nil if the field does not exist or an error occurs.
	HGet(key string, field string) (*any, error)

	// HGetAll retrieves all fields and their associated values from a hash in Redis.
	// The method returns a map of field names to values or an error if the operation fails.
	HGetAll(key string) (map[string]any, error)

	// HScan iterates over fields in a hash by a pattern.
	// Returns the matching fields and their values.
	HScan(key string, pattern string, count int64) (map[string]string, error)

	// HGetFields retrieves specific fields and their associated values from a hash in Redis.
	// The method returns a map of the requested field names to their values.
	// Fields not found in the hash are excluded from the returned map.
	HGetFields(key string, fields ...string) (map[string]any, error)

	// HSet sets a single field in a hash in Redis.
	// This method stores the specified value under the given field name,
	// overwriting any existing value.
	HSet(key string, field string, value any) error

	// HMSet sets multiple fields in a hash in Redis.
	HMSet(key string, fields map[string]any) error

	// HDel deletes a specific field from a hash in Redis.
	// This method removes the field and its value, returning an error if the operation fails.
	HDel(key string, field string) error

	// HExists checks if a specific field exists in a hash in Redis.
	// The method returns true if the field exists, false otherwise.
	HExists(key string, field string) (bool, error)

	// NewPipeline creates a new pipeline, which allows you to chain commands and add options (e.g a TTL) in a convenient way.
	NewPipeline() *CachePipeline
}

AbstractCacheRepository defines a generic interface for interacting with a Redis-based cache. T represents the type of the values stored in the cache.

type AbstractRepository

type AbstractRepository[T Identifiable[K], K ID] interface {

	// FindAll retrieves all entities of type T from the database.
	FindAll() ([]T, error)

	// FindByID retrieves a single entity of type T by its ID.
	FindByID(id K) (T, error)

	// FirstByKey retrieves a single entity of type T by a specific field (key),thats mean
	// only the first Match!
	// The `key` parameter specifies the field to search, and `value` is the value to match.
	//
	// if you want to find all use:
	//	 FindAllByKey(key, value)
	FirstByKey(key, value string) (T, error)

	// FindAllByKey retrieves all entities of type T by a specific field (key)
	// The `key` parameter specifies the field to search, and `value` is the value to match.
	FindAllByKey(key, value string) ([]T, error)

	// Create inserts a new entity of type T into the database and returns its ID.
	// The operation can optionally be executed within a transaction.
	Create(tx *gorm.DB, newEntity T) (T, error)

	// Update modifies an existing entity of type T identified by its ID.
	// If one of the parameter is null, it will be ignored! if you need to set a field to null, use UpdateSpecific instead
	// The operation can optionally be executed within a transaction.
	Update(tx *gorm.DB, id K, newEntity T) error

	// UpdateSpecific modifies an existing entity of type T identified by its ID. It only updates the fields specified in the map
	// The operation can optionally be executed within a transaction.
	UpdateSpecific(tx *gorm.DB, id K, specificFields map[string]interface{}) error

	// Delete marks an entity of type T as deleted (soft delete) by its ID.
	// The operation can optionally be executed within a transaction.
	Delete(tx *gorm.DB, id K) error

	// Restore unmarks an entity of type T as deleted (restore) by its ID.
	// The operation can optionally be executed within a transaction.
	Restore(tx *gorm.DB, id K) error

	// GetPreloads returns the default preloads for the repository.
	// 	This need to be overriden by the concrete implementation!!
	// by default is a empty string slice
	GetPreloads() []string

	// GetType returns the types defined of the repository.
	GetType() string

	// transactionCheck if is within a transactional context to use the
	// transaction or use the current repository
	TransactionCheck(tx *gorm.DB) *gorm.DB
}

T is a generic type that represents a database entity. K is a generic type that represents the primary key of the entity, only accepting uint or uuid.UUID.

type CachePipeline added in v0.3.3

type CachePipeline struct {
	// contains filtered or unexported fields
}

CachePipeline is a wrapper around redis.Pipeliner that allows you to chain commands and add options (e.g a TTL) in a convenient way.

func (*CachePipeline) DecrBy added in v0.3.3

func (p *CachePipeline) DecrBy(key string, amount int64) *CachePipeline

Decr decrements the value of a Redis key by amount.

func (*CachePipeline) Del added in v0.3.3

func (p *CachePipeline) Del(keys ...string) *CachePipeline

func (*CachePipeline) Exec added in v0.3.3

func (p *CachePipeline) Exec() ([]redis.Cmder, error)

Exec executes all queued operations in the Redis pipeline and returns results.

func (*CachePipeline) ExecAndDiscard added in v0.3.3

func (p *CachePipeline) ExecAndDiscard() error

ExecAndDiscard executes the Redis pipeline but does not return results.

This method is useful for operations where you don't need command results.

func (*CachePipeline) Expire added in v0.3.3

func (p *CachePipeline) Expire(key string, expiration time.Duration) *CachePipeline

Expire sets an expiration time for a Redis hash.

This method ensures that the hash is automatically removed after a specified duration.

func (*CachePipeline) HDel added in v0.3.3

func (p *CachePipeline) HDel(key string, fields ...string) *CachePipeline

HDel removes one or more fields from a Redis hash.

func (*CachePipeline) HMSet added in v0.3.3

func (p *CachePipeline) HMSet(key string, fields map[string]any) *CachePipeline

HMSet sets multiple fields in a Redis hash.

This method allows batch setting of multiple fields in a single Redis operation.

func (*CachePipeline) HSet added in v0.3.3

func (p *CachePipeline) HSet(key, field string, value any) *CachePipeline

HSet sets a single field in a Redis hash.

This method adds the field to the hash or updates its value if it already exists.

func (*CachePipeline) IncrBy added in v0.3.3

func (p *CachePipeline) IncrBy(key string, amount int64) *CachePipeline

Incr increments the value of a Redis key by amount.

func (*CachePipeline) Set added in v0.3.3

func (p *CachePipeline) Set(key string, value any, expiration time.Duration) *CachePipeline

type Conn

type Conn struct {
	Gorm *gorm.DB
}

Conn represents a database connection encapsulated with Gorm.

func (Conn) GetDB

func (c Conn) GetDB() *gorm.DB

GetDB returns the underlying Gorm database connection.

type Connection

type Connection interface {
	Connect(cfg StdLibConfiguration) (Conn, error)
}

Connection defines an interface for database drivers to implement. It provides the method to establish a database connection using a given configuration.

type DBWrapper

type DBWrapper struct {
	Gorm *gorm.DB
}

DBWrapper is a wrapper around the Gorm database connection. It provides additional methods for managing the database, such as enum migrations and connection pool configuration.

func NewConnection

func NewConnection(driver Connection, cfg StdLibConfiguration) (*DBWrapper, error)

NewConnection establishes a database connection with retry logic and wraps it in a DBWrapper. If the connection fails after multiple attempts (3), it returns an error.

func (*DBWrapper) EnableExtension

func (db *DBWrapper) EnableExtension(extensionName string) *DBWrapper

EnableExtension ensures a PostgreSQL extension is enabled in the database. If the extension does not exist, it creates it.

func (*DBWrapper) EnableUUIDExtension

func (db *DBWrapper) EnableUUIDExtension() *DBWrapper

EnableUUIDExtension is a helper method to enable the 'pgcrypto' extension for UUID generation.

func (*DBWrapper) Migrate

func (db *DBWrapper) Migrate(models ...interface{}) *DBWrapper

Migrate applies database migrations for the specified models. It automatically migrates the database schema based on the provided models.

func (*DBWrapper) MigrateEnums

func (db *DBWrapper) MigrateEnums(enumTypeName string, values []string) *DBWrapper

MigrateEnums adds or updates an ENUM type in the PostgreSQL database. If the ENUM type does not exist, it creates it with the provided values.

func (*DBWrapper) SetConnectionPool

func (db *DBWrapper) SetConnectionPool(maxOpen, maxIdle int, maxLifetime time.Duration) *DBWrapper

SetConnectionPool configures the connection pool settings for the database. It allows setting the maximum number of open connections, idle connections, and connection lifetime.

type ID

type ID interface {
	int | int32 | int64 | uint | uint32 | uint64 | string | uuid.UUID
}

ID is a generic type that represents the primary key of the entity, only accepting uint or uuid.UUID.

type Identifiable

type Identifiable[K ID] interface {
	GetID() K
}

Identifiable is a generic interface that represents an entity that has an ID.

type MariaDBConnection

type MariaDBConnection struct{}

MariaDBConnection is a struct that implements the Connection interface for MariaDB.

func (*MariaDBConnection) Connect

func (m *MariaDBConnection) Connect(cfg StdLibConfiguration) (Conn, error)

Connect establishes a connection to a MariaDB database using the provided configuration.

type PostgresConnection

type PostgresConnection struct{}

PostgresConnection is a struct that implements the Connection interface for PostgreSQL.

func (*PostgresConnection) Connect

func (p *PostgresConnection) Connect(cfg StdLibConfiguration) (Conn, error)

/ Connect establishes a connection to a PostgreSQL database using the provided configuration.

type StandardError

type StandardError struct {
	ErrorMessage string `json:"error" example:"An error occurred - some context"`
}

type StandardResponse

type StandardResponse struct {
	Message string      `json:"message" example:"info message"`
	Data    interface{} `json:"data"`
}

type StdLibConfiguration

type StdLibConfiguration struct {
	DBHost     string
	DBUser     string
	DBPassword string
	DBDatabase string
	DBPort     int
	DBSSLMode  string

	RedisHost     string
	RedisPort     int
	RedisPassword string
	RedisDB       int

	DevMode bool
}

func LoadCfg

func LoadCfg(file ...string) StdLibConfiguration

LoadCfg loads the configuration from the specified file or defaults to ".env". It returns a StdLibConfiguration instance. If an error occurs during loading, it logs the error and continues with the environment variables already set.

type TransactionalRepository added in v0.3.0

type TransactionalRepository interface {

	// BeginTransaction initializes a transaction by returning the transaction context or a possible error
	BeginTransaction() (*gorm.DB, error)

	// CommitTransaction commits a transaction, returning a possible error
	CommitTransaction(tx *gorm.DB) error
	// RollbackTransaction rolls back a transaction leaving changes uncommitted
	RollbackTransaction(tx *gorm.DB) error

	// ExecuteInTransaction executes a function within a transaction context, logging whether there is a possible error
	ExecuteInTransaction(fn func(tx *gorm.DB) error) error
}

func NewTransactionalRepository added in v0.3.0

func NewTransactionalRepository(gorm *gorm.DB) TransactionalRepository

type ValidatorError

type ValidatorError struct {
	ErrorMessage string            `json:"error"  example:"Validation failed"`
	Fields       map[string]string `json:"fields" example:"{'username': 'Username is required'}"`
}

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL