Update the object with the contents of the io.Reader, modTime and size If existing is set then it updates the object rather than creating a new one. The new object may have been created if an error is returned
(ctx context.Context, in io.Reader, src fs.ObjectInfo, options ...fs.OpenOption)
| 1172 | // |
| 1173 | // The new object may have been created if an error is returned |
| 1174 | func (o *Object) Update(ctx context.Context, in io.Reader, src fs.ObjectInfo, options ...fs.OpenOption) (err error) { |
| 1175 | size := src.Size() |
| 1176 | if size < 0 { |
| 1177 | return errors.New("mega backend can't upload a file of unknown length") |
| 1178 | } |
| 1179 | //modTime := src.ModTime(ctx) |
| 1180 | remote := o.Remote() |
| 1181 | |
| 1182 | // Create the parent directory |
| 1183 | dirNode, leaf, err := o.fs.mkdirParent(ctx, remote) |
| 1184 | if err != nil { |
| 1185 | return fmt.Errorf("update make parent dir failed: %w", err) |
| 1186 | } |
| 1187 | |
| 1188 | var u *mega.Upload |
| 1189 | err = o.fs.pacer.Call(func() (bool, error) { |
| 1190 | u, err = o.fs.srv.NewUpload(dirNode, o.fs.opt.Enc.FromStandardName(leaf), size) |
| 1191 | return shouldRetry(ctx, err) |
| 1192 | }) |
| 1193 | if err != nil { |
| 1194 | return fmt.Errorf("upload file failed to create session: %w", err) |
| 1195 | } |
| 1196 | |
| 1197 | // Upload the chunks |
| 1198 | // FIXME do this in parallel |
| 1199 | for id := range u.Chunks() { |
| 1200 | _, chunkSize, err := u.ChunkLocation(id) |
| 1201 | if err != nil { |
| 1202 | return fmt.Errorf("upload failed to read chunk location: %w", err) |
| 1203 | } |
| 1204 | chunk := make([]byte, chunkSize) |
| 1205 | _, err = io.ReadFull(in, chunk) |
| 1206 | if err != nil { |
| 1207 | return fmt.Errorf("upload failed to read data: %w", err) |
| 1208 | } |
| 1209 | |
| 1210 | err = o.fs.pacer.Call(func() (bool, error) { |
| 1211 | err = u.UploadChunk(id, chunk) |
| 1212 | return shouldRetry(ctx, err) |
| 1213 | }) |
| 1214 | if err != nil { |
| 1215 | return fmt.Errorf("upload file failed to upload chunk: %w", err) |
| 1216 | } |
| 1217 | } |
| 1218 | |
| 1219 | // Finish the upload |
| 1220 | var info *mega.Node |
| 1221 | err = o.fs.pacer.Call(func() (bool, error) { |
| 1222 | info, err = u.Finish() |
| 1223 | return shouldRetry(ctx, err) |
| 1224 | }) |
| 1225 | if err != nil { |
| 1226 | return fmt.Errorf("failed to finish upload: %w", err) |
| 1227 | } |
| 1228 | |
| 1229 | // If the upload succeeded and the original object existed, then delete it |
| 1230 | if o.info != nil { |
| 1231 | err = o.fs.deleteNode(ctx, o.info) |
nothing calls this directly
no test coverage detected