ProductDatabaseManager.cs 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  1. using System;
  2. using System.Collections.Generic;
  3. using System.IO;
  4. using Newtonsoft.Json;
  5. using TeamAAS.Database.Models;
  6. namespace TeamAAS.Database.Services
  7. {
  8. /// <summary>
  9. /// 产品数据库管理器:每个产品一个数据库(跟着产品走)。
  10. /// 配置持久化到「产品目录\db.json」;缺省用 SQLite(产品目录\product.db)。
  11. /// 宿主只需给产品名,路径经 <see cref="PathHelper.ProductsDir"/> 拼取。
  12. /// 后续可扩展为“一个产品分多个 db 文件”(届时把单实例缓存换成 产品→多库 的映射即可)。
  13. /// </summary>
  14. public static class ProductDatabaseManager
  15. {
  16. private static readonly Dictionary<string, ProductDatabase> _cache =
  17. new Dictionary<string, ProductDatabase>(StringComparer.OrdinalIgnoreCase);
  18. private static readonly object _sync = new object();
  19. /// <summary>产品目录(Products\产品名)。</summary>
  20. public static string GetProductDir(string productName)
  21. => Path.Combine(PathHelper.ProductsDir, productName ?? "");
  22. /// <summary>产品数据库配置文件路径(产品目录\db.json)。</summary>
  23. public static string GetConfigPath(string productName)
  24. => Path.Combine(GetProductDir(productName), "db.json");
  25. /// <summary>取(或创建)产品的数据库实例(缓存;不自动打开连接)。</summary>
  26. public static ProductDatabase GetOrCreate(string productName)
  27. {
  28. if (string.IsNullOrWhiteSpace(productName)) return null;
  29. lock (_sync)
  30. {
  31. if (_cache.TryGetValue(productName, out var cached) && cached != null)
  32. return cached;
  33. var db = new ProductDatabase(LoadConfig(productName));
  34. _cache[productName] = db;
  35. return db;
  36. }
  37. }
  38. /// <summary>按最新 db.json 重建产品数据库实例(改配置后调用;会释放旧实例)。</summary>
  39. public static ProductDatabase Recreate(string productName)
  40. {
  41. if (string.IsNullOrWhiteSpace(productName)) return null;
  42. lock (_sync)
  43. {
  44. if (_cache.TryGetValue(productName, out var old))
  45. {
  46. try { old?.Dispose(); } catch { }
  47. _cache.Remove(productName);
  48. }
  49. var db = new ProductDatabase(LoadConfig(productName));
  50. _cache[productName] = db;
  51. return db;
  52. }
  53. }
  54. /// <summary>读产品数据库配置;无 db.json 时回退默认 SQLite(产品目录\product.db)。</summary>
  55. public static DatabaseConfig LoadConfig(string productName)
  56. {
  57. var dir = GetProductDir(productName);
  58. try
  59. {
  60. var path = GetConfigPath(productName);
  61. if (File.Exists(path))
  62. {
  63. var cfg = JsonConvert.DeserializeObject<DatabaseConfig>(File.ReadAllText(path));
  64. if (cfg != null)
  65. {
  66. cfg.Name = productName; // 产品名以目录为准
  67. return cfg;
  68. }
  69. }
  70. }
  71. catch { }
  72. return new DatabaseConfig
  73. {
  74. Id = Guid.NewGuid(),
  75. Name = productName,
  76. ProviderType = "sqlite",
  77. Server = Path.Combine(dir, "product.db")
  78. };
  79. }
  80. /// <summary>保存产品数据库配置到 db.json。</summary>
  81. public static bool SaveConfig(string productName, DatabaseConfig config)
  82. {
  83. if (string.IsNullOrWhiteSpace(productName) || config == null) return false;
  84. try
  85. {
  86. var dir = GetProductDir(productName);
  87. if (!Directory.Exists(dir)) Directory.CreateDirectory(dir);
  88. config.Name = productName;
  89. File.WriteAllText(GetConfigPath(productName),
  90. JsonConvert.SerializeObject(config, Formatting.Indented));
  91. return true;
  92. }
  93. catch
  94. {
  95. return false;
  96. }
  97. }
  98. /// <summary>关闭并移除某产品的缓存实例。</summary>
  99. public static void Close(string productName)
  100. {
  101. if (string.IsNullOrWhiteSpace(productName)) return;
  102. lock (_sync)
  103. {
  104. if (_cache.TryGetValue(productName, out var db))
  105. {
  106. try { db?.Dispose(); } catch { }
  107. _cache.Remove(productName);
  108. }
  109. }
  110. }
  111. /// <summary>关闭并移除全部缓存实例(退出 / 切换产品前调用)。</summary>
  112. public static void CloseAll()
  113. {
  114. lock (_sync)
  115. {
  116. foreach (var kv in _cache)
  117. {
  118. try { kv.Value?.Dispose(); } catch { }
  119. }
  120. _cache.Clear();
  121. }
  122. }
  123. }
  124. }