sqlx

package module
v0.0.0-...-5b5decd Latest Latest
Warning

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

Go to latest
Published: Feb 28, 2026 License: Unlicense Imports: 17 Imported by: 0

README

sqlx

For fun and performance.

There are no benchmarks, because while reflection is slow, network and io are even worse. This library is just to make me satisfied, not the CPU or machine power.

<( ̄︶ ̄)↗[GO!]

show case

type User struct {
    ID int64 `db:"id"`
    Name string `db:"name"`
    Age int64 `db:"age"`
    Amount int64 `db:"amount"`
}

stmt := sqlx.NewLazyStmt(`select * from user where id > ${min_id} limit 100`);

_ = sqlx.InitAllLazyStmts(ctx)

type FindArgs struct {
    MinID int64 `args:"min_id"`
}

// Read first user
someone, err := sqlx.First[User](ctx, stmt, FindArgs{MinID: 100}, FindArgs{MinID: 100}) // yes, you can pass multiple args, override.

// Read all users
users, err := sqlx.All[User](ctx, stmt, sizehint: 100, FindArgs{MinID: 100}) // sizehint is the expected size of the result, for pre-allocation.


// in map/reduce,
//     - you can not hold the ele ptr, because the memory will be reused.
//     - safe to use in parallel.

// Map
year := time.Now().Year()
mapop := sqlx.NewMap[User, int64](stmt, func(ctx context.Context, ele *User) (int64, error) { return year - ele.Age, nil })

for birthYear, err := range mapop.Iter(ctx) {
    if err != nil {
        break
    }
}

// Reduce
reduceop := sqlx.NewReduce[User, int64](func(ctx context.Context, prev int64, ele *User) (int64, error) { return prev + ele.Amount, nil })
wg := sync.WaitGroup{}
for i := range 1000 {
    wg.Add(1)
    go func() {
        defer wg.Done()
        sum, err := reduceop.Calc(ctx, 0, FindArgs{MinID: 100 * i})
    }()
}
wg.Wait()

todo

  • Add more tests.
  • Add more dialects.
    • SQLite
    • MySQL
    • ...

Documentation

Index

Constants

This section is empty.

Variables

View Source
var (
	ParamsRegexp = regexp.MustCompile(`\$\{(\s*\[a-zA-Z_]+[a-zA-Z_0-9]*\s*)\}`)
)

Functions

func All

func All[T any](ctx context.Context, stmt *Stmt, sizehint int, args ...any) ([]T, error)

func AllSafe

func AllSafe[T any](ctx context.Context, stmt *Stmt, sizehint int, args ...any) ([]T, error)

func AsModel

func AsModel[T any]()

func DisableEnsureBackedUp

func DisableEnsureBackedUp()

func First

func First[T any](ctx context.Context, stmt *Stmt, args ...any) (*T, error)

func FirstSafe

func FirstSafe[T any](ctx context.Context, stmt *Stmt, args ...any) (*T, error)

func InitAllLazyStmts

func InitAllLazyStmts(ctx context.Context, mapfn func(*LazyStmt) bool) error

func Logger

func Logger() *slog.Logger

func MustDB

func MustDB(ctx context.Context) *sql.DB

func MustTx

func MustTx(ctx context.Context) *sql.Tx

func Page

func Page[T any](ctx context.Context, stmt *Stmt, rows *sql.Rows, page []T) ([]T, bool, error)

func PageSafe

func PageSafe[T any](ctx context.Context, stmt *Stmt, rows *sql.Rows, page []T) ([]T, bool, error)

func PeekDB

func PeekDB(ctx context.Context) *sql.DB

func PeekTx

func PeekTx(ctx context.Context) *sql.Tx

func Stream

func Stream[T any](ctx context.Context, stmt *Stmt, rows *sql.Rows) iter.Seq2[*T, error]

Stream the yielded ptr reused for each row, you can not store it.

func Sync

func Sync(ctx context.Context) error

func TxScope

func TxScope(ctx context.Context, f func(ctx context.Context) error, opts *sql.TxOptions) error

func UnwrapSqlNullType

func UnwrapSqlNullType(st reflect.Type) (reflect.Type, bool)

func WithDB

func WithDB(ctx context.Context, db *sql.DB) context.Context

func WithDialect

func WithDialect(ctx context.Context, dialect IDialect) context.Context

func WithExec

func WithExec(ctx context.Context, exec IExecutor) context.Context

func WithTx

func WithTx(ctx context.Context, tx *sql.Tx) context.Context

Types

type Field

type Field struct {
	Info        reflect.StructField
	IsStructPtr bool

	Index        []int
	GetPtr       func(vv reflect.Value) any
	GetUnsafePtr func(vv unsafe.Pointer) any
	GetValue     func(vv reflect.Value) any
	SetValue     func(vv reflect.Value, val any)
}

type FieldWithTag

