psql

package module
v1.15.1 Latest Latest
Warning

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

Go to latest
Published: Sep 18, 2026 License: MIT Imports: 16 Imported by: 2

README

psql

Go Reference

Package psql provides a PostgreSQL ORM-like query builder for Go.

Features

  • Model-based CRUD - Map Go structs to PostgreSQL tables with automatic column inference
  • JSONB support - Store multiple fields in a single JSONB column
  • Mass assignment protection - Safely filter user input with Permit and Filter
  • Schema generation - Generate CREATE TABLE statements from struct definitions
  • Multiple drivers - Works with pq, pgx, and go-pg at runtime
  • Query builder - Fluent API for SELECT, INSERT, UPDATE, DELETE with JOIN, CTE, and more

Installation

go get github.com/gopsql/psql

Quick Start

package main

import (
    "github.com/gopsql/psql"
    "github.com/gopsql/pq"
)

type User struct {
    Id        int
    Name      string
    Email     string
    CreatedAt time.Time
}

func main() {
    // Connect to database
    conn := pq.MustOpen("postgres://localhost:5432/mydb?sslmode=disable")
    defer conn.Close()

    // Create model
    users := psql.NewModel(User{}, conn)

    // Insert
    var id int
    users.Insert("Name", "Alice", "Email", "alice@example.com").
        Returning("id").MustQueryRow(&id)

    // Select
    var user User
    users.Find().Where("id = $1", id).MustQuery(&user)

    // Update
    users.Update("Name", "Bob").Where("id = $1", id).MustExecute()

    // Delete
    users.Delete().Where("id = $1", id).MustExecute()
}

Database Drivers

Choose one of three PostgreSQL drivers:

import (
    "github.com/gopsql/pq"    // github.com/lib/pq
    "github.com/gopsql/pgx"   // github.com/jackc/pgx
    "github.com/gopsql/gopg"  // github.com/go-pg/pg
)

// Using pgx (recommended for new projects)
conn := pgx.MustOpen("postgres://localhost:5432/mydb?sslmode=disable")

// Using go-pg
conn := gopg.MustOpen("postgres://localhost:5432/mydb?sslmode=disable")

// Using lib/pq
conn := pq.MustOpen("postgres://localhost:5432/mydb?sslmode=disable")

For minimal dependencies with lib/pq:

import (
    "database/sql"
    "github.com/gopsql/standard"
    _ "github.com/lib/pq"
)

db, _ := sql.Open("postgres", "postgres://localhost:5432/mydb?sslmode=disable")
conn := standard.NewDB("postgres", db)

Usage Examples

Schema Generation
type Post struct {
    Id        int
    Title     string
    Views     int    `dataType:"bigint DEFAULT 0"`
    CreatedAt time.Time
}

posts := psql.NewModel(Post{}, conn)
fmt.Println(posts.Schema())
// CREATE TABLE posts (
//     id SERIAL PRIMARY KEY,
//     title text DEFAULT ''::text NOT NULL,
//     views bigint DEFAULT 0,
//     created_at timestamptz DEFAULT NOW() NOT NULL
// );
JSONB Fields
type Product struct {
    Id       int
    Name     string
    Price    int    `jsonb:"metadata"`
    Currency string `jsonb:"metadata"`
}

// Price and Currency are stored in a single "metadata" JSONB column
Mass Assignment Protection
// Only allow Name and Email from user input
changes := users.Permit("Name", "Email").Filter(requestBody)
users.Insert(changes).MustExecute()

// Or with echo/gin style binding
changes, _ := users.Permit("Name", "Email").Bind(c, &user)
Query Results
// Into a slice
var userList []User
users.Find().MustQuery(&userList)

// Into a map
var id2name map[int]string
users.Select("id", "name").MustQuery(&id2name)

// Grouped results
var byDept map[int][]User
users.Select("department_id", "id", "name", "email").MustQuery(&byDept)
Transactions
users.MustTransaction(func(ctx context.Context, tx db.Tx) error {
    users.Insert("Name", "Alice").MustExecuteCtxTx(ctx, tx)
    users.Insert("Name", "Bob").MustExecuteCtxTx(ctx, tx)
    return nil // commit; return error to rollback
})
Raw SQL Expressions
// Increment a counter
users.Update("Views", psql.String("Views + 1")).Where("id = $1", 1).MustExecute()

// With parameters
users.Update("Views", psql.StringWithArg("Views + $?", 10)).Where("id = $1", 1).MustExecute()
Common Confusions
QueryRow vs Query
Method Purpose Arguments Use Case
QueryRow Scan single row into individual variables Multiple pointers (one per column) Simple values: &name, &id
Query Scan results into struct, slice, or map Single pointer to composite type Full struct: &user or &users
// QueryRow - pass individual pointers for each column
var name string
var id int
users.Select("name", "id").Where("id = $1", 1).MustQueryRow(&name, &id)

// Query - pass a single pointer to struct (columns auto-map to fields)
var user User
users.Find().Where("id = $1", 1).MustQuery(&user)

// Query - also works with slices and maps
var userList []User
users.Find().MustQuery(&userList)
Where vs WHERE
Method Purpose Column Names Flexibility
Where Raw SQL condition with placeholders Use exact column names Full SQL expression support
WHERE Structured field/operator/value tuples Auto-converts field names Simple comparisons only
// Where - raw SQL condition, use $1/$2 or $? placeholders
users.Find().Where("id = $1", id)
users.Find().Where("name ILIKE $? OR email ILIKE $?", "%john%", "%john%")

// WHERE - structured tuples: (field, operator, value) repeated
users.Find().WHERE("Id", "=", id)
users.Find().WHERE("Status", "=", "active", "Age", ">=", 18)

Benchmarks

Benchmark results for Insert, Update, and Select operations (100 rows each) compared to native driver usage. Benchmarked on Apple M1 Pro MacBook Pro. Run benchmarks with:

cd tests && GENERATE=1 go test -v ./benchmark_test.go

For more information, see Benchmark.

Documentation

Full documentation is available at pkg.go.dev.

For more examples, see examples_test.go.

License

MIT

Documentation

Overview

Package psql provides a PostgreSQL ORM-like query builder for Go.

Overview

Package psql maps Go structs to PostgreSQL tables and provides fluent APIs for building and executing SELECT, INSERT, UPDATE, and DELETE queries. It supports multiple PostgreSQL drivers (pq, pgx, go-pg) and can be switched at runtime.

Key features include:

  • Model-based CRUD operations with automatic column name inference
  • JSONB column support for storing multiple fields in a single column
  • Mass assignment protection via Permit and Filter
  • Query results scanning into structs, slices, and maps
  • Transaction support with context
  • Schema generation from struct definitions

Basic Usage

Create a model from a struct and perform CRUD operations:

type User struct {
	Id        int
	Name      string
	Email     string
	CreatedAt time.Time
}

// Initialize model with database connection
users := psql.NewModel(User{}, conn)

// Insert a record
var id int
users.Insert("Name", "Alice", "Email", "alice@example.com").
	Returning("id").MustQueryRow(&id)

// Find records
var user User
users.Find().Where("id = $1", id).MustQuery(&user)

// Update a record
users.Update("Name", "Bob").Where("id = $1", id).MustExecute()

