storage

package module
v0.0.0-...-6cf786e Latest Latest
Warning

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

Go to latest
Published: Apr 2, 2025 License: MIT Imports: 31 Imported by: 2

README

Storage

Go Report Card GoDoc License

The Storage library provides a unified interface for various storage types, including SQL, NoSQL, and File. The library uses the Abstract Factory design pattern to create different storage objects.

Installation

go get github.com/golang-common-packages/storage

Features

  • SQL Relational: Support for SQL databases through Go's database/sql package
  • NoSQL Document: Support for MongoDB
  • NoSQL Key-Value: Support for Redis, BigCache, and custom implementations
  • File: Support for Google Drive and custom implementations

Usage

Import
import "github.com/golang-common-packages/storage"
Working with MongoDB
// Initialize MongoDB client
mongoClient := storage.New(context.Background(), storage.NOSQLDOCUMENT)(storage.MONGODB, &storage.Config{
    MongoDB: storage.MongoDB{
        User:     "USERNAME",
        Password: "PASSWORD",
        Hosts:    []string{"localhost:27017"},
        Options:  []string{},
        DB:       "DATABASE_NAME",
    },
}).(storage.INoSQLDocument)

// Create document
documents := []interface{}{
    map[string]interface{}{
        "name": "John Doe",
        "age":  30,
    },
}
result, err := mongoClient.Create("database", "collection", documents)

// Read document
filter := bson.M{"name": "John Doe"}
result, err := mongoClient.Read("database", "collection", filter, 10, reflect.TypeOf(YourModel{}))

// Update document
filter := bson.M{"name": "John Doe"}
update := bson.M{"$set": bson.M{"age": 31}}
result, err := mongoClient.Update("database", "collection", filter, update)

// Delete document
filter := bson.M{"name": "John Doe"}
result, err := mongoClient.Delete("database", "collection", filter)
Working with Redis
// Initialize Redis client
redisClient := storage.New(context.Background(), storage.NOSQLKEYVALUE)(storage.REDIS, &storage.Config{
    Redis: storage.Redis{
        Host:       "localhost:6379",
        Password:   "PASSWORD",
        DB:         0,
        MaxRetries: 3,
    },
}).(storage.INoSQLKeyValue)

// Store value
err := redisClient.Set("key", "value", 1*time.Hour)

// Get value
value, err := redisClient.Get("key")

// Update value
err := redisClient.Update("key", "new-value", 1*time.Hour)

// Delete value
err := redisClient.Delete("key")
Working with Google Drive
// Initialize Google Drive client
driveClient := storage.New(context.Background(), storage.FILE)(storage.DRIVE, &storage.Config{
    GoogleDrive: storage.GoogleDrive{
        PoolSize:     4,
        ByHTTPClient: false,
        Credential:   "credentials.json",
        Token:        "token.json",
    },
}).(storage.IFILE)

// List files
files, err := driveClient.List(100)

// Create folder
folder, err := driveClient.CreateFolder("folder-name")

// Upload file
file, err := os.Open("file.txt")
result, err := driveClient.Upload("file.txt", file)

// Download file
result, err := driveClient.Download("file-id")

// Move file
result, err := driveClient.Move("file-id", "old-parent-id", "new-parent-id")

// Delete file
err := driveClient.Delete([]string{"file-id"})

Development

Requirements
  • Go 1.15+
  • MongoDB (for NoSQL Document)
  • Redis (for NoSQL Key-Value)
  • SQLite (for SQL Relational)
Running tests
# Run all tests
make test

# Run short tests (skip tests requiring database connections)
make test-short

# Run tests with coverage
make coverage
Docker
# Build Docker image
make docker-build

# Run Docker container
make docker-run

# Run with Docker Compose
docker-compose up

Contributing

We welcome contributions from the community. Please create an issue or pull request on GitHub.

License

This project is distributed under the MIT license. See the LICENSE file for more details.

Documentation

Overview

Package storage provides a unified interface for various storage types using the abstract factory pattern.

Index

Constants

View Source
const (
	// DRIVE cloud services
	DRIVE = iota
	// CUSTOMFILE file services
	CUSTOMFILE
)
View Source
const (
	// CUSTOM caching on local memory
	CUSTOM = iota
	// BIGCACHE database
	BIGCACHE
	// REDIS database
	REDIS
)
View Source
const (
	// MONGODB database
	MONGODB = iota
)
View Source
const (
	// SQLLike database (common relational database)
	SQLLike = iota
)

Variables

