sqlb

package module
v0.1.0 Latest Latest
Warning

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

Go to latest
Published: Jul 11, 2023 License: MIT Imports: 16 Imported by: 0

README

go-sqlb

GoDev

go-sqlb パッケージは SQL 操作のユーティリティを提供します.

Usage

import "github.com/17e10/go-sqlb"

var extra []sqlb.Sqler

// 追加条件1 オーストラリア出身
extra = append(extra, sqlb.T("birthplace = @", "Australia"))

// 追加条件2 A から始まる名前
extra = append(extra, sqlb.T("(@ <= given_name AND given_name < @)", "A", "B"))

query := sqlb.M(`
    SELECT
        given_name, family_name
    FROM
        person
    WHERE
        gen = @gen
    AND $extra
`, map[string]any{
    "@gen":   3,
    "$extra": sqlb.And(extra...),
})

s, _ := sqlb.Stringify(query)
sqlb.Compact(s) == `SELECT given_name, family_name FROM person WHERE gen = 3 AND birthplace = 'Australia' AND ('A' <= given_name AND given_name < 'B')`

License

This software is released under the MIT License, see LICENSE.

Author

17e10

Documentation

Overview

sqlb パッケージは SQL 操作のユーティリティを提供します.

sqlb は ORM (Object-Relational Mapping) のような大規模な仕組みではなく、 Go 標準パッケージの database/sql を容易に扱うためのユーティリティ群です.

MySQL で使用する場合 次の import を追加してください.

import _ "github.com/17e10/b/sqlb/dialect/mysql"

Sqler

SQL を動的に組み立てる仕組みに Sqler インターフェイスを導入しています.

type Sqler interface {
	Sql(w Writer) error
}

Sqler は SQL 文字列が必要になったときに Writer に SQL を出力していくことで 高速かつメモリ効率よく SQL を生成します.

SQL 記述

動的な SQL を簡潔に記述できる T 関数, M 関数を提供しています. これらの関数は SQL テンプレートに値や識別子, SQL を展開をできます. 構文は非常にシンプルながらとても柔軟かつ強力です.

値の展開: @

1つの値を展開:

nil			T("@", nil)							NULL
整数			T("@", 123)							123
浮動小数点	T("@", 123.45)						123.45
文字列		T("@", "abc")						'abc'
ブール値		T("@", false)						FALSE
バイト列		T("@", []byte{0x41, 0x42, 0x43})	X'414243'
日付時刻		T("@", time.Time{})					'2001-01-02 13:14:15.678901'

特別な展開:

値リスト				T("@", []any{"a", "b"})						'a', 'b'
グループリスト			T("@", [][]any{{"a", "b"}, {"c", "d"}})		('a', 'b'), ('c', 'd')
Key-Value ペアリスト	T("@", []Kv{{"k1", "v1"}, {"k2", "v2"}})	`k1` = 'v1', `k2` = 'v2'

識別子の展開: #

1つの識別子を展開:

識別子		T("#", "a")					`a`
フィールドリスト	T("#", []string{"a", "b"})	`a`, `b`

SQL の展開: $

SQL		T("WHERE $", sqler)		WHERE `a` = b

擬似イコール構文: == @, !== @

=				T("== @", "a")				= 'a'
!=				T("!== @", "a")				!= 'a'
IN (...)		T("== @", []any{"a", "b"})	IN ('a', 'b')
NOT IN (...)	T("!== @", []any{"a", "b"})	NOT IN ('a', 'b')
IS NULL			T("== @", nil)				IS NULL
IS NOT NULL		T("!== @", nil)				IS NOT NULL

Index

Examples

Constants

This section is empty.

Variables

View Source
var ColumnCase = nameb.Snake

ColumnCase は sqlb が生成するカラム名の形式を保持します.

Functions

func Columns

func Columns[V any](v *V, excludes ...string) []string

Columns は構造体からカラムリストを作成します.

excludes でリストから除外するカラムを指定できます.

func Compact

func Compact(s string) string

Compact は SQL から重複するスペースを削除します.

func Exec

func Exec(conn sqlt.Execer, ctx context.Context, sqler Sqler) (sql.Result, error)

Exec は database/sql の ExecContext メソッドを Sqler で呼び出すショートハンドです.

func GroupValues

func GroupValues[V any](v []V, excludes ...string) [][]any

GroupValues は構造体の配列からグループリストを作成します.

excludes でリストから除外するカラムを指定できます.

func Query

func Query(conn sqlt.Queryer, ctx context.Context, sqler Sqler) (*sql.Rows, error)

Query は database/sql の QueryContext メソッドを Sqler で呼び出すショートハンドです.

func QueryRow

func QueryRow(conn sqlt.QueryRower, ctx context.Context, sqler Sqler) *sql.Row

