234 lines
3.8 KiB
Cheetah
234 lines
3.8 KiB
Cheetah
package {{.PackageName}}
|
|
|
|
import (
|
|
"database/sql"
|
|
"errors"
|
|
"iter"
|
|
|
|
"github.com/mattn/go-sqlite3"
|
|
)
|
|
|
|
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 */}}
|