pg

package
v0.1.0 Latest Latest
Warning

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

Go to latest
Published: May 30, 2026 License: MIT Imports: 21 Imported by: 0

Documentation

Overview

Package pg provides PostgreSQL schema declarations and a fluent query builder for use with drops.

Tables are declared with NewTable and a sequence of column constructors (Text, Integer, Serial, Boolean, Timestamp, UUID, JSONB, ...). Columns are themselves drops.Expressions and may be referenced anywhere a SQL fragment is expected.

Queries are composed via the methods on DB (Select, Insert, Update, Delete). Each builder is immutable in spirit — methods return the builder to support chaining — and ends with an executor (All, One, Exec, Returning + Scan).

Index

Examples

Constants

View Source
const DefaultMigrationsTable = "_drops_migrations"

DefaultMigrationsTable is the table used to track applied migrations when no override is set on the Migrator.

View Source
const DrizzleSchema = "drizzle"

DrizzleSchema is the schema where drizzle stores migration history.

View Source
const DrizzleTable = "__drizzle_migrations"

DrizzleTable is the migration history table.

View Source
const StatementBreakpoint = "--> statement-breakpoint"

StatementBreakpoint is the delimiter drizzle-kit emits between statements when breakpoints are enabled.

Variables

View Source
var (
	// ErrReturningRequired is returned by *Builder.All / *Builder.One on
	// INSERT/UPDATE/DELETE statements that were not paired with a
	// Returning(...) clause.
	ErrReturningRequired = errors.New("drops/pg: builder.All/One requires Returning(...)")

	// ErrNoRowsToInsert is returned by InsertBuilder.Exec when no row has
	// been added via Row / Rows.
	ErrNoRowsToInsert = errors.New("drops/pg: INSERT with no rows")

	// ErrNoUpdateAssignments is returned by UpdateBuilder.Exec when no
	// Set assignment has been added.
	ErrNoUpdateAssignments = errors.New("drops/pg: UPDATE with no Set assignments")

	// ErrSchemaRequired is returned by Push when schema is nil.
	ErrSchemaRequired = errors.New("drops/pg: Schema is required")

	// ErrInvalidIdentifier is returned when a SQL identifier (table,
	// column, schema) contains characters that would break out of
	// double-quoted identifier safety (NUL, embedded double quotes).
	ErrInvalidIdentifier = errors.New("drops/pg: invalid SQL identifier")
)

Package-level sentinel errors. Callers may check them with errors.Is to branch on a specific failure mode without inspecting the message.

The decorating wrappers used by builders use fmt.Errorf("...: %w", err) so the chain stays intact when extra context is added.

View Source
var ErrNoMigrationsApplied = errors.New("drops/pg: no migrations applied")

ErrNoMigrationsApplied is returned by Down when the history table is empty.

View Source
var ErrNoRows = errors.New("drops/pg: no rows in result set")

ErrNoRows is returned by One when the query produced no rows.

Functions

func Abs

func Abs(e any) drops.Expression

func Acos

func Acos(e any) drops.Expression

func Age

func Age(args ...any) drops.Expression

Age renders age(<a>, <b>) — the interval between two timestamps. Pass only one timestamp to compute age(now(), ts).

func All

func All(value, array any) drops.Expression

All renders <value> = ALL(<array>).

func AllSub

func AllSub(value, sub any) drops.Expression

AllSub renders <value> = ALL(<subquery>).

func AlterEnumAddValue

func AlterEnumAddValue(enumName, value string, before, after string) drops.Expression

AlterEnumAddValue appends a new label to an existing enum (PG 9.1+). before/after are optional anchors; if both are empty the value is appended at the end.

func AlterEnumRenameValue

func AlterEnumRenameValue(enumName, oldValue, newValue string) drops.Expression

AlterEnumRenameValue renames an existing enum label (PG 10+).

func And

func And(preds ...drops.Expression) drops.Expression

And joins the predicates with AND. With no arguments it renders TRUE.

func Any

func Any(value, array any) drops.Expression

Any renders <value> = ANY(<array>).

func AnySub

func AnySub(value, sub any) drops.Expression

AnySub renders <value> = ANY(<subquery>). Use a subquery expression (typically SelectBuilder) as the right-hand side.

func ArrayAgg

func ArrayAgg(e any) drops.Expression

func ArrayAppend

func ArrayAppend(arr, v any) drops.Expression

func ArrayConcat

func ArrayConcat(a, b any) drops.Expression

ArrayConcat renders <a> || <b>.

func ArrayContainedIn

func ArrayContainedIn(a, b any) drops.Expression

ArrayContainedIn renders <a> <@ <b>.

func ArrayContains

func ArrayContains(a, b any) drops.Expression

ArrayContains renders <a> @> <b> (array containment).

func ArrayLength

func ArrayLength(arr, dim any) drops.Expression

func ArrayLit

func ArrayLit(values ...any) drops.Expression

ArrayLit renders an ARRAY[...] literal. Values may be expressions or Go values (bound as params).

func ArrayLower

func ArrayLower(arr, dim any) drops.Expression

func ArrayOverlaps

func ArrayOverlaps(a, b any) drops.Expression

ArrayOverlaps renders <a> && <b>.

func ArrayPosition

func ArrayPosition(arr, v any) drops.Expression

func ArrayPositions

func ArrayPositions(arr, v any) drops.Expression

func ArrayPrepend

func ArrayPrepend(v, arr any) drops.Expression

func ArrayRemove

func ArrayRemove(arr, v any) drops.Expression

func ArrayReplace

func ArrayReplace(arr, oldV, newV any) drops.Expression

func ArrayToString

func ArrayToString(arr, sep any) drops.Expression

func ArrayUpper

func ArrayUpper(arr, dim any) drops.Expression

func As

func As(e drops.Expression, alias string) drops.Expression

As renames an arbitrary expression: "<expr> AS <alias>".

func Asin

func Asin(e any) drops.Expression

func AtTimeZone

func AtTimeZone(ts, zone any) drops.Expression

AtTimeZone renders <ts> AT TIME ZONE <zone>.

func Atan

func Atan(e any) drops.Expression

func Avg

func AvgDistinct

func AvgDistinct(e drops.Expression) drops.Expression

func Between

func Between(left, low, high any) drops.Expression

Between renders "left BETWEEN low AND high".

func BoolAnd

func BoolAnd(e any) drops.Expression

BoolAnd / BoolOr aggregates.

func BoolOr

func BoolOr(e any) drops.Expression

func Cardinality

func Cardinality(arr any) drops.Expression

func Cast

func Cast(e any, typeSQL string) drops.Expression

Cast renders <e>::<type> — the PostgreSQL shorthand for explicit type conversion. Equivalent to CAST(<e> AS <type>).

func CastAs

func CastAs(e any, typeSQL string) drops.Expression

CastAs renders CAST(<e> AS <type>) — the standard-SQL form.

func Ceil

func Ceil(e any) drops.Expression

func CharLength

func CharLength(e any) drops.Expression

CharLength renders char_length(<e>).

func Coalesce

func Coalesce(args ...any) drops.Expression

Coalesce renders coalesce(<args...>). Arguments may be Expressions or Go values (bound as parameters).

func ColumnExists

func ColumnExists(ctx context.Context, db *DB, schema, table, column string) (bool, error)

ColumnExists reports whether a column exists on a table. schema may be empty to mean "public".

func CommentOnColumn

func CommentOnColumn(c ColRef, text string) drops.Expression

CommentOnColumn returns COMMENT ON COLUMN <t>.<c> IS 'text'.

func CommentOnTable

func CommentOnTable(t *Table, text string) drops.Expression

CommentOnTable returns COMMENT ON TABLE <t> IS 'text'. text must not contain unsanitised single quotes.

func Concat

func Concat(args ...any) drops.Expression

Concat renders concat(args...).

func ConcatOp

func ConcatOp(left, right any) drops.Expression

ConcatOp renders the SQL || concatenation operator: (a || b).

func ConcatWS

func ConcatWS(sep any, args ...any) drops.Expression

ConcatWS renders concat_ws(sep, args...).

func ConstraintExists

func ConstraintExists(ctx context.Context, db *DB, schema, table, constraint string) (bool, error)

ConstraintExists reports whether a named constraint exists on a table. schema may be empty to mean "public".

func Cos

func Cos(e any) drops.Expression

func CosineDistance

func CosineDistance(left, right any) drops.Expression

CosineDistance renders <col> <=> <vec>.

func Count

Count renders count(<e>).

func CountAll

func CountAll() drops.Expression

CountAll renders count(*).

func CountDistinct

func CountDistinct(e drops.Expression) drops.Expression

CountDistinct renders count(DISTINCT <e>).

func CreateEnum

func CreateEnum(e *PgEnum) drops.Expression

CreateEnum returns a CREATE TYPE ... AS ENUM (...) statement.

func CreateExtension

func CreateExtension(name string) drops.Expression

CreateExtension returns CREATE EXTENSION "name". Common values: "pgcrypto", "uuid-ossp", "postgis", "pg_trgm".

func CreateExtensionIfNotExists

func CreateExtensionIfNotExists(name string) drops.Expression

CreateExtensionIfNotExists is the IF NOT EXISTS variant.

func CreateFunction

func CreateFunction(name string, opts FunctionOptions) drops.Expression

CreateFunction returns a CREATE FUNCTION statement. The body is wrapped in $func$ delimiters so it may contain arbitrary single quotes.

func CreateIndex

func CreateIndex(idx *Index) drops.Expression

CreateIndex returns the CREATE INDEX statement for idx.

func CreateIndexIfNotExists

func CreateIndexIfNotExists(idx *Index) drops.Expression

CreateIndexIfNotExists is the IF NOT EXISTS variant.

func CreateMaterializedView

func CreateMaterializedView(name string, query drops.Expression, withData bool) drops.Expression

CreateMaterializedView returns CREATE MATERIALIZED VIEW. withData=false emits WITH NO DATA so the view is empty until first refreshed.

func CreateOrReplaceView

func CreateOrReplaceView(name string, query drops.Expression) drops.Expression

CreateOrReplaceView returns CREATE OR REPLACE VIEW ...

func CreateSchema

func CreateSchema(name string) drops.Expression

CreateSchema returns CREATE SCHEMA "name".

func CreateSchemaIfNotExists

func CreateSchemaIfNotExists(name string) drops.Expression

CreateSchemaIfNotExists is the IF NOT EXISTS variant.

func CreateSequence

func CreateSequence(name string, opts ...SequenceOptions) drops.Expression

CreateSequence returns a CREATE SEQUENCE statement.

func CreateSequenceIfNotExists

func CreateSequenceIfNotExists(name string, opts ...SequenceOptions) drops.Expression

CreateSequenceIfNotExists is the IF NOT EXISTS variant.

func CreateTable

func CreateTable(t *Table) drops.Expression

CreateTable returns a CREATE TABLE statement for t.

The generated SQL covers column types, NOT NULL, DEFAULT, UNIQUE, PRIMARY KEY (single-column only), and inline FOREIGN KEY references. More elaborate DDL — composite keys, indexes, partitioning — is out of scope; emit it via raw SQL.

func CreateTableIfNotExists

func CreateTableIfNotExists(t *Table) drops.Expression

CreateTableIfNotExists is the IF NOT EXISTS variant.

func CreateTrigger

func CreateTrigger(name string, opts TriggerOptions) drops.Expression

