Data.DataSource.cs 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201
  1. using System;
  2. using System.Collections.Concurrent;
  3. using System.Collections.Generic;
  4. using System.Linq;
  5. using System.Threading.Tasks;
  6. using Vit.Core.Util.ConfigurationManager;
  7. using Vit.Core.Util.Reflection;
  8. using Vit.Linq;
  9. using Vitorm.DataProvider;
  10. namespace Vitorm
  11. {
  12. public partial class Data
  13. {
  14. public partial class DataSource
  15. {
  16. /// <summary>
  17. /// Data.Init("appsettings.Development.json")
  18. /// </summary>
  19. /// <param name="appsettingsFileName"></param>
  20. public virtual DataSource AddDataProviders(string appsettingsFileName)
  21. {
  22. AddDataProviders(new JsonFile(appsettingsFileName));
  23. return this;
  24. }
  25. public virtual DataSource AddDataProviders(JsonFile json, string configPath = "Vitorm.Data")
  26. {
  27. var dataProviderConfigs = json.GetByPath<List<Dictionary<string, object>>>(configPath);
  28. return AddDataProviders(dataProviderConfigs);
  29. }
  30. public virtual DataSource AddDataProviders(IEnumerable<Dictionary<string, object>> dataProviderConfigs)
  31. {
  32. var dataProviders = dataProviderConfigs?.Select(CreateDataProvider).NotNull().ToList();
  33. if (dataProviders?.Any() == true) providerCache.AddRange(dataProviders);
  34. providerMap.Clear();
  35. return this;
  36. }
  37. public virtual bool AddDataProvider(Dictionary<string, object> dataProviderConfig)
  38. {
  39. var provider = CreateDataProvider(dataProviderConfig);
  40. if (provider == null) return false;
  41. providerCache.Insert(0, provider);
  42. providerMap.Clear();
  43. return true;
  44. }
  45. public virtual void ClearDataProviders(Predicate<DataProviderCache> predicate = null)
  46. {
  47. if (predicate != null)
  48. providerCache.RemoveAll(predicate);
  49. else
  50. providerCache.Clear();
  51. providerMap.Clear();
  52. }
  53. #region DataProvider
  54. public virtual IDataProvider DataProvider<Entity>() => DataProvider(typeof(Entity));
  55. public virtual IDataProvider DataProvider(Type entityType)
  56. {
  57. return providerMap.GetOrAdd(entityType, GetDataProviderFromConfig);
  58. }
  59. private IDataProvider GetDataProviderFromConfig(Type entityType)
  60. {
  61. var classFullName = entityType.FullName;
  62. return providerCache.FirstOrDefault(cache => cache.Match(classFullName))?.dataProvider
  63. ?? throw new NotImplementedException("can not find config for type: " + classFullName);
  64. }
  65. /// <summary>
  66. /// nameOrNamespace: dataProviderName or dataProviderNamespace
  67. /// </summary>
  68. /// <param name="nameOrNamespace"></param>
  69. /// <returns></returns>
  70. public virtual IDataProvider DataProvider(string nameOrNamespace)
  71. {
  72. return providerCache.FirstOrDefault(cache => cache.name == nameOrNamespace || cache.Match(nameOrNamespace))?.dataProvider;
  73. }
  74. readonly ConcurrentDictionary<Type, IDataProvider> providerMap = new();
  75. readonly List<DataProviderCache> providerCache = new();
  76. DataProviderCache CreateDataProvider(Dictionary<string, object> dataProviderConfig)
  77. {
  78. /*
  79. "provider": "Vitorm.Sqlite.DataProvider",
  80. "assemblyName": "Vitorm.Sqlite",
  81. "assemblyFile": "Vitorm.Sqlite.dll",
  82. */
  83. object temp;
  84. string provider = dataProviderConfig.TryGetValue("provider", out temp) ? temp as string : null;
  85. string assemblyName = dataProviderConfig.TryGetValue("assemblyName", out temp) ? temp as string : null;
  86. string assemblyFile = dataProviderConfig.TryGetValue("assemblyFile", out temp) ? temp as string : null;
  87. Type providerType;
  88. IDataProvider dataProvider;
  89. // #1 load
  90. providerType = ObjectLoader.GetType(className: provider, assemblyName: assemblyName, assemblyFile: assemblyFile);
  91. dataProvider = providerType?.GetConstructor(Type.EmptyTypes)?.Invoke(new object[] { }) as IDataProvider;
  92. // #2 try load by database type (Sqlite/MySql/SqlServer)
  93. if (dataProvider == null)
  94. {
  95. providerType = ObjectLoader.GetType(className: $"Vitorm.{provider}.DataProvider", assemblyName: $"Vitorm.{provider}", assemblyFile: $"Vitorm.{provider}.dll");
  96. dataProvider = providerType?.GetConstructor(Type.EmptyTypes)?.Invoke(new object[] { }) as IDataProvider;
  97. }
  98. if (dataProvider == null) return null;
  99. dataProvider.Init(dataProviderConfig);
  100. return new DataProviderCache(dataProvider, dataProviderConfig);
  101. }
  102. #endregion
  103. #region CRUD Sync
  104. // #0 Schema : TryCreateTable TryDropTable
  105. public virtual void TryCreateTable<Entity>() => DataProvider<Entity>().TryCreateTable<Entity>();
  106. public virtual void TryDropTable<Entity>() => DataProvider<Entity>().TryDropTable<Entity>();
  107. public virtual void Truncate<Entity>() => DataProvider<Entity>().Truncate<Entity>();
  108. // #1 Create : Add AddRange
  109. public virtual Entity Add<Entity>(Entity entity) => DataProvider<Entity>().Add<Entity>(entity);
  110. public virtual void AddRange<Entity>(IEnumerable<Entity> entities) => DataProvider<Entity>().AddRange<Entity>(entities);
  111. // #2 Retrieve : Get Query
  112. public virtual Entity Get<Entity>(object keyValue) => DataProvider<Entity>().Get<Entity>(keyValue);
  113. public virtual IQueryable<Entity> Query<Entity>() => DataProvider<Entity>().Query<Entity>();
  114. // #3 Update: Update UpdateRange
  115. public virtual int Update<Entity>(Entity entity) => DataProvider<Entity>().Update<Entity>(entity);
  116. public virtual int UpdateRange<Entity>(IEnumerable<Entity> entities) => DataProvider<Entity>().UpdateRange<Entity>(entities);
  117. // #4 Delete : Delete DeleteRange DeleteByKey DeleteByKeys
  118. public virtual int Delete<Entity>(Entity entity) => DataProvider<Entity>().Delete<Entity>(entity);
  119. public virtual int DeleteRange<Entity>(IEnumerable<Entity> entities) => DataProvider<Entity>().DeleteRange<Entity>(entities);
  120. public virtual int DeleteByKey<Entity>(object keyValue) => DataProvider<Entity>().DeleteByKey<Entity>(keyValue);
  121. public virtual int DeleteByKeys<Entity, Key>(IEnumerable<Key> keys) => DataProvider<Entity>().DeleteByKeys<Entity, Key>(keys);
  122. #endregion
  123. #region CRUD Async
  124. // #0 Schema : TryCreateTable TryDropTable
  125. public virtual Task TryCreateTableAsync<Entity>() => DataProvider<Entity>().TryCreateTableAsync<Entity>();
  126. public virtual Task TryDropTableAsync<Entity>() => DataProvider<Entity>().TryDropTableAsync<Entity>();
  127. public virtual Task TruncateAsync<Entity>() => DataProvider<Entity>().TruncateAsync<Entity>();
  128. // #1 Create : Add AddRange
  129. public virtual Task<Entity> AddAsync<Entity>(Entity entity) => DataProvider<Entity>().AddAsync<Entity>(entity);
  130. public virtual Task AddRangeAsync<Entity>(IEnumerable<Entity> entities) => DataProvider<Entity>().AddRangeAsync<Entity>(entities);
  131. // #2 Retrieve : Get Query
  132. public virtual Task<Entity> GetAsync<Entity>(object keyValue) => DataProvider<Entity>().GetAsync<Entity>(keyValue);
  133. // #3 Update: Update UpdateRange
  134. public virtual Task<int> UpdateAsync<Entity>(Entity entity) => DataProvider<Entity>().UpdateAsync<Entity>(entity);
  135. public virtual Task<int> UpdateRangeAsync<Entity>(IEnumerable<Entity> entities) => DataProvider<Entity>().UpdateRangeAsync<Entity>(entities);
  136. // #4 Delete : Delete DeleteRange DeleteByKey DeleteByKeys
  137. public virtual Task<int> DeleteAsync<Entity>(Entity entity) => DataProvider<Entity>().DeleteAsync<Entity>(entity);
  138. public virtual Task<int> DeleteRangeAsync<Entity>(IEnumerable<Entity> entities) => DataProvider<Entity>().DeleteRangeAsync<Entity>(entities);
  139. public virtual Task<int> DeleteByKeyAsync<Entity>(object keyValue) => DataProvider<Entity>().DeleteByKeyAsync<Entity>(keyValue);
  140. public virtual Task<int> DeleteByKeysAsync<Entity, Key>(IEnumerable<Key> keys) => DataProvider<Entity>().DeleteByKeysAsync<Entity, Key>(keys);
  141. #endregion
  142. }
  143. }
  144. }