repository

package module
v0.16.1 Latest Latest
Warning

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

Go to latest
Published: Jun 2, 2026 License: MIT Imports: 22 Imported by: 24

README

Generic Repository with Go Generics and Bun ORM

A generic implementation of a data access layer using Go generics and Bun ORM.

Features

  • Generic repository pattern implementation
  • CRUD operations with transactional support
  • Dynamic query building with criteria functions
  • Custom identifiers and UUID support
  • Soft delete capabilities
  • Raw query execution
  • Bulk operations (CreateMany, UpdateMany, UpsertMany)
  • GetOrCreate and Upsert convenience methods
  • Map-native struct/map projection and patch helpers (no JSON roundtrip)
  • Multi-database support (PostgreSQL, SQLite, MSSQL, MySQL)
  • Sophisticated error handling with categorized errors
  • Model metadata extraction and field introspection
  • Transaction management utilities
  • Comprehensive test coverage

Installation

go get github.com/goliatone/go-repository-bun

Development Quality

This repository uses a taskfile-based Go quality workflow:

./taskfile go:tools:all
./taskfile go:fmt:check
./taskfile go:test
./taskfile go:lint:baseline
./taskfile go:quality:baseline

golangci-lint, govulncheck, and gosec are managed through ./taskfile. Existing lint and security findings are tracked in ops/quality/baselines/ so new work can be checked without requiring a full backlog cleanup first.

Usage

Import the package
import (
    repository "github.com/goliatone/go-repository-bun"
    "github.com/uptrace/bun"
    "github.com/google/uuid"
)
Defining Models
type User struct {
    bun.BaseModel `bun:"table:users,alias:u"`

    ID        uuid.UUID  `bun:"id,pk,notnull"`
    Name      string     `bun:"name,notnull"`
    Email     string     `bun:"email,notnull,unique"`
    DeletedAt *time.Time `bun:"deleted_at,soft_delete"`
    CreatedAt time.Time  `bun:"created_at,notnull"`
    UpdatedAt time.Time  `bun:"updated_at,notnull"`
}
Creating Repository
// Define handlers for your model
handlers := repository.ModelHandlers[*User]{
    NewRecord: func() *User {
        return &User{}
    },
    GetID: func(record *User) uuid.UUID {
        if record == nil {
            return uuid.Nil
        }
        return record.ID
    },
    SetID: func(record *User, id uuid.UUID) {
        record.ID = id
    },
    GetIdentifier: func() string {
        return "email" // Unique identifier field
    },
    GetIdentifierValue: func(record *User) string {
        if record == nil {
            return ""
        }
        return record.Email
    },
    ResolveIdentifier: func(identifier string) []repository.IdentifierOption {
        identifier = strings.TrimSpace(identifier)
        if identifier == "" {
            return nil
        }

        var lookups []repository.IdentifierOption

        if strings.Contains(identifier, "@") {
            lookups = append(lookups, repository.IdentifierOption{
                Column: "email",
                Value:  strings.ToLower(identifier),
            })
        }

        if _, err := uuid.Parse(identifier); err == nil {
            lookups = append(lookups, repository.IdentifierOption{
                Column: "id",
            })
        }

        // Always try username as a fallback.
        lookups = append(lookups, repository.IdentifierOption{
            Column: "username",
        })

        return lookups
    },
}

// Create repository instance
userRepo := repository.MustNewRepository[*User](db, handlers)

ResolveIdentifier is optional. When provided, the repository will try each returned IdentifierOption (column/value pair) in order until a record is found. Returning nil or an empty slice falls back to the default GetIdentifier/GetIdentifierValue behaviour.

For Upsert* and GetOrCreate*, you can also configure a composite/natural key resolver through repo options:

userRepo := repository.MustNewRepositoryWithConfig[*User](
    db,
    handlers,
    nil, // db options
    repository.WithRecordLookupResolver(func(record *User) []repository.SelectCriteria {
        if record == nil {
            return nil
        }
        return []repository.SelectCriteria{
            repository.SelectBy("company_id", "=", record.CompanyID.String()),
            repository.SelectBy("name", "=", record.Name),
            // Optional domain ordering
            repository.OrderBy("updated_at DESC"),
        }
    }),
)

Lookup precedence in Upsert*/GetOrCreate* is:

  1. ID
  2. identifier (GetIdentifierValue)
  3. WithRecordLookupResolver criteria

If resolver criteria are used, the repository appends a stable id ASC tie breaker to guarantee deterministic selection when criteria are not unique.

WithRecordLookupResolver is type checked against the repository model type. Mismatches fail validation and will fail Upsert*/GetOrCreate* fast if not validated explicitly.

Basic Operations
// Create
user := &User{Name: "John Doe", Email: "john.doe@example.com"}
created, err := userRepo.Create(ctx, user)

// Retrieve by ID
user, err := userRepo.GetByID(ctx, "user-uuid")

// Retrieve by identifier (email in this case)
user, err := userRepo.GetByIdentifier(ctx, "john.doe@example.com")

// Update
user.Name = "Jane Doe"
updated, err := userRepo.Update(ctx, user)

// Delete (soft delete if DeletedAt field exists)
err := userRepo.Delete(ctx, user)

// Force delete (permanent delete)
err := userRepo.ForceDelete(ctx, user)
Bulk Operations
// Create multiple records
users := []*User{
    {Name: "User 1", Email: "user1@example.com"},
    {Name: "User 2", Email: "user2@example.com"},
}
created, err := userRepo.CreateMany(ctx, users)

// Update multiple records
updated, err := userRepo.UpdateMany(ctx, users)

// Optional: reorder returned records to match input IDs
created, err = userRepo.CreateMany(ctx, users, repository.InsertReturnOrderByID())
updated, err = userRepo.UpdateMany(ctx, users, repository.UpdateReturnOrderByID())

// Upsert multiple records
upserted, err := userRepo.UpsertMany(ctx, users)
Convenience Methods
// Get or create
user := &User{Email: "new@example.com", Name: "New User"}
result, err := userRepo.GetOrCreate(ctx, user)

// Upsert (update if exists, create if not)
user := &User{ID: someID, Name: "Updated Name", Email: "email@example.com"}
result, err := userRepo.Upsert(ctx, user)
Scopes

Scopes let you register reusable filters that are applied automatically to repository operations.

const tenantScope = "tenant"

