Compare commits

..

6 Commits

Author SHA1 Message Date
c84f94372e workaround for cache invalidation 2021-08-16 22:40:10 +02:00
65739c9307 createDir cache fix 2021-08-16 22:16:42 +02:00
c20748aef1 added createDir mutation 2021-08-16 19:57:48 +02:00
6e323a0e4f invalidate cache on move mutation 2021-08-16 14:58:03 +02:00
3c8ece72cc move mutation dest dir fix 2021-08-16 02:04:44 +02:00
72901e4685 copy mutation in dir fix 2021-08-16 01:40:01 +02:00
3 changed files with 92 additions and 1 deletions

View File

@@ -6,6 +6,7 @@ import (
"path/filepath"
"github.com/graph-gophers/dataloader"
log "github.com/sirupsen/logrus"
)
func invalidateCache(ctx context.Context, id string) error {
@@ -14,10 +15,15 @@ func invalidateCache(ctx context.Context, id string) error {
return fmt.Errorf("Failed to get loader from context")
}
log.Debug("Invalidate cache for id: ", id)
loader["getFile"].Clear(ctx, dataloader.StringKey(id))
loader["listObjects"].Clear(ctx, dataloader.StringKey(id))
loader["getFiles"].Clear(ctx, dataloader.StringKey(getPathFromId(id)))
// FIXME: this is the only way i can invalidate the cache without it breaking stuff
// loader["listObjects"].Clear(ctx, dataloader.StringKey(id))
loader["listObjects"].ClearAll()
return nil
}
@@ -30,3 +36,24 @@ func getPathFromId(id string) string {
return dir + "/"
}
func getFilenameFromID(id string) string {
return filepath.Base(id)
}
func invalidateCacheForDir(ctx context.Context, path string) error {
loader, ok := ctx.Value("loader").(map[string]*dataloader.Loader)
if !ok {
return fmt.Errorf("Failed to get loader from context")
}
log.Debug("Invalidate cache for dir: ", path)
// FIXME: only clear required ids
loader["getFile"].ClearAll()
loader["listObjects"].ClearAll()
loader["getFiles"].ClearAll()
loader["getDirs"].ClearAll()
return nil
}

View File

@@ -3,6 +3,7 @@ package s3browser
import (
"context"
"fmt"
"strings"
"github.com/minio/minio-go/v7"
)
@@ -33,6 +34,13 @@ func copyMutation(ctx context.Context, src, dest string) (*File, error) {
return nil, fmt.Errorf("Failed to get s3Client from context")
}
// Check if dest is a file or a dir
if strings.HasSuffix(dest, "/") {
// create new dest id
// TODO: What if a file with this id already exists?
dest += getFilenameFromID(src)
}
info, err := s3Client.CopyObject(ctx, minio.CopyDestOptions{
Bucket: bucketName,
Object: dest,
@@ -62,6 +70,13 @@ func moveMutation(ctx context.Context, src, dest string) (*File, error) {
return nil, fmt.Errorf("Failed to get s3Client from context")
}
// Check if dest is a file or a dir
if strings.HasSuffix(dest, "/") {
// create new dest id
// TODO: What if a file with this id already exists?
dest += getFilenameFromID(src)
}
// There is no (spoon) move. Only copy and delete
info, err := s3Client.CopyObject(ctx, minio.CopyDestOptions{
Bucket: bucketName,
@@ -81,8 +96,39 @@ func moveMutation(ctx context.Context, src, dest string) (*File, error) {
return nil, err
}
invalidateCache(ctx, info.Key)
return &File{
ID: info.Key,
}, nil
}
func createDirectory(ctx context.Context, path string) (*Directory, error) {
s3Client, ok := ctx.Value("s3Client").(*minio.Client)
if !ok {
return nil, fmt.Errorf("Failed to get s3Client from context")
}
if !strings.HasSuffix(path, "/") {
path += "/"
}
info, err := s3Client.PutObject(ctx, bucketName, path, strings.NewReader(""), 0, minio.PutObjectOptions{
ContentType: "application/x-directory",
})
if err != nil {
return nil, err
}
// Invalidate cache
// TODO: check error
invalidateCacheForDir(ctx, info.Key)
return &Directory{
ID: info.Key,
}, nil
}

View File

@@ -146,6 +146,24 @@ func graphqlSchema() (graphql.Schema, error) {
return moveMutation(p.Context, src, dest)
},
},
"createDir": &graphql.Field{
Type: graphql.NewNonNull(graphqlDirType),
Args: graphql.FieldConfigArgument{
"path": &graphql.ArgumentConfig{
Type: graphql.NewNonNull(graphql.ID),
},
},
Resolve: func(p graphql.ResolveParams) (interface{}, error) {
path, ok := p.Args["path"].(string)
if !ok {
return nil, fmt.Errorf("Failed to parse args")
}
log.Debug("mutation 'createDir': ", path)
return createDirectory(p.Context, path)
},
},
}
rootQuery := graphql.ObjectConfig{