View Source
var (
	// ErrInvalidStorageType is returned when an invalid storage type is provided
	ErrInvalidStorageType = errors.New("invalid storage type")
	// ErrInvalidConfig is returned when an invalid configuration is provided
	ErrInvalidConfig = errors.New("invalid configuration")
)

Functions

func GetContext

func GetContext() context.Context

GetContext returns the current context

func New

func New(context context.Context, storageType StorageType) func(databaseCompany int, config *Config) interface{}

New creates a new storage instance using the abstract factory pattern It returns a function that can be called with a specific database company and config to get the concrete implementation.

func SetContext

func SetContext(context context.Context)

SetContext sets a new context for the package

Types

type BigCacheClient

type BigCacheClient struct {
	Client *bigcache.BigCache
}

BigCacheClient manage all BigCache actions

func (*BigCacheClient) Append

func (bc *BigCacheClient) Append(key string, value interface{}) error

Append new value base on the key provide, With Append() you can concatenate multiple entries under the same key in an lock optimized way.

func (*BigCacheClient) Close

func (bc *BigCacheClient) Close() error

Close function will close BigCache connection

func (*BigCacheClient) Delete

func (bc *BigCacheClient) Delete(key string) error

Delete function will delete value based on the key provided

func (*BigCacheClient) Get

func (bc *BigCacheClient) Get(key string) (interface{}, error)

Get return value based on the key provided

func (*BigCacheClient) GetCapacity

func (bc *BigCacheClient) GetCapacity() (interface{}, error)

GetCapacity method return redis database size

func (*BigCacheClient) GetNumberOfRecords

func (bc *BigCacheClient) GetNumberOfRecords() int

GetNumberOfRecords return number of records

func (*BigCacheClient) Middleware

func (bc *BigCacheClient) Middleware(hash hash.IHash) echo.MiddlewareFunc

Middleware for echo framework

func (*BigCacheClient) Set

func (bc *BigCacheClient) Set(key string, value interface{}, expire time.Duration) error

Set new record set key and value

func (*BigCacheClient) Update

func (bc *BigCacheClient) Update(key string, value interface{}, expire time.Duration) error

Update new value over the key provided

type Config

type Config struct {
	LIKE           LIKE            `json:"like,omitempty"`
	MongoDB        MongoDB         `json:"mongodb,omitempty"`
	Redis          Redis           `json:"redis,omitempty"`
	CustomKeyValue CustomKeyValue  `json:"customKeyValue,omitempty"`
	BigCache       bigcache.Config `json:"bigCache,omitempty"`
	GoogleDrive    GoogleDrive     `json:"googleDrive,omitempty"`
	CustomFile     CustomFile      `json:"customFile,omitempty"`
}

Config model for database config

type CustomFile

type CustomFile struct {
	PoolSize             int    `json:"poolSize"`
	RootServiceDirectory string `json:"rootDirectory"`
}

CustomFile config model

type CustomFileClient

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

CustomFileClient manage all custom file action

func (*CustomFileClient) CreateFolder

func (cf *CustomFileClient) CreateFolder(name string, parents ...string) (interface{}, error)

CreateFolder on root service directory

func (*CustomFileClient) Delete

func (cf *CustomFileClient) Delete(fileIDs []string) error

Delete file/folder based on IDs (that is the list of file name)

func (*CustomFileClient) Download

func (cf *CustomFileClient) Download(fileID string) (interface{}, error)

Download feature doesn't implemented for this service

func (*CustomFileClient) GetMetaData

func (cf *CustomFileClient) GetMetaData(fileID string) (interface{}, error)

GetMetaData from file based on fileID (that is file name)

func (*CustomFileClient) List

func (cf *CustomFileClient) List(pageSize int64, pageToken ...string) (interface{}, error)

List all of file and folder

func (*CustomFileClient) Move

func (cf *CustomFileClient) Move(fileID, oldParentID, newParentID string) (interface{}, error)

Move file to new location based on fileID, oldParentID, newParentID

func (*CustomFileClient) Upload

func (cf *CustomFileClient) Upload(name string, fileContent io.Reader, parents ...string) (interface{}, error)

Upload file to root service directory

type CustomKeyValue

type CustomKeyValue struct {
	MemorySize       int64         `json:"memorySize"` // byte
	CleaningEnable   bool          `json:"cleaningEnable"`
	CleaningInterval time.Duration `json:"cleaningInterval"` // nanosecond
}

CustomKeyValue config model

type DriveServices

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

DriveServices manage all drive action

func (*DriveServices) CreateFolder

func (dr *DriveServices) CreateFolder(name string, parents ...string) (interface{}, error)

CreateFolder on drive

func (*DriveServices) Delete