userRepo.RegisterScope(tenantScope, repository.ScopeDefinition{
    Select: func(ctx context.Context) []repository.SelectCriteria {
        value, ok := repository.ScopeData(ctx, tenantScope)
        if !ok {
            return nil
        }
        tenantID, ok := value.(uuid.UUID)
        if !ok || tenantID == uuid.Nil {
            return nil
        }
        return []repository.SelectCriteria{
            repository.SelectBy("company_id", "=", tenantID.String()),
        }
    },
})

if err := userRepo.SetScopeDefaults(repository.ScopeDefaults{
    Select: []string{tenantScope},
}); err != nil {
    panic(err)
}

To avoid duplicating the same guard logic in every scope, register the helper instead:

userRepo.RegisterScope(tenantScope, repository.ScopeByField(tenantScope, "company_id"))

ScopeByField is fail-closed: when scope data is missing/invalid, it adds a no-match predicate.

For explicit fail-open behavior (legacy), use ScopeByFieldOptional:

userRepo.RegisterScope(tenantScope, repository.ScopeByFieldOptional(tenantScope, "company_id"))

Activate scopes through the context. Default scopes run automatically unless disabled:

ctx := repository.WithScopeData(ctx, tenantScope, tenantID)
users, total, err := userRepo.List(ctx) // tenant scope applied

ctx = repository.WithoutDefaultScopes(ctx)
ctx = repository.WithSelectScopes(ctx, tenantScope)
ctx = repository.WithScopeData(ctx, tenantScope, tenantID)
users, total, err = userRepo.List(ctx) // scope applied explicitly

Other operations can be scoped with WithInsertScopes, WithUpdateScopes, and WithDeleteScopes.

When scope data is missing or empty, ScopeByField/ScopeByFieldRequired add a no-match predicate so queries fail closed. If you need fail-open behavior, use ScopeByFieldOptional. To surface configuration mistakes early, SetScopeDefaults validates that every default references a registered scope and returns a validation error otherwise.

If you need to propagate the active scope set into other infrastructure (for example, cache decorators), use repository.ResolveScopeState(ctx, defaults, repository.ScopeOperationSelect) together with repository.ScopeDataSnapshot(ctx) to build deterministic signatures.

For repositories that need explicit tenant/org predicates instead of registered context scopes, use the lower-level scope helpers:

expr, args, ok := repository.ScopeWhere(
	repository.ScopeColumns{Tenant: "cf.tenant_id", Org: "cf.org_id"},
	repository.ScopeValues{TenantID: tenantID, OrgID: orgID},
	repository.ScopeExact,
)
if ok {
	query = query.Where(expr, args...)
}

Supported modes are:

  • ScopeExact: match the provided tenant/org exactly and fail closed when a configured column has no value.
  • ScopeGlobal: match blank/global rows only.
  • ScopeExactOrGlobal: match exact rows or blank/global rows where explicitly allowed by the caller.

SelectScope, UpdateScope, and DeleteScope apply the generated predicates directly to Bun queries. DefaultScope(record, values) and DefaultScopeMap(values, scope) fill missing tenant/org values on scoped records or metadata maps before persistence. These helpers are app-agnostic: the caller decides whether single-tenant defaults, multi-tenant actor claims, or global fallback are allowed.

Query Criteria
// Legacy constructors keep compatibility defaults: LIMIT 25 OFFSET 0.
userRepo := repository.MustNewRepository[*User](db, handlers)
users, total, err := userRepo.List(ctx)

// List with pagination
users, total, err := userRepo.List(ctx,
    repository.SelectPaginate(10, 0),
    repository.OrderBy("created_at DESC"),
)

// Unsafe identifier/operator inputs are ignored or fail closed.
// Column names and operators are validated internally.
users, total, err = userRepo.List(ctx,
    repository.SelectBy("status", "=", "active"),
)

// Complex queries
users, total, err := userRepo.List(ctx,
    repository.SelectBy("status", "=", "active"),
    repository.SelectColumns("id", "name", "email"),
    repository.SelectRelation("Profile"),
    repository.SelectRawProcessor(func(q *bun.SelectQuery) *bun.SelectQuery {
        return q.Where("created_at > ?", time.Now().Add(-24*time.Hour)).
                WhereOr("updated_at > ?", time.Now().Add(-1*time.Hour))
    }),
)

// Count records
count, err := userRepo.Count(ctx,
    repository.SelectBy("status", "=", "active"),
)

// Delete with criteria
err := userRepo.DeleteWhere(ctx,
    repository.DeleteBy("status", "=", "inactive"),
    repository.DeleteByTimetz("created_at", "<", time.Now().Add(-365*24*time.Hour)),
)

// Delete by ID list
err = userRepo.DeleteWhere(ctx, repository.DeleteByIDs([]string{"id-1", "id-2"}))

DeleteWhere/DeleteMany now require at least one non-nil criteria function by default. To explicitly allow full-table deletes, configure:

userRepo := repository.MustNewRepositoryWithConfig[*User](
    db,
    handlers,
    nil,
    repository.WithAllowFullTableDelete(true),
)

Use the config constructor to disable implicit pagination defaults:

userRepo := repository.MustNewRepositoryWithConfig[*User](
    db,
    handlers,
    nil, // db options
    // no repo options => no implicit LIMIT/OFFSET
)

You can also set per repository defaults explicitly:

userRepo := repository.MustNewRepositoryWithConfig[*User](
    db,
    handlers,
    nil, // db options
    repository.WithDefaultListPagination(50, 0),
)

Runtime mutation is also available via SetDefaultListPagination(limit, offset), but it should be treated as an initialization stage setting. Changing defaults in live concurrent systems can lead to mixed pagination behavior across requests.

SetDefaultListPagination is exposed via the optional DefaultListPaginationConfigurer interface (not the base Repository interface):

if cfg, ok := userRepo.(repository.DefaultListPaginationConfigurer); ok {
    cfg.SetDefaultListPagination(25, 0)
}

Migration note: NewRepository and NewRepositoryWithOptions preserve legacy LIMIT 25 OFFSET 0 behavior for compatibility. To opt into unbounded default list behavior, use NewRepositoryWithConfig(..., nil) (or pass repo options explicitly).

Transactions
// Using manual transactions
tx, err := db.BeginTx(ctx, nil)
if err != nil {
    return err
}
defer tx.Rollback()

user, err := userRepo.CreateTx(ctx, tx, user)
if err != nil {
    return err
}

// All repository methods have Tx variants
updated, err := userRepo.UpdateTx(ctx, tx, user)
if err != nil {
    return err
}

err = tx.Commit()
Raw Queries
// Execute raw SQL queries
users, err := userRepo.Raw(ctx,
    "SELECT * FROM users WHERE created_at > ? AND status = ?",
    time.Now().Add(-24*time.Hour),
    "active",
)
Error Handling

