repo

package
v0.13.0 Latest Latest
Warning

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

Go to latest
Published: Feb 27, 2024 License: Apache-2.0 Imports: 18 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

View Source
var (
	ErrorInvalidCrudModel     = data.NewDataError(data.ErrorCodeInvalidCrudModel, "invalid model for CrudRepository")
	ErrorUnsupportedOptions   = data.NewDataError(data.ErrorCodeUnsupportedOptions, "unsupported Option")
	ErrorUnsupportedCondition = data.NewDataError(data.ErrorCodeUnsupportedCondition, "unsupported Condition")
	ErrorInvalidCrudParam     = data.NewDataError(data.ErrorCodeInvalidCrudParam, "invalid CRUD param")
	ErrorInvalidPagination    = data.NewDataError(data.ErrorCodeInvalidPagination, "invalid pagination")
	ErrorInvalidUtilityUsage  = data.NewDataError(data.ErrorCodeInvalidApiUsage, "invalid utility usage")
)
View Source
var Module = &bootstrap.Module{
	Name:       "DB Repo",
	Precedence: bootstrap.DatabasePrecedence,
	Options: []fx.Option{
		fx.Provide(newGormFactory),
		fx.Provide(newGormApi),
		fx.Invoke(initialize),
	},
}

Functions

func AsGormScope

func AsGormScope(i interface{}) func(*gorm.DB) *gorm.DB

AsGormScope convert following types to a func(*gorm.DB)*gorm.DB: - Option or slice of Option - Condition or slice of Condition - func(*gorm.DB)*gorm.DB (noop) - slice of func(*gorm.DB)*gorm.DB

This function is intended for custom repository implementations. The result can be used as "db.Scopes(result...)" The function panic on any type not listed above

func MustApplyConditions

func MustApplyConditions(db *gorm.DB, conds ...Condition) *gorm.DB

MustApplyConditions takes a slice of Condition and apply it to the given gorm.DB. This function is intended for custom repository implementations. The function panic if any Condition is not supported type

func MustApplyOptions

func MustApplyOptions(db *gorm.DB, opts ...Option) *gorm.DB

MustApplyOptions takes a slice of Option and apply it to the given gorm.DB. This function is intended for custom repository implementations. The function panic if any Option is not supported type

Types

type Condition

type Condition interface{}

Condition is typically used for generic CRUD repository supported condition depends on operation and underlying implementation:

  • map[string]interface{} (should be generally supported) e.g. {"col1": "val1", "col2": 10} -> "WHERE col1 = "val1" AND col2 = 10"
  • Struct (supported by gorm) e.g. &User{FirstName: "john", Age: 20} -> "WHERE first_name = "john" AND age = 20"
  • raw condition generated by Where
  • scope function func(*gorm.DB) *gorm.DB
  • valid gorm clause. e.g. clause.Where
  • slice of above

If given condition is not supported, an error with code data.ErrorCodeUnsupportedCondition will be return

func Or

func Or(query interface{}, args ...interface{}) Condition

Or is a Condition that directly bridge parameters to (*gorm.DB).Or()

func Where

func Where(query interface{}, args ...interface{}) Condition

Where is a Condition that directly bridge parameters to (*gorm.DB).Where()

type CrudRepository