QueryRow は database/sql の QueryRowContext メソッドを Sqler で呼び出すショートハンドです.

func Scan

func Scan[V any](row sqlt.RowsScanner, dest *V) error

Scan は database/sql の Row(s).Scan メソッドの結果を構造体に入れます.

Scan で受け取るフィールド順序は Columns で生成されるカラム列の順序と一致します.

Example
var person struct {
	ID         uint64
	GivenName  string
	FamilyName string
}

// クエリを実行する
// SELECT id, given_name, family_name FROM person ORDER BY id
rows, err := sqlb.Query(conn, ctx, sqlb.T(
	"SELECT # FROM person ORDER BY id",
	sqlb.Columns(&person),
))
if err != nil {
	return
}
defer rows.Close()

// Rows を読む
for rows.Next() {
	if err = sqlb.Scan(rows, &person); err != nil {
		return
	}
	fmt.Printf("%#v\n", &person)
}
Output:

func Stringify

func Stringify(sqler Sqler) (string, error)

Sqler から文字列を得ます.

func Values

func Values[V any](v *V, excludes ...string) []any

Values は構造体から値リストを作成します.

excludes でリストから除外するカラムを指定できます.

Types

type Kv

type Kv struct {
	K string
	V any
}

Kv は Key-Value ペア `key` = val を表す構造体です.

func KeyValues

func KeyValues[V any](v *V, excludes ...string) []Kv

KeyValues は構造体から Key-Value リストを作成します.

excludes でリストから除外するカラムを指定できます.

type Sqler

type Sqler interface {
	Sql(w Writer) error
}

Sqler は SQL を構築するインターフェイスを表します.

func And

func And(v ...Sqler) Sqler

And は条件式を表す Sqler を AND で繋げます.

func Bracket

func Bracket(sqler Sqler) Sqler

Bracket は条件式を表す Sqler を括弧で括ります.

func M

func M(tmpl string, params map[string]any) Sqler

M は名前付きプレースホルダを展開します.

M は比較的長い SQL を記述するための関数です. tmpl には次の構文が利用できます.

$sqler_name // Sqler
#ident_name // 識別子
@value_name // 値
Example
var extra []sqlb.Sqler

// 追加条件1 オーストラリア出身
extra = append(extra, sqlb.T("birthplace = @", "Australia"))

// 追加条件2 A から始まる名前
extra = append(extra, sqlb.T("(@ <= given_name AND given_name < @)", "A", "B"))

query := sqlb.M(`
		SELECT
			given_name, family_name
		FROM
			person
		WHERE
			gen = @gen
		AND $extra
	`, map[string]any{
	"@gen":   3,
	"$extra": sqlb.And(extra...),
})

s, _ := sqlb.Stringify(query)
fmt.Println(sqlb.Compact(s))
Output:

SELECT given_name, family_name FROM person WHERE gen = 3 AND birthplace = 'Australia' AND ('A' <= given_name AND given_name < 'B')

func Or

func Or(v ...Sqler) Sqler

Or は条件式を表す Sqler を OR で繋げます.

func T

func T(tmpl string, a ...any) Sqler

T はプレースホルダを展開します.

T は比較的短い SQL を簡潔に記述するための関数です. tmpl には次の構文が利用できます.

$(index) // Sqler
#(index) // 識別子
@(index) // 値

index は省略可能で 省略した場合は引数の先頭から順に展開します. index を指定した場合は指定した位置の引数から順に展開します.

Example
type person struct {
	Id         uint64
	GivenName  string
	FamilyName string
	Age        int
}
persons := []person{
	{1, "Olivia", "Williams", 54},
	{2, "Kenny", "Loggins", 75},
}

query := sqlb.T(
	"INSERT INTO person (#) VALUES @",
	sqlb.Columns((*person)(nil), "id"),
	sqlb.GroupValues(persons, "id"),
)

s, _ := sqlb.Stringify(query)
fmt.Println(sqlb.Compact(s))
Output:

INSERT INTO person (`given_name`, `family_name`, `age`) VALUES ('Olivia', 'Williams', 54), ('Kenny', 'Loggins', 75)

type SqlerFunc

type SqlerFunc func(w Writer) error

SqlerFunc 型は関数を Sqler として使用できるようにするアダプタです.

func (SqlerFunc) Sql

func (fn SqlerFunc) Sql(w Writer) error

Sql は fn(w) を呼び出します.

type StringSqler

type StringSqler string

StringSqler は Sqler インターフェイスを持つ文字列型です.

func (StringSqler) Sql

func (s StringSqler) Sql(w Writer) error

type Writer

type Writer = d.Writer

Writer は SQL を書き込むインターフェイスです.

標準的な Writer は bytes.Buffer や strings.Builder です.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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