// Delete a record
users.Delete().Where("id = $1", id).MustExecute()

Table and Column Naming

Table names are derived from the struct name and converted to plural form by default (e.g., User becomes users). You can customize this by:

  • Adding a __TABLE_NAME__ field with a tag specifying the table name
  • Implementing a TableName() string method on the struct
  • Setting DefaultTableNamer to a custom function

Column names are derived from struct field names. Customize with:

  • The "column" struct tag
  • SetColumnNamer for model-specific naming
  • DefaultColumnNamer for global naming

JSONB Support

Store multiple struct fields in a single JSONB column using the "jsonb" tag:

type Product struct {
	Id       int
	Name     string
	Price    int    `jsonb:"metadata"`  // stored in metadata column
	Currency string `jsonb:"metadata"`  // stored in metadata column
}

The JSONB column (metadata) is automatically created with appropriate defaults. When querying, JSONB fields are automatically unmarshaled into their struct fields.

Mass Assignment Protection

Use Permit and Filter to safely handle user input, similar to Rails strong parameters:

// Only allow Name and Email to be set from user input
changes := users.Permit("Name", "Email").Filter(userInput)
users.Insert(changes).MustExecute()

Filter accepts multiple input types: map[string]interface{}, JSON strings, []byte, io.Reader, or structs.

Query Results

Query results can be scanned into various target types:

// Single struct
var user User
users.Find().Where("id = $1", 1).MustQuery(&user)

// Slice of structs
var userList []User
users.Find().MustQuery(&userList)

// Slice of single values
var ids []int
users.Select("id").MustQuery(&ids)

// Map for key-value pairs
var id2name map[int]string
users.Select("id", "name").MustQuery(&id2name)

// Map with struct keys/values for grouping
var byDept map[int][]User
users.Select("department_id", "id", "name").MustQuery(&byDept)

Method Comparison

Some methods have similar names but different purposes:

QueryRow vs Query:

  • QueryRow(dest ...interface{}) scans a single row into individual pointers, one for each column. Use when you need specific column values.
  • Query(target interface{}) scans results into a struct, slice, or map. Columns are auto-mapped to struct fields by name.

Example:

// QueryRow - individual pointers for each column
var name string
var id int
users.Select("name", "id").Where("id = $1", 1).MustQueryRow(&name, &id)

// Query - single pointer to struct (auto-maps columns to fields)
var user User
users.Find().Where("id = $1", 1).MustQuery(&user)

Where vs WHERE:

  • Where(condition string, args ...) takes a raw SQL condition with $1, $2 or $? placeholders. Full SQL expression flexibility.
  • WHERE(args ...) takes field/operator/value tuples (3 args per condition). Field names are auto-converted to column names.

Example:

// Where - raw SQL condition string
users.Find().Where("id = $1", id)
users.Find().Where("name ILIKE $1 OR email ILIKE $1", "%john%")

// WHERE - structured tuples: (field, operator, value)
users.Find().WHERE("Id", "=", id)
users.Find().WHERE("Status", "=", "active", "Age", ">=", 18)

Schema Generation

Generate CREATE TABLE statements from struct definitions:

fmt.Println(users.Schema())
// CREATE TABLE users (
//     id SERIAL PRIMARY KEY,
//     name text DEFAULT ''::text NOT NULL,
//     email text DEFAULT ''::text NOT NULL,
//     created_at timestamptz DEFAULT NOW() NOT NULL
// );

Use the "dataType" tag to customize PostgreSQL data types:

type User struct {
	Id    int
	Score float64 `dataType:"numeric(10, 4)"`
}

Transactions

Execute multiple operations in a transaction:

users.MustTransaction(func(ctx context.Context, tx db.Tx) error {
	users.Insert("Name", "Alice").MustExecuteCtxTx(ctx, tx)
	users.Insert("Name", "Bob").MustExecuteCtxTx(ctx, tx)
	return nil // commit; return error to rollback
})

Database Drivers

Package psql supports multiple PostgreSQL drivers through the db.DB interface:

  • github.com/lib/pq via github.com/gopsql/pq
  • github.com/jackc/pgx via github.com/gopsql/pgx
  • github.com/go-pg/pg via github.com/gopsql/gopg

For minimal dependencies, use database/sql with lib/pq:

import (
	"database/sql"
	"github.com/gopsql/standard"
	_ "github.com/lib/pq"
)

db, _ := sql.Open("postgres", connStr)
conn := standard.NewDB("postgres", db)
users := psql.NewModel(User{}, conn)

Index

Constants

This section is empty.

Variables

View Source
var (
	// ErrInvalidTarget is returned when Query receives a target that is not a
	// pointer to a struct, slice, or map.
	ErrInvalidTarget = errors.New("target must be pointer of a struct, slice or map")

	// ErrNoConnection is returned when attempting to execute a query without
	// a database connection set on the Model.
	ErrNoConnection = errors.New("no connection")

	// ErrNoSQL is returned when Execute is called with an empty SQL statement.
	ErrNoSQL = errors.New("no sql statements to execute")

	// ErrTypeAssertionFailed is returned when scanning a JSONB value fails
	// due to an unexpected source type.
	ErrTypeAssertionFailed = errors.New("type assertion failed")

	// ErrUnsupportedExplainTarget is returned when Explain is called with a
	// target type that is not supported (*string, io.Writer, logger.Logger,
	// func(string), or func(...interface{})).
	ErrUnsupportedExplainTarget = errors.New("unsupported explain target type")
)
View Source
var (
	// DefaultColumnNamer is the default function for transforming struct field
	// names to database column names. If nil (the default), field names are
	// used as-is. Set to ToUnderscore for snake_case column names.
	DefaultColumnNamer func(string) string = nil

	// DefaultTableNamer is the default function for transforming struct names
	// to database table names. Defaults to ToPlural, which converts "User" to
	// "Users". Set to ToPluralUnderscore for snake_case table names.
	DefaultTableNamer func(string) string = ToPlural
)
View Source
var AddTableName fieldsFunc = func(fields []string, tableName string) (out []string) {
	for _, field := range fields {
		if strings.Contains(field, ".") {
			out = append(out, field)
			continue
		}
		out = append(out, tableName+"."+field)
	}
	return
}

AddTableName is a helper function that prefixes field names with the table name. It can be passed to Find to disambiguate columns in JOIN queries. Fields that already contain a dot are left unchanged.

View Source
var (
	// ErrMustBePointer is returned when a function expects a pointer argument
	// but receives a non-pointer value.
	ErrMustBePointer = errors.New("must be pointer")
)

Functions

func FieldDataType added in v1.7.0

func FieldDataType(fieldName, fieldType string) (dataType string)

FieldDataType generates a PostgreSQL data type definition from a Go field name and type. This is the default implementation used by Schema. Fields named "id" with integer types become SERIAL PRIMARY KEY. Pointer types are nullable; non-pointer types include NOT NULL. To customize type mapping, implement FieldDataType on your database connection type.

func StringWithArg added in v1.12.2

func StringWithArg(str string, arg interface{}) stringWithArg

StringWithArg creates a raw SQL expression with a parameter placeholder. The $? in the string will be replaced with the proper positional parameter.

