more on SQL templates - create table 'tracks', with DB-specific parameters

This commit is contained in:
Helmut Merz 2024-03-24 19:13:10 +01:00
parent 0202727990
commit 8d022e1930
5 changed files with 72 additions and 28 deletions

View file

@ -5,3 +5,8 @@ package pgsql
import (
_ "github.com/lib/pq"
)
const (
IdType = "bigserial"
JsonType = "jsonb default '{}'::jsonb"
)

View file

@ -18,6 +18,8 @@ type Cfg struct {
type Storage struct {
*sql.DB
*Cfg
Schema string
Params map[string]string
Sql *template.Template
Errors []error
}
@ -46,7 +48,12 @@ func Open(cfg *Cfg) *Storage {
log.Error(err).Msg("sql.Open")
return nil
}
storage := Storage{DB: db, Cfg: cfg}
storage := Storage{
DB: db,
Cfg: cfg,
Schema: cfg.Schema,
Params: map[string]string{},
}
storage.Sql = storage.ParseTemplate(SqlSources)
return &storage
}
@ -118,6 +125,9 @@ func (db *Storage) Exec(q string, args ...interface{}) (int64, error) {
}
func (db *Storage) DropTable(tn string) error {
//if db.Schema != "" {
// tn = fmt.Sprintf("%s.%s", db.Schema, tn)
//}
_, err := db.Exec(fmt.Sprintf(sql_drop, tn))
return err
}

View file

@ -1,17 +1,36 @@
package tracking
const sql_table = `
{{- $tablename := .tablename -}}
create table {{ $tablename }} (
trackid {{ .idType }} primary key,
{{ range .headFields -}}{{ . }} text,
const (
sql_table = `
{{- $tablename := or (and .schema (printf "%s.%s" .schema .tablename)) .tablename -}}
{{- $json := or .jsonType "json" -}}
create table if not exists {{ $tablename }} (
trackid {{ or .idType "integer" }} primary key,
{{ range .headFields -}}{{ ToLower . }} text default '',
{{ end -}}
timestamp timestamptz default current_timestamp,
data {{ .jsonType -}}
data {{ $json }}
);
{{- range $i, $cols := .indexes }}
create index idx_{{ $i }} on {{ $tablename }} ({{ $cols }});
create index idx_{{ $.tablename }}_{{ Add1 $i }} on {{ $tablename }} (
{{- range $j, $c := $cols -}}
{{- if ne $j 0 -}}, {{ end }}{{ ToLower $c }}
{{- end -}}
);
{{- end }}
create index idx_timestamp on {{ .tablename }} (timestamp);
create index idx_{{ $.tablename }}_ts on {{ $tablename }} (timestamp);
`
sql_insert = `
{{- $tablename := or (and .schema (printf "%s.%s" .schema .tablename)) .tablename -}}
insert into {{ $tablename }} (
{{- range $j, $c := .columns -}}
{{- if ne $j 0 -}}, {{ end }}{{ ToLower $c }}
{{- end -}})
values (
{{- range $j, $c := .columns -}}
{{- if ne $j 0 -}}, {{ end }}${{ $j }}
{{- end -}})
`
)

View file

@ -5,6 +5,7 @@ package tracking
import (
"fmt"
"strings"
"text/template"
"time"
lib "git.sr.ht/~cco/go-scopes"
@ -21,31 +22,40 @@ type track struct {
type container struct {
headFields []string
indexes []string
indexes [][]string
storage *sql.Storage
}
func Container(db *sql.Storage) *container {
return &container{
headFields: []string{"taskId", "userName"},
//indexes: [][]string{[]string{"taskId", "userName"}, []string{"userName"}},
indexes: []string{"taskid, username", "username"},
storage: db,
indexes: [][]string{[]string{"taskId", "userName"}, []string{"userName"}},
storage: db,
}
}
func Create(cont *container) *container {
db := cont.storage
t := db.ParseTemplate(sql_table)
t := template.New("create_table")
t = t.Funcs(map[string]any{
"ToLower": strings.ToLower,
"Add1": func(i int) int { return i + 1 },
})
t, err := t.Parse(sql_table)
if err != nil {
db.LogErr(err, "storage.tracking.Create", fmt.Sprintf("%+v", t))
return nil
}
var out strings.Builder
data := map[string]interface{}{
"schema": db.Schema,
"tablename": "tracks",
"headFields": cont.headFields,
"indexes": cont.indexes,
"idType": "integer",
"jsonType": "json",
"idType": db.Params["idType"],
"jsonType": db.Params["jsonType"],
}
err := t.Execute(&out, data)
err = t.Execute(&out, data)
if err != nil {
db.LogErr(err, "storage.tracking.Create", fmt.Sprintf("%+v", t))
return nil
@ -53,10 +63,8 @@ func Create(cont *container) *container {
sql := out.String()
println(sql)
_, err = db.Exec(sql)
if err != nil {
println(err)
db.LogErr(err, "storage.tracking.Create", fmt.Sprintf("%+v", t))
return nil
if err == nil {
return cont
}
return cont
return nil
}

View file

@ -6,7 +6,7 @@ import (
"git.sr.ht/~cco/go-scopes/common/testing"
"git.sr.ht/~cco/go-scopes/core/message"
sql "git.sr.ht/~cco/go-scopes/storage"
_ "git.sr.ht/~cco/go-scopes/storage/db/pgsql"
"git.sr.ht/~cco/go-scopes/storage/db/pgsql"
_ "git.sr.ht/~cco/go-scopes/storage/db/sqlite"
msgstore "git.sr.ht/~cco/go-scopes/storage/message"
"git.sr.ht/~cco/go-scopes/storage/tracking"
@ -25,6 +25,8 @@ func TestPgsql(tb *tbase.T) {
t := testing.SetUp(tb)
cfg := etc.ConfigPgsql()
db := sql.Open(cfg)
db.Params["idType"] = pgsql.IdType
db.Params["jsonType"] = pgsql.JsonType
resetPgsql(db)
DoTests(t, cfg, db)
}
@ -62,16 +64,16 @@ func BaseTest(t *testing.T, cfg *sql.Cfg, db *sql.Storage) {
t.AssertEqual(data[1].label, "Good Afternoon")
}
func MessageTest(t *testing.T, cfg *sql.Cfg, db *sql.Storage) {
msg := message.SimpleMessage("data")
msgstore.StoreDB(db, msg)
}
func TrackingTest(t *testing.T, cfg *sql.Cfg, db *sql.Storage) {
cont := tracking.Container(db)
tracking.Create(cont)
}
func MessageTest(t *testing.T, cfg *sql.Cfg, db *sql.Storage) {
msg := message.SimpleMessage("data")
msgstore.StoreDB(db, msg)
}
func resetSqlite(db *sql.Storage) {
db.DropTable("test")
db.DropTable("tracks")