sql

package
v0.67.0 Latest Latest
Warning

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

Go to latest
Published: Aug 11, 2026 License: BSD-3-Clause Imports: 15 Imported by: 0

Documentation

Overview

Package sql is an extension to standard library database/sql that provides common functionalities across DBMS.

Index

Examples

Constants

View Source
const (
	DriverNameMysql    = "mysql"
	DriverNamePostgres = "postgres"
)

List of known driver name for database connection.

View Source
const DefaultPlaceHolder = "?"

DefaultPlaceHolder define default placeholder for DML, which is placeholder for MySQL.

Variables

This section is empty.

Functions

func BulkInsert added in v0.66.0

func BulkInsert(dbs Session, meta *Meta, tableName string) (result sql.Result, err error)

BulkInsert executes bulk INSERT on table tableName using meta to generate query.

func Delete added in v0.66.0

func Delete(dbs Session, meta *Meta, tableName string) (result sql.Result, err error)

Delete executes the DELETE statement on table tableName using meta to generate query.

func Insert added in v0.66.0

func Insert(dbs Session, meta *Meta, tableName string) (result sql.Result, err error)

Insert executes the INSERT statement into table tableName using meta to generate query.

func Select added in v0.66.0

func Select(dbs Session, meta *Meta, tableName string) (err error)

Select executes SELECT statement with Session.QueryRow using meta to generate query on table tableName.

func SelectManyFunc added in v0.66.0

func SelectManyFunc(dbs Session, meta *Meta, tableName string, afterScan func()) (err error)

SelectManyFunc executes SELECT statement with Session.Query using meta to generate query on table tableName. The afterScan function is called after sql.Rows.Scan is completed in loop.

func Update added in v0.66.0

func Update(dbs Session, meta *Meta, tableName string) (result sql.Result, err error)

Update executes the UPDATE statement on table tableName using meta to generate query string.

Types

type Client

type Client struct {
	*sql.DB
	ClientOptions
	TableNames []string // List of tables in database.
}

Client provides a wrapper for generic database instance.

func NewClient

func NewClient(opts ClientOptions) (cl *Client, err error)

NewClient creates and initializes new database client.

func (*Client) FetchTableNames

func (cl *Client) FetchTableNames() (tableNames []string, err error)

FetchTableNames returns the table names in current database schema sorted in ascending order.

func (*Client) Meta

func (cl *Client) Meta() *Meta

Meta returns new instance of Meta.

func (*Client) Migrate

func (cl *Client) Migrate(tableMigration string, fs *memfs.MemFS) (listApplied []string, err error)

Migrate migrates the database using the list of SQL files inside the fs instance and returns only list of applied SQL migration files. The returned listApplied can be used to execute code-based data migration based on file name.

Each SQL files in the fs will be executed in alphabetical order based on the last state. The state of migration is stored in tableMigration, default to "_migration" if its empty.

DDL for table migration,

CREATE TABLE _migration (
  filename    VARCHAR(1024) PRIMARY KEY
, applied_at  TIMESTAMP DEFAULT NOW()
);

The state including the SQL file name that has been executed and the timestamp.

func (*Client) TruncateTable

func (cl *Client) TruncateTable(tableName string) (err error)

TruncateTable truncate all data on table `tableName` with cascade option. On PostgreSQL, any identity columns (for example, serial) will be reset back to its initial value.

type ClientOptions

type ClientOptions struct {
	DriverName   string
	DSN          string
	MigrationDir string
}

ClientOptions contains options to connect to database server, including the migration directory.

type Meta

type Meta struct {

	// ListName contains list of column name.
	ListName []string

	// ListValue contains list of column values, either for insert or
	// select.
	ListValue []any
	// contains filtered or unexported fields
}

Meta contains the DML meta data, including driver name, list of column names, list of column holders, and list of values.

Example (DeleteOnPostgresql)
package main

import (
	"fmt"

	"kilabit.info/pakakeh.go/lib/sql"
)

func main() {
	var (
		meta  = sql.NewMeta(sql.DriverNamePostgres)
		qid   = 1
		qname = `hello`
	)

	meta.BindWhere(``, `id`, `=`, qid)
	meta.BindWhere(`OR`, `name`, `=`, qname)

	var q = fmt.Sprintf(`DELETE FROM t WHERE %s;`, meta.WhereFields())

	// db.Exec(q, meta.WhereValues()...)

	fmt.Println(q)
	fmt.Println(meta.WhereValues())

}
Output:
DELETE FROM t WHERE  id = $1 OR name = $2;
[1 hello]
Example (InsertOnPostgresql)
package main

