Skip to content

Commit

Permalink
Added a rename callback to directory copying
Browse files Browse the repository at this point in the history
  • Loading branch information
Animagne committed Nov 15, 2023
1 parent e586da0 commit 90b7cbb
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 10 deletions.
22 changes: 14 additions & 8 deletions storage/core/src/server/ServerStorage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -192,14 +192,11 @@ export abstract class ServerStorage
private async copyObjectWithKey(
sourceStorage: ServerStorage,
sourceReference: ObjectReference,
targetDirectory: BaseDirectory
targetReference: ObjectReference
): Promise<string> {
const newTaskKey = this.buildTaskKey(sourceReference);
try {
await this.copyObject(sourceStorage, sourceReference, {
...sourceReference,
baseDirectory: targetDirectory.baseDirectory,
});
await this.copyObject(sourceStorage, sourceReference, targetReference);
return newTaskKey;
} catch (error) {
throw { key: newTaskKey, error };
Expand All @@ -213,6 +210,8 @@ export abstract class ServerStorage
* @param {BaseDirectory} targetDirectory base directory in the target storage.
* @param {Function} predicate optional predicate to filter objects to copy. If not specified, all
* objects from the sourceDirectory will be copied.
* @param {Function} renameCallback optional callback to rename objects as they are copied. If
* specified, targetDirectory argument will be ignored.
* @returns {Promise<void>}
* @note This uses server-side copying. Cross-region copy support depends on the storage provider.
*/
Expand All @@ -221,6 +220,7 @@ export abstract class ServerStorage
sourceDirectory: BaseDirectory,
targetDirectory: BaseDirectory,
predicate?: (objectReference: ObjectReference) => boolean,
renameCallback?: (objectReference: ObjectReference) => ObjectReference,
copyOptions: CopyOptions = {
maxPageSize: 100,
maxConcurrency: 50,
Expand All @@ -243,15 +243,21 @@ export abstract class ServerStorage
}
};

for await (const object of this.listObjectsFiltered(
for await (const sourceReference of this.listObjectsFiltered(
sourceStorage,
sourceDirectory,
copyOptions.maxPageSize,
predicate
)) {
const targetReference = renameCallback
? renameCallback(sourceReference)
: {
...sourceReference,
baseDirectory: targetDirectory.baseDirectory,
};
taskMap.set(
this.buildTaskKey(object),
this.copyObjectWithKey(sourceStorage, object, targetDirectory)
this.buildTaskKey(sourceReference),
this.copyObjectWithKey(sourceStorage, sourceReference, targetReference)
);
if (taskMap.size >= copyOptions.maxConcurrency) {
await handleSingleTask();
Expand Down
24 changes: 22 additions & 2 deletions tests/backend-storage/src/common-tests/ServerStorage.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -892,6 +892,7 @@ describe(`${ServerStorage.name}: ${serverStorage.constructor.name}`, () => {
sourceTestDirectory.baseDirectory,
targetTestDirectory.baseDirectory,
undefined,
undefined,
{ maxConcurrency: 3, maxPageSize: 5, continueOnError: true }
);

Expand Down Expand Up @@ -934,6 +935,7 @@ describe(`${ServerStorage.name}: ${serverStorage.constructor.name}`, () => {
sourceTestDirectory.baseDirectory,
targetTestDirectory.baseDirectory,
undefined,
undefined,
{ maxConcurrency: 3, maxPageSize: 5, continueOnError: true }
);

Expand Down Expand Up @@ -977,15 +979,21 @@ describe(`${ServerStorage.name}: ${serverStorage.constructor.name}`, () => {
targetTestDirectory.baseDirectory,
(object) =>
object.objectName === sourceReference1.objectName ||
object.objectName === sourceReference3.objectName
object.objectName === sourceReference3.objectName,
(object: ObjectReference) => {
return {
...targetTestDirectory.baseDirectory,
objectName: `2-${object.objectName}`,
};
}
);

await expect(
serverStorage.objectExists({
...targetTestDirectory.baseDirectory,
objectName: sourceReference1.objectName,
})
).to.eventually.be.true;
).to.eventually.be.false;
await expect(
serverStorage.objectExists({
...targetTestDirectory.baseDirectory,
Expand All @@ -997,6 +1005,18 @@ describe(`${ServerStorage.name}: ${serverStorage.constructor.name}`, () => {
...targetTestDirectory.baseDirectory,
objectName: sourceReference3.objectName,
})
).to.eventually.be.false;
await expect(
serverStorage.objectExists({
...targetTestDirectory.baseDirectory,
objectName: `2-${sourceReference1.objectName}`,
})
).to.eventually.be.true;
await expect(
serverStorage.objectExists({
...targetTestDirectory.baseDirectory,
objectName: `2-${sourceReference3.objectName}`,
})
).to.eventually.be.true;
});
});
Expand Down

0 comments on commit 90b7cbb

Please sign in to comment.