The package provides categorized errors for better error handling:

err := userRepo.Create(ctx, user)
if err != nil {
    if repository.IsRecordNotFound(err) {
        // Handle not found
    }
    if repository.IsDuplicatedKey(err) {
        // Handle duplicate
    }
    if repository.IsConstraintViolation(err) {
        // Handle constraint violation
    }
    // Other error categories available
}
Map Native Helpers

Use map-native helpers when integrating generic admin adapters that exchange map[string]any.

mapper := repository.NewMapRecordMapper[*User](repository.MapRecordMapperConfig{
    ProjectionOptions: []repository.MapProjectionOption{
        repository.WithProjectionKeyMode(repository.MapKeyBun), // default
    },
    PatchOptions: []repository.MapPatchOption{
        repository.WithPatchKeyMode(repository.MapKeyBun), // default
        repository.WithPatchAllowedFields("name", "email", "updated_at"),
    },
})

payload := map[string]any{
    "name": "Updated Name",
}

record, err := mapper.ToRecord(payload)
asMap, err := mapper.ToMap(record)
patched, columns, err := mapper.ApplyPatch(record, payload)
_ = columns // Bun column names changed by the patch

ID based safe partial update flow:

updated, err := repository.UpdateByIDWithMapPatch(
    ctx,
    userRepo,
    userID,
    map[string]any{"name": "Updated Name"},
    nil, // optional update criteria
    repository.WithPatchAllowedFields("name"),
)

Direct query update criteria from a map payload:

criteria, err := repository.UpdateCriteriaForMapPatch(
    map[string]any{"name": "Updated Name"},
    repository.WithPatchAllowedFields("name"),
)
if err != nil {
    return err
}
// criteria includes UpdateColumns("name") + UpdateSetColumn("name", ...)

"Not found" checks support both helper and sentinel:

if repository.IsRecordNotFound(err) || errors.Is(err, repository.ErrRecordNotFound) {
    // handle not found
}

Advanced Features

Model Metadata

The package provides utilities to extract model metadata and field information:

// Get model fields with database metadata
fields := repository.GetModelFields(db, &User{})
for _, field := range fields {
    fmt.Printf("Field: %s, PK: %v, Type: %s\n", field.Name, field.IsPK, field.SQLType)
}

// Generate complete model metadata including JSON tags and validations
meta := repository.GenerateModelMeta(&User{})
fmt.Printf("Table: %s\n", meta.TableName)
for _, field := range meta.Fields {
    fmt.Printf("Field: %s, Required: %v, Unique: %v\n",
        field.Name, field.IsRequired, field.IsUnique)
}
Transaction Management

The package includes a TransactionManager interface for managing database transactions:

type TransactionManager interface {
    RunInTx(ctx context.Context, opts *sql.TxOptions,
        f func(ctx context.Context, tx bun.Tx) error) error
}

Database Support

The repository automatically detects and adapts to different database drivers:

  • PostgreSQL
  • SQLite
  • MSSQL
  • MySQL

Database driver detection is handled automatically via the DetectDriver function.

Project Structure

  • repo.go - Main repository implementation and DetectDriver function
  • errors.go - Custom error types and handlers
  • meta.go - Model metadata extraction utilities
  • types.go - Type definitions and interfaces
  • utils.go - Utility functions including error helpers
  • query_*_criteria.go - Query builder criteria functions
  • examples/ - Example usage and model definitions

License

MIT

Documentation

Index

Constants

View Source
const (
	CategoryDatabase              = errors.Category("database")
	CategoryDatabaseNotFound      = errors.Category("database_not-found")
	CategoryDatabaseConstraint    = errors.Category("database_constraint")
	CategoryDatabaseDuplicate     = errors.Category("database_duplicate")
	CategoryDatabaseConnection    = errors.Category("database_connection")
	CategoryDatabaseTimeout       = errors.Category("database_timeout")
	CategoryDatabaseLock          = errors.Category("database_lock")
	CategoryDatabasePermission    = errors.Category("database_permission")
	CategoryDatabaseSyntax        = errors.Category("database_syntax")
	CategoryDatabaseExpectedCount = errors.Category("database_expected-count")
)

Variables

View Source
var (
	// ErrUnknownPatchField indicates that a patch payload includes a field that does not exist.
	ErrUnknownPatchField = stderrors.New("repository: unknown patch field")
	// ErrPatchFieldNotAllowed indicates that a patch payload attempted to update a disallowed field.
	ErrPatchFieldNotAllowed = stderrors.New("repository: patch field not allowed")
	// ErrPatchPrimaryKeyNotAllowed indicates a patch payload attempted to update a primary key field.
	ErrPatchPrimaryKeyNotAllowed = stderrors.New("repository: patch primary key not allowed")
)
View Source
var (
	ErrQueryHookNil        = errors.New("query hook is nil")
	ErrQueryHookNilPointer = errors.New("query hook is a nil pointer")
)
View Source
var ErrRecordNotFound = stderrors.New("repository: record not found")

ErrRecordNotFound is a sentinel error that enables errors.Is(err, ErrRecordNotFound) checks.

Functions

func ApplyMapPatch added in v0.13.0

func ApplyMapPatch[T any](record T, patch map[string]any, opts ...MapPatchOption) (T, []string, error)

ApplyMapPatch applies a partial map payload onto a record and returns the updated record plus the changed Bun column names.

func ApplyScope added in v0.16.0

func ApplyScope(q *bun.SelectQuery, cols ScopeColumns, scope ScopeValues, mode ScopePredicateMode) *bun.SelectQuery

ApplyScope applies a select predicate generated by ScopeWhere.

func ApplyScopeToDelete added in v0.16.0

func ApplyScopeToDelete(q *bun.DeleteQuery, cols ScopeColumns, scope ScopeValues) *bun.DeleteQuery

ApplyScopeToDelete applies exact scope matching to a delete query.

func ApplyScopeToUpdate added in v0.16.0

func ApplyScopeToUpdate(q *bun.UpdateQuery, cols ScopeColumns, scope ScopeValues) *bun.UpdateQuery

ApplyScopeToUpdate applies exact scope matching to an update query.

func DefaultScope added in v0.16.0

func DefaultScope(record ScopedRecord, scope ScopeValues) bool

DefaultScope fills blank tenant/org record values from scope and preserves values already present on the record.

func DefaultScopeMap added in v0.16.0

func DefaultScopeMap(values map[string]any, scope ScopeValues) bool

DefaultScopeMap fills blank tenant_id/org_id values from scope in a metadata map and preserves explicit non-blank values.

