108 lines
3.7 KiB
Go
108 lines
3.7 KiB
Go
package pgsql
|
|
|
|
import (
|
|
"bytes"
|
|
"strings"
|
|
"testing"
|
|
|
|
"git.warky.dev/wdevs/relspecgo/pkg/models"
|
|
"git.warky.dev/wdevs/relspecgo/pkg/writers"
|
|
)
|
|
|
|
func directiveTestDB(t *testing.T) *models.Database {
|
|
t.Helper()
|
|
db := models.InitDatabase("testdb")
|
|
schema := models.InitSchema("public")
|
|
table := models.InitTable("events", "public")
|
|
|
|
id := models.InitColumn("id", "events", "public")
|
|
id.Type = "bigint"
|
|
id.IsPrimaryKey = true
|
|
id.NotNull = true
|
|
models.AddDirective(id.Metadata, models.Directive{Namespace: "postgres", Args: "identity always"})
|
|
models.AddDirective(id.Metadata, models.Directive{Namespace: "sqlite", Args: "collate NOCASE"})
|
|
table.Columns["id"] = id
|
|
|
|
created := models.InitColumn("created_at", "events", "public")
|
|
created.Type = "timestamp"
|
|
created.NotNull = true
|
|
table.Columns["created_at"] = created
|
|
|
|
models.AddDirective(table.Metadata, models.Directive{Namespace: "postgres", Args: "partition by RANGE (created_at)"})
|
|
models.AddDirective(table.Metadata, models.Directive{Namespace: "postgres", Args: "tablespace fast_data"})
|
|
models.AddDirective(table.Metadata, models.Directive{Namespace: "sqlite", Args: "without rowid"})
|
|
|
|
idx := models.InitIndex("idx_events_created", "events", "public")
|
|
idx.Columns = []string{"created_at"}
|
|
models.AddDirective(idx.Metadata, models.Directive{Namespace: "postgres", Args: "with (fillfactor=90)"})
|
|
models.AddDirective(idx.Metadata, models.Directive{Namespace: "postgres", Args: "tablespace idx_space"})
|
|
table.Indexes["idx_events_created"] = idx
|
|
|
|
schema.Tables = append(schema.Tables, table)
|
|
db.Schemas = append(db.Schemas, schema)
|
|
return db
|
|
}
|
|
|
|
func TestPgDirectives_WriteDatabasePath(t *testing.T) {
|
|
var buf bytes.Buffer
|
|
w := NewWriter(&writers.WriterOptions{})
|
|
w.writer = &buf
|
|
if err := w.WriteDatabase(directiveTestDB(t)); err != nil {
|
|
t.Fatalf("WriteDatabase: %v", err)
|
|
}
|
|
out := buf.String()
|
|
|
|
for _, want := range []string{
|
|
") PARTITION BY RANGE (created_at) TABLESPACE fast_data",
|
|
"GENERATED ALWAYS AS IDENTITY",
|
|
"WITH (fillfactor=90) TABLESPACE \"idx_space\"",
|
|
} {
|
|
if !strings.Contains(out, want) {
|
|
t.Errorf("missing %q in:\n%s", want, out)
|
|
}
|
|
}
|
|
// sqlite directives must never reach PG output.
|
|
if strings.Contains(out, "WITHOUT ROWID") || strings.Contains(strings.ToUpper(out), "COLLATE NOCASE") {
|
|
t.Errorf("sqlite directive leaked into PG output:\n%s", out)
|
|
}
|
|
}
|
|
|
|
func TestPgDirectives_WriteSchemaPath(t *testing.T) {
|
|
var buf bytes.Buffer
|
|
w := NewWriter(&writers.WriterOptions{})
|
|
w.writer = &buf
|
|
if err := w.WriteSchema(directiveTestDB(t).Schemas[0]); err != nil {
|
|
t.Fatalf("WriteSchema: %v", err)
|
|
}
|
|
out := buf.String()
|
|
if !strings.Contains(out, ") PARTITION BY RANGE (created_at) TABLESPACE fast_data;") {
|
|
t.Errorf("table suffix missing from WriteSchema path:\n%s", out)
|
|
}
|
|
if !strings.Contains(out, "WITH (fillfactor=90) TABLESPACE \"idx_space\"") {
|
|
t.Errorf("index clauses missing from WriteSchema path:\n%s", out)
|
|
}
|
|
}
|
|
|
|
func TestPgDirectives_StrictUnknownKeyErrors(t *testing.T) {
|
|
db := directiveTestDB(t)
|
|
models.AddDirective(db.Schemas[0].Tables[0].Metadata, models.Directive{Namespace: "postgres", Args: "frobnicate x"})
|
|
|
|
var buf bytes.Buffer
|
|
w := NewWriter(&writers.WriterOptions{StrictDirectives: true})
|
|
w.writer = &buf
|
|
err := w.WriteSchema(db.Schemas[0])
|
|
if err == nil || !strings.Contains(err.Error(), "frobnicate") {
|
|
t.Fatalf("want strict error for unknown postgres key, got %v", err)
|
|
}
|
|
}
|
|
|
|
func TestPgDirectives_StrictIgnoresOtherNamespaces(t *testing.T) {
|
|
// sqlite directives are present but must not trip PG strict mode.
|
|
var buf bytes.Buffer
|
|
w := NewWriter(&writers.WriterOptions{StrictDirectives: true})
|
|
w.writer = &buf
|
|
if err := w.WriteSchema(directiveTestDB(t).Schemas[0]); err != nil {
|
|
t.Fatalf("strict mode should ignore non-postgres directives, got %v", err)
|
|
}
|
|
}
|