/Data/Persistence/Level1/BaseRowAdapter.cs

http://dpo.codeplex.com · C# · 301 lines · 213 code · 69 blank · 19 comment · 30 complexity · ff9a19e3433a08e46942554c888010af MD5 · raw file

  1. //--------------------------------------------------------------------------------------------------//
  2. // //
  3. // DPO(Data Persistent Object) //
  4. // //
  5. // Copyright(c) Datum Connect Inc. //
  6. // //
  7. // This source code is subject to terms and conditions of the Datum Connect Software License. A //
  8. // copy of the license can be found in the License.html file at the root of this distribution. If //
  9. // you cannot locate the Datum Connect Software License, please send an email to //
  10. // datconn@gmail.com. By using this source code in any fashion, you are agreeing to be bound //
  11. // by the terms of the Datum Connect Software License. //
  12. // //
  13. // You must not remove this notice, or any other, from this software. //
  14. // //
  15. // //
  16. //--------------------------------------------------------------------------------------------------//
  17. using System;
  18. using System.Collections.Generic;
  19. using System.Linq;
  20. using System.Text;
  21. using System.Data;
  22. namespace Sys.Data
  23. {
  24. public abstract class BaseRowAdapter: System.Collections.IEnumerable
  25. {
  26. protected ColumnAdapterCollection columns;
  27. protected DataFieldCollection fields;
  28. private TableName tableName;
  29. protected Locator locator;
  30. private DataRow loadedRow = null; //existing row
  31. private bool? exists = null;
  32. public BaseRowAdapter(TableName tname, Locator locator)
  33. {
  34. this.columns = new ColumnAdapterCollection();
  35. this.fields = new DataFieldCollection();
  36. this.tableName = tname;
  37. this.locator = locator;
  38. }
  39. public TableName TableName
  40. {
  41. get { return this.tableName; }
  42. }
  43. protected void UpdateWhere(Locator where)
  44. {
  45. this.locator = where;
  46. }
  47. public override string ToString()
  48. {
  49. return string.Join<ColumnAdapter>(",", columns);
  50. }
  51. public System.Collections.IEnumerator GetEnumerator()
  52. {
  53. return columns.GetEnumerator();
  54. }
  55. protected SqlTrans transaction = null;
  56. public void SetTransaction(SqlTrans transaction)
  57. {
  58. this.transaction = transaction;
  59. }
  60. public void Validate()
  61. {
  62. MetaTable metaTable = tableName.GetCachedMetaTable();
  63. foreach (ColumnAdapter column in columns)
  64. {
  65. DataField field = column.Field;
  66. if (field.Saved || field.Primary)
  67. {
  68. MetaColumn metaColumn = metaTable[field.Name];
  69. if (!metaColumn.Nullable && (column.Value == System.DBNull.Value || column.Value == null))
  70. throw new Sys.JException("Column[{0}] value cannot be null", field.Name);
  71. if (metaColumn.Oversize(column.Value))
  72. throw new Sys.JException("Column[{0}] is oversize, limit={1}, actual={2}", field.Name, metaColumn.Length, ((string)(column.Value)).Length);
  73. }
  74. }
  75. }
  76. private bool insertIdentityOn = false;
  77. public bool InsertIdentityOn
  78. {
  79. get { return this.insertIdentityOn; }
  80. set { this.insertIdentityOn = value; }
  81. }
  82. public ValueChangedHandler ValueChangedHandler
  83. {
  84. set
  85. {
  86. foreach (ColumnAdapter column in columns)
  87. {
  88. column.ValueChanged += value;
  89. }
  90. }
  91. }
  92. #region private SQL Query String Template
  93. private string selectCommandTemplate
  94. {
  95. get { return string.Format("SELECT {0} FROM {1} WHERE {2}", "{0}", tableName, locator); }
  96. }
  97. private string updateCommandTemplate
  98. {
  99. get { return string.Format("UPDATE {0} SET {1} WHERE {2}", tableName, "{0}", locator); }
  100. }
  101. private string insertCommandTemplate
  102. {
  103. get { return string.Format("INSERT {0}({1}) VALUES({2}) {3}", tableName, "{0}", "{1}", "{2}"); }
  104. }
  105. private string deleteCommandTemplate
  106. {
  107. get { return string.Format("DELETE FROM {0} WHERE {1}", tableName, locator); }
  108. }
  109. #endregion
  110. #region private Select/Update/Insert/Delete/Where Query String
  111. protected string updateQuery()
  112. {
  113. string SQL = "";
  114. foreach (DataField field in fields)
  115. {
  116. if (field.Saved)
  117. {
  118. if (SQL != "")
  119. SQL += ",";
  120. SQL += field.UpdateString();
  121. }
  122. }
  123. SQL = string.Format(updateCommandTemplate, SQL);
  124. return SQL;
  125. }
  126. protected string insertQuery()
  127. {
  128. string SQL0 = "";
  129. string SQL1 = "";
  130. string SQL2 = "";
  131. bool hasIdentity = false;
  132. foreach (DataField field in fields)
  133. {
  134. if (SQL0 != "")
  135. SQL0 += ",";
  136. if (SQL1 != "")
  137. SQL1 += ",";
  138. if (field.Identity)
  139. {
  140. hasIdentity = true;
  141. if (!this.InsertIdentityOn)
  142. SQL2 = string.Format(";SET @{0}=@@IDENTITY", field.Name); //bug : only suport one identity column
  143. else
  144. {
  145. string[] s = field.InsertString();
  146. SQL0 += s[0];
  147. SQL1 += s[1];
  148. }
  149. }
  150. else if (field.Saved)
  151. {
  152. string[] s = field.InsertString();
  153. SQL0 += s[0];
  154. SQL1 += s[1];
  155. }
  156. }
  157. if (this.InsertIdentityOn && hasIdentity)
  158. {
  159. string SQL = string.Format(insertCommandTemplate, SQL0, SQL1, "");
  160. return string.Format("SET IDENTITY_INSERT {0} ON; {1}; SET IDENTITY_INSERT {0} OFF", tableName, SQL);
  161. }
  162. return string.Format(insertCommandTemplate, SQL0, SQL1, SQL2);
  163. }
  164. protected string selectQuery()
  165. {
  166. string selector = string.Join(",", fields.Select(field => string.Format("[{0}]", field.Name))); ;
  167. return string.Format(selectCommandTemplate, selector);
  168. }
  169. protected string deleteQuery()
  170. {
  171. return deleteCommandTemplate;
  172. }
  173. #endregion
  174. protected DataRow LoadRecord()
  175. {
  176. if (RefreshRow())
  177. {
  178. foreach (ColumnAdapter column in this.columns)
  179. column.UpdateValue(this.loadedRow);
  180. }
  181. return this.loadedRow;
  182. }
  183. protected bool RefreshRow()
  184. {
  185. SqlCmd sqlCmd = new SqlCmd(this.tableName.Provider, selectQuery());
  186. foreach (ColumnAdapter column in columns)
  187. {
  188. column.AddParameter(sqlCmd);
  189. }
  190. DataTable dt = sqlCmd.ReadDataTable();
  191. if (dt.Rows.Count == 0)
  192. {
  193. this.loadedRow = dt.NewRow();
  194. this.exists = false;
  195. return false;
  196. }
  197. if (dt.Rows.Count > 1 && this.locator.Unique)
  198. throw new ApplicationException("ERROR: Row is not unique.");
  199. this.loadedRow = dt.Rows[0];
  200. this.exists = true;
  201. return true;
  202. }
  203. public bool Exists
  204. {
  205. get
  206. {
  207. if (this.exists == null)
  208. {
  209. return RefreshRow();
  210. }
  211. else
  212. return (bool)exists;
  213. }
  214. }
  215. /// <summary>
  216. /// Row loaded from SQL Server
  217. /// </summary>
  218. public DataRow Row1
  219. {
  220. get
  221. {
  222. if (this.exists == null)
  223. {
  224. RefreshRow();
  225. return this.loadedRow;
  226. }
  227. else
  228. return this.loadedRow;
  229. }
  230. }
  231. }
  232. }