postgres

package
v0.0.0-...-c537d22 Latest Latest
Warning

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

Go to latest
Published: Jan 19, 2024 License: MIT Imports: 10 Imported by: 0

Documentation

Index

Constants

View Source
const TablePlaceholder = "[[table]]"

Variables

View Source
var (
	ErrMissingProvider = errors.New("missing db provider")
)
View Source
var (
	ErrSelectorMissingColumns = errors.New("columns are missing")
)

Functions

func AddStringArrayCondition

func AddStringArrayCondition[T ~string](d *StatementBuilder, column string, value []T, xs ...ConditionOption)

AddStringArrayCondition is a generic version of StatementBuilder.AddStringArrayCondition which helps convert the string array into a pq.StringArray

func ApplyConditions

ApplyConditions applies the Where to the provided Builder.

func ApplyPaging

func ApplyPaging[T PageApplicable[T]](d *StatementBuilder, qry T) T

ApplyPaging applies the Limit and Offset to the provided Builder.

func ApplySort

func ApplySort[T SortApplicable[T]](
	d *StatementBuilder,
	p *ConditionOptionPreprocessParams,
	qry T,
) T

ApplySort applies the OrderBy to the provided Builder.

func Get

func Get[T any](s *Selector[T], scanner Scanner[T], cols ...string) (T, error)

Get returns a single object with custom columns provided.

func Select

func Select[R any](s *Selector[R], scanner Scanner[R], cols ...string) ([]R, error)

Select returns a list of objects with columns provided. It uses the conditions / paging / sort in the provided Selector to restrict the output.

func SingleColumnScanner

func SingleColumnScanner[T any](row squirrel.RowScanner) (T, error)

func WithTablePlaceholder

func WithTablePlaceholder(col string) string

Types

type Collection

type Collection[K comparable, T any] interface {
	// Add adds the item into the collection. Key is for allowing for map types. Slices should ignore the key param.
	Add(key K, item T)

	// Size of the collection
	Size() int

	// Apply adds the condition to the item and returns a new item,
	// as well as the corresponding sqlizer.
	Apply(o ConditionOption, item T) (T, squirrel.Sqlizer)
}

Collection is the data type that is passed into OptionConditionRegistry. Specific to this registry, it requires an applier to apply the condition option to an item before the item is added to the collection.

type ConditionApplicable

type ConditionApplicable[T any] interface {
	Where(pred interface{}, args ...interface{}) T
}

ConditionApplicable is an interface that defines a Where method which returns a specific type. Together with ApplyConditions, defines a type that returns itself.

type ConditionOption

type ConditionOption interface {
	ModifyCondition(s squirrel.Sqlizer) squirrel.Sqlizer
}

ConditionOption is an option that modifies a query string sqlizer for a condition.

type ConditionOptionPreprocess

type ConditionOptionPreprocess interface {
	Preprocess(q *StatementBuilder, p *ConditionOptionPreprocessParams)
}

ConditionOptionPreprocess denotes that the ConditionOption can be registered for preprocessing before it is applied to the query. It does this by passing the whole *StatementBuilder as a preprocessing step.

See QueryCondition.Apply.

type ConditionOptionPreprocessParams

type ConditionOptionPreprocessParams struct {
	// BaseTable for SELECT is the table after [FROM] keyword. For update and delete, it is the table that is being
	// updated or deleted From (i.e., the table following the [UPDATE] and [DELETE] keywords, correspondingly).
	BaseTable string
}

ConditionOptionPreprocessParams are parameters that can be passed into the params, which are unrelated to conditions.

type DBProvider

type DBProvider interface {
	GetDb() sqlx.Ext
}

DBProvider is an interface that provides the database connection to the Selector.

type Join

type Join struct {
	JoinSql  squirrel.Sqlizer
	JoinType JoinType
}

type JoinMapCollection

type JoinMapCollection struct {
	MapCollection[string, Join]

	// Order of the joins to apply.
	Order []string
}

JoinMapCollection adds a join to the map.

func NewJoinMapCollection

func NewJoinMapCollection() *JoinMapCollection

func (*JoinMapCollection) Add

func (c *JoinMapCollection) Add(key string, item Join)

func (*JoinMapCollection) Apply

type JoinStr

type JoinStr string

func (*JoinStr) ToSql

func (j *JoinStr) ToSql() (string, []interface{}, error)

type JoinType

type JoinType string
const (
	JoinTypeLeft  JoinType = "left"
	JoinTypeInner JoinType = "inner"
)

type MapCollection

type MapCollection[K comparable, T any] struct {
	Map map[K]T
}