CreateTrigger returns a CREATE TRIGGER statement.

func CreateView

func CreateView(name string, query drops.Expression) drops.Expression

CreateView returns CREATE VIEW "name" AS <select>.

func CumeDist

func CumeDist() drops.Expression

func CurrVal

func CurrVal(name string) drops.Expression

CurrVal returns currval('"name"').

func CurrentDate

func CurrentDate() drops.Expression

CurrentDate renders current_date.

func CurrentTime

func CurrentTime() drops.Expression

CurrentTime renders current_time.

func CurrentTimestamp

func CurrentTimestamp() drops.Expression

CurrentTimestamp renders current_timestamp.

func DatePart

func DatePart(field string, ts any) drops.Expression

DatePart renders date_part('field', <ts>) — the function form of EXTRACT.

func DateTrunc

func DateTrunc(field string, ts any) drops.Expression

DateTrunc renders date_trunc('field', <ts>) — e.g. DateTrunc("day", col).

func Day

func Day(n int) drops.Expression

Day / Hour / Minute / Second build INTERVAL literals from numeric n.

func Decode

func Decode(text, format any) drops.Expression

Decode renders decode(<text>, <format>).

func DenseRank

func DenseRank() drops.Expression

func Diff

func Diff(prev, cur *Snapshot, opts ...DiffOptions) []string

Diff returns the ordered list of SQL statements that, applied in order, evolve a database from prev's schema to cur's. Output is deterministic for a given (prev, cur, opts) — keys are walked in sorted order — so re-running against the same input produces byte-identical SQL.

Operation order:

  1. DROP TABLE for tables removed entirely
  2. CREATE TABLE for new tables (column defs + inline UNIQUE only)
  3. ALTER TABLE for column-level changes on surviving tables (drop, add, type, NOT NULL, DEFAULT)
  4. UNIQUE constraint adds/drops on surviving tables
  5. FOREIGN KEY adds/drops on every table — emitted after CREATE TABLEs so cross-table references resolve.

func Div

func Div(left, right any) drops.Expression

func DropEnum

func DropEnum(name string) drops.Expression

DropEnum returns DROP TYPE "name".

func DropEnumIfExists

func DropEnumIfExists(name string) drops.Expression

DropEnumIfExists is the IF EXISTS variant.

func DropExtension

func DropExtension(name string) drops.Expression

DropExtension returns DROP EXTENSION "name".

func DropExtensionIfExists

func DropExtensionIfExists(name string) drops.Expression

DropExtensionIfExists is the IF EXISTS variant.

func DropFunction

func DropFunction(name, args string) drops.Expression

DropFunction returns DROP FUNCTION "name"(args). args is the raw argument-types signature, e.g. "integer, integer".

func DropFunctionIfExists

func DropFunctionIfExists(name, args string) drops.Expression

DropFunctionIfExists is the IF EXISTS variant.

func DropIndex

func DropIndex(name string) drops.Expression

DropIndex returns DROP INDEX "name".

func DropIndexConcurrently

func DropIndexConcurrently(name string) drops.Expression

DropIndexConcurrently emits DROP INDEX CONCURRENTLY.

func DropIndexIfExists

func DropIndexIfExists(name string) drops.Expression

DropIndexIfExists is the IF EXISTS variant.

func DropMaterializedView

func DropMaterializedView(name string) drops.Expression

DropMaterializedView returns DROP MATERIALIZED VIEW "name".

func DropSchema

func DropSchema(name string) drops.Expression

DropSchema returns DROP SCHEMA "name".

func DropSchemaIfExists

func DropSchemaIfExists(name string, cascade bool) drops.Expression

DropSchemaIfExists is the IF EXISTS variant. Cascade=true appends CASCADE so dependent objects are dropped too.

func DropSequence

func DropSequence(name string) drops.Expression

DropSequence returns DROP SEQUENCE "name".

func DropSequenceIfExists

func DropSequenceIfExists(name string) drops.Expression

DropSequenceIfExists is the IF EXISTS variant.

func DropTable

func DropTable(t *Table) drops.Expression

DropTable returns a DROP TABLE statement.

func DropTableIfExists

func DropTableIfExists(t *Table) drops.Expression

DropTableIfExists is the IF EXISTS variant of DropTable.

func DropTrigger

func DropTrigger(name string, table *Table) drops.Expression

DropTrigger returns DROP TRIGGER "name" ON <table>.

func DropTriggerIfExists

func DropTriggerIfExists(name string, table *Table) drops.Expression

DropTriggerIfExists is the IF EXISTS variant.

func DropView

func DropView(name string) drops.Expression

DropView returns DROP VIEW "name".

func DropViewIfExists

func DropViewIfExists(name string) drops.Expression

DropViewIfExists is the IF EXISTS variant.

func Encode

func Encode(bytea, format any) drops.Expression

Encode renders encode(<bytea>, <format>) — format is 'base64', 'hex', or 'escape'.

func Eq

func Eq(left, right any) drops.Expression

func Every

func Every(e any) drops.Expression

Every is the standard-SQL alias for bool_and.

func Excluded

func Excluded(c ColRef) drops.Expression

Excluded refers to a column in the EXCLUDED pseudo-table inside an ON CONFLICT update — i.e. the value that would have been inserted. Accepts either *Column or *Col[T] via the ColRef interface.

func Exists

func Exists(q drops.Expression) drops.Expression

Exists renders EXISTS (<subquery>).

func Exp

func Exp(e any) drops.Expression

func Extract

func Extract(field string, ts any) drops.Expression

Extract renders extract(<field> FROM <ts>).

func Filter

func Filter(agg drops.Expression, pred drops.Expression) drops.Expression

Filter wraps an aggregate with a FILTER (WHERE ...) clause:

pg.Filter(pg.Count(UserID), pg.Eq(UserStatus, "active"))

func FirstValue

func FirstValue(expr any) drops.Expression

func Floor

func Floor(e any) drops.Expression

func Format

func Format(format any, args ...any) drops.Expression

Format renders format(<fmt>, args...).

func Func

func Func(name string, args ...any) drops.Expression

Func renders an arbitrary function call <name>(<args...>). Use it as an escape hatch when a built-in helper isn't provided.

func Greatest

func Greatest(args ...any) drops.Expression

Greatest renders greatest(args...).

func Gt

func Gt(left, right any) drops.Expression

func Gte

func Gte(left, right any) drops.Expression

func HammingDistance

func HammingDistance(left, right any) drops.Expression

HammingDistance renders <col> <~> <vec> — bit-vector Hamming distance (BitVec columns only).

func Hour

func Hour(n int) drops.Expression

func ILike

func ILike(left, pattern any) drops.Expression

func In

func In(left any, values ...any) drops.Expression

In renders "left IN (...)". A single slice argument is expanded so In(col, []int{1, 2, 3}) is equivalent to In(col, 1, 2, 3).

func Initcap

func Initcap(e any) drops.Expression

Initcap renders initcap(<e>).

func InnerProduct

func InnerProduct(left, right any) drops.Expression

InnerProduct renders <col> <#> <vec> — pgvector's negative inner product. Smaller is better; for raw inner product, negate the expression or use the cosine helper if your vectors are normalised.

func IntervalLit

func IntervalLit(literal string) drops.Expression

IntervalLit renders an INTERVAL literal — e.g. IntervalLit("1 day"), IntervalLit("2 hours 30 minutes"). The value is wrapped in INTERVAL '...' with single quotes doubled.

Named with "Lit" to avoid a collision with the Interval(name) column type constructor in types.go.

func IsNotNull

func IsNotNull(e any) drops.Expression

func IsNull

func IsNull(e any) drops.Expression

func JSONAgg

func JSONAgg(e any) drops.Expression

JSONAgg / JSONBAgg are aggregates.

func JSONArrayLength

func JSONArrayLength(e any) drops.Expression

func JSONBAgg

func JSONBAgg(e any) drops.Expression

func JSONBArrayLength

func JSONBArrayLength(e any) drops.Expression

func JSONBBuildArray

func JSONBBuildArray(args ...any) drops.Expression

func JSONBBuildObject

func JSONBBuildObject(args ...any) drops.Expression

JSONBBuildObject / JSONBBuildArray are the jsonb variants.

func JSONBConcat

func JSONBConcat(a, b any) drops.Expression

JSONBConcat renders <a> || <b>.

func JSONBContainedIn

func JSONBContainedIn(a, b any) drops.Expression

JSONBContainedIn renders <a> <@ <b>.

func JSONBContains

func JSONBContains(a, b any) drops.Expression

JSONBContains renders <a> @> <b> (does a contain b? jsonb only).

func JSONBDelete

func JSONBDelete(e, key any) drops.Expression

JSONBDelete renders <e> - <key>.

func JSONBHasAllKeys

func JSONBHasAllKeys(e, keys any) drops.Expression

JSONBHasAllKeys renders <e> ?& <keys>.

func JSONBHasAnyKey

func JSONBHasAnyKey(e, keys any) drops.Expression

JSONBHasAnyKey renders <e> ?| <keys> (keys is text[]).

func JSONBHasKey

func JSONBHasKey(e, key any) drops.Expression

JSONBHasKey renders <e> ? <key>.

func JSONBInsert

func JSONBInsert(target, path, newVal any, insertAfter ...bool) drops.Expression

JSONBInsert renders jsonb_insert(<target>, <path>, <newVal>, [<insertAfter>]).

func JSONBObjectAgg

func JSONBObjectAgg(k, v any) drops.Expression

func JSONBPretty

func JSONBPretty(e any) drops.Expression

JSONBPretty renders jsonb_pretty(<e>).

func JSONBSet

func JSONBSet(target, path, value any, createMissing ...bool) drops.Expression

JSONBSet renders jsonb_set(<target>, <path>, <value>, [<createMissing>]).

func JSONBStripNulls

func JSONBStripNulls(e any) drops.Expression

JSONBStripNulls renders jsonb_strip_nulls(<e>).

func JSONBTypeof

func JSONBTypeof(e any) drops.Expression

func JSONBuildArray

func JSONBuildArray(args ...any) drops.Expression

JSONBuildArray renders json_build_array(args...).

func JSONBuildObject

func JSONBuildObject(args ...any) drops.Expression

JSONBuildObject renders json_build_object(args...). Pairs are key/value: JSONBuildObject("name", UserName, "age", UserAge).

func JSONGet

func JSONGet(e, key any) drops.Expression

JSONGet renders <e> -> <key> (JSON object/array element, returns json). key may be a string (object key) or int (array index).

func JSONGetText

func JSONGetText(e, key any) drops.Expression

JSONGetText renders <e> ->> <key> (as text).

func JSONObjectAgg

func JSONObjectAgg(k, v any) drops.Expression

JSONObjectAgg / JSONBObjectAgg.

func JSONPath

func JSONPath(e, path any) drops.Expression

JSONPath renders <e> #> <path> (path is text[] — pass a Go []string).

func JSONPathText

func JSONPathText(e, path any) drops.Expression

JSONPathText renders <e> #>> <path>.

func JSONTypeof

func JSONTypeof(e any) drops.Expression

func JaccardDistance

func JaccardDistance(left, right any) drops.Expression

JaccardDistance renders <col> <%> <vec> — bit-vector Jaccard distance.

func L1Distance

func L1Distance(left, right any) drops.Expression