import (
	"fmt"

	"kilabit.info/pakakeh.go/lib/sql"
)

func main() {
	type Table struct {
		Name string
		ID   int
	}

	var (
		meta = sql.NewMeta(sql.DriverNamePostgres)
		t    = Table{
			ID:   1,
			Name: `hello`,
		}
	)

	meta.Bind(`id`, t.ID)
	meta.Bind(`name`, t.Name)

	var q = fmt.Sprintf(`INSERT INTO t (%s) VALUES (%s);`, meta.Names(),
		meta.InsertHolders())

	// db.Exec(q, meta.ListValue...)

	fmt.Println(q)
	fmt.Println(meta.ListValue)

}
Output:
INSERT INTO t (id,name) VALUES ($1,$2);
[1 hello]
Example (SelectOnPostgresql)
package main

import (
	"fmt"

	"kilabit.info/pakakeh.go/lib/sql"
)

func main() {
	type Table struct {
		Name string
		ID   int
	}

	var (
		meta  = sql.NewMeta(sql.DriverNamePostgres)
		t     = Table{}
		qid   = 1
		qname = `hello`
	)

	meta.BindSelect(`id`, &t.ID)
	meta.BindSelect(`name`, &t.Name)
	meta.BindWhere(``, `id`, `=`, qid)
	meta.BindWhere(`OR`, `name`, `=`, qname)

	var q = fmt.Sprintf(`SELECT %s FROM t WHERE %s;`, meta.Names(), meta.WhereFields())

	// db.QueryRow(q, meta.WhereValues()...).Scan(meta.ListValue...)

	fmt.Println(q)
	fmt.Println(`WHERE=`, meta.WhereValues())
	fmt.Println(len(meta.ListValue))

}
Output:
SELECT id,name FROM t WHERE  id = $1 OR name = $2;
WHERE= [1 hello]
2
Example (Subquery)

Example of creating parent and sub-query.

package main

import (
	"fmt"
	"slices"

	"kilabit.info/pakakeh.go/lib/sql"
)

func main() {
	type Table struct {
		Name  string
		ID    int
		SubID int
	}

	var (
		meta  = sql.NewMeta(sql.DriverNamePostgres)
		id    = 1
		subid = 500
		t     Table
	)

	meta.BindSelect(`id`, &t.ID)
	meta.BindSelect(`sub_id`, &t.SubID)
	meta.BindSelect(`name`, &t.Name)
	meta.BindWhere(``, `id`, `=`, id)

	subq := meta.Sub()
	subq.BindSelect(`id`, nil)
	subq.BindWhere(``, `u.id`, `=`, subid)

	q := fmt.Sprintf(`%s AND sub_id = (%s)`, meta.Select(`t`), subq.Select(`u`))
	vals := slices.Concat(meta.WhereValues(), subq.WhereValues())
	fmt.Println(q)
	fmt.Println(vals)

}
Output:
SELECT id,sub_id,name FROM t WHERE  id = $1 AND sub_id = (SELECT id FROM u WHERE  u.id = $2)
[1 500]

func NewMeta

func NewMeta(driverName string) (meta *Meta)

NewMeta creates new Meta using specific driver name and DML operations.

func (*Meta) Bind

func (meta *Meta) Bind(colName string, val any)

Bind binds the column name and value for DML INSERT or UPDATE.

Example
package main

import (
	"fmt"

	"kilabit.info/pakakeh.go/lib/sql"
)

func main() {
	type Table struct {
		Name string
		ID   int
	}

	meta := sql.NewMeta(sql.DriverNameMysql)
	t := Table{
		Name: `roana`,
		ID:   100,
	}

	meta.Bind(`id`, t.ID)
	meta.Bind(`name`, t.Name)

	fmt.Println(meta.Insert(`t`))
	fmt.Println(meta.InsertValues())

	fmt.Println(meta.Update(`t`))
	fmt.Println(meta.UpdateValues())

}
Output:
INSERT INTO t (id,name) VALUES (?,?);
[100 roana]
UPDATE t SET id=?,name=?
[100 roana]

