Add json tags and fix smaller issues
parent
9eea116536
commit
07465cfafe
11
go.mod
11
go.mod
|
@ -2,11 +2,14 @@ module git.rpjosh.de/RPJosh/go-ddl-parser
|
||||||
|
|
||||||
go 1.22.1
|
go 1.22.1
|
||||||
|
|
||||||
|
require (
|
||||||
|
git.rpjosh.de/RPJosh/go-logger v1.3.2
|
||||||
|
github.com/davecgh/go-spew v1.1.1
|
||||||
|
github.com/go-sql-driver/mysql v1.8.1
|
||||||
|
github.com/google/go-cmp v0.6.0
|
||||||
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
filippo.io/edwards25519 v1.1.0 // indirect
|
filippo.io/edwards25519 v1.1.0 // indirect
|
||||||
git.rpjosh.de/RPJosh/go-logger v1.3.2 // indirect
|
|
||||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
|
||||||
github.com/go-sql-driver/mysql v1.8.1 // indirect
|
|
||||||
github.com/google/go-cmp v0.6.0 // indirect
|
|
||||||
golang.org/x/sys v0.19.0 // indirect
|
golang.org/x/sys v0.19.0 // indirect
|
||||||
)
|
)
|
||||||
|
|
|
@ -70,7 +70,7 @@ func (s *Mariadb) GetTable(schema, name string) (*Table, error) {
|
||||||
c.IS_NULLABLE,
|
c.IS_NULLABLE,
|
||||||
c.DATA_TYPE,
|
c.DATA_TYPE,
|
||||||
c.COLUMN_TYPE,
|
c.COLUMN_TYPE,
|
||||||
COALESCE(c.CHARACTER_MAXIMUM_LENGTH, c.NUMERIC_PRECISION, c.DATETIME_PRECISION),
|
COALESCE(c.CHARACTER_MAXIMUM_LENGTH, c.NUMERIC_PRECISION, c.DATETIME_PRECISION, 0),
|
||||||
c.COLUMN_KEY,
|
c.COLUMN_KEY,
|
||||||
c.COLUMN_COMMENT,
|
c.COLUMN_COMMENT,
|
||||||
c.extra,
|
c.extra,
|
||||||
|
@ -142,6 +142,7 @@ func (s *Mariadb) GetTables(schema string) ([]*Table, error) {
|
||||||
t.TABLE_NAME
|
t.TABLE_NAME
|
||||||
FROM information_schema.tables t
|
FROM information_schema.tables t
|
||||||
WHERE t.table_schema = ?
|
WHERE t.table_schema = ?
|
||||||
|
ORDER BY t.TABLE_NAME ASC
|
||||||
`
|
`
|
||||||
rows, err := s.db.Query(sql, schema)
|
rows, err := s.db.Query(sql, schema)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -280,7 +280,7 @@ func ConnectToMariadb(t *testing.T) *sql.DB {
|
||||||
}
|
}
|
||||||
|
|
||||||
// createMariadbTable creates a table with the provided column configuration
|
// createMariadbTable creates a table with the provided column configuration
|
||||||
// in statementand returns the created table name
|
// in statement and returns the created table name
|
||||||
func createMariadbTable(db *sql.DB, statement string) (string, error) {
|
func createMariadbTable(db *sql.DB, statement string) (string, error) {
|
||||||
name, _ := GenerateRandomString(8)
|
name, _ := GenerateRandomString(8)
|
||||||
name = "ddl_test_" + name
|
name = "ddl_test_" + name
|
||||||
|
|
|
@ -4,9 +4,12 @@ import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
|
"os/exec"
|
||||||
"regexp"
|
"regexp"
|
||||||
"sort"
|
"sort"
|
||||||
"strings"
|
"strings"
|
||||||
|
"unicode"
|
||||||
|
"unicode/utf8"
|
||||||
|
|
||||||
"git.rpjosh.de/RPJosh/go-ddl-parser"
|
"git.rpjosh.de/RPJosh/go-ddl-parser"
|
||||||
|
|
||||||
|
@ -114,6 +117,13 @@ func CreateStructs(conf *StructConfig, tables []*ddl.Table) error {
|
||||||
return fmt.Errorf("failed to write file %q: %s", tblConfig.Path, err)
|
return fmt.Errorf("failed to write file %q: %s", tblConfig.Path, err)
|
||||||
}
|
}
|
||||||
f.Close()
|
f.Close()
|
||||||
|
|
||||||
|
// Lint go file
|
||||||
|
cmd := exec.Command("go", "fmt", tblConfig.Path)
|
||||||
|
if err := cmd.Run(); err != nil {
|
||||||
|
logger.Warning("Failed to run go fmt: %s", err)
|
||||||
|
}
|
||||||
|
cmd.Wait()
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
@ -144,6 +154,24 @@ func GetFieldName(fieldName string) string {
|
||||||
return rtc
|
return rtc
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetJsonName returns the json key value for the provided fildName of
|
||||||
|
// the database.
|
||||||
|
// The json keys are CamelCased
|
||||||
|
func GetJsonName(fieldName string) string {
|
||||||
|
structField := GetFieldName(fieldName)
|
||||||
|
|
||||||
|
// Lowercase the first character for json
|
||||||
|
r, size := utf8.DecodeRuneInString(structField)
|
||||||
|
if r == utf8.RuneError && size <= 1 {
|
||||||
|
return structField
|
||||||
|
}
|
||||||
|
lc := unicode.ToLower(r)
|
||||||
|
if r == lc {
|
||||||
|
return structField
|
||||||
|
}
|
||||||
|
return string(lc) + structField[size:]
|
||||||
|
}
|
||||||
|
|
||||||
// findTableConfig returns a specific table configuration for the table
|
// findTableConfig returns a specific table configuration for the table
|
||||||
// or an empty configuration struct if no one was provided
|
// or an empty configuration struct if no one was provided
|
||||||
func (c *constructor) findTableConfig(tbl *ddl.Table) *TableConfig {
|
func (c *constructor) findTableConfig(tbl *ddl.Table) *TableConfig {
|
||||||
|
@ -215,7 +243,8 @@ func (c *constructor) getGoFile(existingContent string, tbl *ddl.Table, tblConfi
|
||||||
}
|
}
|
||||||
|
|
||||||
fieldName := GetFieldName(col.Name)
|
fieldName := GetFieldName(col.Name)
|
||||||
rtc += fmt.Sprintf("\t%s %s `%s:\"%s\"`\n", fieldName, dataType, ColumnTagId, tags.ToTag())
|
jsonName := GetJsonName(col.Name)
|
||||||
|
rtc += fmt.Sprintf("\t%s %s `json:\"%s\" %s:\"%s\"`\n", fieldName, dataType, jsonName, ColumnTagId, tags.ToTag())
|
||||||
columns += fmt.Sprintf("\t %s_%s string = \"%s\"\n", tableName, fieldName, fieldName)
|
columns += fmt.Sprintf("\t %s_%s string = \"%s\"\n", tableName, fieldName, fieldName)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -235,7 +264,7 @@ func (c *constructor) getGoFile(existingContent string, tbl *ddl.Table, tblConfi
|
||||||
Schema: tbl.Schema,
|
Schema: tbl.Schema,
|
||||||
Table: tbl.Name,
|
Table: tbl.Name,
|
||||||
}
|
}
|
||||||
rtc += fmt.Sprintf("\t%s any `%s:\"%s\"`\n", MetadataFieldName, MetadataTagId, metaData.ToTag())
|
rtc += fmt.Sprintf("\t%s any `json:\"-\" %s:\"%s\"`\n", MetadataFieldName, MetadataTagId, metaData.ToTag())
|
||||||
|
|
||||||
// Add closing line
|
// Add closing line
|
||||||
rtc += "}\n"
|
rtc += "}\n"
|
||||||
|
@ -243,7 +272,7 @@ func (c *constructor) getGoFile(existingContent string, tbl *ddl.Table, tblConfi
|
||||||
|
|
||||||
// Add package header if no file exists already
|
// Add package header if no file exists already
|
||||||
if existingContent == "" {
|
if existingContent == "" {
|
||||||
header := fmt.Sprintf("package %s\n", tblConfig.PackageName)
|
header := fmt.Sprintf("package %s\n\n", tblConfig.PackageName)
|
||||||
importStr := ""
|
importStr := ""
|
||||||
if len(imports) != 0 {
|
if len(imports) != 0 {
|
||||||
importStr = "import (\n"
|
importStr = "import (\n"
|
||||||
|
@ -253,9 +282,9 @@ func (c *constructor) getGoFile(existingContent string, tbl *ddl.Table, tblConfi
|
||||||
importStr += ")\n"
|
importStr += ")\n"
|
||||||
}
|
}
|
||||||
|
|
||||||
rtc = header + importStr + rtc + columns
|
rtc = header + importStr + "\n" + rtc + columns
|
||||||
} else {
|
} else {
|
||||||
// @TODO merge file...
|
rtc = c.patchFile(existingContent, rtc+columns, tbl, tblConfig, imports)
|
||||||
}
|
}
|
||||||
|
|
||||||
return rtc
|
return rtc
|
||||||
|
@ -277,9 +306,9 @@ func (c *constructor) getDataType(column *ddl.Column, tblConfig *TableConfig, ta
|
||||||
case ddl.StringType:
|
case ddl.StringType:
|
||||||
return "sql.NullString", "database/sql"
|
return "sql.NullString", "database/sql"
|
||||||
case ddl.IntType:
|
case ddl.IntType:
|
||||||
return "sql.NullInt", "database/sql"
|
return "sql.NullInt64", "database/sql"
|
||||||
case ddl.DoubleType:
|
case ddl.DoubleType:
|
||||||
return "sql.NullFloat", "database/sql"
|
return "sql.NullFloat64", "database/sql"
|
||||||
case ddl.DateType:
|
case ddl.DateType:
|
||||||
return "sql.NullTime", "database/sql"
|
return "sql.NullTime", "database/sql"
|
||||||
}
|
}
|
||||||
|
@ -291,7 +320,7 @@ func (c *constructor) getDataType(column *ddl.Column, tblConfig *TableConfig, ta
|
||||||
case ddl.IntType:
|
case ddl.IntType:
|
||||||
return "int", ""
|
return "int", ""
|
||||||
case ddl.DoubleType:
|
case ddl.DoubleType:
|
||||||
return "float", ""
|
return "float64", ""
|
||||||
case ddl.DateType:
|
case ddl.DateType:
|
||||||
return "time.Time", "time"
|
return "time.Time", "time"
|
||||||
}
|
}
|
||||||
|
@ -397,7 +426,7 @@ func (c *constructor) patchFile(existingContent string, newStruct string, tbl *d
|
||||||
|
|
||||||
if reg.MatchString(existingContent) {
|
if reg.MatchString(existingContent) {
|
||||||
// Replace content
|
// Replace content
|
||||||
return reg.ReplaceAllString(existingContent, newStruct+"\n")
|
return reg.ReplaceAllString(existingContent, newStruct)
|
||||||
} else {
|
} else {
|
||||||
// Append content
|
// Append content
|
||||||
return existingContent + "\n" + newStruct
|
return existingContent + "\n" + newStruct
|
||||||
|
@ -413,11 +442,12 @@ func (c *constructor) patchImports(existingContent string, imports map[string]bo
|
||||||
reg := regexp.MustCompile(`"([^"]+)"`)
|
reg := regexp.MustCompile(`"([^"]+)"`)
|
||||||
|
|
||||||
var importStart, importEnd int
|
var importStart, importEnd int
|
||||||
|
importFound := true
|
||||||
// Find any existing import clause within the first 5 lines
|
// Find any existing import clause within the first 5 lines
|
||||||
for i, line := range strings.Split(existingContent, "\n") {
|
for i, line := range strings.Split(existingContent, "\n") {
|
||||||
// No import found
|
// No import found
|
||||||
if i > 5 && importStart == 0 {
|
if i > 5 && importStart == 0 {
|
||||||
return existingContent, nil
|
importFound = false
|
||||||
}
|
}
|
||||||
|
|
||||||
// Trim any whitespace for import
|
// Trim any whitespace for import
|
||||||
|
@ -480,6 +510,22 @@ func (c *constructor) patchImports(existingContent string, imports map[string]bo
|
||||||
}
|
}
|
||||||
newImport += ")"
|
newImport += ")"
|
||||||
|
|
||||||
|
// We didn't found an existing import statment yet that we could replace
|
||||||
|
if !importFound {
|
||||||
|
lines := strings.Split(existingContent, "\n")
|
||||||
|
|
||||||
|
// Only a single line -> add it directly below
|
||||||
|
if len(lines) <= 1 {
|
||||||
|
lines = append(lines, "")
|
||||||
|
lines = append(lines, strings.Split(newImport, "\n")...)
|
||||||
|
} else {
|
||||||
|
// Insert it into existing, empty line
|
||||||
|
return replaceLines(existingContent, 1, 1, strings.Split("\n"+newImport, "\n")), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return strings.Join(lines, "\n"), nil
|
||||||
|
}
|
||||||
|
|
||||||
// Replace import string
|
// Replace import string
|
||||||
return replaceLines(existingContent, importStart, importEnd, strings.Split(newImport, "\n")), nil
|
return replaceLines(existingContent, importStart, importEnd, strings.Split(newImport, "\n")), nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -393,6 +393,7 @@ func TestPatchFilePatchSelf(t *testing.T) {
|
||||||
// Replace a single column ID to test some change.
|
// Replace a single column ID to test some change.
|
||||||
// WithUnder -> ReplacedColumn
|
// WithUnder -> ReplacedColumn
|
||||||
expected = strings.ReplaceAll(expected, "WithUnder", "ReplacedColumn")
|
expected = strings.ReplaceAll(expected, "WithUnder", "ReplacedColumn")
|
||||||
|
expected = strings.ReplaceAll(expected, "withUnder", "replacedColumn")
|
||||||
expected = strings.ReplaceAll(expected, "with_under", "replaced_column")
|
expected = strings.ReplaceAll(expected, "with_under", "replaced_column")
|
||||||
tbl.Columns[1].Name = "replaced_column"
|
tbl.Columns[1].Name = "replaced_column"
|
||||||
|
|
||||||
|
@ -429,13 +430,13 @@ func replaceWhitespaces(val string) string {
|
||||||
// getStructTag returns the tag for a struct to append to.
|
// getStructTag returns the tag for a struct to append to.
|
||||||
// We already tested the struct tags in another test!
|
// We already tested the struct tags in another test!
|
||||||
func getStructTag(col *ddl.Column) string {
|
func getStructTag(col *ddl.Column) string {
|
||||||
tagStart := "`" + ColumnTagId + ":\""
|
tagStart := "`json:\"" + GetJsonName(col.Name) + "\" " + ColumnTagId + ":\""
|
||||||
tagEnd := "\"`"
|
tagEnd := "\"`"
|
||||||
|
|
||||||
return tagStart + GetColumnTag(col).ToTag() + tagEnd
|
return tagStart + GetColumnTag(col).ToTag() + tagEnd
|
||||||
}
|
}
|
||||||
func getMetadataTag(tbl *ddl.Table) string {
|
func getMetadataTag(tbl *ddl.Table) string {
|
||||||
tagStart := "`" + MetadataTagId + ":\""
|
tagStart := "`json:\"-\" " + MetadataTagId + ":\""
|
||||||
tagEnd := "\"`"
|
tagEnd := "\"`"
|
||||||
|
|
||||||
m := &MetadataTag{
|
m := &MetadataTag{
|
||||||
|
|
Loading…
Reference in New Issue