Skip to content

Improving adapter functionality #5

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 7 commits into from
Oct 11, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 3 additions & 5 deletions Excel_Adapter/AdapterActions/Pull.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
using BH.Adapter;
using BH.Engine.Adapter;
using BH.oM.Adapter;
using BH.oM.Adapters.Excel;
using BH.oM.Base;
using BH.oM.Data.Requests;
using System.Collections.Generic;
Expand All @@ -36,13 +37,10 @@ public partial class ExcelAdapter : BHoMAdapter
/**** Method Overrides ****/
/***************************************************/

public override IEnumerable<object> Pull(IRequest request, PullType pullOption = PullType.AdapterDefault, ActionConfig actionConfig = null)
public override IEnumerable<object> Pull(IRequest request = null, PullType pullOption = PullType.AdapterDefault, ActionConfig actionConfig = null)
{
if (request == null)
{
BH.Engine.Base.Compute.RecordError("The request has not been provided for Pull action.");
return new List<object>();
}
request = new CellValuesRequest();

if (!File.Exists(m_FileSettings.GetFullFileName()))
{
Expand Down
94 changes: 43 additions & 51 deletions Excel_Adapter/AdapterActions/Push.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
*/

using BH.Engine.Adapter;
using BH.Engine.Reflection;
using BH.oM.Adapter;
using BH.oM.Adapters.Excel;
using BH.oM.Base;
Expand All @@ -46,6 +47,7 @@ public override List<object> Push(IEnumerable<object> objects, string tag = "",
BH.Engine.Base.Compute.RecordError("No objects were provided for Push action.");
return new List<object>();
}
objects = objects.Where(x => x != null).ToList();

// If unset, set the pushType to AdapterSettings' value (base AdapterSettings default is FullCRUD).
if (pushType == PushType.AdapterDefault)
Expand All @@ -59,7 +61,7 @@ public override List<object> Push(IEnumerable<object> objects, string tag = "",
config = new ExcelPushConfig();
}

// Make sure that only objects to be pushed are Tables.
// Make sure that a single type of objects are pushed
List<Type> objectTypes = objects.Select(x => x.GetType()).Distinct().ToList();
if (objectTypes.Count != 1)
{
Expand All @@ -70,29 +72,6 @@ public override List<object> Push(IEnumerable<object> objects, string tag = "",
return new List<object>();
}

Type type = objectTypes[0];
if (type != typeof(Table))
{
BH.Engine.Base.Compute.RecordError($"Push failed: Excel Adapter can push only one objects of type {nameof(Table)}.");
return new List<object>();
}

// Check if all tables have distinct, non-empty names.
List<Table> tables = objects.Cast<Table>().ToList();
if (tables.Any(x => string.IsNullOrWhiteSpace(x.Name)))
{
BH.Engine.Base.Compute.RecordError("Push aborted: all tables need to have non-empty name.");
return new List<object>();
}

List<string> duplicateNames = tables.GroupBy(x => x.Name.ToLower()).Where(x => x.Count() != 1).Select(x => x.Key).ToList();
if (duplicateNames.Count != 0)
{
BH.Engine.Base.Compute.RecordError("Push failed: all tables need to have distinct names, regardless of letter casing.\n" +
$"Following names are currently duplicate: {string.Join(", ", duplicateNames)}.");
return new List<object>();
}

// Check if the workbook exists and create it if not.
string fileName = m_FileSettings.GetFullFileName();
XLWorkbook workbook;
Expand Down Expand Up @@ -120,57 +99,50 @@ public override List<object> Push(IEnumerable<object> objects, string tag = "",
}

// Split the tables into collections to delete, create and update.
List<Table> toDelete = new List<Table>();
List<Table> toCreate = new List<Table>();
List<Table> toUpdate = new List<Table>();
bool success = true;
string sheetName = config.Worksheet;

List<TableRow> data = new List<TableRow>();
if (objects.All(x => x is TableRow))
data = objects.OfType<TableRow>().ToList();
else
data = ToTableRows(objects.ToList(), config.ObjectProperties);

switch (pushType)
{
case PushType.CreateNonExisting:
{
toCreate.AddRange(tables.Where(x => workbook.Worksheets.All(y => x.Name != y.Name)));
if (workbook.Worksheets.All(x => x.Name != sheetName))
success &= Create(workbook, sheetName, data, config);
break;
}
case PushType.DeleteThenCreate:
{
toDelete.AddRange(tables.Where(x => workbook.Worksheets.Any(y => x.Name == y.Name)));
toCreate.AddRange(tables);
if (workbook.Worksheets.Any(x => x.Name == sheetName))
success &= Delete(workbook, sheetName);
success &= Create(workbook, sheetName, data, config);
break;
}
case PushType.UpdateOnly:
{
toUpdate.AddRange(tables.Where(x => workbook.Worksheets.Any(y => x.Name == y.Name)));
success &= Update(workbook, sheetName, data, config);
break;
}
case PushType.UpdateOrCreateOnly:
{
toCreate.AddRange(tables.Where(x => workbook.Worksheets.All(y => x.Name != y.Name)));
toUpdate.AddRange(tables.Except(toCreate).ToList());
if (workbook.Worksheets.All(x => x.Name != sheetName))
success &= Create(workbook, sheetName, data, config);
else
success &= Update(workbook, sheetName, data, config);
break;
}
default:
{
BH.Engine.Base.Compute.RecordError($"Currently Excel adapter supports only {nameof(PushType)} equal to {pushType}");
BH.Engine.Base.Compute.RecordError($"Currently Excel adapter does not supports {nameof(PushType)} equal to {pushType}");
return new List<object>();
}
}

// Execute deletion, creation and update in a sequence.
bool success = true;
foreach (Table table in toDelete)
{
success &= Delete(workbook, table);
}

foreach (Table table in toCreate)
{
success &= Create(workbook, table, config);
}

foreach (Table table in toUpdate)
{
success &= Update(workbook, table, config);
}

// Try to update the workbook properties and then save it.
try
{
Expand All @@ -185,6 +157,26 @@ public override List<object> Push(IEnumerable<object> objects, string tag = "",
}
}

/***************************************************/
/**** Private Methods ****/
/***************************************************/

private List<TableRow> ToTableRows(List<object> objects, List<string> properties)
{
List<Dictionary<string, object>> content = objects.Where(x => x != null).Select(x => x.PropertyDictionary()).ToList();

List<string> ignore = new List<string> { "Tags", "CustomData", "Fragments" };
if (properties == null || properties.Count == 0)
properties = content.SelectMany(x => x.Keys).Distinct().Where(x => !ignore.Contains(x)).ToList();

List<TableRow> values = content
.Select(dic => properties.Select(p => dic.ContainsKey(p) ? dic[p].ToString() : ""))
.Select(x => new TableRow { Content = x.ToList<object>() })
.ToList();

return new List<TableRow> { new TableRow { Content = properties.ToList<object>() } }.Concat(values).ToList();
}

/***************************************************/
}
}
Expand Down
15 changes: 9 additions & 6 deletions Excel_Adapter/CRUD/Create/Create.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,12 @@

using BH.Engine.Excel;
using BH.oM.Adapters.Excel;
using BH.oM.Base;
using BH.oM.Data.Collections;
using ClosedXML.Excel;
using System;
using System.Collections.Generic;
using System.Linq;

namespace BH.Adapter.Excel
{
Expand All @@ -34,15 +37,15 @@ public partial class ExcelAdapter
/**** Public Methods ****/
/***************************************************/

private bool Create(IXLWorkbook workbook, Table table, ExcelPushConfig config)
private bool Create(IXLWorkbook workbook, string sheetName, List<TableRow> data, ExcelPushConfig config)
{
if (table?.Data == null)
if (data == null || data.Count == 0)
{
BH.Engine.Base.Compute.RecordError("Creation of a table failed: input table is null or does not contain a table.");
BH.Engine.Base.Compute.RecordError("Creation of a table failed: input table is null or does not contain data.");
return false;
}

string workSheetName = Validation.WorksheetName(table.Name, workbook);
string workSheetName = Validation.WorksheetName(sheetName, workbook);

try
{
Expand All @@ -52,12 +55,12 @@ private bool Create(IXLWorkbook workbook, Table table, ExcelPushConfig config)
if (string.IsNullOrWhiteSpace(startingCell))
return false;

worksheet.Cell(startingCell).InsertData(table.Data);
worksheet.Cell(startingCell).InsertData(data.Select(x => x.Content.ToArray()).ToList());
return true;
}
catch (Exception e)
{
BH.Engine.Base.Compute.RecordError($"Creation of worksheet {table.Name} failed with the following error: {e.Message}");
BH.Engine.Base.Compute.RecordError($"Creation of worksheet {sheetName} failed with the following error: {e.Message}");
return false;
}
}
Expand Down
6 changes: 3 additions & 3 deletions Excel_Adapter/CRUD/Delete/Delete.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,16 +32,16 @@ public partial class ExcelAdapter
/**** Public Methods ****/
/***************************************************/

private bool Delete(IXLWorkbook workbook, Table table)
private bool Delete(IXLWorkbook workbook, string sheetName)
{
try
{
workbook.Worksheets.Delete(table.Name);
workbook.Worksheets.Delete(sheetName);
return true;
}
catch (Exception e)
{
BH.Engine.Base.Compute.RecordError($"Deletion of worksheet {table.Name} failed with the following error: {e.Message}");
BH.Engine.Base.Compute.RecordError($"Deletion of worksheet {sheetName} failed with the following error: {e.Message}");
return false;
}
}
Expand Down
Loading