Skip to content

Commit 211baf8

Browse files
committed
Add Read operation to the plugin to read and load csv data from StructuredData
#6
1 parent 0eb2bf0 commit 211baf8

4 files changed

Lines changed: 78 additions & 2 deletions

File tree

src/CsvPlugin.cs

Lines changed: 54 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ internal CsvPlugin(IGuidProvider guidProvider, IReflectionGuard reflectionGuard)
3232
Name = "Csv",
3333
CompanyName = "FlowSynx",
3434
Description = Resources.PluginDescription,
35-
Version = new PluginVersion(1, 1, 0),
35+
Version = new PluginVersion(1, 1, 1),
3636
Category = PluginCategory.Data,
3737
Authors = new List<string> { "FlowSynx" },
3838
Copyright = "© FlowSynx. All rights reserved.",
@@ -49,6 +49,7 @@ internal CsvPlugin(IGuidProvider guidProvider, IReflectionGuard reflectionGuard)
4949

5050
private Dictionary<string, ICsvOperationHandler> OperationMap => new(StringComparer.OrdinalIgnoreCase)
5151
{
52+
["read"] = new ReadOperationHandler(),
5253
["filter"] = new FilterOperationHandler(),
5354
["map"] = new MapOperationHandler()
5455
};
@@ -84,7 +85,7 @@ public Task Initialize(IPluginLogger logger)
8485
}
8586

8687
var context = ParseDataToContext(inputParameter.Data);
87-
var csv = context.Content ?? throw new ArgumentException("Input CSV is required.");
88+
var csv = ReadDataFromPluginContext(context, inputParameter);
8889

8990
using var reader = new StringReader(csv);
9091
using var csvReader = new CsvReader(reader, new CsvConfiguration(CultureInfo.InvariantCulture)
@@ -132,6 +133,57 @@ private PluginContext ParseDataToContext(object? data)
132133
};
133134
}
134135

136+
private string ReadDataFromPluginContext(PluginContext pluginContext, InputParameter inputParameter)
137+
{
138+
if (pluginContext.Content is not null)
139+
return pluginContext.Content;
140+
else if (pluginContext.StructuredData is not null)
141+
return StructuredDataToCsv(pluginContext.StructuredData, inputParameter.Delimiter);
142+
else
143+
throw new InvalidDataException(string.Format(Resources.TheEnteredDataIsInvalid, pluginContext.Id));
144+
}
145+
146+
private string StructuredDataToCsv(List<Dictionary<string, object>>? data, string? delimiter = ",")
147+
{
148+
if (data == null || data.Count == 0)
149+
return string.Empty;
150+
151+
using var writer = new StringWriter();
152+
var config = new CsvConfiguration(CultureInfo.InvariantCulture)
153+
{
154+
Delimiter = delimiter ?? ",",
155+
HasHeaderRecord = true,
156+
TrimOptions = TrimOptions.Trim,
157+
DetectColumnCountChanges = true,
158+
BadDataFound = null
159+
};
160+
161+
using var csv = new CsvWriter(writer, config);
162+
163+
// Get all unique headers
164+
var headers = data.SelectMany(d => d.Keys).Distinct().ToList();
165+
166+
// Write headers
167+
foreach (var header in headers)
168+
{
169+
csv.WriteField(header);
170+
}
171+
csv.NextRecord();
172+
173+
// Write rows
174+
foreach (var row in data)
175+
{
176+
foreach (var header in headers)
177+
{
178+
row.TryGetValue(header, out var value);
179+
csv.WriteField(value);
180+
}
181+
csv.NextRecord();
182+
}
183+
184+
return writer.ToString();
185+
}
186+
135187
private async Task<string> ToCsvStringAsync(IEnumerable<ExpandoObject> records, InputParameter inputParameter)
136188
{
137189
using var writer = new StringWriter();

src/Resources.Designer.cs

Lines changed: 9 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/Resources.resx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,9 @@
126126
<data name="ReflectionBasedAccessIsNotAllowed" xml:space="preserve">
127127
<value>Reflection-based access is not allowed.</value>
128128
</data>
129+
<data name="TheEnteredDataIsInvalid" xml:space="preserve">
130+
<value>The entered data is invalid for '{0}'</value>
131+
</data>
129132
<data name="ThePathIsNotDirectory" xml:space="preserve">
130133
<value>The entered path is not a directory.</value>
131134
</data>
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
using FlowSynx.Plugins.Csv.Models;
2+
using System.Dynamic;
3+
4+
namespace FlowSynx.Plugins.Csv.Services;
5+
6+
internal class ReadOperationHandler : ICsvOperationHandler
7+
{
8+
public IEnumerable<ExpandoObject> Handle(IEnumerable<ExpandoObject> rows, InputParameter parameter)
9+
{
10+
return rows;
11+
}
12+
}

0 commit comments

Comments
 (0)