func (*Meta) BindJoin added in v0.66.0

func (meta *Meta) BindJoin(onTable, alias, onColumn, refColumn string)

BindJoin adds the JOIN statement for SELECT query.

Example
package main

import (
	"fmt"

	"kilabit.info/pakakeh.go/lib/sql"
)

func main() {
	type row struct {
		name string
		id   int
	}
	qmeta := sql.NewMeta(sql.DriverNamePostgres)
	r := row{}
	qmeta.BindSelect(`id`, &r.id)
	qmeta.BindSelect(`name`, &r.name)
	qmeta.BindJoin(`other`, `o`, `o.id`, `my_table.id`)

	q := qmeta.Select(`my_table`)
	fmt.Println(q)
}
Output:
SELECT id,name FROM my_table JOIN other AS o ON o.id = my_table.id

func (*Meta) BindLeftJoin added in v0.66.0

func (meta *Meta) BindLeftJoin(onTable, alias, onColumn, refColumn string)

BindLeftJoin adds the LEFT JOIN statement for SELECT query.

Example
package main

import (
	"fmt"

	"kilabit.info/pakakeh.go/lib/sql"
)

func main() {
	type row struct {
		name string
		id   int
	}
	qmeta := sql.NewMeta(sql.DriverNamePostgres)
	r := row{}
	qmeta.BindSelect(`id`, &r.id)
	qmeta.BindSelect(`name`, &r.name)
	qmeta.BindLeftJoin(`other`, `o`, `o.id`, `my_table.id`)

	q := qmeta.Select(`my_table`)
	fmt.Println(q)
}
Output:
SELECT id,name FROM my_table LEFT JOIN other AS o ON o.id = my_table.id

func (*Meta) BindLimit added in v0.66.0

func (meta *Meta) BindLimit(n int)

BindLimit sets the limit of rows in select query.

Example
package main

import (
	"fmt"

	"kilabit.info/pakakeh.go/lib/sql"
)

func main() {
	type row struct {
		name string
		id   int
	}
	qmeta := sql.NewMeta(sql.DriverNamePostgres)
	r := row{}
	qmeta.BindSelect(`id`, &r.id)
	qmeta.BindSelect(`name`, &r.name)
	qmeta.BindLimit(10)

	q := qmeta.Select(`my_table`)
	fmt.Println(q)
}
Output:
SELECT id,name FROM my_table LIMIT 10

func (*Meta) BindOrderBy added in v0.66.0

func (meta *Meta) BindOrderBy(name, order string)

BindOrderBy adds the column name and their order for SELECT ... ORDER BY query.

Example
package main

import (
	"fmt"

	"kilabit.info/pakakeh.go/lib/sql"
)

func main() {
	var id int64
	var name string
	qmeta := sql.NewMeta(sql.DriverNamePostgres)
	qmeta.BindSelect(`id`, &id)
	qmeta.BindSelect(`name`, &name)
	qmeta.BindOrderBy(`id`, `DESC`)
	qmeta.BindOrderBy(`name`, `DESC`)
	fmt.Println(qmeta.Select(`my_table`))
}
Output:
SELECT id,name FROM my_table ORDER BY id DESC, name DESC

func (*Meta) BindSelect added in v0.66.0

func (meta *Meta) BindSelect(colName string, val any)

BindSelect binds the column name and scan holder value for DML SELECT.

func (*Meta) BindWhere

func (meta *Meta) BindWhere(logic, col, comp string, val any) (whereOp *OpWhere)

BindWhere binds the value val for DML WHERE condition.

The logic parameter defines the logical operator like "OR" and "AND" for joining multiple BindWhere.

The col parameter defines the column name to be compared with val.

The comp parameter defines the comparison for col and val, like "=" for equality or "!=" for non-equality;

The comp parameter also allow formatted query contains function call using "%?" as placeholder for val value. For example, "@@ websearch_to_tsquery('simple', %?)", bind val to parameter "%?" (the "$?" will be replaced by "?" or "$<DIGIT>" based on SQL driver).

Example
package main

import (
	"fmt"

	"kilabit.info/pakakeh.go/lib/sql"
)