func DetectDriver added in v0.4.3

func DetectDriver(db *bun.DB) string

func EntityToMap added in v0.13.0

func EntityToMap(entity any, opts ...MapProjectionOption) (map[string]any, error)

EntityToMap projects an entity into a map using map-native reflection (no JSON roundtrip).

func IsConnectionError added in v0.3.0

func IsConnectionError(err error) bool

func IsConstraintViolation added in v0.3.0

func IsConstraintViolation(err error) bool

func IsDuplicatedKey added in v0.3.0

func IsDuplicatedKey(err error) bool

func IsRecordNotFound

func IsRecordNotFound(err error) bool

func IsRetryableDatabase added in v0.3.0

func IsRetryableDatabase(err error) bool

func IsSQLExpectedCountViolation

func IsSQLExpectedCountViolation(err error) bool

And add a category checker:

func LogQueryHookErrorHandler added in v0.12.0

func LogQueryHookErrorHandler(db *bun.DB, hook bun.QueryHook, err error)

LogQueryHookErrorHandler logs invalid hook registrations.

func MapCommonDatabaseErrors added in v0.3.0

func MapCommonDatabaseErrors(err error) error

func MapDatabaseError added in v0.3.0

func MapDatabaseError(err error, driver string) error

func MapMSSQLErrors added in v0.3.0

func MapMSSQLErrors(err error) error

func MapPostgresErrors added in v0.3.0

func MapPostgresErrors(err error) error

func MapSQLiteErrors added in v0.3.0

func MapSQLiteErrors(err error) error

func MapToRecord added in v0.13.0

func MapToRecord[T any](payload map[string]any, opts ...MapPatchOption) (T, error)

MapToRecord maps a payload into a record using map-native reflection (no JSON roundtrip).

func NewRecordNotFound added in v0.4.1

func NewRecordNotFound() *errors.RetryableError

func PanicQueryHookErrorHandler added in v0.12.0

func PanicQueryHookErrorHandler(db *bun.DB, hook bun.QueryHook, err error)

PanicQueryHookErrorHandler panics on invalid hook registrations.

func RecordToMap added in v0.13.0

func RecordToMap[T any](record T, opts ...MapProjectionOption) (map[string]any, error)

RecordToMap projects a typed record into a map using map-native reflection (no JSON roundtrip).

func SQLExpectedCount

func SQLExpectedCount(res sql.Result, expected int64) error

func ScopeData added in v0.7.0

func ScopeData(ctx context.Context, name string) (any, bool)

func ScopeDataSnapshot added in v0.7.0

func ScopeDataSnapshot(ctx context.Context) map[string]any

func ScopeWhere added in v0.16.0

func ScopeWhere(cols ScopeColumns, scope ScopeValues, mode ScopePredicateMode) (expr string, args []any, ok bool)

ScopeWhere builds a safe SQL predicate and arguments for common tenant/org scope matching. Invalid columns fail closed; missing columns return ok=false.

func UpdateByIDWithMapPatch added in v0.13.0

func UpdateByIDWithMapPatch[T any](
	ctx context.Context,
	repo Repository[T],
	id string,
	patch map[string]any,
	updateCriteria []UpdateCriteria,
	opts ...MapPatchOption,
) (T, error)

UpdateByIDWithMapPatch performs an ID-based safe partial update flow: load current record -> apply map patch -> update changed columns only.

func UpdateByIDWithMapPatchTx added in v0.13.0

func UpdateByIDWithMapPatchTx[T any](
	ctx context.Context,
	repo Repository[T],
	tx bun.IDB,
	id string,
	patch map[string]any,
	updateCriteria []UpdateCriteria,
	opts ...MapPatchOption,
) (T, error)

UpdateByIDWithMapPatchTx is the transactional variant of UpdateByIDWithMapPatch.

func WithDeleteScopes added in v0.7.0

func WithDeleteScopes(ctx context.Context, names ...string) context.Context

func WithInsertScopes added in v0.7.0

func WithInsertScopes(ctx context.Context, names ...string) context.Context

func WithScopeData added in v0.7.0

func WithScopeData(ctx context.Context, name string, data any) context.Context

func WithScopes added in v0.7.0

func WithScopes(ctx context.Context, names ...string) context.Context

func WithSelectScopes added in v0.7.0

func WithSelectScopes(ctx context.Context, names ...string) context.Context

func WithUpdateScopes added in v0.7.0

func WithUpdateScopes(ctx context.Context, names ...string) context.Context

func WithoutDefaultScopes added in v0.7.0

func WithoutDefaultScopes(ctx context.Context) context.Context

Types

type DBProvider added in v0.12.0

type DBProvider interface {
	DB() *bun.DB
}

DBProvider exposes access to the underlying bun.DB when needed.

type DatabaseErrorMapper added in v0.3.0

type DatabaseErrorMapper func(error) error

DatabaseErrorMapper maps database specific errors to standardized errors

func GetDatabaseErrorMappers added in v0.3.0

func GetDatabaseErrorMappers(driver string) []DatabaseErrorMapper

type DefaultListPaginationConfigurer added in v0.14.0

type DefaultListPaginationConfigurer interface {
	SetDefaultListPagination(limit, offset int)
}

DefaultListPaginationConfigurer is an optional capability for repository instances that support mutating default list pagination at runtime.

Prefer configuring defaults at initialization via NewRepositoryWithConfig(..., WithDefaultListPagination(...)). Runtime mutation in live concurrent systems can lead to mixed pagination behavior across requests.

type DeleteCriteria

type DeleteCriteria func(*bun.DeleteQuery) *bun.DeleteQuery

DeleteCriteria is the function we use to create select queries

func DeleteBy

func DeleteBy(column, operator, value string) DeleteCriteria

DeleteBy will delete by a given property

func DeleteByID

func DeleteByID(id string) DeleteCriteria

DeleteByID will delete by the given ID

func DeleteByIDs added in v0.11.0

func DeleteByIDs(ids []string) DeleteCriteria

DeleteByIDs deletes by a list of IDs.

func DeleteByTimetz

func DeleteByTimetz(column, operator string, value time.Time) DeleteCriteria

DeleteByTimetz will format the time provided

func DeleteColumnIn added in v0.11.0

func DeleteColumnIn[T any](column string, values []T) DeleteCriteria

DeleteColumnIn deletes by matching any of the provided values. An empty slice results in a no-op filter that matches nothing.

func DeleteForReal

func DeleteForReal() DeleteCriteria

DeleteForReal will set the force delete flag to really remove items.

func DeleteScope added in v0.16.0

