github.com/0chain/gosdk@v1.17.11/zboxcore/allocationchange/moveobject.go (about)

     1  package allocationchange
     2  
     3  import (
     4  	"path"
     5  	"strings"
     6  
     7  	"github.com/0chain/errors"
     8  	"github.com/0chain/gosdk/core/common"
     9  	"github.com/0chain/gosdk/core/pathutil"
    10  	"github.com/0chain/gosdk/core/util"
    11  	"github.com/0chain/gosdk/zboxcore/fileref"
    12  	"github.com/google/uuid"
    13  )
    14  
    15  type MoveFileChange struct {
    16  	change
    17  	ObjectTree fileref.RefEntity
    18  	DestPath   string
    19  	Uuid       uuid.UUID
    20  }
    21  
    22  func (ch *MoveFileChange) ProcessChange(rootRef *fileref.Ref, fileIDMeta map[string]string) (err error) {
    23  	oldParentPath, oldFileName := pathutil.Split(ch.ObjectTree.GetPath())
    24  	fields, err := common.GetPathFields(oldParentPath)
    25  	if err != nil {
    26  		return
    27  	}
    28  
    29  	delRef := rootRef
    30  	for i := 0; i < len(fields); i++ {
    31  		found := false
    32  		for _, child := range delRef.Children {
    33  			if child.GetName() == fields[i] {
    34  				delRef = child.(*fileref.Ref)
    35  				delRef.HashToBeComputed = true
    36  				found = true
    37  				break
    38  			}
    39  		}
    40  
    41  		if !found {
    42  			err = errors.New("invalid_reference_path", "Ref not found in root reference object")
    43  			return
    44  		}
    45  	}
    46  
    47  	var removed bool
    48  	for i, child := range delRef.Children {
    49  		if child.GetName() == oldFileName {
    50  			delRef.RemoveChild(i)
    51  			removed = true
    52  			break
    53  		}
    54  	}
    55  
    56  	if !removed {
    57  		err = errors.New("incomplete_move", "could not remove ref from source path")
    58  		return
    59  	}
    60  
    61  	fields, err = common.GetPathFields(ch.DestPath)
    62  	if err != nil {
    63  		return
    64  	}
    65  	rootRef.HashToBeComputed = true
    66  	dirRef := rootRef
    67  	for i := 0; i < len(fields); i++ {
    68  		found := false
    69  		for _, child := range dirRef.Children {
    70  			if child.GetName() == fields[i] {
    71  				if child.GetType() != fileref.DIRECTORY {
    72  					err = errors.New("invalid_reference_path", "Invalid reference path from the blobber")
    73  					return
    74  				}
    75  				dirRef = child.(*fileref.Ref)
    76  				found = true
    77  				break
    78  			}
    79  		}
    80  
    81  		if !found {
    82  			uid := util.GetSHA1Uuid(ch.Uuid, fields[i])
    83  			ch.Uuid = uid
    84  			newRef := &fileref.Ref{
    85  				Type:         fileref.DIRECTORY,
    86  				AllocationID: dirRef.AllocationID,
    87  				Path:         path.Join("/", strings.Join(fields[:i+1], "/")),
    88  				Name:         fields[i],
    89  				FileID:       uid.String(),
    90  			}
    91  			fileIDMeta[newRef.Path] = newRef.FileID
    92  			dirRef.AddChild(newRef)
    93  			dirRef = newRef
    94  		}
    95  		dirRef.HashToBeComputed = true
    96  	}
    97  
    98  	if dirRef.GetPath() != ch.DestPath || dirRef.GetType() != fileref.DIRECTORY {
    99  		err = errors.New("file_not_found", "Object to move not found in blobber")
   100  		return
   101  	}
   102  
   103  	var affectedRef *fileref.Ref
   104  	if ch.ObjectTree.GetType() == fileref.FILE {
   105  		affectedRef = &(ch.ObjectTree.(*fileref.FileRef)).Ref
   106  	} else {
   107  		affectedRef = ch.ObjectTree.(*fileref.Ref)
   108  	}
   109  
   110  	affectedRef.Path = pathutil.Join(dirRef.GetPath(), affectedRef.Name)
   111  	ch.processChildren(affectedRef)
   112  
   113  	dirRef.AddChild(ch.ObjectTree)
   114  
   115  	return
   116  }
   117  
   118  func (ch *MoveFileChange) processChildren(curRef *fileref.Ref) {
   119  	for _, childRefEntity := range curRef.Children {
   120  		var childRef *fileref.Ref
   121  		if childRefEntity.GetType() == fileref.FILE {
   122  			childRef = &(childRefEntity.(*fileref.FileRef)).Ref
   123  		} else {
   124  			childRef = childRefEntity.(*fileref.Ref)
   125  		}
   126  		childRef.Path = pathutil.Join(curRef.Path, childRef.Name)
   127  		if childRefEntity.GetType() == fileref.DIRECTORY {
   128  			ch.processChildren(childRef)
   129  		}
   130  	}
   131  	curRef.HashToBeComputed = true
   132  	curRef.ChildrenLoaded = true
   133  }
   134  
   135  func (n *MoveFileChange) GetAffectedPath() []string {
   136  	return []string{n.DestPath, pathutil.Dir(n.ObjectTree.GetPath())}
   137  }
   138  
   139  func (n *MoveFileChange) GetSize() int64 {
   140  	return 0
   141  }