MapCollection contains a map that implements Collection's Add and Size functions.

func (*MapCollection[K, T]) Add

func (c *MapCollection[K, T]) Add(key K, item T)

func (*MapCollection[K, T]) Has

func (c *MapCollection[K, T]) Has(key K) bool

func (*MapCollection[K, T]) Size

func (c *MapCollection[K, T]) Size() int

type OptionConditionRegistry

type OptionConditionRegistry[T any, K comparable, C Collection[K, T]] struct {

	// Collection for items that may be in the registry.
	Data C

	// List of items the requires preprocessing.
	Registry []ConditionOptionPreprocess
	// contains filtered or unexported fields
}

OptionConditionRegistry defines a container for items which may require preprocessing.

func NewOptionConditionRegistry

func NewOptionConditionRegistry[T any, K comparable, C Collection[K, T]](p *StatementBuilder, col C) *OptionConditionRegistry[T, K, C]

func (*OptionConditionRegistry[T, K, C]) Add

func (r *OptionConditionRegistry[T, K, C]) Add(key K, item T, xs ...ConditionOption)

Add adds an item to the Collection, while applying the ConditionOptions and registering them as necessary.

func (*OptionConditionRegistry[T, K, C]) Preprocess

func (r *OptionConditionRegistry[T, K, C]) Preprocess(p *ConditionOptionPreprocessParams)

Preprocess runs the preprocessor for each item in the registry

type PageApplicable

type PageApplicable[T any] interface {
	Limit(uint64) T
	Offset(uint64) T
}

PageApplicable is an interface that defines two methods - Limit and Offset which return a specific type. Together with ApplyPaging, defines a type that returns itself.

type Preprocessor

type Preprocessor[T squirrel.Sqlizer] func(tbl string, sql T) T

Preprocessor is a generic type for preprocessing queries.

type QueryBuilderConditionOptionFunc

type QueryBuilderConditionOptionFunc func(s squirrel.Sqlizer) squirrel.Sqlizer

QueryBuilderConditionOptionFunc converts a func to satisfy ConditionOption

var ReplaceTablePlaceholderOption QueryBuilderConditionOptionFunc = func(s squirrel.Sqlizer) squirrel.Sqlizer {
	return &ReplaceTablePlaceholder{
		Sqlizer: s,
	}
}

ReplaceTablePlaceholderOption instructs the query builder to replace the TablePlaceholder occurrences in the SQL with a proper table, defined by the [From].

func SubQueryOption

SubQueryOption wraps the string array condition in a subquery. In particular, it adds it as a WHERE condition in the provided squirrel.SelectBuilder.

func (QueryBuilderConditionOptionFunc) ModifyCondition

ModifyCondition satisfies ConditionOption

type ReplaceTablePlaceholder

type ReplaceTablePlaceholder struct {

	// The base sqlizer to modify.
	squirrel.Sqlizer
	// contains filtered or unexported fields
}

ReplaceTablePlaceholder is a squirrel.Sqlizer that adds a table to an existing SQL string. It looks for a placeholder [[table]] which it replaces with the table provided.

func (*ReplaceTablePlaceholder) Preprocess

Preprocess implements ConditionOptionPreprocess

func (*ReplaceTablePlaceholder) ToSql

func (t *ReplaceTablePlaceholder) ToSql() (string, []interface{}, error)

ToSql satisfies squirrel.Sqlizer.

type Scanner

type Scanner[T any] interface {
	Scan(scanner squirrel.RowScanner) (T, error)
}

Scanner is an object that contains a Scan method. The method expects a row of data From the source database to be used to create a single object of type T.

type ScannerFunc

type ScannerFunc[T any] func(scanner squirrel.RowScanner) (T, error)

ScannerFunc is a definition for a function that performs scanning.

func (ScannerFunc[T]) Scan

func (f ScannerFunc[T]) Scan(scanner squirrel.RowScanner) (T, error)

type SelectBuilder

type SelectBuilder struct {
	*StatementBuilder

	// From - a table
	From string

	// Tables that need to be joined. Since the provided *StatementBuilder is a pointer, it might be shared between
	// different objects such as this SelectBuilder and an UpdateBuilder. This is for joins that should only be shown
	// for the SelectBuilder, usually related to the columns for retrieval (and not the conditions).
	//
	// Since joins are mapped by key, if any join key matches that From the StatementBuilder, it will be ignored.
	Joins *OptionConditionRegistry[Join, string, *JoinMapCollection]
}

func NewSelectBuilder

func NewSelectBuilder(statement *StatementBuilder) *SelectBuilder

func (*SelectBuilder) AddSelectJoin

