sqldb

package module
v0.0.3 Latest Latest
Warning

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

Go to latest
Published: Nov 28, 2022 License: Apache-2.0 Imports: 9 Imported by: 0

README

Introduction

Go Report Card Go Reference

sqldb is a useful package which defines some common types and interfaces in manipulating data of models in sql database.

It also provides an implementation of the interfaces based on the GORM library.

Getting Started

A Model defined in sqldb.go contains a set of commonly used methods when handling data in a database.

type Model[T any] interface {
	Columns() T
	Create(ctx context.Context, entity *T) error
	Get(ctx context.Context, opts []OpQueryOptionInterface) (*T, error)
	List(ctx context.Context, opts ListOptions) ([]*T, uint64, error)
	Update(ctx context.Context, query FilterOptions, opts []UpdateOptionInterface) (uint64, error)
	Delete(ctx context.Context, opts FilterOptions) error
}

Before using the Model you have to declaring your model, User for example:

import "github.com/YLonely/sqldb"

type User struct {
	ID      sqldb.Column[uint64] `gorm:"column:id;primaryKey"`
	Name    sqldb.Column[string] `gorm:"column:user_name"`
	Age     sqldb.PtrColumn[int]
	CreatedAt sqldb.Column[time.Time]
	DeletedAt sqldb.Column[gorm.DeletedAt]
}

Here sqldb.Column or sqldb.PtrColumn is a generic type which represents a table column in the database, it contains the value of the corresponding field and also the column name of it.

Now we can initialize a Model type for User:

import (
	"context"

	"github.com/YLonely/sqldb"
	sqlgorm "github.com/YLonely/sqldb/gorm"
)

func main(){
	// Use gorm to open the database.
	dsn := "user:pass@tcp(127.0.0.1:3306)/dbname?charset=utf8mb4&parseTime=True&loc=Local"
  	db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})
	if err != nil{
		panic(err)
	}

	var Users sqldb.Model[User] = sqlgorm.NewModel[User](db)
	ctx := context.Background()

	// To create a new user
	age := 10
	u := &User{
		Name: sqldb.NewColumn("test"),
		Age: sqldb.NewPtrColumn(age),
	}
	_ = Users.Create(ctx, u)

	// To get the user
	u, err := Users.Get(ctx, []sqldb.OpQueryOptionInterface{
		// No more string literals, use .Columns() instead.
		sqldb.NewEqualOption(Users.Columns().Name, "test"),
		// Not recommended.
		sqldb.OpQueryOption[string]{
			Op: sqldb.OpEq,
			Option: sqldb.Option[string]{
				Column: "user_name",
				Value: "test",
			},
		},
	})
}

It is worth noting that you do not write string literals of columns when constructing query options, every Model[T] type has a method Columns() which returns a instance of type T, all fields of type sqldb.Column in type T are populated with column name during initialization. You can also use the option structs directly, but you have to confirm the column name by yourself, which is extremely not recommended.

sqldb.go also defines a function type which abstracts transactions:

type TransactionFunc func(ctx context.Context, run func(context.Context) error) error

To create a TransactionFunc implemented by GORM and process models in the transaction:

Transaction := gorm.NewTransactionFunc(db)

Transaction(context.Background(), func(ctx context.Context) error {
	if err := Users.Delete(ctx, sqldb.FilterOptions{
		InOptions: []sqldb.RangeQueryOptionInterface{
			sqldb.NewRangeQueryOption(Users.Age, []int{10, 11, 12}),
		}
	}); err != nil {
		return err
	}

	// nested transaction.
	Transaction(ctx, func(ctx context.Context) error {
	})
})

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Column

type Column[T any] struct {
	ColumnValue[T]
	ColumnName
}

Column represents a column of a table.

func NewColumn

func NewColumn[T any](v T) Column[T]

NewColumn creates a new Column of type T.

type ColumnGetter

type ColumnGetter interface {
	GetColumnName() string
}

type ColumnHint

type ColumnHint[T any] struct {
	// contains filtered or unexported fields
}

ColumnHint is supposed to be embedded into structs to implement the Model interface.

func NewColumnHint

func NewColumnHint[T any](f NameFieldFunc) ColumnHint[T]

func (ColumnHint[T]) Columns

func (ch ColumnHint[T]) Columns() T

type ColumnName

type ColumnName string

func (ColumnName) GetColumnName

func (cn ColumnName) GetColumnName() string

type ColumnType added in v0.0.3

type ColumnType[T any] interface {
	Column[T] | PtrColumn[T]
}

ColumnType contains valid column types.

type ColumnValue

type ColumnValue[T any] struct {
	V T
}

func (ColumnValue[T]) CreateClauses

func (cv ColumnValue[T]) CreateClauses(f *schema.Field) []clause.Interface

