This repository has been archived by the owner on Jun 14, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 18
/
Copy pathcolumn.go
107 lines (103 loc) · 4.5 KB
/
column.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
105
106
107
package tengo
import (
"fmt"
"strings"
)
// Column represents a single column of a table.
type Column struct {
Name string `json:"name"`
TypeInDB string `json:"type"`
Nullable bool `json:"nullable,omitempty"`
AutoIncrement bool `json:"autoIncrement,omitempty"`
Default string `json:"default,omitempty"` // Stored as an expression, i.e. quote-wrapped if string
OnUpdate string `json:"onUpdate,omitempty"`
GenerationExpr string `json:"generationExpression,omitempty"` // Only populated if generated column
Virtual bool `json:"virtual,omitempty"`
CharSet string `json:"charSet,omitempty"` // Only populated if textual type
Collation string `json:"collation,omitempty"` // Only populated if textual type
CollationIsDefault bool `json:"collationIsDefault,omitempty"` // Only populated if textual type; indicates default for CharSet
Compression string `json:"compression,omitempty"` // Only non-empty if using column compression in Percona Server or MariaDB
Comment string `json:"comment,omitempty"`
Invisible bool `json:"invisible,omitempty"` // True if an invisible column (MariaDB 10.3+, MySQL 8.0.23+)
CheckClause string `json:"check,omitempty"` // Only non-empty for MariaDB inline check constraint clause
}
// Definition returns this column's definition clause, for use as part of a DDL
// statement. A table may optionally be supplied, which simply causes CHARACTER
// SET clause to be omitted if the table and column have the same *collation*
// (mirroring the specific display logic used by SHOW CREATE TABLE)
func (c *Column) Definition(flavor Flavor, table *Table) string {
var compression, charSet, collation, generated, nullability, visibility, autoIncrement, defaultValue, onUpdate, colFormat, comment, check string
if c.Compression != "" && flavor.Vendor == VendorMariaDB {
// MariaDB puts compression modifiers in a different place than Percona Server
compression = fmt.Sprintf(" /*!100301 %s*/", c.Compression)
}
if c.CharSet != "" && (table == nil || c.Collation != table.Collation || c.CharSet != table.CharSet) {
charSet = fmt.Sprintf(" CHARACTER SET %s", c.CharSet)
}
// Any flavor: Collations are displayed if not the default for the charset
// 8.0 only: Collations are also displayed any time a charset is displayed
// (except if the table was upgraded from pre-8.0, in which case it may not be;
// this can only be fixed up hackily post-introspection though)
if c.Collation != "" && (!c.CollationIsDefault || (charSet != "" && flavor.HasDataDictionary())) {
collation = fmt.Sprintf(" COLLATE %s", c.Collation)
}
if c.GenerationExpr != "" {
genKind := "STORED"
if c.Virtual {
genKind = "VIRTUAL"
}
generated = fmt.Sprintf(" GENERATED ALWAYS AS (%s) %s", c.GenerationExpr, genKind)
}
if !c.Nullable {
nullability = " NOT NULL"
} else if strings.HasPrefix(c.TypeInDB, "timestamp") {
// Oddly the timestamp type always displays nullability
nullability = " NULL"
}
if c.Invisible {
if flavor.Vendor == VendorMariaDB {
visibility = " INVISIBLE"
} else {
visibility = " /*!80023 INVISIBLE */"
}
}
if c.AutoIncrement {
autoIncrement = " AUTO_INCREMENT"
}
if c.Default != "" {
defaultValue = fmt.Sprintf(" DEFAULT %s", c.Default)
}
if c.OnUpdate != "" {
onUpdate = fmt.Sprintf(" ON UPDATE %s", c.OnUpdate)
}
if c.Compression != "" && flavor.Vendor == VendorPercona {
colFormat = fmt.Sprintf(" /*!50633 COLUMN_FORMAT %s */", c.Compression)
}
if c.Comment != "" {
comment = fmt.Sprintf(" COMMENT '%s'", EscapeValueForCreateTable(c.Comment))
}
if c.CheckClause != "" {
check = fmt.Sprintf(" CHECK (%s)", c.CheckClause)
}
clauses := []string{
EscapeIdentifier(c.Name), " ", c.TypeInDB, compression, charSet, collation, generated, nullability,
}
if flavor.Vendor == VendorMariaDB {
clauses = append(clauses, visibility, autoIncrement, defaultValue, onUpdate, colFormat, comment, check)
} else {
clauses = append(clauses, autoIncrement, defaultValue, onUpdate, visibility, colFormat, comment)
}
return strings.Join(clauses, "")
}
// Equals returns true if two columns are identical, false otherwise.
func (c *Column) Equals(other *Column) bool {
// shortcut if both nil pointers, or both pointing to same underlying struct
if c == other {
return true
}
// if one is nil, but we already know the two aren't equal, then we know the other is non-nil
if c == nil || other == nil {
return false
}
return *c == *other
}