L1Distance renders <col> <+> <vec> — Manhattan distance.

func L2Distance

func L2Distance(left, right any) drops.Expression

L2Distance renders <col> <-> <vec> — Euclidean distance. The right-hand side is typically a Go []float32 (bound as a param) or another vector column.

func LTrim

func LTrim(e any) drops.Expression

LTrim renders ltrim(<e>).

func Lag

func Lag(expr any, args ...any) drops.Expression

Lag renders lag(expr [, offset [, default]]).

func LastValue

func LastValue(expr any) drops.Expression

func Lead

func Lead(expr any, args ...any) drops.Expression

Lead renders lead(expr [, offset [, default]]).

func Least

func Least(args ...any) drops.Expression

Least renders least(args...).

func Length

func Length(e any) drops.Expression

Length renders length(<e>).

func Like

func Like(left, pattern any) drops.Expression

func Ln

func Ln(e any) drops.Expression

func LocalTime

func LocalTime() drops.Expression

LocalTime / LocalTimestamp (without time zone).

func LocalTimestamp

func LocalTimestamp() drops.Expression

func Log

func Log(e any) drops.Expression

func LoggerHook

func LoggerHook(log LoggerFunc, opts ...LoggerOptions) drops.Hook

LoggerHook re-exports drops.LoggerHook. See its documentation for behaviour and tuning options.

func Lower

Lower / Upper case-folding helpers.

func Lt

func Lt(left, right any) drops.Expression

func Lte

func Lte(left, right any) drops.Expression

func MakeDate

func MakeDate(y, m, d any) drops.Expression

MakeDate renders make_date(<y>, <m>, <d>).

func MakeTime

func MakeTime(h, m, s any) drops.Expression

MakeTime renders make_time(<h>, <m>, <s>).

func MakeTimestamp

func MakeTimestamp(args ...any) drops.Expression

MakeTimestamp renders make_timestamp(y, mo, d, h, mi, s).

func MakeTimestampTZ

func MakeTimestampTZ(args ...any) drops.Expression

MakeTimestampTZ is the TZ-aware variant.

func Max

func Md5

func Md5(e any) drops.Expression

Md5 renders md5(<e>).

func Min

func Minus

func Minus(left, right any) drops.Expression

func Minute

func Minute(n int) drops.Expression

func Mod

func Mod(a, b any) drops.Expression

func Month

func Month(n int) drops.Expression

func Mul

func Mul(left, right any) drops.Expression

func Ne

func Ne(left, right any) drops.Expression

func NextVal

func NextVal(name string) drops.Expression

NextVal returns the SQL expression nextval('"name"'::regclass).

func Not

Not negates a predicate.

func NotExists

func NotExists(q drops.Expression) drops.Expression

NotExists renders NOT EXISTS (<subquery>).

func NotIn

func NotIn(left any, values ...any) drops.Expression

NotIn renders "left NOT IN (...)".

func Now

func Now() drops.Expression

Now renders now().

func NthValue

func NthValue(expr, n any) drops.Expression

func Ntile

func Ntile(n any) drops.Expression

func OnDelete

func OnDelete(action string) func(*FK)

OnDelete configures the referential action for ON DELETE.

func OnUpdate

func OnUpdate(action string) func(*FK)

OnUpdate configures the referential action for ON UPDATE.

func Or

func Or(preds ...drops.Expression) drops.Expression

Or joins the predicates with OR. With no arguments it renders FALSE.

func Over

func Over(fn drops.Expression, win *Window) drops.Expression

Over wraps an aggregate or window function with an OVER clause.

pg.Over(pg.RowNumber(),
    pg.WindowSpec().PartitionBy(UserID).OrderBy(PostCreatedAt.Desc()))

func ParseMigrationName

func ParseMigrationName(filename string) (version, name, kind string, ok bool)

ParseMigrationName recognises "<version>_<name>.{up,down}.sql" and returns the version, name and kind ("up" or "down"). It is exposed so callers can validate filenames before adding them.

func PercentRank

func PercentRank() drops.Expression

func Plus

func Plus(left, right any) drops.Expression

Plus, Minus, Mul, Div: arithmetic operators as parenthesised binary expressions. Useful for column-arithmetic in SELECT lists and updates.

func Position

func Position(substring, str any) drops.Expression

Position renders position(<substring> IN <string>).

func Power

func Power(a, b any) drops.Expression

func RTrim

func RTrim(e any) drops.Expression

RTrim renders rtrim(<e>).

func Random

func Random() drops.Expression

Random renders random().

func Rank

func Rank() drops.Expression

func RefreshMaterializedView

func RefreshMaterializedView(name string, concurrently bool) drops.Expression

RefreshMaterializedView returns REFRESH MATERIALIZED VIEW. concurrently emits the CONCURRENTLY keyword (PG 9.4+) which requires a UNIQUE index.

func RegexpMatch

func RegexpMatch(e, pattern any) drops.Expression

RegexpMatch renders regexp_match(<e>, <pattern>).

func RegexpReplace

func RegexpReplace(e, pattern, replacement any, flags ...string) drops.Expression

RegexpReplace renders regexp_replace(<e>, <pattern>, <replacement>, [<flags>]).

func Replace

func Replace(e, from, to any) drops.Expression

Replace renders replace(<e>, <from>, <to>).

func Round

func Round(e any, digits ...int) drops.Expression

Round renders round(<e>) or round(<e>, <digits>) when digits is non-nil.

func RowNumber

func RowNumber() drops.Expression

func SchemaExists

func SchemaExists(ctx context.Context, db *DB, schema string) (bool, error)

SchemaExists reports whether the named PostgreSQL schema exists.

func Second

func Second(n int) drops.Expression

func SetVal

func SetVal(name string, value any) drops.Expression

SetVal returns setval('"name"', value).

func Sign

func Sign(e any) drops.Expression

func Sin

func Sin(e any) drops.Expression

Trigonometric helpers — pass radians.

func Sqrt

func Sqrt(e any) drops.Expression

func StrPos

func StrPos(str, substring any) drops.Expression

StrPos renders strpos(<string>, <substring>).

func StringAgg

func StringAgg(e, sep any) drops.Expression

StringAgg renders string_agg(<e>, <sep>).

func StringToArray

func StringToArray(str, sep any) drops.Expression

func Subquery

func Subquery(q drops.Expression) drops.Expression

Subquery wraps an expression (typically a SELECT) in parentheses for use as a scalar subquery.

func Substring

func Substring(e any, from any, count any) drops.Expression

Substring renders substring(<e> FROM <from> FOR <count>). count may be nil to omit the FOR clause.

func Sum

Sum / Avg / Min / Max aggregates.

func SumDistinct

func SumDistinct(e drops.Expression) drops.Expression

SumDistinct / AvgDistinct apply DISTINCT to the aggregate.

func TableExists

func TableExists(ctx context.Context, db *DB, schema, table string) (bool, error)

TableExists reports whether a table exists in the given schema. schema may be empty to mean "public".

func Tan

func Tan(e any) drops.Expression

func ToChar

func ToChar(value, pattern any) drops.Expression

ToChar renders to_char(<value>, <pattern>).

func ToDate

func ToDate(text, pattern any) drops.Expression

ToDate / ToTimestamp / ToNumber — text conversion helpers.

func ToJSON

func ToJSON(e any) drops.Expression

func ToJSONB

func ToJSONB(e any) drops.Expression

func ToNumber

func ToNumber(text, pattern any) drops.Expression

func ToTimestamp

func ToTimestamp(text, pattern any) drops.Expression

func Trim

func Trim(e any) drops.Expression

Trim renders trim(<e>).

func Unnest

func Unnest(arr any) drops.Expression

func Upper

func Week

func Week(n int) drops.Expression

func Year

func Year(n int) drops.Expression

Types

type CTE

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

CTE describes one common table expression.

func CTEDef

func CTEDef(name string, query drops.Expression, columns ...string) *CTE

CTEDef returns a CTE definition with optional column aliasing.

func (*CTE) Col

func (c *CTE) Col(col string) drops.Expression

Col returns a column reference inside the CTE: "<cte>"."<col>".

func (*CTE) Name

func (c *CTE) Name() string

Name returns the CTE's alias.

func (*CTE) Ref

func (c *CTE) Ref() drops.Expression

Ref returns an expression that references the CTE as a relation — useful inside JOIN/FROM clauses on subsequent SELECTs.

type CaseExpr

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

CaseExpr is the in-progress CASE expression.

func Case

func Case() *CaseExpr

Case begins a CASE expression. Chain When / Else / End to finish.

pg.Case().
    When(UserAge.Lt(18), "minor").
    When(UserAge.Lt(65), "adult").
    Else("senior").
    End()

func CaseOn

func CaseOn(value any) *CaseExpr

CaseOn begins a simple CASE expression on a value:

pg.CaseOn(UserStatus).
    When("active", 1).
    When("pending", 2).
    Else(0).
    End()

func (*CaseExpr) Else

func (c *CaseExpr) Else(value any) *CaseExpr

Else sets the ELSE value.

func (*CaseExpr) End

func (c *CaseExpr) End() drops.Expression

End finalises the CASE expression.

func (*CaseExpr) When

func (c *CaseExpr) When(cond, value any) *CaseExpr

When adds a WHEN <cond> THEN <value> branch.

type Col

type Col[T any] struct {
	*Column
}

Col is the typed handle for a column whose Go value type is T.

It embeds *Column so it implements drops.Expression and exposes Asc/Desc/As; its own methods (NotNull, PrimaryKey, Eq, In, Val, ...) preserve the type parameter so the chain stays typed end-to-end.

func Add

func Add[T any](t *Table, c *Col[T]) *Col[T]

Add registers c with t and returns it. It is the primary way to attach columns to a table — type inference keeps the *Col[T] handle typed:

var Users    = pg.NewTable("users")
var (
    UserID   = pg.Add(Users, pg.BigSerial("id").PrimaryKey())   // *Col[int64]
    UserName = pg.Add(Users, pg.Text("name").NotNull())          // *Col[string]
    UserAge  = pg.Add(Users, pg.Integer("age"))                  // *Col[int32]
)

Go does not allow generic methods, so Add lives as a free function.

Example

ExampleAdd shows the typical schema-declaration pattern: NewTable followed by package-level pg.Add calls, each binding a typed column to the table. Type inference keeps the column handles typed (*pg.Col[int64], *pg.Col[string], …) so subsequent comparisons and value bindings are compile-time checked.

package main

import (
	"fmt"

	"github.com/bernardoforcillo/drops/pg"
)

func main() {
	products := pg.NewTable("products")
	id := pg.Add(products, pg.BigSerial("id").PrimaryKey())
	name := pg.Add(products, pg.Text("name").NotNull())
	priceCents := pg.Add(products, pg.Integer("price_cents").NotNull())

	fmt.Printf("%s.%s, %s.%s, %s.%s\n",
		products.Name(), id.Name(),
		products.Name(), name.Name(),
		products.Name(), priceCents.Name(),
	)
}
Output:
products.id, products.name, products.price_cents

func BigInt

func BigInt(name string) *Col[int64]

func BigSerial

func BigSerial(name string) *Col[int64]

func BitVec

func BitVec(name string, dim int) *Col[string]

BitVec returns a bit(N) column for binary-vector similarity search.

func Boolean

func Boolean(name string) *Col[bool]

func Bytea

