diff --git a/db.go b/db.go index 8d23fdc..cedcc9e 100644 --- a/db.go +++ b/db.go @@ -364,6 +364,12 @@ func (db *DB) QueryRow(ctx context.Context, query string, args ...any) Row { return db.Pool.QueryRow(ctx, query, args...) } +// QueryBoolean executes a query that returns a single boolean value and returns it as a bool and an error. +func (db *DB) QueryBoolean(ctx context.Context, query string, args ...any) (ok bool, err error) { + err = db.QueryRow(ctx, query, args...).Scan(&ok) + return +} + // Exec executes SQL. The query can be either a prepared statement name or an SQL string. // Arguments should be referenced positionally from the sql "query" string as $1, $2, etc. func (db *DB) Exec(ctx context.Context, query string, args ...any) (pgconn.CommandTag, error) { diff --git a/desc/table.go b/desc/table.go index 796df18..95151e0 100644 --- a/desc/table.go +++ b/desc/table.go @@ -223,7 +223,7 @@ func (td *Table) ForeignKeyColumnNames() []string { // PrimaryKey returns the primary key's column of the // row definition and reports if there is one. -func (td *Table) PrimaryKey() (*Column, bool) { +func (td *Table) PrimaryKey() (*Column, bool) { // TODO: think of making it a static variable but keep the function somehow. for _, c := range td.Columns { if c.PrimaryKey { return c, true diff --git a/repository.go b/repository.go index 91aec03..7ff79e6 100644 --- a/repository.go +++ b/repository.go @@ -51,6 +51,11 @@ func (repo *Repository[T]) QueryRow(ctx context.Context, query string, args ...a return repo.db.QueryRow(ctx, query, args...) } +// QueryBoolean executes a query that returns a single boolean value and returns it as a bool and an error. +func (repo *Repository[T]) QueryBoolean(ctx context.Context, query string, args ...any) (bool, error) { + return repo.db.QueryBoolean(ctx, query, args...) +} + // Query executes a query that returns multiple rows and returns them as a Rows instance and an error. func (repo *Repository[T]) Query(ctx context.Context, query string, args ...any) (Rows, error) { return repo.db.Query(ctx, query, args...) @@ -182,6 +187,9 @@ func (repo *Repository[T]) InsertSingle(ctx context.Context, value T, idPtr any) return repo.db.insertTableRecord(ctx, repo.td, desc.IndirectValue(value), idPtr, "", false) // delegate the insertion to repo.db.insertTableRecord and return its result } +// DoNothing is a constant that can be used as the forceOnConflictExpr argument of Upsert/UpsertSingle to do nothing on conflict. +const DoNothing = "DO NOTHING" + // Upsert inserts or updates one or more values of type T into the database. func (repo *Repository[T]) Upsert(ctx context.Context, forceOnConflictExpr string, values ...T) error { if repo.IsReadOnly() {