You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

222 lines
7.1 KiB

8 months ago
  1. using Npgsql;
  2. using Oracle.ManagedDataAccess.Client;
  3. using System;
  4. using System.Configuration;
  5. using System.Data;
  6. using System.Data.SqlClient;
  7. using System.Xml;
  8. namespace Mirle.Component.Database
  9. {
  10. /// <summary>
  11. /// 關聯式資料庫類別
  12. /// </summary>
  13. public class RelationDatabaseFactory : IDisposable
  14. {
  15. /// <summary>
  16. /// 建構式
  17. /// </summary>
  18. protected RelationDatabaseFactory()
  19. {
  20. Opne();
  21. }
  22. /// <summary>
  23. /// 建構式
  24. /// </summary>
  25. /// <param name="databaseType">資料庫類別</param>
  26. protected RelationDatabaseFactory(RelationDatabaseType databaseType)
  27. {
  28. _databaseType = databaseType;
  29. Opne();
  30. }
  31. /// <summary>
  32. /// 關聯式資料庫物件
  33. /// </summary>
  34. private static volatile RelationDatabaseFactory _relationDB;
  35. /// <summary>
  36. /// 關聯式資料庫物件鎖定
  37. /// </summary>
  38. private static readonly object _syncRoot = new object();
  39. /// <summary>
  40. /// 關聯式資料庫類別
  41. /// </summary>
  42. private RelationDatabaseType _databaseType = RelationDatabaseType.Oracle;
  43. /// <summary>
  44. /// 關聯式資料庫連線
  45. /// </summary>
  46. public IDbConnection Connection
  47. {
  48. get
  49. {
  50. return Opne();
  51. }
  52. }
  53. /// <summary>
  54. /// 關聯式資料庫類別實例
  55. /// </summary>
  56. /// <param name="databaseType">資料庫類別</param>
  57. /// <returns>關聯式資料庫類別</returns>
  58. /// <remarks>預設為 Oracle Database</remarks>
  59. public static RelationDatabaseFactory Instance(RelationDatabaseType databaseType = RelationDatabaseType.Oracle)
  60. {
  61. if (_relationDB == null)
  62. {
  63. lock (_syncRoot) // 鎖定避免多執行緒重覆呼叫建立物件
  64. {
  65. _relationDB = new RelationDatabaseFactory(databaseType);
  66. }
  67. }
  68. return _relationDB;
  69. }
  70. /// <summary>
  71. /// 開啟資料庫連線
  72. /// </summary>
  73. /// <returns>資料庫連線</returns>
  74. /// <exception cref="ArgumentException">資料庫類別未定義</exception>
  75. private IDbConnection Opne()
  76. {
  77. IDbConnection conn;
  78. switch (_databaseType)
  79. {
  80. case RelationDatabaseType.Oracle:
  81. {
  82. conn = new OracleConnection(ConfigurationManager.ConnectionStrings["Oracle"].ConnectionString);
  83. break;
  84. }
  85. case RelationDatabaseType.Mssql:
  86. {
  87. conn = new SqlConnection(ConfigurationManager.ConnectionStrings["Mssql"].ConnectionString);
  88. break;
  89. }
  90. case RelationDatabaseType.PostgreSQL:
  91. {
  92. conn = new NpgsqlConnection(ConfigurationManager.ConnectionStrings["PostgreSQL"].ConnectionString);
  93. break;
  94. }
  95. default:
  96. {
  97. throw new ArgumentException("Undefined database or not support.");
  98. }
  99. }
  100. if (conn.State != ConnectionState.Open)
  101. conn.Open();
  102. return conn;
  103. }
  104. /// <summary>
  105. /// 設定資料庫類別
  106. /// </summary>
  107. /// <param name="relationDatabaseType">資料庫類別列舉項目</param>
  108. public void SetRelationDatabaseType(RelationDatabaseType relationDatabaseType)
  109. {
  110. _databaseType = relationDatabaseType;
  111. }
  112. /// <summary>
  113. /// 確認交易
  114. /// </summary>
  115. /// <param name="trans">資料庫交易</param>
  116. /// <param name="result">交易結果</param>
  117. /// <returns>True/False</returns>
  118. public bool Commit(IDbTransaction trans, out string result)
  119. {
  120. try
  121. {
  122. trans.Commit();
  123. result = "Success";
  124. return true;
  125. }
  126. catch (Exception ex)
  127. {
  128. trans.Rollback();
  129. result = ex.Message;
  130. return false;
  131. }
  132. finally
  133. {
  134. trans.Dispose();
  135. }
  136. }
  137. /// <summary>
  138. /// 取得資料庫語法
  139. /// </summary>
  140. /// <param name="filePath">完整檔案路徑</param>
  141. /// <param name="nodeName">完整子節點名稱</param>
  142. /// <returns>資料庫語法</returns>
  143. public string GetScriptContent(string filePath, string nodeName)
  144. {
  145. XmlDocument xmlDocument = new XmlDocument();
  146. xmlDocument.Load(filePath);
  147. return xmlDocument.SelectSingleNode(nodeName).InnerText.Trim();
  148. }
  149. /// <summary>
  150. /// 取得資料庫語法
  151. /// </summary>
  152. /// <param name="filePath">檔案路徑</param>
  153. /// <param name="fileName">檔案名稱</param>
  154. /// <param name="nodeName">完整子節點名稱</param>
  155. /// <returns>資料庫語法</returns>
  156. public string GetScriptContent(string filePath, string fileName, string nodeName)
  157. {
  158. XmlDocument xmlDocument = new XmlDocument();
  159. xmlDocument.Load($"{filePath}\\{fileName}");
  160. return xmlDocument.SelectSingleNode(nodeName).InnerText.Trim();
  161. }
  162. #region Destructure
  163. /// <summary>
  164. /// 釋放旗標
  165. /// </summary>
  166. private bool disposedValue;
  167. /// <summary>
  168. /// 釋放物件
  169. /// </summary>
  170. public void Dispose()
  171. {
  172. // 請勿變更此程式碼。請將清除程式碼放入 'Dispose(bool disposing)' 方法
  173. Dispose(disposing: true);
  174. GC.SuppressFinalize(this);
  175. }
  176. /// <summary>
  177. /// 解構式
  178. /// </summary>
  179. ~RelationDatabaseFactory() => Dispose(false); // 僅有當 'Dispose(bool disposing)' 具有會釋出非受控資源的程式碼時,才覆寫完成項
  180. /// <summary>
  181. /// 釋放物件
  182. /// </summary>
  183. /// <param name="disposing">受控物件釋放旗標</param>
  184. protected virtual void Dispose(bool disposing)
  185. {
  186. if (!disposedValue)
  187. {
  188. if (disposing)
  189. {
  190. // 處置受控狀態 (受控物件)
  191. }
  192. // 釋出非受控資源 (非受控物件) 並覆寫完成項
  193. // 將大型欄位設為 Null
  194. disposedValue = true;
  195. }
  196. }
  197. #endregion
  198. }
  199. /// <summary>
  200. /// 關聯式資料庫類別
  201. /// </summary>
  202. public enum RelationDatabaseType
  203. {
  204. /// <summary>
  205. /// Oracle Database
  206. /// </summary>
  207. Oracle,
  208. /// <summary>
  209. /// Microsoft SQL Server Database
  210. /// </summary>
  211. Mssql,
  212. /// <summary>
  213. /// PostgreSQL Database
  214. /// </summary>
  215. PostgreSQL
  216. }
  217. }