Skip to content

Commit 799c4d3

Browse files
committed
Implement shared ID for public links and shares
1 parent d4c5866 commit 799c4d3

File tree

4 files changed

+68
-8
lines changed

4 files changed

+68
-8
lines changed

share/model.go

+21-1
Original file line numberDiff line numberDiff line change
@@ -30,12 +30,32 @@ func (i ItemType) String() string {
3030
return string(i)
3131
}
3232

33+
// ShareID only contains IDs of shares and public links. This is because OCIS requires
34+
// that shares and public links do not share an ID, so we need a shared table to make sure
35+
// that there are no duplicates.
36+
// This is implemented by having ShareID have an ID that is auto-increment, and shares and
37+
// public links will have their ID be a foreign key to ShareID
38+
// When creating a new share, we will then first create an ID entry and use this for the ID
39+
40+
type ShareID struct {
41+
ID uint `gorm:"primarykey"`
42+
}
43+
44+
// We cannot use gorm.Model, because we want our ID to be a foreign key to ShareID
45+
type BaseModel struct {
46+
ID uint //`gorm:"uniqueIndex"`
47+
ShareId ShareID `gorm:"foreignKey:ID;references:ID;constraint:OnDelete:CASCADE"` //;references:ID
48+
CreatedAt time.Time
49+
UpdatedAt time.Time
50+
DeletedAt gorm.DeletedAt `gorm:"index"`
51+
}
52+
3353
// ProtoShare contains fields that are shared between PublicLinks and Shares.
3454
// Unfortunately, because these are shared, we cannot name our indexes
3555
// because then two indexes with the same name would be created
3656
type ProtoShare struct {
3757
// Including gorm.Model will embed a number of gorm-default fields
38-
gorm.Model
58+
BaseModel
3959
UIDOwner string `gorm:"size:64"`
4060
UIDInitiator string `gorm:"size:64"`
4161
ItemType ItemType `gorm:"size:16;index:"` // file | folder | reference | symlink

share/sql/common.go

+18-3
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package sql
33
import (
44
"fmt"
55

6+
model "github.com/cernbox/reva-plugins/share"
67
"github.com/cs3org/reva"
78
"gorm.io/driver/mysql"
89
"gorm.io/driver/sqlite"
@@ -33,14 +34,28 @@ func init() {
3334
}
3435

3536
func getDb(c config) (*gorm.DB, error) {
37+
gormCfg := &gorm.Config{
38+
DisableForeignKeyConstraintWhenMigrating: false,
39+
}
3640
switch c.Engine {
3741
case "sqlite":
38-
return gorm.Open(sqlite.Open(c.DBName), &gorm.Config{})
42+
return gorm.Open(sqlite.Open(c.DBName), gormCfg)
3943
case "mysql":
4044
dsn := fmt.Sprintf("%s:%s@tcp(%s:%d)/%s?parseTime=true", c.DBUsername, c.DBPassword, c.DBHost, c.DBPort, c.DBName)
41-
return gorm.Open(mysql.Open(dsn), &gorm.Config{})
45+
return gorm.Open(mysql.Open(dsn), gormCfg)
4246
default: // default is mysql
4347
dsn := fmt.Sprintf("%s:%s@tcp(%s:%d)/%s?parseTime=true", c.DBUsername, c.DBPassword, c.DBHost, c.DBPort, c.DBName)
44-
return gorm.Open(mysql.Open(dsn), &gorm.Config{})
48+
return gorm.Open(mysql.Open(dsn), gormCfg)
49+
}
50+
}
51+
52+
func createID(db *gorm.DB) (uint, error) {
53+
id := &model.ShareID{}
54+
55+
res := db.Create(&id)
56+
if res.Error != nil {
57+
return 0, res.Error
58+
} else {
59+
return id.ID, nil
4560
}
4661
}

share/sql/public_link.go

+12-1
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,17 @@ func (m *publicShareMgr) CreatePublicShare(ctx context.Context, u *user.User, md
106106
NotifyUploadsExtraRecipients: notifyUploadsExtraRecipients,
107107
}
108108

109+
// Create Shared ID
110+
id, err := createID(m.db)
111+
if err != nil {
112+
return nil, errors.Wrap(err, "failed to create id for PublicShare")
113+
}
114+
115+
publiclink.BaseModel = model.BaseModel{
116+
ID: id,
117+
ShareId: model.ShareID{ID: id},
118+
}
119+
109120
publiclink.UIDOwner = conversions.FormatUserID(md.Owner)
110121
publiclink.UIDInitiator = conversions.FormatUserID(user.Id)
111122
publiclink.InitialPath = md.Path
@@ -375,7 +386,7 @@ func emptyLinkWithId(id string) (*model.PublicLink, error) {
375386
}
376387
share := &model.PublicLink{
377388
ProtoShare: model.ProtoShare{
378-
Model: gorm.Model{
389+
BaseModel: model.BaseModel{
379390
ID: uint(intId),
380391
},
381392
},

share/sql/share.go

+17-3
Original file line numberDiff line numberDiff line change
@@ -75,12 +75,14 @@ func NewShareManager(ctx context.Context, m map[string]interface{}) (revashare.M
7575
}
7676

7777
// Migrate schemas
78-
err = db.AutoMigrate(&model.Share{}, &model.ShareState{})
79-
78+
err = db.AutoMigrate(&model.ShareID{}, &model.Share{}, &model.ShareState{})
8079
if err != nil {
8180
return nil, err
8281
}
8382

83+
db.Migrator().CreateConstraint(&model.Share{}, "ShareId")
84+
db.Migrator().CreateConstraint(&model.Share{}, "fk_shares_share_ids")
85+
8486
mgr := &shareMgr{
8587
c: &c,
8688
db: db,
@@ -125,6 +127,18 @@ func (m *shareMgr) Share(ctx context.Context, md *provider.ResourceInfo, g *coll
125127
ShareWith: shareWith,
126128
SharedWithIsGroup: g.Grantee.Type == provider.GranteeType_GRANTEE_TYPE_GROUP,
127129
}
130+
131+
// Create Shared ID
132+
id, err := createID(m.db)
133+
if err != nil {
134+
return nil, errors.Wrap(err, "failed to create id for PublicShare")
135+
}
136+
137+
share.BaseModel = model.BaseModel{
138+
ID: id,
139+
ShareId: model.ShareID{ID: id},
140+
}
141+
128142
share.UIDOwner = conversions.FormatUserID(md.Owner)
129143
share.UIDInitiator = conversions.FormatUserID(user.Id)
130144
share.InitialPath = md.Path
@@ -415,7 +429,7 @@ func emptyShareWithId(id string) (*model.Share, error) {
415429
}
416430
share := &model.Share{
417431
ProtoShare: model.ProtoShare{
418-
Model: gorm.Model{
432+
BaseModel: model.BaseModel{
419433
ID: uint(intId),
420434
},
421435
},

0 commit comments

Comments
 (0)