func Bytea(name string) *Col[[]byte]

func Char

func Char(name string, n int) *Col[string]

func Custom

func Custom[T any](name, typeSQL string) *Col[T]

Custom creates a column with an arbitrary type literal. Specify the Go value type as the type parameter — e.g. pg.Custom[string]("status", "user_status_enum").

func Date

func Date(name string) *Col[time.Time]

func DoublePrecision

func DoublePrecision(name string) *Col[float64]

func HalfVec

func HalfVec(name string, dim int) *Col[[]float32]

HalfVec returns a halfvec(N) column (half-precision float). The Go value type stays []float32; the driver converts on the wire.

func Integer

func Integer(name string) *Col[int32]

func Interval

func Interval(name string) *Col[string]

func JSON

func JSON(name string) *Col[json.RawMessage]

func JSONB

func JSONB(name string) *Col[json.RawMessage]

func Numeric

func Numeric(name string, precision, scale int) *Col[string]

Numeric returns NUMERIC(precision, scale) — represented as string so arbitrary-precision values aren't truncated. precision=0 means unconstrained NUMERIC.

func Real

func Real(name string) *Col[float32]

func Serial

func Serial(name string) *Col[int32]

func SmallInt

func SmallInt(name string) *Col[int16]

func SparseVec

func SparseVec(name string, dim int) *Col[string]

SparseVec returns a sparsevec(N) column. Encoding is driver-specific; represented as string for portability.

func Text

func Text(name string) *Col[string]

func Time

func Time(name string) *Col[time.Time]

func Timestamp

func Timestamp(name string, withTimeZone bool) *Col[time.Time]

Timestamp creates a TIMESTAMP column (TIMESTAMPTZ if withTimeZone).

func UUID

func UUID(name string) *Col[string]

func Varchar

func Varchar(name string, n int) *Col[string]

func Vector

func Vector(name string, dim int) *Col[[]float32]

Vector returns a vector(N) column. The Go value type is []float32 — the same shape pgvector exposes through pgx and lib/pq's text codec.

func (*Col[T]) Between

func (c *Col[T]) Between(lo, hi T) drops.Expression

func (*Col[T]) Cosine

func (c *Col[T]) Cosine(v any) drops.Expression

Cosine is the method form of CosineDistance.

func (*Col[T]) Default

func (c *Col[T]) Default(sqlExpr string) *Col[T]

Default sets a raw SQL default expression — e.g. "now()", "0", "'pending'". PostgreSQL DEFAULT clauses cannot be parameterised.

func (*Col[T]) Eq

func (c *Col[T]) Eq(v T) drops.Expression
Example

ExampleEq shows the type-safe comparison shorthand on a typed column.

package main

import (
	"fmt"

	"github.com/bernardoforcillo/drops"
	"github.com/bernardoforcillo/drops/pg"
)

// Schema fixtures used by the examples. Declaring them at package level
// mirrors how a real application stores its schema and lets every
// example reuse the same definitions.
var (
	exUsers = pg.NewTable("users")

	exUserName = pg.Add(exUsers, pg.Text("name").NotNull())
)

func main() {
	sql, args := drops.String(exUserName.Eq("Alice"))
	fmt.Println(sql)
	fmt.Println(args)
}
Output:
("users"."name" = $1)
[Alice]

func (*Col[T]) EqCol

func (c *Col[T]) EqCol(other *Col[T]) drops.Expression

func (*Col[T]) Excluded

func (c *Col[T]) Excluded() drops.Expression

Excluded returns an EXCLUDED.<col> reference for use inside an ON CONFLICT DO UPDATE clause.

func (*Col[T]) Expr

func (c *Col[T]) Expr(e drops.Expression) ColumnValue

Expr binds an arbitrary expression to the column.

func (*Col[T]) Gt

func (c *Col[T]) Gt(v T) drops.Expression

func (*Col[T]) GtCol

func (c *Col[T]) GtCol(other *Col[T]) drops.Expression

func (*Col[T]) Gte

func (c *Col[T]) Gte(v T) drops.Expression

func (*Col[T]) GteCol

func (c *Col[T]) GteCol(other *Col[T]) drops.Expression

func (*Col[T]) ILike

func (c *Col[T]) ILike(pattern string) drops.Expression

func (*Col[T]) IP

func (c *Col[T]) IP(v any) drops.Expression

IP is the method form of InnerProduct.

func (*Col[T]) In

func (c *Col[T]) In(values ...T) drops.Expression

func (*Col[T]) IsNotNull

func (c *Col[T]) IsNotNull() drops.Expression

func (*Col[T]) IsNull

func (c *Col[T]) IsNull() drops.Expression

func (*Col[T]) L1

func (c *Col[T]) L1(v any) drops.Expression

L1 is the method form of L1Distance.

func (*Col[T]) L2

func (c *Col[T]) L2(v any) drops.Expression

L2 is the method form of L2Distance.

func (*Col[T]) Like

func (c *Col[T]) Like(pattern string) drops.Expression

func (*Col[T]) Lt

func (c *Col[T]) Lt(v T) drops.Expression

func (*Col[T]) LtCol

func (c *Col[T]) LtCol(other *Col[T]) drops.Expression

func (*Col[T]) Lte

func (c *Col[T]) Lte(v T) drops.Expression

func (*Col[T]) LteCol

func (c *Col[T]) LteCol(other *Col[T]) drops.Expression

func (*Col[T]) Ne

func (c *Col[T]) Ne(v T) drops.Expression

func (*Col[T]) NeCol

func (c *Col[T]) NeCol(other *Col[T]) drops.Expression

func (*Col[T]) NotIn

func (c *Col[T]) NotIn(values ...T) drops.Expression

func (*Col[T]) NotNull

func (c *Col[T]) NotNull() *Col[T]

func (*Col[T]) PrimaryKey

func (c *Col[T]) PrimaryKey() *Col[T]

func (*Col[T]) References

func (c *Col[T]) References(target *Col[T], opts ...func(*FK)) *Col[T]

References declares a foreign-key constraint to a target column. The target's value type must match — type inference catches mismatches at declaration time.

func (*Col[T]) SetDefault

func (c *Col[T]) SetDefault() ColumnValue

SetDefault binds the SQL DEFAULT keyword.

func (*Col[T]) Unique

func (c *Col[T]) Unique() *Col[T]

func (*Col[T]) Val

func (c *Col[T]) Val(v T) ColumnValue

Val binds a typed value as the column's payload in an INSERT row or UPDATE assignment.

type ColRef

type ColRef interface {
	drops.Expression
	// contains filtered or unexported methods
}

ColRef is implemented by *Column and *Col[T]. It is the type-erased column reference used by APIs that don't depend on the column's Go value type — JOIN ON wiring, ON CONFLICT targets, EXCLUDED references.

type Column

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

Column is the type-erased AST node for a column reference. It is registered with a Table and can be written into a drops.Builder.

Most user code holds a *Col[T] instead, which embeds *Column and adds type-safe builder and operator methods. The untyped Column exists so table column lists can be heterogeneous and so generic methods (Go does not allow them on non-generic types) need not be added to Table.

func (*Column) As

func (c *Column) As(alias string) drops.Expression

As returns an aliased column expression: "<col>" AS "<alias>".

func (*Column) Asc

func (c *Column) Asc() drops.Expression

Asc / Desc produce ORDER BY direction expressions.

func (*Column) DefaultSQL

func (c *Column) DefaultSQL() string

DefaultSQL returns the raw SQL DEFAULT expression.

func (*Column) Desc

func (c *Column) Desc() drops.Expression

func (*Column) ForeignKey

func (c *Column) ForeignKey() *FK

ForeignKey returns the foreign-key reference, or nil if none.

func (*Column) HasDefault

func (c *Column) HasDefault() bool

HasDefault reports whether a DEFAULT clause was declared.

func (*Column) IsNotNull

func (c *Column) IsNotNull() bool

IsNotNull reports whether the column was declared NOT NULL.

func (*Column) IsPrimaryKey

func (c *Column) IsPrimaryKey() bool

IsPrimaryKey reports whether the column was declared PRIMARY KEY.

func (*Column) IsUnique

func (c *Column) IsUnique() bool

IsUnique reports whether the column was declared UNIQUE.

func (*Column) Name

func (c *Column) Name() string

Name returns the unqualified column name.

func (*Column) Table

func (c *Column) Table() *Table

Table returns the table this column was registered with, or nil before registration.

func (*Column) Type

func (c *Column) Type() ColumnType

Type returns the column's SQL type.

func (*Column) WriteSQL

func (c *Column) WriteSQL(b *drops.Builder)

WriteSQL writes a qualified reference to the column.

type ColumnSnapshot

type ColumnSnapshot struct {
	Name       string  `json:"name"`
	Type       string  `json:"type"`
	PrimaryKey bool    `json:"primaryKey"`
	NotNull    bool    `json:"notNull"`
	Default    *string `json:"default,omitempty"`
}

ColumnSnapshot is one entry in TableSnapshot.Columns.

type ColumnType

type ColumnType interface {
	// TypeSQL returns the PostgreSQL type expression as it appears in
	// CREATE TABLE — e.g. "text", "integer", "varchar(255)", "uuid".
	TypeSQL() string
}

ColumnType describes the SQL type of a column.

type ColumnValue

type ColumnValue interface {
	// contains filtered or unexported methods
}

ColumnValue pairs a target column with the value or expression to write for it in an INSERT row or UPDATE SET assignment. Construct one via (*Col[T]).Val, (*Col[T]).Expr, or (*Col[T]).SetDefault.

type ConflictUpdate

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

ConflictUpdate is the configuration handle returned by OnConflictUpdate.

func (*ConflictUpdate) Done

func (cu *ConflictUpdate) Done() *InsertBuilder

Done returns the InsertBuilder for further chaining (e.g. Returning).

func (*ConflictUpdate) Set

func (cu *ConflictUpdate) Set(values ...ColumnValue) *ConflictUpdate

Set adds an assignment to the conflict update.

func (*ConflictUpdate) Where

func (cu *ConflictUpdate) Where(preds ...drops.Expression) *ConflictUpdate

Where adds predicates that gate the conflict update.

type DB

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

DB is the entry point for issuing PostgreSQL queries through a drops.Driver. Any driver implementation — database/sql, pgx, or a custom connection — can back a DB.

A DB is safe for concurrent use by multiple goroutines provided the underlying Driver is. The builder types returned by Select/Insert/ Update/Delete/Find are NOT safe for concurrent use; create one per query.

An optional drops.Hook can be attached via WithHook to observe every driver operation — query logging, slow-query alerts, tracing, metrics. The hook is propagated into the transaction-bound DBs returned by Begin and InTx, and InTx emits "begin"/"commit"/"rollback" events for the transaction lifecycle. For full lifecycle observability prefer InTx; with an explicit Begin you must call Commit/Rollback yourself, and those bypass the hook unless you wrap them.

func New

func New(drv drops.Driver) *DB

New wraps a drops.Driver as a DB.

func (*DB) Begin

func (db *DB) Begin(ctx context.Context) (*DB, drops.Tx, error)

Begin opens a transaction and returns a DB bound to it plus the raw Tx handle. Most callers should prefer InTx for automatic commit/ rollback and full hook coverage.

func (*DB) Close

func (db *DB) Close() error

Close shuts down the underlying driver if it implements io.Closer. For Drivers that don't (most pool wrappers do), it is a no-op and returns nil.

