README

GORM

This package contains a set of utilities for famous GORM library. If used together they can significantly help you to enable persistency in your application.

Collection Operators

The package provides some helpers which are able to apply collection operators defined in query package to a GORM query.

Applying query.Filtering
...
// given that Person is a protobuf message and PersonORM is a corresponding GORM model
db, assoc, err = gorm.ApplyFiltering(ctx, db, filtering, &PersonORM{}, &Person{})
if err != nil {
    ...
}
// Join required associations(for nested field support)
db, err = gorm.JoinAssociations(ctx, db, assoc, &PersonORM{})
if err != nil {
    ...
}
var people []Person
db.Find(&people)
...
Applying query.Sorting
...
db, assoc, err = gorm.ApplySorting(ctx, db, sorting, &PersonORM{}, &Person{})
if err != nil {
    ...
}
// Join required associations(for nested field support)
db, err = gorm.JoinAssociations(ctx, db, assoc, &PersonORM{})
if err != nil {
    ...
}
var people []Person
db.Find(&people)
...
Applying query.Pagination
...
db = gorm.ApplyPagination(ctx, db, pagination, &PersonORM{}, &Person{})
if err != nil {
    ...
}
var people []Person
db.Find(&people)
...
Applying query.FieldSelection
...
db, err = gorm.ApplyFieldSelection(ctx, db, fields, &PersonORM{}, &Person{})
if err != nil {
    ...
}
var people []Person
db.Find(&people)
...
Applying everything
...
db, err = gorm.ApplyCollectionOperators(ctx, db, &PersonORM{}, &Person{}, filtering, sorting, pagination, fields)
if err != nil {
    ...
}
var people []Person
db.Find(&people)
...

Transaction Management

We provide transaction management by offering gorm.Transaction wrapper and gorm.UnaryServerInterceptor. The gorm.Transaction works as a singleton to prevent an application of creating more than one transaction instance per incoming request. The gorm.UnaryServerInterceptor performs management on transactions. Interceptor creates new transaction on each incoming request and commits it if request finishes without error, otherwise transaction is aborted. The created transaction is stored in context.Context and passed to the request handler as usual.

NOTE Client is responsible to call txn.Begin() to open transaction.

// add gorm interceptor to the chain
  server := grpc.NewServer(
    grpc.UnaryInterceptor(
      grpc_middleware.ChainUnaryServer( // middleware chain
        ...
        gorm.UnaryServerInterceptor(), // transaction management
        ...
      ),
    ),
  )
import (
	"github.com/infobloxopen/atlas-app-toolkit/gorm"
)

func (s *MyService) MyMethod(ctx context.Context, req *MyMethodRequest) (*MyMethodResponse, error) {
	// extract gorm transaction from context
	txn, ok := gorm.FromContext(ctx)
	if !ok {
		return panic("transaction is not opened") // don't panic in production!
	}
	// start transaction
	gormDB := txn.Begin()
	if err := gormDB.Error; err != nil {
		return nil, err
	}
	// do stuff with *gorm.DB
	return &MyMethodResponse{...}, nil
}

Migration version validation

The toolkit does not require any specific method for database provisioning and setup. However, if golang-migrate or the infobloxopen fork of it is used, a couple helper functions are provided here for verifying that the database version matches a required version without having to import the entire migration package.

Expand ▾ Collapse ▴

Documentation

Index

Constants

This section is empty.

Variables

View Source
var (
	ErrCtxTxnMissing = errors.New("Database transaction for request missing in context")
	ErrCtxTxnNoDB    = errors.New("Transaction in context, but DB is nil")
)

Functions

func ApplyCollectionOperators

