SqlDataReader.cs 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422
  1. //
  2. // System.Data.SqlClient.SqlDataReader.cs
  3. //
  4. // Author:
  5. // Rodrigo Moya ([email protected])
  6. // Daniel Morgan ([email protected])
  7. //
  8. // (C) Ximian, Inc 2002
  9. // (C) Daniel Morgan 2002
  10. //
  11. // Credits:
  12. // SQL and concepts were used from libgda 0.8.190 (GNOME Data Access)
  13. // http://www.gnome-db.org/
  14. // with permission from the authors of the
  15. // PostgreSQL provider in libgda:
  16. // Michael Lausch <[email protected]>
  17. // Rodrigo Moya <[email protected]>
  18. // Vivien Malerba <[email protected]>
  19. // Gonzalo Paniagua Javier <[email protected]>
  20. //
  21. // *** uncomment #define to get debug messages, comment for production ***
  22. //#define DEBUG_SqlDataReader
  23. using System;
  24. using System.Collections;
  25. using System.ComponentModel;
  26. using System.Data;
  27. namespace System.Data.SqlClient {
  28. /// <summary>
  29. /// Provides a means of reading one or more forward-only streams
  30. /// of result sets obtained by executing a command
  31. /// at a SQL database.
  32. /// </summary>
  33. //public sealed class SqlDataReader : MarshalByRefObject,
  34. // IEnumerable, IDataReader, IDisposable, IDataRecord
  35. public sealed class SqlDataReader : IEnumerable,
  36. IDataReader, IDataRecord {
  37. #region Fields
  38. private SqlCommand cmd;
  39. private DataTable table = null;
  40. // columns in a row
  41. private object[] fields; // data value in a .NET type
  42. private string[] types; // PostgreSQL Type
  43. private bool[] isNull; // is NULL?
  44. private int[] actualLength; // ActualLength of data
  45. private DbType[] dbTypes; // DB data type
  46. // actucalLength = -1 is variable-length
  47. private bool open = false;
  48. IntPtr pgResult; // PGresult
  49. private int rows;
  50. private int cols;
  51. private int recordsAffected = -1; // TODO: get this value
  52. private int currentRow = -1; // no Read() has been done yet
  53. #endregion // Fields
  54. #region Constructors
  55. internal SqlDataReader (SqlCommand sqlCmd) {
  56. cmd = sqlCmd;
  57. open = true;
  58. cmd.OpenReader(this);
  59. }
  60. #endregion
  61. #region Public Methods
  62. [MonoTODO]
  63. public void Close() {
  64. open = false;
  65. // free SqlDataReader resources in SqlCommand
  66. // and allow SqlConnection to be used again
  67. cmd.CloseReader();
  68. // TODO: get parameters from result
  69. // clear unmanaged PostgreSQL result set
  70. PostgresLibrary.PQclear (pgResult);
  71. pgResult = IntPtr.Zero;
  72. }
  73. [MonoTODO]
  74. public DataTable GetSchemaTable() {
  75. return table;
  76. }
  77. [MonoTODO]
  78. public bool NextResult() {
  79. SqlResult res;
  80. currentRow = -1;
  81. bool resultReturned;
  82. // reset
  83. table = null;
  84. pgResult = IntPtr.Zero;
  85. rows = 0;
  86. cols = 0;
  87. types = null;
  88. recordsAffected = -1;
  89. res = cmd.NextResult();
  90. resultReturned = res.ResultReturned;
  91. if(resultReturned == true) {
  92. table = res.Table;
  93. pgResult = res.PgResult;
  94. rows = res.RowCount;
  95. cols = res.FieldCount;
  96. types = res.PgTypes;
  97. recordsAffected = res.RecordsAffected;
  98. }
  99. res = null;
  100. return resultReturned;
  101. }
  102. [MonoTODO]
  103. public bool Read() {
  104. string dataValue;
  105. int c = 0;
  106. if(currentRow < rows - 1) {
  107. currentRow++;
  108. // re-init row
  109. fields = new object[cols];
  110. //dbTypes = new DbType[cols];
  111. actualLength = new int[cols];
  112. isNull = new bool[cols];
  113. for(c = 0; c < cols; c++) {
  114. // get data value
  115. dataValue = PostgresLibrary.
  116. PQgetvalue(
  117. pgResult,
  118. currentRow, c);
  119. // is column NULL?
  120. //isNull[c] = PostgresLibrary.
  121. // PQgetisnull(pgResult,
  122. // currentRow, c);
  123. // get Actual Length
  124. actualLength[c] = PostgresLibrary.
  125. PQgetlength(pgResult,
  126. currentRow, c);
  127. DbType dbType;
  128. dbType = PostgresHelper.
  129. TypnameToSqlDbType(types[c]);
  130. if(dataValue == null) {
  131. fields[c] = null;
  132. isNull[c] = true;
  133. }
  134. else if(dataValue.Equals("")) {
  135. fields[c] = null;
  136. isNull[c] = true;
  137. }
  138. else {
  139. isNull[c] = false;
  140. fields[c] = PostgresHelper.
  141. ConvertDbTypeToSystem (
  142. dbType,
  143. dataValue);
  144. }
  145. }
  146. return true;
  147. }
  148. return false; // EOF
  149. }
  150. [MonoTODO]
  151. public byte GetByte(int i) {
  152. throw new NotImplementedException ();
  153. }
  154. [MonoTODO]
  155. public long GetBytes(int i, long fieldOffset,
  156. byte[] buffer, int bufferOffset,
  157. int length) {
  158. throw new NotImplementedException ();
  159. }
  160. [MonoTODO]
  161. public char GetChar(int i) {
  162. throw new NotImplementedException ();
  163. }
  164. [MonoTODO]
  165. public long GetChars(int i, long fieldOffset,
  166. char[] buffer, int bufferOffset,
  167. int length) {
  168. throw new NotImplementedException ();
  169. }
  170. [MonoTODO]
  171. public IDataReader GetData(int i) {
  172. throw new NotImplementedException ();
  173. }
  174. [MonoTODO]
  175. public string GetDataTypeName(int i) {
  176. return types[i];
  177. }
  178. [MonoTODO]
  179. public DateTime GetDateTime(int i) {
  180. return (DateTime) fields[i];
  181. }
  182. [MonoTODO]
  183. public decimal GetDecimal(int i) {
  184. return (decimal) fields[i];
  185. }
  186. [MonoTODO]
  187. public double GetDouble(int i) {
  188. return (double) fields[i];
  189. }
  190. [MonoTODO]
  191. public Type GetFieldType(int i) {
  192. DataRow row = table.Rows[i];
  193. return Type.GetType((string)row["DataType"]);
  194. }
  195. [MonoTODO]
  196. public float GetFloat(int i) {
  197. return (float) fields[i];
  198. }
  199. [MonoTODO]
  200. public Guid GetGuid(int i) {
  201. throw new NotImplementedException ();
  202. }
  203. [MonoTODO]
  204. public short GetInt16(int i) {
  205. return (short) fields[i];
  206. }
  207. [MonoTODO]
  208. public int GetInt32(int i) {
  209. return (int) fields[i];
  210. }
  211. [MonoTODO]
  212. public long GetInt64(int i) {
  213. return (long) fields[i];
  214. }
  215. [MonoTODO]
  216. public string GetName(int i) {
  217. DataRow row = table.Rows[i];
  218. return (string) row["ColumnName"];
  219. }
  220. [MonoTODO]
  221. public int GetOrdinal(string name) {
  222. int i;
  223. DataRow row;
  224. for(i = 0; i < table.Rows.Count; i++) {
  225. row = table.Rows[i];
  226. if(((string) row["ColumnName"]).Equals(name))
  227. return i;
  228. }
  229. for(i = 0; i < table.Rows.Count; i++) {
  230. string ta;
  231. string n;
  232. row = table.Rows[i];
  233. ta = ((string) row["ColumnName"]).ToUpper();
  234. n = name.ToUpper();
  235. if(ta.Equals(n)) {
  236. return i;
  237. }
  238. }
  239. throw new MissingFieldException("Missing field: " + name);
  240. }
  241. [MonoTODO]
  242. public string GetString(int i) {
  243. return (string) fields[i];
  244. }
  245. [MonoTODO]
  246. public object GetValue(int i) {
  247. return fields[i];
  248. }
  249. [MonoTODO]
  250. public int GetValues(object[] values)
  251. {
  252. Array.Copy (fields, values, fields.Length);
  253. return fields.Length;
  254. }
  255. [MonoTODO]
  256. public bool IsDBNull(int i) {
  257. return isNull[i];
  258. }
  259. [MonoTODO]
  260. public bool GetBoolean(int i) {
  261. return (bool) fields[i];
  262. }
  263. [MonoTODO]
  264. public IEnumerator GetEnumerator() {
  265. throw new NotImplementedException ();
  266. }
  267. #endregion // Public Methods
  268. #region Destructors
  269. [MonoTODO]
  270. public void Dispose () {
  271. }
  272. //[MonoTODO]
  273. //~SqlDataReader() {
  274. //}
  275. #endregion // Destructors
  276. #region Properties
  277. public int Depth {
  278. [MonoTODO]
  279. get {
  280. return 0; // always return zero, unless
  281. // this provider will allow
  282. // nesting of a row
  283. }
  284. }
  285. public bool IsClosed {
  286. [MonoTODO]
  287. get {
  288. if(open == false)
  289. return true;
  290. else
  291. return false;
  292. }
  293. }
  294. public int RecordsAffected {
  295. [MonoTODO]
  296. get {
  297. return recordsAffected;
  298. }
  299. }
  300. public int FieldCount {
  301. [MonoTODO]
  302. get {
  303. return cols;
  304. }
  305. }
  306. public object this[string name] {
  307. [MonoTODO]
  308. get {
  309. int i;
  310. DataRow row;
  311. for(i = 0; i < table.Rows.Count; i++) {
  312. row = table.Rows[i];
  313. if(row["ColumnName"].Equals(name))
  314. return fields[i];
  315. }
  316. for(i = 0; i < table.Rows.Count; i++) {
  317. string ta;
  318. string n;
  319. row = table.Rows[i];
  320. ta = ((string) row["ColumnName"]).ToUpper();
  321. n = name.ToUpper();
  322. if(ta.Equals(n)) {
  323. return fields[i];
  324. }
  325. }
  326. throw new MissingFieldException("Missing field: " + name);
  327. }
  328. }
  329. public object this[int i] {
  330. [MonoTODO]
  331. get {
  332. return fields[i];
  333. }
  334. }
  335. #endregion // Properties
  336. }
  337. }