func (d *SelectBuilder) AddSelectJoin(name string, join string, xs ...ConditionOption) *SelectBuilder

AddSelectJoin adds an inner join to the query builder. The term "Select" is provided to differentiate From the AddJoin in the StatementBuilder so it is not shadowed.

func (*SelectBuilder) AddSelectLeftJoin

func (d *SelectBuilder) AddSelectLeftJoin(name string, join string, xs ...ConditionOption) *SelectBuilder

AddSelectLeftJoin adds a left (outer) join to the query builder. The term "Select" is provided to differentiate From the AddJoin in the StatementBuilder so it is not shadowed.

func (*SelectBuilder) ApplyConditions

func (d *SelectBuilder) ApplyConditions(qry *squirrel.SelectBuilder)

ApplyConditions applies the Where conditions to the provided SelectBuilder.

func (*SelectBuilder) ApplyJoin

func (d *SelectBuilder) ApplyJoin(qry *squirrel.SelectBuilder)

func (*SelectBuilder) ApplyPaging

func (d *SelectBuilder) ApplyPaging(qry *squirrel.SelectBuilder)

ApplyPaging applies the Limit and Offset to the provided SelectBuilder.

func (*SelectBuilder) ApplySort

func (d *SelectBuilder) ApplySort(qry *squirrel.SelectBuilder)

ApplySort applies the sort fields to the provided SelectBuilder.

func (*SelectBuilder) Builder

func (d *SelectBuilder) Builder(cols ...string) squirrel.SelectBuilder

Builder returns a builder filling in the with prefix and Joins. It uses the default placeholder format for squirrel.SelectBuilder.

To use with postgres as a main query, chain with `PlaceholderFormat`. Subqueries should use the default placeholder format.

Ensure to add paging etc and sort. Conditions are automatically applied.

func (*SelectBuilder) SetFrom

func (d *SelectBuilder) SetFrom(table string) *SelectBuilder

SetFrom sets the base [From] table in the query.

type SelectIterator

type SelectIterator[R any] struct {
	Rows *sql.Rows // Rows to iterate over.
	Fn   Scanner[R]
}

SelectIterator is a way to retrieve an iterator for a select to use with scanning.

func Iterate

func Iterate[R any](s *Selector[R], scanner Scanner[R], cols ...string) (*SelectIterator[R], error)

Iterate returns an iterator for retrieving multiple rows sequentially From the database.

func (*SelectIterator[R]) Next

func (i *SelectIterator[R]) Next() (R, error)

Next returns the next item in the list.

type Selector

type Selector[T any] struct {
	// The base query builder object. Needs to be passed in order to properly generate the query.
	QueryBuilder *SelectBuilder

	// The scanner that outputs an object containing the values of the row. This is used for both Get and Select.
	// The columns scanned by the Scanner *must* match the columns provided in GetCols.
	Scanner Scanner[T]

	// What provides the DB connection for calling the functions.
	Provider DBProvider

	// Columns related to Get and Select
	GetCols []string

	// Column related to the Total
	TotalColumnName string

	// PreprocessSelect allows preprocessing of the select query *before*
	// Querying and scanning. It, for example, allows for adding of extra
	// conditions or columns.
	//
	// The same preprocessor is used for Iterate, Exists, and Total
	PreprocessSelect func(from string, sql squirrel.SelectBuilder) squirrel.SelectBuilder

	// PreprocessGet allows preprocessing of the get query *before* Querying
	// and scanning. It, for example, allows for adding of extra
	// conditions or columns.
	PreprocessGet func(builder squirrel.SelectBuilder) squirrel.SelectBuilder

	// ProcessSelectResult allows further processing as a result of the result
	// of the select.
	ProcessSelectResult func(val interface{}, err error)

	// ProcessGetResult allows further processing as a result of the result
	// of the get.
	ProcessGetResult func(val interface{}, err error) error
}

Selector provides three methods that can be used as defaults. 1. Total - returns the total # of objects that satisfies the query. 2. Select - returns a list of results 3. Get - returns a single result.

func (*Selector[T]) Exists

func (s *Selector[T]) Exists() (bool, error)

Exists returns true if any result filtered by the query is present.

func (*Selector[T]) Get

func (s *Selector[T]) Get() (T, error)

Get returns a single object that satisfies the query, up to a certain Limit. It handles sorting but paging is unncessary as the first object will always be the one that is returned. If no columns are provided, ErrSelectorMissingColumns is returned.

func (*Selector[T]) Iterate

func (s *Selector[T]) Iterate() (*SelectIterator[T], error)

Iterate returns an iterator to retrieve objects with the columns provided. It uses the conditions / paging / sort in the provided Selector to restrict the output.

