/
model.go
104 lines (86 loc) · 2.19 KB
/
model.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
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
package model
import (
"encoding/json"
"fmt"
"strings"
"time"
"unicode"
"github.com/rjeczalik/bigstruct/internal/random"
"gorm.io/gorm"
)
var (
TablePrefix = "bigstruct"
RefSeparator = '='
ModelBeforeCreate = RandomID
)
func RandomID(m *Model, db *gorm.DB) error {
if m.ID == 0 {
m.ID = random.ID()
}
return nil
}
type Model struct {
ID uint64 `gorm:"column:id;type:bigint;not null;primaryKey;autoIncrement" yaml:"id,omitempty" json:"id,omitempty"`
CreatedAt time.Time `gorm:"column:created_at;type:datetime;not null" yaml:"created_at,omitempty" json:"created_at,omitempty"`
UpdatedAt time.Time `gorm:"column:updated_at;type:datetime;not null" yaml:"updated_at,omitempty" json:"updated_at,omitempty"`
DeletedAt gorm.DeletedAt `gorm:"column:deleted_at;type:datetime;index" yaml:"deleted_at,omitempty" json:"deleted_at,omitempty"`
}
func (m *Model) BeforeCreate(db *gorm.DB) error {
return ModelBeforeCreate(m, db)
}
func (*Model) Options() []string {
return []string{
"gorm:table_options", "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4",
}
}
func Ref(name, prop string) string {
if prop != "" {
return name + string(RefSeparator) + prop
}
return name
}
func ParseRef(ref string) (name, prop string, err error) {
parts, err := splitAlphanum(ref, string(RefSeparator))
if err != nil {
return "", "", fmt.Errorf("invalid ref: %w", err)
}
switch len(parts) {
case 0:
return "", "", fmt.Errorf("ref is empty or missing: %q", ref)
case 1:
return parts[0], "", nil
case 2:
return parts[0], parts[1], nil
default:
return "", "", fmt.Errorf("invalid ref: %q", ref)
}
}
func nonempty(s ...string) string {
for _, s := range s {
if s != "" {
return s
}
}
return ""
}
func splitAlphanum(s, sep string) (sl []string, err error) {
for _, s := range strings.Split(s, sep) {
if s = strings.TrimSpace(s); s == "" {
continue
}
for _, r := range s {
if !unicode.IsLetter(r) && !unicode.IsNumber(r) && r != '.' {
return nil, fmt.Errorf("bad char: %q", r)
}
}
sl = append(sl, s)
}
return sl, nil
}
func reencode(in, out interface{}) error {
p, err := json.Marshal(in)
if err != nil {
return err
}
return json.Unmarshal(p, out)
}