func main() {
	var (
		meta = sql.NewMeta(sql.DriverNamePostgres)
		vals = []any{
			int(1000),
			string(`JohnDoe`),
		}
		id int
	)

	meta.BindSelect(`id`, &id)
	meta.BindWhere(``, `value`, `=`, vals[0])
	meta.BindWhere(`AND`, `name`, `=`, vals[1])
	meta.BindWhere(`AND`, `labels`, `=`, []string{`male`, `employee`})
	meta.BindWhere(`AND`, `to_tsvector('simple', title || ' ' || body)`,
		`@@ to_tsquery('simple', %?)`, `friend`)
	fmt.Println(meta.Select(`my_table`))
	fmt.Println(meta.WhereHolders())
	fmt.Println(meta.WhereValues())

}
Output:
SELECT id FROM my_table WHERE  value = $1 AND name = $2 AND labels = ANY($3) AND to_tsvector('simple', title || ' ' || body) @@ to_tsquery('simple', $4)
$1,$2,$3,$4
[1000 JohnDoe [male employee] friend]

func (*Meta) BulkBindName added in v0.66.0

func (meta *Meta) BulkBindName(name string, unique bool) (err error)

BulkBindName binds the column name for bulk insert. The argument unique=false allow setting the value only once in multiple insert-values.

See the examples in Meta.BulkInsert.

func (*Meta) BulkBindValues added in v0.66.0

func (meta *Meta) BulkBindValues(values ...any) (err error)

BulkBindValues bind the values for bulk insert. The number of arguments must match with the number of calls to [Meta.BindName].

See the examples in Meta.BulkInsert.

func (*Meta) BulkHolders

func (meta *Meta) BulkHolders() string

BulkHolders returns the string holders for bulk VALUES in INSERT query. For example, with Postgresql driver, it will return "($1,$2),($3,$4)".

func (*Meta) BulkInsert added in v0.66.0

func (meta *Meta) BulkInsert(tableName string) string

BulkInsert returns the string query for bulk INSERT. For example, with Postgresql driver, it will return "INSERT INTO t (x,y) VALUES ($1,$2),($3,$4)".

Example (NonPostgres)
package main

import (
	"fmt"

	"kilabit.info/pakakeh.go/lib/sql"
)

func main() {
	type Tag struct {
		Name string
		ID   int
	}
	type Document struct {
		Tags []Tag
		ID   int
	}

	meta := sql.NewMeta(sql.DriverNameMysql)
	doc := Document{
		ID: 1,
		Tags: []Tag{{
			ID:   100,
			Name: `tag A`,
		}, {
			ID:   101,
			Name: `tag B`,
		}},
	}

	meta.BulkBindName(`document_id`, false)
	meta.BulkBindName(`tag_id`, true)

	for _, tag := range doc.Tags {
		meta.BulkBindValues(doc.ID, tag.ID)
	}

	var q = fmt.Sprintf(`INSERT INTO document_tag (%s) VALUES %s;`,
		meta.Names(), meta.BulkHolders())

	// db.Exec(q, meta.InsertValues()...)

	fmt.Println(q)
	fmt.Println(meta.InsertValues())

}
Output:
INSERT INTO document_tag (document_id,tag_id) VALUES (?,?),(?,?);
[1 100 1 101]
Example (Postgres)
package main

import (
	"fmt"

	"kilabit.info/pakakeh.go/lib/sql"
)

func main() {
	type Tag struct {
		Name string
		ID   int
	}
	type Document struct {
		Tags []Tag
		ID   int
	}

	meta := sql.NewMeta(sql.DriverNamePostgres)
	doc := Document{
		ID: 1,
		Tags: []Tag{{
			ID:   100,
			Name: `tag A`,
		}, {
			ID:   101,
			Name: `tag B`,
		}},
	}

	meta.BulkBindName(`document_id`, false)
	meta.BulkBindName(`tag_id`, true)

	for _, tag := range doc.Tags {
		meta.BulkBindValues(doc.ID, tag.ID)
	}

	q := meta.BulkInsert(`document_tag`)

	// db.Exec(q, meta.InsertValues()...)

	fmt.Println(q)
	fmt.Println(meta.InsertValues())

}
Output:
INSERT INTO document_tag (document_id,tag_id) VALUES ($1,$2),($1,$3);
[1 100 101]

func (*Meta) Delete added in v0.66.0

func (meta *Meta) Delete(tableName string) string

Delete returns the DML for DELETE query.