users.Update("views", psql.StringWithArg("views + $?", 1))
// UPDATE users SET views = views + $1

func ToPlural added in v1.8.0

func ToPlural(in string) string

ToPlural converts a word to its plural form using simple English rules: words ending in "y" become "ies", words ending in "s" or "o" add "es", and other words add "s". For example, "Product" becomes "Products".

func ToPluralUnderscore added in v1.8.0

func ToPluralUnderscore(in string) string

ToPluralUnderscore converts a CamelCase word to plural snake_case form. For example, "PostComment" becomes "post_comments".

func ToTableName

func ToTableName(object interface{}) (name string)

ToTableName extracts the database table name from a struct. The name is determined in order of priority:

  1. Return value of TableName() method if implemented
  2. Tag value of __TABLE_NAME__ field if present
  3. Struct name transformed by DefaultTableNamer

Returns "error_no_table_name" for anonymous structs without explicit naming.

func ToUnderscore added in v1.8.0

func ToUnderscore(str string) string

ToUnderscore converts a CamelCase string to snake_case. For example, "FullName" becomes "full_name". Numbers are not treated as word separators.

Types

type Changes

type Changes map[Field]interface{}

Changes maps Field definitions to their values. It is the output of Filter and the input to Insert and Update operations.

func (Changes) MarshalJSON

func (c Changes) MarshalJSON() ([]byte, error)

func (Changes) String

func (c Changes) String() string

type DeleteSQL added in v1.3.0

type DeleteSQL struct {
	*SQL
	// contains filtered or unexported fields
}

DeleteSQL represents a DELETE statement builder. Create instances using Model.Delete or SQL.AsDelete.

func (*DeleteSQL) Explain added in v1.14.0

func (s *DeleteSQL) Explain(target interface{}, options ...string) *DeleteSQL

Explain sets up EXPLAIN output collection. When Query, QueryRow, or Execute is called, an EXPLAIN statement will be executed first and the result will be written to the target. Target can be *string, io.Writer, logger.Logger, func(string), or func(...interface{}) (e.g. log.Println). Options can include ANALYZE, VERBOSE, BUFFERS, COSTS, TIMING, FORMAT JSON, etc.

func (*DeleteSQL) ExplainAnalyze added in v1.14.0

func (s *DeleteSQL) ExplainAnalyze(target interface{}, options ...string) *DeleteSQL

ExplainAnalyze is a shorthand for Explain(target, "ANALYZE", ...). Target can be *string, io.Writer, logger.Logger, func(string), or func(...interface{}). Note: The ANALYZE option causes the statement to be actually executed, not just planned. The DELETE will actually remove data from the table.

func (*DeleteSQL) Returning added in v1.3.0

func (s *DeleteSQL) Returning(expressions ...string) *DeleteSQL

Returning adds a RETURNING clause to retrieve values from deleted rows.

func (*DeleteSQL) String added in v1.3.0

func (s *DeleteSQL) String() string

func (*DeleteSQL) StringValues added in v1.13.0

func (s *DeleteSQL) StringValues() (string, []interface{})

func (*DeleteSQL) Tap added in v1.5.0

func (s *DeleteSQL) Tap(funcs ...func(*DeleteSQL) *DeleteSQL) *DeleteSQL

Tap applies transformation functions to this DeleteSQL, enabling custom method chaining.

func (*DeleteSQL) Using added in v1.3.0

func (s *DeleteSQL) Using(list ...string) *DeleteSQL

Using adds a USING clause for DELETE with joins.

func (*DeleteSQL) WHERE added in v1.9.0

func (s *DeleteSQL) WHERE(args ...interface{}) *DeleteSQL

WHERE adds conditions from field/operator/value tuples. Each tuple consists of three consecutive arguments: field name, operator, and value.

func (*DeleteSQL) Where added in v1.3.0

func (s *DeleteSQL) Where(condition string, args ...interface{}) *DeleteSQL

Where adds a WHERE condition to the DELETE statement. Use $1, $2 for positional parameters, or $? which is auto-replaced when a single argument is provided.

type Field

type Field struct {
	Name       string // Name is the struct field name.
	ColumnName string // ColumnName is the database column name (or JSONB key).
	ColumnType string // ColumnType is the Go type as a string (e.g., "int", "string").
	JsonName   string // JsonName is the key name used in JSON input/output.
	Jsonb      string // Jsonb is the JSONB column name if this field is stored in JSONB.
	DataType   string // DataType is the PostgreSQL data type from the dataType tag.
	Exported   bool   // Exported is true if the struct field is exported (capitalized).
	Strict     bool   // Strict enables JSON unmarshal error reporting for JSONB fields.
	Parent     string // Parent is the parent struct path for anonymous/embedded fields.
}

Field represents a mapping between a struct field and a database column.

type InsertSQL added in v1.3.0

type InsertSQL struct {
	*SQL
	// contains filtered or unexported fields
}

InsertSQL represents an INSERT statement builder. Create instances using Model.Insert or SQL.AsInsert.

func (*InsertSQL) DoNothing added in v1.3.0

func (s *InsertSQL) DoNothing() *InsertSQL

DoNothing adds ON CONFLICT DO NOTHING, ignoring rows that conflict. Must be used after OnConflict.

func (*InsertSQL) DoUpdate added in v1.3.0

func (s *InsertSQL) DoUpdate(expressions ...string) *InsertSQL

DoUpdate adds ON CONFLICT DO UPDATE SET with custom expressions. Must be used after OnConflict.

func (*InsertSQL) DoUpdateAll added in v1.3.0

func (s *InsertSQL) DoUpdateAll() *InsertSQL

DoUpdateAll adds ON CONFLICT DO UPDATE SET for all inserted fields. Must be used after OnConflict.

func (*InsertSQL) DoUpdateAllExcept added in v1.10.3

func (s *InsertSQL) DoUpdateAllExcept(fields ...string) *InsertSQL

DoUpdateAllExcept is like DoUpdateAll but excludes specified fields from the update.

func (*InsertSQL) Explain added in v1.14.0

func (s *InsertSQL) Explain(target interface{}, options ...string) *InsertSQL

Explain sets up EXPLAIN output collection. When Query, QueryRow, or Execute is called, an EXPLAIN statement will be executed first and the result will be written to the target. Target can be *string, io.Writer, logger.Logger, func(string), or func(...interface{}) (e.g. log.Println). Options can include ANALYZE, VERBOSE, BUFFERS, COSTS, TIMING, FORMAT JSON, etc.

func (*InsertSQL) ExplainAnalyze added in v1.14.0

func (s *InsertSQL) ExplainAnalyze(target interface{}, options ...string) *InsertSQL

ExplainAnalyze is a shorthand for Explain(target, "ANALYZE", ...). Target can be *string, io.Writer, logger.Logger, func(string), or func(...interface{}). Note: The ANALYZE option causes the statement to be actually executed, not just planned. The INSERT will actually insert data into the table.

func (*InsertSQL) OnConflict added in v1.3.0

func (s *InsertSQL) OnConflict(targets ...string) *InsertSQL

OnConflict specifies conflict target columns for upsert operations. Use with DoNothing, DoUpdate, or DoUpdateAll.

func (*InsertSQL) Returning added in v1.3.0

