SqlCommand.cs 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367
  1. //
  2. // System.Data.SqlClient.SqlCommand.cs
  3. //
  4. // Author:
  5. // Rodrigo Moya ([email protected])
  6. // Daniel Morgan ([email protected])
  7. //
  8. // (C) Ximian, Inc 2002
  9. //
  10. // use #define DEBUG_SqlCommand if you want to spew debug messages
  11. // #define DEBUG_SqlCommand
  12. using System;
  13. using System.ComponentModel;
  14. using System.Data;
  15. using System.Data.Common;
  16. using System.Runtime.InteropServices;
  17. using System.Xml;
  18. namespace System.Data.SqlClient
  19. {
  20. /// <summary>
  21. /// Represents a SQL statement that is executed
  22. /// while connected to a SQL database.
  23. /// </summary>
  24. // public sealed class SqlCommand : Component, IDbCommand, ICloneable
  25. public sealed class SqlCommand : IDbCommand
  26. {
  27. // FIXME: Console.WriteLine() is used for debugging throughout
  28. #region Fields
  29. string sql = "";
  30. int timeout = 30;
  31. // default is 30 seconds
  32. // for command execution
  33. SqlConnection conn = null;
  34. SqlTransaction trans = null;
  35. CommandType cmdType = CommandType.Text;
  36. bool designTime = false;
  37. SqlParameterCollection parmCollection = new
  38. SqlParameterCollection();
  39. #endregion // Fields
  40. #region Constructors
  41. public SqlCommand()
  42. {
  43. sql = "";
  44. }
  45. public SqlCommand (string cmdText)
  46. {
  47. sql = cmdText;
  48. }
  49. public SqlCommand (string cmdText, SqlConnection connection)
  50. {
  51. sql = cmdText;
  52. conn = connection;
  53. }
  54. public SqlCommand (string cmdText, SqlConnection connection,
  55. SqlTransaction transaction)
  56. {
  57. sql = cmdText;
  58. conn = connection;
  59. trans = transaction;
  60. }
  61. #endregion // Constructors
  62. #region Methods
  63. [MonoTODO]
  64. public void Cancel ()
  65. {
  66. throw new NotImplementedException ();
  67. }
  68. // FIXME: is this the correct way to return a stronger type?
  69. [MonoTODO]
  70. IDbDataParameter IDbCommand.CreateParameter ()
  71. {
  72. return CreateParameter ();
  73. }
  74. [MonoTODO]
  75. public SqlParameter CreateParameter ()
  76. {
  77. return new SqlParameter ();
  78. }
  79. [MonoTODO]
  80. public int ExecuteNonQuery ()
  81. {
  82. IntPtr pgResult; // PGresult
  83. int rowsAffected = -1;
  84. ExecStatusType execStatus;
  85. String rowsAffectedString;
  86. if(conn.State != ConnectionState.Open)
  87. throw new InvalidOperationException("ConnnectionState is not Open");
  88. // FIXME: PQexec blocks
  89. // while PQsendQuery is non-blocking
  90. // which is better to use?
  91. // int PQsendQuery(PGconn *conn,
  92. // const char *query);
  93. // execute SQL command
  94. // uses internal property to get the PGConn IntPtr
  95. pgResult = PostgresLibrary.
  96. PQexec (conn.PostgresConnection, sql);
  97. execStatus = PostgresLibrary.
  98. PQresultStatus (pgResult);
  99. if(execStatus == ExecStatusType.PGRES_COMMAND_OK)
  100. {
  101. rowsAffectedString = PostgresLibrary.
  102. PQcmdTuples (pgResult);
  103. #if DEBUG_SqlCommand
  104. Console.WriteLine("rowsAffectedString: " +
  105. rowsAffectedString);
  106. #endif // DEBUG_SqlCommand
  107. if(rowsAffectedString != null)
  108. if(rowsAffectedString.Equals("") == false)
  109. rowsAffected = int.Parse(rowsAffectedString);
  110. }
  111. else
  112. {
  113. String errorMessage = "ExecuteNonQuery execution failure";
  114. errorMessage = PostgresLibrary.
  115. PQresStatus(execStatus);
  116. errorMessage += " " + PostgresLibrary.
  117. PQresultErrorMessage(pgResult);
  118. throw new SqlException(0, 0,
  119. errorMessage, 0, "",
  120. conn.DataSource, "SqlCommand", 0);
  121. }
  122. #if DEBUG_SqlCommand
  123. String cmdStatus;
  124. cmdStatus = PostgresLibrary.
  125. PQcmdStatus(pgResult);
  126. Console.WriteLine("*** Command Status: " +
  127. cmdStatus);
  128. #endif // DEBUG_SqlCommand
  129. PostgresLibrary.PQclear (pgResult);
  130. // FIXME: get number of rows
  131. // affected for INSERT, UPDATE, or DELETE
  132. // any other, return -1 (such as, CREATE TABLE)
  133. return rowsAffected;
  134. }
  135. // FIXME: temporarily commmented out, so I could get a simple working
  136. // SqlConnection and SqlCommand. I had to temporarily
  137. // comment it out the ExecuteReader in IDbCommand as well.
  138. /*
  139. [MonoTODO]
  140. IDataReader IDbCommand.ExecuteReader ()
  141. {
  142. throw new NotImplementedException ();
  143. }
  144. [MonoTODO]
  145. SqlDataReader ExecuteReader ()
  146. {
  147. throw new NotImplementedException ();
  148. }
  149. [MonoTODO]
  150. IDataReader IDbCommand.ExecuteReader (
  151. CommandBehavior behavior)
  152. {
  153. throw new NotImplementedException ();
  154. }
  155. [MonoTODO]
  156. public SqlDataReader ExecuteReader (CommandBehavior behavior)
  157. {
  158. throw new NotImplementedException ();
  159. }
  160. */
  161. [MonoTODO]
  162. public object ExecuteScalar ()
  163. {
  164. throw new NotImplementedException ();
  165. }
  166. [MonoTODO]
  167. public XmlReader ExecuteXmlReader ()
  168. {
  169. throw new NotImplementedException ();
  170. }
  171. [MonoTODO]
  172. public void Prepare ()
  173. {
  174. // FIXME: parameters have to be implemented for this
  175. throw new NotImplementedException ();
  176. }
  177. [MonoTODO]
  178. public SqlCommand Clone ()
  179. {
  180. throw new NotImplementedException ();
  181. }
  182. #endregion // Methods
  183. #region Properties
  184. public string CommandText {
  185. get {
  186. return sql;
  187. }
  188. set {
  189. sql = value;
  190. }
  191. }
  192. public int CommandTimeout {
  193. get {
  194. return timeout;
  195. }
  196. set {
  197. // FIXME: if value < 0, throw
  198. // ArgumentException
  199. // if (value < 0)
  200. // throw ArgumentException;
  201. timeout = value;
  202. }
  203. }
  204. public CommandType CommandType {
  205. get {
  206. return cmdType;
  207. }
  208. set {
  209. cmdType = value;
  210. }
  211. }
  212. // FIXME: for property Connection, is this the correct
  213. // way to handle a return of a stronger type?
  214. IDbConnection IDbCommand.Connection {
  215. get {
  216. return Connection;
  217. }
  218. set {
  219. // FIXME: throw an InvalidOperationException
  220. // if the change was during a
  221. // transaction in progress
  222. Connection = (SqlConnection) value;
  223. // FIXME: set Transaction property to null
  224. }
  225. }
  226. public SqlConnection Connection {
  227. get {
  228. // conn defaults to null
  229. return conn;
  230. }
  231. set {
  232. // FIXME: throw an InvalidOperationException
  233. // if the change was during
  234. // a transaction in progress
  235. conn = value;
  236. // FIXME: set Transaction property to null
  237. }
  238. }
  239. public bool DesignTimeVisible {
  240. get {
  241. return designTime;
  242. }
  243. set{
  244. designTime = value;
  245. }
  246. }
  247. // FIXME; for property Parameters, is this the correct
  248. // way to handle a stronger return type?
  249. IDataParameterCollection IDbCommand.Parameters {
  250. get {
  251. return Parameters;
  252. }
  253. }
  254. SqlParameterCollection Parameters {
  255. get {
  256. return parmCollection;
  257. }
  258. }
  259. // FIXME: for property Transaction, is this the correct
  260. // way to handle a return of a stronger type?
  261. IDbTransaction IDbCommand.Transaction {
  262. get {
  263. return Transaction;
  264. }
  265. set {
  266. // FIXME: error handling
  267. Transaction = (SqlTransaction) value;
  268. }
  269. }
  270. public SqlTransaction Transaction {
  271. get {
  272. return trans;
  273. }
  274. set {
  275. // FIXME: error handling
  276. trans = value;
  277. }
  278. }
  279. [MonoTODO]
  280. public UpdateRowSource UpdatedRowSource {
  281. // FIXME: do this once DbDataAdaptor
  282. // and DataRow are done
  283. get {
  284. throw new NotImplementedException ();
  285. }
  286. set {
  287. throw new NotImplementedException ();
  288. }
  289. }
  290. #endregion // Properties
  291. #region Destructors
  292. [MonoTODO]
  293. public void Dispose() {
  294. // FIXME: need proper way to release resources
  295. // Dispose(true);
  296. }
  297. [MonoTODO]
  298. ~SqlCommand()
  299. {
  300. // FIXME: need proper way to release resources
  301. // Dispose(false);
  302. }
  303. #endregion //Destructors
  304. }
  305. }