Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Respect character_maximum_length when generating random values for string columns #241

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 11 additions & 7 deletions gen/bobgen-mysql/driver/mysql.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"strings"
"sync"

"github.com/aarondl/opt/null"
"github.com/go-sql-driver/mysql"
helpers "github.com/stephenafamo/bob/gen/bobgen-helpers"
"github.com/stephenafamo/bob/gen/drivers"
Expand Down Expand Up @@ -157,6 +158,7 @@ func (d *driver) TableDetails(ctx context.Context, info drivers.TableInfo, colFi
c.data_type,
c.column_default,
c.extra = 'auto_increment' AS autoincr,
c.character_maximum_length,
c.is_nullable = 'YES' AS nullable,
(c.extra = 'STORED GENERATED' OR c.extra = 'VIRTUAL GENERATED') is_generated
from information_schema.columns as c
Expand Down Expand Up @@ -188,7 +190,8 @@ func (d *driver) TableDetails(ctx context.Context, info drivers.TableInfo, colFi
var colName, colFullType, colComment, colType string
var autoIncr, nullable, generated bool
var defaultValue *string
if err := rows.Scan(&colName, &colFullType, &colComment, &colType, &defaultValue, &autoIncr, &nullable, &generated); err != nil {
var charMaxLen null.Val[int]
if err := rows.Scan(&colName, &colFullType, &colComment, &colType, &defaultValue, &autoIncr, &charMaxLen, &nullable, &generated); err != nil {
return "", "", nil, fmt.Errorf("unable to scan for table %s: %w", tableName, err)
}

Expand All @@ -197,12 +200,13 @@ func (d *driver) TableDetails(ctx context.Context, info drivers.TableInfo, colFi
}

column := drivers.Column{
Name: colName,
Comment: colComment,
DBType: colType,
Nullable: nullable,
Generated: generated,
AutoIncr: autoIncr,
Name: colName,
Comment: colComment,
DBType: colType,
Nullable: nullable,
Generated: generated,
AutoIncr: autoIncr,
CharMaxLen: charMaxLen,
}

if defaultValue != nil {
Expand Down
19 changes: 12 additions & 7 deletions gen/bobgen-psql/driver/psql.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"fmt"
"sort"

"github.com/aarondl/opt/null"
"github.com/lib/pq"
helpers "github.com/stephenafamo/bob/gen/bobgen-helpers"
"github.com/stephenafamo/bob/gen/drivers"
Expand Down Expand Up @@ -230,6 +231,7 @@ func (d *driver) TableDetails(ctx context.Context, info drivers.TableInfo, colFi
) AS array_type,
c.domain_name,
c.column_default,
c.character_maximum_length,
coalesce(col_description(('"' || c.table_schema || '"."' || c.table_name || '"')::regclass::oid, ordinal_position), '') AS column_comment,
c.is_nullable = 'YES' AS is_nullable,
(
Expand Down Expand Up @@ -288,7 +290,8 @@ func (d *driver) TableDetails(ctx context.Context, info drivers.TableInfo, colFi
column_comment,
is_nullable,
is_generated,
is_identity
is_identity,
character_maximum_length
FROM (
%s
) AS c`, tableQuery) // matviewQuery, tableQuery)
Expand Down Expand Up @@ -325,16 +328,18 @@ func (d *driver) TableDetails(ctx context.Context, info drivers.TableInfo, colFi
var colName, colType, udtSchema, udtName, comment string
var defaultValue, arrayType, domainName *string
var nullable, generated, identity bool
if err := rows.Scan(&colName, &colType, &udtSchema, &udtName, &arrayType, &domainName, &defaultValue, &comment, &nullable, &generated, &identity); err != nil {
var charMaxLen null.Val[int]
if err := rows.Scan(&colName, &colType, &udtSchema, &udtName, &arrayType, &domainName, &defaultValue, &comment, &nullable, &generated, &identity, &charMaxLen); err != nil {
return "", "", nil, fmt.Errorf("unable to scan for table %s: %w", info.Key, err)
}

column := drivers.Column{
Name: colName,
DBType: colType,
Comment: comment,
Nullable: nullable,
Generated: generated,
Name: colName,
DBType: colType,
Comment: comment,
Nullable: nullable,
Generated: generated,
CharMaxLen: charMaxLen,
}
info := colInfo{
UDTSchema: udtSchema,
Expand Down
3 changes: 3 additions & 0 deletions gen/drivers/column.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package drivers
import (
"strings"

"github.com/aarondl/opt/null"
"github.com/volatiletech/strmangle"
)

Expand All @@ -21,6 +22,8 @@ type Column struct {
// https://www.postgresql.org/docs/16/extend-type-system.html
DomainName string `json:"domain_name" yaml:"domain_name" toml:"domain_name"`

CharMaxLen null.Val[int] `json:"char_max_len" yaml:"char_max_len" toml:"char_max_len"`

Type string `json:"type" yaml:"type" toml:"type"`
}

Expand Down
18 changes: 12 additions & 6 deletions gen/templates/factory/03_create.go.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,20 @@

func ensureCreatable{{$tAlias.UpSingular}}(m *models.{{$tAlias.UpSingular}}Setter) {
{{range $column := $table.Columns -}}
{{- if $column.Default}}{{continue}}{{end -}}
{{- if $column.Nullable}}{{continue}}{{end -}}
{{- if $column.Default}}{{continue}}{{end -}}
{{- if $column.Nullable}}{{continue}}{{end -}}
{{- if $column.Generated}}{{continue}}{{end -}}
{{- $colAlias := $tAlias.Column $column.Name -}}
{{- $typDef := index $.Types $column.Type -}}
{{- $colTyp := or $typDef.AliasOf $column.Type -}}
if m.{{$colAlias}}.IsUnset() {
m.{{$colAlias}} = omit.From(random_{{normalizeType $column.Type}}(nil))
{{- $typDef := index $.Types $column.Type -}}
{{- $colTyp := or $typDef.AliasOf $column.Type -}}
{{- $wrapStart := "" -}}
{{- $wrapEnd := "" -}}
{{- if $column.CharMaxLen.IsSet -}}
{{- $wrapStart = "truncateString(" -}}
{{- $wrapEnd = printf `,%d )` $column.CharMaxLen.GetOrZero -}}
{{- end -}}
if m.{{$colAlias}}.IsUnset() {
m.{{$colAlias}} = omit.From({{$wrapStart}}random_{{normalizeType $column.Type}}(nil){{$wrapEnd}})
}
{{end -}}
}
Expand Down
11 changes: 9 additions & 2 deletions gen/templates/factory/11_column_mods.go.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,13 @@ func (m {{$tAlias.DownSingular}}Mods) RandomizeAllColumns(f *faker.Faker) {{$tAl
{{- $colTyp = printf "null.Val[%s]" $colTyp -}}
{{- end -}}

{{- $wrapStart := "" -}}
{{- $wrapEnd := "" -}}
{{- if $column.CharMaxLen.IsSet -}}
{{- $wrapStart = "truncateString(" -}}
{{- $wrapEnd = printf `,%d )` $column.CharMaxLen.GetOrZero -}}
{{- end -}}

// Set the model columns to this value
func (m {{$tAlias.DownSingular}}Mods) {{$colAlias}}(val {{$colTyp}}) {{$tAlias.UpSingular}}Mod {
return {{$tAlias.UpSingular}}ModFunc(func(o *{{$tAlias.UpSingular}}Template) {
Expand Down Expand Up @@ -59,9 +66,9 @@ func (m {{$tAlias.DownSingular}}Mods) Random{{$colAlias}}(f *faker.Faker) {{$tAl
return null.FromPtr[{{or $typDef.AliasOf $column.Type}}](nil)
}

return null.From(random_{{normalizeType $column.Type}}(f))
return null.From({{$wrapStart}}random_{{normalizeType $column.Type}}(f){{$wrapEnd}})
{{- else -}}
return random_{{normalizeType $column.Type}}(f)
return {{$wrapStart}}random_{{normalizeType $column.Type}}(f){{$wrapEnd}}
{{- end}}
}
})
Expand Down
11 changes: 11 additions & 0 deletions gen/templates/factory/singleton/bobfactory_random.go.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,12 @@

var defaultFaker = faker.New()

{{$hasCharMaxLen := false}}
{{$doneTypes := dict }}
{{- range $table := .Tables}}
{{- $tAlias := $.Aliases.Table $table.Key}}
{{range $column := $table.Columns -}}
{{- if $column.CharMaxLen -}}{{- $hasCharMaxLen = true -}}{{- end -}}
{{- $colTyp := $column.Type -}}
{{- if hasKey $doneTypes $column.Type}}{{continue}}{{end -}}
{{- $_ := set $doneTypes $column.Type nil -}}
Expand Down Expand Up @@ -34,3 +36,12 @@ var defaultFaker = faker.New()
{{$typDef.RandomExpr}}
}
{{end -}}

{{- if $hasCharMaxLen -}}
func truncateString(s string, maxLen int) string {
if len(s) > maxLen {
return s[:maxLen]
}
return s
}
{{- end -}}
Loading