Typical usage is `defer db.Close()` next to the connection-open call:

sqlDB, _ := sql.Open("pgx", dsn)
db := pg.New(stdlib.New(sqlDB))
defer db.Close()

func (*DB) Delete

func (db *DB) Delete(t *Table) *DeleteBuilder

Delete begins a DELETE FROM <t>.

func (*DB) Driver

func (db *DB) Driver() drops.Driver

Driver returns the underlying driver. Useful for adapters or for dropping down to raw SQL.

func (*DB) Exec

func (db *DB) Exec(ctx context.Context, sql string, args ...any) (drops.Result, error)

Exec runs a raw SQL statement with positional ($1, $2, ...) placeholders.

func (*DB) ExecExpr

func (db *DB) ExecExpr(ctx context.Context, e drops.Expression) (drops.Result, error)

ExecExpr renders e to SQL and runs it as a statement. Convenience for DDL helpers like CreateTable.

func (*DB) Find

func (db *DB) Find(t *Table) *FindBuilder

Find begins a relational query against t. The result type passed to All/One determines what columns are scanned (via the same struct-field mapping rules as Select.All).

func (*DB) Hook

func (db *DB) Hook() drops.Hook

Hook returns the currently attached hook, or nil.

func (*DB) InTx

func (db *DB) InTx(ctx context.Context, fn func(*DB) error) (err error)

InTx runs fn inside a transaction. The transaction is committed if fn returns nil and rolled back otherwise (including on panic, after which the panic is re-raised). Hook events are emitted for begin, commit and rollback alongside the ordinary exec/query events fn produces.

Rollback uses a detached context with a short timeout so a cancelled or expired caller-ctx doesn't prevent cleanup.

func (*DB) Insert

func (db *DB) Insert(t *Table) *InsertBuilder

Insert begins an INSERT INTO <t>.

Example

ExampleDB_Insert demonstrates a typed INSERT with RETURNING.

package main

import (
	"fmt"

	"github.com/bernardoforcillo/drops/pg"
)

// Schema fixtures used by the examples. Declaring them at package level
// mirrors how a real application stores its schema and lets every
// example reuse the same definitions.
var (
	exUsers    = pg.NewTable("users")
	exUserID   = pg.Add(exUsers, pg.BigSerial("id").PrimaryKey())
	exUserName = pg.Add(exUsers, pg.Text("name").NotNull())
	exUserAge  = pg.Add(exUsers, pg.Integer("age"))
)

func main() {
	db := pg.New(nil)
	sql, args := db.Insert(exUsers).
		Row(exUserName.Val("Alice"), exUserAge.Val(30)).
		Returning(exUserID).
		ToSQL()
	fmt.Println(sql)
	fmt.Println(args)
}
Output:
INSERT INTO "users" ("name", "age") VALUES ($1, $2) RETURNING "users"."id"
[Alice 30]

func (*DB) Ping

func (db *DB) Ping(ctx context.Context) error

Ping verifies that the database accepts a no-op query.

func (*DB) Query

func (db *DB) Query(ctx context.Context, sql string, args ...any) (drops.Rows, error)

Query runs a raw SQL query.

func (*DB) Select

func (db *DB) Select(cols ...drops.Expression) *SelectBuilder

Select begins a SELECT. With no columns the projection is "*".

Example

ExampleDB_Select shows a typical filtered + ordered SELECT and how the typed column helpers produce parameter-safe SQL.

package main

import (
	"fmt"

	"github.com/bernardoforcillo/drops/pg"
)

// Schema fixtures used by the examples. Declaring them at package level
// mirrors how a real application stores its schema and lets every
// example reuse the same definitions.
var (
	exUsers    = pg.NewTable("users")
	exUserID   = pg.Add(exUsers, pg.BigSerial("id").PrimaryKey())
	exUserName = pg.Add(exUsers, pg.Text("name").NotNull())
	exUserAge  = pg.Add(exUsers, pg.Integer("age"))
)

func main() {
	db := pg.New(nil) // no driver — we only render SQL
	sql, args := db.Select(exUserID, exUserName).
		From(exUsers).
		Where(exUserAge.Gte(18)).
		OrderBy(exUserName.Asc()).
		Limit(10).
		ToSQL()
	fmt.Println(sql)
	fmt.Println(args)
}
Output:
SELECT "users"."id", "users"."name" FROM "users" WHERE ("users"."age" >= $1) ORDER BY "users"."name" ASC LIMIT $2
[18 10]

func (*DB) Update

func (db *DB) Update(t *Table) *UpdateBuilder

Update begins an UPDATE <t>.

func (*DB) WithHook

func (db *DB) WithHook(hook drops.Hook) *DB

WithHook returns a shallow copy of db with hook installed. Passing nil removes the hook. Compose multiple hooks via drops.ChainHooks.

Example

ExampleDB_WithHook shows attaching a tiny observability hook for query logging. Production code usually pairs LoggerHook with a structured logger and a SlowQuery threshold.

package main

import (
	"context"
	"fmt"

	"github.com/bernardoforcillo/drops"
	"github.com/bernardoforcillo/drops/pg"
)

func main() {
	hook := func(_ context.Context, e drops.QueryEvent) {
		fmt.Printf("%s in %v err=%v\n", e.Kind, e.Duration > 0, e.Err)
	}
	db := pg.New(&exampleNoopDriver{}).WithHook(hook)
	_, _ = db.Exec(context.Background(), "SELECT 1")
}

// exampleNoopDriver lets the examples render SQL through DB.Exec
// without depending on the test-only fakeDriver. It is purely for
// documentation; production code never embeds a no-op driver.
type exampleNoopDriver struct{}

func (exampleNoopDriver) Exec(context.Context, string, ...any) (drops.Result, error) {
	return exampleNoopResult{}, nil
}
func (exampleNoopDriver) Query(context.Context, string, ...any) (drops.Rows, error) {
	return nil, fmt.Errorf("not implemented")
}
func (exampleNoopDriver) Begin(context.Context) (drops.Tx, error) {
	return nil, fmt.Errorf("not implemented")
}

type exampleNoopResult struct{}

func (exampleNoopResult) RowsAffected() (int64, error) { return 0, nil }
Output:
exec in true err=<nil>

type DeleteBuilder

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

DeleteBuilder composes a DELETE statement.

func (*DeleteBuilder) All

func (d *DeleteBuilder) All(ctx context.Context, dest any) error

All executes the DELETE and scans the RETURNING rows into dest.

func (*DeleteBuilder) Exec

func (d *DeleteBuilder) Exec(ctx context.Context) (drops.Result, error)

Exec runs the DELETE.

func (*DeleteBuilder) One

func (d *DeleteBuilder) One(ctx context.Context, dest any) error

One executes the DELETE and scans the first RETURNING row into dest.

func (*DeleteBuilder) Returning

func (d *DeleteBuilder) Returning(cols ...drops.Expression) *DeleteBuilder

Returning sets a RETURNING clause.

func (*DeleteBuilder) ToSQL

func (d *DeleteBuilder) ToSQL() (string, []any)

ToSQL renders the statement.

func (*DeleteBuilder) Using

func (d *DeleteBuilder) Using(tables ...*Table) *DeleteBuilder

Using adds tables to a PostgreSQL DELETE ... USING clause for joins.

func (*DeleteBuilder) Where

func (d *DeleteBuilder) Where(preds ...drops.Expression) *DeleteBuilder

Where appends predicates joined by AND.

func (*DeleteBuilder) WriteSQL

func (d *DeleteBuilder) WriteSQL(b *drops.Builder)

WriteSQL renders the DELETE.

type DiffOptions

type DiffOptions struct {
	// Safe wraps every destructive or creative DDL in IF [NOT] EXISTS so
	// the migration can be re-run without errors. ALTER COLUMN does not
	// have an IF EXISTS form in PostgreSQL, so it is emitted unchanged.
	Safe bool
}

DiffOptions tunes how Diff renders statements.

type DrizzleEntry

type DrizzleEntry struct {
	Tag         string
	SQL         string
	Hash        string
	Breakpoints bool
	When        int64
}

DrizzleEntry is a parsed, hash-computed migration ready to apply.

type DrizzleMigrator

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

DrizzleMigrator runs migrations from a drizzle-kit-formatted directory.

func NewDrizzleMigrator

func NewDrizzleMigrator(db *DB, fsys fs.FS, dir string) *DrizzleMigrator

NewDrizzleMigrator wraps db with a migrator that reads from dir within fsys. dir is typically "drizzle" when using `//go:embed drizzle/*` from a project root that has a `drizzle/` directory; pass "." when fsys is already rooted at the migrations directory.

func (*DrizzleMigrator) LoadEntries

func (d *DrizzleMigrator) LoadEntries() ([]DrizzleEntry, error)

LoadEntries reads and hashes every migration referenced by the journal. Useful for tooling — Up calls it internally.

func (*DrizzleMigrator) Status

func (d *DrizzleMigrator) Status(ctx context.Context) ([]DrizzleStatus, error)

Status reports every entry in the journal and whether it has been applied (matched by hash, the same way drizzle-orm matches).

func (*DrizzleMigrator) Up

func (d *DrizzleMigrator) Up(ctx context.Context) error

Up applies every pending migration in journal order. Each migration runs in its own transaction; failure of any statement rolls back that migration only.

func (*DrizzleMigrator) WithSchema

func (d *DrizzleMigrator) WithSchema(schema string) *DrizzleMigrator

WithSchema overrides the migration history schema. Match drizzle.config.ts's `migrationsSchema` to stay interoperable.

func (*DrizzleMigrator) WithTable

func (d *DrizzleMigrator) WithTable(table string) *DrizzleMigrator

WithTable overrides the migration history table name. Match drizzle.config.ts's `migrationsTable` to stay interoperable.

type DrizzleStatus

type DrizzleStatus struct {
	Tag     string
	Hash    string
	Applied bool
	When    int64 // journal timestamp (unix milliseconds)
}

DrizzleStatus is one row of the Status report.

type FK

type FK struct {
	Target   *Column
	OnDelete string
	OnUpdate string
}

FK describes a foreign-key reference.

type FindBuilder

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

FindBuilder composes a SELECT and (optionally) eager-loads relations declared via NewRelations. It mirrors a subset of SelectBuilder's API — Where, OrderBy, Limit, Offset — and adds With/WithRel for relations.

func (*FindBuilder) All

func (f *FindBuilder) All(ctx context.Context, dest any) error

All runs the find and populates dest, which must be *[]Struct or *[]*Struct. Each requested relation is loaded with a single follow-up query and stitched onto the right field of every parent.

func (*FindBuilder) Limit

func (f *FindBuilder) Limit(n int64) *FindBuilder

Limit sets the LIMIT.

func (*FindBuilder) Offset

func (f *FindBuilder) Offset(n int64) *FindBuilder

Offset sets the OFFSET.

func (*FindBuilder) One

func (f *FindBuilder) One(ctx context.Context, dest any) error

One runs the find and populates dest, a pointer to a struct. Returns ErrNoRows if no row matches.

func (*FindBuilder) OrderBy

func (f *FindBuilder) OrderBy(exprs ...drops.Expression) *FindBuilder

OrderBy appends ORDER BY expressions.

func (*FindBuilder) Where

func (f *FindBuilder) Where(preds ...drops.Expression) *FindBuilder

