Documentation ¶
Overview ¶
Package utils provides utility types and funcs for packages [datarepo] and [sqlite]. It exists mainly to prevent circular dependencies.
Index ¶
- Constants
- Variables
- func Close()
- func Create(ctx context.Context, q string, args ...any) (int64, error)
- func DB() *sql.DB
- func GetField[T Field](ctx context.Context, q string, args ...any) (T, error)
- func GetFields[T Field](ctx context.Context, q string, args ...any) ([]T, error)
- func GetRow[T any, PT Row[T]](ctx context.Context, q string, args ...any) (T, error)
- func GetRows[T any, PT Row[T]](ctx context.Context, q string, args ...any) ([]T, error)
- func InArgs[T Field](inArgs []T) (string, []any)
- func Init()
- func StringifyAnyArgs(args ...any) string
- type DAO
- type DbOp
- type Field
- type QuerySpec
- type Repo
- type Row
- type Times
Constants ¶
const ( // Odd ops OpCreateTable DbOp = "CreateTable" OpCount = "Count" // () (int, error) // Ops on single items: // - 5 functions (2 generic) - lacking ModByID // - All operate by using the ID, except of course Add(T) OpAdd = "Add" // (T) (int, error) OpDel = "Del" // (T) error OpMod = "Mod" // (T) error OpGetByID = "GetByID" // [T](int) (T, error) OpDelByID = "DelByID" // [T](int) error // Ops on multiple items where the count is KNOWN: // - 6 functions (3 generic) OpGetByIDs = "GetByIDs" // [T]([]int) ([]T, []error) OpDelByIDs = "DelByIDs" // [T]([]int) []error OpModByIDs = "ModByIDs" // [T]([]int, actions ...string) []error OpAddAll = "AddAll" // ([]T) ([]int, []error) OpDelAll = "DelAll" // ([]T) []error OpModAll = "ModAll" // ([]T) []error // Ops on multiple items (WHERE, Everything) // where the count is NOT known: // - 6 functions (all generic) - lacking ModEverything OpGetIDsWhere = "GetIDsWhere" // [T](cond string) ([]int64, error) OpGetWhere = "GetWhere" // [T](cond string) ([]T, error) OpDelWhere = "DelWhere" // [T](cond string) ([]int64, error) OpModWhere = "ModWhere" // [T](cond s, action s) ([]int64, e) OpGetEverything = "GetEverything" // [T]() ([]T, error) OpDelEverything = "DelEverything" // [T]() (error) )
Variables ¶
var ErrNotFound = errors.New("DB record not found")
ErrNotFound is returned when no row is found for an SQL query.
var QueriesByOp = map[DbOp]string{
OpCount: "SELECT COUNT(*) from %s;",
OpCreateTable: "!TBS!",
OpAdd: "INSERT into %s (%s) values (?, ?, ?);",
OpGetByID: "SELECT ID, %s from %s where ID = ? limit 1;",
OpGetByIDs: "SELECT ID, %s from %s where ID in (%s) order by id;",
OpGetIDsWhere: "SELECT ID from %s where %s;",
}
Functions ¶
func Create ¶
Create executes the INSERT statement found in q. It returns the last inserted ID if any, as an int64. Thus it does not need (or use) generics. .
func GetField ¶
GetField returns a single column value from the DB as type T. If no column is found, it returns the T zero value with no error.
Example:
- func GetField [T Field](ctx, q, args ...any) (T, error)
- return db.GetField[int64](ctx, q_getCount)
.
func GetFields ¶
GetFields returns fields from the DB as type []T. T must satisfy the Field constraint: T must be a basic Go data type. As the main use case, an int64 primary index satisfies this constraint.
Example:
- func GetFields[T Field](ctx, q, args ...any) ([]T, error)
- return db.GetFields[int64](ctx, q_getByIDsWithBio)
.
func GetRow ¶
GetRow returns a single row from the DB as type T. If no row is found, it returns the T zero value and ErrNotFound.
Example: retval,e := db.GetRow[User](ctx, q_getByID, id) // retval.(User) is true. .
func GetRows ¶
GetRows returns rows from the DB as type []T. T must implement PtrFields() with a ptr receiver type.
func InArgs ¶
InArgs returns ( placeholders and args ) as formatted for a WHERE IN clause. For example, calling InArgs([]int{1,2,3}) will return ("?,?,?", []any{1,2,3}).
func StringifyAnyArgs ¶
Types ¶
type Field ¶
Field is a type constraint for types that represent
- a single database column, or
- any other non-struct datum, such as an int64 primary index.
type QuerySpec ¶
type QuerySpec struct { DbOp // Table must not be empty; if it is treated as // case-insensitive then no validity checking // is done. Table string // Fields must not be empty, for consistency // in technique re. using ptrs everywhere in // order to enable generics and Scan(..). Fields string // ID can safely be ignored if // (IDs != nil) && (ID == 0 || ID == -1) ID int64 // IDs != nil is an error if ID is valid. IDs []int64 Where string }
QuerySpec is the basic strings that get plugged into a query: table name, column names, "where" clause. It is meant to be passed to query composers (not "builders") that are specific to various DBs. Which means, for now, SQLite.
A query composer might also be a query executor, which would mean distinguiishing at the API level among return values of int64, []int64, Row, and []Row.
There is redundancy built in, to help ensure against errors in usage: the DB op, the presence or absence of a WHERE clause, the number of IDs passed (0, 1, N). .
type Row ¶
type Row[T any] interface { // PtrFields returns a slice of // ptrs, one per struct field, // for use with [Row.Scan]. // Implement it for - and call // it with - ptr receivers ONLY. PtrFields() []any // TODO Try []*any *T }
Row is a type constraint for types that
- represent a single database row, and
- therefore correspond to a Go struct.
According to this definition, a Row can
- cough up a set of ptrs suitable for setting every field/column, and
- have its own address be taken (and passed around), making it writable.