Example
package main

import (
	"fmt"

	"kilabit.info/pakakeh.go/lib/sql"
)

func main() {
	qmeta := sql.NewMeta(sql.DriverNamePostgres)
	qmeta.BindWhere(``, `account_id`, `=`, 1000)
	qmeta.BindWhere(`AND`, `id`, `=`, 1)
	q := qmeta.Delete(`my_table`)
	fmt.Println(q)
	fmt.Println(qmeta.WhereValues())
}
Output:
DELETE FROM my_table WHERE  account_id = $1 AND id = $2
[1000 1]

func (*Meta) Insert added in v0.66.0

func (meta *Meta) Insert(tableName string) string

Insert returns the DML for INSERT query.

Example
package main

import (
	"fmt"

	"kilabit.info/pakakeh.go/lib/sql"
)

func main() {
	qmeta := sql.NewMeta(sql.DriverNamePostgres)
	qmeta.Bind(`name`, `roana`)
	qmeta.Bind(`age`, 43)
	q := qmeta.Insert(`my_table`)
	fmt.Println(q)
	fmt.Println(qmeta.InsertValues())
}
Output:
INSERT INTO my_table (name,age) VALUES ($1,$2);
[roana 43]

func (*Meta) InsertHolders added in v0.67.0

func (meta *Meta) InsertHolders() string

InsertHolders returns string of holders joined with comma "," for INSERT values. For example "$1,$2".

Example (Mysql)
package main

import (
	"fmt"

	"kilabit.info/pakakeh.go/lib/sql"
)

func main() {
	type Table struct {
		Name string
		ID   int
	}

	var (
		meta = sql.NewMeta(sql.DriverNameMysql)
		t    = Table{Name: `newname`, ID: 2}
	)

	meta.Bind(`id`, &t.ID)
	meta.Bind(`name`, &t.Name)

	fmt.Printf("INSERT INTO t VALUES (%s);\n", meta.InsertHolders())
}
Output:
INSERT INTO t VALUES (?,?);
Example (Postgres)
package main

import (
	"fmt"

	"kilabit.info/pakakeh.go/lib/sql"
)

func main() {
	type Table struct {
		Name string
		ID   int
	}

	var (
		meta = sql.NewMeta(sql.DriverNamePostgres)
		t    = Table{Name: `newname`, ID: 2}
	)

	meta.Bind(`id`, &t.ID)
	meta.Bind(`name`, &t.Name)

	fmt.Printf("INSERT INTO t VALUES (%s);\n", meta.InsertHolders())
}
Output:
INSERT INTO t VALUES ($1,$2);

func (*Meta) InsertValues

func (meta *Meta) InsertValues() []any

InsertValues returns the list of value for executing INSERT statement.

func (*Meta) Names

func (meta *Meta) Names() string

Names returns string of column names, for example "col1, col2, ...", for DML INSERT or SELECT.

Example
package main

import (
	"fmt"

	"kilabit.info/pakakeh.go/lib/sql"
)

func main() {
	type Table struct {
		Name string
		ID   int
	}

	var (
		meta = sql.NewMeta(sql.DriverNamePostgres)
		t    = Table{}
	)

	meta.Bind(`id`, &t.ID)
	meta.Bind(`name`, &t.Name)

	fmt.Printf("SELECT %s FROM t;\n", meta.Names())
}
Output:
SELECT id,name FROM t;

func (*Meta) ScanHolders added in v0.66.0

func (meta *Meta) ScanHolders() []any

ScanHolders returns list of variables for sql.Row.Scan or sql.Rows.Scan.

func (*Meta) Select added in v0.66.0

func (meta *Meta) Select(tableName string) (q string)

Select returns the DML SELECT for tableName.

Example
package main

import (
	"fmt"

	"kilabit.info/pakakeh.go/lib/sql"
)

func main() {
	var id int64
	var name string
	qmeta := sql.NewMeta(sql.DriverNamePostgres)
	qmeta.BindSelect(`id`, &id)
	qmeta.BindSelect(`name`, &name)
	q := qmeta.Select(`my_table`)
	fmt.Println(q)
	fmt.Printf("%T %T\n", qmeta.ScanHolders()...)
}
Output:
SELECT id,name FROM my_table
*int64 *string
Example (WithWhere)
package main