func (dr *DriveServices) Delete(fileIDs []string) error

Delete file/folder based on IDs

func (*DriveServices) Download

func (dr *DriveServices) Download(fileID string) (interface{}, error)

Download file based on fileID

func (*DriveServices) GetMetaData

func (dr *DriveServices) GetMetaData(fileID string) (interface{}, error)

GetMetaData from file based on fileID

func (*DriveServices) List

func (dr *DriveServices) List(pageSize int64, pageToken ...string) (interface{}, error)

List all files based on pageSize

func (*DriveServices) Move

func (dr *DriveServices) Move(fileID, oldParentID, newParentID string) (interface{}, error)

Move file to new location based on fileID, oldParentID, newParentID

func (*DriveServices) Upload

func (dr *DriveServices) Upload(name string, fileContent io.Reader, parents ...string) (interface{}, error)

Upload file to drive

type GoogleDrive

type GoogleDrive struct {
	PoolSize     int    `json:"poolSize"`
	ByHTTPClient bool   `json:"byHTTPClient"`
	Token        string `json:"token"`
	Credential   string `json:"credential"`
}

GoogleDrive config model

type GoogleFileListModel

type GoogleFileListModel struct {
	drive.FileList
}

GoogleFileListModel for unmarshal object has interface type

type GoogleFileModel

type GoogleFileModel struct {
	drive.File
}

GoogleFileModel for unmarshal object has interface type

type IFILE

type IFILE interface {
	List(pageSize int64, pageToken ...string) (interface{}, error)
	GetMetaData(fileID string) (interface{}, error)
	CreateFolder(name string, parents ...string) (interface{}, error)
	Upload(name string, fileContent io.Reader, parents ...string) (interface{}, error)
	Download(fileID string) (interface{}, error)
	Move(fileID, oldParentID, newParentID string) (interface{}, error)
	Delete(fileIDs []string) error
}

IFILE factory pattern interface

type INoSQLDocument

type INoSQLDocument interface {
	Create(databaseName, collectionName string, documents []interface{}) (interface{}, error)
	Read(databaseName, collectionName string, filter interface{}, limit int64, dataModel reflect.Type) (interface{}, error)
	Update(databaseName, collectionName string, filter, update interface{}) (interface{}, error)
	Delete(databaseName, collectionName string, filter interface{}) (interface{}, error)
}

INoSQLDocument factory pattern CRUD interface

type INoSQLKeyValue

type INoSQLKeyValue interface {
	Middleware(hash hash.IHash) echo.MiddlewareFunc
	Get(key string) (interface{}, error)
	Set(key string, value interface{}, expire time.Duration) error
	Update(key string, value interface{}, expire time.Duration) error
	Delete(key string) error
	GetNumberOfRecords() int
	GetCapacity() (interface{}, error)
	Close() error
}

INoSQLKeyValue factory pattern interface

type ISQLRelational

type ISQLRelational interface {
	Execute(query string, dataModel interface{}) (interface{}, error)
}

ISQLRelational factory pattern interface

type KeyValueCustomClient

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

KeyValueCustomClient manage all custom caching actions

func (*KeyValueCustomClient) Close

func (cl *KeyValueCustomClient) Close() error

Close stops the background cleaning process and frees up resources

func (*KeyValueCustomClient) Delete

func (cl *KeyValueCustomClient) Delete(key string) error

Delete removes a key from the cache Returns an error if the key doesn't exist

func (*KeyValueCustomClient) Get

func (cl *KeyValueCustomClient) Get(key string) (interface{}, error)

Get retrieves a value from the cache based on the key provided Returns nil, nil if the key exists but the value is expired

func (*KeyValueCustomClient) GetCapacity

func (cl *KeyValueCustomClient) GetCapacity() (interface{}, error)

GetCapacity returns the current size of the cache in bytes

func (*KeyValueCustomClient) GetMany

func (cl *KeyValueCustomClient) GetMany(keys []string) (map[string]interface{}, []string, error)

GetMany returns values based on the list of keys provided Returns a map of found items, a slice of keys not found, and any error encountered

func (*KeyValueCustomClient) GetNumberOfRecords

func (cl *KeyValueCustomClient) GetNumberOfRecords() int

GetNumberOfRecords returns the total number of records in the cache Note: This includes expired records that haven't been cleaned up yet

func (*KeyValueCustomClient) Middleware

func (cl *KeyValueCustomClient) Middleware(hash hash.IHash) echo.MiddlewareFunc

Middleware for echo framework

func (*KeyValueCustomClient) Range

func (cl *KeyValueCustomClient) Range(f func(key, value interface{}) bool)

