gocrud

package module
v0.0.0-...-f5e801a Latest Latest
Warning

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

Go to latest
Published: Jun 27, 2026 License: MIT Imports: 24 Imported by: 9

README

CRUD in Golang

Example

See crud_test.go

Documentation

Index

Constants

View Source
const (
	XFileDigest = "X-File-Digest"
)

Variables

View Source
var (
	NilGroupError    = errors.New("group is nil")
	NilDatabaseError = errors.New("database is nil")
)
View Source
var (
	DefaultPageSizes = []uint64{10, 20, 50, 100}
	DefaultPageSize  = uint64(50)
)
View Source
var (
	DefaultOkayHttpStatusRange = HttpStatusRange{http.StatusOK, http.StatusMultipleChoices}
	ErrorBaseURLRequired       = errors.New("BaseURL is required")
)
View Source
var (
	ErrorIncompleteWrite    = errors.New("incomplete write")
	ErrorFileExists         = errors.New("file already exists")
	ErrorFileIsDir          = errors.New("file is a directory")
	ErrorUploadNotAllowed   = errors.New("upload not allowed")
	ErrorFileDigestMismatch = errors.New("digest mismatch")
)
View Source
var IDKind = reflect.Uint64
View Source
var (
	NotArrayError = fmt.Errorf("not an array")
)
View Source
var RestCoder = NewDefaultCoder()

Functions

func DefaultCorsConfig

func DefaultCorsConfig() cors.Config

func DuplicateFieldCheck

func DuplicateFieldCheck[T any](
	db *gorm.DB, context *gin.Context, logger *gogger.Logger,
	objectForCheck *T, objectFieldName, dbFieldName string,
) error

DuplicateFieldCheck T must extend from Base which must contain id field

func GetJSONFieldNameOf

func GetJSONFieldNameOf[T any](fields ...string) ([]string, error)

func GetSearchValuesFromContext

func GetSearchValuesFromContext(context *gin.Context) (url.Values, error)

func HandleSearch

func HandleSearch(context *gin.Context, db *gorm.DB, searchHandlers SearchHandlers) (*gorm.DB, error)

func IDsJoin

func IDsJoin(ids []ID, sep string) string

func IsNotEmptyArray

func IsNotEmptyArray(v any) bool

func MakeErrorResponse

func MakeErrorResponse(context *gin.Context, code Code, err any)

func MakeJSONRequest

func MakeJSONRequest[T any](
	httpClient *http.Client, okayHttpStatusRange *HttpStatusRange,
	u *url.URL, method string,
	body io.Reader, res *R[T],
) error

func MakeOkayDataResponse

func MakeOkayDataResponse[T any](context *gin.Context, data T)

func MakeOkayResponse

func MakeOkayResponse[T any](context *gin.Context, code Code, message string, data T)

func MapFuncOverCommaSeparatedString

func MapFuncOverCommaSeparatedString(mapFunc func(string), css string)

func NewCors

func NewCors() gin.HandlerFunc

func NewHardDeleteHandler

func NewHardDeleteHandler[T any](coder Coder) func(context *gin.Context, db *gorm.DB) bool

func NewHttpFileSystem

func NewHttpFileSystem(group *gin.RouterGroup, folder string, config *HttpFileSystemConfig) error

func NewSingleHTMLServe

func NewSingleHTMLServe(group *gin.RouterGroup, indexHTMLFile string, config *SingleHTMLServeConfig) error

func NewSoftDeleteHandler

func NewSoftDeleteHandler[T any](coder Coder) func(context *gin.Context, db *gorm.DB) bool

func NowString

func NowString(patternOrEmpty string) string

func NumericValidate

func NumericValidate(value string) any

func OverflowedArrayTrimmer

func OverflowedArrayTrimmer[T any](array []T, max int) []T

func OverflowedArrayTrimmerFilter

func OverflowedArrayTrimmerFilter[T any](max int) func([]T) []T

func Pick

func Pick[T any](arr []T, index int, defaultValue T) T

func PickFirstValuableString

func PickFirstValuableString(array []string) (string, bool)

func RecoveryHandler

func RecoveryHandler(responseFullError bool) gin.HandlerFunc

func RemoveDuplication

func RemoveDuplication[T ~[]E, E comparable](array T) T

func SaveAsDigestedFile

func SaveAsDigestedFile(
	folder string,
	filename string,
	reader io.Reader,
	length int64,
	validigest FileDigest,
) (Filename, FileDigest, error)

func Setup

func Setup[T any](
	group *gin.RouterGroup,
	database *gorm.DB,
	logger *gogger.Logger,
	crud *Crud[T],
) error

func SetupDualPrimaryKeyModelController

func SetupDualPrimaryKeyModelController[T any](
	group *gin.RouterGroup, db *gorm.DB, logger *gogger.Logger,
	objectFieldName1, objectFieldName2 string,
	databaseFieldName1, databaseFieldName2 string,
	extraSearchHandlers ...SearchHandlers,
) error