import (
	"fmt"

	"kilabit.info/pakakeh.go/lib/sql"
)

func main() {
	var id int64
	var name string
	qmeta := sql.NewMeta(sql.DriverNamePostgres)
	qmeta.BindSelect(`id`, &id)
	qmeta.BindSelect(`name`, &name)
	qmeta.BindWhere(``, `id`, `>`, 10)
	q := qmeta.Select(`my_table`)
	fmt.Println(q)
	fmt.Println(qmeta.WhereValues())
	fmt.Printf("%T %T\n", qmeta.ScanHolders()...)
}
Output:
SELECT id,name FROM my_table WHERE  id > $1
[10]
*int64 *string

func (*Meta) Sub

func (meta *Meta) Sub() (sub *Meta)

Sub returns the child of Meta for building subquery.

Example
package main

import (
	"fmt"
	"slices"

	"kilabit.info/pakakeh.go/lib/sql"
)

func main() {
	type Table struct {
		Name string
		ID   int
	}

	var (
		meta = sql.NewMeta(sql.DriverNamePostgres)
		t    = Table{}
		qid  = 1
	)

	meta.BindSelect(`id`, &t.ID)
	meta.BindSelect(`name`, &t.Name)
	meta.BindWhere(``, `id`, `=`, qid)

	var (
		metain = meta.Sub()
		qnames = []string{`hello`, `world`}
	)

	metain.BindWhere(``, ``, ``, qnames[0])
	metain.BindWhere(``, ``, ``, qnames[1])

	var q = fmt.Sprintf(`SELECT %s FROM t WHERE id=$1 OR name IN (%s);`,
		meta.Names(), metain.WhereHolders())

	var qparams = slices.Concat(meta.WhereValues(), metain.WhereValues())

	// db.QueryRow(q, qparams...).Scan(meta.ListValue...)

	fmt.Println(q)
	fmt.Println(`WHERE=`, meta.WhereValues())
	fmt.Println(`WHERE IN=`, metain.WhereValues())
	fmt.Println(`qparams=`, qparams)

}
Output:
SELECT id,name FROM t WHERE id=$1 OR name IN ($2,$3);
WHERE= [1]
WHERE IN= [hello world]
qparams= [1 hello world]

func (*Meta) Update added in v0.66.0

func (meta *Meta) Update(tableName string) (q string)

Update returns the DML UPDATE query for tableName.

Example
package main

import (
	"fmt"

	"kilabit.info/pakakeh.go/lib/sql"
)

func main() {
	qmeta := sql.NewMeta(sql.DriverNamePostgres)
	qmeta.Bind(`name`, `roana`)
	qmeta.Bind(`age`, 43)
	q := qmeta.Update(`my_table`)
	fmt.Println(q)
	fmt.Println(qmeta.UpdateValues())
}
Output:
UPDATE my_table SET name=$1,age=$2
[roana 43]
Example (WithWhere)
package main

import (
	"fmt"

	"kilabit.info/pakakeh.go/lib/sql"
)

func main() {
	qmeta := sql.NewMeta(sql.DriverNamePostgres)
	qmeta.Bind(`name`, `roana`)
	qmeta.Bind(`age`, 44)
	qmeta.BindWhere(``, `id`, `=`, `1`)
	q := qmeta.Update(`my_table`)
	fmt.Println(q)
	fmt.Println(qmeta.UpdateValues())
}
Output:
UPDATE my_table SET name=$1,age=$2 WHERE  id = $3
[roana 44 1]

func (*Meta) UpdateFields

func (meta *Meta) UpdateFields() string

UpdateFields returns string of "col1=<holder>, col2=<holder>, ..." for DML UPDATE.

Example
package main

import (
	"fmt"

	"kilabit.info/pakakeh.go/lib/sql"
)

func main() {
	type Table struct {
		Name string
		ID   int
	}

	var (
		meta = sql.NewMeta(sql.DriverNamePostgres)
		t    = Table{
			ID:   2,
			Name: `world`,
		}
		qid   = 1
		qname = `hello`
	)

	meta.Bind(`id`, t.ID)
	meta.Bind(`name`, t.Name)
	meta.BindWhere(``, `id`, `=`, qid)
	meta.BindWhere(`AND`, `name`, `=`, qname)

	var q = fmt.Sprintf(`UPDATE t SET %s WHERE %s;`,
		meta.UpdateFields(), meta.WhereFields())

	// db.Exec(q, meta.UpdateValues()...);

	fmt.Println(q)
	fmt.Println(`UpdateValues=`, meta.UpdateValues())

}
Output:
UPDATE t SET id=$1,name=$2 WHERE  id = $3 AND name = $4;
UpdateValues= [2 world 1 hello]

