Skip to content

Commit

Permalink
Made things compile and added more tests
Browse files Browse the repository at this point in the history
  • Loading branch information
Stephan Møller committed Mar 14, 2024
1 parent 73033d2 commit afb1d19
Show file tree
Hide file tree
Showing 8 changed files with 200 additions and 154 deletions.
8 changes: 4 additions & 4 deletions Readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ new RowbotExecutorBuilder()

// Async version
await new RowbotAsyncExecutorBuilder()
.FromObjects(myObjects)
.FromObjects(myObjectsAsAsyncEnumerable)
.ToExcel(filepath: "c:\\temp\\result.xlsx", sheetName: "Sheet1", writeHeaders: true)
.ExecuteAsync();
```
Expand All @@ -47,7 +47,7 @@ new RowbotExecutorBuilder()

// Async version
await new RowbotAsyncExecutorBuilder()
.FromObjects(myObjects)
.FromObjects(myObjectsAsAsyncEnumerable)
.ToCsvUsingCsvHelper(filepath: "c:\\temp\\output.csv", config: new CsvConfiguration(CultureInfo.InvariantCulture), writeHeaders: true)
.ExecuteAsync();
```
Expand All @@ -62,7 +62,7 @@ new RowbotExecutorBuilder()

// Async version
await new RowbotAsyncExecutorBuilder()
.FromObjects(myObjects)
.FromObjects(myObjectsAsAsyncEnumerable)
.ToExcel(filepath: "c:\\temp\\output.xlsx", sheetName: "MySheet", writeHeaders: true)
.ExecuteAsync();
```
Expand All @@ -77,7 +77,7 @@ new RowbotExecutorBuilder()

// Async version
await new RowbotAsyncExecutorBuilder()
.FromDataTable(myDataTable)
.FromDataTable(myObjectsAsAsyncEnumerable)
.ToCsvUsingCsvHelper(filepath: "c:\\temp\\output.csv", config: new CsvConfiguration(CultureInfo.InvariantCulture), writeHeaders: true)
.ExecuteAsync();
```
Expand Down
27 changes: 14 additions & 13 deletions examples/Examples.SimpleDemos/Examples.SimpleDemos.csproj
Original file line number Diff line number Diff line change
@@ -1,19 +1,20 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Dapper" Version="2.0.123" />
<PackageReference Include="System.Data.SqlClient" Version="4.8.6" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Dapper" Version="2.0.123"/>
<PackageReference Include="System.Data.SqlClient" Version="4.8.6"/>
<PackageReference Include="System.Linq.Async" Version="6.0.1"/>
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\..\src\Rowbot\Rowbot.csproj" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\src\Rowbot\Rowbot.csproj"/>
</ItemGroup>

