diff --git a/src/Dynamicweb.DataIntegration.Providers.ODataProvider.csproj b/src/Dynamicweb.DataIntegration.Providers.ODataProvider.csproj
index 66f31c1..1b7895d 100644
--- a/src/Dynamicweb.DataIntegration.Providers.ODataProvider.csproj
+++ b/src/Dynamicweb.DataIntegration.Providers.ODataProvider.csproj
@@ -1,6 +1,6 @@
- 10.8.4
+ 10.9.0
1.0.0.0
OData Provider
The Odata Provider lets you fetch and map data from or to any OData endpoint.
@@ -24,11 +24,15 @@
snupkg
-
+
+
+ ..\..\..\Dynamicweb10\src\Features\DataIntegration\Dynamicweb.DataIntegration\bin\Debug\net8.0\Dynamicweb.DataIntegration.dll
+
+
diff --git a/src/ODataProvider.cs b/src/ODataProvider.cs
index a949df5..d96968c 100644
--- a/src/ODataProvider.cs
+++ b/src/ODataProvider.cs
@@ -1,25 +1,27 @@
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.Linq;
-using System.Net;
-using System.Net.Http;
-using System.Text.Json;
-using System.Text.RegularExpressions;
-using System.Threading.Tasks;
-using System.Xml;
-using System.Xml.Linq;
-using Dynamicweb.Core;
+using Dynamicweb.Core;
using Dynamicweb.DataIntegration.EndpointManagement;
using Dynamicweb.DataIntegration.Integration;
using Dynamicweb.DataIntegration.Integration.ERPIntegration;
using Dynamicweb.DataIntegration.Integration.Interfaces;
+using Dynamicweb.DataIntegration.ProviderHelpers;
using Dynamicweb.DataIntegration.Providers.ODataProvider.Interfaces;
using Dynamicweb.DataIntegration.Providers.ODataProvider.Model;
using Dynamicweb.Extensibility.AddIns;
using Dynamicweb.Extensibility.Editors;
using Dynamicweb.Logging;
using Dynamicweb.Security.Licensing;
+using System;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.IO;
+using System.Linq;
+using System.Net;
+using System.Net.Http;
+using System.Text.Json;
+using System.Text.RegularExpressions;
+using System.Threading.Tasks;
+using System.Xml;
+using System.Xml.Linq;
namespace Dynamicweb.DataIntegration.Providers.ODataProvider;
@@ -31,7 +33,7 @@ namespace Dynamicweb.DataIntegration.Providers.ODataProvider;
[ResponseMapping(true)]
public class ODataProvider : BaseProvider, ISource, IDestination, IParameterOptions, IODataBaseProvider, IParameterVisibility
{
- internal readonly EndpointService _endpointService = new();
+ internal readonly EndpointService _endpointService = new();
internal readonly EndpointCollectionService _endpointCollectionService = new EndpointCollectionService();
internal Schema _schema;
internal Endpoint _endpoint;
@@ -219,20 +221,20 @@ IEnumerable IParameterOptions.GetParameterOptions(string parame
{
var result = new List();
- foreach(var collection in _endpointCollectionService.GetEndpointCollections().OrderBy(ec => ec.Sorting))
- {
- var parameterOptions = _endpointCollectionService.GetEndpoints(collection.Id).Select(endpoint =>
- new ParameterOption(endpoint.Name,new GroupedDropDownParameterEditor.DropDownItem(endpoint.Name, collection.Name, endpoint.Id.ToString()))
- {
+ foreach (var collection in _endpointCollectionService.GetEndpointCollections().OrderBy(ec => ec.Sorting))
+ {
+ var parameterOptions = _endpointCollectionService.GetEndpoints(collection.Id).Select(endpoint =>
+ new ParameterOption(endpoint.Name, new GroupedDropDownParameterEditor.DropDownItem(endpoint.Name, collection.Name, endpoint.Id.ToString()))
+ {
Group = collection.Name
});
- result.AddRange(parameterOptions);
- }
+ result.AddRange(parameterOptions);
+ }
result.AddRange(_endpointService.GetEndpoints().Where(e => e.Collection == null).Select(endpoint =>
- new ParameterOption(endpoint.Name, new GroupedDropDownParameterEditor.DropDownItem(endpoint.Name, "Dynamicweb 9 Endpoints", endpoint.Id.ToString()))
- {
- Group = "Dynamicweb 9 Endpoints"
- }));
+ new ParameterOption(endpoint.Name, new GroupedDropDownParameterEditor.DropDownItem(endpoint.Name, "Dynamicweb 9 Endpoints", endpoint.Id.ToString()))
+ {
+ Group = "Dynamicweb 9 Endpoints"
+ }));
return result;
}
@@ -302,34 +304,36 @@ public override void OverwriteDestinationSchemaToOriginal()
///
public override Schema GetOriginalSourceSchema()
{
- var name = GetEntityName();
var entityTypeTables = new Schema();
var entitySetsTables = new Schema();
+ if (_endpoint == null)
+ {
+ return new Schema();
+ }
+
+ var name = GetEntityName();
var header = new Dictionary
{
{ "accept", "text/html,application/xhtml+xml,application/xml" },
{ "Content-Type", "text/html" }
};
- if (_endpoint != null)
+ var endpointAuthentication = _endpoint.Authentication;
+ if (endpointAuthentication != null)
{
- var endpointAuthentication = _endpoint.Authentication;
- if (endpointAuthentication != null)
- {
- SetCredentials();
- }
- Task metadataResponse;
- if (endpointAuthentication.IsTokenBased())
- {
- string token = OAuthHelper.GetToken(_endpoint, endpointAuthentication);
- metadataResponse = new HttpRestClient(_credentials, 20).GetAsync(GetMetadataURL(), HandleStream, token);
- }
- else
- {
- metadataResponse = new HttpRestClient(_credentials, 20).GetAsync(GetMetadataURL(), HandleStream, endpointAuthentication, header);
- }
- metadataResponse.Wait();
+ SetCredentials();
}
+ Task metadataResponse;
+ if (endpointAuthentication.IsTokenBased())
+ {
+ string token = OAuthHelper.GetToken(_endpoint, endpointAuthentication);
+ metadataResponse = new HttpRestClient(_credentials, 20).GetAsync(GetMetadataURL(), HandleStream, token);
+ }
+ else
+ {
+ metadataResponse = new HttpRestClient(_credentials, 20).GetAsync(GetMetadataURL(), HandleStream, endpointAuthentication, header);
+ }
+ metadataResponse.Wait();
var emptySchema = new Schema();
if (entitySetsTables == emptySchema)
@@ -356,9 +360,13 @@ void HandleStream(Stream responseStream, HttpStatusCode responseStatusCode, Dict
else if (xmlReader.NodeType == XmlNodeType.Element &&
xmlReader.Name.Equals("EntitySet", StringComparison.OrdinalIgnoreCase))
{
- GetColumnsFromEntityTypeTableToEntitySetTable(entitySetsTables.AddTable(xmlReader.GetAttribute("Name")), entityTypeTables, xmlReader.GetAttribute("EntityType"));
+ var entityTypeName = xmlReader.GetAttribute("EntityType");
+ var SqlSchema = entityTypeName.Substring(entityTypeName.LastIndexOf(".") + 1);
+ var setTable = entitySetsTables.AddTable(xmlReader.GetAttribute("Name"), SqlSchema);
}
}
+
+ GetColumnsFromEntityTypeTableToEntitySetTable(entityTypeTables, entitySetsTables);
if (!EndpointIsLoadAllEntities(_endpoint.Url))
{
var singleEntitySetSelected = entitySetsTables.GetTables().FirstOrDefault(obj => obj.Name.Equals(name, StringComparison.OrdinalIgnoreCase));
@@ -377,20 +385,39 @@ void HandleStream(Stream responseStream, HttpStatusCode responseStatusCode, Dict
}
}
- private void GetColumnsFromEntityTypeTableToEntitySetTable(Table table, Schema entityTypeSchema, string entityTypeName)
+ private void GetColumnsFromEntityTypeTableToEntitySetTable(Schema entityTypeSchema, Schema entitySetsTables)
{
- var entityTypeNameClean = entityTypeName.Substring(entityTypeName.LastIndexOf(".") + 1);
- Table result = entityTypeSchema.GetTables().Where(obj => obj.Name.Equals(entityTypeNameClean, StringComparison.OrdinalIgnoreCase)).FirstOrDefault();
- if (result != null)
+ var entityTypeSchemaTables = entityTypeSchema.GetTables();
+ var entitySetSchemaTables = entitySetsTables.GetTables();
+ foreach (var table in entitySetSchemaTables)
{
- foreach (var item in result.Columns)
+ Table result = entityTypeSchemaTables.Where(obj => obj.Name.Equals(table.SqlSchema, StringComparison.OrdinalIgnoreCase)).FirstOrDefault();
+ if (result != null)
{
- if (table.Columns.Where(obj => obj.Name == item.Name).Count() == 0)
+ foreach (var item in result.Columns)
{
- table.AddColumn(new Column(item.Name, item.Type, table, item.IsPrimaryKey, item.IsNew, item.ReadOnly));
+ if (table.Columns.Where(obj => obj.Name == item.Name).Count() == 0)
+ {
+ if (item is TableColumn tableColumn)
+ {
+ var tableGroupName = tableColumn.Group;
+ var columns = entityTypeSchemaTables.FirstOrDefault(obj => obj.Name.Equals(tableColumn.Group, StringComparison.OrdinalIgnoreCase))?.Columns ?? [];
+ var entitySetTableName = entitySetSchemaTables.FirstOrDefault(obj => obj.SqlSchema.Equals(tableColumn.Group));
+ if (entitySetTableName != null)
+ {
+ tableGroupName = entitySetTableName.Name;
+ }
+ table.AddColumn(new TableColumn(tableColumn.Name, tableGroupName, table, tableColumn.Type, columns));
+ }
+ else
+ {
+ table.AddColumn(new Column(item.Name, item.Type, table, item.IsPrimaryKey, item.IsNew, item.ReadOnly));
+ }
+ }
}
}
}
+ entitySetSchemaTables.ForEach(obj => obj.SqlSchema = string.Empty);
}
private void AddPropertiesFromXMLReaderToTable(XmlReader xmlReader, Table table, Schema result)
@@ -399,6 +426,7 @@ private void AddPropertiesFromXMLReaderToTable(XmlReader xmlReader, Table table,
string entityName = xmlReader.GetAttribute("Name");
List primaryKeys = new List();
Column column = null;
+ TableColumn tableColumn = null;
while (xmlReader.Read() && !(xmlReader.NodeType == XmlNodeType.EndElement && xmlReader.Name.Equals("EntityType", StringComparison.OrdinalIgnoreCase)))
{
if (xmlReader.NodeType == XmlNodeType.Element && xmlReader.Name.Equals("PropertyRef", StringComparison.OrdinalIgnoreCase))
@@ -429,6 +457,16 @@ private void AddPropertiesFromXMLReaderToTable(XmlReader xmlReader, Table table,
if (!string.IsNullOrEmpty(permission) && permission.ToLower().EndsWith("permissiontype/read"))
column.ReadOnly = true;
}
+ else if (xmlReader.NodeType == XmlNodeType.Element && xmlReader.Name.Equals("NavigationProperty", StringComparison.OrdinalIgnoreCase))
+ {
+ //var containsTarget = xmlReader.GetAttribute("ContainsTarget");
+ var navigationPropertyName = xmlReader.GetAttribute("Name");
+ var navigationPropertyTypeString = xmlReader.GetAttribute("Type");
+ var navigationPropertyType = GetColumnTableType(navigationPropertyTypeString);
+ var groupName = GetTableName(navigationPropertyTypeString);
+ tableColumn = new TableColumn(navigationPropertyName, groupName, table, navigationPropertyType, []);
+ table.AddTableColumn(tableColumn);
+ }
else if (xmlReader.Name.Equals("EntityType", StringComparison.OrdinalIgnoreCase) && xmlReader.GetAttribute("Name") != entityName)
{
break;
@@ -480,6 +518,22 @@ private static Type GetColumnType(string columnTypeString)
return typeof(object);
}
+ private static Type GetColumnTableType(string columnTableTypeString)
+ {
+ if (columnTableTypeString.StartsWith("Collection", StringComparison.OrdinalIgnoreCase))
+ return typeof(Collection