Skip to content

Commit

Permalink
Support passing non-string args to templates.
Browse files Browse the repository at this point in the history
  • Loading branch information
mortenson committed Jun 29, 2024
1 parent 87290e6 commit 33bd63e
Show file tree
Hide file tree
Showing 4 changed files with 28 additions and 10 deletions.
6 changes: 5 additions & 1 deletion db.go
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,11 @@ func buildQueryForRow(rowId string, row Row, dependencyGraph graph.Graph[string,
values := []string{}
setStatements := []string{}
onConflictColumn := ""
for column, value := range row {
for column, valueRaw := range row {
// Technically we allow more than strings in ripoff files for templating purposes,
// but full support (ex: escaping arrays, what to do with maps, etc.) is quite hard so tabling that for now.
value := fmt.Sprint(valueRaw)

// Rows can explicitly mark what columns they should conflict with, in cases like composite primary keys.
if column == "~conflict" {
// Really novice way of escaping these.
Expand Down
13 changes: 4 additions & 9 deletions ripoff_file.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,27 +6,22 @@ import (
"os"
"path/filepath"
"regexp"
"strconv"
"strings"
"text/template"

"gopkg.in/yaml.v3"
)

type Row map[string]string
type Row map[string]interface{}

type RipoffFile struct {
Rows map[string]Row `yaml:"rows"`
}

var funcMap = template.FuncMap{
// Convenient way to loop a set amount of times.
"intSlice": func(countStr string) ([]int, error) {
countInt, err := strconv.Atoi(countStr)
if err != nil {
return []int{}, err
}
ret := make([]int, countInt)
"intSlice": func(count int) ([]int, error) {
ret := make([]int, count)
for i := range ret {
ret[i] = i
}
Expand All @@ -43,7 +38,7 @@ func concatRows(templates *template.Template, existingRows map[string]Row, newRo
if rowExists {
return fmt.Errorf("row %s is defined more than once", rowId)
}
templateName, usesTemplate := row["template"]
templateName, usesTemplate := row["template"].(string)
if usesTemplate {
// "rowId" allows dependencies between templated rows to be clear outside of the template.
// Templates can additionally use it to seed random generators.
Expand Down
10 changes: 10 additions & 0 deletions testdata/templates/template_users.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
rows:
{{ range $email, $avatarUrl := .users }}
users:uuid({{ $email }}):
id: users:uuid({{ $email }})
email: {{ $email }}
avatar_id: avatars:uuid({{ $avatarUrl }})
avatars:uuid({{ $avatarUrl }}):
id: avatars:uuid({{ $avatarUrl }})
url: {{ $avatarUrl }}
{{ end }}
9 changes: 9 additions & 0 deletions testdata/templates/templates.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,12 @@ rows:
email: [email protected]
avatarUrl: image.png
avatarGrayscale: false
# Templates actually end up replacing the row, so if you don't use rowId in
# the template you can get away with using other variables as seeds.
bulk_users:
template: template_users.yml
users:
[email protected]: a.png
[email protected]: b.png
[email protected]: c.png
[email protected]: d.png

0 comments on commit 33bd63e

Please sign in to comment.