Where appends predicates joined by AND.

func (*FindBuilder) With

func (f *FindBuilder) With(names ...string) *FindBuilder

With marks one or more relations to eager-load. Names must match relations declared on the table via NewRelations.

Nested relations are expressed with dot paths: With("posts.comments") loads each parent's posts, then every comment of those posts. Paths that share a prefix are merged, so With("posts.comments", "posts.tags") fetches posts once and fans out into comments and tags. Each relation edge costs one extra query regardless of how many parents it spans.

Use WithRel when a relation needs filtering or ordering.

func (*FindBuilder) WithRel

func (f *FindBuilder) WithRel(name string, fn func(*RelConfig)) *FindBuilder

WithRel eager-loads a single relation with per-relation constraints. The callback receives a RelConfig to filter (Where), order (OrderBy), and declare deeper relations (With/WithRel):

db.Find(Users).WithRel("posts", func(p *pg.RelConfig) {
    p.Where(Posts.Published.Eq(true)).
        OrderBy(Posts.CreatedAt.Desc()).
        With("comments")
}).All(ctx, &users)

name may itself be a dot path; the constraints attach to its leaf. A relation configured by WithRel and also named in With merges into the same edge, so it is still fetched once.

type ForeignKeySnapshot

type ForeignKeySnapshot struct {
	Name        string   `json:"name"`
	TableFrom   string   `json:"tableFrom"`
	ColumnsFrom []string `json:"columnsFrom"`
	TableTo     string   `json:"tableTo"`
	SchemaTo    string   `json:"schemaTo"`
	ColumnsTo   []string `json:"columnsTo"`
	OnDelete    string   `json:"onDelete"`
	OnUpdate    string   `json:"onUpdate"`
}

ForeignKeySnapshot is one entry in TableSnapshot.ForeignKeys.

type FunctionOptions

type FunctionOptions struct {
	Args       string // raw, e.g. "a integer, b integer"
	Returns    string // raw, e.g. "integer" or "trigger"
	Language   string // default "plpgsql"
	Body       string // function body (without surrounding $$ delimiters)
	Volatility string // "IMMUTABLE", "STABLE", "VOLATILE" (default omitted)
	OrReplace  bool
}

FunctionOptions configures CreateFunction.

type GenerateOptions

type GenerateOptions struct {
	// Schema is the current desired schema. Required.
	Schema *Schema

	// Dir is the migration directory — both the root for FS reads (if FS
	// is nil) and the destination for Write (if Write is nil). Required.
	Dir string

	// Name is the suffix appended to the migration tag — e.g. "init"
	// produces "0000_init". If empty, a random two-word name is generated.
	Name string

	// FS is an optional override for reads. When set, the journal and
	// previous snapshot are read from FS (paths relative to Dir become
	// paths relative to the FS root). When nil, os.DirFS is used.
	FS fs.FS

	// Write is an optional override for file writes. When set, it is
	// called for each output file (relative path within Dir + bytes).
	// When nil, files are written to disk under Dir with os.WriteFile.
	Write func(relPath string, data []byte) error

	// Now overrides the timestamp written into journal entries (unix
	// milliseconds). When nil, time.Now().UnixMilli() is used.
	Now func() int64

	// NameFn overrides the random-name generator used when Name is empty.
	NameFn func() string

	// Safe wraps every destructive or creative DDL in IF [NOT] EXISTS
	// so the migration can be re-run idempotently. See DiffOptions.Safe.
	Safe bool
}

GenerateOptions configures a single migration-generation run.

The default behaviour reads from and writes to a single Dir on disk. All FS-touching fields can be overridden for tests or for embedding the generator in tooling that wants to capture output in memory.

type GenerateResult

type GenerateResult struct {
	Tag      string // e.g. "0003_warm_iron_man"; empty when NoOp
	Idx      int    // sequence index for the new migration
	SQL      string // statement-breakpoint-joined migration SQL
	NoOp     bool   // true when prev and cur snapshots are equivalent
	Snapshot []byte // bytes written to meta/<idx>_snapshot.json
	Journal  []byte // bytes written to meta/_journal.json
}

GenerateResult describes what a Run produced.

func GenerateMigration

func GenerateMigration(opts GenerateOptions) (*GenerateResult, error)

GenerateMigration computes the schema diff and writes a new drizzle-kit migration set: <tag>.sql, meta/<idx>_snapshot.json and an updated meta/_journal.json.

It is a no-op when there are no differences between the current Go schema and the latest snapshot; no files are written in that case.

type Index

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

Index describes a PostgreSQL index. It is built via NewIndex (or the fluent helpers Unique, Concurrently, Where, Include, Using, On) and rendered with CreateIndex / DropIndex.

func NewIndex

func NewIndex(name string, t *Table, cols ...drops.Expression) *Index

NewIndex declares an index on t spanning cols. Cols may be column references (*Col[T] / *Column) or arbitrary expressions — Lower(c), pg.Func("upper", c), etc. — for functional indexes.

func (*Index) Concurrently

func (i *Index) Concurrently() *Index

Concurrently emits the CONCURRENTLY keyword (PG creates the index without taking a long-lived ACCESS EXCLUSIVE lock; cannot run inside a transaction).

func (*Index) Include

func (i *Index) Include(cols ...*Column) *Index

Include adds columns to the INCLUDE clause (covering indexes).

func (*Index) Name

func (i *Index) Name() string

Name returns the unqualified index name.

func (*Index) OpClass

func (i *Index) OpClass(class VectorOpClass) *Index

OpClass attaches a per-column operator class hint to the most recent column in the index. Use it alongside Using("hnsw") or Using("ivfflat") on a vector index:

idx := pg.NewIndex("items_embedding_idx", Items, Embedding).
    Using("hnsw").
    OpClass(pg.VectorCosineOps).
    With("m = 16, ef_construction = 64")

(Index.With and OpClass are pgvector additions to the Index type; see index.go for the underlying fields.)

func (*Index) Table

func (i *Index) Table() *Table

Table returns the table the index is on.

func (*Index) Unique

func (i *Index) Unique() *Index

Unique marks the index as UNIQUE.

func (*Index) Using

func (i *Index) Using(method string) *Index

Using sets the access method (btree, hash, gin, gist, brin, spgist).

func (*Index) Where

func (i *Index) Where(pred drops.Expression) *Index

Where adds a partial-index predicate.

func (*Index) With

func (i *Index) With(spec string) *Index

With attaches a `WITH (key = value, ...)` clause — the conventional place for pgvector index parameters (m, ef_construction, lists).

type InsertBuilder

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

InsertBuilder composes an INSERT statement.

Rows are supplied via Row (one row at a time) or Rows (a batch). The column order across rows is fixed by the first Row call — subsequent rows must target the same set of columns; columns not bound on a row receive DEFAULT.

func (*InsertBuilder) All

func (i *InsertBuilder) All(ctx context.Context, dest any) error

All executes the INSERT and scans the RETURNING rows into dest.

func (*InsertBuilder) Exec

func (i *InsertBuilder) Exec(ctx context.Context) (drops.Result, error)

Exec runs the INSERT.

func (*InsertBuilder) OnConflictDoNothing

func (i *InsertBuilder) OnConflictDoNothing(target ...ColRef) *InsertBuilder

OnConflictDoNothing adds ON CONFLICT [(target...)] DO NOTHING.

func (*InsertBuilder) OnConflictUpdate

func (i *InsertBuilder) OnConflictUpdate(target ...ColRef) *ConflictUpdate

OnConflictUpdate begins an ON CONFLICT (target...) DO UPDATE SET ... clause. Pair with Set / Where to populate the update.

func (*InsertBuilder) One

func (i *InsertBuilder) One(ctx context.Context, dest any) error

One executes the INSERT and scans the first RETURNING row into dest.

func (*InsertBuilder) Returning

func (i *InsertBuilder) Returning(cols ...drops.Expression) *InsertBuilder

Returning sets a RETURNING clause.

func (*InsertBuilder) Row

func (i *InsertBuilder) Row(values ...ColumnValue) *InsertBuilder

Row appends a single row. The first Row determines the column list.

func (*InsertBuilder) Rows

func (i *InsertBuilder) Rows(rows ...[]ColumnValue) *InsertBuilder

Rows appends multiple rows in a single call. Equivalent to calling Row once per slice element.

func (*InsertBuilder) ToSQL

func (i *InsertBuilder) ToSQL() (string, []any)

ToSQL renders the statement.

func (*InsertBuilder) WriteSQL

func (i *InsertBuilder) WriteSQL(b *drops.Builder)

WriteSQL renders the INSERT statement.

type IntrospectOptions

type IntrospectOptions struct {
	// Schemas restricts the introspection to these schema names. Empty
	// means just "public".
	Schemas []string
}

IntrospectOptions tunes which schemas Introspect inspects.

type LoggerFunc

type LoggerFunc = drops.LoggerFunc

LoggerFunc / LoggerOptions / LoggerHook are aliases for the dialect-neutral versions in the root drops package. They are kept here so existing pg-only call sites compile unchanged.

New code should prefer drops.LoggerHook + drops.LoggerOptions directly — the same hook works against pg.DB, clickhouse.DB and qdrant.Client without modification.

type LoggerOptions

type LoggerOptions = drops.LoggerOptions

LoggerFunc / LoggerOptions / LoggerHook are aliases for the dialect-neutral versions in the root drops package. They are kept here so existing pg-only call sites compile unchanged.

New code should prefer drops.LoggerHook + drops.LoggerOptions directly — the same hook works against pg.DB, clickhouse.DB and qdrant.Client without modification.

type Migration

type Migration struct {
	Version string // sortable string — zero-padded numeric is recommended ("0001")
	Name    string // human-readable label, used only for status output
	Up      func(ctx context.Context, db *DB) error
	Down    func(ctx context.Context, db *DB) error
}

Migration is one unit of schema change. Up and Down may be nil; a nil Down means the migration is irreversible (Down() will refuse to roll it back).

type Migrator

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

Migrator runs database migrations and tracks their history in a table.

func NewMigrator

func NewMigrator(db *DB) *Migrator

NewMigrator returns a migrator bound to db. Add migrations with Add / AddSQL / AddFS, then call Up.

func (*Migrator) Add

func (m *Migrator) Add(mig Migration) *Migrator

Add registers a single migration.

func (*Migrator) AddFS

func (m *Migrator) AddFS(fsys fs.FS, dir string) error

AddFS scans dir within fsys for migration files and registers them.

Filename format: <version>_<name>.up.sql and (optionally) <version>_<name>.down.sql — for example, "0001_create_users.up.sql". Versions are compared lexicographically; zero-pad numeric versions.

func (*Migrator) AddSQL

func (m *Migrator) AddSQL(version, name, upSQL, downSQL string) *Migrator

AddSQL registers a migration whose Up and Down are raw SQL. downSQL may be empty.

func (*Migrator) Down

func (m *Migrator) Down(ctx context.Context) error

Down rolls back the most recently applied migration. Returns ErrNoMigrationsApplied if there are none.

func (*Migrator) Status

func (m *Migrator) Status(ctx context.Context) ([]Status, error)

Status reports every registered migration and whether it has been applied.

func (*Migrator) Up

func (m *Migrator) Up(ctx context.Context) error

Up applies every registered migration that hasn't been applied yet, in version order. Each migration runs in its own transaction.

