Skip to content

Commit

Permalink
Add support for file which are named after the end of the period of d…
Browse files Browse the repository at this point in the history
…ata they contain
  • Loading branch information
Apollo3zehn committed Aug 26, 2024
1 parent 4b51555 commit a9a36ce
Show file tree
Hide file tree
Showing 8 changed files with 58 additions and 9 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,4 @@ These tests cover all cases for file/folder structures which contain files with
| M | datetime file with random start time | 00:00:00 | 01:00:00 | x |
| N | date folder, time file | 12:00:00 | 06:00:00 | |
| O | datetime file with random start time and interval exceeding end | 00:00:00 | 01:00:00 | x |
| P | datetime file with file name offset | 00:00:00 | 00:10:00 | |
26 changes: 17 additions & 9 deletions src/Nexus.Sources.StructuredFile/StructuredFileDataSource.cs
Original file line number Diff line number Diff line change
Expand Up @@ -582,7 +582,8 @@ protected abstract Task ReadAsync(
? DateTime.SpecifyKind(begin.Add(fileSource.UtcOffset), DateTimeKind.Local)
: throw new ArgumentException("The begin parameter must of kind UTC.");

var localFileBegin = localBegin.RoundDown(fileSource.FilePeriod);
var localFileBegin = localBegin
.RoundDown(fileSource.FilePeriod);

var folderNames = fileSource
.PathSegments
Expand Down Expand Up @@ -652,6 +653,10 @@ protected abstract Task ReadAsync(

else
{
/* correct local file begin */
if (fileSource.FileNameOffset != TimeSpan.Zero)
localFileBegin = localFileBegin.Add(fileSource.FileNameOffset);

var folderPath = Path.Combine(folderNameArray);
var fileName = localFileBegin.ToString(fileSource.FileTemplate);

Expand Down Expand Up @@ -981,7 +986,7 @@ internal static bool TryGetFileBeginByPath(
CustomDateTimeOffset folderBegin = default)
{
var fileName = Path.GetFileName(filePath);
bool isSuccess;
bool success;

if (TryGetFileBeginByName_AnyKind(fileName, fileSource, out fileBegin))
{
Expand All @@ -991,7 +996,7 @@ internal static bool TryGetFileBeginByPath(
// date+time: use file date/time
if (fileBegin.DateTime.Date != default)
{
isSuccess = true;
success = true;
}

// time-only: use combined folder and file date/time
Expand All @@ -1004,7 +1009,7 @@ internal static bool TryGetFileBeginByPath(
new DateTime(folderBegin.DateTime.Date.Ticks + fileBegin.DateTime.TimeOfDay.Ticks),
fileBegin.Offset);

isSuccess = true;
success = true;
}

// long way
Expand All @@ -1016,7 +1021,7 @@ internal static bool TryGetFileBeginByPath(
new DateTime(folderBegin.DateTime.Ticks + fileBegin.DateTime.TimeOfDay.Ticks),
fileBegin.Offset);

isSuccess = folderBegin != default;
success = folderBegin != default;
}
}

Expand All @@ -1027,7 +1032,7 @@ internal static bool TryGetFileBeginByPath(
if (folderBegin != default)
{
fileBegin = folderBegin;
isSuccess = true;
success = true;
}

// long way
Expand All @@ -1036,18 +1041,21 @@ internal static bool TryGetFileBeginByPath(
folderBegin = GetFolderBegin_AnyKind(filePath, fileSource);

fileBegin = folderBegin;
isSuccess = folderBegin != default;
success = folderBegin != default;
}
}

if (success && fileSource.FileNameOffset != TimeSpan.Zero)
fileBegin = new CustomDateTimeOffset(fileBegin.DateTime - fileSource.FileNameOffset, fileBegin.Offset);
}

// no date + no time: failed
else
{
isSuccess = false;
success = false;
}

return isSuccess;
return success;
}

private static CustomDateTimeOffset GetFolderBegin_AnyKind(string filePath, FileSource fileSource)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ namespace Nexus.Sources;
/// <param name="FileDateTimePreselector">An optional regular expression to select only relevant parts of a file name (e.g. to select the date/time and a unqiue identifier in case there is more than one kind of file in the same folder). In case of a file named 20200101_13_my-id_1234.dat the preselector could be like "(.{11})_my-id". It is also required for file names containing an opaque string that changes for every file.</param>
/// <param name="FileDateTimeSelector">An optional date/time selector which is mandatory when the preselector is provided. In case of a file named like "20200101_13_my-id_1234.dat", and a preselector of "(.{11})_my-id", the selector should be like "yyyyMMdd_HH".</param>
/// <param name="FilePeriod">The period per file.</param>
/// <param name="FileNameOffset">The file name offset of the file data. This is useful for files that are named according to the end date of the data they contain.</param>
/// <param name="UtcOffset">The UTC offset of the file data.</param>
/// <param name="IrregularTimeInterval">The file time interval is irregular. I.e. the file end is not aligned to multiples of the file period.</param>
/// <param name="AdditionalProperties">Additional properties to be used by the data source implementation.</param>
Expand All @@ -23,6 +24,7 @@ public record FileSource(
string? FileDateTimePreselector,
string? FileDateTimeSelector,
TimeSpan FilePeriod,
TimeSpan FileNameOffset,
TimeSpan UtcOffset,
bool IrregularTimeInterval,
JsonElement? AdditionalProperties
Expand Down
Empty file.
Empty file.
15 changes: 15 additions & 0 deletions tests/Nexus.Sources.StructuredFile.Tests/DATABASES/P/config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"/A/B/C": {
"default": [
{
"PathSegments": [
"'DATA'"
],
"FileTemplate": "yyyy-MM-ddTHH-mm-ssZ'.dat'",
"FilePeriod": "00:10:00",
"UtcOffset": "00:00:00",
"FileNameOffset": "00:10:00"
}
]
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@ public async Task CanProvideFirstFile()
[InlineData("DATABASES/M", "2020-01-01T01-35-23Z", "2020-01-01T05-00-00Z")]
[InlineData("DATABASES/N", "2019-12-31T12-00-00Z", "2020-01-03T12-00-00Z")]
[InlineData("DATABASES/O", "2020-01-01T00-35-23Z", "2020-01-01T01-00-10Z")]
[InlineData("DATABASES/P", "2020-01-01T00-00-00Z", "2020-01-01T00-20-00Z")]
public async Task CanProvideTimeRange(string root, string expectedBeginString, string expectedEndString)
{
var expectedBegin = DateTime.ParseExact(expectedBeginString, "yyyy-MM-ddTHH-mm-ssZ", null, DateTimeStyles.AdjustToUniversal);
Expand Down Expand Up @@ -152,6 +153,7 @@ public async Task CanProvideTimeRange(string root, string expectedBeginString, s
[InlineData("DATABASES/M", "2020-01-01T00-00-00Z", "2020-01-02T00-00-00Z", 4 / 24.0, 3)]
[InlineData("DATABASES/N", "2020-01-01T00-00-00Z", "2020-01-03T00-00-00Z", 7 / 8.0, 2)]
[InlineData("DATABASES/O", "2020-01-01T00-00-00Z", "2020-01-02T00-00-00Z", 3 / 288.0, 4)]
[InlineData("DATABASES/P", "2020-01-01T00-00-00Z", "2020-01-02T00-00-00Z", 2 / 144.0, 4)]
public async Task CanProvideAvailability(string root, string beginString, string endString, double expected, int precision)
{
// Arrange
Expand Down Expand Up @@ -297,6 +299,7 @@ await Assert.ThrowsAsync<ArgumentException>(() =>
[InlineData("M", "2020-01-01T00:00:00Z", "2020-01-02T00:00:00Z")]
[InlineData("N", "2020-01-01T00:00:00Z", "2020-01-04T00:00:00Z")]
[InlineData("O", "2020-01-01T00:00:00Z", "2020-01-02T00:00:00Z")]
[InlineData("P", "2020-01-01T00:00:00Z", "2020-01-02T00:00:00Z")]
public async Task CanRead_ReadInfos(string database, string beginString, string endString)
{
// Arrange
Expand Down
20 changes: 20 additions & 0 deletions tests/Nexus.Sources.StructuredFile.Tests/expected/P.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
[
{
"BufferOffset": 0,
"FilePath": "/debug/DATABASES/P/DATA/2020-01-01T00-10-00Z.dat",
"FileSource": null,
"RegularFileBegin": "2020-01-01T00:00:00Z",
"FileOffset": 0,
"FileBlock": 600,
"FileLength": 600
},
{
"BufferOffset": 600,
"FilePath": "/debug/DATABASES/P/DATA/2020-01-01T00-20-00Z.dat",
"FileSource": null,
"RegularFileBegin": "2020-01-01T00:10:00Z",
"FileOffset": 0,
"FileBlock": 600,
"FileLength": 600
}
]

0 comments on commit a9a36ce

Please sign in to comment.