</Project>
49 changes: 27 additions & 22 deletions examples/Examples.SimpleDemos/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,14 @@ namespace Examples.SimpleDemos
{
internal class Program
{
public class FooType
{
}

static async Task Main(string[] args)
{
var myObjects = Enumerable.Range(0, 10).Select(num => num);
var myObjects = Enumerable.Range(0, 10).Select(num => new FooType());
var myObjectsAsAsyncEnumerable = AsyncEnumerable.Range(0, 10).Select(num => new FooType());
DataTable myDataTable = new DataTable();
string myConnectionString = "...";

Expand All @@ -25,36 +30,36 @@ static async Task Main(string[] args)
.FromObjects(myObjects)
.ToExcel(filepath: "c:\\temp\\result.xlsx", sheetName: "Sheet1", writeHeaders: true)
.Execute();

// Async version
await new RowbotAsyncExecutorBuilder()
.FromObjects(myObjects)
.FromObjects(myObjectsAsAsyncEnumerable)
.ToExcel(filepath: "c:\\temp\\result.xlsx", sheetName: "Sheet1", writeHeaders: true)
.ExecuteAsync();

// Objects => Csv (Space complexity: O(1))
// Sync version
new RowbotExecutorBuilder()
.FromObjects(myObjects)
.ToCsvUsingCsvHelper(filepath: "c:\\temp\\output.csv", config: new CsvConfiguration(CultureInfo.InvariantCulture), writeHeaders: true)
.Execute();
// Async version
await new RowbotAsyncExecutorBuilder()
.FromObjects(myObjects)

// Async version
await new RowbotAsyncExecutorBuilder()
.FromObjects(myObjectsAsAsyncEnumerable)
.ToCsvUsingCsvHelper(filepath: "c:\\temp\\output.csv", config: new CsvConfiguration(CultureInfo.InvariantCulture), writeHeaders: true)
.ExecuteAsync();

// DataTable => Excel (Space complexity: O(1))
// Sync version
new RowbotExecutorBuilder()
.FromObjects(myObjects)
.ToExcel(filepath: "c:\\temp\\output.xlsx", sheetName: "MySheet", writeHeaders: true)
.Execute();

// Async version
await new RowbotAsyncExecutorBuilder()
.FromObjects(myObjects)
.FromObjects(myObjectsAsAsyncEnumerable)
.ToExcel(filepath: "c:\\temp\\output.xlsx", sheetName: "MySheet", writeHeaders: true)
.ExecuteAsync();

Expand All @@ -64,7 +69,7 @@ static async Task Main(string[] args)
.FromDataTable(myDataTable)
.ToCsvUsingCsvHelper(filepath: "c:\\temp\\output.csv", config: new CsvConfiguration(CultureInfo.InvariantCulture), writeHeaders: true)
.Execute();

// Async version
await new RowbotAsyncExecutorBuilder()
.FromDataTable(myDataTable)
Expand All @@ -77,7 +82,7 @@ static async Task Main(string[] args)
using (var conn = new SqlConnection(myConnectionString))
{
conn.Open();
var dataReader = conn.ExecuteReader("SELECT * FROM Orders WHERE CustomerId = @customerId", new { customerId = 123 });
var dataReader = conn.ExecuteReader("SELECT * FROM Orders WHERE CustomerId = @customerId", new {customerId = 123});

new RowbotExecutorBuilder()
.FromDataReader(dataReader)
Expand All @@ -89,41 +94,41 @@ static async Task Main(string[] args)
using (var conn = new SqlConnection(myConnectionString))
{
await conn.OpenAsync();
var dataReader = conn.ExecuteReader("SELECT * FROM Orders WHERE CustomerId = @customerId", new { customerId = 123 });
var dataReader = conn.ExecuteReader("SELECT * FROM Orders WHERE CustomerId = @customerId", new {customerId = 123});

await new RowbotAsyncExecutorBuilder()
.FromDataReader(dataReader)
.ToExcel(filepath: "c:\\temp\\output.xlsx", sheetName: "MySheet", writeHeaders: true)
.ExecuteAsync();
}

// Database => CSV (Space complexity: O(1))
// Sync version
// using Dapper;
using (var conn = new SqlConnection(myConnectionString))
{
conn.Open();
var dataReader = conn.ExecuteReader("SELECT * FROM Orders WHERE CustomerId = @customerId", new { customerId = 123 });
var dataReader = conn.ExecuteReader("SELECT * FROM Orders WHERE CustomerId = @customerId", new {customerId = 123});

new RowbotExecutorBuilder()
.FromDataReader(dataReader)
.ToCsvUsingCsvHelper(filepath: "c:\\temp\\output.csv", config: new CsvConfiguration(CultureInfo.InvariantCulture), writeHeaders: true)
.Execute();
}

// Async version
// using Dapper;
using (var conn = new SqlConnection(myConnectionString))
{
await conn.OpenAsync();
var dataReader = conn.ExecuteReader("SELECT * FROM Orders WHERE CustomerId = @customerId", new { customerId = 123 });
var dataReader = conn.ExecuteReader("SELECT * FROM Orders WHERE CustomerId = @customerId", new {customerId = 123});

await new RowbotAsyncExecutorBuilder()
.FromDataReader(dataReader)
.ToCsvUsingCsvHelper(filepath: "c:\\temp\\output.csv", config: new CsvConfiguration(CultureInfo.InvariantCulture), writeHeaders: true)
.ExecuteAsync();
}

// DataTable => List of objects (Space complexity: O(1))
// Sync version
new RowbotExecutorBuilder()
Expand All @@ -138,7 +143,7 @@ static async Task Main(string[] args)
// Do something with the customer here
}
});

// Async version
await new RowbotAsyncExecutorBuilder()
.FromDataTable(myDataTable)
Expand All @@ -159,7 +164,7 @@ static async Task Main(string[] args)
.FromCsvByCsvHelper(inputStream: File.Open("path//to//file.csv", FileMode.Open), csvConfiguration: new CsvConfiguration(CultureInfo.InvariantCulture), readFirstLineAsHeaders: true)
.ToExcel(filepath: "c:\\temp\\output.xlsx", sheetName: "MySheet", writeHeaders: true)
.Execute();

// Async version
await new RowbotAsyncExecutorBuilder()
.FromCsvByCsvHelper(inputStream: File.Open("path//to//file.csv", FileMode.Open), csvConfiguration: new CsvConfiguration(CultureInfo.InvariantCulture), readFirstLineAsHeaders: true)
Expand Down
61 changes: 61 additions & 0 deletions src/Rowbot/Execution/RowbotAsyncEnumerableExecutor.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
using System;
using System.Collections.Generic;
using System.Threading.Tasks;

namespace Rowbot.Execution
{
public sealed class RowbotAsyncEnumerableExecutor<TElement> : IDisposable
{
private readonly AsyncSourceGuards _source;
private readonly AsyncEnumerableTargetGuards<TElement> _target;

public RowbotAsyncEnumerableExecutor(IAsyncRowSource source, IAsyncEnumerableRowTarget<TElement> target)
{
_source = new AsyncSourceGuards(source);
_target = new AsyncEnumerableTargetGuards<TElement>(target);
}

public Task ExecuteAsync(Func<IAsyncEnumerable<TElement>, Task> consumer)
{
return consumer(ExecuteInternal());
}

private async IAsyncEnumerable<TElement> ExecuteInternal()
{
// Columns
var columnNames = await _source.InitAndGetColumnsAsync();
await _target.InitAsync(columns: columnNames);

// Rows
var valuesBuffer = new object[columnNames.Length];
while (await _source.ReadRowAsync(valuesBuffer))
{
yield return await _target.WriteRowAsync(valuesBuffer);
}

await _source.CompleteAsync();
await _target.CompleteAsync();

Dispose();
}

public void Dispose()
{
#pragma warning disable S2486 // Generic exceptions should not be ignored
#pragma warning disable S108 // Nested blocks of code should not be left empty
try
{
_source.Dispose();
}
catch { }

try
{
_target.Dispose();
}
catch { }
#pragma warning restore S108 // Nested blocks of code should not be left empty
#pragma warning restore S2486 // Generic exceptions should not be ignored
}
}
}
56 changes: 0 additions & 56 deletions src/Rowbot/Execution/RowbotAsyncExecutor.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using System;
using System.Collections.Generic;
using System.Threading.Tasks;

namespace Rowbot.Execution
Expand Down Expand Up @@ -53,59 +52,4 @@ public async Task ExecuteAsync()
Dispose();
}
}