func (*Migrator) WithTable

func (m *Migrator) WithTable(name string) *Migrator

WithTable overrides the migrations history table (default DefaultMigrationsTable).

type PgEnum

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

PgEnum describes a PostgreSQL enum type. Use it to declare the type once and then reference it from one or more columns via EnumCol.

func NewEnum

func NewEnum(name string, values ...string) *PgEnum

NewEnum declares a PostgreSQL enum type with the given values.

func (*PgEnum) Col

func (e *PgEnum) Col(name string) *Col[string]

EnumCol returns a column of this enum type. The Go value type is string — drizzle-orm uses the same mapping. Use Custom[Foo] if you have a typed string wrapper you want preserved instead.

func (*PgEnum) Name

func (e *PgEnum) Name() string

Name returns the enum's type name.

func (*PgEnum) Values

func (e *PgEnum) Values() []string

Values returns the labels in declaration order.

type PushOptions

type PushOptions struct {
	// Schema restricts introspection to one PostgreSQL schema. Empty
	// defaults to "public".
	Schema string

	// Safe wraps every destructive or creative DDL in IF [NOT] EXISTS
	// so the apply is idempotent and safe to retry.
	Safe bool

	// DryRun returns the statements that would be applied without
	// executing them. Useful for previewing changes in CI.
	DryRun bool
}

PushOptions tunes how Push applies schema changes.

type PushResult

type PushResult struct {
	// Statements is the ordered SQL diff between the live database and
	// the supplied Go schema.
	Statements []string
	// Applied is true when the statements were executed (false for
	// DryRun, or when the diff was empty).
	Applied bool
}

PushResult is the outcome of a Push call.

func Push

func Push(ctx context.Context, db *DB, schema *Schema, opts ...PushOptions) (*PushResult, error)

Push introspects the live database, diffs it against the supplied Go schema, and applies the changes — drops's equivalent of drizzle-kit's `push` command.

Behaviour:

  • Reads the current state of the configured schema via Introspect.
  • Builds a target snapshot from `schema`.
  • Diffs the two using DiffOptions{Safe: opts.Safe}.
  • If DryRun, returns the statements unexecuted.
  • Otherwise applies them inside a single transaction; any failure rolls back the whole push.

Push is convenient for development but skips migration history. For production use, prefer GenerateMigration + DrizzleMigrator so changes are reviewable and reproducible.

type RelConfig

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

RelConfig configures a single eager-loaded relation: filter the related rows with Where, order them with OrderBy, and declare deeper relations with With/WithRel. It is handed to the callback passed to WithRel.

Where predicates and OrderBy expressions reference the related table's columns and are applied to that relation's batched query, so they cost nothing extra — one query per edge, just narrower or sorted.

func (*RelConfig) OrderBy

func (c *RelConfig) OrderBy(exprs ...drops.Expression) *RelConfig

OrderBy appends ORDER BY expressions to this relation's batched query. Each parent's loaded slice ends up in this order.

func (*RelConfig) Where

func (c *RelConfig) Where(preds ...drops.Expression) *RelConfig

Where AND-s predicates into this relation's batched query, filtering the related rows (e.g. only published posts).

func (*RelConfig) With

func (c *RelConfig) With(names ...string) *RelConfig

With declares deeper relations to eager-load beneath this one, using the same dot-path syntax as FindBuilder.With.

func (*RelConfig) WithRel

func (c *RelConfig) WithRel(name string, fn func(*RelConfig)) *RelConfig

WithRel declares a deeper, individually configured relation beneath this one.

type Relation

type Relation struct {
	Name      string
	Kind      RelationKind
	From      *Table
	To        *Table
	ParentKey *Column
	ChildKey  *Column

	// Junction-table fields, populated only for ManyToManyKind.
	Through    *Table
	ThroughFK1 *Column
	ThroughFK2 *Column
}

Relation describes a foreign-key relationship between two tables.

HasMany / HasOne: From is the parent, To is the child.
  ParentKey is the column on From (typically the PK).
  ChildKey  is the FK column on To pointing back at ParentKey.

BelongsTo: From is the child, To is the parent.
  ChildKey  is the FK column on From.
  ParentKey is the column on To pointed at by ChildKey.

ManyToMany: From and To are joined through a junction Table.
  ParentKey  is the column on From (typically the PK).
  ChildKey   is the column on To (typically the PK).
  Through    is the junction table.
  ThroughFK1 is the FK on Through pointing back to ParentKey.
  ThroughFK2 is the FK on Through pointing to ChildKey.

type RelationKind

type RelationKind int

RelationKind identifies the cardinality of a Relation.

const (
	// HasMany: the parent owns zero or more children. The relation is
	// loaded as a slice on the parent struct.
	HasManyKind RelationKind = iota
	// HasOne: the parent owns at most one child. The relation is loaded
	// as a struct or pointer-to-struct on the parent.
	HasOneKind
	// BelongsTo: this row references one parent. The relation is loaded
	// as a struct or pointer-to-struct.
	BelongsToKind
	// ManyToMany: parent and target are linked through a junction table.
	// The relation is loaded as a slice on the parent struct.
	ManyToManyKind
)

type Relations

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

Relations is the registration handle for one table. Use NewRelations followed by HasMany/HasOne/BelongsTo to declare relations:

pg.NewRelations(Users).
    HasMany("posts", Posts, UserID, PostUserID).
    HasOne("profile", Profiles, UserID, ProfileUserID)

pg.NewRelations(Posts).
    BelongsTo("author", Users, PostUserID, UserID)

func NewRelations

func NewRelations(t *Table) *Relations

NewRelations begins relation declarations for t. The returned handle stores its declarations on t directly.

func (*Relations) BelongsTo

func (r *Relations) BelongsTo(name string, parent *Table, childFK, parentKey ColRef) *Relations

BelongsTo declares a many-to-one relation.

childFK:   FK column on the current table.
parentKey: column on `parent` pointed at by childFK.

func (*Relations) HasMany

func (r *Relations) HasMany(name string, child *Table, parentKey, childFK ColRef) *Relations

HasMany declares a one-to-many relation.

parentKey: column on the current table (usually the PK).
childFK:   FK column on `child` pointing at parentKey.

func (*Relations) HasOne

func (r *Relations) HasOne(name string, child *Table, parentKey, childFK ColRef) *Relations

HasOne declares a one-to-one relation. The cardinality is enforced by data conventions, not by SQL — it loads at most one row per parent.

func (*Relations) ManyToMany

func (r *Relations) ManyToMany(
	name string,
	target *Table,
	through *Table,
	throughLocal, throughRemote ColRef,
	localKey, targetKey ColRef,
) *Relations

ManyToMany declares a many-to-many relation through a junction table.

target:        the related table
through:       the junction table
throughLocal:  FK on through pointing back at the current table
throughRemote: FK on through pointing at the target table
localKey:      key on the current table (typically the PK)
targetKey:     key on the target table (typically the PK)

Loading runs two queries: one to fetch the junction rows for the parent IDs, one to fetch the target rows for the unique remote IDs. The relation field on the parent struct must be a slice.

type Schema

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

Schema is a registered set of tables — the input to snapshotting, diffing and migration generation. It is just a thin wrapper around a slice of *Table; the table declarations themselves are unaffected.

func NewSchema

func NewSchema(tables ...*Table) *Schema

NewSchema returns a Schema containing the supplied tables.

func (*Schema) Add

func (s *Schema) Add(t *Table) *Schema

Add appends a table.

func (*Schema) Tables

func (s *Schema) Tables() []*Table

Tables returns the registered tables.

type SelectBuilder

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

SelectBuilder composes a SELECT statement.

func (*SelectBuilder) All

func (s *SelectBuilder) All(ctx context.Context, dest any) error

All executes the SELECT and scans every row into dest, which must be a pointer to a slice of structs (or pointer-to-structs).

func (*SelectBuilder) AsSubquery

func (s *SelectBuilder) AsSubquery(alias string) drops.Expression

AsSubquery returns a parenthesised, aliased form of the SELECT for use as a subquery in another statement.

func (*SelectBuilder) Count

func (s *SelectBuilder) Count(ctx context.Context) (int64, error)

Count returns the number of rows the current SELECT would produce, computed as SELECT count(*) FROM (<original>) AS _drops_count. The original ORDER BY / LIMIT / OFFSET are kept inside the subquery so LIMIT-aware page counts work correctly.

For un-paginated counts on simple SELECTs, this is the natural and safe shape — PostgreSQL will optimise the inner query as needed.

func (*SelectBuilder) Distinct

func (s *SelectBuilder) Distinct() *SelectBuilder

Distinct toggles SELECT DISTINCT.

func (*SelectBuilder) DistinctOn

func (s *SelectBuilder) DistinctOn(exprs ...drops.Expression) *SelectBuilder

DistinctOn renders SELECT DISTINCT ON (exprs...). Mutually exclusive with Distinct().

func (*SelectBuilder) Except

func (s *SelectBuilder) Except(other *SelectBuilder) *SelectBuilder

Except appends EXCEPT <select>.

func (*SelectBuilder) ExceptAll

func (s *SelectBuilder) ExceptAll(other *SelectBuilder) *SelectBuilder

ExceptAll appends EXCEPT ALL <select>.

func (*SelectBuilder) ForUpdate

func (s *SelectBuilder) ForUpdate() *SelectBuilder

ForUpdate appends FOR UPDATE row locking.

func (*SelectBuilder) From

func (s *SelectBuilder) From(t *Table) *SelectBuilder

From sets the FROM clause. Required before execution.

func (*SelectBuilder) FromExpr

func (s *SelectBuilder) FromExpr(e drops.Expression) *SelectBuilder

FromExpr appends an arbitrary FROM source — a subquery, CTE reference, set-returning function, etc. Multiple FROMs are comma-joined (i.e. cross-joined).

func (*SelectBuilder) FullJoin

func (s *SelectBuilder) FullJoin(t *Table, on drops.Expression) *SelectBuilder

FullJoin appends a FULL OUTER JOIN.

func (*SelectBuilder) GroupBy

func (s *SelectBuilder) GroupBy(exprs ...drops.Expression) *SelectBuilder

GroupBy appends GROUP BY expressions.

func (*SelectBuilder) Having

func (s *SelectBuilder) Having(preds ...drops.Expression) *SelectBuilder

Having appends predicates to the HAVING clause (joined by AND).

func (*SelectBuilder) Intersect

func (s *SelectBuilder) Intersect(other *SelectBuilder) *SelectBuilder

Intersect appends INTERSECT <select>.

func (*SelectBuilder) IntersectAll

func (s *SelectBuilder) IntersectAll(other *SelectBuilder) *SelectBuilder

IntersectAll appends INTERSECT ALL <select>.

func (*SelectBuilder) Join

Join appends an INNER JOIN.

func (*SelectBuilder) LeftJoin

func (s *SelectBuilder) LeftJoin(t *Table, on drops.Expression) *SelectBuilder

LeftJoin appends a LEFT JOIN.

func (*SelectBuilder) Limit

func (s *SelectBuilder) Limit(n int64) *SelectBuilder

Limit sets the LIMIT.

func (*SelectBuilder) Offset

func (s *SelectBuilder) Offset(n int64) *SelectBuilder

Offset sets the OFFSET.

func (*SelectBuilder) One

func (s *SelectBuilder) One(ctx context.Context, dest any) error

