Rebase with github repository
This commit is contained in:
		
							parent
							
								
									e38eb7aa1c
								
							
						
					
					
						commit
						d7b0a471f0
					
				@ -1,5 +1,6 @@
 | 
				
			|||||||
using System.Collections.Immutable;
 | 
					using System.Collections.Immutable;
 | 
				
			||||||
using System.Data;
 | 
					using System.Data;
 | 
				
			||||||
 | 
					using System.Reflection;
 | 
				
			||||||
using Connected.Data.Schema.Sql;
 | 
					using Connected.Data.Schema.Sql;
 | 
				
			||||||
using Connected.Entities.Annotations;
 | 
					using Connected.Entities.Annotations;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -44,6 +45,7 @@ internal class ExistingColumn : ISchemaColumn, IExistingSchemaColumn
 | 
				
			|||||||
	public DateKind DateKind { get; set; } = DateKind.DateTime;
 | 
						public DateKind DateKind { get; set; } = DateKind.DateTime;
 | 
				
			||||||
	public BinaryKind BinaryKind { get; set; } = BinaryKind.VarBinary;
 | 
						public BinaryKind BinaryKind { get; set; } = BinaryKind.VarBinary;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						public PropertyInfo Property { get; set; }
 | 
				
			||||||
	public int DatePrecision { get; set; }
 | 
						public int DatePrecision { get; set; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	public ImmutableArray<string> QueryIndexColumns(string column)
 | 
						public ImmutableArray<string> QueryIndexColumns(string column)
 | 
				
			||||||
 | 
				
			|||||||
@ -1,4 +1,5 @@
 | 
				
			|||||||
using System.Data;
 | 
					using System.Data;
 | 
				
			||||||
 | 
					using System.Reflection;
 | 
				
			||||||
using Connected.Entities.Annotations;
 | 
					using Connected.Entities.Annotations;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Connected.Data.Schema;
 | 
					namespace Connected.Data.Schema;
 | 
				
			||||||
@ -21,4 +22,6 @@ public interface ISchemaColumn
 | 
				
			|||||||
	DateKind DateKind { get; }
 | 
						DateKind DateKind { get; }
 | 
				
			||||||
	BinaryKind BinaryKind { get; }
 | 
						BinaryKind BinaryKind { get; }
 | 
				
			||||||
	int DatePrecision { get; }
 | 
						int DatePrecision { get; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						PropertyInfo Property { get; }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -1,13 +1,15 @@
 | 
				
			|||||||
using System.Data;
 | 
					using System.Data;
 | 
				
			||||||
 | 
					using System.Reflection;
 | 
				
			||||||
using Connected.Entities.Annotations;
 | 
					using Connected.Entities.Annotations;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Connected.Data.Schema;
 | 
					namespace Connected.Data.Schema;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
internal class SchemaColumn : IEquatable<ISchemaColumn>, ISchemaColumn
 | 
					internal class SchemaColumn : IEquatable<ISchemaColumn>, ISchemaColumn
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	public SchemaColumn(ISchema schema)
 | 
						public SchemaColumn(ISchema schema, PropertyInfo property)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		Schema = schema;
 | 
							Schema = schema;
 | 
				
			||||||
 | 
							Property = property;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	private ISchema Schema { get; }
 | 
						private ISchema Schema { get; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -30,6 +32,8 @@ internal class SchemaColumn : IEquatable<ISchemaColumn>, ISchemaColumn
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	public int Ordinal { get; set; }
 | 
						public int Ordinal { get; set; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						public PropertyInfo Property { get; set; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	public bool Equals(ISchemaColumn? other)
 | 
						public bool Equals(ISchemaColumn? other)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		if (other is null)
 | 
							if (other is null)
 | 
				
			||||||
 | 
				
			|||||||
@ -60,6 +60,7 @@ internal class SchemaService : ISchemaService
 | 
				
			|||||||
				await middleware.Synchronize(entity, schema);
 | 
									await middleware.Synchronize(entity, schema);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				synchronized = true;
 | 
									synchronized = true;
 | 
				
			||||||
 | 
									break;
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			/*
 | 
								/*
 | 
				
			||||||
			 * We should notify the environment that entity is no synchronized.
 | 
								 * We should notify the environment that entity is no synchronized.
 | 
				
			||||||
@ -80,7 +81,7 @@ internal class SchemaService : ISchemaService
 | 
				
			|||||||
	{
 | 
						{
 | 
				
			||||||
		var persistence = entityType.GetCustomAttribute<PersistenceAttribute>();
 | 
							var persistence = entityType.GetCustomAttribute<PersistenceAttribute>();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		return persistence is null || !persistence.Persistence.HasFlag(ColumnPersistence.Write);
 | 
							return persistence is null || persistence.Persistence.HasFlag(ColumnPersistence.Write);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	private static ISchema CreateSchema(Type type)
 | 
						private static ISchema CreateSchema(Type type)
 | 
				
			||||||
@ -104,7 +105,7 @@ internal class SchemaService : ISchemaService
 | 
				
			|||||||
			if (property.FindAttribute<PersistenceAttribute>() is PersistenceAttribute pa && pa.IsVirtual)
 | 
								if (property.FindAttribute<PersistenceAttribute>() is PersistenceAttribute pa && pa.IsVirtual)
 | 
				
			||||||
				continue;
 | 
									continue;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			var column = new SchemaColumn(result)
 | 
								var column = new SchemaColumn(result, property)
 | 
				
			||||||
			{
 | 
								{
 | 
				
			||||||
				Name = ResolveColumnName(property),
 | 
									Name = ResolveColumnName(property),
 | 
				
			||||||
				DataType = DataExtensions.ToDbType(property)
 | 
									DataType = DataExtensions.ToDbType(property)
 | 
				
			||||||
 | 
				
			|||||||
@ -4,8 +4,7 @@ using Connected.Entities.Annotations;
 | 
				
			|||||||
namespace Connected.Data.Schema.Sql;
 | 
					namespace Connected.Data.Schema.Sql;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[Persistence(Persistence = ColumnPersistence.InMemory)]
 | 
					[Persistence(Persistence = ColumnPersistence.InMemory)]
 | 
				
			||||||
internal sealed class AdHocSchemaEntity : IEntity
 | 
					internal sealed record AdHocSchemaEntity : Entity
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	public State State { get; init; }
 | 
					 | 
				
			||||||
	public bool Result { get; init; }
 | 
						public bool Result { get; init; }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -1,6 +1,6 @@
 | 
				
			|||||||
using Connected.Data.Sql;
 | 
					using System.Data;
 | 
				
			||||||
 | 
					using Connected.Data.Sql;
 | 
				
			||||||
using Connected.Entities.Storage;
 | 
					using Connected.Entities.Storage;
 | 
				
			||||||
using System.Data;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Connected.Data.Schema.Sql;
 | 
					namespace Connected.Data.Schema.Sql;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -50,7 +50,7 @@ internal class SchemaExecutionContext
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	public async Task Execute(string commandText)
 | 
						public async Task Execute(string commandText)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		await Storage.Open<AdHocSchemaEntity>().Select(new SchemaStorageArgs(new StorageOperation { CommandText = commandText }, typeof(SqlDataConnection), ConnectionString));
 | 
							await Storage.Open<AdHocSchemaEntity>().Execute(new SchemaStorageArgs(new StorageOperation { CommandText = commandText }, typeof(SqlDataConnection), ConnectionString));
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	public async Task<AdHocSchemaEntity?> Select(string commandText)
 | 
						public async Task<AdHocSchemaEntity?> Select(string commandText)
 | 
				
			||||||
@ -74,7 +74,7 @@ internal class SchemaExecutionContext
 | 
				
			|||||||
			Constraints.Add(type, existing);
 | 
								Constraints.Add(type, existing);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (ConstraintNameExists(name))
 | 
							if (!ConstraintNameExists(name))
 | 
				
			||||||
			existing.Add(name);
 | 
								existing.Add(name);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -1,7 +1,6 @@
 | 
				
			|||||||
using Connected.Data.Storage;
 | 
					using System.Data;
 | 
				
			||||||
using Connected.Entities.Storage;
 | 
					using Connected.Entities.Storage;
 | 
				
			||||||
using Connected.Interop;
 | 
					using Connected.Interop;
 | 
				
			||||||
using System.Data;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Connected.Data.Schema.Sql;
 | 
					namespace Connected.Data.Schema.Sql;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -53,9 +52,8 @@ internal class SpHelp : SynchronizationQuery<ObjectDescriptor>
 | 
				
			|||||||
		if (rdr.Read())
 | 
							if (rdr.Read())
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			Result.MetaData.Name = rdr.GetValue("Name", string.Empty);
 | 
								Result.MetaData.Name = rdr.GetValue("Name", string.Empty);
 | 
				
			||||||
            Result.MetaData.Created = rdr.GetValue("Created_datetime", DateTime.MinValue);
 | 
					 | 
				
			||||||
			Result.MetaData.Owner = rdr.GetValue("Owner", string.Empty);
 | 
								Result.MetaData.Owner = rdr.GetValue("Owner", string.Empty);
 | 
				
			||||||
            Result.MetaData.Type = rdr.GetValue("Type", string.Empty);
 | 
								Result.MetaData.Type = rdr.GetValue("Object_type", string.Empty);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -1,10 +1,10 @@
 | 
				
			|||||||
using Connected.Data.Schema;
 | 
					using System.Collections.Immutable;
 | 
				
			||||||
 | 
					using Connected.Data.Schema;
 | 
				
			||||||
using Connected.Data.Sharding;
 | 
					using Connected.Data.Sharding;
 | 
				
			||||||
using Connected.Entities.Storage;
 | 
					using Connected.Entities.Storage;
 | 
				
			||||||
using Connected.Middleware;
 | 
					using Connected.Middleware;
 | 
				
			||||||
using Connected.ServiceModel;
 | 
					using Connected.ServiceModel;
 | 
				
			||||||
using Connected.ServiceModel.Transactions;
 | 
					using Connected.ServiceModel.Transactions;
 | 
				
			||||||
using System.Collections.Immutable;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Connected.Data.Storage;
 | 
					namespace Connected.Data.Storage;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -26,7 +26,7 @@ internal sealed class ConnectionProvider : IConnectionProvider, IAsyncDisposable
 | 
				
			|||||||
	public IMiddlewareService Middleware { get; }
 | 
						public IMiddlewareService Middleware { get; }
 | 
				
			||||||
	private ITransactionContext TransactionService { get; }
 | 
						private ITransactionContext TransactionService { get; }
 | 
				
			||||||
	private List<IStorageConnection> Connections => _connections;
 | 
						private List<IStorageConnection> Connections => _connections;
 | 
				
			||||||
	public StorageConnectionMode Mode { get; set; } = StorageConnectionMode.Isolated;
 | 
						public StorageConnectionMode Mode { get; set; } = StorageConnectionMode.Shared;
 | 
				
			||||||
	public async Task<ImmutableList<IStorageConnection>> Open<TEntity>(StorageContextArgs args)
 | 
						public async Task<ImmutableList<IStorageConnection>> Open<TEntity>(StorageContextArgs args)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		/*
 | 
							/*
 | 
				
			||||||
 | 
				
			|||||||
@ -1,10 +1,10 @@
 | 
				
			|||||||
using Connected.Entities;
 | 
					using System.Data;
 | 
				
			||||||
 | 
					using System.Reflection;
 | 
				
			||||||
 | 
					using System.Text;
 | 
				
			||||||
 | 
					using Connected.Entities;
 | 
				
			||||||
using Connected.Entities.Annotations;
 | 
					using Connected.Entities.Annotations;
 | 
				
			||||||
using Connected.Entities.Storage;
 | 
					using Connected.Entities.Storage;
 | 
				
			||||||
using Connected.Interop;
 | 
					using Connected.Interop;
 | 
				
			||||||
using System.Data;
 | 
					 | 
				
			||||||
using System.Reflection;
 | 
					 | 
				
			||||||
using System.Text;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Connected.Data.Update;
 | 
					namespace Connected.Data.Update;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -115,7 +115,20 @@ internal abstract class CommandBuilder
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	protected virtual List<PropertyInfo> GetProperties()
 | 
						protected virtual List<PropertyInfo> GetProperties()
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
        return Interop.Properties.GetImplementedProperties(Entity);
 | 
							var props = Interop.Properties.GetImplementedProperties(Entity);
 | 
				
			||||||
 | 
							var result = new List<PropertyInfo>();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							foreach (var property in props)
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								var persistence = property.FindAttribute<PersistenceAttribute>();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								if (persistence is not null && persistence.Persistence.HasFlag(ColumnPersistence.InMemory))
 | 
				
			||||||
 | 
									continue;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								result.Add(property);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							return result;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	protected static bool IsVersion(PropertyInfo property)
 | 
						protected static bool IsVersion(PropertyInfo property)
 | 
				
			||||||
 | 
				
			|||||||
@ -1,11 +1,11 @@
 | 
				
			|||||||
using Connected.Expressions.Languages;
 | 
					using System.Collections.ObjectModel;
 | 
				
			||||||
using Connected.Expressions.Translation;
 | 
					 | 
				
			||||||
using Connected.Expressions.Visitors;
 | 
					 | 
				
			||||||
using System.Collections.ObjectModel;
 | 
					 | 
				
			||||||
using System.Globalization;
 | 
					using System.Globalization;
 | 
				
			||||||
using System.Linq.Expressions;
 | 
					using System.Linq.Expressions;
 | 
				
			||||||
using System.Reflection;
 | 
					using System.Reflection;
 | 
				
			||||||
using System.Text;
 | 
					using System.Text;
 | 
				
			||||||
 | 
					using Connected.Expressions.Languages;
 | 
				
			||||||
 | 
					using Connected.Expressions.Translation;
 | 
				
			||||||
 | 
					using Connected.Expressions.Visitors;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Connected.Expressions.Formatters;
 | 
					namespace Connected.Expressions.Formatters;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -34,6 +34,7 @@ public class SqlFormatter : DatabaseVisitor
 | 
				
			|||||||
	protected virtual QueryLanguage? Language { get; }
 | 
						protected virtual QueryLanguage? Language { get; }
 | 
				
			||||||
	protected bool HideColumnAliases { get; set; }
 | 
						protected bool HideColumnAliases { get; set; }
 | 
				
			||||||
	protected bool HideTableAliases { get; set; }
 | 
						protected bool HideTableAliases { get; set; }
 | 
				
			||||||
 | 
						protected bool UseBracketsInWhere { get; set; } = true;
 | 
				
			||||||
	protected bool IsNested { get; set; }
 | 
						protected bool IsNested { get; set; }
 | 
				
			||||||
	public int IndentationWidth { get; set; } = 2;
 | 
						public int IndentationWidth { get; set; } = 2;
 | 
				
			||||||
	private StringBuilder Text { get; }
 | 
						private StringBuilder Text { get; }
 | 
				
			||||||
@ -316,6 +317,7 @@ public class SqlFormatter : DatabaseVisitor
 | 
				
			|||||||
		var left = b.Left;
 | 
							var left = b.Left;
 | 
				
			||||||
		var right = b.Right;
 | 
							var right = b.Right;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (UseBracketsInWhere)
 | 
				
			||||||
			Write(OpenBracket);
 | 
								Write(OpenBracket);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		switch (b.NodeType)
 | 
							switch (b.NodeType)
 | 
				
			||||||
@ -445,6 +447,7 @@ public class SqlFormatter : DatabaseVisitor
 | 
				
			|||||||
				throw new NotSupportedException($"The binary operator '{b.NodeType}' is not supported");
 | 
									throw new NotSupportedException($"The binary operator '{b.NodeType}' is not supported");
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (UseBracketsInWhere)
 | 
				
			||||||
			Write(CloseBracket);
 | 
								Write(CloseBracket);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		return b;
 | 
							return b;
 | 
				
			||||||
@ -630,11 +633,7 @@ public class SqlFormatter : DatabaseVisitor
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (select.Where is not null)
 | 
							if (select.Where is not null)
 | 
				
			||||||
        {
 | 
								WriteWhere(select.Where);
 | 
				
			||||||
            WriteLine(Indentation.Same);
 | 
					 | 
				
			||||||
            Write("WHERE ");
 | 
					 | 
				
			||||||
            VisitPredicate(select.Where);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (select.GroupBy is not null && select.GroupBy.Any())
 | 
							if (select.GroupBy is not null && select.GroupBy.Any())
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
@ -672,6 +671,13 @@ public class SqlFormatter : DatabaseVisitor
 | 
				
			|||||||
		return select;
 | 
							return select;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						protected virtual void WriteWhere(Expression expression)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							WriteLine(Indentation.Same);
 | 
				
			||||||
 | 
							Write("WHERE ");
 | 
				
			||||||
 | 
							VisitPredicate(expression);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	protected virtual void WriteTopClause(Expression expression)
 | 
						protected virtual void WriteTopClause(Expression expression)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		Write("TOP (");
 | 
							Write("TOP (");
 | 
				
			||||||
 | 
				
			|||||||
@ -1,11 +1,11 @@
 | 
				
			|||||||
using Connected.Expressions.Visitors;
 | 
					using System.Linq.Expressions;
 | 
				
			||||||
using System.Linq.Expressions;
 | 
					using Connected.Expressions.Visitors;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Connected.Expressions.Translation.Rewriters;
 | 
					namespace Connected.Expressions.Translation.Rewriters;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
public class WhereClauseRewriter : DatabaseVisitor
 | 
					public class WhereClauseRewriter : DatabaseVisitor
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    private WhereClauseRewriter(ExpressionCompilationContext context)
 | 
						protected WhereClauseRewriter(ExpressionCompilationContext context)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		Context = context;
 | 
							Context = context;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
				
			|||||||
@ -46,7 +46,7 @@ internal static class EntitySynchronizer
 | 
				
			|||||||
		else
 | 
							else
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			/*
 | 
								/*
 | 
				
			||||||
			 * entitySynchronization = token1, token2,...
 | 
								 * entitySynchronization = token1; token2,...
 | 
				
			||||||
			 */
 | 
								 */
 | 
				
			||||||
			var tokens = value.Split(',');
 | 
								var tokens = value.Split(',');
 | 
				
			||||||
			/*
 | 
								/*
 | 
				
			||||||
@ -66,13 +66,20 @@ internal static class EntitySynchronizer
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
					await Synchronize(schemaService, Assembly.Load(AssemblyName.GetAssemblyName(subTokens[1])), logger);
 | 
										await Synchronize(schemaService, Assembly.Load(AssemblyName.GetAssemblyName(subTokens[1])), logger);
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
				else if (string.Equals(subTokens[1], "type", StringComparison.OrdinalIgnoreCase))
 | 
									else if (string.Equals(subTokens[0], "type", StringComparison.OrdinalIgnoreCase))
 | 
				
			||||||
				{
 | 
									{
 | 
				
			||||||
					logger.LogTrace("Loading type '{type}'", subTokens[1]);
 | 
										var typeTokens = subTokens[1].Split("/");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
					if (Type.GetType(subTokens[1]) is not Type type)
 | 
										if (typeTokens.Length != 2)
 | 
				
			||||||
 | 
											throw new ArgumentException("Invalid entitySyncronization token '{token}'. Expected type:[assembly]/[type].", subTokens[1]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
										var qualifier = $"{typeTokens[1]}, {typeTokens[0]}";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
										logger.LogTrace("Loading type '{type}'", qualifier);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
										if (Type.GetType(qualifier) is not Type type)
 | 
				
			||||||
					{
 | 
										{
 | 
				
			||||||
						logger.LogWarning("Entity type '{type}' could not be loaded. Synchronization on the specified type could not be performed.", subTokens[1]);
 | 
											logger.LogWarning("Entity type '{type}' could not be loaded. Synchronization on the specified type could not be performed.", qualifier);
 | 
				
			||||||
						continue;
 | 
											continue;
 | 
				
			||||||
					}
 | 
										}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -18,5 +18,33 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
			return false;
 | 
								return false;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							public static bool ImplementsInterface(this Type type, Type interfaceType)
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								var interfaces = type.GetInterfaces();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								foreach (var i in interfaces)
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									if (!i.IsGenericType)
 | 
				
			||||||
 | 
									{
 | 
				
			||||||
 | 
										if (i == interfaceType)
 | 
				
			||||||
 | 
											return true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
										continue;
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									var definition = i.GetGenericTypeDefinition();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									if (definition == interfaceType)
 | 
				
			||||||
 | 
										return true;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								return false;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							public static bool ImplementsInterface<TInterface>(this Type type)
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								return ImplementsInterface(type, typeof(TInterface));
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -63,7 +63,7 @@ namespace Connected.Interop.Merging
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
			var addMethod = property.PropertyType.GetMethod(nameof(IList.Add), BindingFlags.Public | BindingFlags.Instance | BindingFlags.NonPublic);
 | 
								var addMethod = property.PropertyType.GetMethod(nameof(IList.Add), BindingFlags.Public | BindingFlags.Instance | BindingFlags.NonPublic);
 | 
				
			||||||
			var instance = addMethod is not null ? Activator.CreateInstance(property.PropertyType) : Array.CreateInstance(property.PropertyType, array.Count);
 | 
								var instance = addMethod is not null ? Activator.CreateInstance(property.PropertyType) : Array.CreateInstance(property.PropertyType, array.Count);
 | 
				
			||||||
			var elementType = instance.GetType().GetElementType();
 | 
								var elementType = property.PropertyType.GenericTypeArguments[0];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			for (var i = 0; i < array.Count; i++)
 | 
								for (var i = 0; i < array.Count; i++)
 | 
				
			||||||
			{
 | 
								{
 | 
				
			||||||
 | 
				
			|||||||
@ -1,9 +1,9 @@
 | 
				
			|||||||
using Connected.Interop.Merging;
 | 
					using System.Collections;
 | 
				
			||||||
using System.Collections;
 | 
					 | 
				
			||||||
using System.Reflection;
 | 
					using System.Reflection;
 | 
				
			||||||
using System.Text;
 | 
					using System.Text;
 | 
				
			||||||
using System.Text.Json;
 | 
					using System.Text.Json;
 | 
				
			||||||
using System.Text.Json.Nodes;
 | 
					using System.Text.Json.Nodes;
 | 
				
			||||||
 | 
					using Connected.Interop.Merging;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Connected.Interop;
 | 
					namespace Connected.Interop;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -41,12 +41,17 @@ public static class Serializer
 | 
				
			|||||||
		using var ms = new MemoryStream();
 | 
							using var ms = new MemoryStream();
 | 
				
			||||||
		using var writer = new Utf8JsonWriter(ms, new JsonWriterOptions { Indented = true, SkipValidation = false });
 | 
							using var writer = new Utf8JsonWriter(ms, new JsonWriterOptions { Indented = true, SkipValidation = false });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (value is JsonNode json)
 | 
				
			||||||
 | 
								json.WriteTo(writer);
 | 
				
			||||||
 | 
							else
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
			if (value.GetType().IsEnumerable())
 | 
								if (value.GetType().IsEnumerable())
 | 
				
			||||||
				SerializeArray(writer, null, value);
 | 
									SerializeArray(writer, null, value);
 | 
				
			||||||
			else if (value.GetType().IsTypePrimitive())
 | 
								else if (value.GetType().IsTypePrimitive())
 | 
				
			||||||
				SerializePrimitive(writer, value);
 | 
									SerializePrimitive(writer, value);
 | 
				
			||||||
			else
 | 
								else
 | 
				
			||||||
				SerializeObject(writer, null, value);
 | 
									SerializeObject(writer, null, value);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		await writer.FlushAsync();
 | 
							await writer.FlushAsync();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -78,18 +83,20 @@ public static class Serializer
 | 
				
			|||||||
		if (value is null)
 | 
							if (value is null)
 | 
				
			||||||
			return;
 | 
								return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							var enumerable = property.GetValue(value) as IEnumerable;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (enumerable is null)
 | 
				
			||||||
 | 
								return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (property is not null)
 | 
							if (property is not null)
 | 
				
			||||||
			writer.WriteStartArray(property.Name.ToCamelCase());
 | 
								writer.WriteStartArray(property.Name.ToCamelCase());
 | 
				
			||||||
		else
 | 
							else
 | 
				
			||||||
			writer.WriteStartArray();
 | 
								writer.WriteStartArray();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (value is IEnumerable enumerable)
 | 
					 | 
				
			||||||
		{
 | 
					 | 
				
			||||||
		var enumerator = enumerable.GetEnumerator();
 | 
							var enumerator = enumerable.GetEnumerator();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		while (enumerator.MoveNext())
 | 
							while (enumerator.MoveNext())
 | 
				
			||||||
			SerializeObject(writer, null, enumerator.Current);
 | 
								SerializeObject(writer, null, enumerator.Current);
 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
		writer.WriteEndArray();
 | 
							writer.WriteEndArray();
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@ -100,11 +107,13 @@ public static class Serializer
 | 
				
			|||||||
			SerializeArray(writer, property, value);
 | 
								SerializeArray(writer, property, value);
 | 
				
			||||||
		else if (!property.PropertyType.IsTypePrimitive())
 | 
							else if (!property.PropertyType.IsTypePrimitive())
 | 
				
			||||||
			SerializeObject(writer, property, value);
 | 
								SerializeObject(writer, property, value);
 | 
				
			||||||
 | 
							else
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
			writer.WritePropertyName(property.Name.ToCamelCase());
 | 
								writer.WritePropertyName(property.Name.ToCamelCase());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			SerializePrimitive(writer, property.GetValue(value));
 | 
								SerializePrimitive(writer, property.GetValue(value));
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	private static void SerializePrimitive(Utf8JsonWriter writer, object? value)
 | 
						private static void SerializePrimitive(Utf8JsonWriter writer, object? value)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
 | 
				
			|||||||
@ -96,8 +96,10 @@ namespace Connected.Interop
 | 
				
			|||||||
				return DbType.Byte;
 | 
									return DbType.Byte;
 | 
				
			||||||
			else if (underlyingType == typeof(bool))
 | 
								else if (underlyingType == typeof(bool))
 | 
				
			||||||
				return DbType.Boolean;
 | 
									return DbType.Boolean;
 | 
				
			||||||
			else if (underlyingType == typeof(DateTime) || underlyingType == typeof(DateTimeOffset))
 | 
								else if (underlyingType == typeof(DateTime))
 | 
				
			||||||
				return DbType.DateTime2;
 | 
									return DbType.DateTime2;
 | 
				
			||||||
 | 
								else if (underlyingType == typeof(DateTimeOffset))
 | 
				
			||||||
 | 
									return DbType.DateTimeOffset;
 | 
				
			||||||
			else if (underlyingType == typeof(decimal))
 | 
								else if (underlyingType == typeof(decimal))
 | 
				
			||||||
				return DbType.Decimal;
 | 
									return DbType.Decimal;
 | 
				
			||||||
			else if (underlyingType == typeof(double))
 | 
								else if (underlyingType == typeof(double))
 | 
				
			||||||
 | 
				
			|||||||
@ -68,7 +68,11 @@ public static class HttpExtensions
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
	public static async Task<TResult?> Post<TResult>(this IHttpService factory, string? requestUri, object? content, CancellationToken cancellationToken = default)
 | 
						public static async Task<TResult?> Post<TResult>(this IHttpService factory, string? requestUri, object? content, CancellationToken cancellationToken = default)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		return await HandleResponse<TResult>(await factory.CreateClient().SendAsync(await CreatePostMessage(requestUri, content), cancellationToken));
 | 
							var client = factory.CreateClient();
 | 
				
			||||||
 | 
							var message = await CreatePostMessage(requestUri, content);
 | 
				
			||||||
 | 
							var response = await client.SendAsync(message, cancellationToken);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							return await HandleResponse<TResult>(response);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	private static HttpRequestMessage CreateGetMessage(string? requestUri)
 | 
						private static HttpRequestMessage CreateGetMessage(string? requestUri)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user