fix(assets): correct type column in assets (#4295)

* fix(asssets): correct remove asset objects with text column

* fix(assets): type asset_type, correct and add unit tests

* fix(assets): set unspecified objecttype to empty string

Co-authored-by: Livio Spring <livio.a@gmail.com>
This commit is contained in:
Stefan Benz 2022-09-08 08:39:38 +01:00 committed by GitHub
parent aa4df33b62
commit 5052aa1c12
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 127 additions and 6 deletions

View File

@ -44,7 +44,7 @@ func (c *crdbStorage) PutObject(ctx context.Context, instanceID, location, resou
} }
stmt, args, err := squirrel.Insert(assetsTable). stmt, args, err := squirrel.Insert(assetsTable).
Columns(AssetColInstanceID, AssetColResourceOwner, AssetColName, AssetColType, AssetColContentType, AssetColData, AssetColUpdatedAt). Columns(AssetColInstanceID, AssetColResourceOwner, AssetColName, AssetColType, AssetColContentType, AssetColData, AssetColUpdatedAt).
Values(instanceID, resourceOwner, name, objectType, contentType, data, "now()"). Values(instanceID, resourceOwner, name, objectType.String(), contentType, data, "now()").
Suffix(fmt.Sprintf( Suffix(fmt.Sprintf(
"ON CONFLICT (%s, %s, %s) DO UPDATE"+ "ON CONFLICT (%s, %s, %s) DO UPDATE"+
" SET %s = $5, %s = $6"+ " SET %s = $5, %s = $6"+
@ -167,7 +167,7 @@ func (c *crdbStorage) RemoveObjects(ctx context.Context, instanceID, resourceOwn
Where(squirrel.Eq{ Where(squirrel.Eq{
AssetColInstanceID: instanceID, AssetColInstanceID: instanceID,
AssetColResourceOwner: resourceOwner, AssetColResourceOwner: resourceOwner,
AssetColType: objectType, AssetColType: objectType.String(),
}). }).
PlaceholderFormat(squirrel.Dollar). PlaceholderFormat(squirrel.Dollar).
ToSql() ToSql()

View File

@ -21,12 +21,20 @@ var (
) )
const ( const (
objectStmt = "INSERT INTO system.assets" + createObjectStmt = "INSERT INTO system.assets" +
" (instance_id,resource_owner,name,asset_type,content_type,data,updated_at)" + " (instance_id,resource_owner,name,asset_type,content_type,data,updated_at)" +
" VALUES ($1,$2,$3,$4,$5,$6,$7)" + " VALUES ($1,$2,$3,$4,$5,$6,$7)" +
" ON CONFLICT (instance_id, resource_owner, name) DO UPDATE SET" + " ON CONFLICT (instance_id, resource_owner, name) DO UPDATE SET" +
" content_type = $5, data = $6" + " content_type = $5, data = $6" +
" RETURNING hash" " RETURNING hash"
removeObjectStmt = "DELETE FROM system.assets" +
" WHERE instance_id = $1" +
" AND name = $2" +
" AND resource_owner = $3"
removeObjectsStmt = "DELETE FROM system.assets" +
" WHERE asset_type = $1" +
" AND instance_id = $2" +
" AND resource_owner = $3"
) )
func Test_crdbStorage_CreateObject(t *testing.T) { func Test_crdbStorage_CreateObject(t *testing.T) {
@ -56,7 +64,7 @@ func Test_crdbStorage_CreateObject(t *testing.T) {
fields{ fields{
client: prepareDB(t, client: prepareDB(t,
expectQuery( expectQuery(
objectStmt, createObjectStmt,
[]string{ []string{
"hash", "hash",
"updated_at", "updated_at",
@ -70,7 +78,7 @@ func Test_crdbStorage_CreateObject(t *testing.T) {
"instanceID", "instanceID",
"resourceOwner", "resourceOwner",
"name", "name",
static.ObjectTypeUserAvatar, static.ObjectTypeUserAvatar.String(),
"contentType", "contentType",
[]byte("test"), []byte("test"),
"now()", "now()",
@ -83,6 +91,7 @@ func Test_crdbStorage_CreateObject(t *testing.T) {
resourceOwner: "resourceOwner", resourceOwner: "resourceOwner",
name: "name", name: "name",
contentType: "contentType", contentType: "contentType",
objectType: static.ObjectTypeUserAvatar,
data: bytes.NewReader([]byte("test")), data: bytes.NewReader([]byte("test")),
objectSize: 4, objectSize: 4,
}, },
@ -115,6 +124,107 @@ func Test_crdbStorage_CreateObject(t *testing.T) {
} }
} }
func Test_crdbStorage_RemoveObject(t *testing.T) {
type fields struct {
client db
}
type args struct {
ctx context.Context
instanceID string
resourceOwner string
name string
}
tests := []struct {
name string
fields fields
args args
wantErr bool
}{
{
"remove ok",
fields{
client: prepareDB(t,
expectExec(
removeObjectStmt,
nil,
"instanceID",
"name",
"resourceOwner",
)),
},
args{
ctx: context.Background(),
instanceID: "instanceID",
resourceOwner: "resourceOwner",
name: "name",
},
false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
c := &crdbStorage{
client: tt.fields.client.db,
}
err := c.RemoveObject(tt.args.ctx, tt.args.instanceID, tt.args.resourceOwner, tt.args.name)
if (err != nil) != tt.wantErr {
t.Errorf("RemoveObject() error = %v, wantErr %v", err, tt.wantErr)
return
}
})
}
}
func Test_crdbStorage_RemoveObjects(t *testing.T) {
type fields struct {
client db
}
type args struct {
ctx context.Context
instanceID string
resourceOwner string
objectType static.ObjectType
}
tests := []struct {
name string
fields fields
args args
wantErr bool
}{
{
"remove ok",
fields{
client: prepareDB(t,
expectExec(
removeObjectsStmt,
nil, static.ObjectTypeUserAvatar.String(),
"instanceID",
"resourceOwner",
)),
},
args{
ctx: context.Background(),
instanceID: "instanceID",
resourceOwner: "resourceOwner",
objectType: static.ObjectTypeUserAvatar,
},
false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
c := &crdbStorage{
client: tt.fields.client.db,
}
err := c.RemoveObjects(tt.args.ctx, tt.args.instanceID, tt.args.resourceOwner, tt.args.objectType)
if (err != nil) != tt.wantErr {
t.Errorf("RemoveObjects() error = %v, wantErr %v", err, tt.wantErr)
return
}
})
}
}
type db struct { type db struct {
mock sqlmock.Sqlmock mock sqlmock.Sqlmock
db *sql.DB db *sql.DB

View File

@ -21,10 +21,21 @@ type Storage interface {
type ObjectType int32 type ObjectType int32
const ( const (
ObjectTypeUserAvatar = iota ObjectTypeUserAvatar ObjectType = iota
ObjectTypeStyling ObjectTypeStyling
) )
func (o ObjectType) String() string {
switch o {
case ObjectTypeUserAvatar:
return "0"
case ObjectTypeStyling:
return "1"
default:
return ""
}
}
type Asset struct { type Asset struct {
InstanceID string InstanceID string
ResourceOwner string ResourceOwner string