Merge pull request #392 from VolkerLieber/master

Include postgres comments in output
This commit is contained in:
go-jet 2024-09-26 19:24:09 +02:00 committed by GitHub
commit d17ab3d080
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
9 changed files with 168 additions and 19 deletions

View file

@ -1,9 +1,5 @@
package metadata
import (
"regexp"
)
// Column struct
type Column struct {
Name string `sql:"primary_key"`
@ -15,16 +11,6 @@ type Column struct {
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)
type DataTypeKind string

View file

@ -2,6 +2,7 @@ package metadata
// Enum metadata struct
type Enum struct {
Name string `sql:"primary_key"`
Values []string
Name string `sql:"primary_key"`
Comment string
Values []string
}

View file

@ -3,6 +3,7 @@ package metadata
// Table metadata struct
type Table struct {
Name string `sql:"primary_key"`
Comment string
Columns []Column
}

View file

@ -14,7 +14,7 @@ type postgresQuerySet struct{}
func (p postgresQuerySet) GetTablesMetaData(db *sql.DB, schemaName string, tableType metadata.TableType) ([]metadata.Table, error) {
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
WHERE table_schema = $1 and table_type = $2
ORDER BY table_name;
@ -57,6 +57,7 @@ func getColumnsMetaData(db *sql.DB, schemaName string, tableName string) ([]meta
query := `
select
attr.attname as "column.Name",
col_description(attr.attrelid, attr.attnum) as "column.Comment",
exists(
select 1
from pg_catalog.pg_index indx
@ -101,6 +102,7 @@ order by
func (p postgresQuerySet) GetEnumsMetaData(db *sql.DB, schemaName string) ([]metadata.Enum, error) {
query := `
SELECT t.typname as "enum.name",
obj_description(t.oid) as "enum.comment",
e.enumlabel as "values"
FROM pg_catalog.pg_type t
JOIN pg_catalog.pg_enum e on t.oid = e.enumtypid

View file

@ -26,13 +26,14 @@ import (
var {{tableTemplate.InstanceName}} = new{{tableTemplate.TypeName}}("{{schemaName}}", "{{.Name}}", "{{tableTemplate.DefaultAlias}}")
{{golangComment .Comment}}
type {{structImplName}} struct {
{{dialect.PackageName}}.Table
// Columns
{{- range $i, $c := .Columns}}
{{- $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}}
AllColumns {{dialect.PackageName}}.ColumnList
@ -119,10 +120,11 @@ import (
{{end}}
{{$modelTableTemplate := tableTemplate}}
{{golangComment .Comment}}
type {{$modelTableTemplate.TypeName}} struct {
{{- range .Columns}}
{{- $field := structField .}}
{{$field.Name}} {{$field.Type.Name}} ` + "{{$field.TagsString}}" + ` {{- if .Comment }} // {{.GoLangComment}} {{end}}
{{$field.Name}} {{$field.Type.Name}} ` + "{{$field.TagsString}}" + ` {{golangComment .Comment}}
{{- end}}
}
@ -132,6 +134,7 @@ var enumSQLBuilderTemplate = `package {{package}}
import "github.com/go-jet/jet/v2/{{dialect.PackageName}}"
{{golangComment .Comment}}
var {{enumTemplate.InstanceName}} = &struct {
{{- range $index, $value := .Values}}
{{enumValueName $value}} {{dialect.PackageName}}.StringExpression
@ -148,6 +151,7 @@ var enumModelTemplate = `package {{package}}
import "errors"
{{golangComment .Comment}}
type {{$enumTemplate.TypeName}} string
const (

View 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, "")
}

View 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)
}
})
}
}

View file

@ -140,6 +140,7 @@ func processEnumSQLBuilder(dirPath string, dialect jet.Dialect, enumsMetaData []
"enumValueName": func(enumValue string) string {
return enumTemplate.ValueName(enumValue)
},
"golangComment": formatGolangComment,
})
if err != nil {
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 {
return insertedRowAlias(dialect)
},
"golangComment": formatGolangComment,
})
if err != nil {
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 {
return tableTemplate.Field(columnMetaData)
},
"golangComment": formatGolangComment,
})
if err != nil {
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 {
return enumTemplate.ValueName(value)
},
"golangComment": formatGolangComment,
})
if err != nil {

View file

@ -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",
"components.go", "vulnerabilities.go", "all_types_materialized_view.go", "sample_ranges.go")
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",
"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+"/sample_ranges.go", sampleRangeTableContent)
testutils.AssertFileContent(t, tableDir+"/link.go", linkTableContent)
testutils.AssertFileNamesEqual(t, viewDir, "all_types_materialized_view.go", "all_types_view.go",
"view_use_schema.go")
}
@ -650,6 +653,7 @@ package enum
import "github.com/go-jet/jet/v2/postgres"
// Level enum
var Level = &struct {
Level1 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 = `
//
// 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,
}
}
`