func (*Selector[T]) Select

func (s *Selector[T]) Select() ([]T, error)

Select returns a list of objects that satisfies the query, up to a certain Limit. It also handles sorting and Offset. Columns are required for the selector to function. If no columns are provided, ErrSelectorMissingColumns is returned.

func (*Selector[T]) Total

func (s *Selector[T]) Total() (uint64, error)

Total returns the total # of objects that satisfies the query. It will extract the query form the StatementBuilder and apply conditions to it. It attempts to extract the column From TotalColumnName, but will default to COUNT(*) if it is not provided.

type SliceCollection

type SliceCollection[T any] struct {
	Slice []T
}

SliceCollection contains a slice that implements Collection's Add and Size functions.

func (*SliceCollection[T]) Add

func (c *SliceCollection[T]) Add(_ string, item T)

func (*SliceCollection[T]) Size

func (c *SliceCollection[T]) Size() int

type SliceOptionConditionRegistry

type SliceOptionConditionRegistry[T any, C Collection[string, T]] struct {
	*OptionConditionRegistry[T, string, C]
}

SliceOptionConditionRegistry is syntactic sugar for collections that must be slices.

func NewSliceConditionRegistry

func NewSliceConditionRegistry[T any, C Collection[string, T]](p *StatementBuilder, col C) *SliceOptionConditionRegistry[T, C]

func (*SliceOptionConditionRegistry[T, C]) Add

func (s *SliceOptionConditionRegistry[T, C]) Add(item T, xs ...ConditionOption)

type SortApplicable

type SortApplicable[T any] interface {
	OrderBy(...string) T
}

SortApplicable is an interface that defines an OrderBy method which returns a specific type. Together with ApplySort, defines a type that returns itself.

type SqlizerSliceCollection

type SqlizerSliceCollection struct {
	SliceCollection[squirrel.Sqlizer]
}

SqlizerSliceCollection is a slice of Sqlizer which implements Collection

func (*SqlizerSliceCollection) Apply

Apply adds the condition to the item.

func (*SqlizerSliceCollection) ToStrings

func (s *SqlizerSliceCollection) ToStrings() []string

ToStrings converts the sqlizer items to strings.

type StatementBuilder

type StatementBuilder struct {
	// Tables to add to the top. Use the map to make sure that if it has been added or not.
	WithPrefix With

	// Tables to be joined. The reason that this is part of the statement builder is because sometimes the conditions
	// require that the table be included.
	//
	// Joins only make sense in the context of SelectBuilder. For UpdateBuilder, joins will be merged as the last
	// WithPrefix statement as a sub-select, so that it can be used in the WHERE statement properly.
	Joins *OptionConditionRegistry[Join, string, *JoinMapCollection]

	// Where conditions for postgres querying.
	Where *SliceOptionConditionRegistry[squirrel.Sqlizer, *SqlizerSliceCollection]

	// OrderBys are the order-by column
	OrderBys *SliceOptionConditionRegistry[squirrel.Sqlizer, *SqlizerSliceCollection]

	// Limit is the Limit for the query
	Limit uint64

	// Offset is an Offset for the query.
	Offset uint64
}

StatementBuilder helps with building select, update and delete queries.

func NewStatementBuilder

func NewStatementBuilder() *StatementBuilder

NewStatementBuilder generates a query builder and initiates all required internal variables.

func (*StatementBuilder) AddCondition

func (d *StatementBuilder) AddCondition(where squirrel.Sqlizer, xs ...ConditionOption) *StatementBuilder

AddCondition adds a "Where" condition to the query.

func (*StatementBuilder) AddJoin

func (d *StatementBuilder) AddJoin(name string, join string, xs ...ConditionOption) *StatementBuilder

AddJoin adds an inner join to the query builder.

func (*StatementBuilder) AddLeftJoin

func (d *StatementBuilder) AddLeftJoin(name string, join string, xs ...ConditionOption) *StatementBuilder

AddLeftJoin adds a left (outer) join to the query builder.

func (*StatementBuilder) AddPrefix

func (d *StatementBuilder) AddPrefix(name string, prefix squirrel.Sqlizer) *StatementBuilder

AddPrefix adds a prefix to the StatementBuilder.

func (*StatementBuilder) AddSort

func (d *StatementBuilder) AddSort(sort []string, xs ...ConditionOption) *StatementBuilder

AddSort adds an orderBy to the OrderBys field for the query.

func (*StatementBuilder) AddStringArrayCondition

func (d *StatementBuilder) AddStringArrayCondition(column string, value pq.StringArray, xs ...ConditionOption) *StatementBuilder