Range iterates over all non-expired items in the cache The provided function is called for each key-value pair

func (*KeyValueCustomClient) Set

func (cl *KeyValueCustomClient) Set(key string, value interface{}, expire time.Duration) error

Set creates a new record with the specified key, value, and expiration

func (*KeyValueCustomClient) Update

func (cl *KeyValueCustomClient) Update(key string, value interface{}, expire time.Duration) error

Update modifies an existing key with a new value and expiration Returns an error if the key doesn't exist

type LIKE

type LIKE struct {
	DriverName            string        `json:"driverName"`
	DataSourceName        string        `json:"dataSourceName"`
	MaxConnectionLifetime time.Duration `json:"maxConnectionLifetime"`
	MaxConnectionIdle     int           `json:"maxConnectionIdle"`
	MaxConnectionOpen     int           `json:"maxConnectionOpen"`
}

LIKE model for SQL-LIKE connection config

type MongoClient

type MongoClient struct {
	Client *mongo.Client
	Cancel context.CancelFunc
	Config *MongoDB
}

MongoClient manage all mongodb actions

func (*MongoClient) Create

func (m *MongoClient) Create(databaseName, collectionName string, documents []interface{}) (interface{}, error)

Create inserts a list of documents into the specified collection

func (*MongoClient) Delete

func (m *MongoClient) Delete(databaseName, collectionName string, filter interface{}) (interface{}, error)

Delete removes documents from the specified collection based on filter

func (*MongoClient) Read

func (m *MongoClient) Read(databaseName, collectionName string, filter interface{}, limit int64, dataModel reflect.Type) (interface{}, error)

Read retrieves documents from the specified collection based on filter

func (*MongoClient) Update

func (m *MongoClient) Update(databaseName, collectionName string, filter, update interface{}) (interface{}, error)

Update modifies documents in the specified collection based on filter

type MongoDB

type MongoDB struct {
	User     string   `json:"user"`
	Password string   `json:"password"`
	Hosts    []string `json:"hosts"`
	DB       string   `json:"db"`
	Options  []string `json:"options"`
}

MongoDB model for MongoDB connection config

type Redis

type Redis struct {
	Password   string `json:"password"`
	Host       string `json:"host"`
	DB         int    `json:"db"`
	MaxRetries int    `json:"maxRetries"`
}

Redis model for redis config

type RedisClient

type RedisClient struct {
	Client *redis.Client
}

RedisClient manage all redis actions

func (*RedisClient) Append

func (r *RedisClient) Append(key string, value interface{}) error

Append adds a string value to the end of an existing string key

func (*RedisClient) Close

func (r *RedisClient) Close() error

Close method will close redis connection

func (*RedisClient) Delete

func (r *RedisClient) Delete(key string) error

Delete removes a key from Redis

func (*RedisClient) Get

func (r *RedisClient) Get(key string) (interface{}, error)

Get retrieves a value from Redis based on the key provided

func (*RedisClient) GetCapacity

func (r *RedisClient) GetCapacity() (interface{}, error)

GetCapacity method return redis database size

func (*RedisClient) GetNumberOfRecords

func (r *RedisClient) GetNumberOfRecords() int

GetNumberOfRecords return number of records

func (*RedisClient) Middleware

func (r *RedisClient) Middleware(hash hash.IHash) echo.MiddlewareFunc

Middleware for echo framework

func (*RedisClient) Set

func (r *RedisClient) Set(key string, value interface{}, expire time.Duration) error

Set creates a new record with the specified key, value, and expiration

func (*RedisClient) Update

func (r *RedisClient) Update(key string, value interface{}, expire time.Duration) error

Update modifies an existing key with a new value and expiration Returns an error if the key doesn't exist

type SQLLikeClient

type SQLLikeClient struct {
	Client *sql.DB
	Config *LIKE
}

SQLLikeClient manage all SQL-Like actions

func (*SQLLikeClient) Execute

func (c *SQLLikeClient) Execute(
	query string,
	dataModel interface{}) (interface{}, error)

Execute return results based on 'query' and 'dataModel'

type StorageType

type StorageType int

StorageType defines the type of storage

const (
	// SQLRELATIONAL is SQL relational type
	SQLRELATIONAL StorageType = iota
	// NOSQLDOCUMENT is NoSQL document type
	NOSQLDOCUMENT
	// NOSQLKEYVALUE is NoSQL key-value type
	NOSQLKEYVALUE
	// FILE is file management
	FILE
)

Directories

Path Synopsis
examples
file command

Jump to

Keyboard shortcuts

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