sqlutil

package module
v0.0.10 Latest Latest
Warning

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

Go to latest
Published: Jun 23, 2026 License: MPL-2.0 Imports: 4 Imported by: 0

README

sqliteutil

sqliteutil provides utility functions to work with the standard database/sql package in golang. It is based on Cols and Vals, two functions to get field names and scan targets from struct based on struct tags.

It additionally provides the Builder, that allows to generate parameterized Queries like it was fmt.Sprintf.

Example

type Car struct {
	ID    int64  `db:"id,select"`
	Make  string `db:"make,select,insert,update"`
	Model string `db:"model,select,insert,update"`
	Year  int64  `db:"year,select,insert,update"`
	Color string `db:"color,select,insert,update"`
}

func InsertCar(tx *sql.Tx, c *Car) (int64, error) {
	// extract all columns with the "insert" tag
	cols := sqlutil.Cols(c, "", "insert")
	vals := sqlutil.Vals(c, "insert")

	// create a Builder for sqlite (using the ? placeholder)
	// and write the query. It will end up looking like
	// INSERT INTO car (make, model, year, color) VALUES (?, ?, ?, ?)
	b := sqlutil.Builder{Dialect: sqlutil.SQLite}
	b.Printf("INSERT INTO car (%s) VALUES (%s)", cols, vals)

	// execute the query using the (matching) number of arguments
	res, err := tx.Exec(b.String(), b.Args...)
	if err != nil {
		return 0, err
	}
	return res.LastInsertId()
}

func SelectCars(tx *sql.Tx) ([]Car, error) {
	// extract all columns with the "select" tag
	var c Car
	cols := sqlutil.Cols(&c, "", "select")
	vals := sqlutil.Vals(&c, "select")

	// build the query only using the "select" cols
	b := sqlutil.Builder{Dialect: sqlutil.SQLite}
	b.Printf("SELECT %v FROM car", cols)

	// execute the query
	// See sqlutil.Slice and sqlutil.MappedSlice for other scan targets
	// that support straight forward scanning into slices.
	var cars []Car
	err := b.ScanRows(tx, &sqlutil.ScanFunc{
		Dest: vals,
		Add: func() {
			cars = append(cars, c)
		},
	})
	return cars, err
}

func UpdateCar(tx *sql.Tx, c *Car) error {
	// extract all columns with the "update" tag
	cols := sqlutil.Cols(c, "", "update")
	vals := sqlutil.Vals(c, "update")

	// create a Builder for sqlite (using the ? placeholder)
	// and use it to format the update statement. FieldList
	// is used to create the col = ...  part.
	b := sqliteutil.Builder()
	fields := sqlutil.FieldList{
		Cols: cols,
		Vals: vals,
		OP:   "=",
	}
	b.Printf("UPDATE car SET %v WHERE id = %v", fields, c.ID)
	_, err := tx.Exec(b.String(), b.Args...)
	return err
}

Struct Tags

The function Cols and Vals work using struct tags. Each field that should be retrievable must contain a struct tag named db.

The tag value consists of a field name, and optional "tags". The empty tag is implicitly given to all struct fields.

Licensing

sqlutil is released under the MPL v2.0 license

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func ScriptMigration

func ScriptMigration(script string) func(*sql.Tx) error

Types

type ArgList added in v0.0.9

type ArgList []any

ArgList allows to use a single slice as multiple Scan arguments

type Builder

type Builder struct {
	Dialect Dialect
	Args    []any
	// contains filtered or unexported fields
}

func (*Builder) Exec added in v0.0.4

func (b *Builder) Exec(e DB) (sql.Result, error)

func (*Builder) Printf

func (b *Builder) Printf(format string, a ...any)

func (*Builder) Query added in v0.0.4

func (b *Builder) Query(q DB) (*sql.Rows, error)

func (*Builder) QueryRow added in v0.0.4

func (b *Builder) QueryRow(q DB) *sql.Row

func (*Builder) Reset added in v0.0.9

func (b *Builder) Reset()

func (*Builder) ScanRow added in v0.0.4

func (b *Builder) ScanRow(db DB, dest ...any) error

func (*Builder) ScanRows added in v0.0.8

func (b *Builder) ScanRows(q DB, s RowScanner) error

func (*Builder) String

func (b *Builder) String() string

type DB added in v0.0.9

type DB interface {
	Exec(query string, a ...any) (sql.Result, error)
	Query(query string, a ...any) (*sql.Rows, error)
	QueryRow(query string, a ...any) *sql.Row
}

type Dialect added in v0.0.9

type Dialect interface {
	Param(idx int) string
}
var (
	SQLite Dialect = sqliteDialectImpl{}
)

type FieldList

type FieldList struct {
	Cols   []string
	Vals   []any
	OP     string
	JoinBy string
}

FieldList creates a list of col .. val ... col .. val. OP specifies what comes between col and val, default is " = "" JoinBy specifies what comes between pairs, default is ", "

func (FieldList) RawString

func (l FieldList) RawString(b RawBuilder) string

type MappedSlice added in v0.0.9

type MappedSlice[T, D any] struct {
	Tag string
	Map func(t D) T
	S   []T
	// contains filtered or unexported fields
}

func (*MappedSlice[T, D]) Cols added in v0.0.9

func (s *MappedSlice[T, D]) Cols(prefix string) RawList

func (*MappedSlice[T, D]) ScanRow added in v0.0.9

func (s *MappedSlice[T, D]) ScanRow(rows *sql.Rows) error

type Migration

type Migration struct {
	Version int64
	Migrate func(tx *sql.Tx) error
}

type Raw

type Raw string

Raw will be formatted as raw SQL

type RawBuilder

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

func (RawBuilder) Param

func (b RawBuilder) Param(val any) string

Param converts val to a value safe to use in SQL. if it is Raw, the value will be returned. In any other case a parameter will be created

type RawList

type RawList []string

RawList is a string slice that will be used as a comma seperated list of raw strings.

func Cols

func Cols(t any, prefix string, tag string) RawList

func (RawList) RawString

func (s RawList) RawString(b RawBuilder) string

func (RawList) String

func (s RawList) String() string

type RawStringer

type RawStringer interface {
	RawString(b RawBuilder) string
}

type RowScanner added in v0.0.9

type RowScanner interface {
	ScanRow(rows *sql.Rows) error
}

type ScanFunc added in v0.0.9

type ScanFunc struct {
	Dest []any
	Add  func()
	// contains filtered or unexported fields
}

func (*ScanFunc) ScanRow added in v0.0.9

func (s *ScanFunc) ScanRow(rows *sql.Rows) error

type Slice added in v0.0.9

type Slice[T any] struct {
	Tag string
	S   []T
	// contains filtered or unexported fields
}

func (*Slice[T]) Cols added in v0.0.9

func (s *Slice[T]) Cols(prefix string) RawList

func (*Slice[T]) ScanRow added in v0.0.9

func (s *Slice[T]) ScanRow(rows *sql.Rows) error

type ValList

type ValList []any

func Vals

func Vals(t any, tag string) ValList

Vals gets the field values of the struct in t if t is a pointer, pointers to the fields are returned

func (ValList) ArgList added in v0.0.10

func (v ValList) ArgList() ArgList

func (ValList) RawString

func (s ValList) RawString(b RawBuilder) string

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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