SqlCommandBuilder.cs 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358
  1. //
  2. // System.Data.SqlClient.SqlCommandBuilder.cs
  3. //
  4. // Author:
  5. // Tim Coleman ([email protected])
  6. // Veerapuram Varadhan ([email protected])
  7. //
  8. // Copyright (C) Tim Coleman, 2002
  9. //
  10. //
  11. // Copyright (C) 2004, 2009 Novell, Inc (http://www.novell.com)
  12. //
  13. // Permission is hereby granted, free of charge, to any person obtaining
  14. // a copy of this software and associated documentation files (the
  15. // "Software"), to deal in the Software without restriction, including
  16. // without limitation the rights to use, copy, modify, merge, publish,
  17. // distribute, sublicense, and/or sell copies of the Software, and to
  18. // permit persons to whom the Software is furnished to do so, subject to
  19. // the following conditions:
  20. //
  21. // The above copyright notice and this permission notice shall be
  22. // included in all copies or substantial portions of the Software.
  23. //
  24. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  25. // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  26. // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  27. // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
  28. // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
  29. // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  30. // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  31. //
  32. using System;
  33. using System.Collections;
  34. using System.ComponentModel;
  35. using System.Data;
  36. using System.Data.Common;
  37. using System.Data.SqlTypes;
  38. using System.Text;
  39. namespace System.Data.SqlClient
  40. {
  41. public sealed class SqlCommandBuilder : DbCommandBuilder
  42. {
  43. #region Fields
  44. readonly string _catalogSeparator = ".";
  45. readonly string _schemaSeparator = ".";
  46. readonly CatalogLocation _catalogLocation = CatalogLocation.Start;
  47. #endregion // Fields
  48. #region Constructors
  49. public SqlCommandBuilder ()
  50. {
  51. QuoteSuffix = "]";
  52. QuotePrefix = "[";
  53. }
  54. public SqlCommandBuilder (SqlDataAdapter adapter)
  55. : this ()
  56. {
  57. DataAdapter = adapter;
  58. }
  59. #endregion // Constructors
  60. #region Properties
  61. [DefaultValue (null)]
  62. public new SqlDataAdapter DataAdapter {
  63. get {
  64. return (SqlDataAdapter)base.DataAdapter;
  65. } set {
  66. base.DataAdapter = value;
  67. }
  68. }
  69. [Browsable (false)]
  70. [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
  71. [EditorBrowsable (EditorBrowsableState.Never)]
  72. public
  73. override
  74. string QuotePrefix {
  75. get {
  76. return base.QuotePrefix;
  77. }
  78. set {
  79. if (value != "[" && value != "\"")
  80. throw new ArgumentException ("Only '[' " +
  81. "and '\"' are allowed as value " +
  82. "for the 'QuoteSuffix' property.");
  83. base.QuotePrefix = value;
  84. }
  85. }
  86. [Browsable (false)]
  87. [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
  88. [EditorBrowsable (EditorBrowsableState.Never)]
  89. public
  90. override
  91. string QuoteSuffix {
  92. get {
  93. return base.QuoteSuffix;
  94. }
  95. set {
  96. if (value != "]" && value != "\"")
  97. throw new ArgumentException ("Only ']' " +
  98. "and '\"' are allowed as value " +
  99. "for the 'QuoteSuffix' property.");
  100. base.QuoteSuffix = value;
  101. }
  102. }
  103. [EditorBrowsable (EditorBrowsableState.Never)]
  104. [Browsable (false)]
  105. [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
  106. public override string CatalogSeparator {
  107. get { return _catalogSeparator; }
  108. set {
  109. if (value != _catalogSeparator)
  110. throw new ArgumentException ("Only " +
  111. "'.' is allowed as value " +
  112. "for the 'CatalogSeparator' " +
  113. "property.");
  114. }
  115. }
  116. [EditorBrowsable (EditorBrowsableState.Never)]
  117. [Browsable (false)]
  118. [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
  119. public override string SchemaSeparator {
  120. get { return _schemaSeparator; }
  121. set {
  122. if (value != _schemaSeparator)
  123. throw new ArgumentException ("Only " +
  124. "'.' is allowed as value " +
  125. "for the 'SchemaSeparator' " +
  126. "property.");
  127. }
  128. }
  129. [EditorBrowsable (EditorBrowsableState.Never)]
  130. [Browsable (false)]
  131. [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
  132. public override CatalogLocation CatalogLocation {
  133. get { return _catalogLocation; }
  134. set {
  135. if (value != CatalogLocation.Start)
  136. throw new ArgumentException ("Only " +
  137. "'Start' is allowed as value " +
  138. "for the 'CatalogLocation' " +
  139. "property.");
  140. }
  141. }
  142. #endregion // Properties
  143. #region Methods
  144. public static void DeriveParameters (SqlCommand command)
  145. {
  146. command.DeriveParameters ();
  147. }
  148. public
  149. new
  150. SqlCommand GetDeleteCommand ()
  151. {
  152. return (SqlCommand) base.GetDeleteCommand (false);
  153. }
  154. public
  155. new
  156. SqlCommand GetInsertCommand ()
  157. {
  158. return (SqlCommand) base.GetInsertCommand (false);
  159. }
  160. public
  161. new
  162. SqlCommand GetUpdateCommand ()
  163. {
  164. return (SqlCommand) base.GetUpdateCommand (false);
  165. }
  166. public new SqlCommand GetUpdateCommand (bool useColumnsForParameterNames)
  167. {
  168. return (SqlCommand) base.GetUpdateCommand (useColumnsForParameterNames);
  169. }
  170. public new SqlCommand GetDeleteCommand (bool useColumnsForParameterNames)
  171. {
  172. return (SqlCommand) base.GetDeleteCommand (useColumnsForParameterNames);
  173. }
  174. public new SqlCommand GetInsertCommand (bool useColumnsForParameterNames)
  175. {
  176. return (SqlCommand) base.GetInsertCommand (useColumnsForParameterNames);
  177. }
  178. public override string QuoteIdentifier (string unquotedIdentifier)
  179. {
  180. if (unquotedIdentifier == null)
  181. throw new ArgumentNullException ("unquotedIdentifier");
  182. string prefix = QuotePrefix;
  183. string suffix = QuoteSuffix;
  184. if ((prefix == "[" && suffix != "]") || (prefix == "\"" && suffix != "\""))
  185. throw new ArgumentException ("The QuotePrefix " +
  186. "and QuoteSuffix properties do not match.");
  187. string escaped = unquotedIdentifier.Replace (suffix,
  188. suffix + suffix);
  189. return string.Concat (prefix, escaped, suffix);
  190. }
  191. public override string UnquoteIdentifier (string quotedIdentifier)
  192. {
  193. return base.UnquoteIdentifier (quotedIdentifier);
  194. }
  195. private bool IncludedInInsert (DataRow schemaRow)
  196. {
  197. // If the parameter has one of these properties, then we don't include it in the insert:
  198. // AutoIncrement, Hidden, Expression, RowVersion, ReadOnly
  199. if (!schemaRow.IsNull ("IsAutoIncrement") && (bool) schemaRow ["IsAutoIncrement"])
  200. return false;
  201. if (!schemaRow.IsNull ("IsHidden") && (bool) schemaRow ["IsHidden"])
  202. return false;
  203. if (!schemaRow.IsNull ("IsExpression") && (bool) schemaRow ["IsExpression"])
  204. return false;
  205. if (!schemaRow.IsNull ("IsRowVersion") && (bool) schemaRow ["IsRowVersion"])
  206. return false;
  207. if (!schemaRow.IsNull ("IsReadOnly") && (bool) schemaRow ["IsReadOnly"])
  208. return false;
  209. return true;
  210. }
  211. private bool IncludedInUpdate (DataRow schemaRow)
  212. {
  213. // If the parameter has one of these properties, then we don't include it in the insert:
  214. // AutoIncrement, Hidden, RowVersion
  215. if (!schemaRow.IsNull ("IsAutoIncrement") && (bool) schemaRow ["IsAutoIncrement"])
  216. return false;
  217. if (!schemaRow.IsNull ("IsHidden") && (bool) schemaRow ["IsHidden"])
  218. return false;
  219. if (!schemaRow.IsNull ("IsRowVersion") && (bool) schemaRow ["IsRowVersion"])
  220. return false;
  221. if (!schemaRow.IsNull ("IsExpression") && (bool) schemaRow ["IsExpression"])
  222. return false;
  223. if (!schemaRow.IsNull ("IsReadOnly") && (bool) schemaRow ["IsReadOnly"])
  224. return false;
  225. return true;
  226. }
  227. private bool IncludedInWhereClause (DataRow schemaRow)
  228. {
  229. if ((bool) schemaRow ["IsLong"])
  230. return false;
  231. return true;
  232. }
  233. protected override void ApplyParameterInfo (DbParameter parameter,
  234. DataRow datarow,
  235. StatementType statementType,
  236. bool whereClause)
  237. {
  238. SqlParameter sqlParam = (SqlParameter) parameter;
  239. sqlParam.SqlDbType = (SqlDbType) datarow ["ProviderType"];
  240. object precision = datarow ["NumericPrecision"];
  241. if (precision != DBNull.Value) {
  242. short val = (short) precision;
  243. if (val < byte.MaxValue && val >= byte.MinValue)
  244. sqlParam.Precision = (byte) val;
  245. }
  246. object scale = datarow ["NumericScale"];
  247. if (scale != DBNull.Value) {
  248. short val = ((short) scale);
  249. if (val < byte.MaxValue && val >= byte.MinValue)
  250. sqlParam.Scale = (byte) val;
  251. }
  252. }
  253. protected override
  254. string GetParameterName (int parameterOrdinal)
  255. {
  256. return String.Format ("@p{0}", parameterOrdinal);
  257. }
  258. protected override
  259. string GetParameterName (string parameterName)
  260. {
  261. return String.Format ("@{0}", parameterName);
  262. }
  263. protected override string GetParameterPlaceholder (int parameterOrdinal)
  264. {
  265. return GetParameterName (parameterOrdinal);
  266. }
  267. #endregion // Methods
  268. #region Event Handlers
  269. void RowUpdatingHandler (object sender, SqlRowUpdatingEventArgs args)
  270. {
  271. base.RowUpdatingHandler (args);
  272. }
  273. protected override void SetRowUpdatingHandler (DbDataAdapter adapter)
  274. {
  275. SqlDataAdapter sda = adapter as SqlDataAdapter;
  276. if (sda == null) {
  277. throw new InvalidOperationException ("Adapter needs to be a SqlDataAdapter");
  278. }
  279. if (sda != base.DataAdapter)
  280. sda.RowUpdating += new SqlRowUpdatingEventHandler (RowUpdatingHandler);
  281. else
  282. sda.RowUpdating -= new SqlRowUpdatingEventHandler (RowUpdatingHandler);;
  283. }
  284. protected override DataTable GetSchemaTable (DbCommand srcCommand)
  285. {
  286. using (SqlDataReader rdr = (SqlDataReader) srcCommand.ExecuteReader (CommandBehavior.KeyInfo | CommandBehavior.SchemaOnly))
  287. return rdr.GetSchemaTable ();
  288. }
  289. protected override DbCommand InitializeCommand (DbCommand command)
  290. {
  291. if (command == null) {
  292. command = new SqlCommand ();
  293. } else {
  294. command.CommandTimeout = 30;
  295. command.Transaction = null;
  296. command.CommandType = CommandType.Text;
  297. command.UpdatedRowSource = UpdateRowSource.None;
  298. }
  299. return command;
  300. }
  301. #endregion // Event Handlers
  302. }
  303. }