CreateClauses implements the CreateClausesInterface interface from GORM.

func (ColumnValue[T]) DeleteClauses

func (cv ColumnValue[T]) DeleteClauses(f *schema.Field) []clause.Interface

DeleteClauses implements the DeleteClausesInterface interface from GORM.

func (ColumnValue[T]) MarshalJSON

func (cv ColumnValue[T]) MarshalJSON() ([]byte, error)

func (ColumnValue[T]) QueryClauses

func (cv ColumnValue[T]) QueryClauses(f *schema.Field) []clause.Interface

QueryClauses implements the QueryClausesInterface interface from GORM.

func (*ColumnValue[T]) Scan

func (cv *ColumnValue[T]) Scan(src any) error

Scan implements the Scanner interface.

func (*ColumnValue[T]) UnmarshalJSON

func (cv *ColumnValue[T]) UnmarshalJSON(data []byte) error

func (ColumnValue[T]) UpdateClauses

func (cv ColumnValue[T]) UpdateClauses(f *schema.Field) []clause.Interface

UpdateClauses implements the UpdateClausesInterface interface from GORM.

func (ColumnValue[T]) Value

func (cv ColumnValue[T]) Value() (driver.Value, error)

Value implements the driver Valuer interface.

type FilterOptions

type FilterOptions struct {
	OpOptions    []OpQueryOptionInterface
	FuzzyOptions []FuzzyQueryOptionInterface
	InOptions    []RangeQueryOptionInterface
	NotInOptions []RangeQueryOptionInterface
}

FilterOptions contains options that related to data filtering.

type FuzzyQueryOption

type FuzzyQueryOption[T comparable] struct {
	ValuesOption[T]
}

FuzzyQueryOption implements the FuzzyQueryOptionInterface.

func NewFuzzyQueryOption

func NewFuzzyQueryOption[T comparable, C ColumnType[T]](col C, vs []T) FuzzyQueryOption[T]

NewFuzzyQueryOption creates a new FuzzyQueryOption.

type FuzzyQueryOptionInterface

type FuzzyQueryOptionInterface interface {
	ValuesOptionInterface
}

FuzzyQueryOptionInterface represents a query that find data that match given patterns approximately.

type ListOptions

type ListOptions struct {
	FilterOptions
	Offset      uint64
	Limit       uint64
	SortOptions []SortOptionInterface
}

ListOptions contains options and parameters that related to data listing.

type Model

type Model[T any] interface {
	// Columns returns a instance of type T,
	// all fields of type sqldb.Column[U] in the instance are populated with corresponding column name.
	Columns() T
	Create(ctx context.Context, entity *T) error
	Get(ctx context.Context, opts []OpQueryOptionInterface) (*T, error)
	List(ctx context.Context, opts ListOptions) ([]*T, uint64, error)
	Update(ctx context.Context, query FilterOptions, opts []UpdateOptionInterface) (uint64, error)
	Delete(ctx context.Context, opts FilterOptions) error
}

Model is an interface defines commonly used methods to manipulate data.

type NameFieldFunc

type NameFieldFunc func(target reflect.StructField, parents ...reflect.StructField) string

A NameFieldFunc gives the target filed a corresponding column name.

type OpQueryOption

type OpQueryOption[T comparable] struct {
	Option[T]
	Op QueryOp
}

OpQueryOption implements the OpQueryOptionInterface.

func NewEqualOption

func NewEqualOption[T comparable, C ColumnType[T]](col C, v T) OpQueryOption[T]

NewEqualOption creates an OpQueryOption with operator OpEq.

func NewGreaterEqualOption

func NewGreaterEqualOption[T comparable, C ColumnType[T]](col C, v T) OpQueryOption[T]

NewGreaterEqualOption creates an OpQueryOption with operator OpGte.

func NewGreaterOption

func NewGreaterOption[T comparable, C ColumnType[T]](col C, v T) OpQueryOption[T]

NewGreaterOption creates an OpQueryOption with operator OpGt.

func NewLessEqualOption

func NewLessEqualOption[T comparable, C ColumnType[T]](col C, v T) OpQueryOption[T]

NewLessEqualOption creates an OpQueryOption with operator OpLte.

func NewLessOption

func NewLessOption[T comparable, C ColumnType[T]](col C, v T) OpQueryOption[T]

NewLessOption creates an OpQueryOption with operator OpLt.

func NewNotEqualOption

func NewNotEqualOption[T comparable, C ColumnType[T]](col C, v T) OpQueryOption[T]

NewNotEqualOption creates an OpQueryOption with operator OpNe.

func NewOpQueryOption

func NewOpQueryOption[T comparable, C ColumnType[T]](col C, op QueryOp, v T) OpQueryOption[T]

NewOpQueryOption creates an OpQueryOption.