One executes the SELECT and scans the first row into dest. Returns ErrNoRows if no row is produced.

func (*SelectBuilder) OrderBy

func (s *SelectBuilder) OrderBy(exprs ...drops.Expression) *SelectBuilder

OrderBy appends ORDER BY expressions. Use Column.Asc / Column.Desc for direction.

func (*SelectBuilder) RightJoin

func (s *SelectBuilder) RightJoin(t *Table, on drops.Expression) *SelectBuilder

RightJoin appends a RIGHT JOIN.

func (*SelectBuilder) Rows

func (s *SelectBuilder) Rows(ctx context.Context) (drops.Rows, error)

Rows executes the SELECT and returns the raw cursor for manual scanning.

func (*SelectBuilder) ToSQL

func (s *SelectBuilder) ToSQL() (string, []any)

ToSQL renders the statement to a SQL string and arg list.

func (*SelectBuilder) Union

func (s *SelectBuilder) Union(other *SelectBuilder) *SelectBuilder

Union appends UNION <select>. Multiple set operations are chainable.

func (*SelectBuilder) UnionAll

func (s *SelectBuilder) UnionAll(other *SelectBuilder) *SelectBuilder

UnionAll appends UNION ALL <select>.

func (*SelectBuilder) Where

func (s *SelectBuilder) Where(preds ...drops.Expression) *SelectBuilder

Where appends predicates joined by AND.

func (*SelectBuilder) With

func (s *SelectBuilder) With(ctes ...*CTE) *SelectBuilder

With prepends a WITH clause to the SELECT. Multiple calls accumulate.

func (*SelectBuilder) WithRecursive

func (s *SelectBuilder) WithRecursive(ctes ...*CTE) *SelectBuilder

WithRecursive marks the WITH clause as RECURSIVE. Only one mode is possible per statement; calling this is sticky.

func (*SelectBuilder) WriteSQL

func (s *SelectBuilder) WriteSQL(b *drops.Builder)

WriteSQL renders the SELECT into a Builder. Wrapped in parentheses so the same builder can be embedded as a subquery.

type SequenceOptions

type SequenceOptions struct {
	Start     *int64
	Increment *int64
	MinValue  *int64
	MaxValue  *int64
	Cache     *int64
	Cycle     bool
	OwnedBy   *Column // optional: link sequence ownership to a column
}

SequenceOptions configures CreateSequence.

type Snapshot

type Snapshot struct {
	ID        string                    `json:"id"`
	PrevID    string                    `json:"prevId"`
	Version   string                    `json:"version"`
	Dialect   string                    `json:"dialect"`
	Tables    map[string]*TableSnapshot `json:"tables"`
	Enums     map[string]any            `json:"enums"`
	Schemas   map[string]any            `json:"schemas"`
	Sequences map[string]any            `json:"sequences"`
	Roles     map[string]any            `json:"roles"`
	Policies  map[string]any            `json:"policies"`
	Views     map[string]any            `json:"views"`
	Meta      SnapshotMeta              `json:"_meta"`
}

Snapshot is the on-disk representation of a database schema as written to drizzle-kit's meta/<idx>_snapshot.json. The JSON keys match drizzle-kit's PostgreSQL snapshot v7 format so a Snapshot produced by drops is round-trippable through drizzle-kit, and vice versa.

func BuildSnapshot

func BuildSnapshot(schema *Schema) *Snapshot

BuildSnapshot constructs a snapshot from a Go schema definition. The resulting ID is a fresh UUID v4; PrevID defaults to zeroUUID and the caller should overwrite it from the previous snapshot, if any.

func EmptySnapshot

func EmptySnapshot() *Snapshot

EmptySnapshot returns a fresh snapshot with no tables. Useful as the "previous" snapshot when diffing the first migration.

func Introspect

func Introspect(ctx context.Context, db *DB, opts ...IntrospectOptions) (*Snapshot, error)

Introspect queries the live database and returns a Snapshot describing its current state — tables, columns (with type normalisation matching drizzle-kit's conventions: bigserial / serial / smallserial detected from int + nextval default), primary keys, single-column unique constraints, and single-column foreign keys with referential actions.

The returned snapshot is in the same format as BuildSnapshot's output and can be diffed against a Go-schema snapshot via Diff. It deliberately leaves indexes, composite keys, enums, sequences and views empty — those features aren't yet representable in drops's schema layer.

func UnmarshalSnapshot

func UnmarshalSnapshot(data []byte) (*Snapshot, error)

UnmarshalSnapshot parses a snapshot from JSON, restoring zero-valued maps for any nil collections (so subsequent reads/diffs don't have to check for nil).

func (*Snapshot) Marshal

func (s *Snapshot) Marshal() ([]byte, error)

Marshal returns the snapshot as the canonical 2-space-indented JSON drizzle-kit produces.

type SnapshotMeta

type SnapshotMeta struct {
	Columns map[string]any `json:"columns"`
	Schemas map[string]any `json:"schemas"`
	Tables  map[string]any `json:"tables"`
}

SnapshotMeta carries rename-tracking annotations. drops never sets these; the field is present for drizzle-kit compatibility.

type Status

type Status struct {
	Version   string
	Name      string
	Applied   bool
	AppliedAt time.Time // zero if not applied
}

Status is a single row produced by Migrator.Status.

type Table

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

Table represents a schema-qualified PostgreSQL table.

func NewSchemaTable

func NewSchemaTable(schema, name string) *Table

NewSchemaTable creates a table in an explicit schema.

func NewTable

func NewTable(name string) *Table

NewTable creates a table in the default ("public") schema. The name is validated and the constructor panics on invalid identifiers — see ErrInvalidIdentifier — because schemas are typically declared in package init / var blocks where a bad name should fail loudly at startup rather than at the first query.

func (*Table) Alias

func (t *Table) Alias() string

Alias returns the alias set via As, or "" if none.

func (*Table) As

func (t *Table) As(alias string) *Table

As returns a shallow copy of the table bound to alias.

func (*Table) Col

func (t *Table) Col(name string) *Column

Col looks up a registered column by name.

func (*Table) Columns

func (t *Table) Columns() []*Column

Columns returns all registered columns in declaration order.

func (*Table) Name

func (t *Table) Name() string

Name returns the table's unqualified name.

func (*Table) Relation

func (t *Table) Relation(name string) *Relation

Relation looks up a registered relation by name. Returns nil if no such relation exists.

func (*Table) Schema

func (t *Table) Schema() string

Schema returns the table's schema (empty for the default schema).

func (*Table) WriteSQL

func (t *Table) WriteSQL(b *drops.Builder)

WriteSQL writes the FROM/JOIN form. Implements drops.Expression.

type TableSnapshot

type TableSnapshot struct {
	Name                 string                         `json:"name"`
	Schema               string                         `json:"schema"`
	Columns              map[string]*ColumnSnapshot     `json:"columns"`
	Indexes              map[string]any                 `json:"indexes"`
	ForeignKeys          map[string]*ForeignKeySnapshot `json:"foreignKeys"`
	CompositePrimaryKeys map[string]any                 `json:"compositePrimaryKeys"`
	UniqueConstraints    map[string]*UniqueSnapshot     `json:"uniqueConstraints"`
	Policies             map[string]any                 `json:"policies"`
	CheckConstraints     map[string]any                 `json:"checkConstraints"`
	IsRLSEnabled         bool                           `json:"isRLSEnabled"`
}

TableSnapshot is one entry in Snapshot.Tables.

type TriggerOptions

type TriggerOptions struct {
	Timing    string // "BEFORE" | "AFTER" | "INSTEAD OF"
	Events    string // "INSERT" | "UPDATE" | "DELETE" | combinations like "INSERT OR UPDATE"
	Table     *Table
	ForEach   string // "ROW" or "STATEMENT" (default "ROW")
	When      string // raw SQL condition (optional)
	Execute   string // raw, e.g. "my_func()"
	OrReplace bool
}

TriggerOptions configures CreateTrigger.

type UniqueSnapshot

type UniqueSnapshot struct {
	Name             string   `json:"name"`
	NullsNotDistinct bool     `json:"nullsNotDistinct"`
	Columns          []string `json:"columns"`
}

UniqueSnapshot is one entry in TableSnapshot.UniqueConstraints.

type UpdateBuilder

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

UpdateBuilder composes an UPDATE statement.

func (*UpdateBuilder) All

func (u *UpdateBuilder) All(ctx context.Context, dest any) error

All executes the UPDATE and scans the RETURNING rows into dest.

func (*UpdateBuilder) Exec

func (u *UpdateBuilder) Exec(ctx context.Context) (drops.Result, error)

Exec runs the UPDATE.

func (*UpdateBuilder) From

func (u *UpdateBuilder) From(tables ...*Table) *UpdateBuilder

From adds tables to a PostgreSQL UPDATE ... FROM clause for joins.

func (*UpdateBuilder) One

func (u *UpdateBuilder) One(ctx context.Context, dest any) error

One executes the UPDATE and scans the first RETURNING row into dest.

func (*UpdateBuilder) Returning

func (u *UpdateBuilder) Returning(cols ...drops.Expression) *UpdateBuilder

Returning sets a RETURNING clause.

func (*UpdateBuilder) Set

func (u *UpdateBuilder) Set(values ...ColumnValue) *UpdateBuilder

Set adds one or more assignments. Use (*Col[T]).Val(v) to bind a typed value or (*Col[T]).Expr(e) to bind an expression.

func (*UpdateBuilder) ToSQL

func (u *UpdateBuilder) ToSQL() (string, []any)

ToSQL renders the statement.

func (*UpdateBuilder) Where

func (u *UpdateBuilder) Where(preds ...drops.Expression) *UpdateBuilder

Where appends predicates joined by AND.

func (*UpdateBuilder) WriteSQL

func (u *UpdateBuilder) WriteSQL(b *drops.Builder)

WriteSQL renders the UPDATE.

type VectorOpClass

type VectorOpClass string

VectorOpClass is one of the per-distance-metric operator classes pgvector exposes for indexing. Pass the relevant value to (*Index).OpClass() on a Vector column.

const (
	VectorL2Ops     VectorOpClass = "vector_l2_ops"
	VectorIPOps     VectorOpClass = "vector_ip_ops"
	VectorCosineOps VectorOpClass = "vector_cosine_ops"
	VectorL1Ops     VectorOpClass = "vector_l1_ops"

	HalfVecL2Ops     VectorOpClass = "halfvec_l2_ops"
	HalfVecIPOps     VectorOpClass = "halfvec_ip_ops"
	HalfVecCosineOps VectorOpClass = "halfvec_cosine_ops"

	BitHammingOps VectorOpClass = "bit_hamming_ops"
	BitJaccardOps VectorOpClass = "bit_jaccard_ops"
)

type Window

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

Window describes the contents of an OVER (...) clause.

func WindowSpec

func WindowSpec() *Window

WindowSpec begins building a window specification.

func (*Window) Frame

func (w *Window) Frame(spec string) *Window

Frame sets the raw frame specification — e.g. "ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING".

func (*Window) OrderBy

func (w *Window) OrderBy(exprs ...drops.Expression) *Window

OrderBy adds ORDER BY entries to the window.

func (*Window) PartitionBy

func (w *Window) PartitionBy(exprs ...drops.Expression) *Window

PartitionBy adds PARTITION BY columns.

Jump to

Keyboard shortcuts

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