type FieldWithTag struct {
	*Field
	Tag *Tag
}

type IDialect

type IDialect interface {
	EnsureTables(ctx context.Context, infos []*ModelInfo) error

	ParamPlaceholder(index int) string
}

func MustDialect

func MustDialect(ctx context.Context) IDialect

func PeekDialect

func PeekDialect(ctx context.Context) IDialect

type IExecutor

type IExecutor interface {
	QueryContext(ctx context.Context, query string, args ...any) (*sql.Rows, error)
	ExecContext(ctx context.Context, query string, args ...any) (sql.Result, error)
}

func MustExecutor

func MustExecutor(ctx context.Context) IExecutor

func PeekExecutor

func PeekExecutor(ctx context.Context) IExecutor

type LazyStmt

type LazyStmt struct {
	*Stmt
	// contains filtered or unexported fields
}

func NewLazyStmt

func NewLazyStmt(rawsql string) *LazyStmt

func (*LazyStmt) Init

func (s *LazyStmt) Init(ctx context.Context) error

func (*LazyStmt) Must

func (s *LazyStmt) Must() *Stmt

func (*LazyStmt) Name

func (s *LazyStmt) Name() string

func (*LazyStmt) String

func (s *LazyStmt) String() string

func (*LazyStmt) WithName

func (s *LazyStmt) WithName(name string) *LazyStmt

type LazyStmtGroup

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

func NewLazyStmtGroup

func NewLazyStmtGroup() *LazyStmtGroup

func (*LazyStmtGroup) InitAll

func (g *LazyStmtGroup) InitAll(ctx context.Context, mapfn func(*LazyStmt) bool) error

func (*LazyStmtGroup) New

func (g *LazyStmtGroup) New(rawsql string) *LazyStmt

type MapOperator

type MapOperator[T any, U any] struct {
	// contains filtered or unexported fields
}

func NewMap

func NewMap[T any, U any](stmt *Stmt, operator func(ctx context.Context, t *T) (U, error)) *MapOperator[T, U]

func (*MapOperator[T, U]) Iter

func (m *MapOperator[T, U]) Iter(ctx context.Context, args ...any) iter.Seq2[U, error]

type ModelField

type ModelField struct {
	Name   string
	GoType reflect.Type
	Opts   TagOptions
}

type ModelInfo

type ModelInfo struct {
	GoType reflect.Type
	Fields []*ModelField
}

type ReduceOperator

type ReduceOperator[T any, U any] struct {
	// contains filtered or unexported fields
}

func NewReduce

func NewReduce[T any, U any](stmt *Stmt, operator func(context.Context, U, *T) (U, error)) *ReduceOperator[T, U]

func (*ReduceOperator[T, U]) Calc

func (r *ReduceOperator[T, U]) Calc(ctx context.Context, result U, args ...any) (U, error)

type Stmt

type Stmt struct {
	*sql.Stmt
	// contains filtered or unexported fields
}

func NewStmt

func NewStmt(ctx context.Context, sql string) (*Stmt, error)

func (*Stmt) Args

func (s *Stmt) Args(vals ...any) ([]any, error)

func (*Stmt) Exec

func (s *Stmt) Exec(ctx context.Context, args ...any) (sql.Result, error)

func (*Stmt) MustExec

func (s *Stmt) MustExec(ctx context.Context, args ...any) sql.Result

func (*Stmt) MustRows

func (s *Stmt) MustRows(ctx context.Context, args ...any) *sql.Rows

func (*Stmt) Rows

func (s *Stmt) Rows(ctx context.Context, args ...any) (*sql.Rows, error)

type Tag

type Tag struct {
	Name string
	Opts TagOptions
}

type TagOptions

type TagOptions struct {
	url.Values
}

func (*TagOptions) GetBool

func (opts *TagOptions) GetBool(key string) (bool, error)

func (*TagOptions) GetInt

func (opts *TagOptions) GetInt(key string) (int, error)

func (*TagOptions) GetUint

func (opts *TagOptions) GetUint(key string) (uint, error)

func (*TagOptions) HasAny

func (opts *TagOptions) HasAny(keys ...string) bool

type TypeInfo

type TypeInfo struct {
	Type reflect.Type
	// contains filtered or unexported fields
}

func GetTypeInfo

func GetTypeInfo(t reflect.Type) *TypeInfo

func (*TypeInfo) Field

func (ti *TypeInfo) Field(tagname, name string, iface reflect.Type) (*FieldWithTag, error)

func (*TypeInfo) Fields

func (ti *TypeInfo) Fields(tagname string, iface reflect.Type) ([]*FieldWithTag, error)

func (*TypeInfo) MustField

func (ti *TypeInfo) MustField(tagname, name string, iface reflect.Type) *FieldWithTag

func (*TypeInfo) MustFields

func (ti *TypeInfo) MustFields(tagname string, iface reflect.Type) []*FieldWithTag

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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