using AyCode.Core.Extensions; using AyCode.Core.Interfaces; using AyCode.Interfaces.Entities; using AyCode.Services.SignalRs; using AyCode.Utils.Extensions; using AyCode.Utils.Wrappers; using DevExpress.Blazor.Scheduler.Internal; using FruitBank.Common; using FruitBank.Common.Dtos; using FruitBank.Common.Entities; using FruitBank.Common.SignalRs; using FruitBankHybrid.Shared.Services.SignalRs; using Nop.Core.Domain.Common; using Nop.Core.Domain.Orders; using System.Collections.Concurrent; using System.Collections.ObjectModel; using System.Threading; namespace FruitBankHybrid.Shared.Databases; public class ShippingTableItem : Shipping { } public class ShippingDocumentTableItem : ShippingDocument { } public class ShippingItemTableItem : ShippingItem { } public class ShippingItemPalletTableItem : ShippingItemPallet { } public class ProductDtoTableItem : ProductDto { //[Newtonsoft.Json.JsonProperty] //public new ObservableCollection? GenericAttributes { get; set; } } public class OrderDtoTableItem : OrderDto { //[Newtonsoft.Json.JsonProperty] //public new ObservableCollection? GenericAttributes { get; set; } //[Newtonsoft.Json.JsonProperty] //public new ObservableCollection? OrderItemDtos { get; set; } } public class ShippingItemTable : SignalRDataSourceList { private static readonly SignalRCrudTags SignalRCrudTags = new(SignalRTags.GetShippingItems, 0, SignalRTags.AddShippingItem, SignalRTags.UpdateShippingItem, 0); public ShippingItemTable(AcSignalRClientBase signalRClient, params object[]? contextIds) : this(signalRClient, SignalRCrudTags, contextIds) { } public ShippingItemTable(AcSignalRClientBase signalRClient, SignalRCrudTags signalRCrudTags, params object[]? contextIds) : base(signalRClient, signalRCrudTags, contextIds) { } } public class ProductDtoTable(FruitBankSignalRClient fruitBankSignalRClient) : MgObservableCollection { private readonly SemaphoreSlim _semaphoreSlim = new(1); public async Task LoadDataAsync(bool onlyIfEmpty = true) { if (onlyIfEmpty && Count != 0) return this; using (await _semaphoreSlim.UseWaitAsync()) { //Előfordulhat, h egy másik szálban már megtörtént a refresh... - J. if (onlyIfEmpty && Count != 0) return this; var items = (await fruitBankSignalRClient.GetProductDtoTableItems() ?? []); //Clear(); this.Replace(items); //foreach (var productDto in items) //{ // this.UpdateCollection(productDto, false); //} } return this; } } public class OrderDtoTable(FruitBankSignalRClient fruitBankSignalRClient) : MgObservableCollection { private readonly SemaphoreSlim _semaphoreSlim = new(1); public async Task LoadDataAsync(bool onlyIfEmpty = true) { if (onlyIfEmpty && Count != 0) return this; using (await _semaphoreSlim.UseWaitAsync()) { if (Count != 0) return this; var items = (await fruitBankSignalRClient.GetAllOrderDtoTableItems() ?? []); //Clear(); this.Replace(items); //foreach (var orderDto in items) //{ // this.UpdateCollection(orderDto, false); //} } return this; } } public abstract class DatabaseTableBase : SignalRDataSourceObservable where TDataItem : class, IId { protected DatabaseTableBase(AcSignalRClientBase signalRClient, SignalRCrudTags signalRCrudTags, params object[]? contextIds) : base(signalRClient, signalRCrudTags, contextIds) { } //protected readonly SemaphoreSlim _semaphoreSlim = new(1); //public async Task LoadDataAsync(bool onlyIfEmpty = true) //{ // if (onlyIfEmpty && Count != 0) return this; // using (await _semaphoreSlim.UseWaitAsync()) // { // if (Count != 0) return this; // var items = (await fruitBankSignalRClient.GetAllOrderDtoTableItems() ?? []); // Clear(); // foreach (var orderDto in items) // { // this.Add(orderDto); // } // } // return this; //} } public static class LoadingPanelVisibility { public static bool Visible =false; } public static class ObjectLock { private static readonly Dictionary SemaphoresByType = new(); public static SemaphoreSlim GetSemaphore() { lock (SemaphoresByType) { if (!SemaphoresByType.TryGetValue(typeof(TObject), out var semaphore)) { semaphore = new SemaphoreSlim(1); SemaphoresByType[typeof(TObject)] = semaphore; } return semaphore; } } } public class DatabaseClient : DatabaseClientBase { private readonly FruitBankSignalRClient _fruitBankSignalRClient; public DatabaseClient(FruitBankSignalRClient fruitBankSignalRClient) { _fruitBankSignalRClient = fruitBankSignalRClient; AddTable(new ProductDtoTable(_fruitBankSignalRClient)); AddTable(new ShippingItemTable(_fruitBankSignalRClient)); AddTable(new OrderDtoTable(_fruitBankSignalRClient)); } public ProductDtoTable ProductDtoTable { get => (GetRows()! as ProductDtoTable)!; //set => AddRows(value); } public OrderDtoTable OrderDtoTable => (GetRows()! as OrderDtoTable)!; } public abstract class DatabaseClientBase { //private ObservableCollection a = new ObservableCollection(); private readonly ConcurrentDictionary _database = new(); protected void AddTable(IList table)where TEntity: class, IEntityInt { if (GetTableObject() == null) { if (!_database.TryAdd(typeof(TEntity), table)) return; } return; } protected IList? GetTableObject() where T : class, IEntityInt { return _database.GetValueOrDefault(typeof(T)) as IList; } public IEnumerable? GetRows() where T : class, IEntityInt { return GetTableObject(); } public T? GetRow(int id) where T : class, IEntityInt { return GetTableObject()?.FirstOrDefault(x => x.Id == id) as T; } public T AddRow(T entity) where T : class, IEntityInt => AddRow(GetTableObject()!, entity); protected T AddRow(in IList table, T entity) where T : class, IEntityInt { table.Add(entity); return entity; } public void AddRows(IEnumerable entities) where T : class, IEntityInt { var table = GetTableObject()!; foreach (var entity in entities) { AddRow(table, entity); } } public T? DeleteRow(int id) where T : class, IEntityInt { var table = GetTableObject(); if (table == null) return null; var index = table.FindIndex(x => x.Id == id); if (index < 0) return null; var entity = table[index]; table.RemoveAt(index); return entity as T; } }