unify (and extend) query specification

This commit is contained in:
Helmut Merz 2024-04-12 12:46:27 +02:00
parent cad0da95e1
commit a9f8ea6b47
4 changed files with 51 additions and 32 deletions

View file

@ -4,7 +4,6 @@ import (
"strings" "strings"
"text/template" "text/template"
lib "git.sr.ht/~cco/go-scopes"
"git.sr.ht/~cco/go-scopes/logging/log" "git.sr.ht/~cco/go-scopes/logging/log"
) )
@ -22,7 +21,7 @@ func Template(name, src string) *template.Template {
return t return t
} }
func BuildSql(t *template.Template, data lib.Map) string { func BuildSql(t *template.Template, data any) string {
var out strings.Builder var out strings.Builder
err := t.Execute(&out, data) err := t.Execute(&out, data)
if err != nil { if err != nil {

View file

@ -41,17 +41,16 @@ insert into {{ $tablename }} (
returning trackid, timestamp` returning trackid, timestamp`
sql_select = ` sql_select = `
{{- $tablename := or (and .schema (printf "%s.%s" .schema .tablename)) .tablename -}} select {{ range $j, $c := .Scols -}}
select {{ range $j, $c := .scols -}}
{{- if ne $j 0 -}}, {{ end }}{{ toLower $c }}{{- end }} {{- if ne $j 0 -}}, {{ end }}{{ toLower $c }}{{- end }}
from {{ $tablename }} from {{ .Table }}
where {{ range $j, $c := .qucols -}} where {{ range $j, $c := .Qucols -}}
{{- if ne $j 0 }} and {{ end }}{{ toLower $c }} = ${{ add1 $j }}{{- end }} {{- if ne $j 0 }} and {{ end }}{{ toLower $c }} = ${{ add1 $j }}{{- end }}
{{ with .ordcols -}} {{ with .Ordcols -}}
order by {{ range $j, $c := . -}} order by {{ range $j, $c := . -}}
{{- if ne $j 0 -}}, {{ end }}{{ toLower $c }}{{- end -}} {{- if ne $j 0 -}}, {{ end }}{{ toLower $c }}{{- end -}}
{{- end }} {{- end }}
{{ with .limit }}limit {{ . }}{{ end }} {{ with .Limit }}limit {{ . }}{{ end }}
` `
) )

View file

@ -5,6 +5,7 @@ package tracking
import ( import (
sqllib "database/sql" sqllib "database/sql"
"encoding/json" "encoding/json"
"fmt"
"time" "time"
lib "git.sr.ht/~cco/go-scopes" lib "git.sr.ht/~cco/go-scopes"
@ -92,6 +93,36 @@ func Tracks(db *sql.Storage) *Container {
return &Container{container_definition, db} return &Container{container_definition, db}
} }
func (cont *Container) setupQuerySpec(spec *querySpec) *querySpec {
if cont.Storage.Schema == "" {
spec.Table = cont.TableName
} else {
spec.Table = fmt.Sprintf("%s.%s", cont.Storage.Schema, cont.TableName)
}
spec.Scols = append(cont.HeadFields, "timestamp", "data", "trackid")
for i, v := range spec.Headvals {
if v != "" {
spec.Qucols = append(spec.Qucols, cont.HeadFields[i])
spec.Quvals = append(spec.Quvals, v)
}
}
return spec
}
type querySpec struct {
Table string
Headvals lib.StrSlice
Scols lib.StrSlice
Qucols, Ordcols lib.StrSlice
Quspecs []struct{ col, op string }
Ordspecs []struct {
Col string
Desc bool
}
Limit int
Quvals []any
}
func (cont *Container) Get(id lib.Ident) *Track { func (cont *Container) Get(id lib.Ident) *Track {
db := cont.Storage db := cont.Storage
var tr *Track var tr *Track
@ -99,41 +130,31 @@ func (cont *Container) Get(id lib.Ident) *Track {
tr = cont.ItemFactory(cont) tr = cont.ItemFactory(cont)
return tr.ScanP(r) return tr.ScanP(r)
} }
quData := lib.Map{ quSpec := &querySpec{
"schema": db.Schema, Qucols: lib.StrSlice{"trackid"},
"tablename": cont.TableName, Quvals: []any{id},
"scols": append(cont.HeadFields, "timestamp", "data", "trackid"),
"qucols": lib.StrSlice{"trackid"},
} }
sql := storage.BuildSql(SqlSelect, quData) cont.setupQuerySpec(quSpec)
sql := storage.BuildSql(SqlSelect, quSpec)
db.Query(proc, sql, id) db.Query(proc, sql, id)
return tr return tr
} }
func (cont *Container) QueryLast(hv lib.StrSlice) *Track { func (cont *Container) QueryLast(hv ...string) *Track {
db := cont.Storage db := cont.Storage
var tr *Track var tr *Track
proc := func(r *sql.Rows) error { proc := func(r *sql.Rows) error {
tr = cont.ItemFactory(cont) tr = cont.ItemFactory(cont)
return tr.ScanP(r) return tr.ScanP(r)
} }
var qucols lib.StrSlice quSpec := &querySpec{
var quvals []any Headvals: hv,
for i, k := range hv { Ordcols: lib.StrSlice{"timestamp"},
if k != "" {
qucols = append(qucols, cont.HeadFields[i])
quvals = append(quvals, k)
}
} }
quData := lib.Map{ cont.setupQuerySpec(quSpec)
"schema": db.Schema, sql := storage.BuildSql(SqlSelect, quSpec)
"tablename": cont.TableName, println(sql)
"scols": append(cont.HeadFields, "timestamp", "data", "trackid"), db.Query(proc, sql, quSpec.Quvals...)
"qucols": qucols,
"ordcols": lib.StrSlice{"timestamp"},
}
sql := storage.BuildSql(SqlSelect, quData)
db.Query(proc, sql, quvals...)
return tr return tr
} }

View file

@ -74,7 +74,7 @@ func TrackingTest(t *testing.T, cfg *sql.Cfg, db *sql.Storage) {
tr2 := cont.Get(1) tr2 := cont.Get(1)
//fmt.Printf("%+v\n", tr2.TimeStamp()) //fmt.Printf("%+v\n", tr2.TimeStamp())
t.AssertEqual(tr2.Head["userName"], "john") t.AssertEqual(tr2.Head["userName"], "john")
tr3 := cont.QueryLast(lib.StrSlice{"", "john"}) tr3 := cont.QueryLast("", "john")
t.AssertEqual(tr3.Head["taskId"], "t01") t.AssertEqual(tr3.Head["taskId"], "t01")
} }