Skip to content

Commit

Permalink
Merge pull request #312 from FoundatioFx/bugfix/delete-files-wildcard
Browse files Browse the repository at this point in the history
Storage bug fixes with DeleteFilesAsync
  • Loading branch information
niemyjski authored Sep 25, 2024
2 parents f161567 + 29d112d commit 4f6cca6
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 20 deletions.
40 changes: 26 additions & 14 deletions src/Foundatio.TestHarness/Storage/FileStorageTestsBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ public virtual async Task CanGetEmptyFileListOnMissingDirectoryAsync()

using (storage)
{
Assert.Empty(await storage.GetFileListAsync(Guid.NewGuid() + "\\*"));
Assert.Empty(await storage.GetFileListAsync($"{Guid.NewGuid()}\\*"));
}
}

Expand Down Expand Up @@ -283,11 +283,12 @@ public virtual async Task CanDeleteEntireFolderAsync()

using (storage)
{
await storage.SaveFileAsync(@"x\README", "hello");
await storage.SaveFileAsync(@"x\hello.txt", "hello");
await storage.SaveFileAsync(@"x\nested\world.csv", "nested world");
Assert.Equal(2, (await storage.GetFileListAsync()).Count);
Assert.Equal(3, (await storage.GetFileListAsync()).Count);

await storage.DeleteFilesAsync(@"x\*");
Assert.Equal(3, await storage.DeleteFilesAsync(@"x\*"));
Assert.Empty(await storage.GetFileListAsync());
}
}
Expand All @@ -304,13 +305,14 @@ public virtual async Task CanDeleteEntireFolderWithWildcardAsync()
{
await storage.SaveFileAsync(@"x\hello.txt", "hello");
await storage.SaveFileAsync(@"x\nested\world.csv", "nested world");
Assert.Equal(2, (await storage.GetFileListAsync()).Count);
await storage.SaveFileAsync(@"x\nested\docs\README", "manual");
Assert.Single(await storage.GetFileListAsync(limit: 1));
Assert.Equal(2, (await storage.GetFileListAsync(@"x\*")).Count);
Assert.Single(await storage.GetFileListAsync(@"x\nested\*"));

await storage.DeleteFilesAsync(@"x\*");
Assert.Equal(3, (await storage.GetFileListAsync()).Count);
Assert.Equal(3, (await storage.GetFileListAsync(@"x\*")).Count);
Assert.Equal(2, (await storage.GetFileListAsync(@"x\nested\*")).Count);
Assert.Single(await storage.GetFileListAsync(@"x\nested\docs\*"));

Assert.Equal(3, await storage.DeleteFilesAsync(@"x\*"));
Assert.Empty(await storage.GetFileListAsync());
}
}
Expand Down Expand Up @@ -388,20 +390,30 @@ public virtual async Task CanDeleteNestedFolderAsync()
using (storage)
{
await storage.SaveFileAsync(@"x\hello.txt", "hello");
await storage.SaveFileAsync(@"x\nested\world.csv", "nested world");
await storage.SaveFileAsync(@"x\nested\hello.txt", "nested hello");
Assert.Equal(3, (await storage.GetFileListAsync()).Count);
await storage.SaveFileAsync(@"x\nested\world.csv", "nested world");
await storage.SaveFileAsync(@"x\nested\docs\README", "README");
await storage.SaveFileAsync(@"x\nested\media\README", "README");
Assert.Equal(5, (await storage.GetFileListAsync()).Count);
Assert.Single(await storage.GetFileListAsync(limit: 1));
Assert.Equal(3, (await storage.GetFileListAsync(@"x\*")).Count);
Assert.Equal(2, (await storage.GetFileListAsync(@"x\nested\*")).Count);
Assert.Equal(5, (await storage.GetFileListAsync(@"x\*")).Count);
Assert.Equal(4, (await storage.GetFileListAsync(@"x\nested\*")).Count);
Assert.Equal(2, (await storage.GetFileListAsync(@"x\*.txt")).Count);

await storage.DeleteFilesAsync(@"x\nested\*");
Assert.Equal(1, await storage.DeleteFilesAsync(@"x\nested\docs\"));
Assert.Equal(1, await storage.DeleteFilesAsync(@"x\nested\media"));
Assert.Equal(2, await storage.DeleteFilesAsync(@"x\nested\*"));

Assert.Single(await storage.GetFileListAsync());
Assert.True(await storage.ExistsAsync(@"x\hello.txt"));
Assert.False(await storage.ExistsAsync(@"x\nested\hello.txt"));
Assert.False(await storage.ExistsAsync(@"x\nested\world.csv"));
Assert.False(await storage.ExistsAsync(@"x\nested\docs\README"));
Assert.False(await storage.ExistsAsync(@"x\nested\media\README"));

Assert.Equal(1, await storage.DeleteFilesAsync(@"x\hello*"));
Assert.Empty(await storage.GetFileListAsync());
Assert.False(await storage.ExistsAsync(@"x\hello.txt"));
}
}

Expand All @@ -426,7 +438,7 @@ public virtual async Task CanDeleteSpecificFilesInNestedFolderAsync()
Assert.Equal(3, (await storage.GetFileListAsync(@"x\nested\*")).Count);
Assert.Equal(3, (await storage.GetFileListAsync(@"x\*.txt")).Count);

await storage.DeleteFilesAsync(@"x\nested\*.txt");
Assert.Equal(2, await storage.DeleteFilesAsync(@"x\nested\*.txt"));

Assert.Equal(3, (await storage.GetFileListAsync()).Count);
Assert.True(await storage.ExistsAsync(@"x\hello.txt"));
Expand Down
8 changes: 4 additions & 4 deletions src/Foundatio/Storage/FolderFileStorage.cs
Original file line number Diff line number Diff line change
Expand Up @@ -239,7 +239,7 @@ public Task<int> DeleteFilesAsync(string searchPattern = null, CancellationToken
if (Directory.Exists(Folder))
{
_logger.LogInformation("Deleting {Directory} directory", Folder);
count += Directory.EnumerateFiles(Folder, "*,*", SearchOption.AllDirectories).Count();
count += Directory.EnumerateFiles(Folder, "*.*", SearchOption.AllDirectories).Count();
Directory.Delete(Folder, true);
_logger.LogTrace("Finished deleting {Directory} directory with {FileCount} files", Folder, count);
}
Expand All @@ -249,13 +249,13 @@ public Task<int> DeleteFilesAsync(string searchPattern = null, CancellationToken

searchPattern = searchPattern.NormalizePath();
string path = Path.Combine(Folder, searchPattern);
if (path[path.Length - 1] == Path.DirectorySeparatorChar || path.EndsWith(Path.DirectorySeparatorChar + "*"))
if (path[path.Length - 1] == Path.DirectorySeparatorChar || path.EndsWith($"{Path.DirectorySeparatorChar}*"))
{
string directory = Path.GetDirectoryName(path);
if (Directory.Exists(directory))
{
_logger.LogInformation("Deleting {Directory} directory", directory);
count += Directory.EnumerateFiles(directory, "*,*", SearchOption.AllDirectories).Count();
count += Directory.EnumerateFiles(directory, "*.*", SearchOption.AllDirectories).Count();
Directory.Delete(directory, true);
_logger.LogTrace("Finished deleting {Directory} directory with {FileCount} files", directory, count);
return Task.FromResult(count);
Expand All @@ -267,7 +267,7 @@ public Task<int> DeleteFilesAsync(string searchPattern = null, CancellationToken
if (Directory.Exists(path))
{
_logger.LogInformation("Deleting {Directory} directory", path);
count += Directory.EnumerateFiles(path, "*,*", SearchOption.AllDirectories).Count();
count += Directory.EnumerateFiles(path, "*.*", SearchOption.AllDirectories).Count();
Directory.Delete(path, true);
_logger.LogTrace("Finished deleting {Directory} directory with {FileCount} files", path, count);
return Task.FromResult(count);
Expand Down
3 changes: 1 addition & 2 deletions src/Foundatio/Storage/InMemoryFileStorage.cs
Original file line number Diff line number Diff line change
Expand Up @@ -228,11 +228,10 @@ public Task<int> DeleteFilesAsync(string searchPattern = null, CancellationToken

if (searchPattern[searchPattern.Length - 1] == Path.DirectorySeparatorChar)
searchPattern = $"{searchPattern}*";
else if (!searchPattern.EndsWith(Path.DirectorySeparatorChar + "*") && !Path.HasExtension(searchPattern))
else if (!searchPattern.EndsWith("*") && !Path.HasExtension(searchPattern))
searchPattern = Path.Combine(searchPattern, "*");

var regex = new Regex($"^{Regex.Escape(searchPattern).Replace("\\*", ".*?")}$");

var keys = _storage.Keys.Where(k => regex.IsMatch(k)).Select(k => _storage[k].Spec).ToList();

_logger.LogInformation("Deleting {FileCount} files matching {SearchPattern} (Regex={SearchPatternRegex})", keys.Count, searchPattern, regex);
Expand Down

0 comments on commit 4f6cca6

Please sign in to comment.