Skip to content

Commit

Permalink
Allow setting of arbitrary metadata, minor bug fixes (#764)
Browse files Browse the repository at this point in the history
  • Loading branch information
ishank011 authored May 20, 2020
1 parent dac884c commit fbf3d95
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 29 deletions.
2 changes: 1 addition & 1 deletion internal/grpc/services/gateway/storageprovider.go
Original file line number Diff line number Diff line change
Expand Up @@ -1209,7 +1209,7 @@ func (s *svc) getPath(ctx context.Context, ref *provider.Reference) (string, err
return ref.GetPath(), nil
}

if ref.GetId() != nil {
if ref.GetId() != nil && ref.GetId().GetOpaqueId() != "" {
req := &provider.StatRequest{Ref: ref}
res, err := s.stat(ctx, req)
if err != nil {
Expand Down
20 changes: 16 additions & 4 deletions pkg/storage/fs/local/db.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ func initializeDB(root string) (*sql.DB, error) {
return nil, errors.Wrap(err, "localfs: error executing create statement")
}

stmt, err = db.Prepare("CREATE TABLE IF NOT EXISTS metadata (resource TEXT PRIMARY KEY, etag TEXT DEFAULT '')")
stmt, err = db.Prepare("CREATE TABLE IF NOT EXISTS metadata (resource TEXT, key TEXT, value TEXT, PRIMARY KEY (resource, key))")
if err != nil {
return nil, errors.Wrap(err, "localfs: error preparing statement")
}
Expand Down Expand Up @@ -164,18 +164,30 @@ func (fs *localfs) removeFromFavoritesDB(ctx context.Context, resource, grantee
return nil
}

func (fs *localfs) addToEtagDB(ctx context.Context, resource, etag string) error {
stmt, err := fs.db.Prepare("INSERT INTO metadata (resource, etag) VALUES (?, ?) ON CONFLICT(resource) DO UPDATE SET etag=?")
func (fs *localfs) addToMetadataDB(ctx context.Context, resource, key, value string) error {
stmt, err := fs.db.Prepare("INSERT INTO metadata (resource, key, value) VALUES (?, ?, ?) ON CONFLICT(resource, key) DO UPDATE SET value=?")
if err != nil {
return errors.Wrap(err, "localfs: error preparing statement")
}
_, err = stmt.Exec(resource, etag, etag)
_, err = stmt.Exec(resource, key, value, value)
if err != nil {
return errors.Wrap(err, "localfs: error executing insert statement")
}
return nil
}

func (fs *localfs) removeFromMetadataDB(ctx context.Context, resource, key string) error {
stmt, err := fs.db.Prepare("DELETE FROM metadata WHERE resource=? AND key=?")
if err != nil {
return errors.Wrap(err, "localfs: error preparing statement")
}
_, err = stmt.Exec(resource, key)
if err != nil {
return errors.Wrap(err, "localfs: error executing delete statement")
}
return nil
}

func (fs *localfs) addToReferencesDB(ctx context.Context, resource, target string) error {
stmt, err := fs.db.Prepare("INSERT INTO share_references (resource, target) VALUES (?, ?) ON CONFLICT(resource) DO UPDATE SET target=?")
if err != nil {
Expand Down
67 changes: 43 additions & 24 deletions pkg/storage/fs/local/local.go
Original file line number Diff line number Diff line change
Expand Up @@ -517,31 +517,41 @@ func (fs *localfs) SetArbitraryMetadata(ctx context.Context, ref *provider.Refer
} else {
return errors.Wrap(err, "could not parse mtime")
}
delete(md.Metadata, "mtime")
}

if _, ok := md.Metadata["etag"]; ok {
etag := calcEtag(ctx, fi)
if etag != md.Metadata["etag"] {
err = fs.addToEtagDB(ctx, np, etag)
err = fs.addToMetadataDB(ctx, np, "etag", etag)
if err != nil {
return errors.Wrap(err, "localfs: error adding entry to DB")
}
}
delete(md.Metadata, "etag")
}

if _, ok := md.Metadata["favorite"]; ok {
if u, err := getUser(ctx); err != nil {
if uid := u.GetId(); uid != nil {
usr := fmt.Sprintf("u:%s@%s", uid.GetOpaqueId(), uid.GetIdp())
if err = fs.addToFavoritesDB(ctx, np, usr); err != nil {
return errors.Wrap(err, "localfs: error adding entry to DB")
}
} else {
return errors.Wrap(errtypes.UserRequired("userrequired"), "user has no id")
u, err := getUser(ctx)
if err != nil {
return err
}
if uid := u.GetId(); uid != nil {
usr := fmt.Sprintf("u:%s@%s", uid.GetOpaqueId(), uid.GetIdp())
if err = fs.addToFavoritesDB(ctx, np, usr); err != nil {
return errors.Wrap(err, "localfs: error adding entry to DB")
}
} else {
return err
return errors.Wrap(errtypes.UserRequired("userrequired"), "user has no id")
}
delete(md.Metadata, "favorite")
}
}

for k, v := range md.Metadata {
err = fs.addToMetadataDB(ctx, np, k, v)
if err != nil {
return errors.Wrap(err, "localfs: error adding entry to DB")
}
}

Expand Down Expand Up @@ -587,20 +597,27 @@ func (fs *localfs) UnsetArbitraryMetadata(ctx context.Context, ref *provider.Ref
for _, k := range keys {
switch k {
case "favorite":
if u, err := getUser(ctx); err != nil {
if uid := u.GetId(); uid != nil {
usr := fmt.Sprintf("u:%s@%s", uid.GetOpaqueId(), uid.GetIdp())
if err = fs.removeFromFavoritesDB(ctx, np, usr); err != nil {
return errors.Wrap(err, "localfs: error removing entry from DB")
}
} else {
return errors.Wrap(errtypes.UserRequired("userrequired"), "user has no id")
u, err := getUser(ctx)
if err != nil {
return err
}
if uid := u.GetId(); uid != nil {
usr := fmt.Sprintf("u:%s@%s", uid.GetOpaqueId(), uid.GetIdp())
if err = fs.removeFromFavoritesDB(ctx, np, usr); err != nil {
return errors.Wrap(err, "localfs: error removing entry from DB")
}
} else {
return err
return errors.Wrap(errtypes.UserRequired("userrequired"), "user has no id")
}
case "etag":
return errors.Wrap(errtypes.NotSupported("unsetting etag not supported"), "could not unset metadata")
case "mtime":
return errors.Wrap(errtypes.NotSupported("unsetting mtime not supported"), "could not unset metadata")
default:
return errors.Wrap(errtypes.NotSupported("metadata not supported"), "could not unset metadata")
err = fs.removeFromMetadataDB(ctx, np, k)
if err != nil {
return errors.Wrap(err, "localfs: error adding entry to DB")
}
}
}

Expand Down Expand Up @@ -707,7 +724,7 @@ func (fs *localfs) Delete(ctx context.Context, ref *provider.Reference) error {
return errors.Wrap(err, "localfs: error adding entry to DB")
}

return fs.propagate(ctx, path.Dir(fn))
return fs.propagate(ctx, path.Dir(fp))
}

func (fs *localfs) Move(ctx context.Context, oldRef, newRef *provider.Reference) error {
Expand Down Expand Up @@ -974,7 +991,7 @@ func (fs *localfs) DownloadRevision(ctx context.Context, ref *provider.Reference
}

versionsDir := fs.wrapVersions(ctx, np)
vp := path.Join(versionsDir, fmt.Sprintf(".v%s", revisionKey))
vp := path.Join(versionsDir, revisionKey)

r, err := os.Open(vp)
if err != nil {
Expand All @@ -998,7 +1015,8 @@ func (fs *localfs) RestoreRevision(ctx context.Context, ref *provider.Reference,
}

versionsDir := fs.wrapVersions(ctx, np)
vp := path.Join(versionsDir, fmt.Sprintf(".v%s", revisionKey))
vp := path.Join(versionsDir, revisionKey)
np = fs.wrap(ctx, np)

// check revision exists
vs, err := os.Stat(vp)
Expand Down Expand Up @@ -1110,8 +1128,9 @@ func (fs *localfs) RestoreRecycleItem(ctx context.Context, restoreKey string) er
} else {
originalPath = fs.wrap(ctx, filePath)
}

if _, err = os.Stat(originalPath); err == nil {
return errors.Wrap(err, "localfs: can't restore - file already exists at original path")
return errors.New("localfs: can't restore - file already exists at original path")
}

rp := fs.wrapRecycleBin(ctx, restoreKey)
Expand Down

0 comments on commit fbf3d95

Please sign in to comment.