type CrudRepository interface {
	SchemaResolver

	// FindById fetch model by primary key and scan it into provided interface.
	// Accepted "dest" types:
	//		*ModelStruct
	FindById(ctx context.Context, dest interface{}, id interface{}, options ...Option) error

	// FindAll fetch all model scan it into provided slice.
	// Accepted "dest" types:
	//		*[]*ModelStruct
	//		*[]ModelStruct
	FindAll(ctx context.Context, dest interface{}, options ...Option) error

	// FindOneBy fetch single model with given condition and scan result into provided value.
	// Accepted "dest" types:
	//		*ModelStruct
	FindOneBy(ctx context.Context, dest interface{}, condition Condition, options ...Option) error

	// FindAllBy fetch all model with given condition and scan result into provided value.
	// Accepted "dest" types:
	//		*[]*ModelStruct
	//		*[]ModelStruct
	FindAllBy(ctx context.Context, dest interface{}, condition Condition, options ...Option) error

	// CountAll counts all
	CountAll(ctx context.Context, options ...Option) (int, error)

	// CountBy counts based on conditions.
	CountBy(ctx context.Context, condition Condition, options ...Option) (int, error)

	// Save create or update model or model array.
	// Accepted "v" types:
	//		*ModelStruct
	//		[]*ModelStruct
	//		[]ModelStruct
	//		ModelStruct
	//  	map[string]interface{}
	// Note:
	//		1. map[string]interface{} might not be supported by underlying implementation
	//		2. ModelStruct is not recommended because auto-generated field default will be lost
	Save(ctx context.Context, v interface{}, options ...Option) error

	// Create create model or model array. returns error if model already exists
	// Accepted "v" types:
	//		*ModelStruct
	//		[]*ModelStruct
	//		[]ModelStruct
	//		ModelStruct
	//  	map[string]interface{}
	// Note:
	//		1. map[string]interface{} might not be supported by underlying implementation
	//		2. ModelStruct is not recommended because auto-generated field default will be lost
	Create(ctx context.Context, v interface{}, options ...Option) error

	// Update update model, only non-zero fields of "v" are updated.
	// "model" is the model to be updated, loaded from DB
	// Accepted "dest" types:
	//		*ModelStruct
	//		ModelStruct
	// Accepted "v" types:
	//		ModelStruct
	//		*ModelStruct
	//		map[string]interface{}
	// Update might support Select and Omit depends on implementation
	// Note: when ModelStruct or *ModelStruct is used, GORM limitation applys:
	// 		 https://gorm.io/docs/update.html#Updates-multiple-columns
	// The workaround is to use Select as described here:
	//		 https://gorm.io/docs/update.html#Update-Selected-Fields
	Update(ctx context.Context, model interface{}, v interface{}, options ...Option) error

	// Delete delete given model or model array
	// Accepted "v" types:
	//		*ModelStruct
	//		[]*ModelStruct
	//		[]ModelStruct
	//		ModelStruct
	// returns error if such deletion violate any existing foreign key constraints
	Delete(ctx context.Context, v interface{}, options ...Option) error

	// DeleteBy delete models matching given condition.
	// returns error if such deletion violate any existing foreign key constraints
	DeleteBy(ctx context.Context, condition Condition, options ...Option) error

	// Truncate attempt to truncate the table associated the repository
	// returns error if such truncattion violate any existing foreign key constraints
	// Warning: User with Caution: interface is not finalized
	Truncate(ctx context.Context) error
}

type Factory

type Factory interface {
	// NewCRUD create an implementation specific CrudRepository.
	// "model" represent the model this repository works on. It could be Struct or *Struct
	// It panic if model is not a valid model definition
	// accepted options depends on implementation. for gorm, *gorm.Session can be supplied
	NewCRUD(model interface{}, options ...interface{}) CrudRepository
}

Factory usually used in repository creation.

type GormApi

type GormApi interface {
	DB(ctx context.Context) *gorm.DB
	Transaction(ctx context.Context, txFunc TxWithGormFunc, opts ...*sql.TxOptions) error
	WithSession(config *gorm.Session) GormApi
}

type GormCrud

type GormCrud struct {
	GormApi
	GormMetadata
}

GormCrud implements CrudRepository and can be embedded into any repositories using gorm as ORM

func (GormCrud) ColumnDataType

func (g GormCrud) ColumnDataType(fieldName string) string

func (GormCrud) ColumnName

func (g GormCrud) ColumnName(fieldName string) string

func (GormCrud) CountAll

func (g GormCrud) CountAll(ctx context.Context, options ...Option) (int, error)

func (GormCrud) CountBy

func (g GormCrud) CountBy(ctx context.Context, condition Condition, options ...Option) (int, error)

func (GormCrud) Create

func (g GormCrud) Create(ctx context.Context, v interface{}, options ...Option) error

func (GormCrud) Delete

func (g GormCrud) Delete(ctx context.Context, v interface{}, options ...Option) error

func (GormCrud) DeleteBy

func (g GormCrud) DeleteBy(ctx context.Context, condition Condition, options ...Option) error

func (GormCrud) FindAll

func (g GormCrud) FindAll(ctx context.Context, dest interface{}, options ...Option) error

func (GormCrud) FindAllBy

func (g GormCrud) FindAllBy(ctx context.Context, dest interface{}, condition Condition, options ...Option) error

func (GormCrud) FindById

func (g GormCrud) FindById(ctx context.Context, dest interface{}, id interface{}, options ...Option) error