func (s *InsertSQL) Returning(expressions ...string) *InsertSQL

Returning adds a RETURNING clause to retrieve values from inserted rows.

func (InsertSQL) String added in v1.3.0

func (s InsertSQL) String() string

func (*InsertSQL) StringValues added in v1.13.0

func (s *InsertSQL) StringValues() (string, []interface{})

func (*InsertSQL) Tap added in v1.5.0

func (s *InsertSQL) Tap(funcs ...func(*InsertSQL) *InsertSQL) *InsertSQL

Tap applies transformation functions to this InsertSQL, enabling custom method chaining.

type Model

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

Model represents a database table mapped from a Go struct.

Table names are inferred from the struct name and converted to plural form by default (e.g., User becomes users). To customize the table name:

  • Define a __TABLE_NAME__ field with the table name as its tag value
  • Implement a TableName() string method on the struct

Column names are inferred from struct field names. To customize:

  • Use the "column" struct tag for individual fields
  • Call SetColumnNamer to set a naming function for all fields

func NewModel

func NewModel(object interface{}, options ...interface{}) (m *Model)

NewModel creates a new Model from a struct. The struct defines the table schema, with field names mapped to column names. Options can include a db.DB connection and/or a logger.Logger for query logging. See SetOptions for details on available options.

func NewModelTable

func NewModelTable(tableName string, options ...interface{}) (m *Model)

NewModelTable creates a new Model with only a table name, without struct field mappings. This is useful for operations that don't require field information, such as counting rows or executing raw SQL:

psql.NewModelTable("users", conn).MustCount()

Options can include a db.DB connection and/or a logger.Logger.

func (Model) AddTableName added in v1.12.0

func (m Model) AddTableName(fields ...string) []string

AddTableName prefixes each field name with the table name (e.g., "id" becomes "tablename.id"). This is useful for queries involving multiple tables to avoid column name ambiguity.

func (Model) Assign

func (m Model) Assign(target interface{}, lotsOfChanges ...interface{}) (out []interface{}, err error)

Assign applies changes to a target struct. This is useful when you need to validate the struct before inserting or updating. The target must be a pointer to a struct. Returns the changes as a slice suitable for passing to Insert or Update.

func create(c echo.Context) error {
	var user models.User
	m := psql.NewModel(user, conn)
	changes := m.MustAssign(
		&user,
		m.Permit("Name").Filter(c.Request().Body),
	)
	if err := c.Validate(user); err != nil {
		panic(err)
	}
	var id int
	m.Insert(changes...).Returning("id").MustQueryRow(&id)
	// ...
}

func (Model) Changes

func (m Model) Changes(in RawChanges) (out Changes)

Changes converts RawChanges to Changes using JSON tag names as keys. Use FieldChanges if your keys are struct field names instead.

changes := users.Changes(map[string]interface{}{
	"name": "Alice",  // matches `json:"name"` tag
})

func (*Model) Clone added in v1.2.2

func (m *Model) Clone() *Model

Clone returns a copy of the model.

func (Model) ColumnDataTypes added in v1.4.0

func (m Model) ColumnDataTypes() map[string]string

ColumnDataTypes returns a map of column names to their PostgreSQL data type definitions. This is used by Schema to generate CREATE TABLE statements.

func (Model) Columns added in v1.4.0

func (m Model) Columns() []string

Columns returns all database column names for this Model, including JSONB columns but excluding fields stored within JSONB columns.

func (*Model) Connection added in v1.0.1

func (m *Model) Connection() db.DB

Connection returns the database connection for this Model.

func (Model) Count

func (m Model) Count(optional ...string) (count int, err error)

Count executes a SELECT COUNT(*) query and returns the number of rows matching any WHERE conditions set on the Model. Pass a custom expression for different counting, e.g., Count("COUNT(DISTINCT author_id)").

func (Model) CountCtxTx added in v1.15.0

func (m Model) CountCtxTx(ctx context.Context, tx Tx, optional ...string) (count int, err error)

CountCtxTx is like Count but accepts a context and optional transaction.

func (Model) CreatedAt

func (m Model) CreatedAt() Changes

CreatedAt returns Changes setting the CreatedAt field to the current UTC time.

func (Model) Delete

func (m Model) Delete() *DeleteSQL

Delete creates a DELETE statement. Use Where to specify which rows to delete.

// Delete with condition
users.Delete().Where("id = $1", 1).MustExecute()

// Delete with RETURNING clause
var ids []int
users.Delete().Where("status = $1", "inactive").Returning("id").MustQuery(&ids)

func (Model) DropSchema

func (m Model) DropSchema() string

DropSchema generates a DROP TABLE IF EXISTS SQL statement for this Model's table. If the struct implements DropSchema() string, that method is called instead.

func (Model) Exists

func (m Model) Exists() (exists bool, err error)

Exists executes a SELECT 1 query and returns true if at least one row matches any WHERE conditions set on the Model, false otherwise.

func (Model) ExistsCtxTx added in v1.15.0

func (m Model) ExistsCtxTx(ctx context.Context, tx Tx) (exists bool, err error)

ExistsCtxTx is like Exists but accepts a context and optional transaction.

func (Model) FieldByName

func (m Model) FieldByName(name string) *Field

FieldByName returns the Field with the given struct field name, or nil if no such field exists.

func (Model) FieldChanges added in v1.1.0

func (m Model) FieldChanges(in RawChanges) (out Changes)

FieldChanges converts RawChanges to Changes using struct field names as keys. Use Changes if your keys are JSON tag names instead.

func (Model) Fields added in v1.12.0

func (m Model) Fields() []string

Fields returns field names of the Model. For JSONB fields, see JSONBFields().

func (Model) Find

func (m Model) Find(options ...interface{}) *SelectSQL

Find creates a SELECT query for all columns defined in the Model's struct. Results are scanned into the same struct type or a slice of that type.

// Query multiple rows into a slice
var users []User
psql.NewModel(User{}, conn).Find().MustQuery(&users)

// Query single row into a struct
var user User
psql.NewModel(User{}, conn).Find().Where("id = $1", 1).MustQuery(&user)

Options can include field transformation functions like AddTableName, which prefixes each column with the table name for use in JOIN queries.

func (Model) From added in v1.13.0

func (m Model) From(items ...string) *SelectSQL

From creates a SELECT query with additional FROM items (tables or subqueries).

func (Model) Insert

func (m Model) Insert(lotsOfChanges ...interface{}) *InsertSQL

Insert creates an INSERT statement with the given field/value changes. Changes can be field name and value pairs, or Changes maps from Filter, Permit, etc.

// Using field/value pairs
users.Insert("Name", "Alice", "Email", "alice@example.com").MustExecute()

// Using Changes from Filter
changes := users.Permit("Name", "Email").Filter(input)
users.Insert(changes).Returning("id").MustQueryRow(&id)

func (Model) JSONBFields added in v1.12.0

func (m Model) JSONBFields() []string

JSONBFields returns JSONB field names of the Model.

func (Model) Join added in v1.3.1

func (m Model) Join(expressions ...string) *SelectSQL

Join creates a SELECT query with JOIN clauses.

func (*Model) Logger added in v1.14.0

func (m *Model) Logger() logger.Logger