func DeleteScope(cols ScopeColumns, scope ScopeValues) DeleteCriteria

DeleteScope returns a DeleteCriteria that applies exact scope matching.

func WithSoftDelete added in v0.8.0

func WithSoftDelete() DeleteCriteria

WithSoftDelete forces the query to only target rows that have already been soft deleted (i.e. where deleted_at IS NOT NULL). This is especially useful when combined with DeleteForReal to permanently remove records that were previously soft deleted.

type FieldMeta added in v0.1.0

type FieldMeta struct {
	Name         string   `json:"name"`
	StructName   string   `json:"struct_name"`
	Type         string   `json:"type"`
	IsRequired   bool     `json:"is_required"`
	IsNullable   bool     `json:"is_nullable"`
	IsUnique     bool     `json:"is_unique"`
	IsPK         bool     `json:"is_pk"`
	Description  string   `json:"description"`
	DefaultValue string   `json:"default_value"`
	Validations  []string `json:"validations,omitempty"`
}

FieldMeta represents metadata for a single field

type IdentifierOption added in v0.8.0

type IdentifierOption struct {
	Column string
	Value  string
}

IdentifierOption describes a single identifier lookup attempt.

type InsertCriteria

type InsertCriteria func(*bun.InsertQuery) *bun.InsertQuery

InsertCriteria is the function we use to create insert queries

func InsertOnConflictIgnore added in v0.1.0

func InsertOnConflictIgnore() InsertCriteria

func InsertOnConflictUpdate added in v0.1.0

func InsertOnConflictUpdate(cols ...string) InsertCriteria

func InsertReturnOrderByID added in v0.11.0

func InsertReturnOrderByID() InsertCriteria

InsertReturnOrderByID requests that bulk create results are reordered to match input IDs.

func InsertSetColumn added in v0.1.0

func InsertSetColumn(col string, val any) InsertCriteria

InsertSetColumn will set the column to be updated

type MapKeyMode added in v0.13.0

type MapKeyMode string

MapKeyMode controls which field name strategy is used for map payloads.

const (
	// MapKeyBun uses Bun column names (`bun:"column_name"` or Bun's inferred snake_case name).
	MapKeyBun MapKeyMode = "bun"
	// MapKeyJSON uses JSON tags (`json:"field_name"`) with Go field name fallback.
	MapKeyJSON MapKeyMode = "json"
	// MapKeyStruct uses the struct field name (e.g. `FieldName`).
	MapKeyStruct MapKeyMode = "struct"
)

type MapPatchOption added in v0.13.0

type MapPatchOption func(*mapPatchConfig)

MapPatchOption configures map patch behavior.

func WithPatchAllowedFields added in v0.13.0

func WithPatchAllowedFields(fields ...string) MapPatchOption

WithPatchAllowedFields allowlists patchable fields. Values can be Bun names, JSON names, or struct field names.

func WithPatchDenyPrimaryKey added in v0.13.0

func WithPatchDenyPrimaryKey() MapPatchOption

WithPatchDenyPrimaryKey rejects updates to primary key fields.

func WithPatchIgnoreNil added in v0.13.0

func WithPatchIgnoreNil(ignore bool) MapPatchOption

WithPatchIgnoreNil controls whether nil payload values are ignored.

func WithPatchIgnoreUnknown added in v0.13.0

func WithPatchIgnoreUnknown(ignore bool) MapPatchOption

WithPatchIgnoreUnknown controls whether unknown payload keys are ignored.

func WithPatchKeyMode added in v0.13.0

func WithPatchKeyMode(mode MapKeyMode) MapPatchOption

WithPatchKeyMode selects how payload keys are resolved.

type MapProjectionOption added in v0.13.0

type MapProjectionOption func(*mapProjectionConfig)

MapProjectionOption configures RecordToMap/EntityToMap projection behavior.

func WithProjectionIncludeNilPointers added in v0.13.0

func WithProjectionIncludeNilPointers(include bool) MapProjectionOption

WithProjectionIncludeNilPointers controls whether nil pointers are included as map entries.

func WithProjectionKeyMode added in v0.13.0

func WithProjectionKeyMode(mode MapKeyMode) MapProjectionOption

WithProjectionKeyMode selects how projected map keys are generated.

type MapRecordMapper added in v0.13.0

type MapRecordMapper[T any] struct {
	ToRecord   func(map[string]any) (T, error)
	ToMap      func(T) (map[string]any, error)
	ApplyPatch func(T, map[string]any) (T, []string, error)
}

MapRecordMapper is a reusable generic utility set for map-based integrations.

func NewMapRecordMapper added in v0.13.0

func NewMapRecordMapper[T any](cfg MapRecordMapperConfig) MapRecordMapper[T]

NewMapRecordMapper returns a reusable map-native generic adapter utility set.

type MapRecordMapperConfig added in v0.13.0

type MapRecordMapperConfig struct {
	ProjectionOptions []MapProjectionOption
	PatchOptions      []MapPatchOption
}

MapRecordMapperConfig configures NewMapRecordMapper.

type Meta added in v0.2.0

type Meta[T any] interface {
	TableName() string
}

type ModelField added in v0.1.0

type ModelField struct {
	Name       string `json:"name"`
	IsPK       bool   `json:"is_pk"`
	SQLType    string `json:"sql_type"`
	SQLDefault string `json:"sql_default"`
	Identity   bool   `json:"identity"`
	IsUnique   bool   `json:"is_unique"`
}

func GetModelFields added in v0.1.0

func GetModelFields(db *bun.DB, model any) []ModelField

GetModelFields returns a list of fields for the model: fields := GetModelFields(db, &User{})

type ModelHandlers

type ModelHandlers[T any] struct {
	NewRecord     func() T
	GetID         func(T) uuid.UUID
	SetID         func(T, uuid.UUID)
	GetIdentifier func() string
	// GetIdentifierValue returns the value for the identifier column.
	// Return an empty string to indicate that the identifier is not available.
	GetIdentifierValue func(T) string
	// ResolveIdentifier allows callers to customize how identifiers are resolved.
	// It can inspect the provided identifier and return one or more IdentifierOptions
	// to try (e.g., try email, username, and id for flexible lookups). Returning nil
	// or an empty slice falls back to GetIdentifier/GetIdentifierValue.
	ResolveIdentifier func(identifier string) []IdentifierOption
}

type ModelMeta added in v0.1.0

type ModelMeta struct {
	TableName string      `json:"table_name"`
	Fields    []FieldMeta `json:"fields"`
}

ModelMeta represents the collected metadata for a model

