b2: implement SetModTime #3210

SetModTime() is implemented by copying an object onto itself and
updating the metadata in the process.
This commit is contained in:
Nick Craig-Wood 2019-05-24 16:07:22 +01:00
parent a5bed67016
commit 22368b997c
2 changed files with 52 additions and 22 deletions

View File

@ -1206,17 +1206,8 @@ func (o *Object) decodeMetaDataFileInfo(info *api.FileInfo) (err error) {
return o.decodeMetaDataRaw(info.ID, info.SHA1, info.Size, info.UploadTimestamp, info.Info, info.ContentType) return o.decodeMetaDataRaw(info.ID, info.SHA1, info.Size, info.UploadTimestamp, info.Info, info.ContentType)
} }
// readMetaData gets the metadata if it hasn't already been fetched // getMetaData gets the metadata from the object unconditionally
// func (o *Object) getMetaData() (info *api.File, err error) {
// Sets
// o.id
// o.modTime
// o.size
// o.sha1
func (o *Object) readMetaData() (err error) {
if o.id != "" {
return nil
}
maxSearched := 1 maxSearched := 1
var timestamp api.Timestamp var timestamp api.Timestamp
baseRemote := o.remote baseRemote := o.remote
@ -1224,7 +1215,6 @@ func (o *Object) readMetaData() (err error) {
timestamp, baseRemote = api.RemoveVersion(baseRemote) timestamp, baseRemote = api.RemoveVersion(baseRemote)
maxSearched = maxVersions maxSearched = maxVersions
} }
var info *api.File
err = o.fs.list("", true, baseRemote, maxSearched, o.fs.opt.Versions, func(remote string, object *api.File, isDirectory bool) error { err = o.fs.list("", true, baseRemote, maxSearched, o.fs.opt.Versions, func(remote string, object *api.File, isDirectory bool) error {
if isDirectory { if isDirectory {
return nil return nil
@ -1239,12 +1229,30 @@ func (o *Object) readMetaData() (err error) {
}) })
if err != nil { if err != nil {
if err == fs.ErrorDirNotFound { if err == fs.ErrorDirNotFound {
return fs.ErrorObjectNotFound return nil, fs.ErrorObjectNotFound
} }
return err return nil, err
} }
if info == nil { if info == nil {
return fs.ErrorObjectNotFound return nil, fs.ErrorObjectNotFound
}
return info, nil
}
// readMetaData gets the metadata if it hasn't already been fetched
//
// Sets
// o.id
// o.modTime
// o.size
// o.sha1
func (o *Object) readMetaData() (err error) {
if o.id != "" {
return nil
}
info, err := o.getMetaData()
if err != nil {
return err
} }
return o.decodeMetaData(info) return o.decodeMetaData(info)
} }
@ -1283,10 +1291,33 @@ func (o *Object) ModTime() (result time.Time) {
return o.modTime return o.modTime
} }
// SetModTime sets the modification time of the local fs object // SetModTime sets the modification time of the Object
func (o *Object) SetModTime(modTime time.Time) error { func (o *Object) SetModTime(modTime time.Time) error {
// Not possible with B2 info, err := o.getMetaData()
return fs.ErrorCantSetModTime if err != nil {
return err
}
info.Info[timeKey] = timeString(modTime)
opts := rest.Opts{
Method: "POST",
Path: "/b2_copy_file",
}
var request = api.CopyFileRequest{
SourceID: o.id,
Name: o.fs.root + o.remote, // copy to same name
MetadataDirective: "REPLACE",
ContentType: info.ContentType,
Info: info.Info,
}
var response api.FileInfo
err = o.fs.pacer.Call(func() (bool, error) {
resp, err := o.fs.srv.CallJSON(&opts, &request, &response)
return o.fs.shouldRetry(resp, err)
})
if err != nil {
return err
}
return o.decodeMetaDataFileInfo(&response)
} }
// Storable returns if this object is storable // Storable returns if this object is storable

View File

@ -124,10 +124,9 @@ The modified time is stored as metadata on the object as
in the Backblaze standard. Other tools should be able to use this as in the Backblaze standard. Other tools should be able to use this as
a modified time. a modified time.
Modified times are used in syncing and are fully supported except in Modified times are used in syncing and are fully supported. Note that
the case of updating a modification time on an existing object. In if a modification time needs to be updated on an object then it will
this case the object will be uploaded again as B2 doesn't have an API create a new version of the object.
method to set the modification time independent of doing an upload.
### SHA1 checksums ### ### SHA1 checksums ###