Documentation
¶
Overview ¶
Package builder provides cross-database query building utilities. This package implements vendor-specific SQL generation and identifier handling for PostgreSQL, Oracle, and other database backends.
Index ¶
- type DeleteQueryBuilder
- func (dqb *DeleteQueryBuilder) Limit(limit uint64) dbtypes.DeleteQueryBuilder
- func (dqb *DeleteQueryBuilder) OrderBy(orderBys ...string) dbtypes.DeleteQueryBuilder
- func (dqb *DeleteQueryBuilder) ToSQL() (sql string, args []any, err error)
- func (dqb *DeleteQueryBuilder) Where(filter dbtypes.Filter) dbtypes.DeleteQueryBuilder
- type Filter
- type FilterFactory
- func (ff *FilterFactory) And(filters ...dbtypes.Filter) dbtypes.Filter
- func (ff *FilterFactory) Between(column string, lowerBound, upperBound any) dbtypes.Filter
- func (ff *FilterFactory) Eq(column string, value any) dbtypes.Filter
- func (ff *FilterFactory) Exists(subquery dbtypes.SelectQueryBuilder) dbtypes.Filter
- func (ff *FilterFactory) Gt(column string, value any) dbtypes.Filter
- func (ff *FilterFactory) Gte(column string, value any) dbtypes.Filter
- func (ff *FilterFactory) In(column string, values any) dbtypes.Filter
- func (ff *FilterFactory) InSubquery(column string, subquery dbtypes.SelectQueryBuilder) dbtypes.Filter
- func (ff *FilterFactory) Like(column, pattern string) dbtypes.Filter
- func (ff *FilterFactory) Lt(column string, value any) dbtypes.Filter
- func (ff *FilterFactory) Lte(column string, value any) dbtypes.Filter
- func (ff *FilterFactory) Not(filter dbtypes.Filter) dbtypes.Filter
- func (ff *FilterFactory) NotEq(column string, value any) dbtypes.Filter
- func (ff *FilterFactory) NotExists(subquery dbtypes.SelectQueryBuilder) dbtypes.Filter
- func (ff *FilterFactory) NotIn(column string, values any) dbtypes.Filter
- func (ff *FilterFactory) NotNull(column string) dbtypes.Filter
- func (ff *FilterFactory) Null(column string) dbtypes.Filter
- func (ff *FilterFactory) Or(filters ...dbtypes.Filter) dbtypes.Filter
- func (ff *FilterFactory) Raw(condition string, args ...any) dbtypes.Filter
- type JoinFilter
- type JoinFilterFactory
- func (jff *JoinFilterFactory) And(filters ...dbtypes.JoinFilter) dbtypes.JoinFilter
- func (jff *JoinFilterFactory) Between(column string, lowerBound, upperBound any) dbtypes.JoinFilter
- func (jff *JoinFilterFactory) Eq(column string, value any) dbtypes.JoinFilter
- func (jff *JoinFilterFactory) EqColumn(leftColumn, rightColumn string) dbtypes.JoinFilter
- func (jff *JoinFilterFactory) Gt(column string, value any) dbtypes.JoinFilter
- func (jff *JoinFilterFactory) GtColumn(leftColumn, rightColumn string) dbtypes.JoinFilter
- func (jff *JoinFilterFactory) Gte(column string, value any) dbtypes.JoinFilter
- func (jff *JoinFilterFactory) GteColumn(leftColumn, rightColumn string) dbtypes.JoinFilter
- func (jff *JoinFilterFactory) In(column string, values any) dbtypes.JoinFilter
- func (jff *JoinFilterFactory) Like(column, pattern string) dbtypes.JoinFilter
- func (jff *JoinFilterFactory) Lt(column string, value any) dbtypes.JoinFilter
- func (jff *JoinFilterFactory) LtColumn(leftColumn, rightColumn string) dbtypes.JoinFilter
- func (jff *JoinFilterFactory) Lte(column string, value any) dbtypes.JoinFilter
- func (jff *JoinFilterFactory) LteColumn(leftColumn, rightColumn string) dbtypes.JoinFilter
- func (jff *JoinFilterFactory) NotEq(column string, value any) dbtypes.JoinFilter
- func (jff *JoinFilterFactory) NotEqColumn(leftColumn, rightColumn string) dbtypes.JoinFilter
- func (jff *JoinFilterFactory) NotIn(column string, values any) dbtypes.JoinFilter
- func (jff *JoinFilterFactory) NotNull(column string) dbtypes.JoinFilter
- func (jff *JoinFilterFactory) Null(column string) dbtypes.JoinFilter
- func (jff *JoinFilterFactory) Or(filters ...dbtypes.JoinFilter) dbtypes.JoinFilter
- func (jff *JoinFilterFactory) Raw(condition string, args ...any) dbtypes.JoinFilter
- type QueryBuilder
- func (qb *QueryBuilder) BuildBooleanValue(value bool) any
- func (qb *QueryBuilder) BuildCaseInsensitiveLike(column, value string) squirrel.Sqlizer
- func (qb *QueryBuilder) BuildCurrentTimestamp() string
- func (qb *QueryBuilder) BuildUUIDGeneration() string
- func (qb *QueryBuilder) BuildUpsert(table string, conflictColumns []string, ...) (query string, args []any, err error)
- func (qb *QueryBuilder) Columns(structPtr any) dbtypes.Columns
- func (qb *QueryBuilder) Delete(table string) dbtypes.DeleteQueryBuilder
- func (qb *QueryBuilder) Eq(column string, value any) squirrel.Eq
- func (qb *QueryBuilder) EscapeIdentifier(identifier string) string
- func (qb *QueryBuilder) Expr(sql string, alias ...string) (dbtypes.RawExpression, error)
- func (qb *QueryBuilder) Filter() dbtypes.FilterFactory
- func (qb *QueryBuilder) Gt(column string, value any) squirrel.Gt
- func (qb *QueryBuilder) GtOrEq(column string, value any) squirrel.GtOrEq
- func (qb *QueryBuilder) Insert(table string) squirrel.InsertBuilder
- func (qb *QueryBuilder) InsertFields(table string, instance any, fields ...string) squirrel.InsertBuilder
- func (qb *QueryBuilder) InsertStruct(table string, instance any) squirrel.InsertBuilder
- func (qb *QueryBuilder) InsertWithColumns(table string, columns ...string) squirrel.InsertBuilder
- func (qb *QueryBuilder) JoinFilter() dbtypes.JoinFilterFactory
- func (qb *QueryBuilder) Lt(column string, value any) squirrel.Lt
- func (qb *QueryBuilder) LtOrEq(column string, value any) squirrel.LtOrEq
- func (qb *QueryBuilder) MustExpr(sql string, alias ...string) dbtypes.RawExpression
- func (qb *QueryBuilder) NotEq(column string, value any) squirrel.NotEq
- func (qb *QueryBuilder) Select(columns ...any) *SelectQueryBuilder
- func (qb *QueryBuilder) Update(table string) dbtypes.UpdateQueryBuilder
- func (qb *QueryBuilder) Vendor() string
- type SelectQueryBuilder
- func (sqb *SelectQueryBuilder) CrossJoinOn(table any) dbtypes.SelectQueryBuilder
- func (sqb *SelectQueryBuilder) From(from ...any) dbtypes.SelectQueryBuilder
- func (sqb *SelectQueryBuilder) GroupBy(groupBys ...any) dbtypes.SelectQueryBuilder
- func (sqb *SelectQueryBuilder) Having(pred any, rest ...any) dbtypes.SelectQueryBuilder
- func (sqb *SelectQueryBuilder) InnerJoinOn(table any, filter dbtypes.JoinFilter) dbtypes.SelectQueryBuilder
- func (sqb *SelectQueryBuilder) JoinOn(table any, filter dbtypes.JoinFilter) dbtypes.SelectQueryBuilder
- func (sqb *SelectQueryBuilder) LeftJoinOn(table any, filter dbtypes.JoinFilter) dbtypes.SelectQueryBuilder
- func (sqb *SelectQueryBuilder) Limit(limit uint64) dbtypes.SelectQueryBuilder
- func (sqb *SelectQueryBuilder) Offset(offset uint64) dbtypes.SelectQueryBuilder
- func (sqb *SelectQueryBuilder) OrderBy(orderBys ...any) dbtypes.SelectQueryBuilder
- func (sqb *SelectQueryBuilder) Paginate(limit, offset uint64) dbtypes.SelectQueryBuilder
- func (sqb *SelectQueryBuilder) RightJoinOn(table any, filter dbtypes.JoinFilter) dbtypes.SelectQueryBuilder
- func (sqb *SelectQueryBuilder) ToSQL() (sql string, args []any, err error)
- func (sqb *SelectQueryBuilder) ValidateForSubquery() error
- func (sqb *SelectQueryBuilder) Where(filter dbtypes.Filter) dbtypes.SelectQueryBuilder
- type UpdateQueryBuilder
- func (uqb *UpdateQueryBuilder) Set(column string, value any) dbtypes.UpdateQueryBuilder
- func (uqb *UpdateQueryBuilder) SetMap(clauses map[string]any) dbtypes.UpdateQueryBuilder
- func (uqb *UpdateQueryBuilder) SetStruct(instance any, fields ...string) dbtypes.UpdateQueryBuilder
- func (uqb *UpdateQueryBuilder) ToSQL() (sql string, args []any, err error)
- func (uqb *UpdateQueryBuilder) Where(filter dbtypes.Filter) dbtypes.UpdateQueryBuilder
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type DeleteQueryBuilder ¶ added in v0.13.0
type DeleteQueryBuilder struct {
// contains filtered or unexported fields
}
DeleteQueryBuilder provides a type-safe interface for building DELETE queries with Filter API support.
func (*DeleteQueryBuilder) Limit ¶ added in v0.13.0
func (dqb *DeleteQueryBuilder) Limit(limit uint64) dbtypes.DeleteQueryBuilder
Limit sets the maximum number of rows to delete. Note: LIMIT in DELETE is not standard SQL and may not be supported by all databases.
func (*DeleteQueryBuilder) OrderBy ¶ added in v0.13.0
func (dqb *DeleteQueryBuilder) OrderBy(orderBys ...string) dbtypes.DeleteQueryBuilder
OrderBy adds ORDER BY clauses to the DELETE statement. Note: ORDER BY in DELETE is not standard SQL and may not be supported by all databases.
func (*DeleteQueryBuilder) ToSQL ¶ added in v0.13.0
func (dqb *DeleteQueryBuilder) ToSQL() (sql string, args []any, err error)
ToSQL generates the final SQL query and arguments.
func (*DeleteQueryBuilder) Where ¶ added in v0.13.0
func (dqb *DeleteQueryBuilder) Where(filter dbtypes.Filter) dbtypes.DeleteQueryBuilder
Where adds a filter to the WHERE clause. Multiple calls to Where() will be combined with AND logic.
type Filter ¶ added in v0.13.0
type Filter struct {
// contains filtered or unexported fields
}
Filter represents a composable WHERE clause filter that can be combined with AND/OR/NOT operators. Filters are created through FilterFactory methods and maintain vendor-specific quoting rules.
Note: Filter does NOT apply placeholder formatting (?, $1, :1) - that's handled by squirrel's StatementBuilder when the full query is built. This ensures proper sequential numbering across multiple WHERE clauses.
type FilterFactory ¶ added in v0.13.0
type FilterFactory struct {
// contains filtered or unexported fields
}
FilterFactory provides methods for creating type-safe filters with automatic vendor-specific quoting. Obtain a FilterFactory through QueryBuilder.Filter().
func (*FilterFactory) And ¶ added in v0.13.0
func (ff *FilterFactory) And(filters ...dbtypes.Filter) dbtypes.Filter
And combines multiple filters with AND logic. Returns a filter that matches when ALL provided filters match. Nil filters are treated as no-ops and skipped.
Example:
f := qb.Filter()
filter := f.And(
f.Eq("status", "active"),
f.Gt("age", 18),
)
func (*FilterFactory) Between ¶ added in v0.13.0
func (ff *FilterFactory) Between(column string, lowerBound, upperBound any) dbtypes.Filter
Between creates a BETWEEN filter (column BETWEEN lowerBound AND upperBound). Column names are automatically quoted according to database vendor rules.
func (*FilterFactory) Eq ¶ added in v0.13.0
func (ff *FilterFactory) Eq(column string, value any) dbtypes.Filter
Eq creates an equality filter (column = value). Column names are automatically quoted according to database vendor rules.
func (*FilterFactory) Exists ¶ added in v0.14.2
func (ff *FilterFactory) Exists(subquery dbtypes.SelectQueryBuilder) dbtypes.Filter
Exists creates an EXISTS filter for checking if a subquery returns any rows. The subquery should be a complete SELECT query.
Example:
subquery := qb.Select("id").From("categories").Where(f.Eq("status", "active"))
query := qb.Select("*").From("products").Where(f.Exists(subquery))
// SQL: SELECT * FROM products WHERE EXISTS (SELECT id FROM categories WHERE status = :1)
For correlated subqueries (referencing outer query columns), use JoinFilter methods:
subquery := qb.Select("1").From("reviews").Where(jf.And(
jf.EqColumn("reviews.product_id", "p.id"),
f.Eq("reviews.rating", 5),
))
query := qb.Select("p.name").From(Table("products").As("p")).Where(f.Exists(subquery))
func (*FilterFactory) Gt ¶ added in v0.13.0
func (ff *FilterFactory) Gt(column string, value any) dbtypes.Filter
Gt creates a greater-than filter (column > value). Column names are automatically quoted according to database vendor rules.
func (*FilterFactory) Gte ¶ added in v0.13.0
func (ff *FilterFactory) Gte(column string, value any) dbtypes.Filter
Gte creates a greater-than-or-equal filter (column >= value). Column names are automatically quoted according to database vendor rules.
func (*FilterFactory) In ¶ added in v0.13.0
func (ff *FilterFactory) In(column string, values any) dbtypes.Filter
In creates an IN filter (column IN (values...)). Accepts both slices and scalar values. Scalars are automatically wrapped in a slice. Column names are automatically quoted according to database vendor rules.
Examples:
f.In("status", []string{"active", "pending"}) // IN with multiple values
f.In("status", "active") // IN with single value (wrapped automatically)
func (*FilterFactory) InSubquery ¶ added in v0.14.2
func (ff *FilterFactory) InSubquery(column string, subquery dbtypes.SelectQueryBuilder) dbtypes.Filter
InSubquery creates an IN filter where the values come from a subquery. The subquery should return a single column that matches the specified column's type.
This is a separate method from In() to maintain type safety and explicit API design (following the "Explicit > Implicit" principle from the developer manifesto).
Example:
subquery := qb.Select("category_id").From("featured_categories").Where(f.Eq("active", true))
query := qb.Select("*").From("products").Where(f.InSubquery("category_id", subquery))
// SQL: SELECT * FROM products WHERE category_id IN (SELECT category_id FROM featured_categories WHERE active = :1)
For correlated subqueries:
subquery := qb.Select("max_price").From("price_history").Where(jf.EqColumn("price_history.product_id", "p.id"))
query := qb.Select("*").From(Table("products").As("p")).Where(f.InSubquery("p.current_price", subquery))
func (*FilterFactory) Like ¶ added in v0.13.0
func (ff *FilterFactory) Like(column, pattern string) dbtypes.Filter
Like creates a case-insensitive LIKE filter. This uses vendor-specific case-insensitive logic: - PostgreSQL: Uses ILIKE operator - Oracle: Uses UPPER() function on both column and value - Other vendors: Uses standard LIKE
func (*FilterFactory) Lt ¶ added in v0.13.0
func (ff *FilterFactory) Lt(column string, value any) dbtypes.Filter
Lt creates a less-than filter (column < value). Column names are automatically quoted according to database vendor rules.
func (*FilterFactory) Lte ¶ added in v0.13.0
func (ff *FilterFactory) Lte(column string, value any) dbtypes.Filter
Lte creates a less-than-or-equal filter (column <= value). Column names are automatically quoted according to database vendor rules.
func (*FilterFactory) Not ¶ added in v0.13.0
func (ff *FilterFactory) Not(filter dbtypes.Filter) dbtypes.Filter
Not negates a filter. Returns a filter that matches when the provided filter does NOT match.
Example:
f := qb.Filter()
filter := f.Not(f.Eq("status", "deleted"))
func (*FilterFactory) NotEq ¶ added in v0.13.0
func (ff *FilterFactory) NotEq(column string, value any) dbtypes.Filter
NotEq creates a not-equal filter (column <> value). Column names are automatically quoted according to database vendor rules.
func (*FilterFactory) NotExists ¶ added in v0.14.2
func (ff *FilterFactory) NotExists(subquery dbtypes.SelectQueryBuilder) dbtypes.Filter
NotExists creates a NOT EXISTS filter for checking if a subquery returns no rows. The subquery should be a complete SELECT query.
Example:
subquery := qb.Select("1").From("orders").Where(f.Eq("orders.status", "pending"))
query := qb.Select("*").From("customers").Where(f.NotExists(subquery))
// SQL: SELECT * FROM customers WHERE NOT EXISTS (SELECT 1 FROM orders WHERE orders.status = :1)
func (*FilterFactory) NotIn ¶ added in v0.13.0
func (ff *FilterFactory) NotIn(column string, values any) dbtypes.Filter
NotIn creates a NOT IN filter (column NOT IN (values...)). Accepts both slices and scalar values. Scalars are automatically wrapped in a slice. Column names are automatically quoted according to database vendor rules.
Examples:
f.NotIn("status", []string{"deleted", "banned"}) // NOT IN with multiple values
f.NotIn("status", "deleted") // NOT IN with single value (wrapped automatically)
func (*FilterFactory) NotNull ¶ added in v0.13.0
func (ff *FilterFactory) NotNull(column string) dbtypes.Filter
NotNull creates an IS NOT NULL filter. Column names are automatically quoted according to database vendor rules.
func (*FilterFactory) Null ¶ added in v0.13.0
func (ff *FilterFactory) Null(column string) dbtypes.Filter
Null creates an IS NULL filter. Column names are automatically quoted according to database vendor rules.
func (*FilterFactory) Or ¶ added in v0.13.0
func (ff *FilterFactory) Or(filters ...dbtypes.Filter) dbtypes.Filter
Or combines multiple filters with OR logic. Returns a filter that matches when ANY provided filter matches. Nil filters are treated as no-ops and skipped.
Example:
f := qb.Filter()
filter := f.Or(
f.Eq("status", "active"),
f.Eq("role", "admin"),
)
func (*FilterFactory) Raw ¶ added in v0.13.0
func (ff *FilterFactory) Raw(condition string, args ...any) dbtypes.Filter
Raw creates a filter from raw SQL with manual placeholder handling.
WARNING: This method bypasses all identifier quoting and SQL injection protection. It is the caller's responsibility to:
- Properly quote any identifiers (especially Oracle reserved words like "number", "level", "size")
- Ensure the SQL fragment is valid for the target database
- Never concatenate user input directly into the condition string
Use this method ONLY when the type-safe methods cannot express your condition. For Oracle, remember to quote reserved words: Raw(`"number" = ?`, value)
Examples:
f.Raw(`"number" = ?`, accountNumber) // Oracle reserved word f.Raw(`ROWNUM <= ?`, 10) // Oracle-specific syntax f.Raw(`ST_Distance(location, ?) < ?`, point, radius) // Spatial queries
type JoinFilter ¶ added in v0.13.0
type JoinFilter struct {
// contains filtered or unexported fields
}
JoinFilter represents a composable JOIN ON condition that compares columns to other columns. JoinFilters are created through JoinFilterFactory methods and maintain vendor-specific quoting rules.
Unlike Filter (which compares columns to values with placeholders), JoinFilter compares columns to other columns directly in the SQL (e.g., "users.id = profiles.user_id").
type JoinFilterFactory ¶ added in v0.13.0
type JoinFilterFactory struct {
// contains filtered or unexported fields
}
JoinFilterFactory provides methods for creating type-safe JOIN ON filters with automatic vendor-specific quoting. Obtain a JoinFilterFactory through QueryBuilder.JoinFilter().
func (*JoinFilterFactory) And ¶ added in v0.13.0
func (jff *JoinFilterFactory) And(filters ...dbtypes.JoinFilter) dbtypes.JoinFilter
And combines multiple join filters with AND logic. Returns a filter that matches when ALL provided filters match. Nil filters are treated as no-ops and skipped.
Example:
jf := qb.JoinFilter()
filter := jf.And(
jf.EqColumn("users.id", "profiles.user_id"),
jf.GtColumn("profiles.created_at", "users.created_at"),
)
func (*JoinFilterFactory) Between ¶ added in v0.14.3
func (jff *JoinFilterFactory) Between(column string, lowerBound, upperBound any) dbtypes.JoinFilter
Between creates a BETWEEN condition (column BETWEEN lowerBound AND upperBound). Column names are automatically quoted according to database vendor rules. Accepts RawExpression for complex SQL expressions without placeholders.
Examples:
jf.Between("price", 10.0, 20.0) // price BETWEEN ? AND ?
jf.Between("age", qb.Expr("18"), qb.Expr("65")) // age BETWEEN 18 AND 65 (expressions)
func (*JoinFilterFactory) Eq ¶ added in v0.14.3
func (jff *JoinFilterFactory) Eq(column string, value any) dbtypes.JoinFilter
Eq creates an equality condition (column = value). Column names are automatically quoted according to database vendor rules. Accepts RawExpression for complex SQL expressions without placeholders.
Examples:
jf.Eq("status", "active") // status = ? (with placeholder)
jf.Eq("amount", qb.Expr("TO_NUMBER(?)"), 100) // amount = TO_NUMBER(?) (expression)
func (*JoinFilterFactory) EqColumn ¶ added in v0.13.0
func (jff *JoinFilterFactory) EqColumn(leftColumn, rightColumn string) dbtypes.JoinFilter
EqColumn creates an equality join condition (leftColumn = rightColumn). Column names are automatically quoted according to database vendor rules.
Example:
jf.EqColumn("users.id", "profiles.user_id") // users.id = profiles.user_id
func (*JoinFilterFactory) Gt ¶ added in v0.14.3
func (jff *JoinFilterFactory) Gt(column string, value any) dbtypes.JoinFilter
Gt creates a greater-than condition (column > value). Column names are automatically quoted according to database vendor rules. Accepts RawExpression for complex SQL expressions without placeholders.
func (*JoinFilterFactory) GtColumn ¶ added in v0.13.0
func (jff *JoinFilterFactory) GtColumn(leftColumn, rightColumn string) dbtypes.JoinFilter
GtColumn creates a greater-than join condition (leftColumn > rightColumn). Column names are automatically quoted according to database vendor rules.
func (*JoinFilterFactory) Gte ¶ added in v0.14.3
func (jff *JoinFilterFactory) Gte(column string, value any) dbtypes.JoinFilter
Gte creates a greater-than-or-equal condition (column >= value). Column names are automatically quoted according to database vendor rules. Accepts RawExpression for complex SQL expressions without placeholders.
func (*JoinFilterFactory) GteColumn ¶ added in v0.13.0
func (jff *JoinFilterFactory) GteColumn(leftColumn, rightColumn string) dbtypes.JoinFilter
GteColumn creates a greater-than-or-equal join condition (leftColumn >= rightColumn). Column names are automatically quoted according to database vendor rules.
func (*JoinFilterFactory) In ¶ added in v0.14.3
func (jff *JoinFilterFactory) In(column string, values any) dbtypes.JoinFilter
In creates an IN condition (column IN (values...)). Accepts both slices and scalar values. Scalars are automatically wrapped in a slice. Column names are automatically quoted according to database vendor rules.
Examples:
jf.In("status", []string{"active", "pending"}) // IN with multiple values
jf.In("status", "active") // IN with single value (wrapped automatically)
func (*JoinFilterFactory) Like ¶ added in v0.14.3
func (jff *JoinFilterFactory) Like(column, pattern string) dbtypes.JoinFilter
Like creates a LIKE condition. Column names are automatically quoted according to database vendor rules. Pattern must be a string value (RawExpression not supported for LIKE).
Note: This uses standard LIKE (case-sensitive). For case-insensitive matching, use Raw() with vendor-specific functions (ILIKE for PostgreSQL, UPPER() for Oracle).
Examples:
jf.Like("name", "%Smith%") // name LIKE ?
func (*JoinFilterFactory) Lt ¶ added in v0.14.3
func (jff *JoinFilterFactory) Lt(column string, value any) dbtypes.JoinFilter
Lt creates a less-than condition (column < value). Column names are automatically quoted according to database vendor rules. Accepts RawExpression for complex SQL expressions without placeholders.
func (*JoinFilterFactory) LtColumn ¶ added in v0.13.0
func (jff *JoinFilterFactory) LtColumn(leftColumn, rightColumn string) dbtypes.JoinFilter
LtColumn creates a less-than join condition (leftColumn < rightColumn). Column names are automatically quoted according to database vendor rules.
func (*JoinFilterFactory) Lte ¶ added in v0.14.3
func (jff *JoinFilterFactory) Lte(column string, value any) dbtypes.JoinFilter
Lte creates a less-than-or-equal condition (column <= value). Column names are automatically quoted according to database vendor rules. Accepts RawExpression for complex SQL expressions without placeholders.
func (*JoinFilterFactory) LteColumn ¶ added in v0.13.0
func (jff *JoinFilterFactory) LteColumn(leftColumn, rightColumn string) dbtypes.JoinFilter
LteColumn creates a less-than-or-equal join condition (leftColumn <= rightColumn). Column names are automatically quoted according to database vendor rules.
func (*JoinFilterFactory) NotEq ¶ added in v0.14.3
func (jff *JoinFilterFactory) NotEq(column string, value any) dbtypes.JoinFilter
NotEq creates an inequality condition (column != value). Column names are automatically quoted according to database vendor rules. Accepts RawExpression for complex SQL expressions without placeholders.
func (*JoinFilterFactory) NotEqColumn ¶ added in v0.13.0
func (jff *JoinFilterFactory) NotEqColumn(leftColumn, rightColumn string) dbtypes.JoinFilter
NotEqColumn creates an inequality join condition (leftColumn != rightColumn). Column names are automatically quoted according to database vendor rules.
func (*JoinFilterFactory) NotIn ¶ added in v0.14.3
func (jff *JoinFilterFactory) NotIn(column string, values any) dbtypes.JoinFilter
NotIn creates a NOT IN condition (column NOT IN (values...)). Accepts both slices and scalar values. Scalars are automatically wrapped in a slice. Column names are automatically quoted according to database vendor rules.
Examples:
jf.NotIn("status", []string{"deleted", "banned"}) // NOT IN with multiple values
jf.NotIn("status", "deleted") // NOT IN with single value (wrapped automatically)
func (*JoinFilterFactory) NotNull ¶ added in v0.14.3
func (jff *JoinFilterFactory) NotNull(column string) dbtypes.JoinFilter
NotNull creates an IS NOT NULL condition. Column names are automatically quoted according to database vendor rules.
func (*JoinFilterFactory) Null ¶ added in v0.14.3
func (jff *JoinFilterFactory) Null(column string) dbtypes.JoinFilter
Null creates an IS NULL condition. Column names are automatically quoted according to database vendor rules.
func (*JoinFilterFactory) Or ¶ added in v0.13.0
func (jff *JoinFilterFactory) Or(filters ...dbtypes.JoinFilter) dbtypes.JoinFilter
Or combines multiple join filters with OR logic. Returns a filter that matches when ANY provided filter matches. Nil filters are treated as no-ops and skipped.
Example:
jf := qb.JoinFilter()
filter := jf.Or(
jf.EqColumn("users.primary_email", "contacts.email"),
jf.EqColumn("users.secondary_email", "contacts.email"),
)
func (*JoinFilterFactory) Raw ¶ added in v0.13.0
func (jff *JoinFilterFactory) Raw(condition string, args ...any) dbtypes.JoinFilter
Raw creates a join filter from raw SQL with manual placeholder handling.
WARNING: This method bypasses all identifier quoting and SQL injection protection. It is the caller's responsibility to:
- Properly quote any identifiers (especially Oracle reserved words)
- Ensure the SQL fragment is valid for the target database
- Never concatenate user input directly into the condition string
Use this method ONLY when the type-safe methods cannot express your JOIN condition.
Examples:
jf.Raw(`users.id = profiles.user_id AND profiles."type" = ?`, "primary") // Mixed column comparison + value jf.Raw(`ST_Distance(users.location, stores.location) < 1000`) // Spatial functions
type QueryBuilder ¶
type QueryBuilder struct {
// contains filtered or unexported fields
}
QueryBuilder provides vendor-specific SQL query building. It wraps squirrel.StatementBuilderType with database-specific customizations for placeholder formats, identifier quoting, and function generation.
func NewQueryBuilder ¶
func NewQueryBuilder(vendor dbtypes.Vendor) *QueryBuilder
NewQueryBuilder creates a new query builder for the specified database vendor. It configures placeholder formats and prepares for vendor-specific SQL generation.
func (*QueryBuilder) BuildBooleanValue ¶
func (qb *QueryBuilder) BuildBooleanValue(value bool) any
BuildBooleanValue converts a Go boolean to the appropriate database representation
func (*QueryBuilder) BuildCaseInsensitiveLike ¶
func (qb *QueryBuilder) BuildCaseInsensitiveLike(column, value string) squirrel.Sqlizer
BuildCaseInsensitiveLike creates a case-insensitive LIKE expression. The implementation varies by database vendor.
func (*QueryBuilder) BuildCurrentTimestamp ¶
func (qb *QueryBuilder) BuildCurrentTimestamp() string
BuildCurrentTimestamp returns the current timestamp function for the database vendor
func (*QueryBuilder) BuildUUIDGeneration ¶
func (qb *QueryBuilder) BuildUUIDGeneration() string
BuildUUIDGeneration returns the UUID generation function for the database vendor
func (*QueryBuilder) BuildUpsert ¶
func (qb *QueryBuilder) BuildUpsert(table string, conflictColumns []string, insertColumns, updateColumns map[string]any) (query string, args []any, err error)
BuildUpsert creates an UPSERT/MERGE query using Oracle's MERGE statement. Oracle uses MERGE INTO ... USING ... ON ... WHEN MATCHED ... WHEN NOT MATCHED syntax.
func (*QueryBuilder) Columns ¶ added in v0.15.0
func (qb *QueryBuilder) Columns(structPtr any) dbtypes.Columns
Columns extracts column metadata from a struct with `db:"column_name"` tags. It lazily parses the struct on first use and caches the metadata forever, providing vendor-specific column quoting (e.g., Oracle reserved words).
This method delegates to the global column registry, which maintains per-vendor caches using sync.Map for lock-free cached reads.
Parameters:
- structPtr: Pointer to a struct with `db:"column_name"` tags
Returns:
- dbtypes.ColumnMetadata: Interface providing Get(), Fields(), and All() methods
Panics if:
- structPtr is not a pointer to a struct
- No fields with `db` tags are found
- Any db tag contains dangerous SQL characters
Performance:
- First use: ~2µs (reflection + tag parsing)
- Cached access: ~50ns (sync.Map read + method call)
Example:
type User struct {
ID int64 `db:"id"`
Name string `db:"name"`
Level string `db:"level"` // Oracle reserved word
}
cols := qb.Columns(&User{})
query := qb.Select(cols.Cols("ID", "Name")...).From("users")
// Oracle: SELECT "ID", "NAME" FROM users
// PostgreSQL: SELECT id, name FROM users
func (*QueryBuilder) Delete ¶
func (qb *QueryBuilder) Delete(table string) dbtypes.DeleteQueryBuilder
Delete creates a DELETE query builder for the specified table with Filter API support. The returned DeleteQueryBuilder provides type-safe filtering. Table names are automatically quoted according to database vendor rules to handle reserved words.
Example:
f := qb.Filter()
query := qb.Delete("users").Where(f.And(
f.Eq("status", "deleted"),
f.Lt("deleted_at", threshold),
))
func (*QueryBuilder) Eq ¶ added in v0.11.0
func (qb *QueryBuilder) Eq(column string, value any) squirrel.Eq
Eq creates an equality condition with proper column quoting for the database vendor
func (*QueryBuilder) EscapeIdentifier ¶
func (qb *QueryBuilder) EscapeIdentifier(identifier string) string
EscapeIdentifier escapes a database identifier (table/column name) according to vendor rules
func (*QueryBuilder) Expr ¶ added in v0.14.2
func (qb *QueryBuilder) Expr(sql string, alias ...string) (dbtypes.RawExpression, error)
Expr creates a raw SQL expression for use in SELECT, GROUP BY, and ORDER BY clauses. See dbtypes.Expr() for full documentation and security warnings.
Returns an error if the SQL is empty, too many aliases are provided, or alias contains dangerous characters.
func (*QueryBuilder) Filter ¶ added in v0.13.0
func (qb *QueryBuilder) Filter() dbtypes.FilterFactory
Filter returns a FilterFactory for creating composable WHERE clause filters. The factory provides type-safe methods (Eq, Lt, Gt, etc.) that automatically handle vendor-specific column quoting, as well as composition methods (And, Or, Not).
Example:
f := qb.Filter()
query := qb.Select("*").From("users").Where(f.And(
f.Eq("status", "active"),
f.Gt("age", 18),
))
func (*QueryBuilder) Gt ¶ added in v0.11.0
func (qb *QueryBuilder) Gt(column string, value any) squirrel.Gt
Gt creates a greater-than condition with proper column quoting for the database vendor
func (*QueryBuilder) GtOrEq ¶ added in v0.11.0
func (qb *QueryBuilder) GtOrEq(column string, value any) squirrel.GtOrEq
GtOrEq creates a greater-than-or-equal condition with proper column quoting for the database vendor
func (*QueryBuilder) Insert ¶
func (qb *QueryBuilder) Insert(table string) squirrel.InsertBuilder
Insert creates an INSERT query builder for the specified table
func (*QueryBuilder) InsertFields ¶ added in v0.15.0
func (qb *QueryBuilder) InsertFields(table string, instance any, fields ...string) squirrel.InsertBuilder
InsertFields creates an INSERT query by extracting only specified fields from a struct instance. This is useful for partial inserts or when you need explicit control over which fields to include.
Example:
user := User{ID: 123, Name: "Alice", Email: "alice@example.com", Status: "active"}
query := qb.InsertFields("users", &user, "Name", "Email")
// INSERT INTO users (name, email) VALUES (?, ?)
Panics if instance is not a struct or any field name is invalid.
func (*QueryBuilder) InsertStruct ¶ added in v0.15.0
func (qb *QueryBuilder) InsertStruct(table string, instance any) squirrel.InsertBuilder
InsertStruct creates an INSERT query by extracting all fields from a struct instance. Zero-value ID fields (int64 or string type with field name "ID") are automatically excluded to support auto-increment primary keys.
Example:
type User struct {
ID int64 `db:"id"` // Excluded if zero
Name string `db:"name"`
Email string `db:"email"`
}
user := User{Name: "Alice", Email: "alice@example.com"}
query := qb.InsertStruct("users", &user)
// INSERT INTO users (name, email) VALUES (?, ?)
Panics if instance is not a struct or pointer to struct with db tags.
func (*QueryBuilder) InsertWithColumns ¶
func (qb *QueryBuilder) InsertWithColumns(table string, columns ...string) squirrel.InsertBuilder
InsertWithColumns creates an INSERT query builder with pre-specified columns. It applies vendor-specific column quoting to the provided column list.
func (*QueryBuilder) JoinFilter ¶ added in v0.13.0
func (qb *QueryBuilder) JoinFilter() dbtypes.JoinFilterFactory
JoinFilter returns a JoinFilterFactory for creating composable JOIN ON conditions. The factory provides type-safe methods (EqColumn, LtColumn, GtColumn, etc.) for comparing columns to other columns (not values) with automatic vendor-specific quoting.
Example:
jf := qb.JoinFilter()
query := qb.Select("*").From("users").JoinOn("profiles", jf.And(
jf.EqColumn("users.id", "profiles.user_id"),
jf.GtColumn("profiles.created_at", "users.created_at"),
))
func (*QueryBuilder) Lt ¶ added in v0.11.0
func (qb *QueryBuilder) Lt(column string, value any) squirrel.Lt
Lt creates a less-than condition with proper column quoting for the database vendor
func (*QueryBuilder) LtOrEq ¶ added in v0.11.0
func (qb *QueryBuilder) LtOrEq(column string, value any) squirrel.LtOrEq
LtOrEq creates a less-than-or-equal condition with proper column quoting for the database vendor
func (*QueryBuilder) MustExpr ¶ added in v0.19.0
func (qb *QueryBuilder) MustExpr(sql string, alias ...string) dbtypes.RawExpression
MustExpr is like Expr but panics on error. Use this only in static initialization or tests where errors indicate programming bugs.
func (*QueryBuilder) NotEq ¶ added in v0.11.0
func (qb *QueryBuilder) NotEq(column string, value any) squirrel.NotEq
NotEq creates a not-equal condition with proper column quoting for the database vendor
func (*QueryBuilder) Select ¶
func (qb *QueryBuilder) Select(columns ...any) *SelectQueryBuilder
Select creates a SELECT query builder with vendor-specific column quoting. For Oracle, it applies identifier quoting to handle reserved words appropriately. Accepts both string column names and RawExpression instances (v2.1+).
Examples:
qb.Select("id", "name") // String columns
qb.Select("id", qb.Expr("COUNT(*)", "total")) // Mixed: column + expression
qb.Select(qb.Expr("SUM(amount)", "revenue")) // Expression only
func (*QueryBuilder) Update ¶
func (qb *QueryBuilder) Update(table string) dbtypes.UpdateQueryBuilder
Update creates an UPDATE query builder for the specified table with Filter API support. The returned UpdateQueryBuilder provides type-safe filtering and vendor-specific column quoting. Table names are automatically quoted according to database vendor rules to handle reserved words.
Example:
f := qb.Filter()
query := qb.Update("users").
Set("status", "active").
Set("updated_at", time.Now()).
Where(f.Eq("id", 123))
func (*QueryBuilder) Vendor ¶
func (qb *QueryBuilder) Vendor() string
Vendor returns the database vendor string
type SelectQueryBuilder ¶ added in v0.11.0
type SelectQueryBuilder struct {
// contains filtered or unexported fields
}
SelectQueryBuilder provides a type-safe interface for building SELECT queries with proper identifier quoting and vendor-specific optimizations.
func (*SelectQueryBuilder) CrossJoinOn ¶ added in v0.13.0
func (sqb *SelectQueryBuilder) CrossJoinOn(table any) dbtypes.SelectQueryBuilder
CrossJoinOn adds a CROSS JOIN clause to the query. Accepts either a string table name or *TableRef instance with optional alias. Cross joins do not have ON conditions, so no JoinFilter is needed. The table name is automatically quoted according to vendor rules.
func (*SelectQueryBuilder) From ¶ added in v0.11.0
func (sqb *SelectQueryBuilder) From(from ...any) dbtypes.SelectQueryBuilder
From specifies the table(s) to select from. Accepts either string table names or *TableRef instances with optional aliases. Table names are automatically quoted according to database vendor rules to handle reserved words.
Examples:
From("users") // Simple table
From("users", "profiles") // Multiple tables (cross join)
From(Table("customers").As("c")) // Table with alias
From("users", Table("profiles").As("p")) // Mixed
func (*SelectQueryBuilder) GroupBy ¶ added in v0.11.0
func (sqb *SelectQueryBuilder) GroupBy(groupBys ...any) dbtypes.SelectQueryBuilder
GroupBy adds a GROUP BY clause to the query. Column names are automatically quoted according to database vendor rules. Accepts both string column names and RawExpression instances (v2.1+).
Examples:
.GroupBy("category_id", "status") // String columns
.GroupBy("id", qb.Expr("DATE(created_at)")) // Mixed: column + expression
.GroupBy(qb.Expr("YEAR(order_date)")) // Expression only
func (*SelectQueryBuilder) Having ¶ added in v0.11.0
func (sqb *SelectQueryBuilder) Having(pred any, rest ...any) dbtypes.SelectQueryBuilder
Having adds a HAVING clause to the query
func (*SelectQueryBuilder) InnerJoinOn ¶ added in v0.13.0
func (sqb *SelectQueryBuilder) InnerJoinOn(table any, filter dbtypes.JoinFilter) dbtypes.SelectQueryBuilder
InnerJoinOn adds a type-safe INNER JOIN clause to the query using JoinFilter. Accepts either a string table name or *TableRef instance with optional alias. The table name is automatically quoted according to vendor rules.
func (*SelectQueryBuilder) JoinOn ¶ added in v0.13.0
func (sqb *SelectQueryBuilder) JoinOn(table any, filter dbtypes.JoinFilter) dbtypes.SelectQueryBuilder
JoinOn adds a type-safe JOIN clause to the query using JoinFilter for column comparisons. Accepts either a string table name or *TableRef instance with optional alias. The table name is automatically quoted according to vendor rules.
Example:
jf := qb.JoinFilter()
query.JoinOn(Table("profiles").As("p"), jf.EqColumn("users.id", "p.user_id"))
func (*SelectQueryBuilder) LeftJoinOn ¶ added in v0.13.0
func (sqb *SelectQueryBuilder) LeftJoinOn(table any, filter dbtypes.JoinFilter) dbtypes.SelectQueryBuilder
LeftJoinOn adds a type-safe LEFT JOIN clause to the query using JoinFilter. Accepts either a string table name or *TableRef instance with optional alias. The table name is automatically quoted according to vendor rules.
func (*SelectQueryBuilder) Limit ¶ added in v0.11.0
func (sqb *SelectQueryBuilder) Limit(limit uint64) dbtypes.SelectQueryBuilder
Limit sets the LIMIT for the query
func (*SelectQueryBuilder) Offset ¶ added in v0.11.0
func (sqb *SelectQueryBuilder) Offset(offset uint64) dbtypes.SelectQueryBuilder
Offset sets the OFFSET for the query
func (*SelectQueryBuilder) OrderBy ¶ added in v0.11.0
func (sqb *SelectQueryBuilder) OrderBy(orderBys ...any) dbtypes.SelectQueryBuilder
OrderBy adds an ORDER BY clause to the query. Column names are automatically quoted according to database vendor rules. Accepts both string column names (with optional ASC/DESC) and RawExpression instances (v2.1+).
Examples:
.OrderBy("created_at DESC") // String with direction
.OrderBy("name", "id DESC") // Multiple strings
.OrderBy(qb.Expr("COUNT(*) DESC")) // Expression with direction
.OrderBy("id", qb.Expr("UPPER(name) ASC")) // Mixed
func (*SelectQueryBuilder) Paginate ¶ added in v0.11.0
func (sqb *SelectQueryBuilder) Paginate(limit, offset uint64) dbtypes.SelectQueryBuilder
Paginate applies pagination to the query with vendor-specific syntax. Use limit=0 for no limit (with offset only), offset=0 for no offset (limit only). Oracle 12c+ will use OFFSET...FETCH syntax, others use LIMIT/OFFSET.
func (*SelectQueryBuilder) RightJoinOn ¶ added in v0.13.0
func (sqb *SelectQueryBuilder) RightJoinOn(table any, filter dbtypes.JoinFilter) dbtypes.SelectQueryBuilder
RightJoinOn adds a type-safe RIGHT JOIN clause to the query using JoinFilter. Accepts either a string table name or *TableRef instance with optional alias. The table name is automatically quoted according to vendor rules.
func (*SelectQueryBuilder) ToSQL ¶ added in v0.11.0
func (sqb *SelectQueryBuilder) ToSQL() (sql string, args []any, err error)
ToSQL generates the final SQL query string and arguments. For Oracle, pagination uses OFFSET...FETCH syntax; for others, uses LIMIT/OFFSET.
func (*SelectQueryBuilder) ValidateForSubquery ¶ added in v0.14.2
func (sqb *SelectQueryBuilder) ValidateForSubquery() error
ValidateForSubquery provides lightweight validation without forcing SQL rendering.
func (*SelectQueryBuilder) Where ¶ added in v0.11.0
func (sqb *SelectQueryBuilder) Where(filter dbtypes.Filter) dbtypes.SelectQueryBuilder
Where adds a filter to the WHERE clause. Multiple calls to Where() will be combined with AND logic.
Create filters using the FilterFactory obtained from QueryBuilder.Filter():
Simple condition:
f := qb.Filter()
query.Where(f.Eq("status", "active"))
Multiple conditions with AND:
f := qb.Filter()
query.Where(f.And(
f.Eq("status", "active"),
f.Gt("age", 18),
))
OR conditions:
f := qb.Filter()
query.Where(f.Or(
f.Eq("status", "active"),
f.Eq("role", "admin"),
))
Complex nested logic:
f := qb.Filter()
query.Where(f.And(
f.Or(
f.Eq("status", "active"),
f.Eq("status", "pending"),
),
f.Gt("balance", 1000),
))
type UpdateQueryBuilder ¶ added in v0.13.0
type UpdateQueryBuilder struct {
// contains filtered or unexported fields
}
UpdateQueryBuilder provides a type-safe interface for building UPDATE queries with Filter API support and vendor-specific column quoting.
func (*UpdateQueryBuilder) Set ¶ added in v0.13.0
func (uqb *UpdateQueryBuilder) Set(column string, value any) dbtypes.UpdateQueryBuilder
Set sets a column to a value in the UPDATE statement. Column names are automatically quoted according to database vendor rules.
func (*UpdateQueryBuilder) SetMap ¶ added in v0.13.0
func (uqb *UpdateQueryBuilder) SetMap(clauses map[string]any) dbtypes.UpdateQueryBuilder
SetMap sets multiple columns to values in the UPDATE statement. Column names are automatically quoted according to database vendor rules.
func (*UpdateQueryBuilder) SetStruct ¶ added in v0.15.0
func (uqb *UpdateQueryBuilder) SetStruct(instance any, fields ...string) dbtypes.UpdateQueryBuilder
SetStruct sets multiple columns from a struct instance in the UPDATE statement. If no fields are specified, all struct fields are included. If fields are provided, only those fields are updated. Column names are automatically quoted according to database vendor rules.
Example (all fields):
user := User{Name: "Alice", Email: "alice@example.com", Status: "active"}
query := qb.Update("users").SetStruct(&user).Where(f.Eq("id", 123))
// UPDATE users SET name = ?, email = ?, status = ? WHERE id = ?
Example (selective fields):
user := User{Name: "Bob", Email: "bob@example.com", Status: "inactive"}
query := qb.Update("users").SetStruct(&user, "Name", "Status").Where(f.Eq("id", 456))
// UPDATE users SET name = ?, status = ? WHERE id = ?
Panics if instance is not a struct or any field name is invalid.
func (*UpdateQueryBuilder) ToSQL ¶ added in v0.13.0
func (uqb *UpdateQueryBuilder) ToSQL() (sql string, args []any, err error)
ToSQL generates the final SQL query and arguments.
func (*UpdateQueryBuilder) Where ¶ added in v0.13.0
func (uqb *UpdateQueryBuilder) Where(filter dbtypes.Filter) dbtypes.UpdateQueryBuilder
Where adds a filter to the WHERE clause. Multiple calls to Where() will be combined with AND logic.