@@ -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.
102101type 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.
113113type 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.
128129type 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 .
138143type 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.
150154type 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.
163167type 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