go/sqlgen/sqlite.go.tmpl
2024-11-18 17:01:17 +01:00

231 lines
3.7 KiB
Cheetah

package {{.PackageName}}
import (
"database/sql"
"iter"
)
var (
ErrConstraint = errors.New("constraint violation")
ErrNotFound = errors.New("not found")
)
func translateError(err error) error {
if err == nil {
return nil
}
if e, ok := err.(sqlite3.Error); ok && e.Code == 19 {
return ErrConstraint
}
if errors.Is(err, sql.ErrNoRows) {
return ErrNotFound
}
return err
}
type TX interface {
Exec(query string, args ...any) (sql.Result, error)
Query(query string, args ...any) (*sql.Rows, error)
QueryRow(query string, args ...any) *sql.Row
}
{{range .Schema.Tables}}
// ----------------------------------------------------------------------------
// Table: {{.Name}}
// ----------------------------------------------------------------------------
type {{.Type}} struct {
{{- range .Columns}}
{{.Name}} {{.Type}}{{end}}
}
const {{.Type}}_SelectQuery = "{{.SelectQuery}}"
{{if not .NoInsert -}}
func {{.Type}}_Insert(
tx TX,
row *{{.Type}},
) (err error) {
{{.Type}}_Sanitize(row)
if err = {{.Type}}_Validate(row); err != nil {
return err
}
_, err = tx.Exec("{{.InsertQuery}}", {{.InsertArgs}})
return translateError(err)
}
{{- end}} {{/* if not .NoInsert */}}
{{if not .NoUpdate -}}
{{if .UpdateCols -}}
func {{.Type}}_Update(
tx TX,
row *{{.Type}},
) (err error) {
{{.Type}}_Sanitize(row)
if err = {{.Type}}_Validate(row); err != nil {
return err
}
result, err := tx.Exec("{{.UpdateQuery}}", {{.UpdateArgs}})
if err != nil {
return translateError(err)
}
n, err := result.RowsAffected()
if err != nil {
panic(err)
}
switch n {
case 0:
return ErrNotFound
case 1:
return nil
default:
panic("multiple rows updated")
}
}
{{- end}}
{{if .UpdateFullCols -}}
func {{.Type}}_UpdateFull(
tx TX,
row *{{.Type}},
) (err error) {
{{.Type}}_Sanitize(row)
if err = {{.Type}}_Validate(row); err != nil {
return err
}
result, err := tx.Exec("{{.UpdateFullQuery}}", {{.UpdateFullArgs}})
if err != nil {
return translateError(err)
}
n, err := result.RowsAffected()
if err != nil {
panic(err)
}
switch n {
case 0:
return ErrNotFound
case 1:
return nil
default:
panic("multiple rows updated")
}
}
{{- end}}
{{- end}} {{/* if not .NoUpdate */}}
{{if not .NoDelete -}}
func {{.Type}}_Delete(
tx TX,
{{.PKFunctionArgs -}}
) (err error) {
result, err := tx.Exec("{{.DeleteQuery}}", {{.DeleteArgs}})
if err != nil {
return translateError(err)
}
n, err := result.RowsAffected()
if err != nil {
panic(err)
}
switch n {
case 0:
return ErrNotFound
case 1:
return nil
default:
panic("multiple rows deleted")
}
}
{{- end}}
func {{.Type}}_Get(
tx TX,
{{.PKFunctionArgs -}}
) (
row *{{.Type}},
err error,
) {
row = &{{.Type}}{}
r := tx.QueryRow("{{.GetQuery}}", {{.DeleteArgs}})
err = translateError(r.Scan({{.ScanArgs}}))
return
}
func {{.Type}}_GetWhere(
tx TX,
query string,
args ...any,
) (
row *{{.Type}},
err error,
) {
row = &{{.Type}}{}
r := tx.QueryRow(query, args...)
err = translateError(r.Scan({{.ScanArgs}}))
return
}
func {{.Type}}_Iterate(
tx TX,
query string,
args ...any,
) (
iter.Seq2[*{{.Type}}, error],
) {
rows, err := tx.Query(query, args...)
if err != nil {
return func(yield func(*{{.Type}}, error) bool) {
yield(nil, err)
}
}
return func(yield func(*{{.Type}}, error) bool) {
defer rows.Close()
for rows.Next() {
row := &{{.Type}}{}
err := translateError(rows.Scan({{.ScanArgs}}))
if !yield(row, err) {
return
}
}
}
}
func {{.Type}}_List(
tx TX,
query string,
args ...any,
) (
l []*{{.Type}},
err error,
) {
for row, err := range {{.Type}}_Iterate(tx, query, args...) {
if err != nil {
return nil, err
}
l = append(l, row)
}
return l, nil
}
{{end}} {{/* range .Schema.Tables */}}