func GenerateModelMeta added in v0.1.0

func GenerateModelMeta(model any) ModelMeta

GenerateModelMeta generates metadata from a model using reflection

type Option added in v0.12.0

type Option func(*bun.DB)

func WithQueryHookErrorHandler added in v0.12.0

func WithQueryHookErrorHandler(handler QueryHookErrorHandler) Option

WithQueryHookErrorHandler sets how invalid hooks are handled for the provided bun.DB.

func WithQueryHooks added in v0.12.0

func WithQueryHooks(hooks ...bun.QueryHook) Option

WithQueryHooks registers query hooks on the provided bun.DB, skipping duplicates.

type QueryHookErrorHandler added in v0.12.0

type QueryHookErrorHandler func(db *bun.DB, hook bun.QueryHook, err error)

QueryHookErrorHandler handles invalid query hook registrations.

type QueryHookKeyer added in v0.12.0

type QueryHookKeyer interface {
	QueryHookKey() string
}

QueryHookKeyer allows hooks to provide a stable identity for deduplication.

type RecordLookupResolver added in v0.14.1

type RecordLookupResolver[T any] func(record T) []SelectCriteria

RecordLookupResolver resolves select criteria used to find an existing record during Upsert/GetOrCreate when ID and identifier lookups miss.

type RepoOption added in v0.14.0

type RepoOption func(*repoConfig)

func WithAllowFullTableDelete added in v0.15.1

func WithAllowFullTableDelete(enabled bool) RepoOption

WithAllowFullTableDelete enables DeleteWhere/DeleteMany calls without criteria. Defaults to false for safety.

func WithDefaultListPagination added in v0.14.0

func WithDefaultListPagination(limit, offset int) RepoOption

WithDefaultListPagination configures repository-level default pagination. Use this during repository initialization.

func WithRecordLookupResolver added in v0.14.1

func WithRecordLookupResolver[T any](resolver RecordLookupResolver[T]) RepoOption

WithRecordLookupResolver configures an optional custom existing-record lookup. A nil resolver disables custom lookup.

type Repository

type Repository[T any] interface {
	Raw(ctx context.Context, sql string, args ...any) ([]T, error)
	RawTx(ctx context.Context, tx bun.IDB, sql string, args ...any) ([]T, error)
	Get(ctx context.Context, criteria ...SelectCriteria) (T, error)
	GetTx(ctx context.Context, tx bun.IDB, criteria ...SelectCriteria) (T, error)
	GetByID(ctx context.Context, id string, criteria ...SelectCriteria) (T, error)
	GetByIDTx(ctx context.Context, tx bun.IDB, id string, criteria ...SelectCriteria) (T, error)
	List(ctx context.Context, criteria ...SelectCriteria) ([]T, int, error)
	ListTx(ctx context.Context, tx bun.IDB, criteria ...SelectCriteria) ([]T, int, error)
	Count(ctx context.Context, criteria ...SelectCriteria) (int, error)
	CountTx(ctx context.Context, tx bun.IDB, criteria ...SelectCriteria) (int, error)

	Create(ctx context.Context, record T, criteria ...InsertCriteria) (T, error)
	CreateTx(ctx context.Context, tx bun.IDB, record T, criteria ...InsertCriteria) (T, error)
	CreateMany(ctx context.Context, records []T, criteria ...InsertCriteria) ([]T, error)
	CreateManyTx(ctx context.Context, tx bun.IDB, records []T, criteria ...InsertCriteria) ([]T, error)

	GetOrCreate(ctx context.Context, record T) (T, error)
	GetOrCreateTx(ctx context.Context, tx bun.IDB, record T) (T, error)
	GetByIdentifier(ctx context.Context, identifier string, criteria ...SelectCriteria) (T, error)
	GetByIdentifierTx(ctx context.Context, tx bun.IDB, identifier string, criteria ...SelectCriteria) (T, error)

	Update(ctx context.Context, record T, criteria ...UpdateCriteria) (T, error)
	UpdateTx(ctx context.Context, tx bun.IDB, record T, criteria ...UpdateCriteria) (T, error)
	UpdateMany(ctx context.Context, records []T, criteria ...UpdateCriteria) ([]T, error)
	UpdateManyTx(ctx context.Context, tx bun.IDB, records []T, criteria ...UpdateCriteria) ([]T, error)

	Upsert(ctx context.Context, record T, criteria ...UpdateCriteria) (T, error)
	UpsertTx(ctx context.Context, tx bun.IDB, record T, criteria ...UpdateCriteria) (T, error)
	UpsertMany(ctx context.Context, records []T, criteria ...UpdateCriteria) ([]T, error)
	UpsertManyTx(ctx context.Context, tx bun.IDB, records []T, criteria ...UpdateCriteria) ([]T, error)

	Delete(ctx context.Context, record T) error
	DeleteTx(ctx context.Context, tx bun.IDB, record T) error
	DeleteMany(ctx context.Context, criteria ...DeleteCriteria) error
	DeleteManyTx(ctx context.Context, tx bun.IDB, criteria ...DeleteCriteria) error

	DeleteWhere(ctx context.Context, criteria ...DeleteCriteria) error
	DeleteWhereTx(ctx context.Context, tx bun.IDB, criteria ...DeleteCriteria) error
	ForceDelete(ctx context.Context, record T) error
	ForceDeleteTx(ctx context.Context, tx bun.IDB, record T) error

	Handlers() ModelHandlers[T]
	RegisterScope(name string, scope ScopeDefinition)
	SetScopeDefaults(defaults ScopeDefaults) error
	GetScopeDefaults() ScopeDefaults
}

func MustNewRepository added in v0.5.3

func MustNewRepository[T any](db *bun.DB, handlers ModelHandlers[T]) Repository[T]

func MustNewRepositoryWithConfig added in v0.14.0

func MustNewRepositoryWithConfig[T any](db *bun.DB, handlers ModelHandlers[T], dbOpts []Option, repoOpts ...RepoOption) Repository[T]

func MustNewRepositoryWithOptions added in v0.12.0

func MustNewRepositoryWithOptions[T any](db *bun.DB, handlers ModelHandlers[T], opts ...Option) Repository[T]

func NewRepository

func NewRepository[T any](db *bun.DB, handlers ModelHandlers[T]) Repository[T]

func NewRepositoryWithConfig added in v0.14.0

func NewRepositoryWithConfig[T any](db *bun.DB, handlers ModelHandlers[T], dbOpts []Option, repoOpts ...RepoOption) Repository[T]

func NewRepositoryWithOptions added in v0.12.0

