-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathmodeldiff.go
84 lines (76 loc) · 2.96 KB
/
modeldiff.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
package gomodel
import (
"fmt"
"strings"
"github.com/pkg/errors"
"projectforge.dev/projectforge/app/file"
"projectforge.dev/projectforge/app/lib/types"
"projectforge.dev/projectforge/app/project/export/enum"
"projectforge.dev/projectforge/app/project/export/files/helper"
"projectforge.dev/projectforge/app/project/export/golang"
"projectforge.dev/projectforge/app/project/export/model"
)
func ModelDiff(m *model.Model, args *model.Args, addHeader bool, linebreak string) (*file.File, error) {
g := golang.NewFile(m.Package, []string{"app", m.PackageWithGroup("")}, strings.ToLower(m.Camel())+"diff")
g.AddImport(helper.ImpAppUtil)
mdiff, err := modelDiffBlock(g, m, args.Enums)
if err != nil {
return nil, err
}
g.AddBlocks(mdiff)
return g.Render(addHeader, linebreak)
}
func modelDiffBlock(g *golang.File, m *model.Model, enums enum.Enums) (*golang.Block, error) {
ret := golang.NewBlock("Diff"+m.Proper(), "func")
ret.W("func (%s *%s) Diff(%sx *%s) util.Diffs {", m.FirstLetter(), m.Proper(), m.FirstLetter(), m.Proper())
ret.W("\tvar diffs util.Diffs")
for _, col := range m.Columns {
if col.HasTag("updated") {
continue
}
l := fmt.Sprintf("%s.%s", m.FirstLetter(), col.Proper())
r := fmt.Sprintf("%sx.%s", m.FirstLetter(), col.Proper())
switch col.Type.Key() {
case types.KeyAny, types.KeyList, types.KeyMap, types.KeyValueMap, types.KeyReference:
ret.W("\tdiffs = append(diffs, util.DiffObjects(%s, %s, %q)...)", l, r, col.Camel())
case types.KeyBool, types.KeyInt, types.KeyFloat:
g.AddImport(helper.ImpFmt)
ret.W("\tif %s != %s {", l, r)
ret.W("\t\tdiffs = append(diffs, util.NewDiff(%q, fmt.Sprint(%s), fmt.Sprint(%s)))", col.Camel(), l, r)
ret.W("\t}")
case types.KeyEnum:
e, err := model.AsEnumInstance(col.Type, enums)
if err != nil {
return nil, err
}
ret.W("\tif %s != %s {", l, r)
if e.Simple() {
ret.W("\t\tdiffs = append(diffs, util.NewDiff(%q, string(%s), string(%s)))", col.Camel(), l, r)
} else {
ret.W("\t\tdiffs = append(diffs, util.NewDiff(%q, %s.Key, %s.Key))", col.Camel(), l, r)
}
ret.W("\t}")
case types.KeyString:
ret.W("\tif %s != %s {", l, r)
ret.W("\t\tdiffs = append(diffs, util.NewDiff(%q, %s, %s))", col.Camel(), l, r)
ret.W("\t}")
case types.KeyDate, types.KeyTimestamp, types.KeyUUID:
if col.Nullable {
msg := "\tif (%s == nil && %s != nil) || (%s != nil && %s == nil) || (%s != nil && %s != nil && *%s != *%s) {"
line := fmt.Sprintf(msg, l, r, l, r, l, r, l, r)
ret.W(line)
g.AddImport(helper.ImpFmt)
ret.W("\t\tdiffs = append(diffs, util.NewDiff(%q, fmt.Sprint(%s), fmt.Sprint(%s))) //nolint:gocritic // it's nullable", col.Camel(), l, r)
} else {
ret.W("\tif %s != %s {", l, r)
ret.W("\t\tdiffs = append(diffs, util.NewDiff(%q, %s.String(), %s.String()))", col.Camel(), l, r)
}
ret.W("\t}")
default:
return nil, errors.Errorf("unhandled diff type [%s]", col.Type.Key())
}
}
ret.W("\treturn diffs")
ret.W("}")
return ret, nil
}