Skip to content

Commit 37e5a5a

Browse files
Enhance file path handling in DbfDbCommand and add tests for filename variations (#264)
* Enhance file path handling in DbfDbCommand and add tests for filename variations * Improve error message for invalid command text and enhance filename parsing tests
1 parent 64bf868 commit 37e5a5a

File tree

4 files changed

+79
-17
lines changed

4 files changed

+79
-17
lines changed

src/DbfDataReader/DbfDbCommand.cs

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -61,14 +61,33 @@ protected override DbDataReader ExecuteDbDataReader(CommandBehavior behavior)
6161
}
6262

6363
var fileName = QueryParser.Parse(CommandText);
64+
var filePath = GetFilePath(folder, fileName);
65+
66+
var options = dbfDbConnection.Options;
67+
return new DbfDataReader(filePath, options);
68+
}
69+
70+
private static string GetFilePath(string folder, string fileName)
71+
{
6472
var filePath = Path.Combine(folder, $"{fileName}");
65-
if (!File.Exists(filePath))
73+
if (File.Exists(filePath))
74+
{
75+
return filePath;
76+
}
77+
78+
filePath = Path.ChangeExtension(filePath, ".dbf");
79+
if (File.Exists(filePath))
6680
{
67-
throw new FileNotFoundException(filePath);
81+
return filePath;
6882
}
6983

70-
var options = dbfDbConnection.Options;
71-
return new DbfDataReader(filePath, options);
84+
filePath = Path.ChangeExtension(filePath, ".DBF");
85+
if (File.Exists(filePath))
86+
{
87+
return filePath;
88+
}
89+
90+
throw new FileNotFoundException(filePath);
7291
}
7392
}
7493
}

src/DbfDataReader/QueryParser.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ internal static string Parse(string commandText)
2323
var match = FileNameRegex.Match(commandText);
2424
if (!match.Success)
2525
{
26-
throw new ArgumentException("The command text must be in the format 'SELECT * FROM <FILENAME>'.", nameof(commandText));
26+
throw new ArgumentException($"Invalid command text: '{commandText}'. Must be in the format 'SELECT * FROM <FILENAME>'.", nameof(commandText));
2727
}
2828

2929
return match.Groups["FileName"].Value;

test/DbfDataReader.Tests/DbfDbConnectionTests.cs

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,5 +53,31 @@ public async Task Should_skip_deleted_rows()
5353
}
5454

5555
rowCount.ShouldBe(12);
56+
}
57+
58+
[Theory]
59+
[InlineData("dbase_03")]
60+
[InlineData("dbase_03.dbf")]
61+
[InlineData("dbase_03.DBF")]
62+
public async Task Should_read_file(string filename)
63+
{
64+
var dbConnection = new DbfDbConnection();
65+
dbConnection.ConnectionString = $"Folder={FolderPath};Encoding=ascii;SkipDeletedRecords=false";
66+
dbConnection.Open();
67+
68+
var dbCommand = dbConnection.CreateCommand();
69+
dbCommand.CommandText = $"select * from {filename};";
70+
71+
var rowCount = 0;
72+
var reader = await dbCommand.ExecuteReaderAsync();
73+
while (await reader.ReadAsync())
74+
{
75+
rowCount++;
76+
77+
_ = reader.GetString(0);
78+
_ = reader.GetDecimal(10);
79+
}
80+
81+
rowCount.ShouldBe(14);
5682
}
5783
}

test/DbfDataReader.Tests/QueryParserTests.cs

Lines changed: 29 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using System;
2+
using System.IO;
23
using Bogus;
34
using Shouldly;
45
using Xunit;
@@ -7,49 +8,65 @@ namespace DbfDataReader.Tests;
78

89
public class QueryParserTests
910
{
11+
private readonly string _fileName;
12+
public QueryParserTests()
13+
{
14+
var faker = new Faker();
15+
var fileName = faker.System.FileName("dbf");
16+
_fileName = fileName.Replace("&", "_and_");
17+
}
18+
19+
[Fact]
20+
public void Should_parse_filename_without_extension()
21+
{
22+
// Arrange
23+
var fileNameWithoutExtension = Path.GetFileNameWithoutExtension(_fileName);
24+
var query = $"select * from {fileNameWithoutExtension}";
25+
26+
// Act
27+
var result = QueryParser.Parse(query);
28+
29+
// Assert
30+
result.ShouldBe(fileNameWithoutExtension);
31+
}
32+
1033
[Fact]
1134
public void Should_parse_lowercase_query()
1235
{
1336
// Arrange
14-
var faker = new Faker();
15-
var fileName = $"{faker.System.FileName()}.dbf";
16-
var query = $"select * from {fileName}";
37+
var query = $"select * from {_fileName}";
1738

1839
// Act
1940
var result = QueryParser.Parse(query);
2041

2142
// Assert
22-
result.ShouldBe(fileName);
43+
result.ShouldBe(_fileName);
2344
}
2445

2546
[Fact]
2647
public void Should_parse_uppercase_query()
2748
{
2849
// Arrange
29-
var faker = new Faker();
30-
var fileName = $"{faker.System.FileName()}.dbf".ToUpper();
31-
var query = $"SELECT * FROM {fileName}";
50+
var query = $"SELECT * FROM {_fileName}";
3251

3352
// Act
3453
var result = QueryParser.Parse(query);
3554

3655
// Assert
37-
result.ShouldBe(fileName);
56+
result.ShouldBe(_fileName);
3857
}
3958

4059
[Fact]
4160
public void Should_parse_mixed_case_query()
4261
{
4362
// Arrange
44-
var faker = new Faker();
45-
var fileName = $"{faker.System.FileName()}.dbf";
46-
var query = $"SELECT * from {fileName}";
63+
var query = $"SELECT * from {_fileName}";
4764

4865
// Act
4966
var result = QueryParser.Parse(query);
5067

5168
// Assert
52-
result.ShouldBe(fileName);
69+
result.ShouldBe(_fileName);
5370
}
5471

5572
[Fact]

0 commit comments

Comments
 (0)