func StringArrayFromCommaSeparatedString

func StringArrayFromCommaSeparatedString(css string) []string

func Ternary

func Ternary[T any](condition bool, onTrue T, onFalse T) T

func TernaryFunc

func TernaryFunc[T any](conditionFunc func() bool, onTrueFunc, onFalseFunc func() T) T

func Wait4CtrlC

func Wait4CtrlC() os.Signal

Types

type Base

type Base struct {
	ID        ID         `json:"id"        gorm:"primaryKey"`
	Priority  int64      `json:"priority"`
	CreatedAt time.Time  `json:"createdAt" gorm:"autoCreateTime;<-:create"`
	UpdatedAt time.Time  `json:"updatedAt" gorm:"autoUpdateTime"`
	DeletedAt *time.Time `json:"deletedAt"`
}

type Code

type Code string

type Coder

type Coder interface {
	OK() Code
	InternalServerError() Code
	BadRequest() Code
	NotFound() Code
	MethodNotAllowed() Code
	Conflict() Code

	From(code string) Code
	FromStatus(status int) Code
}

func NewDefaultCoder

func NewDefaultCoder() Coder

type Crud

type Crud[T any] struct {
	DisallowNonstandardPageSize bool
	DefaultPageSize             uint64
	PageSizes                   []uint64

	SearchHandlers SearchHandlers

	EnableGetAll  bool
	DisableGetOne bool
	DisableCount  bool
	DisablePage   bool
	DisableSave   bool
	DisableDelete bool

	WillGetAll func(context *gin.Context, db *gorm.DB) *gorm.DB
	DidGetAll  func(records []T, context *gin.Context, db *gorm.DB)

	WillGetOne func(context *gin.Context, db *gorm.DB) *gorm.DB
	DidGetOne  func(record *T, context *gin.Context, db *gorm.DB)

	WillCount func(context *gin.Context, db *gorm.DB) *gorm.DB
	DidCount  func(count *int64, context *gin.Context, db *gorm.DB)

	WillPage func(pageNum *uint64, pageSize *uint64, context *gin.Context, db *gorm.DB) *gorm.DB
	DidPage  func(pageNum uint64, pageSize uint64, list []T, context *gin.Context, db *gorm.DB)

	WillSave func(record *T, context *gin.Context, db *gorm.DB)
	DidSave  func(record *T, context *gin.Context, db *gorm.DB)

	WillDelete func(context *gin.Context, db *gorm.DB)
	OnDelete   func(context *gin.Context, db *gorm.DB) bool
	DidDelete  func(context *gin.Context, db *gorm.DB)

	Coder             Coder
	MakeOkayResponse  func(context *gin.Context, data any)
	MakeErrorResponse func(context *gin.Context, code Code, err any)

	GetCensors func(context *gin.Context, db *gorm.DB) ([]*censored.Censor, error)
	// contains filtered or unexported fields
}

type Crudy

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

func NewCrudy

func NewCrudy[T any](baseURL string, options ...CrudyOption[T]) (*Crudy[T], error)

func (*Crudy[T]) All

func (c *Crudy[T]) All(searchParams SearchParams) ([]T, error)

func (*Crudy[T]) BuildURL

func (c *Crudy[T]) BuildURL(uri string, searchParams SearchParams) (*url.URL, error)

func (*Crudy[T]) Count

func (c *Crudy[T]) Count(searchParams SearchParams) (uint64, error)

func (*Crudy[T]) Delete

func (c *Crudy[T]) Delete(id ID) (bool, error)

func (*Crudy[T]) One

func (c *Crudy[T]) One(id ID) (*T, error)

func (*Crudy[T]) Page

func (c *Crudy[T]) Page(current, size uint64, searchParams SearchParams) ([]T, error)

func (*Crudy[T]) Save

func (c *Crudy[T]) Save(t *T) (*T, error)

type CrudyBasicOptions

type CrudyBasicOptions[T any] struct {
	CrudyOption[T]
	BaseURL             string
	HttpClient          *http.Client
	OkayHttpStatusRange *HttpStatusRange
}

func (CrudyBasicOptions[T]) Apply

func (b CrudyBasicOptions[T]) Apply(crudy *Crudy[T]) error

type CrudyOption

type CrudyOption[T any] interface {
	Apply(*Crudy[T]) error
}

type CrudyPageOptions

type CrudyPageOptions[T any] struct {
	CrudyOption[T]
	DefaultSize uint64
}

func (CrudyPageOptions[T]) Apply

func (b CrudyPageOptions[T]) Apply(crudy *Crudy[T]) error

type DefaultCoder

type DefaultCoder struct {
	Coder
}

func (*DefaultCoder) BadRequest

func (d *DefaultCoder) BadRequest() Code

func (*DefaultCoder) Conflict

func (d *DefaultCoder) Conflict() Code

func (*DefaultCoder) From

func (d *DefaultCoder) From(code string) Code

func (*DefaultCoder) FromStatus

func (d *DefaultCoder) FromStatus(status int) Code

