SqlCommand.cs 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379
  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(
  88. "ConnnectionState is not Open");
  89. // FIXME: PQexec blocks
  90. // while PQsendQuery is non-blocking
  91. // which is better to use?
  92. // int PQsendQuery(PGconn *conn,
  93. // const char *query);
  94. // execute SQL command
  95. // uses internal property to get the PGConn IntPtr
  96. pgResult = PostgresLibrary.
  97. PQexec (conn.PostgresConnection, sql);
  98. execStatus = PostgresLibrary.
  99. PQresultStatus (pgResult);
  100. if(execStatus == ExecStatusType.PGRES_COMMAND_OK)
  101. {
  102. rowsAffectedString = PostgresLibrary.
  103. PQcmdTuples (pgResult);
  104. #if DEBUG_SqlCommand
  105. Console.WriteLine("rowsAffectedString: " +
  106. rowsAffectedString);
  107. #endif // DEBUG_SqlCommand
  108. if(rowsAffectedString != null)
  109. if(rowsAffectedString.Equals("") == false)
  110. rowsAffected = int.Parse(rowsAffectedString);
  111. }
  112. else
  113. {
  114. String errorMessage = "ExecuteNonQuery execution failure";
  115. errorMessage = PostgresLibrary.
  116. PQresStatus(execStatus);
  117. errorMessage += " " + PostgresLibrary.
  118. PQresultErrorMessage(pgResult);
  119. throw new SqlException(0, 0,
  120. errorMessage, 0, "",
  121. conn.DataSource, "SqlCommand", 0);
  122. }
  123. #if DEBUG_SqlCommand
  124. String cmdStatus;
  125. cmdStatus = PostgresLibrary.
  126. PQcmdStatus(pgResult);
  127. Console.WriteLine("*** Command Status: " +
  128. cmdStatus);
  129. #endif // DEBUG_SqlCommand
  130. PostgresLibrary.PQclear (pgResult);
  131. // FIXME: get number of rows
  132. // affected for INSERT, UPDATE, or DELETE
  133. // any other, return -1 (such as, CREATE TABLE)
  134. return rowsAffected;
  135. }
  136. // FIXME: temporarily commmented out, so I could get a simple working
  137. // SqlConnection and SqlCommand. I had to temporarily
  138. // comment it out the ExecuteReader in IDbCommand as well.
  139. /*
  140. [MonoTODO]
  141. IDataReader IDbCommand.ExecuteReader ()
  142. {
  143. throw new NotImplementedException ();
  144. }
  145. [MonoTODO]
  146. SqlDataReader ExecuteReader ()
  147. {
  148. throw new NotImplementedException ();
  149. }
  150. [MonoTODO]
  151. IDataReader IDbCommand.ExecuteReader (
  152. CommandBehavior behavior)
  153. {
  154. throw new NotImplementedException ();
  155. }
  156. [MonoTODO]
  157. public SqlDataReader ExecuteReader (CommandBehavior behavior)
  158. {
  159. throw new NotImplementedException ();
  160. }
  161. */
  162. [MonoTODO]
  163. public object ExecuteScalar ()
  164. {
  165. throw new NotImplementedException ();
  166. }
  167. [MonoTODO]
  168. public XmlReader ExecuteXmlReader ()
  169. {
  170. throw new NotImplementedException ();
  171. }
  172. [MonoTODO]
  173. public void Prepare ()
  174. {
  175. // FIXME: parameters have to be implemented for this
  176. throw new NotImplementedException ();
  177. }
  178. [MonoTODO]
  179. public SqlCommand Clone ()
  180. {
  181. throw new NotImplementedException ();
  182. }
  183. #endregion // Methods
  184. #region Properties
  185. public string CommandText {
  186. get {
  187. return sql;
  188. }
  189. set {
  190. sql = value;
  191. }
  192. }
  193. public int CommandTimeout {
  194. get {
  195. return timeout;
  196. }
  197. set {
  198. // FIXME: if value < 0, throw
  199. // ArgumentException
  200. // if (value < 0)
  201. // throw ArgumentException;
  202. timeout = value;
  203. }
  204. }
  205. public CommandType CommandType {
  206. get {
  207. return cmdType;
  208. }
  209. set {
  210. cmdType = value;
  211. }
  212. }
  213. // FIXME: for property Connection, is this the correct
  214. // way to handle a return of a stronger type?
  215. IDbConnection IDbCommand.Connection {
  216. get {
  217. return Connection;
  218. }
  219. set {
  220. // FIXME: throw an InvalidOperationException
  221. // if the change was during a
  222. // transaction in progress
  223. // csc
  224. Connection = (SqlConnection) value;
  225. // mcs
  226. // Connection = value;
  227. // FIXME: set Transaction property to null
  228. }
  229. }
  230. public SqlConnection Connection {
  231. get {
  232. // conn defaults to null
  233. return conn;
  234. }
  235. set {
  236. // FIXME: throw an InvalidOperationException
  237. // if the change was during
  238. // a transaction in progress
  239. conn = value;
  240. // FIXME: set Transaction property to null
  241. }
  242. }
  243. public bool DesignTimeVisible {
  244. get {
  245. return designTime;
  246. }
  247. set{
  248. designTime = value;
  249. }
  250. }
  251. // FIXME; for property Parameters, is this the correct
  252. // way to handle a stronger return type?
  253. IDataParameterCollection IDbCommand.Parameters {
  254. get {
  255. return Parameters;
  256. }
  257. }
  258. SqlParameterCollection Parameters {
  259. get {
  260. return parmCollection;
  261. }
  262. }
  263. // FIXME: for property Transaction, is this the correct
  264. // way to handle a return of a stronger type?
  265. IDbTransaction IDbCommand.Transaction {
  266. get {
  267. return Transaction;
  268. }
  269. set {
  270. // FIXME: error handling - do not allow
  271. // setting of transaction if transaction
  272. // has already begun
  273. // csc
  274. Transaction = (SqlTransaction) value;
  275. // mcs
  276. // Transaction = value;
  277. }
  278. }
  279. public SqlTransaction Transaction {
  280. get {
  281. return trans;
  282. }
  283. set {
  284. // FIXME: error handling
  285. trans = value;
  286. }
  287. }
  288. [MonoTODO]
  289. public UpdateRowSource UpdatedRowSource {
  290. // FIXME: do this once DbDataAdaptor
  291. // and DataRow are done
  292. get {
  293. throw new NotImplementedException ();
  294. }
  295. set {
  296. throw new NotImplementedException ();
  297. }
  298. }
  299. #endregion // Properties
  300. #region Destructors
  301. [MonoTODO]
  302. public void Dispose() {
  303. // FIXME: need proper way to release resources
  304. // Dispose(true);
  305. }
  306. [MonoTODO]
  307. ~SqlCommand()
  308. {
  309. // FIXME: need proper way to release resources
  310. // Dispose(false);
  311. }
  312. #endregion //Destructors
  313. }
  314. }