Logger returns the logger for this Model, or nil if no logger is set.

func (Model) MustAssign

func (m Model) MustAssign(i interface{}, lotsOfChanges ...interface{}) []interface{}

MustAssign is like Assign but panics if assign operation fails.

func (Model) MustCount

func (m Model) MustCount(optional ...string) int

MustCount is like Count but panics if count operation fails.

func (Model) MustCountCtxTx added in v1.15.0

func (m Model) MustCountCtxTx(ctx context.Context, tx Tx, optional ...string) int

MustCountCtxTx is like CountCtxTx but panics if count operation fails.

func (Model) MustExists

func (m Model) MustExists() bool

MustExists is like Exists but panics if existence check operation fails. Returns true if record exists, false if not exists.

func (Model) MustExistsCtxTx added in v1.15.0

func (m Model) MustExistsCtxTx(ctx context.Context, tx Tx) bool

MustExistsCtxTx is like ExistsCtxTx but panics if existence check operation fails. Returns true if record exists, false if not exists.

func (Model) MustTransaction added in v1.6.0

func (m Model) MustTransaction(block TransactionBlock)

MustTransaction is like Transaction but panics if the transaction fails.

func (Model) MustTransactionCtx added in v1.6.0

func (m Model) MustTransactionCtx(ctx context.Context, block TransactionBlock)

MustTransactionCtx is like TransactionCtx but panics if the transaction fails.

func (Model) New added in v1.10.0

func (m Model) New() reflect.Value

New returns a reflect.Value representing a pointer to a new zero value for model's struct type.

func (Model) NewSQL added in v1.3.0

func (m Model) NewSQL(sql string, values ...interface{}) *SQL

NewSQL creates a new SQL statement with the given query string and parameter values. Use $1, $2, etc. or $? as placeholders for parameters.

func (Model) NewSlice added in v1.10.0

func (m Model) NewSlice() reflect.Value

NewSlice returns a reflect.Value representing a pointer to a new zero-initialized slice value for model's struct type.

func (Model) Permit

func (m Model) Permit(fieldNames ...string) *ModelWithPermittedFields

Permit creates a ModelWithPermittedFields that only allows the specified fields in Filter operations. This provides mass assignment protection similar to Rails strong parameters. If no field names are provided, no fields are permitted.

func (Model) PermitAllExcept

func (m Model) PermitAllExcept(fieldNames ...string) *ModelWithPermittedFields

PermitAllExcept creates a ModelWithPermittedFields that allows all fields except the specified ones in Filter operations. If no field names are provided, all fields are permitted.

func (*Model) Quiet added in v1.2.2

func (m *Model) Quiet() *Model

Quiet returns a copy of the model without logger.

func (Model) Schema

func (m Model) Schema() string

Schema generates a CREATE TABLE SQL statement from the Model's struct definition.

Go types are mapped to PostgreSQL types as follows:

| Go Type                                        | PostgreSQL Data Type |
|------------------------------------------------|----------------------|
| int8 / int16 / int32 / uint8 / uint16 / uint32 | integer              |
| int64 / uint64 / int / uint                    | bigint               |
| time.Time                                      | timestamptz          |
| float32 / float64 / decimal.Decimal            | numeric              |
| bool                                           | boolean              |
| other                                          | text                 |

Use the "dataType" struct tag to specify a custom PostgreSQL data type. Non-pointer fields automatically include "NOT NULL". Set dataType to "-" to exclude a field from schema generation.

The struct may implement BeforeCreateSchema() string to prepend SQL (e.g., CREATE EXTENSION) or AfterCreateSchema() string to append SQL (e.g., CREATE INDEX).

psql.NewModel(struct {
	__TABLE_NAME__ string `users`

	Id        int
	Name      string
	Age       *int
	Numbers   []int
	CreatedAt time.Time
	DeletedAt *time.Time `dataType:"timestamptz"`
	FullName  string     `jsonb:"meta"`
	NickName  string     `jsonb:"meta"`
}{}).Schema()
// CREATE TABLE users (
//         id SERIAL PRIMARY KEY,
//         name text DEFAULT ''::text NOT NULL,
//         age bigint DEFAULT 0,
//         numbers bigint[] DEFAULT '{}' NOT NULL,
//         created_at timestamptz DEFAULT NOW() NOT NULL,
//         deleted_at timestamptz,
//         meta jsonb DEFAULT '{}'::jsonb NOT NULL
// );

func (Model) Select

func (m Model) Select(fields ...string) *SelectSQL

Select creates a SELECT query with the specified columns. Unlike Find, the result can be scanned into various types including slices, maps, and custom structs.

// Query into a slice of single values
var names []string
users.Select("name").OrderBy("id ASC").MustQuery(&names)

// Query into a slice of custom structs
var results []struct{ Name string; ID int }
users.Select("name", "id").MustQuery(&results)

// Query into a map for key-value lookup
var id2name map[int]string
users.Select("id", "name").MustQuery(&id2name)

// Query into a map with slice values for one-to-many grouping
var byCity map[string][]struct{ ID int; Name string }
users.Select("city", "id", "name").MustQuery(&byCity)

func (*Model) SetColumnNamer added in v1.8.0

func (m *Model) SetColumnNamer(namer func(string) string) *Model

SetColumnNamer sets a function to transform struct field names into database column names. The function is applied to all fields when called. Pass nil to use field names as-is.

func (*Model) SetConnection

func (m *Model) SetConnection(db db.DB) *Model

SetConnection sets the database connection for this Model. A connection is required for executing queries; ErrNoConnection is returned from query methods if no connection is set.

func (*Model) SetLogger

func (m *Model) SetLogger(logger logger.Logger) *Model

SetLogger sets the logger for SQL query logging. Use logger.StandardLogger to log to the standard library's log package. By default, no logger is set and SQL statements are not logged. Pass nil to disable logging.

func (*Model) SetOptions

func (m *Model) SetOptions(options ...interface{}) *Model

SetOptions sets database connection (see SetConnection()) and/or logger (see SetLogger()).

func (Model) String

func (m Model) String() string

func (Model) TableName

func (m Model) TableName() string

TableName returns the database table name for this Model.

func (Model) ToColumnName added in v1.8.0

func (mi Model) ToColumnName(in string) string

ToColumnName converts a struct field name to a database column name using the configured column namer function. If no namer is set, returns the input unchanged.

func (Model) Transaction added in v1.6.0

func (m Model) Transaction(block TransactionBlock) error

Transaction executes the block within a database transaction. The transaction is committed if block returns nil; it is rolled back if block returns an error or panics. Uses context.Background internally; use TransactionCtx for custom contexts.

func (Model) TransactionCtx added in v1.6.0

func (m Model) TransactionCtx(ctx context.Context, block TransactionBlock) (err error)

TransactionCtx executes the block within a database transaction with the given context. The transaction is committed if block returns nil; it is rolled back if block returns an error or panics.

users.TransactionCtx(ctx, func(ctx context.Context, tx db.Tx) error {
	users.Insert("Name", "Alice").MustExecuteCtxTx(ctx, tx)
	users.Insert("Name", "Bob").MustExecuteCtxTx(ctx, tx)
	return nil // commit
})

func (Model) TypeName added in v1.2.1

func (m Model) TypeName() string

