Add option to specify custom null types

main v0.2.1
Jonas Letzbor 2024-05-16 20:10:16 +02:00
parent f1141f9607
commit ee36d8d116
Signed by: RPJosh
GPG Key ID: 43ACB900522EA740
2 changed files with 104 additions and 5 deletions

View File

@ -1,6 +1,7 @@
package structt package structt
import ( import (
"database/sql"
"errors" "errors"
"fmt" "fmt"
"os" "os"
@ -37,6 +38,9 @@ type StructConfig struct {
// The key of this map is either the table name (for any schema) // The key of this map is either the table name (for any schema)
// or a combination of "schema.tableName" // or a combination of "schema.tableName"
Tableconfig map[string]*TableConfig `yaml:"tableConfig"` Tableconfig map[string]*TableConfig `yaml:"tableConfig"`
// Configuration of how to handle nullable columns
NullConfig NullConfig
} }
// TableConfig contains options for a specific table // TableConfig contains options for a specific table
@ -66,6 +70,21 @@ type TableConfig struct {
Suffix string `yaml:"suffix"` Suffix string `yaml:"suffix"`
} }
// NullConfig configures how to transform nullable columns into a go struct
type NullConfig struct {
// Disable the use of nullable datatypes
Disable bool
// Name of the package to import the types from.
// Defaulting to [database/sql]
Package string
// Prefix to use in front of name like "String" or "Int64".
// Defaulting to "sql.Null"
Prefix sql.NullString
}
type constructor struct { type constructor struct {
config *StructConfig config *StructConfig
tables []*ddl.Table tables []*ddl.Table
@ -314,16 +333,27 @@ func (c *constructor) getDataType(column *ddl.Column, tblConfig *TableConfig, _
} }
// Try to use sql null strings // Try to use sql null strings
if column.CanBeNull { if column.CanBeNull && !c.config.NullConfig.Disable {
// Get nullable data types
prefix := "sql.Null"
imp := "database/sql"
if c.config.NullConfig.Package != "" {
imp = c.config.NullConfig.Package
}
if c.config.NullConfig.Prefix.Valid {
prefix = c.config.NullConfig.Prefix.String
}
switch column.Type { switch column.Type {
case ddl.StringType: case ddl.StringType:
return "sql.NullString", "database/sql" return prefix + "String", imp
case ddl.IntType: case ddl.IntType:
return "sql.NullInt64", "database/sql" return prefix + "Int64", imp
case ddl.DoubleType: case ddl.DoubleType:
return "sql.NullFloat64", "database/sql" return prefix + "Float64", imp
case ddl.DateType: case ddl.DateType:
return "sql.NullTime", "database/sql" return prefix + "Time", imp
case ddl.GeoType: case ddl.GeoType:
return "ddl.Location", PackageName return "ddl.Location", PackageName
} }

View File

@ -1,6 +1,7 @@
package structt package structt
import ( import (
"database/sql"
"fmt" "fmt"
"regexp" "regexp"
"strings" "strings"
@ -413,6 +414,74 @@ func TestPatchFilePatchSelf(t *testing.T) {
} }
} }
func TestNullableConfig(t *testing.T) {
c := &constructor{
config: &StructConfig{
NullConfig: NullConfig{
Disable: true,
},
},
}
table := &ddl.Table{
Name: "my_table_name",
Schema: "here_is_me",
Columns: []*ddl.Column{
{
Name: "id",
Type: ddl.IntType,
CanBeNull: true,
},
},
}
tableConfig := &TableConfig{
PackageName: "olaf",
Suffix: "Tab",
}
expected :=
`package olaf
%s
type MyTableNameTab struct {
Id %s ` + getStructTag(table.Columns[0]) + `
` + MetadataFieldName + ` any ` + getMetadataTag(table) + `
}
// MyTableNameTab
const (
MyTableNameTab_Id string = "Id|here_is_me.my_table_name.id"
)
`
goFile := c.getGoFile("", table, tableConfig)
// Compare structs
if diff := cmp.Diff(
replaceWhitespaces(fmt.Sprintf(expected, "", "int")),
replaceWhitespaces(goFile),
); diff != "" {
t.Errorf("Mismatch of disabled null types (-want +got):\n%s", diff)
t.Logf("Expected:\n%s", expected)
t.Logf("Actual:\n%s", goFile)
}
// ==== Test with custom data type ==== //
c.config.NullConfig = NullConfig{
Package: "git.rpjosh.de/MyCustom",
Prefix: sql.NullString{Valid: true, String: "olaf.Null"},
}
goFile = c.getGoFile("", table, tableConfig)
if diff := cmp.Diff(
replaceWhitespaces(fmt.Sprintf(expected, "import (\n\t\"git.rpjosh.de/MyCustom\"\n)", "olaf.NullInt64")),
replaceWhitespaces(goFile),
); diff != "" {
t.Errorf("Mismatch of custom null types (-want +got):\n%s", diff)
t.Logf("Expected:\n%s", expected)
t.Logf("Actual:\n%s", goFile)
}
}
// replaceWhitespaces replaces any space, newline or a squecne of // replaceWhitespaces replaces any space, newline or a squecne of
// spaces with a single space // spaces with a single space
func replaceWhitespaces(val string) string { func replaceWhitespaces(val string) string {