func (GormCrud) FindOneBy

func (g GormCrud) FindOneBy(ctx context.Context, dest interface{}, condition Condition, options ...Option) error

func (GormCrud) ModelName

func (g GormCrud) ModelName() string

func (GormCrud) ModelType

func (g GormCrud) ModelType() reflect.Type

func (GormCrud) RelationshipSchema

func (g GormCrud) RelationshipSchema(fieldName string) SchemaResolver

func (GormCrud) Save

func (g GormCrud) Save(ctx context.Context, v interface{}, options ...Option) error

func (GormCrud) Schema

func (g GormCrud) Schema() *schema.Schema

func (GormCrud) Table

func (g GormCrud) Table() string

func (GormCrud) Truncate

func (g GormCrud) Truncate(ctx context.Context) error

func (GormCrud) Update

func (g GormCrud) Update(ctx context.Context, model interface{}, v interface{}, options ...Option) error

type GormFactory

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

func (GormFactory) NewCRUD

func (f GormFactory) NewCRUD(model interface{}, options ...interface{}) CrudRepository

func (GormFactory) NewGormApi

func (f GormFactory) NewGormApi(options ...interface{}) GormApi

type GormMetadata

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

GormMetadata implements GormSchemaResolver

func (GormMetadata) ColumnDataType

func (g GormMetadata) ColumnDataType(fieldName string) string

func (GormMetadata) ColumnName

func (g GormMetadata) ColumnName(fieldName string) string

func (GormMetadata) ModelName

func (g GormMetadata) ModelName() string

func (GormMetadata) ModelType

func (g GormMetadata) ModelType() reflect.Type

func (GormMetadata) RelationshipSchema

func (g GormMetadata) RelationshipSchema(fieldName string) SchemaResolver

func (GormMetadata) Schema

func (g GormMetadata) Schema() *schema.Schema

func (GormMetadata) Table

func (g GormMetadata) Table() string

type GormSchemaResolver

type GormSchemaResolver interface {
	SchemaResolver
	// Schema returns raw schema.Schema.
	Schema() *schema.Schema
}

GormSchemaResolver extends SchemaResolver to expose more schema related functions

type GormUtils

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

GormUtils implements Utility interface

func (GormUtils) CheckUniqueness

func (g GormUtils) CheckUniqueness(ctx context.Context, v interface{}, keys ...interface{}) (dups map[string]interface{}, err error)

func (GormUtils) Model

func (g GormUtils) Model(model interface{}) Utility

func (GormUtils) ResolveSchema

func (g GormUtils) ResolveSchema(ctx context.Context, model interface{}) (SchemaResolver, error)

type Option

type Option interface{}

Option is typically used for generic CRUD repository supported options depends on operation and underlying implementation

  • Omit for read/write
  • Joins for read
  • Preload for read
  • Select for read/write
  • Sort for read
  • Page for read
  • func(*gorm.DB) *gormDB
  • ...

If given condition is not supported, an error with code data.ErrorCodeUnsupportedOptions will be return TODO Provide more supporting features

func ErrorOnZeroRows

func ErrorOnZeroRows() Option

ErrorOnZeroRows a post-exec option that force repository returns error in case of db.AffectedRows == 0 This option is useful on certain operations such as CrudRepository.Delete, or CrudRepository.Update, which doesn't return error if there is no row get affected/deleted.

func Joins

func Joins(query string, args ...interface{}) Option

Joins is an Option for Find* operations, typically used to populate "ToOne" relationship using JOIN clause e.g. CrudRepository.FindById(ctx, &user, Joins("Status"))

When used on "ToMany", JOIN query is usually used instead of field e.g. CrudRepository.FindById(ctx, &user, Joins("JOIN address ON address.user_id = users.id AND address.country = ?", "Canada"))

func Omit

func Omit(fields ...string) Option

Omit is an Option specifying fields that you want to ignore when creating, updating and querying. When supported by gorm.io, this Option is a direct bridge to (*gorm.DB).Omit(). Please see https://gorm.io/docs/ for detailed usage

func Page

func Page(page, size int) Option