AddStringArrayCondition adds a special condition that looks like [column]=ANY(?)

func (*StatementBuilder) ClearConditions

func (d *StatementBuilder) ClearConditions()

func (*StatementBuilder) GetLimit

func (d *StatementBuilder) GetLimit() uint64

GetLimit returns the Limit Data on the StatementBuilder

func (*StatementBuilder) GetOffset

func (d *StatementBuilder) GetOffset() uint64

GetOffset returns the Limit Data on the StatementBuilder

func (*StatementBuilder) HasConditions

func (d *StatementBuilder) HasConditions() bool

HasConditions returns true if conditions are present.

func (*StatementBuilder) HasJoins

func (d *StatementBuilder) HasJoins() bool

HasJoins returns true if joins are present.

func (*StatementBuilder) SetLimit

func (d *StatementBuilder) SetLimit(limit uint64) *StatementBuilder

SetLimit sets the Limit for the query

func (*StatementBuilder) SetOffset

func (d *StatementBuilder) SetOffset(offset uint64) *StatementBuilder

SetOffset sets the Offset for the query.

type UpdateBuilder

type UpdateBuilder struct {
	// StatementBuilder is used to provide the conditions for the builder. This is a pointer so that the same instance
	// can be used for both the UpdateBuilder and the SelectBuilder.
	*StatementBuilder

	// Name of the id column (for use with complicated WHERE clauses)
	IdColumnName string
	// contains filtered or unexported fields
}

UpdateBuilder generates an update method based on the encapsulated statement builder.

func NewUpdateBuilder

func NewUpdateBuilder(statement *StatementBuilder) *UpdateBuilder

func (*UpdateBuilder) DeleteBuilder

func (d *UpdateBuilder) DeleteBuilder() squirrel.DeleteBuilder

func (*UpdateBuilder) InsertBuilder

func (d *UpdateBuilder) InsertBuilder(setMap map[string]interface{}) squirrel.InsertBuilder

InsertBuilder returns a builder with the provided set information and the predefined table.

func (*UpdateBuilder) SetBaseTable

func (d *UpdateBuilder) SetBaseTable(table string) *UpdateBuilder

SetBaseTable sets the base table in the query.

func (*UpdateBuilder) UpdateBuilder

func (d *UpdateBuilder) UpdateBuilder(setMap map[string]interface{}) squirrel.UpdateBuilder

UpdateBuilder returns a builder filling in the with prefix. If joins are required, an additional WITH will be created using the base table, joined with all the other tables, and containing the Where clause.

type Updater

type Updater[T any] struct {
	// The base query builder object. Needs to be passed in order to properly generate the query.
	QueryBuilder *UpdateBuilder

	// What provides the DB connection for calling the functions.
	Provider DBProvider

	// PreprocessUpdate preprocesses the update query
	PreprocessUpdate Preprocessor[squirrel.UpdateBuilder]

	// PreprocessInsert preprocesses the insert query
	PreprocessInsert Preprocessor[squirrel.InsertBuilder]

	// PreprocessDelete preprocesses the delete query
	PreprocessDelete Preprocessor[squirrel.DeleteBuilder]

	// Set of data to update with.
	Data map[string]interface{}
	// contains filtered or unexported fields
}

Updater provides some default insert/update/delete functionality. The parameter T is the type for the ID which is returned through the insert.

func NewUpdater

func NewUpdater[T any](builder *StatementBuilder, baseTable string) *Updater[T]

func (*Updater[T]) Delete

func (u *Updater[T]) Delete() error

func (*Updater[T]) Insert

func (u *Updater[T]) Insert() (T, error)

func (*Updater[T]) InsertNoId

func (u *Updater[T]) InsertNoId() error

func (*Updater[T]) Set

func (u *Updater[T]) Set(name string, value interface{})

func (*Updater[T]) SetError

func (u *Updater[T]) SetError(err error)

SetError can be used by encapsulating structs to capture errors during set. For example, if JSON marshalling is required, the error return value of json.Marshal can be passed to this function.

func (*Updater[T]) SetIdColumn

func (u *Updater[T]) SetIdColumn(col string) *Updater[T]

func (*Updater[T]) SetProvider

func (u *Updater[T]) SetProvider(db DBProvider) *Updater[T]

func (*Updater[T]) Update

func (u *Updater[T]) Update() error

type With

type With map[string]squirrel.Sqlizer

With implements the squirrel.Sqlizer interface for WITH as a prefix.

func (With) ToSql

func (w With) ToSql() (string, []interface{}, error)

Jump to

Keyboard shortcuts

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