TypeName returns the Go struct type name for this Model, or an empty string if the Model was created with NewModelTable.

func (Model) Update

func (m Model) Update(lotsOfChanges ...interface{}) *UpdateSQL

Update creates an UPDATE statement with the given field/value changes. Always use Where to specify which rows to update.

// Using field/value pairs
users.Update("Name", "Bob").Where("id = $1", 1).MustExecute()

// Using Changes from Filter with rows affected count
var count int
users.Update(changes).Where("id = $1", 1).MustExecute(&count)

func (Model) UpdatedAt

func (m Model) UpdatedAt() Changes

UpdatedAt returns Changes setting the UpdatedAt field to the current UTC time.

func (Model) WHERE added in v1.9.0

func (m Model) WHERE(args ...interface{}) *SelectSQL

WHERE creates a SELECT query with conditions specified as field/operator/value tuples. Each tuple consists of three consecutive arguments.

// Single condition
users.WHERE("id", "=", 1)

// Multiple conditions (AND)
users.WHERE("status", "=", "active", "age", ">=", 18)

func (Model) WITH added in v1.13.0

func (m Model) WITH(name string, sql *SelectSQL) *SelectSQL

WITH creates a SELECT query with a named CTE from another SelectSQL query.

func (Model) Where added in v1.3.0

func (m Model) Where(condition string, args ...interface{}) *SelectSQL

Where creates a SELECT query with a WHERE condition. Use $1, $2 for positional parameters, or $? which is auto-replaced when a single argument is provided.

func (Model) With added in v1.13.0

func (m Model) With(expression string, args ...interface{}) *SelectSQL

With creates a SELECT query with a CTE (Common Table Expression).

func (*Model) WithoutFields added in v1.8.3

func (m *Model) WithoutFields(fieldNames ...string) *Model

WithoutFields returns a copy of the model without given fields.

type ModelWithPermittedFields

type ModelWithPermittedFields struct {
	*Model
	// contains filtered or unexported fields
}

ModelWithPermittedFields wraps a Model with a whitelist of permitted fields for mass assignment protection. Create instances using Permit or PermitAllExcept, then use Filter to safely extract allowed fields from user input.

func (ModelWithPermittedFields) Bind

func (m ModelWithPermittedFields) Bind(ctx interface{ Bind(interface{}) error }, target interface{}) (Changes, error)

Bind extracts permitted fields from an HTTP request using a Bind method (compatible with Echo and similar frameworks). Only permitted fields are copied to target; other fields retain their zero values. The target must be a pointer to a struct.

func handler(c echo.Context) error {
	var user User
	changes, err := users.Permit("Name", "Email").Bind(c, &user)
	if err != nil {
		return err
	}
	users.Insert(changes).MustExecute()
	// ...
}

func (ModelWithPermittedFields) Filter

func (m ModelWithPermittedFields) Filter(inputs ...interface{}) (out Changes)

Filter extracts only permitted fields from input data, providing mass assignment protection. Accepts multiple input types: RawChanges, JSON strings, []byte, io.Reader, or structs. Map/JSON keys must match the field's JSON tag name. The returned Changes can be passed to Insert or Update.

// Filter JSON from request body
changes := users.Permit("Name", "Email").Filter(requestBody)
users.Insert(changes).MustExecute()

// Filter from multiple sources (later values override earlier)
changes := users.Permit("Name").Filter(
	map[string]interface{}{"name": "Alice"},
	`{"name": "Bob"}`,
) // name will be "Bob"

func (ModelWithPermittedFields) MustBind

func (m ModelWithPermittedFields) MustBind(ctx interface{ Bind(interface{}) error }, target interface{}) Changes

MustBind is like Bind but panics if bind operation fails.

func (ModelWithPermittedFields) PermittedFields

func (m ModelWithPermittedFields) PermittedFields() (out []string)

PermittedFields returns the list of field names that are permitted for mass assignment.

func (ModelWithPermittedFields) ToColumnName added in v1.8.0

func (mi ModelWithPermittedFields) ToColumnName(in string) string

ToColumnName converts a struct field name to a database column name using the configured column namer function. If no namer is set, returns the input unchanged.

type RawChanges

type RawChanges map[string]interface{}

RawChanges is a map of string keys to values, used as input to Filter and Changes methods. Keys should match either JSON tag names (for Changes) or struct field names (for FieldChanges).

type SQL added in v1.3.0

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

SQL represents a SQL statement with parameter values. It provides methods for executing queries (Query, QueryRow) and statements (Execute). Create instances using Model.NewSQL or the query builder methods (Find, Select, Insert, Update, Delete).

func (SQL) AsDelete added in v1.3.0

func (s SQL) AsDelete() *DeleteSQL

AsDelete converts a raw SQL statement to a DeleteSQL builder.

func (SQL) AsInsert added in v1.3.0

func (s SQL) AsInsert(changes ...interface{}) *InsertSQL

AsInsert converts a raw SQL statement to an InsertSQL builder with the given changes.

func (SQL) AsSelect added in v1.3.0

func (s SQL) AsSelect(fields ...string) *SelectSQL

AsSelect converts a raw SQL statement to a SelectSQL builder. Optional field names are used as the initial SELECT columns.

func (SQL) AsUpdate added in v1.3.0

func (s SQL) AsUpdate(changes ...interface{}) *UpdateSQL

AsUpdate converts a raw SQL statement to an UpdateSQL builder with the given changes.

func (SQL) Execute added in v1.3.0

func (s SQL) Execute(dest ...interface{}) error

Execute runs an INSERT, UPDATE, or DELETE statement. To get the number of rows affected, pass a pointer to an int or int64 as dest.

func (SQL) ExecuteCtx added in v1.7.0

func (s SQL) ExecuteCtx(ctx context.Context, dest ...interface{}) error

ExecuteCtx is like Execute but accepts a context for cancellation and timeouts.

func (SQL) ExecuteCtxTx added in v1.6.0

func (s SQL) ExecuteCtxTx(ctx context.Context, tx Tx, dest ...interface{}) error

ExecuteCtxTx is like Execute but accepts a context and optional transaction. If tx is non-nil, the statement executes within that transaction.

func (*SQL) Explain added in v1.14.0

func (s *SQL) Explain(target interface{}, options ...string) *SQL

Explain sets up EXPLAIN output collection. When Query, QueryRow, or Execute is called, an EXPLAIN statement will be executed first and the result will be written to the target. Target can be *string, io.Writer, logger.Logger, func(string), or func(...interface{}) (e.g. log.Println). Options can include ANALYZE, VERBOSE, BUFFERS, COSTS, TIMING, FORMAT JSON, etc.

func (*SQL) ExplainAnalyze added in v1.14.0

func (s *SQL) ExplainAnalyze(target interface{}, options ...string) *SQL

ExplainAnalyze is a shorthand for Explain(target, "ANALYZE", ...). Target can be *string, io.Writer, logger.Logger, func(string), or func(...interface{}). Note: The ANALYZE option causes the statement to be actually executed, not just planned. Use with caution on INSERT, UPDATE, DELETE statements as they will modify your data.

func (SQL) MustExecute added in v1.3.0

func (s SQL) MustExecute(dest ...interface{})

