Documentation
¶
Overview ¶
Package relica provides a lightweight, type-safe database query builder for Go.
Relica offers a fluent API for building SQL queries with support for:
- Multiple databases (PostgreSQL, MySQL, SQLite)
- Zero production dependencies
- Prepared statement caching
- Transaction management
- Advanced SQL features (JOINs, aggregates, subqueries, CTEs)
Quick Start ¶
Install:
go get github.com/coregx/relica
Basic usage:
db, err := relica.Open("postgres", "user=postgres dbname=myapp")
if err != nil {
log.Fatal(err)
}
defer db.Close()
var users []User
err = db.Builder().Select("*").From("users").All(&users)
Features ¶
CRUD Operations:
// SELECT
db.Builder().Select("*").From("users").Where("id = ?", 123).One(&user)
// INSERT
db.Builder().Insert("users", map[string]interface{}{
"name": "Alice",
"email": "alice@example.com",
}).Execute()
// UPDATE
db.Builder().Update("users").
Set(map[string]interface{}{"status": "active"}).
Where("id = ?", 123).
Execute()
// DELETE
db.Builder().Delete("users").Where("id = ?", 123).Execute()
Index ¶
- Variables
- type BatchInsertQuery
- func (biq *BatchInsertQuery) Build() *Query
- func (biq *BatchInsertQuery) Execute() (sql.Result, error)
- func (biq *BatchInsertQuery) Values(values ...interface{}) *BatchInsertQuery
- func (biq *BatchInsertQuery) ValuesMap(values map[string]interface{}) *BatchInsertQuery
- func (biq *BatchInsertQuery) WithContext(ctx context.Context) *BatchInsertQuery
- type BatchUpdateQuery
- type DB
- func (d *DB) Begin(ctx context.Context) (*Tx, error)
- func (d *DB) BeginTx(ctx context.Context, opts *TxOptions) (*Tx, error)
- func (d *DB) Builder() *QueryBuilder
- func (d *DB) Close() error
- func (d *DB) ExecContext(ctx context.Context, query string, args ...interface{}) (sql.Result, error)
- func (d *DB) GenerateParamName() string
- func (d *DB) QueryContext(ctx context.Context, query string, args ...interface{}) (*sql.Rows, error)
- func (d *DB) QueryRowContext(ctx context.Context, query string, args ...interface{}) *sql.Row
- func (d *DB) QuoteColumnName(column string) string
- func (d *DB) QuoteTableName(table string) string
- func (d *DB) Unwrap() *core.DB
- func (d *DB) WithContext(ctx context.Context) *DB
- type DeleteQuery
- type Expression
- type HashExp
- type LikeExp
- type Option
- type Query
- type QueryBuilder
- func (qb *QueryBuilder) BatchInsert(table string, columns []string) *BatchInsertQuery
- func (qb *QueryBuilder) BatchUpdate(table, keyColumn string) *BatchUpdateQuery
- func (qb *QueryBuilder) Delete(table string) *DeleteQuery
- func (qb *QueryBuilder) Insert(table string, values map[string]interface{}) *Query
- func (qb *QueryBuilder) Select(cols ...string) *SelectQuery
- func (qb *QueryBuilder) Unwrap() *core.QueryBuilder
- func (qb *QueryBuilder) Update(table string) *UpdateQuery
- func (qb *QueryBuilder) Upsert(table string, values map[string]interface{}) *UpsertQuery
- func (qb *QueryBuilder) WithContext(ctx context.Context) *QueryBuilder
- type SelectQuery
- func (sq *SelectQuery) All(dest interface{}) error
- func (sq *SelectQuery) AsExpression() Expression
- func (sq *SelectQuery) Build() *Query
- func (sq *SelectQuery) CrossJoin(table string) *SelectQuery
- func (sq *SelectQuery) Except(other *SelectQuery) *SelectQuery
- func (sq *SelectQuery) From(table string) *SelectQuery
- func (sq *SelectQuery) FromSelect(subquery *SelectQuery, alias string) *SelectQuery
- func (sq *SelectQuery) FullJoin(table string, on interface{}) *SelectQuery
- func (sq *SelectQuery) GroupBy(columns ...string) *SelectQuery
- func (sq *SelectQuery) Having(condition interface{}, args ...interface{}) *SelectQuery
- func (sq *SelectQuery) InnerJoin(table string, on interface{}) *SelectQuery
- func (sq *SelectQuery) Intersect(other *SelectQuery) *SelectQuery
- func (sq *SelectQuery) LeftJoin(table string, on interface{}) *SelectQuery
- func (sq *SelectQuery) Limit(limit int64) *SelectQuery
- func (sq *SelectQuery) Offset(offset int64) *SelectQuery
- func (sq *SelectQuery) One(dest interface{}) error
- func (sq *SelectQuery) OrderBy(columns ...string) *SelectQuery
- func (sq *SelectQuery) RightJoin(table string, on interface{}) *SelectQuery
- func (sq *SelectQuery) SelectExpr(expr string, args ...interface{}) *SelectQuery
- func (sq *SelectQuery) Union(other *SelectQuery) *SelectQuery
- func (sq *SelectQuery) UnionAll(other *SelectQuery) *SelectQuery
- func (sq *SelectQuery) Unwrap() *core.SelectQuery
- func (sq *SelectQuery) Where(condition interface{}, params ...interface{}) *SelectQuery
- func (sq *SelectQuery) With(name string, query *SelectQuery) *SelectQuery
- func (sq *SelectQuery) WithContext(ctx context.Context) *SelectQuery
- func (sq *SelectQuery) WithRecursive(name string, query *SelectQuery) *SelectQuery
- type Tx
- type TxOptions
- type UpdateQuery
- func (uq *UpdateQuery) Build() *Query
- func (uq *UpdateQuery) Execute() (sql.Result, error)
- func (uq *UpdateQuery) Set(values map[string]interface{}) *UpdateQuery
- func (uq *UpdateQuery) Where(condition interface{}, params ...interface{}) *UpdateQuery
- func (uq *UpdateQuery) WithContext(ctx context.Context) *UpdateQuery
- type UpsertQuery
- func (uq *UpsertQuery) Build() *Query
- func (uq *UpsertQuery) DoNothing() *UpsertQuery
- func (uq *UpsertQuery) DoUpdate(columns ...string) *UpsertQuery
- func (uq *UpsertQuery) Execute() (sql.Result, error)
- func (uq *UpsertQuery) OnConflict(columns ...string) *UpsertQuery
- func (uq *UpsertQuery) WithContext(ctx context.Context) *UpsertQuery
Constants ¶
This section is empty.
Variables ¶
var And = core.And
And combines expressions with AND.
var Between = core.Between
Between creates a BETWEEN expression (column BETWEEN low AND high).
var Eq = core.Eq
Eq creates an equality expression (column = value).
var Exists = core.Exists
Exists creates an EXISTS subquery expression.
var GreaterOrEqual = core.GreaterOrEqual
GreaterOrEqual creates a greater-or-equal expression (column >= value).
var GreaterThan = core.GreaterThan
GreaterThan creates a greater-than expression (column > value).
var In = core.In
In creates an IN expression (column IN (values...)).
var LessOrEqual = core.LessOrEqual
LessOrEqual creates a less-or-equal expression (column <= value).
var LessThan = core.LessThan
LessThan creates a less-than expression (column < value).
var Like = core.Like
Like creates a LIKE expression with automatic escaping.
var NewExp = core.NewExp
NewExp creates a new raw SQL expression.
var Not = core.Not
Not negates an expression.
var NotBetween = core.NotBetween
NotBetween creates a NOT BETWEEN expression.
var NotEq = core.NotEq
NotEq creates a not-equal expression (column != value).
var NotExists = core.NotExists
NotExists creates a NOT EXISTS subquery expression.
var NotIn = core.NotIn
NotIn creates a NOT IN expression (column NOT IN (values...)).
var NotLike = core.NotLike
NotLike creates a NOT LIKE expression.
var Or = core.Or
Or combines expressions with OR.
var OrLike = core.OrLike
OrLike creates a LIKE expression combined with OR.
var OrNotLike = core.OrNotLike
OrNotLike creates a NOT LIKE expression combined with OR.
var WithMaxIdleConns = core.WithMaxIdleConns
WithMaxIdleConns sets the maximum number of idle connections.
var WithMaxOpenConns = core.WithMaxOpenConns
WithMaxOpenConns sets the maximum number of open connections.
var WithStmtCacheCapacity = core.WithStmtCacheCapacity
WithStmtCacheCapacity sets the prepared statement cache capacity.
Functions ¶
This section is empty.
Types ¶
type BatchInsertQuery ¶
type BatchInsertQuery struct {
// contains filtered or unexported fields
}
BatchInsertQuery represents a batch INSERT query being built.
func (*BatchInsertQuery) Build ¶
func (biq *BatchInsertQuery) Build() *Query
Build constructs the Query object.
func (*BatchInsertQuery) Execute ¶
func (biq *BatchInsertQuery) Execute() (sql.Result, error)
Execute executes the batch INSERT query.
func (*BatchInsertQuery) Values ¶
func (biq *BatchInsertQuery) Values(values ...interface{}) *BatchInsertQuery
Values adds a row of values to the batch insert.
Example:
BatchInsert("users", []string{"name", "email"}).
Values("Alice", "alice@example.com").
Values("Bob", "bob@example.com")
func (*BatchInsertQuery) ValuesMap ¶
func (biq *BatchInsertQuery) ValuesMap(values map[string]interface{}) *BatchInsertQuery
ValuesMap adds a row from a map.
Example:
BatchInsert("users", []string{"name", "email"}).
ValuesMap(map[string]interface{}{"name": "Alice", "email": "alice@example.com"})
func (*BatchInsertQuery) WithContext ¶
func (biq *BatchInsertQuery) WithContext(ctx context.Context) *BatchInsertQuery
WithContext sets the context for this batch INSERT query.
type BatchUpdateQuery ¶
type BatchUpdateQuery struct {
// contains filtered or unexported fields
}
BatchUpdateQuery represents a batch UPDATE query being built.
func (*BatchUpdateQuery) Build ¶
func (buq *BatchUpdateQuery) Build() *Query
Build constructs the Query object.
func (*BatchUpdateQuery) Execute ¶
func (buq *BatchUpdateQuery) Execute() (sql.Result, error)
Execute executes the batch UPDATE query.
func (*BatchUpdateQuery) Set ¶
func (buq *BatchUpdateQuery) Set(keyValue interface{}, values map[string]interface{}) *BatchUpdateQuery
Set adds a row update to the batch.
Example:
BatchUpdate("users", "id").
Set(1, map[string]interface{}{"status": 2}).
Set(2, map[string]interface{}{"status": 3})
func (*BatchUpdateQuery) WithContext ¶
func (buq *BatchUpdateQuery) WithContext(ctx context.Context) *BatchUpdateQuery
WithContext sets the context for this batch UPDATE query.
type DB ¶
type DB struct {
// contains filtered or unexported fields
}
DB represents a database connection with query building capabilities.
DB provides a fluent API for constructing and executing SQL queries in a type-safe manner. It wraps the underlying database/sql connection and adds features like:
- Prepared statement caching (LRU eviction, <60ns hit latency)
- Query builder with method chaining
- Transaction management (all isolation levels)
- Multi-database support (PostgreSQL, MySQL, SQLite)
Example:
db, err := relica.Open("postgres", "user=postgres dbname=myapp")
if err != nil {
log.Fatal(err)
}
defer db.Close()
var users []User
err = db.Builder().
Select("id", "name", "email").
From("users").
Where("active = ?", true).
OrderBy("name").
All(&users)
func NewDB ¶
NewDB creates a database connection (deprecated: use Open).
This function exists for backward compatibility. New code should use Open.
Example:
db, err := relica.NewDB("postgres", dsn)
func Open ¶
Open creates a new database connection with optional configuration.
The driverName parameter specifies the database driver:
- "postgres" - PostgreSQL
- "mysql" - MySQL
- "sqlite3" - SQLite
The dsn parameter is the database-specific connection string.
Example:
db, err := relica.Open("postgres", "user=postgres dbname=myapp",
relica.WithMaxOpenConns(100),
relica.WithMaxIdleConns(50))
if err != nil {
log.Fatal(err)
}
defer db.Close()
func WrapDB ¶
WrapDB wraps an existing *sql.DB connection with Relica's query builder.
The caller is responsible for managing the connection lifecycle (including Close()). This is useful when you need to:
- Use Relica with an externally managed connection pool
- Integrate with existing code that already has a *sql.DB instance
- Apply custom connection pool settings before wrapping
Example:
sqlDB, _ := sql.Open("postgres", dsn)
sqlDB.SetMaxOpenConns(100)
sqlDB.SetConnMaxLifetime(time.Hour)
db := relica.WrapDB(sqlDB, "postgres")
defer sqlDB.Close() // Caller's responsibility
func (*DB) Begin ¶
Begin starts a transaction with default options.
The transaction must be committed or rolled back to release resources. It's safe to call Rollback() even after Commit().
Example:
tx, err := db.Begin(ctx)
if err != nil {
return err
}
defer tx.Rollback() // Safe even after Commit
// Use transaction
_, err = tx.Builder().Insert("users", data).Execute()
if err != nil {
return err
}
return tx.Commit()
func (*DB) BeginTx ¶
BeginTx starts a transaction with specified options.
Options can specify isolation level and read-only mode:
- Isolation: sql.LevelReadUncommitted, sql.LevelReadCommitted, sql.LevelRepeatableRead, sql.LevelSerializable
- ReadOnly: true for read-only transactions (some databases optimize these)
Example:
opts := &relica.TxOptions{
Isolation: sql.LevelSerializable,
ReadOnly: false,
}
tx, err := db.BeginTx(ctx, opts)
func (*DB) Builder ¶
func (d *DB) Builder() *QueryBuilder
Builder returns a new QueryBuilder for constructing queries.
The query builder provides a fluent interface for building SELECT, INSERT, UPDATE, DELETE, and UPSERT queries.
Example:
db.Builder().
Select("*").
From("users").
Where("id = ?", 123).
One(&user)
func (*DB) Close ¶
Close releases all database resources including the connection pool and statement cache.
After calling Close, the DB instance should not be used.
Example:
db, _ := relica.Open("postgres", dsn)
defer db.Close()
func (*DB) ExecContext ¶
func (d *DB) ExecContext(ctx context.Context, query string, args ...interface{}) (sql.Result, error)
ExecContext executes a raw SQL query (INSERT/UPDATE/DELETE).
This bypasses the query builder and executes SQL directly. Use this for queries that aren't supported by the query builder or when you need maximum control.
Example:
result, err := db.ExecContext(ctx,
"UPDATE users SET status = ? WHERE id = ?",
1, 123)
if err != nil {
return err
}
rowsAffected, _ := result.RowsAffected()
func (*DB) GenerateParamName ¶
GenerateParamName generates a unique parameter placeholder name.
This is useful when building dynamic SQL queries.
Example:
ph := db.GenerateParamName() // Returns: p1, p2, p3, etc.
func (*DB) QueryContext ¶
func (d *DB) QueryContext(ctx context.Context, query string, args ...interface{}) (*sql.Rows, error)
QueryContext executes a raw SQL query and returns rows.
This bypasses the query builder and executes SQL directly. You are responsible for closing the returned rows.
Example:
rows, err := db.QueryContext(ctx,
"SELECT * FROM users WHERE status = ?", 1)
if err != nil {
return err
}
defer rows.Close()
for rows.Next() {
// Process rows
}
func (*DB) QueryRowContext ¶
QueryRowContext executes a raw SQL query expected to return at most one row.
This bypasses the query builder and executes SQL directly.
Example:
var count int
err := db.QueryRowContext(ctx,
"SELECT COUNT(*) FROM users").Scan(&count)
func (*DB) QuoteColumnName ¶
QuoteColumnName quotes a column name using the database's identifier quoting style.
This is useful when building dynamic SQL queries.
Example:
quoted := db.QuoteColumnName("user_id")
// PostgreSQL: "user_id"
// MySQL: `user_id`
func (*DB) QuoteTableName ¶
QuoteTableName quotes a table name using the database's identifier quoting style.
This is useful when building dynamic SQL queries.
Example:
quoted := db.QuoteTableName("users")
// PostgreSQL: "users"
// MySQL: `users`
func (*DB) Unwrap ¶
Unwrap returns the underlying core.DB for advanced use cases.
This method is provided for edge cases where direct access to internal types is needed. Most users should not need this.
Example:
coreDB := db.Unwrap() // Use coreDB for advanced operations
func (*DB) WithContext ¶
WithContext returns a new DB with the given context.
The context will be used for all subsequent query operations unless overridden at the query level.
Example:
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
db := db.WithContext(ctx)
db.Builder().Select("*").From("users").All(&users)
type DeleteQuery ¶
type DeleteQuery struct {
// contains filtered or unexported fields
}
DeleteQuery represents a DELETE query being built.
func (*DeleteQuery) Build ¶
func (dq *DeleteQuery) Build() *Query
Build constructs the Query object.
func (*DeleteQuery) Execute ¶
func (dq *DeleteQuery) Execute() (sql.Result, error)
Execute executes the DELETE query.
func (*DeleteQuery) Where ¶
func (dq *DeleteQuery) Where(condition interface{}, params ...interface{}) *DeleteQuery
Where adds a WHERE condition to the DELETE query.
Example:
Delete("users").Where("id = ?", 123)
func (*DeleteQuery) WithContext ¶
func (dq *DeleteQuery) WithContext(ctx context.Context) *DeleteQuery
WithContext sets the context for this DELETE query.
type Expression ¶
type Expression = core.Expression
Expression represents a database expression for building complex WHERE clauses.
Expressions provide a type-safe way to construct SQL conditions without writing raw SQL strings. They support nesting and composition.
Example:
expr := relica.And(
relica.Eq("status", 1),
relica.Or(
relica.GreaterThan("age", 18),
relica.Eq("verified", true),
),
)
db.Builder().Select("*").From("users").Where(expr).All(&users)
type HashExp ¶
HashExp represents a hash-based expression using column-value pairs.
HashExp provides a convenient map syntax for simple equality conditions. Special values are handled automatically:
- nil → "column IS NULL"
- []interface{} → "column IN (...)"
Example:
db.Builder().Select("*").From("users").Where(relica.HashExp{
"status": 1,
"role": []string{"admin", "moderator"},
"deleted_at": nil,
}).All(&users)
type LikeExp ¶
LikeExp represents a LIKE expression with automatic escaping.
LikeExp provides pattern matching with automatic escaping of SQL wildcard characters (%, _).
Example:
db.Builder().Select("*").From("users").Where(
relica.Like("name", "john%"),
).All(&users)
type Option ¶
Option is a functional option for configuring DB.
Example:
db, err := relica.Open("postgres", dsn,
relica.WithMaxOpenConns(100),
relica.WithMaxIdleConns(50))
type Query ¶
type Query struct {
// contains filtered or unexported fields
}
Query represents a built query ready for execution.
Query encapsulates the SQL string, parameters, and execution context. It provides methods for executing the query and scanning results.
Example:
q := db.Builder().Select("*").From("users").Where("id = ?", 123).Build()
var user User
err := q.One(&user)
type QueryBuilder ¶
type QueryBuilder struct {
// contains filtered or unexported fields
}
QueryBuilder constructs type-safe queries.
The query builder provides a fluent interface for building SELECT, INSERT, UPDATE, DELETE, UPSERT, and batch operations. All queries are cached and executed with prepared statements.
Example:
qb := db.Builder()
qb.Select("*").From("users").Where("status = ?", 1).All(&users)
func (*QueryBuilder) BatchInsert ¶
func (qb *QueryBuilder) BatchInsert(table string, columns []string) *BatchInsertQuery
BatchInsert creates a batch INSERT query for multiple rows.
This is 3.3x faster than individual INSERTs for 100 rows. Use Values() or ValuesMap() to add rows.
Example:
db.Builder().BatchInsert("users", []string{"name", "email"}).
Values("Alice", "alice@example.com").
Values("Bob", "bob@example.com").
Execute()
func (*QueryBuilder) BatchUpdate ¶
func (qb *QueryBuilder) BatchUpdate(table, keyColumn string) *BatchUpdateQuery
BatchUpdate creates a batch UPDATE query for multiple rows.
This is 2.5x faster than individual UPDATEs for 100 rows. Uses CASE-WHEN logic to update multiple rows with different values.
Example:
db.Builder().BatchUpdate("users", "id").
Set(1, map[string]interface{}{"status": 2}).
Set(2, map[string]interface{}{"status": 3}).
Execute()
func (*QueryBuilder) Delete ¶
func (qb *QueryBuilder) Delete(table string) *DeleteQuery
Delete creates a DELETE query for the specified table.
Use Where() to filter rows to delete.
Example:
db.Builder().Delete("users").
Where("id = ?", 123).
Execute()
func (*QueryBuilder) Insert ¶
func (qb *QueryBuilder) Insert(table string, values map[string]interface{}) *Query
Insert builds an INSERT query for a single row.
The values parameter is a map of column names to values. Column order is deterministic (alphabetically sorted) for cache efficiency.
Example:
result, err := db.Builder().Insert("users", map[string]interface{}{
"name": "Alice",
"email": "alice@example.com",
"status": 1,
}).Execute()
func (*QueryBuilder) Select ¶
func (qb *QueryBuilder) Select(cols ...string) *SelectQuery
Select starts a SELECT query with the specified columns.
If no columns are provided, defaults to "*" (all columns).
Example:
db.Builder().Select("id", "name", "email").From("users").All(&users)
func (*QueryBuilder) Unwrap ¶
func (qb *QueryBuilder) Unwrap() *core.QueryBuilder
Unwrap returns the underlying core.QueryBuilder for advanced use cases.
This method is provided for edge cases where direct access to internal types is needed. Most users should not need this.
func (*QueryBuilder) Update ¶
func (qb *QueryBuilder) Update(table string) *UpdateQuery
Update creates an UPDATE query for the specified table.
Use Set() to specify column values and Where() to filter rows.
Example:
db.Builder().Update("users").
Set(map[string]interface{}{"status": 2}).
Where("id = ?", 123).
Execute()
func (*QueryBuilder) Upsert ¶
func (qb *QueryBuilder) Upsert(table string, values map[string]interface{}) *UpsertQuery
Upsert creates an UPSERT query (INSERT with conflict resolution).
Supported strategies:
- PostgreSQL/SQLite: ON CONFLICT ... DO UPDATE
- MySQL: ON DUPLICATE KEY UPDATE
Example:
db.Builder().Upsert("users", map[string]interface{}{
"id": 1,
"name": "Alice",
"email": "alice@example.com",
}).OnConflict("id").DoUpdate("name", "email").Execute()
func (*QueryBuilder) WithContext ¶
func (qb *QueryBuilder) WithContext(ctx context.Context) *QueryBuilder
WithContext sets the context for all queries built by this builder.
The context will be used for all subsequent query operations unless overridden at the query level.
Example:
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
qb := db.Builder().WithContext(ctx)
qb.Select("*").From("users").All(&users)
type SelectQuery ¶
type SelectQuery struct {
// contains filtered or unexported fields
}
SelectQuery represents a SELECT query being built.
SelectQuery supports a wide range of SQL features including:
- JOINs (INNER, LEFT, RIGHT, FULL, CROSS)
- Aggregates (COUNT, SUM, AVG, MIN, MAX)
- GROUP BY and HAVING
- ORDER BY, LIMIT, OFFSET
- Set operations (UNION, INTERSECT, EXCEPT)
- Common Table Expressions (WITH, WITH RECURSIVE)
- Subqueries (in FROM, WHERE, SELECT clauses)
Example:
sq := db.Builder().
Select("u.name", "COUNT(*) as order_count").
From("users u").
InnerJoin("orders o", "o.user_id = u.id").
GroupBy("u.id", "u.name").
Having("COUNT(*) > ?", 10).
OrderBy("order_count DESC")
sq.All(&results)
func (*SelectQuery) All ¶
func (sq *SelectQuery) All(dest interface{}) error
All scans all rows into dest slice.
Example:
var users []User
err := db.Builder().Select("*").From("users").All(&users)
func (*SelectQuery) AsExpression ¶
func (sq *SelectQuery) AsExpression() Expression
AsExpression converts a SelectQuery to an Expression for subquery use.
Example:
sub := db.Builder().Select("user_id").From("orders").Where("total > ?", 100)
db.Builder().Select("*").From("users").
Where(relica.In("id", sub.AsExpression())).All(&users)
func (*SelectQuery) Build ¶
func (sq *SelectQuery) Build() *Query
Build constructs the Query object from SelectQuery.
Example:
q := db.Builder().Select("*").From("users").Where("id = ?", 123).Build()
sql, params := q.SQL(), q.Params()
func (*SelectQuery) CrossJoin ¶
func (sq *SelectQuery) CrossJoin(table string) *SelectQuery
CrossJoin adds a CROSS JOIN clause (Cartesian product).
Example:
db.Builder().Select("*").
From("colors").
CrossJoin("sizes").
All(&results)
func (*SelectQuery) Except ¶
func (sq *SelectQuery) Except(other *SelectQuery) *SelectQuery
Except combines queries using EXCEPT (rows in first but not second).
Database support: PostgreSQL 9.1+, MySQL 8.0.31+, SQLite 3.25+
Example:
q1 := db.Builder().Select("id").From("all_users")
q2 := db.Builder().Select("user_id").From("banned_users")
q1.Except(q2).All(&activeUsers)
func (*SelectQuery) From ¶
func (sq *SelectQuery) From(table string) *SelectQuery
From specifies the table to select from.
Supports table aliases: From("users u")
Example:
db.Builder().Select("*").From("users").All(&users)
func (*SelectQuery) FromSelect ¶
func (sq *SelectQuery) FromSelect(subquery *SelectQuery, alias string) *SelectQuery
FromSelect specifies a subquery as the FROM source.
The alias parameter is required for the subquery.
Example:
sub := db.Builder().Select("user_id", "COUNT(*) as cnt").
From("orders").GroupBy("user_id")
db.Builder().Select("*").FromSelect(sub, "order_counts").
Where("cnt > ?", 10).All(&results)
func (*SelectQuery) FullJoin ¶
func (sq *SelectQuery) FullJoin(table string, on interface{}) *SelectQuery
FullJoin adds a FULL OUTER JOIN clause.
Note: Not supported by MySQL.
Example:
db.Builder().Select("u.name", "o.total").
From("users u").
FullJoin("orders o", "o.user_id = u.id").
All(&results)
func (*SelectQuery) GroupBy ¶
func (sq *SelectQuery) GroupBy(columns ...string) *SelectQuery
GroupBy adds GROUP BY clause.
Multiple columns supported. Multiple GroupBy() calls are additive.
Example:
GroupBy("user_id", "status")
func (*SelectQuery) Having ¶
func (sq *SelectQuery) Having(condition interface{}, args ...interface{}) *SelectQuery
Having adds HAVING clause (WHERE for aggregates).
Accepts string or Expression. Multiple calls are combined with AND.
Example:
Having("COUNT(*) > ?", 100)
func (*SelectQuery) InnerJoin ¶
func (sq *SelectQuery) InnerJoin(table string, on interface{}) *SelectQuery
InnerJoin adds an INNER JOIN clause.
Example:
db.Builder().Select("u.name", "o.total").
From("users u").
InnerJoin("orders o", "o.user_id = u.id").
All(&results)
func (*SelectQuery) Intersect ¶
func (sq *SelectQuery) Intersect(other *SelectQuery) *SelectQuery
Intersect combines queries using INTERSECT (rows in both).
Database support: PostgreSQL 9.1+, MySQL 8.0.31+, SQLite 3.25+
Example:
q1 := db.Builder().Select("id").From("users")
q2 := db.Builder().Select("user_id").From("orders")
q1.Intersect(q2).All(&ids) // Users who have placed orders
func (*SelectQuery) LeftJoin ¶
func (sq *SelectQuery) LeftJoin(table string, on interface{}) *SelectQuery
LeftJoin adds a LEFT JOIN clause.
Example:
db.Builder().Select("u.name", "o.total").
From("users u").
LeftJoin("orders o", "o.user_id = u.id").
All(&results)
func (*SelectQuery) Limit ¶
func (sq *SelectQuery) Limit(limit int64) *SelectQuery
Limit sets the LIMIT clause.
Example:
Limit(100) // Return at most 100 rows
func (*SelectQuery) Offset ¶
func (sq *SelectQuery) Offset(offset int64) *SelectQuery
Offset sets the OFFSET clause.
Example:
Offset(200) // Skip first 200 rows
func (*SelectQuery) One ¶
func (sq *SelectQuery) One(dest interface{}) error
One scans a single row into dest.
Returns sql.ErrNoRows if no row is found.
Example:
var user User
err := db.Builder().Select("*").From("users").
Where("id = ?", 123).One(&user)
func (*SelectQuery) OrderBy ¶
func (sq *SelectQuery) OrderBy(columns ...string) *SelectQuery
OrderBy adds ORDER BY clause with optional direction (ASC/DESC).
Supports multiple columns. Multiple OrderBy() calls are additive.
Example:
OrderBy("age DESC", "name ASC")
func (*SelectQuery) RightJoin ¶
func (sq *SelectQuery) RightJoin(table string, on interface{}) *SelectQuery
RightJoin adds a RIGHT JOIN clause.
Example:
db.Builder().Select("u.name", "o.total").
From("users u").
RightJoin("orders o", "o.user_id = u.id").
All(&results)
func (*SelectQuery) SelectExpr ¶
func (sq *SelectQuery) SelectExpr(expr string, args ...interface{}) *SelectQuery
SelectExpr adds a raw SQL expression to the SELECT clause.
Useful for scalar subqueries, window functions, or complex expressions.
Example:
db.Builder().Select("id", "name").
SelectExpr("(SELECT COUNT(*) FROM orders WHERE orders.user_id = users.id)", "order_count").
From("users").All(&results)
func (*SelectQuery) Union ¶
func (sq *SelectQuery) Union(other *SelectQuery) *SelectQuery
Union combines this query with another using UNION (removes duplicates).
Example:
q1 := db.Builder().Select("name").From("users")
q2 := db.Builder().Select("name").From("archived_users")
q1.Union(q2).All(&names)
func (*SelectQuery) UnionAll ¶
func (sq *SelectQuery) UnionAll(other *SelectQuery) *SelectQuery
UnionAll combines this query with another using UNION ALL (keeps duplicates).
Example:
q1 := db.Builder().Select("id").From("orders_2023")
q2 := db.Builder().Select("id").From("orders_2024")
q1.UnionAll(q2).All(&orderIDs)
func (*SelectQuery) Unwrap ¶
func (sq *SelectQuery) Unwrap() *core.SelectQuery
Unwrap returns the underlying core.SelectQuery for advanced use cases.
This method is provided for edge cases where direct access to internal types is needed. Most users should not need this.
func (*SelectQuery) Where ¶
func (sq *SelectQuery) Where(condition interface{}, params ...interface{}) *SelectQuery
Where adds a WHERE condition.
Accepts either a string with placeholders or an Expression. Multiple Where() calls are combined with AND.
String example:
Where("status = ? AND age > ?", 1, 18)
Expression example:
Where(relica.And(
relica.Eq("status", 1),
relica.GreaterThan("age", 18),
))
func (*SelectQuery) With ¶
func (sq *SelectQuery) With(name string, query *SelectQuery) *SelectQuery
With adds a Common Table Expression (CTE).
Example:
cte := db.Builder().Select("user_id", "SUM(total) as total").
From("orders").GroupBy("user_id")
db.Builder().Select("*").With("order_totals", cte).
From("order_totals").Where("total > ?", 1000).All(&users)
func (*SelectQuery) WithContext ¶
func (sq *SelectQuery) WithContext(ctx context.Context) *SelectQuery
WithContext sets the context for this SELECT query.
This overrides any context set on the QueryBuilder.
Example:
sq.WithContext(ctx).All(&users)
func (*SelectQuery) WithRecursive ¶
func (sq *SelectQuery) WithRecursive(name string, query *SelectQuery) *SelectQuery
WithRecursive adds a recursive Common Table Expression.
The query MUST use UNION or UNION ALL. Database support: PostgreSQL (all), MySQL 8.0+, SQLite 3.25+
Example:
anchor := db.Builder().Select("id", "name", "manager_id", "1 as level").
From("employees").Where("manager_id IS NULL")
recursive := db.Builder().Select("e.id", "e.name", "e.manager_id", "h.level + 1").
From("employees e").InnerJoin("hierarchy h", "e.manager_id = h.id")
cte := anchor.UnionAll(recursive)
db.Builder().Select("*").WithRecursive("hierarchy", cte).
From("hierarchy").OrderBy("level", "name").All(&employees)
type Tx ¶
type Tx struct {
// contains filtered or unexported fields
}
Tx represents a database transaction.
Transactions provide ACID guarantees and support all standard isolation levels. All queries executed through a transaction's builder automatically participate in that transaction.
Example:
tx, err := db.Begin(ctx)
if err != nil {
return err
}
defer tx.Rollback() // Safe to call even after Commit
_, err = tx.Builder().Insert("users", data).Execute()
if err != nil {
return err
}
return tx.Commit()
func (*Tx) Builder ¶
func (t *Tx) Builder() *QueryBuilder
Builder returns the query builder for this transaction.
All queries built using this builder will execute within the transaction. The builder automatically inherits the transaction's context.
Example:
tx.Builder().Insert("users", data).Execute()
func (*Tx) Commit ¶
Commit commits the transaction.
After calling Commit, the transaction cannot be used for further queries.
Example:
if err := tx.Commit(); err != nil {
return err
}
type TxOptions ¶
TxOptions represents transaction options including isolation level.
Example:
opts := &relica.TxOptions{
Isolation: sql.LevelSerializable,
ReadOnly: true,
}
tx, err := db.BeginTx(ctx, opts)
type UpdateQuery ¶
type UpdateQuery struct {
// contains filtered or unexported fields
}
UpdateQuery represents an UPDATE query being built.
func (*UpdateQuery) Build ¶
func (uq *UpdateQuery) Build() *Query
Build constructs the Query object.
func (*UpdateQuery) Execute ¶
func (uq *UpdateQuery) Execute() (sql.Result, error)
Execute executes the UPDATE query.
func (*UpdateQuery) Set ¶
func (uq *UpdateQuery) Set(values map[string]interface{}) *UpdateQuery
Set specifies the columns and values to update.
Example:
Update("users").Set(map[string]interface{}{"status": 2})
func (*UpdateQuery) Where ¶
func (uq *UpdateQuery) Where(condition interface{}, params ...interface{}) *UpdateQuery
Where adds a WHERE condition to the UPDATE query.
Example:
Update("users").Set(...).Where("id = ?", 123)
func (*UpdateQuery) WithContext ¶
func (uq *UpdateQuery) WithContext(ctx context.Context) *UpdateQuery
WithContext sets the context for this UPDATE query.
type UpsertQuery ¶
type UpsertQuery struct {
// contains filtered or unexported fields
}
UpsertQuery represents an UPSERT query being built.
func (*UpsertQuery) Build ¶
func (uq *UpsertQuery) Build() *Query
Build constructs the Query object.
func (*UpsertQuery) DoNothing ¶
func (uq *UpsertQuery) DoNothing() *UpsertQuery
DoNothing ignores conflicts (no update).
Example:
Upsert(...).OnConflict("id").DoNothing()
func (*UpsertQuery) DoUpdate ¶
func (uq *UpsertQuery) DoUpdate(columns ...string) *UpsertQuery
DoUpdate specifies which columns to update on conflict.
Example:
Upsert(...).OnConflict("id").DoUpdate("name", "email")
func (*UpsertQuery) Execute ¶
func (uq *UpsertQuery) Execute() (sql.Result, error)
Execute executes the UPSERT query.
func (*UpsertQuery) OnConflict ¶
func (uq *UpsertQuery) OnConflict(columns ...string) *UpsertQuery
OnConflict specifies the columns that determine a conflict.
Example:
Upsert(...).OnConflict("id", "email")
func (*UpsertQuery) WithContext ¶
func (uq *UpsertQuery) WithContext(ctx context.Context) *UpsertQuery
WithContext sets the context for this UPSERT query.
Directories
¶
| Path | Synopsis |
|---|---|
|
examples
module
|
|
|
internal
|
|
|
cache
Package cache provides caching utilities for database prepared statements.
|
Package cache provides caching utilities for database prepared statements. |
|
core
Package core provides the core database functionality including connection management, query building, statement caching, and result scanning for Relica.
|
Package core provides the core database functionality including connection management, query building, statement caching, and result scanning for Relica. |
|
dialects
Package dialects provides database-specific SQL dialect implementations for PostgreSQL, MySQL, and SQLite, handling identifier quoting, placeholders, and UPSERT operations.
|
Package dialects provides database-specific SQL dialect implementations for PostgreSQL, MySQL, and SQLite, handling identifier quoting, placeholders, and UPSERT operations. |
|
util
Package util provides utility functions for context handling, string sanitization, and reflection helpers used throughout the Relica library.
|
Package util provides utility functions for context handling, string sanitization, and reflection helpers used throughout the Relica library. |