Skip to content

Commit

Permalink
feat: Better handling for const columns
Browse files Browse the repository at this point in the history
  • Loading branch information
codingconcepts committed Apr 26, 2024
1 parent cb5091f commit 607601a
Show file tree
Hide file tree
Showing 10 changed files with 134 additions and 34 deletions.
3 changes: 0 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -735,7 +735,6 @@ Thanks to the maintainers of the following fantastic packages, whose code this t
### Todos
* Better support for post generation (e.g. `IMPORT`)
* Improve code coverage
* Write file after generating, then only keep columns that other tables need
* Support for range without a table count (e.g. the following results in zero rows unless a count is provided)
Expand All @@ -755,5 +754,3 @@ Thanks to the maintainers of the following fantastic packages, whose code this t
processor:
values: [Win, Lose, Draw]
```

* Default step value for int range (of 1)
26 changes: 16 additions & 10 deletions dg.go
Original file line number Diff line number Diff line change
Expand Up @@ -146,11 +146,17 @@ func generateTable(t model.Table, files map[string]model.CSVFile, tt ui.TimerFun
defer tt(time.Now(), fmt.Sprintf("generated table: %s", t.Name))

// Create the Cartesian product of any each types first.
var g generator.EachGenerator
if err := g.Generate(t, files); err != nil {
var eg generator.EachGenerator
if err := eg.Generate(t, files); err != nil {
return fmt.Errorf("generating each columns: %w", err)
}

// Create any const columns next.
var cg generator.ConstGenerator
if err := cg.Generate(t, files); err != nil {
return fmt.Errorf("generating const columns: %w", err)
}

for _, col := range t.Columns {
switch col.Type {
case "ref":
Expand Down Expand Up @@ -180,14 +186,14 @@ func generateTable(t model.Table, files map[string]model.CSVFile, tt ui.TimerFun
return fmt.Errorf("running set process for %s.%s: %w", t.Name, col.Name, err)
}

case "const":
var g generator.ConstGenerator
if err := col.Generator.UnmarshalFunc(&g); err != nil {
return fmt.Errorf("parsing const process for %s.%s: %w", t.Name, col.Name, err)
}
if err := g.Generate(t, col, files); err != nil {
return fmt.Errorf("running const process for %s.%s: %w", t.Name, col.Name, err)
}
// case "const":
// var g generator.ConstGenerator
// if err := col.Generator.UnmarshalFunc(&g); err != nil {
// return fmt.Errorf("parsing const process for %s.%s: %w", t.Name, col.Name, err)
// }
// if err := g.Generate(t, col, files); err != nil {
// return fmt.Errorf("running const process for %s.%s: %w", t.Name, col.Name, err)
// }

case "inc":
var g generator.IncGenerator
Expand Down
27 changes: 23 additions & 4 deletions examples/const_test/config.yaml
Original file line number Diff line number Diff line change
@@ -1,12 +1,31 @@
tables:
- name: one
columns:
- name: a
- name: c1
type: const
processor:
values: [val_1, val_2, val_3]
values: [a, b, c]

- name: two
columns:
- name: c1
type: const
processor:
values: [a, b, c, d, e]

- name: c2
type: const
processor:
values: [a, b]

- name: three
columns:
- name: c1
type: const
processor:
values: [a, b]

- name: b
- name: c2
type: const
processor:
values: [val_1, val_2, val_3]
values: [a, b, c, d, e]
22 changes: 22 additions & 0 deletions examples/range_test/config.yaml
Original file line number Diff line number Diff line change
@@ -1,4 +1,26 @@
tables:
- name: auto_incrementing_id
count: 20
columns:
- name: id
type: range
processor:
type: int
from: 1

- name: bet_types
columns:
- name: id
type: range
processor:
type: int
from: 1
step: 1
- name: description
type: const
processor:
values: [Win, Lose, Draw]

- name: previous_table
count: 20
columns:
Expand Down
46 changes: 43 additions & 3 deletions internal/pkg/generator/const_generator.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package generator

import (
"fmt"
"sort"

"github.com/codingconcepts/dg/internal/pkg/model"
"github.com/samber/lo"
Expand All @@ -12,8 +13,44 @@ type ConstGenerator struct {
Values []string `yaml:"values"`
}

// Generate generates values for a column based on a series of provided values.
func (g ConstGenerator) Generate(t model.Table, c model.Column, files map[string]model.CSVFile) error {
// Generate values for a column based on a series of provided values.
func (g ConstGenerator) Generate(t model.Table, files map[string]model.CSVFile) error {
cols := lo.Filter(t.Columns, func(c model.Column, _ int) bool {
return c.Type == "const"
})

sortColumns(cols)

for _, c := range cols {
var cg ConstGenerator
if err := c.Generator.UnmarshalFunc(&cg); err != nil {
return fmt.Errorf("parsing const process for %s.%s: %w", t.Name, c.Name, err)
}
if err := cg.generate(t, c, files); err != nil {
return fmt.Errorf("generating const columns: %w", err)
}
}

return nil
}

func sortColumns(cols []model.Column) {
sort.Slice(cols, func(i, j int) bool {
var g1 ConstGenerator
if err := cols[i].Generator.UnmarshalFunc(&g1); err != nil {
return false
}

var g2 ConstGenerator
if err := cols[j].Generator.UnmarshalFunc(&g2); err != nil {
return false
}

return len(g1.Values) > len(g2.Values)
})
}

func (g ConstGenerator) generate(t model.Table, c model.Column, files map[string]model.CSVFile) error {
if len(g.Values) == 0 {
return fmt.Errorf("no values provided for const generator")
}
Expand All @@ -26,8 +63,11 @@ func (g ConstGenerator) Generate(t model.Table, c model.Column, files map[string
count = t.Count
}

// Repeat the values until they equal the count.
if count > len(g.Values) {
return fmt.Errorf("wrong number of values provided for const generator (need %d, got %d)", count, len(g.Values))
for i := 0; len(g.Values) < count; i++ {
g.Values = append(g.Values, g.Values[i%len(g.Values)])
}
}

AddTable(t, c.Name, g.Values, files)
Expand Down
24 changes: 13 additions & 11 deletions internal/pkg/generator/const_generator_test.go
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
package generator

import (
"fmt"
"testing"

"github.com/codingconcepts/dg/internal/pkg/model"
"github.com/samber/lo"
"github.com/stretchr/testify/assert"
)

Expand All @@ -14,6 +14,7 @@ func TestGenerateConstColumn(t *testing.T) {
tableCount int
files map[string]model.CSVFile
values []string
exp []string
expErr error
}{
{
Expand All @@ -34,8 +35,8 @@ func TestGenerateConstColumn(t *testing.T) {
},
},
},
values: []string{"a"},
expErr: fmt.Errorf("wrong number of values provided for const generator (need 3, got 1)"),
values: []string{"a", "b"},
exp: []string{"a", "b", "a"},
},
{
name: "less than current table size with table count",
Expand All @@ -50,8 +51,8 @@ func TestGenerateConstColumn(t *testing.T) {
},
},
},
values: []string{"a"},
expErr: fmt.Errorf("wrong number of values provided for const generator (need 3, got 1)"),
values: []string{"a", "b"},
exp: []string{"a", "b", "a"},
},
{
name: "same as current table size",
Expand Down Expand Up @@ -92,19 +93,20 @@ func TestGenerateConstColumn(t *testing.T) {
table := model.Table{
Name: "table",
Count: c.tableCount,
Columns: []model.Column{
{Name: "col", Type: "const", Generator: model.ToRawMessage(t, g)},
},
}

column := model.Column{
Name: "col",
}

actErr := g.Generate(table, column, c.files)
actErr := g.Generate(table, c.files)
assert.Equal(t, c.expErr, actErr)
if actErr != nil {
return
}

assert.Equal(t, c.values, c.files["table"].Lines[len(c.files["table"].Lines)-1])
exp := lo.Ternary(c.exp != nil, c.exp, c.values)

assert.Equal(t, exp, c.files["table"].Lines[len(c.files["table"].Lines)-1])
})
}
}
2 changes: 1 addition & 1 deletion internal/pkg/generator/gen_generator.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ func (g GenGenerator) GetFormat() string {
return g.Format
}

// Generate generates random data for a given column.
// Generate random data for a given column.
func (g GenGenerator) Generate(t model.Table, c model.Column, files map[string]model.CSVFile) error {
if t.Count == 0 {
t.Count = len(lo.MaxBy(files[t.Name].Lines, func(a, b []string) bool {
Expand Down
2 changes: 1 addition & 1 deletion internal/pkg/generator/inc_generator.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ func (pi IncGenerator) GetFormat() string {
return pi.Format
}

// Generate generates an incrementing number value for a column.
// Generate an incrementing number value for a column.
func (g IncGenerator) Generate(t model.Table, c model.Column, files map[string]model.CSVFile) error {
if t.Count == 0 {
t.Count = len(lo.MaxBy(files[t.Name].Lines, func(a, b []string) bool {
Expand Down
2 changes: 1 addition & 1 deletion internal/pkg/generator/range_generator.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ type RangeGenerator struct {
Format string `yaml:"format"`
}

// Generate generates sequential data between a given start and end range.
// Generate sequential data between a given start and end range.
func (g RangeGenerator) Generate(t model.Table, c model.Column, files map[string]model.CSVFile) error {
count := len(lo.MaxBy(files[t.Name].Lines, func(a, b []string) bool {
return len(a) > len(b)
Expand Down
14 changes: 14 additions & 0 deletions internal/pkg/generator/range_generator_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,20 @@ func TestGenerateRangeColumn(t *testing.T) {
"40",
},
},
{
name: "generates int range for const",
files: map[string]model.CSVFile{},
rtype: "int",
count: 4,
from: "1",
step: "1",
expLines: []string{
"1",
"2",
"3",
"4",
},
},
}

for _, c := range cases {
Expand Down

0 comments on commit 607601a

Please sign in to comment.