using System.Reflection;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Omika.Core.Compatibility;
using Omika.Core.Contracts.Common;
using Omika.Core.Contracts.Planning;
using Omika.Core.Domain.Commands;
using Omika.Core.Domain.Entities.Planning;
using Omika.Core.Interfaces;
using Omika.Core.Runtime;
using Omika.Data;
using Omika.Data.Configuration;
using Omika.Data.Connection;
using Omika.Data.Repositories;
using Omika.Data.Repositories.Batik;
using Omika.Data.Repositories.Omika;
namespace Omika.Tests.Repositories;
///
/// Tests unitaires de : délégation,
/// comportement Unknown, propagation d'erreurs, architecture, et DI.
///
[Collection("ApplicationRuntimeContext")]
public class AdaptiveRendezVousRepositoryTests : IDisposable
{
public AdaptiveRendezVousRepositoryTests()
{
ApplicationRuntimeContext.Reset();
}
public void Dispose()
{
ApplicationRuntimeContext.Reset();
}
// =========================================================================
// DELEGATION SEARCH
// =========================================================================
[Fact]
public async Task SearchAsync_BatikDetected_DelegatesToBatikRepository()
{
ApplicationRuntimeContext.Configure(DatabaseSchemaSelection.Auto);
ApplicationRuntimeContext.SetDetectedVersion(DatabaseSchemaVersion.Batik);
var batikConnection = new SpyingHfsqlConnection();
var omikaConnection = new SpyingHfsqlConnection();
batikConnection.RendezVousRows = [BatikRendezVousDict(1, "Réunion", "INT-001")];
var batikRepo = new BatikRendezVousRepository(batikConnection);
var omikaRepo = new OmikaRendezVousRepository(omikaConnection);
var adaptive = new AdaptiveRendezVousRepository(batikRepo, omikaRepo);
await adaptive.SearchAsync(new RendezVousSearchCriteria { Search = "Réunion" });
Assert.True(batikConnection.QueryCount > 0, "Batik aurait dû exécuter des requêtes.");
Assert.Equal(0, omikaConnection.QueryCount);
}
[Fact]
public async Task SearchAsync_OmikaDetected_DelegatesToOmikaRepository()
{
ApplicationRuntimeContext.Configure(DatabaseSchemaSelection.Auto);
ApplicationRuntimeContext.SetDetectedVersion(DatabaseSchemaVersion.Omika);
var batikConnection = new SpyingHfsqlConnection();
var omikaConnection = new SpyingHfsqlConnection();
omikaConnection.RendezVousRows = [OmikaRendezVousDict(1, "Réunion", "INT-001")];
var batikRepo = new BatikRendezVousRepository(batikConnection);
var omikaRepo = new OmikaRendezVousRepository(omikaConnection);
var adaptive = new AdaptiveRendezVousRepository(batikRepo, omikaRepo);
await adaptive.SearchAsync(new RendezVousSearchCriteria { Search = "Réunion" });
Assert.Equal(0, batikConnection.QueryCount);
Assert.True(omikaConnection.QueryCount > 0, "Omika aurait dû exécuter des requêtes.");
}
[Fact]
public async Task SearchAsync_UnknownDetected_ThrowsInvalidOperationException()
{
ApplicationRuntimeContext.Configure(DatabaseSchemaSelection.Auto);
var batikConnection = new SpyingHfsqlConnection();
var omikaConnection = new SpyingHfsqlConnection();
var batikRepo = new BatikRendezVousRepository(batikConnection);
var omikaRepo = new OmikaRendezVousRepository(omikaConnection);
var adaptive = new AdaptiveRendezVousRepository(batikRepo, omikaRepo);
var ex = await Assert.ThrowsAsync(
() => adaptive.SearchAsync(new RendezVousSearchCriteria()));
Assert.Contains("not been detected", ex.Message);
Assert.Equal(0, batikConnection.QueryCount);
Assert.Equal(0, omikaConnection.QueryCount);
}
[Fact]
public async Task SearchAsync_EmptyCriteria_DoesNotCrash()
{
ApplicationRuntimeContext.Configure(DatabaseSchemaSelection.Auto);
ApplicationRuntimeContext.SetDetectedVersion(DatabaseSchemaVersion.Batik);
var batikConnection = new SpyingHfsqlConnection();
batikConnection.RendezVousRows = [];
var omikaConnection = new SpyingHfsqlConnection();
var batikRepo = new BatikRendezVousRepository(batikConnection);
var omikaRepo = new OmikaRendezVousRepository(omikaConnection);
var adaptive = new AdaptiveRendezVousRepository(batikRepo, omikaRepo);
PagedResult result = await adaptive.SearchAsync(new RendezVousSearchCriteria());
Assert.NotNull(result);
Assert.Empty(result.Items);
}
// =========================================================================
// DELEGATION DETAIL
// =========================================================================
[Fact]
public async Task GetDetailsAsync_BatikDetected_DelegatesToBatik()
{
ApplicationRuntimeContext.Configure(DatabaseSchemaSelection.Auto);
ApplicationRuntimeContext.SetDetectedVersion(DatabaseSchemaVersion.Batik);
var batikConnection = new SpyingHfsqlConnection();
batikConnection.RendezVousRows = [BatikRendezVousDict(42, "Dupont", "INT-001")];
var omikaConnection = new SpyingHfsqlConnection();
var batikRepo = new BatikRendezVousRepository(batikConnection);
var omikaRepo = new OmikaRendezVousRepository(omikaConnection);
var adaptive = new AdaptiveRendezVousRepository(batikRepo, omikaRepo);
RendezVous? result = await adaptive.GetDetailsAsync("42");
Assert.NotNull(result);
Assert.True(batikConnection.QueryCount > 0, "Batik aurait dû exécuter des requêtes.");
Assert.Equal(0, omikaConnection.QueryCount);
}
[Fact]
public async Task GetDetailsAsync_OmikaDetected_DelegatesToOmika()
{
ApplicationRuntimeContext.Configure(DatabaseSchemaSelection.Auto);
ApplicationRuntimeContext.SetDetectedVersion(DatabaseSchemaVersion.Omika);
var batikConnection = new SpyingHfsqlConnection();
var omikaConnection = new SpyingHfsqlConnection();
omikaConnection.RendezVousRows = [OmikaRendezVousDict(42, "Dupont", "INT-001")];
var batikRepo = new BatikRendezVousRepository(batikConnection);
var omikaRepo = new OmikaRendezVousRepository(omikaConnection);
var adaptive = new AdaptiveRendezVousRepository(batikRepo, omikaRepo);
RendezVous? result = await adaptive.GetDetailsAsync("42");
Assert.NotNull(result);
Assert.Equal(0, batikConnection.QueryCount);
Assert.True(omikaConnection.QueryCount > 0, "Omika aurait dû exécuter des requêtes.");
}
[Fact]
public async Task GetDetailsAsync_UnknownDetected_ThrowsInvalidOperationException()
{
ApplicationRuntimeContext.Configure(DatabaseSchemaSelection.Auto);
var batikConnection = new SpyingHfsqlConnection();
var omikaConnection = new SpyingHfsqlConnection();
var batikRepo = new BatikRendezVousRepository(batikConnection);
var omikaRepo = new OmikaRendezVousRepository(omikaConnection);
var adaptive = new AdaptiveRendezVousRepository(batikRepo, omikaRepo);
var ex = await Assert.ThrowsAsync(
() => adaptive.GetDetailsAsync("42"));
Assert.Contains("not been detected", ex.Message);
Assert.Equal(0, batikConnection.QueryCount);
Assert.Equal(0, omikaConnection.QueryCount);
}
[Fact]
public async Task GetDetailsAsync_NullFromRepository_ReturnsNull()
{
ApplicationRuntimeContext.Configure(DatabaseSchemaSelection.Auto);
ApplicationRuntimeContext.SetDetectedVersion(DatabaseSchemaVersion.Batik);
var batikConnection = new SpyingHfsqlConnection();
batikConnection.RendezVousRows = [];
var omikaConnection = new SpyingHfsqlConnection();
var batikRepo = new BatikRendezVousRepository(batikConnection);
var omikaRepo = new OmikaRendezVousRepository(omikaConnection);
var adaptive = new AdaptiveRendezVousRepository(batikRepo, omikaRepo);
RendezVous? result = await adaptive.GetDetailsAsync("999");
Assert.Null(result);
}
// =========================================================================
// PROPAGATION D'ERREURS
// =========================================================================
[Fact]
public async Task SearchAsync_BatikInfrastructureError_Propagated()
{
ApplicationRuntimeContext.Configure(DatabaseSchemaSelection.Auto);
ApplicationRuntimeContext.SetDetectedVersion(DatabaseSchemaVersion.Batik);
var batikConnection = new SpyingHfsqlConnection { ThrowOnQuery = true };
var omikaConnection = new SpyingHfsqlConnection();
var batikRepo = new BatikRendezVousRepository(batikConnection);
var omikaRepo = new OmikaRendezVousRepository(omikaConnection);
var adaptive = new AdaptiveRendezVousRepository(batikRepo, omikaRepo);
await Assert.ThrowsAsync(
() => adaptive.SearchAsync(new RendezVousSearchCriteria()));
}
[Fact]
public async Task GetDetailsAsync_OmikaInfrastructureError_Propagated()
{
ApplicationRuntimeContext.Configure(DatabaseSchemaSelection.Auto);
ApplicationRuntimeContext.SetDetectedVersion(DatabaseSchemaVersion.Omika);
var batikConnection = new SpyingHfsqlConnection();
var omikaConnection = new SpyingHfsqlConnection { ThrowOnQuery = true };
var batikRepo = new BatikRendezVousRepository(batikConnection);
var omikaRepo = new OmikaRendezVousRepository(omikaConnection);
var adaptive = new AdaptiveRendezVousRepository(batikRepo, omikaRepo);
await Assert.ThrowsAsync(
() => adaptive.GetDetailsAsync("42"));
}
// =========================================================================
// DI TESTS
// =========================================================================
[Fact]
public void AddOmikaData_RegistersBatikRendezVousRepositoryAsScoped()
{
var services = new ServiceCollection();
services.AddOmikaData();
var descriptor = services.Single(d => d.ServiceType == typeof(BatikRendezVousRepository));
Assert.Equal(ServiceLifetime.Scoped, descriptor.Lifetime);
}
[Fact]
public void AddOmikaData_RegistersOmikaRendezVousRepositoryAsScoped()
{
var services = new ServiceCollection();
services.AddOmikaData();
var descriptor = services.Single(d => d.ServiceType == typeof(OmikaRendezVousRepository));
Assert.Equal(ServiceLifetime.Scoped, descriptor.Lifetime);
}
[Fact]
public void AddOmikaData_RegistersIRendezVousRepositoryAsScoped()
{
var services = new ServiceCollection();
services.AddOmikaData();
var descriptor = services.Single(d => d.ServiceType == typeof(IRendezVousRepository));
Assert.Equal(ServiceLifetime.Scoped, descriptor.Lifetime);
}
[Fact]
public void AddOmikaData_IRendezVousRepositoryPointsToAdaptiveRendezVousRepository()
{
var services = new ServiceCollection();
services.AddOmikaData();
var descriptor = services.Single(d => d.ServiceType == typeof(IRendezVousRepository));
Assert.Equal(typeof(AdaptiveRendezVousRepository), descriptor.ImplementationType);
}
[Fact]
public void AddOmikaData_OnlyOneIRendezVousRepositoryRegistered()
{
var services = new ServiceCollection();
services.AddOmikaData();
var descriptors = services.Where(d => d.ServiceType == typeof(IRendezVousRepository)).ToList();
Assert.Single(descriptors);
}
[Fact]
public async Task AddOmikaData_ResolvesAllRendezVousRepositories_WithFakeConnection()
{
var services = new ServiceCollection();
services.AddSingleton(new ConfigurationBuilder().Build());
services.AddOmikaData();
var oldDescriptor = services.Single(d => d.ServiceType == typeof(IHfsqlConnection));
services.Remove(oldDescriptor);
services.AddScoped();
var provider = services.BuildServiceProvider();
await using var scope = provider.CreateAsyncScope();
var rendezVousRepo = scope.ServiceProvider.GetRequiredService();
Assert.IsType(rendezVousRepo);
var batikRepo = scope.ServiceProvider.GetRequiredService();
Assert.NotNull(batikRepo);
var omikaRepo = scope.ServiceProvider.GetRequiredService();
Assert.NotNull(omikaRepo);
}
// =========================================================================
// DELEGATION UPDATE
// =========================================================================
[Fact]
public async Task UpdateAsync_BatikDetected_DelegatesToBatik()
{
ApplicationRuntimeContext.Configure(DatabaseSchemaSelection.Auto);
ApplicationRuntimeContext.SetDetectedVersion(DatabaseSchemaVersion.Batik);
var batikConnection = new SpyingHfsqlConnection();
batikConnection.RendezVousRows = [BatikRendezVousDict(42, "Dupont", "INT-001")];
var omikaConnection = new SpyingHfsqlConnection();
var batikRepo = new BatikRendezVousRepository(batikConnection);
var omikaRepo = new OmikaRendezVousRepository(omikaConnection);
var adaptive = new AdaptiveRendezVousRepository(batikRepo, omikaRepo);
await adaptive.UpdateAsync("42", new RendezVousUpdateCommand { Titre = "Updated" },
CancellationToken.None);
Assert.True(batikConnection.QueryCount > 0, "Batik aurait dû exécuter des requêtes.");
Assert.Equal(0, omikaConnection.QueryCount);
}
[Fact]
public async Task UpdateAsync_OmikaDetected_DelegatesToOmika()
{
ApplicationRuntimeContext.Configure(DatabaseSchemaSelection.Auto);
ApplicationRuntimeContext.SetDetectedVersion(DatabaseSchemaVersion.Omika);
var batikConnection = new SpyingHfsqlConnection();
var omikaConnection = new SpyingHfsqlConnection();
omikaConnection.RendezVousRows = [OmikaRendezVousDict(42, "Dupont", "INT-001")];
var batikRepo = new BatikRendezVousRepository(batikConnection);
var omikaRepo = new OmikaRendezVousRepository(omikaConnection);
var adaptive = new AdaptiveRendezVousRepository(batikRepo, omikaRepo);
await adaptive.UpdateAsync(Guid.NewGuid().ToString("D"), new RendezVousUpdateCommand { Titre = "Updated" },
CancellationToken.None);
Assert.Equal(0, batikConnection.QueryCount);
Assert.True(omikaConnection.QueryCount > 0, "Omika aurait dû exécuter des requêtes.");
}
[Fact]
public async Task UpdateAsync_UnknownDetected_ThrowsInvalidOperationException()
{
ApplicationRuntimeContext.Configure(DatabaseSchemaSelection.Auto);
var batikConnection = new SpyingHfsqlConnection();
var omikaConnection = new SpyingHfsqlConnection();
var batikRepo = new BatikRendezVousRepository(batikConnection);
var omikaRepo = new OmikaRendezVousRepository(omikaConnection);
var adaptive = new AdaptiveRendezVousRepository(batikRepo, omikaRepo);
var ex = await Assert.ThrowsAsync(
() => adaptive.UpdateAsync("42", new RendezVousUpdateCommand()));
Assert.Contains("not been detected", ex.Message);
Assert.Equal(0, batikConnection.QueryCount);
Assert.Equal(0, omikaConnection.QueryCount);
}
// =========================================================================
// DELEGATION CANCEL
// =========================================================================
[Fact]
public async Task CancelAsync_BatikDetected_Existing_ReturnsTrue()
{
ApplicationRuntimeContext.Configure(DatabaseSchemaSelection.Auto);
ApplicationRuntimeContext.SetDetectedVersion(DatabaseSchemaVersion.Batik);
var batikConnection = new SpyingHfsqlConnection();
batikConnection.RendezVousRows = [BatikRendezVousDict(42, "Dupont", "INT-001")];
var omikaConnection = new SpyingHfsqlConnection();
var batikRepo = new BatikRendezVousRepository(batikConnection);
var omikaRepo = new OmikaRendezVousRepository(omikaConnection);
var adaptive = new AdaptiveRendezVousRepository(batikRepo, omikaRepo);
bool result = await adaptive.CancelAsync("42", new AnnulationRendezVousCommand());
Assert.True(result);
Assert.True(batikConnection.QueryCount > 0, "Batik aurait dû exécuter des requêtes.");
Assert.Equal(0, omikaConnection.QueryCount);
}
[Fact]
public async Task CancelAsync_OmikaDetected_Existing_ReturnsTrue()
{
ApplicationRuntimeContext.Configure(DatabaseSchemaSelection.Auto);
ApplicationRuntimeContext.SetDetectedVersion(DatabaseSchemaVersion.Omika);
var batikConnection = new SpyingHfsqlConnection();
var omikaConnection = new SpyingHfsqlConnection();
omikaConnection.RendezVousRows = [OmikaRendezVousDict(42, "Dupont", "INT-001")];
var batikRepo = new BatikRendezVousRepository(batikConnection);
var omikaRepo = new OmikaRendezVousRepository(omikaConnection);
var adaptive = new AdaptiveRendezVousRepository(batikRepo, omikaRepo);
bool result = await adaptive.CancelAsync(Guid.NewGuid().ToString("D"), new AnnulationRendezVousCommand());
Assert.True(result);
Assert.Equal(0, batikConnection.QueryCount);
Assert.True(omikaConnection.QueryCount > 0, "Omika aurait dû exécuter des requêtes.");
}
[Fact]
public async Task CancelAsync_UnknownDetected_ThrowsInvalidOperationException()
{
ApplicationRuntimeContext.Configure(DatabaseSchemaSelection.Auto);
var batikConnection = new SpyingHfsqlConnection();
var omikaConnection = new SpyingHfsqlConnection();
var batikRepo = new BatikRendezVousRepository(batikConnection);
var omikaRepo = new OmikaRendezVousRepository(omikaConnection);
var adaptive = new AdaptiveRendezVousRepository(batikRepo, omikaRepo);
var ex = await Assert.ThrowsAsync(
() => adaptive.CancelAsync("42", new AnnulationRendezVousCommand()));
Assert.Contains("not been detected", ex.Message);
Assert.Equal(0, batikConnection.QueryCount);
Assert.Equal(0, omikaConnection.QueryCount);
}
// =========================================================================
// DELEGATION ARCHIVE
// =========================================================================
[Fact]
public async Task ArchiveAsync_BatikDetected_Existing_ReturnsTrue()
{
ApplicationRuntimeContext.Configure(DatabaseSchemaSelection.Auto);
ApplicationRuntimeContext.SetDetectedVersion(DatabaseSchemaVersion.Batik);
var batikConnection = new SpyingHfsqlConnection();
batikConnection.RendezVousRows = [BatikRendezVousDict(42, "Dupont", "INT-001")];
var omikaConnection = new SpyingHfsqlConnection();
var batikRepo = new BatikRendezVousRepository(batikConnection);
var omikaRepo = new OmikaRendezVousRepository(omikaConnection);
var adaptive = new AdaptiveRendezVousRepository(batikRepo, omikaRepo);
bool result = await adaptive.ArchiveAsync("42");
Assert.True(result);
Assert.True(batikConnection.QueryCount > 0, "Batik aurait dû exécuter des requêtes.");
Assert.Equal(0, omikaConnection.QueryCount);
}
[Fact]
public async Task ArchiveAsync_OmikaDetected_Existing_ReturnsTrue()
{
ApplicationRuntimeContext.Configure(DatabaseSchemaSelection.Auto);
ApplicationRuntimeContext.SetDetectedVersion(DatabaseSchemaVersion.Omika);
var batikConnection = new SpyingHfsqlConnection();
var omikaConnection = new SpyingHfsqlConnection();
omikaConnection.RendezVousRows = [OmikaRendezVousDict(42, "Dupont", "INT-001")];
var batikRepo = new BatikRendezVousRepository(batikConnection);
var omikaRepo = new OmikaRendezVousRepository(omikaConnection);
var adaptive = new AdaptiveRendezVousRepository(batikRepo, omikaRepo);
bool result = await adaptive.ArchiveAsync(Guid.NewGuid().ToString("D"));
Assert.True(result);
Assert.Equal(0, batikConnection.QueryCount);
Assert.True(omikaConnection.QueryCount > 0, "Omika aurait dû exécuter des requêtes.");
}
[Fact]
public async Task ArchiveAsync_UnknownDetected_ThrowsInvalidOperationException()
{
ApplicationRuntimeContext.Configure(DatabaseSchemaSelection.Auto);
var batikConnection = new SpyingHfsqlConnection();
var omikaConnection = new SpyingHfsqlConnection();
var batikRepo = new BatikRendezVousRepository(batikConnection);
var omikaRepo = new OmikaRendezVousRepository(omikaConnection);
var adaptive = new AdaptiveRendezVousRepository(batikRepo, omikaRepo);
var ex = await Assert.ThrowsAsync(
() => adaptive.ArchiveAsync("42"));
Assert.Contains("not been detected", ex.Message);
Assert.Equal(0, batikConnection.QueryCount);
Assert.Equal(0, omikaConnection.QueryCount);
}
// =========================================================================
// ARCHITECTURE
// =========================================================================
[Fact]
public void Repository_ImplementsIRendezVousRepository()
{
Assert.True(typeof(IRendezVousRepository).IsAssignableFrom(typeof(AdaptiveRendezVousRepository)));
}
[Fact]
public void Repository_ContainsNoSql()
{
string source = ReadSourceFile(typeof(AdaptiveRendezVousRepository));
Assert.DoesNotContain("SELECT ", source, StringComparison.OrdinalIgnoreCase);
Assert.DoesNotContain("FROM ", source, StringComparison.OrdinalIgnoreCase);
Assert.DoesNotContain("WHERE ", source, StringComparison.OrdinalIgnoreCase);
}
[Fact]
public void Repository_ContainsNoOdbcTypes()
{
var type = typeof(AdaptiveRendezVousRepository);
var referenced = GetPublicSurfaceTypes(type);
Assert.DoesNotContain(referenced, t =>
t.Namespace is not null && t.Namespace.StartsWith("System.Data.Odbc", StringComparison.Ordinal));
}
[Fact]
public void Repository_ContainsNoHfsqlRowReferences()
{
var type = typeof(AdaptiveRendezVousRepository);
var referenced = GetPublicSurfaceTypes(type);
Assert.DoesNotContain(referenced, t =>
t.Name.Contains("Row", StringComparison.OrdinalIgnoreCase)
&& t.Namespace is not null
&& t.Namespace.Contains("HfSql", StringComparison.OrdinalIgnoreCase));
}
[Fact]
public void Repository_DoesNotDependOnHfsqlConnection()
{
var type = typeof(AdaptiveRendezVousRepository);
bool hasHfsqlConnectionCtor = type.GetConstructors()
.Any(c => c.GetParameters()
.Any(p => typeof(IHfsqlConnection).IsAssignableFrom(p.ParameterType)));
Assert.False(hasHfsqlConnectionCtor,
"AdaptiveRendezVousRepository ne doit pas dépendre directement de IHfsqlConnection.");
}
// =========================================================================
// HELPERS
// =========================================================================
private static IEnumerable GetPublicSurfaceTypes(Type type)
{
var members = type.GetMembers(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static)
.Select(m => m.DeclaringType)
.Where(t => t is not null)
.Cast();
var parameters = type.GetMethods(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)
.SelectMany(m => m.GetParameters())
.Select(p => p.ParameterType);
var returnTypes = type.GetMethods(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)
.Select(m => m.ReturnType);
var properties = type.GetProperties(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)
.Select(p => p.PropertyType);
var ctorParams = type.GetConstructors()
.SelectMany(c => c.GetParameters())
.Select(p => p.ParameterType);
return members.Concat(parameters).Concat(returnTypes).Concat(properties).Concat(ctorParams);
}
private static string ReadSourceFile(Type type)
{
string baseDir = AppDomain.CurrentDomain.BaseDirectory;
var dir = new DirectoryInfo(baseDir);
while (dir != null && !File.Exists(Path.Combine(dir.FullName, "Omika.slnx")))
dir = dir.Parent;
string root = dir?.FullName ?? baseDir;
return File.ReadAllText(Path.Combine(root, "src", "Omika.Data", "Repositories", type.Name + ".cs"));
}
// --- Dictionnaires de lignes physiques ----------------------------------
private static Dictionary BatikRendezVousDict(
long pkid, string? objet, string? reference)
=> new()
{
["PL_PKID"] = pkid,
["PL_Objet"] = objet,
["PL_DateDebut"] = new DateTime(2026, 1, 15, 9, 0, 0),
["PL_DateFin"] = new DateTime(2026, 1, 15, 10, 0, 0),
["PL_IDTypeActivite"] = 0L,
["PL_IDStatut"] = 0L,
["PL_IDCollaborateur"] = 0L,
["PL_IDOrigineAnnul"] = 0UL,
["PL_IDMotifAnnul"] = 0UL,
["PL_Prive"] = false,
["PL_Superposable"] = false,
["Archive"] = false
};
private static Dictionary OmikaRendezVousDict(
long pkid, string? objet, string? reference)
=> new()
{
["RV_PKID"] = pkid,
["RV_Objet"] = objet,
["RV_Date"] = new DateOnly(2026, 1, 15),
["RV_CleType"] = null,
["RV_CleStatut"] = null,
["RV_IdLieu"] = 0UL,
["RV_IdDossier"] = 0L,
["RV_IdInter"] = 0L,
["RV_IdSociete"] = 0L,
["RV_CleOrigineAnnu"] = null,
["RV_CleMotifAnnu"] = null,
["GUID"] = null,
["Archive"] = false
};
// =========================================================================
// SpyingHfsqlConnection
// =========================================================================
private sealed class SpyingHfsqlConnection : IHfsqlConnection
{
public HfsqlOptions Options => new();
public HfsqlConnectionState State { get; private set; } = HfsqlConnectionState.Closed;
public int QueryCount { get; private set; }
public bool ThrowOnQuery { get; set; }
public string? LastSql { get; private set; }
public IReadOnlyList