func (*DefaultCoder) InternalServerError

func (d *DefaultCoder) InternalServerError() Code

func (*DefaultCoder) MethodNotAllowed

func (d *DefaultCoder) MethodNotAllowed() Code

func (*DefaultCoder) NotFound

func (d *DefaultCoder) NotFound() Code

func (*DefaultCoder) OK

func (d *DefaultCoder) OK() Code

type DualPrimaryKeyModelHandler

type DualPrimaryKeyModelHandler[T1 any, T2 any, DPKM any] struct {
	ObjectFieldName1 string
	ObjectFieldName2 string
	// contains filtered or unexported fields
}

DualPrimaryKeyModelHandler T1: model 1, should have ID field, connected by objectFieldName1 of DPKM T2: model 2, should have ID field, connected by objectFieldName2 of DPKM DPKM: dual primary key model

func NewDualPrimaryKeyModelHandler

func NewDualPrimaryKeyModelHandler[T1 any, T2 any, DPKM any](
	baseURL string,
	httpClient *http.Client,
	okayHttpStatusRange *HttpStatusRange,
	objectFieldName1, objectFieldName2 string,
) (*DualPrimaryKeyModelHandler[T1, T2, DPKM], error)

func (*DualPrimaryKeyModelHandler[T1, T2, DPKM]) Delete

func (d *DualPrimaryKeyModelHandler[T1, T2, DPKM]) Delete(id1, id2 ID) (int64, error)

func (*DualPrimaryKeyModelHandler[T1, T2, DPKM]) GetAll

func (d *DualPrimaryKeyModelHandler[T1, T2, DPKM]) GetAll(t1IDs, t2IDs []ID, params ...SearchParams) ([]DPKM, error)

func (*DualPrimaryKeyModelHandler[T1, T2, DPKM]) Save

func (d *DualPrimaryKeyModelHandler[T1, T2, DPKM]) Save(records []DPKM) (int64, error)

func (*DualPrimaryKeyModelHandler[T1, T2, DPKM]) SaveAfterDelete

func (d *DualPrimaryKeyModelHandler[T1, T2, DPKM]) SaveAfterDelete(deleteByField string, idToDelete ID, records []DPKM) (int64, error)

type FileDigest

type FileDigest string

type Filename

type Filename string

type HttpFileSystemConfig

type HttpFileSystemConfig struct {
	AllowUpload    bool
	AllowOverwrite bool
	EnableDigest   bool // EnableDigest: if true, will save file with its digest, and discard client defined filename
	Coder          Coder
}

type HttpStatusRange

type HttpStatusRange [2]int

type ID

type ID uint64

func IDsFromCommaSeparatedString

func IDsFromCommaSeparatedString(css string) []ID

type Operator

type Operator string
const (
	OperatorEqual      Operator = "="
	OperatorLike       Operator = "LIKE"
	OperatorNotLike    Operator = "NOT LIKE"
	OperatorIn         Operator = "IN"
	OperatorNotIn      Operator = "NOT IN"
	OperatorNull       Operator = "IS NULL"
	OperatorNNull      Operator = "IS NOT NULL"
	OperatorBetween    Operator = "BETWEEN"
	OperatorNotBetween Operator = "NOT BETWEEN"
	OperatorGt         Operator = ">"
	OperatorGte        Operator = ">="
	OperatorLt         Operator = "<"
	OperatorLte        Operator = "<="
	OperatorNeq        Operator = "!="
)

type R

type R[T any] struct {
	Code    Code   `json:"c,omitempty"`
	Message string `json:"m,omitempty"`
	Data    T      `json:"d,omitempty"`
}

type SearchHandler

type SearchHandler = func(db *gorm.DB, values []string, context *gin.Context) (*gorm.DB, error)

func KeywordEqual

func KeywordEqual(field string, vt ValueTransformer[string, any]) SearchHandler

func KeywordIDIn

func KeywordIDIn(field string, vt ValueTransformer[[]ID, []ID]) SearchHandler

func KeywordIn

func KeywordIn(field string, vt ValueTransformer[[]string, []string]) SearchHandler

func KeywordLike

func KeywordLike(field string, vt ValueTransformer[string, any]) SearchHandler

func KeywordStatement

func KeywordStatement(field string, operator Operator, vt ValueTransformer[string, any]) SearchHandler

func NewSoftDeleteSearchHandler

func NewSoftDeleteSearchHandler(tableName string) SearchHandler

func SortBy

func SortBy(field string) SearchHandler

type SearchHandlers

type SearchHandlers = map[string]SearchHandler

func BaseSearchHandlers

func BaseSearchHandlers(overrideSearchHandlers ...SearchHandlers) SearchHandlers

type SearchParams

type SearchParams map[string]string

type SingleHTMLServeConfig

type SingleHTMLServeConfig struct {
	AllowReplace bool
	Coder        Coder
}

type ValueTransformer

type ValueTransformer[T any, R any] func(value T) R

Jump to

Keyboard shortcuts

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