MustExecute is like Execute but panics if execute operation fails.

func (SQL) MustExecuteCtx added in v1.7.0

func (s SQL) MustExecuteCtx(ctx context.Context, dest ...interface{})

MustExecuteCtx is like ExecuteCtx but panics if execute operation fails.

func (SQL) MustExecuteCtxTx added in v1.6.0

func (s SQL) MustExecuteCtxTx(ctx context.Context, tx Tx, dest ...interface{})

MustExecuteCtxTx is like ExecuteCtxTx but panics if execute operation fails.

func (SQL) MustQuery added in v1.3.0

func (s SQL) MustQuery(target interface{})

MustQuery is like Query but panics if query operation fails.

func (SQL) MustQueryCtx added in v1.7.0

func (s SQL) MustQueryCtx(ctx context.Context, target interface{})

MustQueryCtx is like QueryCtx but panics if query operation fails.

func (SQL) MustQueryCtxTx added in v1.6.0

func (s SQL) MustQueryCtxTx(ctx context.Context, tx Tx, target interface{})

MustQueryCtxTx is like QueryCtxTx but panics if query operation fails.

func (SQL) MustQueryRow added in v1.3.0

func (s SQL) MustQueryRow(dest ...interface{})

MustQueryRow is like QueryRow but panics if query row operation fails.

func (SQL) MustQueryRowCtx added in v1.7.0

func (s SQL) MustQueryRowCtx(ctx context.Context, dest ...interface{})

MustQueryRowCtx is like QueryRowCtx but panics if query row operation fails.

func (SQL) MustQueryRowCtxTx added in v1.6.0

func (s SQL) MustQueryRowCtxTx(ctx context.Context, tx Tx, dest ...interface{})

MustQueryRowCtxTx is like QueryRowCtxTx but panics if query row operation fails.

func (SQL) Query added in v1.3.0

func (s SQL) Query(target interface{}) error

Query executes the SQL query and scans results into target. Target must be a pointer to a struct (single row), slice (multiple rows), or map (key-value pairs). See Find and Select for examples.

func (SQL) QueryCtx added in v1.7.0

func (s SQL) QueryCtx(ctx context.Context, target interface{}) error

QueryCtx is like Query but accepts a context for cancellation and timeouts.

func (SQL) QueryCtxTx added in v1.6.0

func (s SQL) QueryCtxTx(ctx context.Context, tx Tx, target interface{}) error

QueryCtxTx is like Query but accepts a context and optional transaction. If tx is non-nil, the query executes within that transaction.

func (SQL) QueryRow added in v1.3.0

func (s SQL) QueryRow(dest ...interface{}) error

QueryRow executes the query and scans the first row's columns into dest. Each dest must be a pointer to a variable that can hold the column value.

var name string
var id int
psql.NewModelTable("users", conn).Select("name", "id").MustQueryRow(&name, &id)

func (SQL) QueryRowCtx added in v1.7.0

func (s SQL) QueryRowCtx(ctx context.Context, dest ...interface{}) error

QueryRowCtx is like QueryRow but accepts a context for cancellation and timeouts.

func (SQL) QueryRowCtxTx added in v1.6.0

func (s SQL) QueryRowCtxTx(ctx context.Context, tx Tx, dest ...interface{}) error

QueryRowCtxTx is like QueryRow but accepts a context and optional transaction. If tx is non-nil, the query executes within that transaction.

func (SQL) String added in v1.3.0

func (s SQL) String() string

func (SQL) StringValues added in v1.13.0

func (s SQL) StringValues() (string, []interface{})

func (*SQL) Tap added in v1.5.0

func (s *SQL) Tap(funcs ...func(*SQL) *SQL) *SQL

Tap applies a series of functions to the SQL object, allowing method chaining with custom transformations.

func (SQL) Values added in v1.11.1

func (s SQL) Values() []interface{}

type SelectSQL added in v1.3.0

type SelectSQL struct {
	*SQL
	// contains filtered or unexported fields
}

SelectSQL represents a SELECT query builder. Create instances using Model.Find, Model.Select, or SQL.AsSelect.

func (*SelectSQL) Count added in v1.3.0

func (s *SelectSQL) Count(optional ...string) (count int, err error)

Count executes a SELECT COUNT(*) query and returns the number of matching rows. Pass a custom expression for different counting, e.g., Count("COUNT(DISTINCT author_id)").

func (*SelectSQL) CountCtxTx added in v1.15.0

func (s *SelectSQL) CountCtxTx(ctx context.Context, tx Tx, optional ...string) (count int, err error)

CountCtxTx is like Count but accepts a context and optional transaction.

func (*SelectSQL) Delete added in v1.3.0

func (s *SelectSQL) Delete() *DeleteSQL

Delete converts this SelectSQL to a DeleteSQL, preserving WHERE conditions.

func (*SelectSQL) Exists added in v1.3.0

func (s *SelectSQL) Exists() (exists bool, err error)

Exists executes a SELECT 1 query and returns true if at least one row matches the current conditions.

func (*SelectSQL) ExistsCtxTx added in v1.15.0

func (s *SelectSQL) ExistsCtxTx(ctx context.Context, tx Tx) (exists bool, err error)

ExistsCtxTx is like Exists but accepts a context and optional transaction.

func (*SelectSQL) Explain added in v1.14.0

func (s *SelectSQL) Explain(target interface{}, options ...string) *SelectSQL

Explain sets up EXPLAIN output collection. When Query, QueryRow, or Execute is called, an EXPLAIN statement will be executed first and the result will be written to the target. Target can be *string, io.Writer, logger.Logger, func(string), or func(...interface{}) (e.g. log.Println). Options can include ANALYZE, VERBOSE, BUFFERS, COSTS, TIMING, FORMAT JSON, etc.

func (*SelectSQL) ExplainAnalyze added in v1.14.0

func (s *SelectSQL) ExplainAnalyze(target interface{}, options ...string) *SelectSQL

ExplainAnalyze is a shorthand for Explain(target, "ANALYZE", ...). Target can be *string, io.Writer, logger.Logger, func(string), or func(...interface{}). Note: The ANALYZE option causes the statement to be actually executed, not just planned. Use with caution on INSERT, UPDATE, DELETE statements as they will modify your data.

func (*SelectSQL) Find added in v1.3.0

func (s *SelectSQL) Find(options ...interface{}) *SelectSQL

Find populates the SELECT clause with all columns from the Model's struct. Options can include transformation functions like AddTableName or the string "--no-reset" to append rather than replace existing columns.

func (*SelectSQL) From added in v1.13.0

func (s *SelectSQL) From(items ...string) *SelectSQL

From appends items to the FROM clause.

func (*SelectSQL) GroupBy added in v1.3.0

func (s *SelectSQL) GroupBy(expressions ...string) *SelectSQL

GroupBy adds a GROUP BY clause to the query.

func (*SelectSQL) Having added in v1.3.0

func (s *SelectSQL) Having(condition string, args ...interface{}) *SelectSQL

Having adds a HAVING clause to the query. Use $1, $2 for positional parameters, or $? which is auto-replaced when a single argument is provided.

func (*SelectSQL) Join added in v1.3.1

func (s *SelectSQL) Join(expressions ...string) *SelectSQL

