Merge pull request #392 from VolkerLieber/master
Include postgres comments in output
This commit is contained in:
commit
d17ab3d080
9 changed files with 168 additions and 19 deletions
|
|
@ -1,9 +1,5 @@
|
||||||
package metadata
|
package metadata
|
||||||
|
|
||||||
import (
|
|
||||||
"regexp"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Column struct
|
// Column struct
|
||||||
type Column struct {
|
type Column struct {
|
||||||
Name string `sql:"primary_key"`
|
Name string `sql:"primary_key"`
|
||||||
|
|
@ -15,16 +11,6 @@ type Column struct {
|
||||||
Comment string
|
Comment string
|
||||||
}
|
}
|
||||||
|
|
||||||
// GoLangComment returns column comment without ascii control characters
|
|
||||||
func (c Column) GoLangComment() string {
|
|
||||||
if c.Comment == "" {
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
|
|
||||||
// remove ascii control characters from string
|
|
||||||
return regexp.MustCompile(`[[:cntrl:]]+`).ReplaceAllString(c.Comment, "")
|
|
||||||
}
|
|
||||||
|
|
||||||
// DataTypeKind is database type kind(base, enum, user-defined, array)
|
// DataTypeKind is database type kind(base, enum, user-defined, array)
|
||||||
type DataTypeKind string
|
type DataTypeKind string
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,5 +3,6 @@ package metadata
|
||||||
// Enum metadata struct
|
// Enum metadata struct
|
||||||
type Enum struct {
|
type Enum struct {
|
||||||
Name string `sql:"primary_key"`
|
Name string `sql:"primary_key"`
|
||||||
|
Comment string
|
||||||
Values []string
|
Values []string
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ package metadata
|
||||||
// Table metadata struct
|
// Table metadata struct
|
||||||
type Table struct {
|
type Table struct {
|
||||||
Name string `sql:"primary_key"`
|
Name string `sql:"primary_key"`
|
||||||
|
Comment string
|
||||||
Columns []Column
|
Columns []Column
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,7 @@ type postgresQuerySet struct{}
|
||||||
|
|
||||||
func (p postgresQuerySet) GetTablesMetaData(db *sql.DB, schemaName string, tableType metadata.TableType) ([]metadata.Table, error) {
|
func (p postgresQuerySet) GetTablesMetaData(db *sql.DB, schemaName string, tableType metadata.TableType) ([]metadata.Table, error) {
|
||||||
query := `
|
query := `
|
||||||
SELECT table_name as "table.name"
|
SELECT table_name as "table.name", obj_description((quote_ident(table_schema)||'.'||quote_ident(table_name))::regclass) as "table.comment"
|
||||||
FROM information_schema.tables
|
FROM information_schema.tables
|
||||||
WHERE table_schema = $1 and table_type = $2
|
WHERE table_schema = $1 and table_type = $2
|
||||||
ORDER BY table_name;
|
ORDER BY table_name;
|
||||||
|
|
@ -57,6 +57,7 @@ func getColumnsMetaData(db *sql.DB, schemaName string, tableName string) ([]meta
|
||||||
query := `
|
query := `
|
||||||
select
|
select
|
||||||
attr.attname as "column.Name",
|
attr.attname as "column.Name",
|
||||||
|
col_description(attr.attrelid, attr.attnum) as "column.Comment",
|
||||||
exists(
|
exists(
|
||||||
select 1
|
select 1
|
||||||
from pg_catalog.pg_index indx
|
from pg_catalog.pg_index indx
|
||||||
|
|
@ -101,6 +102,7 @@ order by
|
||||||
func (p postgresQuerySet) GetEnumsMetaData(db *sql.DB, schemaName string) ([]metadata.Enum, error) {
|
func (p postgresQuerySet) GetEnumsMetaData(db *sql.DB, schemaName string) ([]metadata.Enum, error) {
|
||||||
query := `
|
query := `
|
||||||
SELECT t.typname as "enum.name",
|
SELECT t.typname as "enum.name",
|
||||||
|
obj_description(t.oid) as "enum.comment",
|
||||||
e.enumlabel as "values"
|
e.enumlabel as "values"
|
||||||
FROM pg_catalog.pg_type t
|
FROM pg_catalog.pg_type t
|
||||||
JOIN pg_catalog.pg_enum e on t.oid = e.enumtypid
|
JOIN pg_catalog.pg_enum e on t.oid = e.enumtypid
|
||||||
|
|
|
||||||
|
|
@ -26,13 +26,14 @@ import (
|
||||||
|
|
||||||
var {{tableTemplate.InstanceName}} = new{{tableTemplate.TypeName}}("{{schemaName}}", "{{.Name}}", "{{tableTemplate.DefaultAlias}}")
|
var {{tableTemplate.InstanceName}} = new{{tableTemplate.TypeName}}("{{schemaName}}", "{{.Name}}", "{{tableTemplate.DefaultAlias}}")
|
||||||
|
|
||||||
|
{{golangComment .Comment}}
|
||||||
type {{structImplName}} struct {
|
type {{structImplName}} struct {
|
||||||
{{dialect.PackageName}}.Table
|
{{dialect.PackageName}}.Table
|
||||||
|
|
||||||
// Columns
|
// Columns
|
||||||
{{- range $i, $c := .Columns}}
|
{{- range $i, $c := .Columns}}
|
||||||
{{- $field := columnField $c}}
|
{{- $field := columnField $c}}
|
||||||
{{$field.Name}} {{dialect.PackageName}}.Column{{$field.Type}} {{- if $c.Comment }} // {{$c.GoLangComment}} {{end}}
|
{{$field.Name}} {{dialect.PackageName}}.Column{{$field.Type}} {{golangComment .Comment}}
|
||||||
{{- end}}
|
{{- end}}
|
||||||
|
|
||||||
AllColumns {{dialect.PackageName}}.ColumnList
|
AllColumns {{dialect.PackageName}}.ColumnList
|
||||||
|
|
@ -119,10 +120,11 @@ import (
|
||||||
{{end}}
|
{{end}}
|
||||||
|
|
||||||
{{$modelTableTemplate := tableTemplate}}
|
{{$modelTableTemplate := tableTemplate}}
|
||||||
|
{{golangComment .Comment}}
|
||||||
type {{$modelTableTemplate.TypeName}} struct {
|
type {{$modelTableTemplate.TypeName}} struct {
|
||||||
{{- range .Columns}}
|
{{- range .Columns}}
|
||||||
{{- $field := structField .}}
|
{{- $field := structField .}}
|
||||||
{{$field.Name}} {{$field.Type.Name}} ` + "{{$field.TagsString}}" + ` {{- if .Comment }} // {{.GoLangComment}} {{end}}
|
{{$field.Name}} {{$field.Type.Name}} ` + "{{$field.TagsString}}" + ` {{golangComment .Comment}}
|
||||||
{{- end}}
|
{{- end}}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -132,6 +134,7 @@ var enumSQLBuilderTemplate = `package {{package}}
|
||||||
|
|
||||||
import "github.com/go-jet/jet/v2/{{dialect.PackageName}}"
|
import "github.com/go-jet/jet/v2/{{dialect.PackageName}}"
|
||||||
|
|
||||||
|
{{golangComment .Comment}}
|
||||||
var {{enumTemplate.InstanceName}} = &struct {
|
var {{enumTemplate.InstanceName}} = &struct {
|
||||||
{{- range $index, $value := .Values}}
|
{{- range $index, $value := .Values}}
|
||||||
{{enumValueName $value}} {{dialect.PackageName}}.StringExpression
|
{{enumValueName $value}} {{dialect.PackageName}}.StringExpression
|
||||||
|
|
@ -148,6 +151,7 @@ var enumModelTemplate = `package {{package}}
|
||||||
|
|
||||||
import "errors"
|
import "errors"
|
||||||
|
|
||||||
|
{{golangComment .Comment}}
|
||||||
type {{$enumTemplate.TypeName}} string
|
type {{$enumTemplate.TypeName}} string
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
|
|
||||||
13
generator/template/format.go
Normal file
13
generator/template/format.go
Normal file
|
|
@ -0,0 +1,13 @@
|
||||||
|
package template
|
||||||
|
|
||||||
|
import "regexp"
|
||||||
|
|
||||||
|
// Returns the provided string as golang comment without ascii control characters
|
||||||
|
func formatGolangComment(comment string) string {
|
||||||
|
if len(comment) == 0 {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
// Format as colang comment and remove ascii control characters from string
|
||||||
|
return "// " + regexp.MustCompile(`[[:cntrl:]]+`).ReplaceAllString(comment, "")
|
||||||
|
}
|
||||||
27
generator/template/format_test.go
Normal file
27
generator/template/format_test.go
Normal file
|
|
@ -0,0 +1,27 @@
|
||||||
|
package template
|
||||||
|
|
||||||
|
import "testing"
|
||||||
|
|
||||||
|
func Test_formatGolangComment(t *testing.T) {
|
||||||
|
type args struct {
|
||||||
|
comment string
|
||||||
|
}
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
args args
|
||||||
|
want string
|
||||||
|
}{
|
||||||
|
{name: "Empty string", args: args{comment: ""}, want: ""},
|
||||||
|
{name: "Non-empty string", args: args{comment: "This is a comment"}, want: "// This is a comment"},
|
||||||
|
{name: "String with control characters", args: args{comment: "This is a comment with control characters \x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f and text after"}, want: "// This is a comment with control characters and text after"},
|
||||||
|
{name: "String with escape characters", args: args{comment: "This is a comment with escape characters \n\r\t and text after"}, want: "// This is a comment with escape characters and text after"},
|
||||||
|
{name: "String with unicode characters", args: args{comment: "This is a comment with unicode characters ₲鬼佬℧⇄↻ and text after"}, want: "// This is a comment with unicode characters ₲鬼佬℧⇄↻ and text after"},
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
if got := formatGolangComment(tt.args.comment); got != tt.want {
|
||||||
|
t.Errorf("formatGoLangComment() = %v, want %v", got, tt.want)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -140,6 +140,7 @@ func processEnumSQLBuilder(dirPath string, dialect jet.Dialect, enumsMetaData []
|
||||||
"enumValueName": func(enumValue string) string {
|
"enumValueName": func(enumValue string) string {
|
||||||
return enumTemplate.ValueName(enumValue)
|
return enumTemplate.ValueName(enumValue)
|
||||||
},
|
},
|
||||||
|
"golangComment": formatGolangComment,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to generete enum type %s: %w", enumTemplate.FileName, err)
|
return fmt.Errorf("failed to generete enum type %s: %w", enumTemplate.FileName, err)
|
||||||
|
|
@ -215,6 +216,7 @@ func processTableSQLBuilder(fileTypes, dirPath string,
|
||||||
"insertedRowAlias": func() string {
|
"insertedRowAlias": func() string {
|
||||||
return insertedRowAlias(dialect)
|
return insertedRowAlias(dialect)
|
||||||
},
|
},
|
||||||
|
"golangComment": formatGolangComment,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to generate table sql builder type %s: %w", tableSQLBuilder.TypeName, err)
|
return fmt.Errorf("failed to generate table sql builder type %s: %w", tableSQLBuilder.TypeName, err)
|
||||||
|
|
@ -307,6 +309,7 @@ func processTableModels(fileTypes, modelDirPath string, tablesMetaData []metadat
|
||||||
"structField": func(columnMetaData metadata.Column) TableModelField {
|
"structField": func(columnMetaData metadata.Column) TableModelField {
|
||||||
return tableTemplate.Field(columnMetaData)
|
return tableTemplate.Field(columnMetaData)
|
||||||
},
|
},
|
||||||
|
"golangComment": formatGolangComment,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to generate model type '%s': %w", tableMetaData.Name, err)
|
return fmt.Errorf("failed to generate model type '%s': %w", tableMetaData.Name, err)
|
||||||
|
|
@ -347,6 +350,7 @@ func processEnumModels(modelDir string, enumsMetaData []metadata.Enum, modelTemp
|
||||||
"valueName": func(value string) string {
|
"valueName": func(value string) string {
|
||||||
return enumTemplate.ValueName(value)
|
return enumTemplate.ValueName(value)
|
||||||
},
|
},
|
||||||
|
"golangComment": formatGolangComment,
|
||||||
})
|
})
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
||||||
|
|
@ -604,6 +604,7 @@ func TestGeneratedAllTypesSQLBuilderFiles(t *testing.T) {
|
||||||
"mood.go", "person.go", "person_phone.go", "weird_names_table.go", "level.go", "user.go", "floats.go", "people.go",
|
"mood.go", "person.go", "person_phone.go", "weird_names_table.go", "level.go", "user.go", "floats.go", "people.go",
|
||||||
"components.go", "vulnerabilities.go", "all_types_materialized_view.go", "sample_ranges.go")
|
"components.go", "vulnerabilities.go", "all_types_materialized_view.go", "sample_ranges.go")
|
||||||
testutils.AssertFileContent(t, modelDir+"/all_types.go", allTypesModelContent)
|
testutils.AssertFileContent(t, modelDir+"/all_types.go", allTypesModelContent)
|
||||||
|
testutils.AssertFileContent(t, modelDir+"/link.go", linkModelContent)
|
||||||
|
|
||||||
testutils.AssertFileNamesEqual(t, tableDir, "all_types.go", "employee.go", "link.go",
|
testutils.AssertFileNamesEqual(t, tableDir, "all_types.go", "employee.go", "link.go",
|
||||||
"person.go", "person_phone.go", "weird_names_table.go", "user.go", "floats.go", "people.go", "table_use_schema.go",
|
"person.go", "person_phone.go", "weird_names_table.go", "user.go", "floats.go", "people.go", "table_use_schema.go",
|
||||||
|
|
@ -611,6 +612,8 @@ func TestGeneratedAllTypesSQLBuilderFiles(t *testing.T) {
|
||||||
testutils.AssertFileContent(t, tableDir+"/all_types.go", allTypesTableContent)
|
testutils.AssertFileContent(t, tableDir+"/all_types.go", allTypesTableContent)
|
||||||
testutils.AssertFileContent(t, tableDir+"/sample_ranges.go", sampleRangeTableContent)
|
testutils.AssertFileContent(t, tableDir+"/sample_ranges.go", sampleRangeTableContent)
|
||||||
|
|
||||||
|
testutils.AssertFileContent(t, tableDir+"/link.go", linkTableContent)
|
||||||
|
|
||||||
testutils.AssertFileNamesEqual(t, viewDir, "all_types_materialized_view.go", "all_types_view.go",
|
testutils.AssertFileNamesEqual(t, viewDir, "all_types_materialized_view.go", "all_types_view.go",
|
||||||
"view_use_schema.go")
|
"view_use_schema.go")
|
||||||
}
|
}
|
||||||
|
|
@ -650,6 +653,7 @@ package enum
|
||||||
|
|
||||||
import "github.com/go-jet/jet/v2/postgres"
|
import "github.com/go-jet/jet/v2/postgres"
|
||||||
|
|
||||||
|
// Level enum
|
||||||
var Level = &struct {
|
var Level = &struct {
|
||||||
Level1 postgres.StringExpression
|
Level1 postgres.StringExpression
|
||||||
Level2 postgres.StringExpression
|
Level2 postgres.StringExpression
|
||||||
|
|
@ -747,6 +751,25 @@ type AllTypes struct {
|
||||||
}
|
}
|
||||||
`
|
`
|
||||||
|
|
||||||
|
var linkModelContent = `
|
||||||
|
//
|
||||||
|
// Code generated by go-jet DO NOT EDIT.
|
||||||
|
//
|
||||||
|
// WARNING: Changes to this file may cause incorrect behavior
|
||||||
|
// and will be lost if the code is regenerated
|
||||||
|
//
|
||||||
|
|
||||||
|
package model
|
||||||
|
|
||||||
|
// Link table
|
||||||
|
type Link struct {
|
||||||
|
ID int64 ` + "`sql:\"primary_key\"`" + ` // this is link id
|
||||||
|
URL string // link url
|
||||||
|
Name string // Unicode characters comment ₲鬼佬℧⇄↻
|
||||||
|
Description *string // '"Z\%_
|
||||||
|
}
|
||||||
|
`
|
||||||
|
|
||||||
var allTypesTableContent = `
|
var allTypesTableContent = `
|
||||||
//
|
//
|
||||||
// Code generated by go-jet DO NOT EDIT.
|
// Code generated by go-jet DO NOT EDIT.
|
||||||
|
|
@ -1103,3 +1126,91 @@ func newSampleRangesTableImpl(schemaName, tableName, alias string) sampleRangesT
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
`
|
`
|
||||||
|
|
||||||
|
var linkTableContent = `
|
||||||
|
//
|
||||||
|
// Code generated by go-jet DO NOT EDIT.
|
||||||
|
//
|
||||||
|
// WARNING: Changes to this file may cause incorrect behavior
|
||||||
|
// and will be lost if the code is regenerated
|
||||||
|
//
|
||||||
|
|
||||||
|
package table
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/go-jet/jet/v2/postgres"
|
||||||
|
)
|
||||||
|
|
||||||
|
var Link = newLinkTable("test_sample", "link", "")
|
||||||
|
|
||||||
|
// Link table
|
||||||
|
type linkTable struct {
|
||||||
|
postgres.Table
|
||||||
|
|
||||||
|
// Columns
|
||||||
|
ID postgres.ColumnInteger // this is link id
|
||||||
|
URL postgres.ColumnString // link url
|
||||||
|
Name postgres.ColumnString // Unicode characters comment ₲鬼佬℧⇄↻
|
||||||
|
Description postgres.ColumnString // '"Z\%_
|
||||||
|
|
||||||
|
AllColumns postgres.ColumnList
|
||||||
|
MutableColumns postgres.ColumnList
|
||||||
|
}
|
||||||
|
|
||||||
|
type LinkTable struct {
|
||||||
|
linkTable
|
||||||
|
|
||||||
|
EXCLUDED linkTable
|
||||||
|
}
|
||||||
|
|
||||||
|
// AS creates new LinkTable with assigned alias
|
||||||
|
func (a LinkTable) AS(alias string) *LinkTable {
|
||||||
|
return newLinkTable(a.SchemaName(), a.TableName(), alias)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Schema creates new LinkTable with assigned schema name
|
||||||
|
func (a LinkTable) FromSchema(schemaName string) *LinkTable {
|
||||||
|
return newLinkTable(schemaName, a.TableName(), a.Alias())
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithPrefix creates new LinkTable with assigned table prefix
|
||||||
|
func (a LinkTable) WithPrefix(prefix string) *LinkTable {
|
||||||
|
return newLinkTable(a.SchemaName(), prefix+a.TableName(), a.TableName())
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithSuffix creates new LinkTable with assigned table suffix
|
||||||
|
func (a LinkTable) WithSuffix(suffix string) *LinkTable {
|
||||||
|
return newLinkTable(a.SchemaName(), a.TableName()+suffix, a.TableName())
|
||||||
|
}
|
||||||
|
|
||||||
|
func newLinkTable(schemaName, tableName, alias string) *LinkTable {
|
||||||
|
return &LinkTable{
|
||||||
|
linkTable: newLinkTableImpl(schemaName, tableName, alias),
|
||||||
|
EXCLUDED: newLinkTableImpl("", "excluded", ""),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func newLinkTableImpl(schemaName, tableName, alias string) linkTable {
|
||||||
|
var (
|
||||||
|
IDColumn = postgres.IntegerColumn("id")
|
||||||
|
URLColumn = postgres.StringColumn("url")
|
||||||
|
NameColumn = postgres.StringColumn("name")
|
||||||
|
DescriptionColumn = postgres.StringColumn("description")
|
||||||
|
allColumns = postgres.ColumnList{IDColumn, URLColumn, NameColumn, DescriptionColumn}
|
||||||
|
mutableColumns = postgres.ColumnList{URLColumn, NameColumn, DescriptionColumn}
|
||||||
|
)
|
||||||
|
|
||||||
|
return linkTable{
|
||||||
|
Table: postgres.NewTable(schemaName, tableName, alias, allColumns...),
|
||||||
|
|
||||||
|
//Columns
|
||||||
|
ID: IDColumn,
|
||||||
|
URL: URLColumn,
|
||||||
|
Name: NameColumn,
|
||||||
|
Description: DescriptionColumn,
|
||||||
|
|
||||||
|
AllColumns: allColumns,
|
||||||
|
MutableColumns: mutableColumns,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue