builder

package
v0.20.0 Latest Latest
Warning

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

Go to latest
Published: Dec 18, 2025 License: MIT Imports: 8 Imported by: 0

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

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

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

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.

func (Filter) ToSQL added in v0.13.0

func (f Filter) ToSQL() (sql string, args []any, err error)

ToSQL is a convenience method with idiomatic Go naming (uppercase SQL). It delegates to ToSql() for actual implementation.

func (Filter) ToSql added in v0.13.0

func (f Filter) ToSql() (sql string, args []any, err error)

ToSql generates the SQL fragment and arguments for this filter. This method implements the squirrel.Sqlizer interface (inherited by dbtypes.Filter).

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").

func (JoinFilter) ToSQL added in v0.13.0

func (jf JoinFilter) ToSQL() (sql string, args []any, err error)

ToSQL is a convenience method with idiomatic Go naming (uppercase SQL). It delegates to ToSql() for actual implementation.

func (JoinFilter) ToSql added in v0.13.0

func (jf JoinFilter) ToSql() (sql string, args []any, err error)

ToSql generates the SQL fragment for this join condition. This method implements the squirrel.Sqlizer interface (inherited by dbtypes.JoinFilter).

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

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

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

Limit sets the LIMIT for the query

func (*SelectQueryBuilder) Offset added in v0.11.0

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

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

Where adds a filter to the WHERE clause. Multiple calls to Where() will be combined with AND logic.

Jump to

Keyboard shortcuts

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