Join appends JOIN clauses to the query.

func (*SelectSQL) Limit added in v1.3.0

func (s *SelectSQL) Limit(count interface{}) *SelectSQL

Limit adds a LIMIT clause to the query. Pass nil to remove the limit.

func (*SelectSQL) MustCount added in v1.3.0

func (s *SelectSQL) MustCount(optional ...string) int

MustCount is like Count but panics if count operation fails.

func (*SelectSQL) MustCountCtxTx added in v1.15.0

func (s *SelectSQL) MustCountCtxTx(ctx context.Context, tx Tx, optional ...string) int

MustCountCtxTx is like CountCtxTx but panics if count operation fails.

func (*SelectSQL) MustExists added in v1.3.0

func (s *SelectSQL) MustExists() bool

MustExists is like Exists but panics if existence check operation fails. Returns true if record exists, false if not exists.

func (*SelectSQL) MustExistsCtxTx added in v1.15.0

func (s *SelectSQL) MustExistsCtxTx(ctx context.Context, tx Tx) bool

MustExistsCtxTx is like ExistsCtxTx but panics if existence check operation fails. Returns true if record exists, false if not exists.

func (*SelectSQL) Offset added in v1.3.0

func (s *SelectSQL) Offset(start interface{}) *SelectSQL

Offset adds an OFFSET clause to the query. Pass nil to remove the offset.

func (*SelectSQL) OrderBy added in v1.3.0

func (s *SelectSQL) OrderBy(expressions ...string) *SelectSQL

OrderBy adds an ORDER BY clause to the query.

func (*SelectSQL) ReplaceSelect added in v1.10.5

func (s *SelectSQL) ReplaceSelect(old, new string) *SelectSQL

ReplaceSelect replaces occurrences of old column name with new in the SELECT clause.

func (*SelectSQL) ResetFrom added in v1.13.0

func (s *SelectSQL) ResetFrom(items ...string) *SelectSQL

ResetFrom replaces the FROM clause with the given items.

func (*SelectSQL) ResetJoin added in v1.5.0

func (s *SelectSQL) ResetJoin(expressions ...string) *SelectSQL

ResetJoin replaces all JOIN clauses with the given expressions.

func (*SelectSQL) ResetSelect added in v1.3.0

func (s *SelectSQL) ResetSelect(expressions ...string) *SelectSQL

ResetSelect replaces all SELECT columns with the given expressions.

func (*SelectSQL) Select added in v1.3.0

func (s *SelectSQL) Select(expressions ...string) *SelectSQL

Select appends columns to the SELECT clause, inserting before JSONB columns.

func (*SelectSQL) String added in v1.3.0

func (s *SelectSQL) String() string

func (*SelectSQL) StringValues added in v1.13.0

func (s *SelectSQL) StringValues() (string, []interface{})

func (*SelectSQL) Tap added in v1.5.0

func (s *SelectSQL) Tap(funcs ...func(*SelectSQL) *SelectSQL) *SelectSQL

Tap applies transformation functions to this SelectSQL, enabling custom method chaining.

func (*SelectSQL) Update added in v1.3.0

func (s *SelectSQL) Update(lotsOfChanges ...interface{}) *UpdateSQL

Update converts this SelectSQL to an UpdateSQL, preserving WHERE conditions.

func (*SelectSQL) WHERE added in v1.9.0

func (s *SelectSQL) WHERE(args ...interface{}) *SelectSQL

WHERE adds conditions from field/operator/value tuples. Each tuple consists of three consecutive arguments: field name, operator, and value. Multiple tuples are combined with AND.

func (*SelectSQL) WITH added in v1.13.0

func (s *SelectSQL) WITH(name string, sql *SelectSQL) *SelectSQL

WITH adds a named CTE from another SelectSQL query. The name can include "AS MATERIALIZED" or "AS NOT MATERIALIZED" for PostgreSQL 12+.

func (*SelectSQL) Where added in v1.3.0

func (s *SelectSQL) Where(condition string, args ...interface{}) *SelectSQL

Where adds a WHERE condition to the query. Multiple calls are combined with AND. Use $1, $2 for positional parameters, or $? for auto-replacement.

func (*SelectSQL) With added in v1.13.0

func (s *SelectSQL) With(expression string, args ...interface{}) *SelectSQL

With adds a CTE (Common Table Expression) to the query.

type String added in v1.12.2

type String string

String is a raw SQL expression that will not be escaped or parameterized. Use for expressions like "NOW()" or "column + 1".

type TransactionBlock added in v1.6.0

type TransactionBlock func(context.Context, Tx) error

TransactionBlock is a function executed within a database transaction. Return nil to commit; return an error or panic to rollback.

type Tx added in v1.12.1

type Tx = db.Tx

Tx is an alias for db.Tx, representing a database transaction.

type UpdateSQL added in v1.3.0

type UpdateSQL struct {
	*SQL
	// contains filtered or unexported fields
}

UpdateSQL represents an UPDATE statement builder. Create instances using Model.Update or SQL.AsUpdate.

func (*UpdateSQL) Explain added in v1.14.0

func (s *UpdateSQL) Explain(target interface{}, options ...string) *UpdateSQL

Explain sets up EXPLAIN output collection. When Query, QueryRow, or Execute is called, an EXPLAIN statement will be executed first and the result will be written to the target. Target can be *string, io.Writer, logger.Logger, func(string), or func(...interface{}) (e.g. log.Println). Options can include ANALYZE, VERBOSE, BUFFERS, COSTS, TIMING, FORMAT JSON, etc.

func (*UpdateSQL) ExplainAnalyze added in v1.14.0

func (s *UpdateSQL) ExplainAnalyze(target interface{}, options ...string) *UpdateSQL

ExplainAnalyze is a shorthand for Explain(target, "ANALYZE", ...). Target can be *string, io.Writer, logger.Logger, func(string), or func(...interface{}). Note: The ANALYZE option causes the statement to be actually executed, not just planned. The UPDATE will actually modify data in the table.

func (*UpdateSQL) Returning added in v1.3.0

func (s *UpdateSQL) Returning(expressions ...string) *UpdateSQL

Returning adds a RETURNING clause to retrieve values from updated rows.

func (*UpdateSQL) String added in v1.3.0

func (s *UpdateSQL) String() string

func (*UpdateSQL) StringValues added in v1.13.0

func (s *UpdateSQL) StringValues() (string, []interface{})

func (*UpdateSQL) Tap added in v1.5.0

func (s *UpdateSQL) Tap(funcs ...func(*UpdateSQL) *UpdateSQL) *UpdateSQL

Tap applies transformation functions to this UpdateSQL, enabling custom method chaining.

func (*UpdateSQL) WHERE added in v1.9.0

func (s *UpdateSQL) WHERE(args ...interface{}) *UpdateSQL

WHERE adds conditions from field/operator/value tuples. Each tuple consists of three consecutive arguments: field name, operator, and value.

func (*UpdateSQL) Where added in v1.3.0

func (s *UpdateSQL) Where(condition string, args ...interface{}) *UpdateSQL

Where adds a WHERE condition to the UPDATE statement. Use $1, $2 for positional parameters, or $? which is auto-replaced when a single argument is provided.

Jump to

Keyboard shortcuts

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