Skip to content

Commit

Permalink
Adding support for deleting files/folders, renaming files/folders to sdk
Browse files Browse the repository at this point in the history
  • Loading branch information
sarath-ambati committed Jul 24, 2019
1 parent 18d2350 commit d83b66f
Show file tree
Hide file tree
Showing 14 changed files with 475 additions and 81 deletions.
1 change: 1 addition & 0 deletions zboxcore/allocationchange/change.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ const (
INSERT_OPERATION = "insert"
DELETE_OPERATION = "delete"
UPDATE_OPERATION = "update"
RENAME_OPERATION = "rename"
)

type change struct {
Expand Down
15 changes: 8 additions & 7 deletions zboxcore/allocationchange/deletefile.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,12 @@ import (

type DeleteFileChange struct {
change
File *fileref.FileRef
//File *fileref.FileRef
ObjectTree fileref.RefEntity
}

func (ch *DeleteFileChange) ProcessChange(rootRef *fileref.Ref) error {
path, _ := filepath.Split(ch.File.Path)
path, _ := filepath.Split(ch.ObjectTree.GetPath())
tSubDirs := getSubDirs(path)
dirRef := rootRef
treelevel := 0
Expand All @@ -36,7 +37,7 @@ func (ch *DeleteFileChange) ProcessChange(rootRef *fileref.Ref) error {
}
idx := -1
for i, child := range dirRef.Children {
if child.GetType() == fileref.FILE && child.GetHash() == ch.File.Hash {
if child.GetName() == ch.ObjectTree.GetName() && child.GetHash() == ch.ObjectTree.GetHash() {
idx = i
break
}
Expand All @@ -51,15 +52,15 @@ func (ch *DeleteFileChange) ProcessChange(rootRef *fileref.Ref) error {
}

func (n *DeleteFileChange) GetAffectedPath() string {
if n.File != nil {
return n.File.Path
if n.ObjectTree != nil {
return n.ObjectTree.GetPath()
}
return ""
}

func (n *DeleteFileChange) GetSize() int64 {
if n.File != nil {
return 0 - (n.File.Size + n.File.ThumbnailSize)
if n.ObjectTree != nil {
return 0 - n.ObjectTree.GetSize()
}
return int64(0)
}
2 changes: 1 addition & 1 deletion zboxcore/allocationchange/newfile.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ func (n *NewFileChange) GetAffectedPath() string {

func (n *NewFileChange) GetSize() int64 {
if n.File != nil {
return n.File.Size + n.File.ThumbnailSize
return n.File.Size
}
return int64(0)
}
94 changes: 94 additions & 0 deletions zboxcore/allocationchange/renameobject.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
package allocationchange

import (
"path/filepath"

"github.com/0chain/gosdk/core/common"
"github.com/0chain/gosdk/zboxcore/fileref"
)

type RenameFileChange struct {
change
ObjectTree fileref.RefEntity
NewName string
}

func (ch *RenameFileChange) ProcessChange(rootRef *fileref.Ref) error {
path, _ := filepath.Split(ch.ObjectTree.GetPath())
tSubDirs := getSubDirs(path)
dirRef := rootRef
treelevel := 0
for treelevel < len(tSubDirs) {
found := false
for _, child := range dirRef.Children {
if child.GetType() == fileref.DIRECTORY && treelevel < len(tSubDirs) {
if (child.(*fileref.Ref)).Name == tSubDirs[treelevel] {
dirRef = child.(*fileref.Ref)
found = true
break
}
}
}
if found {
treelevel++
} else {
return common.NewError("invalid_reference_path", "Invalid reference path from the blobber")
}
}
idx := -1
for i, child := range dirRef.Children {
if child.GetPath() == ch.ObjectTree.GetPath() && child.GetHash() == ch.ObjectTree.GetHash() {
idx = i
break
}
}
if idx < 0 {
return common.NewError("file_not_found", "File to update not found in blobber")
}
dirRef.Children[idx] = ch.ObjectTree
// Logger.Info("Old name: " + dirRef.Children[idx].GetName())
var affectedRef *fileref.Ref
if ch.ObjectTree.GetType() == fileref.FILE {
affectedRef = &(ch.ObjectTree.(*fileref.FileRef)).Ref
} else {
affectedRef = ch.ObjectTree.(*fileref.Ref)
}

path, _ = filepath.Split(affectedRef.Path)
path = filepath.Clean(path)
affectedRef.Name = ch.NewName
affectedRef.Path = filepath.Join(path, ch.NewName)

// Logger.Info("Changed name: " + dirRef.Children[idx].GetName())

ch.processChildren(affectedRef)
// Logger.Info("Process hash for renaming")
rootRef.CalculateHash()
return nil
}

func (ch *RenameFileChange) processChildren(curRef *fileref.Ref) {
for _, childRefEntity := range curRef.Children {
var childRef *fileref.Ref
if childRefEntity.GetType() == fileref.FILE {
childRef = &(childRefEntity.(*fileref.FileRef)).Ref
} else {
childRef = childRefEntity.(*fileref.Ref)
}
childRef.Path = filepath.Join(curRef.Path, childRef.Name)
if childRefEntity.GetType() == fileref.DIRECTORY {
ch.processChildren(childRef)
}
}
}

func (n *RenameFileChange) GetAffectedPath() string {
if n.ObjectTree != nil {
return n.ObjectTree.GetPath()
}
return ""
}

func (n *RenameFileChange) GetSize() int64 {
return int64(0)
}
2 changes: 1 addition & 1 deletion zboxcore/allocationchange/updatefile.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ func (n *UpdateFileChange) GetAffectedPath() string {

func (n *UpdateFileChange) GetSize() int64 {
if n.NewFile != nil && n.OldFile != nil {
return (n.NewFile.Size + n.NewFile.ThumbnailSize) - (n.OldFile.ThumbnailSize + n.OldFile.Size)
return n.NewFile.Size - n.OldFile.Size
}
return int64(0)
}
45 changes: 31 additions & 14 deletions zboxcore/fileref/fileref.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ type FileRef struct {
Ref `json:",squash"`
CustomMeta string `json:"custom_meta"`
ContentHash string `json:"content_hash"`
Size int64 `json:"size"`
MerkleRoot string `json:"merkle_root"`
ThumbnailSize int64 `json:"thumbnail_size"`
ThumbnailHash string `json:"thumbnail_hash"`
Expand All @@ -33,6 +32,7 @@ type FileRef struct {

type RefEntity interface {
GetNumBlocks() int64
GetSize() int64
GetHash() string
CalculateHash() string
GetType() string
Expand All @@ -43,43 +43,52 @@ type RefEntity interface {
}

type Ref struct {
Type string `json:"type"`
AllocationID string `json:"allocation_id"`
Name string `json:"name"`
Path string `json:"path"`
Hash string `json:"hash"`
NumBlocks int64 `json:"num_of_blocks"`
PathHash string `json:"path_hash"`
LookupHash string `json:"lookup_hash"`
Children []RefEntity `json:"-"`
Type string `json:"type"`
AllocationID string `json:"allocation_id"`
Name string `json:"name"`
Path string `json:"path"`
Size int64 `json:"size"`
Hash string `json:"hash"`
NumBlocks int64 `json:"num_of_blocks"`
PathHash string `json:"path_hash"`
LookupHash string `json:"lookup_hash"`
childrenLoaded bool
Children []RefEntity `json:"-"`
}

func GetReferenceLookup(allocationID string, path string) string {
return encryption.Hash(allocationID + ":" + path)
}

func (r *Ref) CalculateHash() string {
if len(r.Children) == 0 {
if len(r.Children) == 0 && !r.childrenLoaded {
return r.Hash
}
sort.SliceStable(r.Children, func(i, j int) bool {
return strings.Compare(GetReferenceLookup(r.AllocationID, r.Children[i].GetPath()), GetReferenceLookup(r.AllocationID, r.Children[j].GetPath())) == -1
})
for _, childRef := range r.Children {
childRef.CalculateHash()
}
childHashes := make([]string, len(r.Children))
childPathHashes := make([]string, len(r.Children))
var refNumBlocks int64
var size int64
for index, childRef := range r.Children {
childHashes[index] = childRef.GetHash()
childPathHashes[index] = childRef.GetPathHash()
refNumBlocks += childRef.GetNumBlocks()
size += childRef.GetSize()
}
// fmt.Println("ref name and path, hash :" + r.Name + " " + r.Path + " " + r.Hash)
// fmt.Println("ref hash data: " + strings.Join(childHashes, ":"))
r.Hash = encryption.Hash(strings.Join(childHashes, ":"))
//fmt.Println("ref hash : " + r.Hash)
// fmt.Println("ref hash : " + r.Hash)
r.NumBlocks = refNumBlocks
r.Size = size
//fmt.Println("Ref Path hash: " + strings.Join(childPathHashes, ":"))
r.PathHash = encryption.Hash(strings.Join(childPathHashes, ":"))

return r.Hash
}

Expand All @@ -95,6 +104,10 @@ func (r *Ref) GetNumBlocks() int64 {
return r.NumBlocks
}

func (r *Ref) GetSize() int64 {
return r.Size
}

func (r *Ref) GetPathHash() string {
return r.PathHash
}
Expand All @@ -119,7 +132,7 @@ func (r *Ref) AddChild(child RefEntity) {
sort.SliceStable(r.Children, func(i, j int) bool {
return strings.Compare(GetReferenceLookup(r.AllocationID, r.Children[i].GetPath()), GetReferenceLookup(r.AllocationID, r.Children[j].GetPath())) == -1
})

r.childrenLoaded = true
}

func (r *Ref) RemoveChild(idx int) {
Expand Down Expand Up @@ -154,7 +167,7 @@ func (fr *FileRef) CalculateHash() string {
// fmt.Println("fileref name , path, hash", fr.Name, fr.Path, fr.Hash)
// fmt.Println("Fileref hash data: " + fr.GetHashData())
fr.Hash = encryption.Hash(fr.GetHashData())
//fmt.Println("Fileref hash : " + fr.Hash)
// fmt.Println("Fileref hash : " + fr.Hash)
fr.NumBlocks = int64(math.Ceil(float64(fr.Size*1.0) / CHUNK_SIZE))
fr.PathHash = GetReferenceLookup(fr.AllocationID, fr.Path)
return fr.Hash
Expand All @@ -168,6 +181,10 @@ func (fr *FileRef) GetNumBlocks() int64 {
return fr.NumBlocks
}

func (fr *FileRef) GetSize() int64 {
return fr.Size
}

func (fr *FileRef) GetPathHash() string {
return fr.PathHash
}
Expand Down
25 changes: 25 additions & 0 deletions zboxcore/fileref/refpath.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,31 @@ type ReferencePath struct {
List []*ReferencePath `json:"list,omitempty"`
}

func (rp *ReferencePath) GetRefFromObjectTree(allocationID string) (RefEntity, error) {
reftype := rp.Meta["type"].(string)
if reftype == FILE {
rootRef := &FileRef{}
rootRef.Type = FILE
rootRef.AllocationID = allocationID
var md mapstructure.Metadata
config := &mapstructure.DecoderConfig{
Metadata: &md,
Result: rootRef,
TagName: "json",
}
decoder, err := mapstructure.NewDecoder(config)
if err != nil {
return nil, err
}
err = decoder.Decode(rp.Meta)
if err != nil {
return nil, err
}
return rootRef, nil
}
return rp.GetDirTree(allocationID)
}

func (rp *ReferencePath) GetDirTree(allocationID string) (*Ref, error) {
reftype := rp.Meta["type"].(string)
if reftype == DIRECTORY {
Expand Down
27 changes: 27 additions & 0 deletions zboxcore/sdk/allocation.go
Original file line number Diff line number Diff line change
Expand Up @@ -420,6 +420,33 @@ func (a *Allocation) DeleteFile(path string) error {
return err
}

func (a *Allocation) RenameObject(path string, destName string) error {
if !a.isInitialized() {
return notInitialized
}
if len(path) == 0 {
return common.NewError("invalid_path", "Invalid path for the list")
}
path = filepath.Clean(path)
isabs := filepath.IsAbs(path)
if !isabs {
return common.NewError("invalid_path", "Path should be valid and absolute")
}

req := &RenameRequest{}
req.blobbers = a.Blobbers
req.allocationID = a.ID
req.newName = destName
req.consensusThresh = (float32(a.DataShards) * 100) / float32(a.DataShards+a.ParityShards)
req.fullconsensus = float32(a.DataShards + a.ParityShards)
req.ctx = a.ctx
req.remotefilepath = path
req.renameMask = 0
req.connectionID = zboxutil.NewConnectionId()
err := req.ProcessRename()
return err
}

func (a *Allocation) GetAuthTicketForShare(path string, filename string, referenceType string, refereeClientID string) (string, error) {
if !a.isInitialized() {
return "", notInitialized
Expand Down
13 changes: 7 additions & 6 deletions zboxcore/sdk/commitworker.go
Original file line number Diff line number Diff line change
Expand Up @@ -112,25 +112,25 @@ func (commitreq *CommitRequest) processCommit() {
ctx, cncl := context.WithTimeout(context.Background(), (time.Second * 30))
err = zboxutil.HttpDo(ctx, cncl, req, func(resp *http.Response, err error) error {
if err != nil {
Logger.Error("List:", err)
Logger.Error("Ref path error:", err)
return err
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
Logger.Error("List response : ", resp.StatusCode)
Logger.Error("Ref path response : ", resp.StatusCode)
}
resp_body, err := ioutil.ReadAll(resp.Body)
if err != nil {
Logger.Error("List: Resp", err)
Logger.Error("Ref path: Resp", err)
return err
}
if resp.StatusCode != http.StatusOK {
return fmt.Errorf("List error response: Status: %d - %s ", resp.StatusCode, string(resp_body))
return fmt.Errorf("Reference path error response: Status: %d - %s ", resp.StatusCode, string(resp_body))
} else {
//Logger.Info("Reference path:", string(resp_body))
err = json.Unmarshal(resp_body, &lR)
if err != nil {
Logger.Error("List json decode error: ", err)
Logger.Error("Reference path json decode error: ", err)
return err
}
}
Expand All @@ -154,7 +154,7 @@ func (commitreq *CommitRequest) processCommit() {
rootRef.CalculateHash()
prevAllocationRoot := encryption.Hash(rootRef.Hash + ":" + strconv.FormatInt(lR.LatestWM.Timestamp, 10))
if prevAllocationRoot != lR.LatestWM.AllocationRoot {
commitreq.result = ErrorCommitResult("Allocation root from latest writemarker mismatch")
commitreq.result = ErrorCommitResult("Allocation root from latest writemarker mismatch. Expected: " + prevAllocationRoot + " got: " + lR.LatestWM.AllocationRoot)
commitreq.wg.Done()
return
}
Expand Down Expand Up @@ -225,6 +225,7 @@ func (req *CommitRequest) commitBlobber(rootRef *fileref.Ref, latestWM *marker.W
}
httpreq.Header.Add("Content-Type", formWriter.FormDataContentType())
ctx, cncl := context.WithTimeout(context.Background(), (time.Second * 60))
Logger.Info("Committing to blobber." + req.blobber.Baseurl)
err = zboxutil.HttpDo(ctx, cncl, httpreq, func(resp *http.Response, err error) error {
if err != nil {
Logger.Error("Commit: ", err)
Expand Down
Loading

0 comments on commit d83b66f

Please sign in to comment.