func NewRepositoryWithOptions[T any](db *bun.DB, handlers ModelHandlers[T], opts ...Option) Repository[T]

type SQLExecuter added in v0.5.0

type SQLExecuter any

type ScopeColumns added in v0.16.0

type ScopeColumns struct {
	Tenant string
	Org    string
}

ScopeColumns identifies the tenant and organization columns for a scoped table. Column names are caller-provided so table aliases such as cf.tenant_id can be used without the repository package knowing model details.

type ScopeDefaults added in v0.7.0

type ScopeDefaults struct {
	All    []string
	Select []string
	Update []string
	Insert []string
	Delete []string
}

func CloneScopeDefaults added in v0.7.0

func CloneScopeDefaults(defaults ScopeDefaults) ScopeDefaults

CloneScopeDefaults creates a deep copy of the provided scope defaults.

type ScopeDefinition added in v0.7.0

type ScopeDefinition struct {
	Select ScopeSelectFunc
	Update ScopeUpdateFunc
	Insert ScopeInsertFunc
	Delete ScopeDeleteFunc
}

func ScopeByField added in v0.7.0

func ScopeByField(scopeName, field string) ScopeDefinition

ScopeByField returns a ScopeDefinition that constrains repository operations to records whose `field` matches the value stored under `scopeName` in the context. Scope data may be provided as uuid.UUID, *uuid.UUID, or any fmt.Stringer/string whose String() value is not blank.

func ScopeByFieldOptional added in v0.15.1

func ScopeByFieldOptional(scopeName, field string) ScopeDefinition

ScopeByFieldOptional keeps the legacy fail-open behavior of ScopeByField: missing or invalid scope data results in no scope criteria being applied.

func ScopeByFieldRequired added in v0.15.1

func ScopeByFieldRequired(scopeName, field string) ScopeDefinition

ScopeByFieldRequired behaves like ScopeByField, but it fails closed: if scope data is missing or invalid, it applies a no-match criterion.

type ScopeDeleteFunc added in v0.7.0

type ScopeDeleteFunc func(context.Context) []DeleteCriteria

type ScopeInsertFunc added in v0.7.0

type ScopeInsertFunc func(context.Context) []InsertCriteria

type ScopeOperation added in v0.7.0

type ScopeOperation int

ScopeOperation identifies the repository operation type used when applying scopes.

const (
	ScopeOperationSelect ScopeOperation = iota
	ScopeOperationUpdate
	ScopeOperationInsert
	ScopeOperationDelete
)

type ScopePredicateMode added in v0.16.0

type ScopePredicateMode string

ScopePredicateMode selects how ScopeWhere should match scoped rows.

const (
	// ScopeExact matches rows with the exact provided scope values.
	ScopeExact ScopePredicateMode = "exact"
	// ScopeGlobal matches rows where the configured scope columns are blank.
	ScopeGlobal ScopePredicateMode = "global"
	// ScopeExactOrGlobal matches exact scoped rows or explicit global rows.
	ScopeExactOrGlobal ScopePredicateMode = "exact_or_global"
)

type ScopeSelectFunc added in v0.7.0

type ScopeSelectFunc func(context.Context) []SelectCriteria

type ScopeState added in v0.7.0

type ScopeState struct {
	Operation   ScopeOperation `json:"operation"`
	UseDefaults bool           `json:"use_defaults"`
	Names       []string       `json:"names"`
	Data        map[string]any `json:"data,omitempty"`
}

ScopeState captures the effective scope configuration for a given operation.

func ResolveScopeState added in v0.7.0

func ResolveScopeState(ctx context.Context, defaults ScopeDefaults, op ScopeOperation) ScopeState

func (ScopeState) IsZero added in v0.7.0

func (s ScopeState) IsZero() bool

IsZero returns true when no scope names or data are configured.

type ScopeUpdateFunc added in v0.7.0

type ScopeUpdateFunc func(context.Context) []UpdateCriteria

type ScopeValues added in v0.16.0

type ScopeValues struct {
	TenantID string
	OrgID    string
}

ScopeValues carries the common tenant and organization scope values used by callers that need explicit row-level predicates.

type ScopedRecord added in v0.16.0

type ScopedRecord interface {
	GetTenantID() string
	SetTenantID(string)
	GetOrgID() string
	SetOrgID(string)
}

ScopedRecord is a minimal mutation contract for records with tenant/org fields. It keeps defaulting independent from any app-specific model type.

type SelectCriteria

type SelectCriteria func(*bun.SelectQuery) *bun.SelectQuery

func ExcludeColumns

func ExcludeColumns(columns ...string) SelectCriteria

ExcludeColumns will select columns

func OrderBy

func OrderBy(expression ...string) SelectCriteria

OrderBy expression

func OrderByJSONText added in v0.10.0

func OrderByJSONText(expr, direction string) SelectCriteria

OrderByJSONText orders by a text-extracting JSON expression. expr should return text (e.g., metadata->>'key' or JSON_UNQUOTE(JSON_EXTRACT(...))).

func SelectBetween added in v0.2.0

func SelectBetween(column string, start, end any) SelectCriteria

func SelectBy

func SelectBy(column, operator, value string) SelectCriteria

SelectBy will select by the given column where: column operator value id = 23 or id <= 23

func SelectByID

func SelectByID(id string) SelectCriteria

SelectByID using ID

func SelectByTimetz

func SelectByTimetz(column, operator string, value time.Time) SelectCriteria

SelectByTimetz will take a time value and format for postgres

func SelectColumnCompare added in v0.2.0

func SelectColumnCompare(col1, operator, col2 string) SelectCriteria

func SelectColumnExpr

func SelectColumnExpr(expr string) SelectCriteria

SelectColumnExpr will select columns

func SelectColumnIn

func SelectColumnIn[T any](column string, slice []T) SelectCriteria

SelectColumnIn will make an array select. - values: It should be a slice i.e. of IDs

func SelectColumnInSubq added in v0.1.0

func SelectColumnInSubq(column string, query string, args ...any) SelectCriteria

SelectColumnInSubq will make an array select

func SelectColumnNotIn added in v0.1.0

func SelectColumnNotIn[T any](column string, slice []T) SelectCriteria

SelectColumnNotIn will make an array select - values: It should be a slice i.e. of IDs

func SelectColumnNotInSubq added in v0.1.0

func SelectColumnNotInSubq(column string, query string, args ...any) SelectCriteria

SelectColumnNotInSubq will make an array select Note that when using `NOT IN` you should ensure that none of the values are NULL:

   AND email NOT IN (
	  	SELECT email
	  	FROM users
			WHERE email is NOT NULL
  )

