Skip to content

Commit 9723609

Browse files
committed
Different approach to declare unique indexes
1 parent 42ecaa6 commit 9723609

File tree

1 file changed

+29
-24
lines changed

1 file changed

+29
-24
lines changed

pkg/share/manager/sql/model/model.go

Lines changed: 29 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -96,49 +96,53 @@ type ShareID struct {
9696
}
9797

9898
// This is the base model for all share types. We cannot use gorm.Model, because we want our ID
99-
// to be a foreign key to ShareID, but we incorporate the date fields from gorm.
100-
// The DeletedAt field is included in multiple unique indexes to allow soft deletion while
101-
// maintaining uniqueness constraints.
99+
// to be a foreign key to ShareID, but we incorporate the date fields from gorm. This struct
100+
// does not declare any unique indexes as it is embedded by others.
102101
type BaseModel struct {
103102
// Id has to be called Id and not ID, otherwise the foreign key will not work
104103
// ID is a special field in GORM, which it uses as the default Primary Key
105104
Id uint `gorm:"primaryKey;not null;autoIncrement:false"`
106105
ShareId ShareID `gorm:"foreignKey:Id;references:ID;constraint:OnDelete:CASCADE"` //;references:ID
107106
CreatedAt time.Time
108107
UpdatedAt time.Time
109-
DeletedAt gorm.DeletedAt `gorm:"uniqueIndex:u_share;uniqueIndex:u_link;uniqueIndex:u_ocmshare"`
108+
DeletedAt gorm.DeletedAt `gorm:"index"`
110109
}
111110

112111
// ProtoShare contains fields that are common between PublicLinks and Shares.
112+
// We also define some indexes for performance reasons.
113113
type ProtoShare struct {
114114
BaseModel
115115
UIDOwner string `gorm:"size:64"`
116-
UIDInitiator string `gorm:"size:64"`
116+
UIDInitiator string `gorm:"size:64;index"`
117117
ItemType ItemType `gorm:"size:16;index"` // file | folder | reference | symlink
118118
InitialPath string
119-
Inode string `gorm:"size:32;uniqueIndex:u_share;uniqueIndex:u_link"`
120-
Instance string `gorm:"size:32;uniqueIndex:u_share;uniqueIndex:u_link"`
121-
Permissions uint8 `gorm:"uniqueIndex:u_share;uniqueIndex:u_link"`
119+
Inode string `gorm:"size:32;index"`
120+
Instance string `gorm:"size:32"`
121+
Permissions uint8
122122
Orphan bool
123123
Expiration datatypes.NullTime
124124
}
125125

126126
// Share is a regular share between users or groups. The unique index ensures that there
127-
// can only be one share per (inode, instance, permissions, recipient) tuple, unless the share is deleted.
127+
// can only be one share per (inode, instance, permissions, recipient) tuple, unless the share is deleted:
128+
// for that, we redeclare the corresponding fields for GORM to define the unique index.
128129
type Share struct {
129130
ProtoShare
130-
ShareWith string `gorm:"size:255;uniqueIndex:u_share"` // 255 because this can be an external account, which has a long representation
131+
DeletedAt gorm.DeletedAt `gorm:"uniqueIndex:u_share"`
132+
Inode string `gorm:"size:32;uniqueIndex:u_share"`
133+
Instance string `gorm:"size:32;uniqueIndex:u_share"`
134+
Permissions uint8 `gorm:"uniqueIndex:u_share"`
135+
ShareWith string `gorm:"size:255;uniqueIndex:u_share"` // 255 because this can be an external account, which has a long representation
131136
SharedWithIsGroup bool
132137
Description string `gorm:"size:1024"`
133138
}
134139

135-
// PublicLink is a public link share. We create a "non-enforcing" unique index here to please GORM:
136-
// there can only be one public link per (token, inode, instance, permissions) tuple, unless the link is deleted.
137-
// It is "non-enforcing" because the token is already unique by itself.
140+
// PublicLink is a public link share.
141+
// TODO(lopresti) We could enforce a unique index on (UIDInitiator, Inode, Permissions, DeleteAt) but for now web allows
142+
// the creation of multiple links (with or without different names), so we only enforce a unique constraint on the token.
138143
type PublicLink struct {
139144
ProtoShare
140-
// Current tokens are only 16 chars long, but old tokens used to be 32 characters
141-
Token string `gorm:"uniqueIndex:i_token;uniqueIndex:u_link;size:32"`
145+
Token string `gorm:"uniqueIndex:u_link_token;size:32"` // Current tokens are only 16 chars long, but old tokens used to be 32 characters
142146
Quicklink bool
143147
NotifyUploads bool
144148
NotifyUploadsExtraRecipients string
@@ -149,20 +153,21 @@ type PublicLink struct {
149153
// ShareState represents the state of a share for a specific recipient.
150154
type ShareState struct {
151155
gorm.Model
152-
ShareID uint `gorm:"uniqueIndex:i_shareid_user"` // Define the foreign key field
153-
Share Share `gorm:"foreignKey:ShareID;references:Id"` // Define the association
154-
// Can not be uid because of lw accs
155-
User string `gorm:"uniqueIndex:i_shareid_user;size:255"`
156-
Synced bool
157-
Hidden bool
158-
Alias string `gorm:"size:64"`
156+
ShareID uint `gorm:"uniqueIndex:i_shareid_user"` // Define the foreign key field
157+
Share Share `gorm:"foreignKey:ShareID;references:Id"` // Define the association
158+
User string `gorm:"uniqueIndex:i_shareid_user;size:255"` // Can not be uid because of lw accounts
159+
Synced bool
160+
Hidden bool
161+
Alias string `gorm:"size:64"`
159162
}
160163

161164
// OcmShare represents an OCM share for a remote user. The unique index ensures that there
162-
// can only be one share per (storageId, fileId, shareWith, owner) tuple, unless the share is deleted.
165+
// can only be one share per (storageId, fileId, shareWith, owner) tuple, unless the share is deleted:
166+
// for that, we redeclare the DeletedAt as in Share. In addition, tokens must be unique.
163167
type OcmShare struct {
164168
BaseModel
165-
Token string `gorm:"size:255;not null;uniqueIndex:i_ocmshare_token"`
169+
DeletedAt gorm.DeletedAt `gorm:"uniqueIndex:u_ocmshare"`
170+
Token string `gorm:"size:255;not null;uniqueIndex:u_ocmshare_token"`
166171
StorageId string `gorm:"size:64;not null;uniqueIndex:u_ocmshare"`
167172
FileId string `gorm:"size:64;not null;uniqueIndex:u_ocmshare"`
168173
Name string `gorm:"type:text;not null"`

0 commit comments

Comments
 (0)