Page is an Option specifying pagination when retrieve records from database page: page number started with 0 size: page size (# of records per page) e.g.

CrudRepository.FindAll(ctx, &user, Page(2, 10))
CrudRepository.FindAllBy(ctx, &user, Where(...), Page(2, 10))

func Preload

func Preload(query string, args ...interface{}) Option

Preload is an Option for Find* operations, typically used to populate relationship fields using separate queries e.g.

CrudRepository.FindAll(ctx, &user, Preload("Roles.Permissions"))
CrudRepository.FindAll(ctx, &user, Preload("Roles", "role_name NOT IN (?)", "excluded"))

func Select

func Select(query interface{}, args ...interface{}) Option

Select is an Option specify fields that you want when querying, creating, updating. This Option has different meaning when used for different operations (query vs create vs update vs save vs delete) When supported by gorm.io, this Option is a direct bridge to (*gorm.DB).Select(). // Please see https://gorm.io/docs/ for detailed usage

func Sort

func Sort(value interface{}) Option

Sort is an Option specifying order when retrieve records from database by using column. This Option is typically used together with Page option When supported by gorm.io, this Option is a direct bridge to (*gorm.DB).Order() e.g.

CrudRepository.FindAll(ctx, &user, Page(2, 10), Sort("name DESC"))
CrudRepository.FindAllBy(ctx, &user, Where(...), Page(2, 10), Sort(clause.OrderByColumn{Column: clause.Column{Name: "name"}, Desc: true}))

func SortBy

func SortBy(fieldName string, desc bool) Option

SortBy an Option similar to Sort, but specifying model's field name This Option also support order by direct "ToOne" relation's field when used together with Joins. e.g.

CrudRepository.FindAll(ctx, &user, Joins("Profile"), Page(2, 10), SortBy("Profile.FirstName", false))
CrudRepository.FindAllBy(ctx, &user, Where(...), Page(2, 10), SortBy("Username", true))

type SchemaResolver

type SchemaResolver interface {
	// ModelType returns reflect type of the model
	ModelType() reflect.Type
	// ModelName returns the name of the model
	ModelName() string
	// Table resolve table name of the model
	Table() string
	// ColumnName resolves the column name by given field name of the Model.
	// field path is supported, e.g. "AssociationField.FieldName"
	ColumnName(fieldName string) string
	// ColumnDataType resolves the column data type string by given field name of the Model
	// field path is supported, e.g. "AssociationField.FieldName"
	ColumnDataType(fieldName string) string
	// RelationshipSchema returns SchemaResolver of the relationship fields with given name.
	// This function returns nil if given field name is not a relationship field.
	RelationshipSchema(fieldName string) SchemaResolver
}

SchemaResolver resolves schema related values

type TxWithGormFunc

type TxWithGormFunc func(ctx context.Context, tx *gorm.DB) error

type Utility

type Utility interface {

	// Model returns a model-specific implementation of Utility.
	// It is useful when model type cannot be deduced from provided parameters
	// e.g.
	// <code>
	//	// this is ok, because value &SomeModel{} also imply the model type
	// 	Utility.CheckUniqueness(ctx, &SomeModel{})
	//
	//	// this is ok, because the model type is specified via Model()
	// 	Utility.Model(&SomeModel{}).CheckUniqueness(ctx, map[string]interface{}{"Field1":"Value1"})
	//
	//  // this is NOT ok, because there is no way to tell what model it is
	// 	Utility.CheckUniqueness(ctx, map[string]interface{}{"Field1":"Value1"})
	// </code>
	Model(model interface{}) Utility

	// ResolveSchema parse given model and returns its SchemaResolver
	// It's highly recommended to use CrudRepository instead of this one.
	ResolveSchema(ctx context.Context, model interface{}) (SchemaResolver, error)

	// CheckUniqueness check if any non-zero unique field of given model ("v") violate unique key constraints in DB
	// When uniqueness check fails, the returned map contains field names and values that violate the constraints
	// and a data.ErrorSubTypeDataIntegrity error
	// Accepted "v" types:
	// 		*ModelStruct
	//		[]*ModelStruct
	// 		map[string]interface{} where key is model's field name or col name
	// By default, this function would use models' schema to figure out unique keys.
	// However, if "keys" is provided, it would override schema definition
	// Supported "keys types:
	// 		string: single field/column
	// 		[]string: index key
	// Note: primary key is not included by default
	CheckUniqueness(ctx context.Context, v interface{}, keys ...interface{}) (map[string]interface{}, error)
}

Utility is a collection of repository related patterns that are useful for common service layer implementation

func Utils

func Utils(options ...interface{}) Utility

Jump to

Keyboard shortcuts

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