diff --git a/internal/gql/mutations.go b/internal/gql/mutations.go index ca64d0e..7fcd1f5 100644 --- a/internal/gql/mutations.go +++ b/internal/gql/mutations.go @@ -74,7 +74,58 @@ func copyMutation(ctx context.Context, src, dest types.ID) (*types.File, error) } -func moveMutation(ctx context.Context, src, dest types.ID) (*types.File, error) { +func moveDirMutation(ctx context.Context, src, dest types.ID) ([]*types.File, error) { + s3Client, ok := ctx.Value("s3Client").(*minio.Client) + + if !ok { + return nil, fmt.Errorf("Failed to get s3Client from context") + } + + if !dest.IsDirectory() { + return nil, fmt.Errorf("Dest must be a directory") + } + + loader, ok := ctx.Value("loader").(*loader.Loader) + + // "move" all file inside dir + files, err := loader.GetFilesRecursive(ctx, src) + if err != nil { + return nil, err + } + + var result []*types.File + parent := src.Parent() + + for _, file := range files { + newID := types.ID{ + Bucket: dest.Bucket, + Key: strings.Replace(file.ID.Key, parent.Key, dest.Key, 1), + } + newID.Normalize() + + _, err := s3Client.CopyObject(ctx, minio.CopyDestOptions{ + Bucket: dest.Bucket, + Object: newID.Key, + }, minio.CopySrcOptions{ + Bucket: file.ID.Bucket, + Object: file.ID.Key, + }) + + if err != nil { + // TODO: handle error + } + + deleteMutation(ctx, file.ID) + + result = append(result, &types.File{ + ID: newID, + }) + } + + return result, nil +} + +func moveFileMutation(ctx context.Context, src, dest types.ID) (*types.File, error) { s3Client, ok := ctx.Value("s3Client").(*minio.Client) if !ok { diff --git a/internal/gql/schema.go b/internal/gql/schema.go index 1cba1fe..3e4b75a 100644 --- a/internal/gql/schema.go +++ b/internal/gql/schema.go @@ -166,7 +166,7 @@ func GraphqlSchema() (graphql.Schema, error) { }, }, "move": &graphql.Field{ - Type: graphqlFileType, + Type: graphql.NewNonNull(graphqlFileType), Args: graphql.FieldConfigArgument{ "src": &graphql.ArgumentConfig{ Type: graphql.NewNonNull(objIDType), @@ -191,7 +191,36 @@ func GraphqlSchema() (graphql.Schema, error) { log.Debug("mutation 'move': ", src, "-->", dest) - return moveMutation(p.Context, *src, *dest) + return moveFileMutation(p.Context, *src, *dest) + }, + }, + "moveDir": &graphql.Field{ + Type: graphql.NewNonNull(graphql.NewList(graphqlFileType)), + Args: graphql.FieldConfigArgument{ + "src": &graphql.ArgumentConfig{ + Type: graphql.NewNonNull(objIDType), + }, + "dest": &graphql.ArgumentConfig{ + Type: graphql.NewNonNull(objIDType), + }, + }, + Resolve: func(p graphql.ResolveParams) (interface{}, error) { + if !helper.IsAuthenticated(p.Context) { + return nil, s3errors.ErrNotAuthenticated + } + + src, ok := p.Args["src"].(*types.ID) + if !ok { + return nil, fmt.Errorf("Failed to parse args") + } + dest, ok := p.Args["dest"].(*types.ID) + if !ok { + return nil, fmt.Errorf("Failed to parse args") + } + + log.Debug("mutation 'moveDir': ", src, "-->", dest) + + return moveDirMutation(p.Context, *src, *dest) }, }, "createDir": &graphql.Field{