func (OpQueryOption[T]) QueryOp

func (opt OpQueryOption[T]) QueryOp() QueryOp

type OpQueryOptionInterface

type OpQueryOptionInterface interface {
	OptionInterface
	QueryOp() QueryOp
}

OpQueryOptionInterface represents a query which use the given query operator to search data.

type Option

type Option[T any] struct {
	Column string
	Value  T
}

Option implements the OptionInterface.

func NewOption

func NewOption[T any, C ColumnType[T]](col C, v T) Option[T]

NewOption returns an new Option.

func (Option[T]) GetValue

func (opt Option[T]) GetValue() any

func (Option[T]) TargetColumnName

func (opt Option[T]) TargetColumnName() string

type OptionInterface

type OptionInterface interface {
	// TargetColumnName returns the name of the column an operation processes against.
	TargetColumnName() string
	// GetValue returns the value the option carries. It is used by the operation to query or update the target column.
	GetValue() any
}

OptionInterface wraps basic methods of options.

type PtrColumn

type PtrColumn[T any] struct {
	ColumnValue[*T]
	ColumnName
}

PtrColumn is used when declaring models with pointer fields, for example:

type Model struct{
	Name PtrColumn[string]
}

equals to

type Model struct{
	Name *string
}

func NewPtrColumn

func NewPtrColumn[T any](v T) PtrColumn[T]

NewPtrColumn creates a new PtrColumn of type T.

type QueryOp

type QueryOp string
const (
	OpEq  QueryOp = "="
	OpNe  QueryOp = "!="
	OpGt  QueryOp = ">"
	OpLt  QueryOp = "<"
	OpGte QueryOp = ">="
	OpLte QueryOp = "<="
)

type RangeQueryOption

type RangeQueryOption[T comparable] struct {
	ValuesOption[T]
}

RangeQueryOption implements the RangeQueryOptionInterface.

func NewRangeQueryOption

func NewRangeQueryOption[T comparable, C ColumnType[T]](col C, vs []T) RangeQueryOption[T]

NewRangeQueryOption creates a new RangeQueryOption.

type RangeQueryOptionInterface

type RangeQueryOptionInterface interface {
	ValuesOptionInterface
}

RangeQueryOptionInterface represents a query that find data from a given range of values.

type SortOption

type SortOption[T comparable] struct {
	Column string
	Order  SortOrder
}

SortOption implements the SortOptionInterface.

func NewSortOption

func NewSortOption[T comparable, C ColumnType[T]](col C, order SortOrder) SortOption[T]

NewSortOption creates a new SortOption.

func (SortOption[T]) SortOrder

func (opt SortOption[T]) SortOrder() SortOrder

func (SortOption[T]) TargetColumnName

func (opt SortOption[T]) TargetColumnName() string

type SortOptionInterface

type SortOptionInterface interface {
	TargetColumnName() string
	SortOrder() SortOrder
}

SortOptionInterface represents an sort operation.

type SortOrder

type SortOrder string
const (
	SortOrderAscending  SortOrder = "asc"
	SortOrderDescending SortOrder = "desc"
)

type TransactionFunc

type TransactionFunc func(ctx context.Context, run func(context.Context) error) error

A TransactionFunc starts a transaction.

type UpdateOption

type UpdateOption[T any] struct {
	Option[T]
}

UpdateOption implements the UpdateOptionInterface.

func NewUpdateOption

func NewUpdateOption[T any, C ColumnType[T]](col C, v T) UpdateOption[T]

NewUpdateOption creates a new UpdateOption.

type UpdateOptionInterface

type UpdateOptionInterface interface {
	OptionInterface
}

UpdateOptionInterface represents an update operation that updates the target column with given value.

type ValuesOption

type ValuesOption[T comparable] struct {
	Column string
	Values []T
}

ValuesOption implements the ValuesOptionInterface.

func NewValuesOption

func NewValuesOption[T comparable, C ColumnType[T]](col C, vs []T) ValuesOption[T]

NewValuesOption returns a new ValuesOption.

func (ValuesOption[T]) GetValues

func (opt ValuesOption[T]) GetValues() []any

func (ValuesOption[T]) TargetColumnName

func (opt ValuesOption[T]) TargetColumnName() string

type ValuesOptionInterface

type ValuesOptionInterface interface {
	// TargetColumnName returns the name of the column an operation processes against.
	TargetColumnName() string
	// GetValues returns the values the option carries. Those values are used to query data.
	GetValues() []any
}

ValuesOptionInterface wraps basic method of options which carry multiple values.

Directories

Path Synopsis
internal
sql
Package sql provides a generic interface around SQL (or SQL-like) databases.
Package sql provides a generic interface around SQL (or SQL-like) databases.

Jump to

Keyboard shortcuts

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