func SelectColumns

func SelectColumns(columns ...string) SelectCriteria

SelectColumns will select columns

func SelectDeletedAlso

func SelectDeletedAlso() SelectCriteria

SelectDeletedAlso will include deleted and non deleted

func SelectDeletedOnly

func SelectDeletedOnly() SelectCriteria

SelectDeletedOnly will include deleted only

func SelectDistinct added in v0.2.0

func SelectDistinct(columns ...string) SelectCriteria

SelectDistinct will add DISTINCT or DISTINCT ON cols

func SelectGroupBy added in v0.2.0

func SelectGroupBy(columns ...string) SelectCriteria

func SelectHaving added in v0.2.0

func SelectHaving(expr string, args ...any) SelectCriteria

func SelectILike added in v0.2.0

func SelectILike(column, pattern string) SelectCriteria

func SelectIsNull added in v0.1.0

func SelectIsNull(column string) SelectCriteria

SelectIsNull IS NULL

func SelectJSONContains added in v0.2.0

func SelectJSONContains(column string, jsonVal any) SelectCriteria

func SelectMaybeByTimetz

func SelectMaybeByTimetz(column, operator string, value *time.Time) SelectCriteria

SelectMaybeByTimetz will only update the select criteria if value is defined

func SelectNotNull

func SelectNotNull(column string) SelectCriteria

SelectNotNull adds IS NOT NULL

func SelectOrBy

func SelectOrBy(column, operator, value string) SelectCriteria

SelectOrBy OR selector

func SelectOrIsNull

func SelectOrIsNull(column string) SelectCriteria

SelectOrIsNull OR IS NULL

func SelectOrNotNull added in v0.1.0

func SelectOrNotNull(column string) SelectCriteria

SelectNotNull adds IS NOT NULL

func SelectOrderAsc

func SelectOrderAsc(column string) SelectCriteria

SelectOrderAsc sort by column

func SelectOrderDesc

func SelectOrderDesc(column string) SelectCriteria

SelectOrderDesc sort by column

func SelectPaginate added in v0.1.0

func SelectPaginate(limit, offset int) SelectCriteria

SelectPaginate will paginate through a result set

func SelectRawProcessor

func SelectRawProcessor(fn func(q *bun.SelectQuery) *bun.SelectQuery) SelectCriteria

SelectRawProcessor will execute the passed in function

func SelectRelation added in v0.1.0

func SelectRelation(model string, criteria ...SelectCriteria) SelectCriteria

SelectRelation will add a LEFT JOIN relation

func SelectScope added in v0.16.0

func SelectScope(cols ScopeColumns, scope ScopeValues, mode ScopePredicateMode) SelectCriteria

SelectScope returns a SelectCriteria that applies ScopeWhere.

func SelectSubquery added in v0.1.0

func SelectSubquery(subq *bun.SelectQuery, aliases ...string) SelectCriteria

func SelectTimeRange added in v0.2.0

func SelectTimeRange(column string, start, end time.Time) SelectCriteria

func WhereJSONContains added in v0.10.0

func WhereJSONContains(expr string, value any) SelectCriteria

WhereJSONContains applies a JSON containment check on the provided expression. expr should be a JSON expression (e.g., metadata->'key' or json_extract(...)).

type TransactionManager added in v0.5.0

type TransactionManager interface {
	RunInTx(ctx context.Context, opts *sql.TxOptions, f func(ctx context.Context, tx bun.Tx) error) error
}

TransactionManager generates transactions

type UpdateCriteria

type UpdateCriteria func(*bun.UpdateQuery) *bun.UpdateQuery

UpdateCriteria is the function we use to create select queries

func UpdateBy

func UpdateBy(column, operator, value string) UpdateCriteria

UpdateBy will select by the given column where: column operator value id = 23 or id <= 23

func UpdateByID

func UpdateByID(id string) UpdateCriteria

UpdateByID using ID

func UpdateByPK added in v0.2.0

func UpdateByPK(cols ...string) UpdateCriteria

func UpdateByTimetz

func UpdateByTimetz(column, operator string, value time.Time) UpdateCriteria

UpdateByTimetz will take a time value and format for postgres

func UpdateColumns

func UpdateColumns(columns ...string) UpdateCriteria

UpdateColumns will select columns

func UpdateCriteriaForMapPatch added in v0.13.0

func UpdateCriteriaForMapPatch(patch map[string]any, opts ...MapPatchOption) ([]UpdateCriteria, error)

UpdateCriteriaForMapPatch builds UpdateCriteria for direct query patch updates. It returns UpdateColumns(...) plus UpdateSetColumn(...) entries.

func UpdateDeletedAlso

func UpdateDeletedAlso() UpdateCriteria

UpdateDeletedAlso will include deleted and non deleted

func UpdateDeletedOnly

func UpdateDeletedOnly() UpdateCriteria

UpdateDeletedOnly will include deleted only

func UpdateExcludeColumns

func UpdateExcludeColumns(columns ...string) UpdateCriteria

UpdateExcludeColumns will select columns

func UpdateMaybeByTimetz

func UpdateMaybeByTimetz(column, operator string, value *time.Time) UpdateCriteria

UpdateMaybeByTimetz will only update the select criteria if value is defined

func UpdateOrBy

func UpdateOrBy(column, operator, value string) UpdateCriteria

UpdateOrBy OR selector

func UpdateOrIsNull

func UpdateOrIsNull(column string) UpdateCriteria

UpdateOrIsNull OR IS NULL

func UpdateRawProcessor

func UpdateRawProcessor(fn func(q *bun.UpdateQuery) *bun.UpdateQuery) UpdateCriteria

UpdateRawProcessor will execute the passed in function

func UpdateReturnOrderByID added in v0.11.0

func UpdateReturnOrderByID() UpdateCriteria

UpdateReturnOrderByID requests that bulk update results are reordered to match input IDs.

func UpdateScope added in v0.16.0

func UpdateScope(cols ScopeColumns, scope ScopeValues) UpdateCriteria

UpdateScope returns an UpdateCriteria that applies exact scope matching.

func UpdateSetColumn

func UpdateSetColumn(col string, val any) UpdateCriteria

UpdateSetColumn will set the column to be updated

func UpdateSkipZeroValues added in v0.7.0

func UpdateSkipZeroValues() UpdateCriteria

UpdateSkipZeroValues opt-in helper to omit zero-valued columns.

type Validator added in v0.5.0

type Validator interface {
	Validate() error
	MustValidate()
}

Validator enables everything is properly configured

Jump to

Keyboard shortcuts

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