func (*Meta) UpdateValues

func (meta *Meta) UpdateValues() (listVal []any)

UpdateValues returns the merged of ListValue and list WhereValues for DML UPDATE.

Example
package main

import (
	"fmt"

	"kilabit.info/pakakeh.go/lib/sql"
)

func main() {
	type Table struct {
		Name string
		ID   int
	}

	var (
		meta = sql.NewMeta(sql.DriverNamePostgres)
		t    = Table{
			ID:   2,
			Name: `world`,
		}
		qid   = 1
		qname = `hello`
	)

	meta.Bind(`id`, t.ID)
	meta.Bind(`name`, t.Name)
	meta.BindWhere(``, `id`, `=`, qid)
	meta.BindWhere(`AND`, `name`, `=`, qname)

	var q = fmt.Sprintf(`UPDATE t SET %s WHERE %s;`,
		meta.UpdateFields(), meta.WhereFields())

	// db.Exec(q, meta.UpdateValues()...);

	fmt.Println(q)
	fmt.Println(`UpdateValues=`, meta.UpdateValues())

}
Output:
UPDATE t SET id=$1,name=$2 WHERE  id = $3 AND name = $4;
UpdateValues= [2 world 1 hello]

func (*Meta) WhereFields

func (meta *Meta) WhereFields() string

WhereFields returns the DML for WHERE query, as in "col=$? AND y!=$?...".

Example
package main

import (
	"fmt"

	"kilabit.info/pakakeh.go/lib/sql"
)

func main() {
	var meta = sql.NewMeta(sql.DriverNamePostgres)

	meta.BindWhere(``, `id`, `=`, 1000)
	meta.BindWhere(`AND`, `name`, `=`, `share`)

	fmt.Printf("SELECT * FROM t WHERE %s;\n", meta.WhereFields())
	fmt.Println(meta.WhereValues())

}
Output:
SELECT * FROM t WHERE  id = $1 AND name = $2;
[1000 share]

func (*Meta) WhereHolders

func (meta *Meta) WhereHolders() string

WhereHolders returns string of holders joining by comma, for example "$1,$2, ...", based on number of item added with Meta.BindWhere. Similar to method Holders but for where condition.

Example
package main

import (
	"fmt"

	"kilabit.info/pakakeh.go/lib/sql"
)

func main() {
	var meta = sql.NewMeta(sql.DriverNamePostgres)

	meta.BindWhere(``, ``, ``, 1000)
	meta.BindWhere(``, ``, ``, `share`)

	fmt.Printf("SELECT * FROM t WHERE id IN (%s);\n", meta.WhereHolders())
	fmt.Println(meta.WhereValues())

}
Output:
SELECT * FROM t WHERE id IN ($1,$2);
[1000 share]

func (*Meta) WhereValues

func (meta *Meta) WhereValues() (list []any)

WhereValues returns list of values in WHERE conditions.

type OpWhere

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

OpWhere stores the operation for WHERE conditions from calling Meta.BindWhere.

func (OpWhere) String

func (op OpWhere) String() (q string)

type Session

type Session interface {
	Exec(query string, args ...any) (sql.Result, error)
	ExecContext(ctx context.Context, query string, args ...any) (sql.Result, error)
	Prepare(query string) (*sql.Stmt, error)
	PrepareContext(ctx context.Context, query string) (*sql.Stmt, error)
	Query(query string, args ...any) (*sql.Rows, error)
	QueryContext(ctx context.Context, query string, args ...any) (*sql.Rows, error)
	QueryRow(query string, args ...any) *sql.Row
	QueryRowContext(ctx context.Context, query string, args ...any) *sql.Row
}

Session is an interface that represent both sql.DB and sql.Tx.

Source Files

  • client.go
  • client_options.go
  • meta.go
  • op_join.go
  • op_order_by.go
  • op_where.go
  • param.go
  • session.go
  • sql.go

Jump to

Keyboard shortcuts

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