-
Notifications
You must be signed in to change notification settings - Fork 6
/
relationship.go
124 lines (106 loc) · 4.23 KB
/
relationship.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
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
package pqt
const (
// RelationshipTypeOneToOne is a relationship that each row in one database table is linked to 1 and only 1 other row in another table.
// In a one-to-one relationship between Table A and Table B, each row in Table A is linked to another row in Table B.
// The number of rows in Table A must equal the number of rows in Table B
RelationshipTypeOneToOne RelationshipType = iota
// RelationshipTypeOneToMany is a relationship that each row in the related to table can be related to many rows in the relating table.
// This allows frequently used information to be saved only once in a table and referenced many times in all other tables.
RelationshipTypeOneToMany
// RelationshipTypeManyToOne works like one to many, but it points to another owner.
RelationshipTypeManyToOne
RelationshipTypeManyToMany
// NoAction produce an error indicating that the deletion or update would create a foreign key constraint violation.
// If the constraint is deferred, this error will be produced at constraint check time if there still exist any referencing rows.
// This is the default action.
NoAction int32 = iota
// Restrict produce an error indicating that the deletion or update would create a foreign key constraint violation.
// This is the same as NO ACTION except that the check is not deferrable.
Restrict
// Cascade delete any rows referencing the deleted row,
// or update the values of the referencing column(s) to the new values of the referenced columns, respectively.
Cascade
// SetNull set the referencing column(s) to null
SetNull
// SetDefault set the referencing column(s) to their default values.
// (There must be a row in the referenced table matching the default values, if they are not null, or the operation will fail
SetDefault
)
// RelationshipType ...
type RelationshipType int
// Relationship ...
type Relationship struct {
Bidirectional bool
Type RelationshipType
OwnerName, InversedName string
OwnerTable, InversedTable, ThroughTable *Table
OwnerForeignKey, InversedForeignKey *Constraint
ColumnName string
OnDelete, OnUpdate int32
}
func newRelationship(owner, inversed, through *Table, rt RelationshipType, opts ...RelationshipOption) *Relationship {
r := &Relationship{
Type: rt,
ThroughTable: through,
OwnerTable: owner,
InversedTable: inversed,
}
for _, opt := range opts {
opt(r)
}
return r
}
// OneToOne ...
func OneToOne(t *Table, opts ...RelationshipOption) *Relationship {
return newRelationship(nil, t, nil, RelationshipTypeOneToOne, opts...)
}
// OneToMany ...
func OneToMany(t *Table, opts ...RelationshipOption) *Relationship {
return newRelationship(t, nil, nil, RelationshipTypeOneToMany, opts...)
}
// ManyToOne ...
func ManyToOne(t *Table, opts ...RelationshipOption) *Relationship {
return newRelationship(nil, t, nil, RelationshipTypeManyToOne, opts...)
}
// ManyToMany ...
func ManyToMany(t1 *Table, t2 *Table, opts ...RelationshipOption) *Relationship {
return newRelationship(t1, t2, nil, RelationshipTypeManyToMany, opts...)
}
// RelationshipOption configures how we set up the relationship.
type RelationshipOption func(*Relationship)
// WithOwnerName ...
func WithOwnerName(s string) RelationshipOption {
return func(r *Relationship) {
r.OwnerName = s
}
}
// WithOwnerForeignKey ...
func WithOwnerForeignKey(columns, references Columns, opts ...ConstraintOption) RelationshipOption {
return func(r *Relationship) {
r.OwnerForeignKey = ForeignKey(r.OwnerTable, columns, references, opts...)
}
}
// WithInversedName ...
func WithInversedName(s string) RelationshipOption {
return func(r *Relationship) {
r.InversedName = s
}
}
// WithInversedForeignKey ...
func WithInversedForeignKey(columns, references Columns, opts ...ConstraintOption) RelationshipOption {
return func(r *Relationship) {
r.InversedForeignKey = ForeignKey(r.InversedTable, columns, references, opts...)
}
}
// WithColumnName ...
func WithColumnName(n string) RelationshipOption {
return func(r *Relationship) {
r.ColumnName = n
}
}
// WithBidirectional ...
func WithBidirectional() RelationshipOption {
return func(r *Relationship) {
r.Bidirectional = true
}
}