public sealed class RowbotAsyncEnumerableExecutor<TElement> : IDisposable
{
private readonly AsyncSourceGuards _source;
private readonly AsyncEnumerableTargetGuards<TElement> _target;

public RowbotAsyncEnumerableExecutor(IAsyncRowSource source, IAsyncEnumerableRowTarget<TElement> target)
{
_source = new AsyncSourceGuards(source);
_target = new AsyncEnumerableTargetGuards<TElement>(target);
}

public Task ExecuteAsync(Func<IAsyncEnumerable<TElement>, Task> consumer)
{
return consumer(ExecuteInternal());
}

private async IAsyncEnumerable<TElement> ExecuteInternal()
{
// Columns
var columnNames = await _source.InitAndGetColumnsAsync();
await _target.InitAsync(columns: columnNames);

// Rows
var valuesBuffer = new object[columnNames.Length];
while (await _source.ReadRowAsync(valuesBuffer))
{
yield return await _target.WriteRowAsync(valuesBuffer);
}

await _source.CompleteAsync();
await _target.CompleteAsync();

Dispose();
}

public void Dispose()
{
#pragma warning disable S2486 // Generic exceptions should not be ignored
#pragma warning disable S108 // Nested blocks of code should not be left empty
try
{
_source.Dispose();
}
catch { }

try
{
_target.Dispose();
}
catch { }
#pragma warning restore S108 // Nested blocks of code should not be left empty
#pragma warning restore S2486 // Generic exceptions should not be ignored
}
}
}
Loading

0 comments on commit afb1d19

Please sign in to comment.