sqlfunc

package module
v0.0.3 Latest Latest
Warning

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

Go to latest
Published: Oct 17, 2025 License: MIT Imports: 8 Imported by: 0

README

SQL-Function

Run your SQL as function.

Example

import (
	"context"
	"database/sql"
	"log"

	"github.com/deadblue/sqlfunc"
)

type (
	QueryParams struct {
		UserId string
		Status int
	}

	UserResult struct {
		UserId    string
		FirstName string
		// sql.NullXXX types are supported.
		LastName sql.NullString
		// Mapping "sex" column to [Gender] field.
		Gender int `sql:"sex"`
	}
)

func main() {
	// Make SQL function
	queryUser, err := sqlfunc.MakeQueryFunc[QueryParams, UserResult](
		"SELECT user_id, first_name, last_name, sex",
		"FROM tbl_user",
		"WHERE user_id = {{ .UserID }} AND status = {{ .Status }}",
	)
	if err != nil {
		panic(err)
	}

	// Connect to database
	db, err := sql.Open("driver", "DSN")
	if err != nil {
		panic(err)
	}
	// Put DB to context
	ctx := sqlfunc.NewContext(context.TODO(), db)

	// Execute query
	result, err := queryUser(ctx, QueryParams{
		UserId: "123",
		Status: 1,
	})
	if err != nil {
		panic(err)
	}
	// Process result
	if result.Valid {
		user := result.V
		if user.LastName.Valid {
			log.Printf("Found user: %s-%s", user.FirstName, user.LastName.String)
		} else {
			log.Printf("Found user: %s", user.FirstName)
		}
	}
}

License

MIT

Documentation

Overview

Example
package main

import (
	"context"
	"database/sql"
	"log"

	"github.com/deadblue/sqlfunc"
)

type (
	QueryParams struct {
		UserId string
		Status int
	}

	UserResult struct {
		UserId    string
		FirstName string
		// sql.NullXXX types are supported.
		LastName sql.NullString
		// Mapping "sex" column to [Gender] field.
		Gender int `sql:"sex"`
	}
)

func main() {
	// Make SQL function
	queryUser, err := sqlfunc.MakeQueryFunc[QueryParams, UserResult](
		"SELECT user_id, first_name, last_name, sex",
		"FROM tbl_user",
		"WHERE user_id = {{ .UserID }} AND status = {{ .Status }}",
	)
	if err != nil {
		panic(err)
	}

	// Connect to database
	db, err := sql.Open("driver", "DSN")
	if err != nil {
		panic(err)
	}
	// Put DB to context
	ctx := sqlfunc.NewContext(context.TODO(), db)

	// Execute query
	result, err := queryUser(ctx, QueryParams{
		UserId: "123",
		Status: 1,
	})
	if err != nil {
		panic(err)
	}
	if !result.Valid {
		return
	}
	user := result.V
	// Process result
	if user.LastName.Valid {
		log.Printf("Found user: %s-%s", user.FirstName, user.LastName.String)
	} else {
		log.Printf("Found user: %s", user.FirstName)
	}
}

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func NewContext

func NewContext(parent context.Context, executor Executor) context.Context

NewContext returns a derived context from parent, with executor in it.

Types

type Executor

type Executor interface {
	// ExecContext executes a query without returning any rows.
	ExecContext(ctx context.Context, query string, args ...any) (sql.Result, error)

	// QueryContext executes a query that returns rows, typically a SELECT.
	QueryContext(ctx context.Context, query string, args ...any) (*sql.Rows, error)
}

Executor interface declares required methods to execute query, that are implemented by *sql.DB, *sql.Conn and *sql.Tx.

type QueryFunc

type QueryFunc[P, R any] func(context.Context, P) (sql.Null[R], error)

QueryFunc executes a retrieving query, returns the first result.

func MakeQueryFunc

func MakeQueryFunc[P, R any](lines ...string) (f QueryFunc[P, R], err error)

MakeQueryFunc makes a QueryFunc from query template lines.

type QueryFunc0

type QueryFunc0[R any] func(context.Context) (sql.Null[R], error)

QueryFunc executes a retrieving query without parameters, returns the first result.

func MakeQueryFunc0

func MakeQueryFunc0[R any](lines ...string) (f QueryFunc0[R], err error)

MakeQueryFunc0 makes a QueryFunc0 from query lines.

type QuerySeqFunc

type QuerySeqFunc[P, R any] func(context.Context, P) (iter.Seq[R], error)

QuerySeqFunc executes a retrieving query, returns an iterator for all matched results.

func MakeQuerySeqFunc

func MakeQuerySeqFunc[P, R any](lines ...string) (f QuerySeqFunc[P, R], err error)

MakeQuerySeqFunc makes a QuerySeqFunc from query template lines.

type QuerySeqFunc0

type QuerySeqFunc0[R any] func(context.Context) (iter.Seq[R], error)

QuerySeqFunc0 executes a retrieving query without parameters, returns an iterator for all matched results.

func MakeQuerySeqFunc0

func MakeQuerySeqFunc0[R any](lines ...string) (f QuerySeqFunc0[R], err error)

MakeQuerySeqFunc0 makes a QuerySeqFunc0 from query lines.

type Scannable

type Scannable interface {
	// Dest returns scanning dest for columns.
	Dest(columns []string) (dest []any)
}

Scannable is an interface that can be implemented by query result struct, to avoid the performance overhead of reflection.

When result struct implements Scannable interface, sqlfunc calls Dest to get corresponding dests for columns.

Example:

type UserResult struct{
	Foo string
	Bar int
}

func (r *UserResult) Dest(columns []string) (dest []any) {
	for _, column := range columns {
		switch column {
		case "foo":
			dest = append(dest, &r.Foo)
		case "bar":
			dest = append(dest, &r.Bar)
		default:
			dest = append(dest, sqlfunc.Void{})
		}
	}
	return
}

type UpdateFunc

type UpdateFunc[P any] func(context.Context, P) (int64, error)

UpdateFunc executes an updating query, returns the number or rows affected by updating query.

func MakeUpdateFunc

func MakeUpdateFunc[P any](lines ...string) (f UpdateFunc[P], err error)

MakeUpdateFunc makes an UpdateFunc from query template lines.

type Void

type Void struct{}

Void implements sql.Scanner interface but discards the value.

func (Void) Scan

func (v Void) Scan(src any) error

Jump to

Keyboard shortcuts

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