func ApplyCollectionOperators(ctx context.Context, db *gorm.DB, obj interface{}, pb proto.Message, f *query.Filtering, s *query.Sorting, p *query.Pagination, fs *query.FieldSelection) (*gorm.DB, error)

    Deprecated: use ApplyCollectionOperatorsEx instead ApplyCollectionOperators applies collection operators to gorm instance db.

    func ApplyCollectionOperatorsEx

    func ApplyCollectionOperatorsEx(ctx context.Context, db *gorm.DB, obj interface{}, c CollectionOperatorsConverter, f *query.Filtering, s *query.Sorting, p *query.Pagination, fs *query.FieldSelection) (*gorm.DB, error)

    func ApplyFieldSelection

    func ApplyFieldSelection(ctx context.Context, db *gorm.DB, fs *query.FieldSelection, obj interface{}) (*gorm.DB, error)

      Deprecated: use ApplyFieldSelectionEx instead ApplyFieldSelection applies field selection operator fs to gorm instance db.

      func ApplyFieldSelectionEx

      func ApplyFieldSelectionEx(ctx context.Context, db *gorm.DB, fs *query.FieldSelection, obj interface{}, c FieldSelectionConverter) (*gorm.DB, error)

        ApplyFieldSelectionEx applies field selection operator fs to gorm instance db.

        func ApplyFiltering

        func ApplyFiltering(ctx context.Context, db *gorm.DB, f *query.Filtering, obj interface{}, pb proto.Message) (*gorm.DB, map[string]struct{}, error)

          Deprecated: use ApplyFilteringEx instead ApplyFiltering applies filtering operator f to gorm instance db.

          func ApplyFilteringEx

          func ApplyFilteringEx(ctx context.Context, db *gorm.DB, f *query.Filtering, obj interface{}, c FilteringConditionConverter) (*gorm.DB, map[string]struct{}, error)

            ApplyFiltering applies filtering operator f to gorm instance db.

            func ApplyPagination

            func ApplyPagination(ctx context.Context, db *gorm.DB, p *query.Pagination) *gorm.DB

              ApplyPagination applies pagination operator p to gorm instance db.

              func ApplyPaginationEx

              func ApplyPaginationEx(ctx context.Context, db *gorm.DB, p *query.Pagination, c PaginationConverter) *gorm.DB

                ApplyPaginationEx applies pagination operator p to gorm instance db.

                func ApplySorting

                func ApplySorting(ctx context.Context, db *gorm.DB, s *query.Sorting, obj interface{}) (*gorm.DB, map[string]struct{}, error)

                  Deprecated: use ApplySortingEx instead ApplySorting applies sorting operator s to gorm instance db.

                  func ApplySortingEx

                  func ApplySortingEx(ctx context.Context, db *gorm.DB, s *query.Sorting, obj interface{}, c SortingCriteriaConverter) (*gorm.DB, map[string]struct{}, error)

                    ApplySorting applies sorting operator s to gorm instance db.

                    func BeginFromContext

                    func BeginFromContext(ctx context.Context) (*gorm.DB, error)

                      BeginFromContext will extract transaction wrapper from context and start new transaction. As result new instance of `*gorm.DB` will be returned. Error will be returned in case either transaction or db connection info is missing in context. Gorm specific error can be checked by `*gorm.DB.Error`.

                      func BeginWithOptionsFromContext

                      func BeginWithOptionsFromContext(ctx context.Context, opts *sql.TxOptions) (*gorm.DB, error)

                        BeginWithOptionsFromContext will extract transaction wrapper from context and start new transaction, options can be specified to control isolation level for transaction. As result new instance of `*gorm.DB` will be returned. Error will be returned in case either transaction or db connection info is missing in context. Gorm specific error can be checked by `*gorm.DB.Error`.

                        func FieldSelectionStringToGorm

                        func FieldSelectionStringToGorm(ctx context.Context, fs string, obj interface{}) ([]string, error)

                          FieldSelectionStringToGorm is a shortcut to parse a string into FieldSelection struct and receive a list of associations to preload.

                          func FilterStringToGorm

                          func FilterStringToGorm(ctx context.Context, filter string, obj interface{}, pb proto.Message) (string, []interface{}, map[string]struct{}, error)

                            FilterStringToGorm is a shortcut to parse a filter string using default FilteringParser implementation and call FilteringToGorm on the returned filtering expression.

                            func FilteringToGorm

                            func FilteringToGorm(ctx context.Context, m *query.Filtering, obj interface{}, pb proto.Message) (string, []interface{}, map[string]struct{}, error)

                              Deprecated: Use FilteringToGormEx instead FilteringToGorm returns GORM Plain SQL representation of the filtering expression.

                              func FilteringToGormEx

                              func FilteringToGormEx(ctx context.Context, m *query.Filtering, obj interface{}, c FilteringConditionConverter) (string, []interface{}, map[string]struct{}, error)

                                FilteringToGorm returns GORM Plain SQL representation of the filtering expression.

                                func HandleFieldPath

                                func HandleFieldPath(ctx context.Context, fieldPath []string, obj interface{}) (string, string, error)

                                  HandleFieldPath converts fieldPath to appropriate db string for use in where/order by clauses according to obj GORM model. If fieldPath cannot be found in obj then original fieldPath is returned to allow tables joined by a third party. If association join is required to resolve the field path then it's name is returned as a second return value.

                                  func HandleJSONFieldPath

                                  func HandleJSONFieldPath(ctx context.Context, fieldPath []string, obj interface{}, values ...string) (string, string, error)

                                    HandleJSONFiledPath translate field path to JSONB path for postgres jsonb

                                    func IsJSONCondition

                                    func IsJSONCondition(ctx context.Context, fieldPath []string, obj interface{}) bool

                                      TODO: add supprt for embeded objects

                                      func JoinAssociations

                                      func JoinAssociations(ctx context.Context, db *gorm.DB, assoc map[string]struct{}, obj interface{}) (*gorm.DB, error)

                                        JoinAssociations joins obj's associations from assoc to the current gorm query.

                                        func JoinInfo

                                        func JoinInfo(ctx context.Context, obj interface{}, assoc string) (string, []string, []string, error)

                                          JoinInfo extracts the following information for assoc association of obj: - association table name - source join keys - target join keys

                                          func MergeWithMask

                                          func MergeWithMask(source, dest interface{}, mask *fieldmask.FieldMask) error

                                            MergeWithMask will take the fields of `source` that are included as paths in `mask` and write them to the corresponding fields of `dest`

                                            func NewContext

                                            func NewContext(parent context.Context, txn *Transaction) context.Context

                                              NewContext returns a new Context that carries value txn.

                                              func UnaryServerInterceptor

                                              func UnaryServerInterceptor(db *gorm.DB) grpc.UnaryServerInterceptor

                                                UnaryServerInterceptor returns grpc.UnaryServerInterceptor that manages a `*Transaction` instance. New *Transaction instance is created before grpc.UnaryHandler call. Client is responsible to call `txn.Begin()` to open transaction. If call of grpc.UnaryHandler returns with an error the transaction is aborted, otherwise committed.

                                                func VerifyMigrationVersion

                                                func VerifyMigrationVersion(db *jgorm.DB, v MigrationVersionValidator) error

                                                  VerifyMigrationVersion checks the schema_migrations table of the db passed against the ValidVersion function of the given validator, returning an error for an invalid version or a dirty database

                                                  Types

                                                  type CollectionOperatorsConverter

                                                  func NewDefaultPbToOrmConverter

                                                  func NewDefaultPbToOrmConverter(pb proto.Message) CollectionOperatorsConverter

                                                    NewDefaultPbToOrmConverter creates default converter for all collection operators

                                                    type DefaultFieldSelectionConverter

                                                    type DefaultFieldSelectionConverter struct{}

                                                      DefaultFieldSelectionConverter performs default convertion for FieldSelection collection operator

                                                      func (*DefaultFieldSelectionConverter) FieldSelectionToGorm

                                                      func (converter *DefaultFieldSelectionConverter) FieldSelectionToGorm(ctx context.Context, fs *query.FieldSelection, obj interface{}) ([]string, error)

                                                        FieldSelectionToGorm receives FieldSelection struct and returns a list of associations to preload.

                                                        type DefaultFilteringConditionConverter

                                                        type DefaultFilteringConditionConverter struct {
                                                        	Processor FilteringConditionProcessor
                                                        }

                                                          DefaultFilteringConditionConverter performs default convertion for Filter collection operator

                                                          func (*DefaultFilteringConditionConverter) LogicalOperatorToGorm

                                                          func (converter *DefaultFilteringConditionConverter) LogicalOperatorToGorm(ctx context.Context, lop *query.LogicalOperator, obj interface{}) (string, []interface{}, map[string]struct{}, error)

                                                            LogicalOperatorToGorm returns GORM Plain SQL representation of the logical operator.

                                                            func (*DefaultFilteringConditionConverter) NullConditionToGorm

                                                            func (converter *DefaultFilteringConditionConverter) NullConditionToGorm(ctx context.Context, c *query.NullCondition, obj interface{}) (string, []interface{}, map[string]struct{}, error)

                                                              NullConditionToGorm returns GORM Plain SQL representation of the null condition.

                                                              func (*DefaultFilteringConditionConverter) NumberArrayConditionToGorm

                                                              func (converter *DefaultFilteringConditionConverter) NumberArrayConditionToGorm(ctx context.Context, c *query.NumberArrayCondition, obj interface{}) (string, []interface{}, map[string]struct{}, error)

                                                              func (*DefaultFilteringConditionConverter) NumberConditionToGorm

                                                              func (converter *DefaultFilteringConditionConverter) NumberConditionToGorm(ctx context.Context, c *query.NumberCondition, obj interface{}) (string, []interface{}, map[string]struct{}, error)

                                                                NumberConditionToGorm returns GORM Plain SQL representation of the number condition.

                                                                func (*DefaultFilteringConditionConverter) StringArrayConditionToGorm

                                                                func (converter *DefaultFilteringConditionConverter) StringArrayConditionToGorm(ctx context.Context, c *query.StringArrayCondition, obj interface{}) (string, []interface{}, map[string]struct{}, error)

                                                                func (*DefaultFilteringConditionConverter) StringConditionToGorm

                                                                func (converter *DefaultFilteringConditionConverter) StringConditionToGorm(ctx context.Context, c *query.StringCondition, obj interface{}) (string, []interface{}, map[string]struct{}, error)

                                                                  StringConditionToGorm returns GORM Plain SQL representation of the string condition.

                                                                  type DefaultFilteringConditionProcessor

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

                                                                    DefaultFilteringConditionProcessor processes filter operator conversion

                                                                    func (*DefaultFilteringConditionProcessor) ProcessStringCondition

                                                                    func (p *DefaultFilteringConditionProcessor) ProcessStringCondition(ctx context.Context, fieldPath []string, value string) (interface{}, error)

                                                                      ProcessStringCondition processes a string condition to GORM Plain SQL representation

                                                                      type DefaultPaginationConverter

                                                                      type DefaultPaginationConverter struct{}

                                                                        DefaultPaginationConverter performs default convertion for Paging collection operator

                                                                        func (*DefaultPaginationConverter) PaginationToGorm

                                                                        func (converter *DefaultPaginationConverter) PaginationToGorm(ctx context.Context, p *query.Pagination) (offset, limit int32)

                                                                        type DefaultPbToOrmConverter

                                                                          DefaultPbToOrmConverter performs default convertion for all collection operators

                                                                          type DefaultSortingCriteriaConverter

                                                                          type DefaultSortingCriteriaConverter struct{}

                                                                            DefaultSortingCriteriaConverter performs default convertion for Sorting collection operator

                                                                            func (*DefaultSortingCriteriaConverter) SortingCriteriaToGorm

                                                                            func (converter *DefaultSortingCriteriaConverter) SortingCriteriaToGorm(ctx context.Context, cr *query.SortCriteria, obj interface{}) (string, string, error)

                                                                            type EmptyFieldPathError

                                                                            type EmptyFieldPathError struct {
                                                                            }

                                                                            func (*EmptyFieldPathError) Error

                                                                            func (e *EmptyFieldPathError) Error() string

                                                                            type FieldSelectionConverter

                                                                            type FieldSelectionConverter interface {
                                                                            	FieldSelectionToGorm(ctx context.Context, fs *query.FieldSelection, obj interface{}) ([]string, error)
                                                                            }

                                                                            type FilteringConditionProcessor

                                                                            type FilteringConditionProcessor interface {
                                                                            	ProcessStringCondition(ctx context.Context, fieldPath []string, value string) (interface{}, error)
                                                                            }

                                                                            type LogicalOperatorConverter

                                                                            type LogicalOperatorConverter interface {
                                                                            	LogicalOperatorToGorm(ctx context.Context, lop *query.LogicalOperator, obj interface{}) (string, []interface{}, map[string]struct{}, error)
                                                                            }

                                                                            type MigrationVersionValidator

                                                                            type MigrationVersionValidator interface {
                                                                            	ValidVersion(int64) error
                                                                            }

                                                                              MigrationVersionValidator has a function for checking the database version

                                                                              func MaxVersionFrom

                                                                              func MaxVersionFrom(path string) (MigrationVersionValidator, error)

                                                                                MaxVersionFrom returns a MigrationVersionValidator with a target based on the highest numbered migration file detected in the given directory

                                                                                func VersionExactly

                                                                                func VersionExactly(version int64) MigrationVersionValidator

                                                                                  VersionExactly returns a MigrationVersionValidator with a specific target version

                                                                                  func VersionRange

                                                                                  func VersionRange(lower, upper int64) MigrationVersionValidator

                                                                                    VersionRange returns a MigrationVersionValidator with a given lower and upper bound

                                                                                    type NullConditionConverter

                                                                                    type NullConditionConverter interface {
                                                                                    	NullConditionToGorm(ctx context.Context, c *query.NullCondition, obj interface{}) (string, []interface{}, map[string]struct{}, error)
                                                                                    }

                                                                                    type NumberArrayConditionConverter

                                                                                    type NumberArrayConditionConverter interface {
                                                                                    	NumberArrayConditionToGorm(ctx context.Context, c *query.NumberArrayCondition, obj interface{}) (string, []interface{}, map[string]struct{}, error)
                                                                                    }

                                                                                    type NumberConditionConverter

                                                                                    type NumberConditionConverter interface {
                                                                                    	NumberConditionToGorm(ctx context.Context, c *query.NumberCondition, obj interface{}) (string, []interface{}, map[string]struct{}, error)
                                                                                    }

                                                                                    type PaginationConverter

                                                                                    type PaginationConverter interface {
                                                                                    	PaginationToGorm(ctx context.Context, p *query.Pagination) (offset, limit int32)
                                                                                    }

                                                                                    type SortingCriteriaConverter

                                                                                    type SortingCriteriaConverter interface {
                                                                                    	SortingCriteriaToGorm(ctx context.Context, cr *query.SortCriteria, obj interface{}) (string, string, error)
                                                                                    }

                                                                                    type StringArrayConditionConverter

                                                                                    type StringArrayConditionConverter interface {
                                                                                    	StringArrayConditionToGorm(ctx context.Context, c *query.StringArrayCondition, obj interface{}) (string, []interface{}, map[string]struct{}, error)
                                                                                    }

                                                                                    type StringConditionConverter

                                                                                    type StringConditionConverter interface {
                                                                                    	StringConditionToGorm(ctx context.Context, c *query.StringCondition, obj interface{}) (string, []interface{}, map[string]struct{}, error)
                                                                                    }

                                                                                    type Transaction

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

                                                                                      Transaction serves as a wrapper around `*gorm.DB` instance. It works as a singleton to prevent an application of creating more than one transaction instance per incoming request.

                                                                                      func FromContext

                                                                                      func FromContext(ctx context.Context) (txn *Transaction, ok bool)

                                                                                        FromContext returns the *Transaction value stored in ctx, if any.

                                                                                        func NewTransaction

                                                                                        func NewTransaction(db *gorm.DB) Transaction

                                                                                        func (*Transaction) AddAfterCommitHook

                                                                                        func (t *Transaction) AddAfterCommitHook(hooks ...func(context.Context))

                                                                                        func (*Transaction) Begin

                                                                                        func (t *Transaction) Begin() *gorm.DB

                                                                                          Begin starts new transaction by calling `*gorm.DB.Begin()` Returns new instance of `*gorm.DB` (error can be checked by `*gorm.DB.Error`)

                                                                                          func (*Transaction) BeginWithOptions

                                                                                          func (t *Transaction) BeginWithOptions(opts *sql.TxOptions) *gorm.DB

                                                                                            BeginWithOptions starts new transaction by calling `*gorm.DB.BeginTx()` Returns new instance of `*gorm.DB` (error can be checked by `*gorm.DB.Error`)

                                                                                            func (*Transaction) Commit

                                                                                            func (t *Transaction) Commit(ctx context.Context) error

                                                                                              Commit finishes transaction by calling `*gorm.DB.Commit()` Reset current transaction and returns an error if any.

                                                                                              func (*Transaction) Rollback

                                                                                              func (t *Transaction) Rollback() error

                                                                                                Rollback terminates transaction by calling `*gorm.DB.Rollback()` Reset current transaction and returns an error if any.

                                                                                                Directories

                                                                                                Path Synopsis