SqlDataReader.cs 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409
  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. }
  59. #endregion
  60. #region Public Methods
  61. [MonoTODO]
  62. public void Close() {
  63. open = false;
  64. // free SqlDataReader resources in SqlCommand
  65. // and allow SqlConnection to be used again
  66. cmd.CloseReader();
  67. // TODO: get parameters from result
  68. // clear unmanaged PostgreSQL result set
  69. PostgresLibrary.PQclear (pgResult);
  70. pgResult = IntPtr.Zero;
  71. }
  72. [MonoTODO]
  73. public DataTable GetSchemaTable() {
  74. return table;
  75. }
  76. [MonoTODO]
  77. public bool NextResult() {
  78. SqlResult res;
  79. currentRow = -1;
  80. res = cmd.NextResult();
  81. if(res.ResultReturned == true) {
  82. table = res.Table;
  83. pgResult = res.PgResult;
  84. rows = res.RowCount;
  85. cols = res.FieldCount;
  86. types = res.PgTypes;
  87. }
  88. return res.ResultReturned;
  89. }
  90. [MonoTODO]
  91. public bool Read() {
  92. string dataValue;
  93. int c = 0;
  94. if(currentRow < rows - 1) {
  95. currentRow++;
  96. // re-init row
  97. fields = new object[cols];
  98. //dbTypes = new DbType[cols];
  99. actualLength = new int[cols];
  100. isNull = new bool[cols];
  101. for(c = 0; c < cols; c++) {
  102. // get data value
  103. dataValue = PostgresLibrary.
  104. PQgetvalue(
  105. pgResult,
  106. currentRow, c);
  107. // is column NULL?
  108. //isNull[c] = PostgresLibrary.
  109. // PQgetisnull(pgResult,
  110. // currentRow, c);
  111. // get Actual Length
  112. actualLength[c] = PostgresLibrary.
  113. PQgetlength(pgResult,
  114. currentRow, c);
  115. DbType dbType;
  116. dbType = PostgresHelper.
  117. TypnameToSqlDbType(types[c]);
  118. if(dataValue == null) {
  119. fields[c] = null;
  120. isNull[c] = true;
  121. }
  122. else if(dataValue.Equals("")) {
  123. fields[c] = null;
  124. isNull[c] = true;
  125. }
  126. else {
  127. isNull[c] = false;
  128. fields[c] = PostgresHelper.
  129. ConvertDbTypeToSystem (
  130. dbType,
  131. dataValue);
  132. }
  133. }
  134. return true;
  135. }
  136. return false; // EOF
  137. }
  138. [MonoTODO]
  139. public byte GetByte(int i) {
  140. throw new NotImplementedException ();
  141. }
  142. [MonoTODO]
  143. public long GetBytes(int i, long fieldOffset,
  144. byte[] buffer, int bufferOffset,
  145. int length) {
  146. throw new NotImplementedException ();
  147. }
  148. [MonoTODO]
  149. public char GetChar(int i) {
  150. throw new NotImplementedException ();
  151. }
  152. [MonoTODO]
  153. public long GetChars(int i, long fieldOffset,
  154. char[] buffer, int bufferOffset,
  155. int length) {
  156. throw new NotImplementedException ();
  157. }
  158. [MonoTODO]
  159. public IDataReader GetData(int i) {
  160. throw new NotImplementedException ();
  161. }
  162. [MonoTODO]
  163. public string GetDataTypeName(int i) {
  164. return types[i];
  165. }
  166. [MonoTODO]
  167. public DateTime GetDateTime(int i) {
  168. return (DateTime) fields[i];
  169. }
  170. [MonoTODO]
  171. public decimal GetDecimal(int i) {
  172. return (decimal) fields[i];
  173. }
  174. [MonoTODO]
  175. public double GetDouble(int i) {
  176. return (double) fields[i];
  177. }
  178. [MonoTODO]
  179. public Type GetFieldType(int i) {
  180. DataRow row = table.Rows[i];
  181. return Type.GetType((string)row["DataType"]);
  182. }
  183. [MonoTODO]
  184. public float GetFloat(int i) {
  185. return (float) fields[i];
  186. }
  187. [MonoTODO]
  188. public Guid GetGuid(int i) {
  189. throw new NotImplementedException ();
  190. }
  191. [MonoTODO]
  192. public short GetInt16(int i) {
  193. return (short) fields[i];
  194. }
  195. [MonoTODO]
  196. public int GetInt32(int i) {
  197. return (int) fields[i];
  198. }
  199. [MonoTODO]
  200. public long GetInt64(int i) {
  201. return (long) fields[i];
  202. }
  203. [MonoTODO]
  204. public string GetName(int i) {
  205. DataRow row = table.Rows[i];
  206. return (string) row["ColumnName"];
  207. }
  208. [MonoTODO]
  209. public int GetOrdinal(string name) {
  210. int i;
  211. DataRow row;
  212. for(i = 0; i < table.Rows.Count; i++) {
  213. row = table.Rows[i];
  214. if(((string) row["ColumnName"]).Equals(name))
  215. return i;
  216. }
  217. for(i = 0; i < table.Rows.Count; i++) {
  218. string ta;
  219. string n;
  220. row = table.Rows[i];
  221. ta = ((string) row["ColumnName"]).ToUpper();
  222. n = name.ToUpper();
  223. if(ta.Equals(n)) {
  224. return i;
  225. }
  226. }
  227. throw new MissingFieldException("Missing field: " + name);
  228. }
  229. [MonoTODO]
  230. public string GetString(int i) {
  231. return (string) fields[i];
  232. }
  233. [MonoTODO]
  234. public object GetValue(int i) {
  235. return fields[i];
  236. }
  237. [MonoTODO]
  238. public int GetValues(object[] values)
  239. {
  240. Array.Copy (fields, values, fields.Length);
  241. return fields.Length;
  242. }
  243. [MonoTODO]
  244. public bool IsDBNull(int i) {
  245. return isNull[i];
  246. }
  247. [MonoTODO]
  248. public bool GetBoolean(int i) {
  249. return (bool) fields[i];
  250. }
  251. [MonoTODO]
  252. public IEnumerator GetEnumerator() {
  253. throw new NotImplementedException ();
  254. }
  255. #endregion // Public Methods
  256. #region Destructors
  257. [MonoTODO]
  258. public void Dispose () {
  259. }
  260. //[MonoTODO]
  261. //~SqlDataReader() {
  262. //}
  263. #endregion // Destructors
  264. #region Properties
  265. public int Depth {
  266. [MonoTODO]
  267. get {
  268. return 0; // always return zero, unless
  269. // this provider will allow
  270. // nesting of a row
  271. }
  272. }
  273. public bool IsClosed {
  274. [MonoTODO]
  275. get {
  276. if(open == false)
  277. return true;
  278. else
  279. return false;
  280. }
  281. }
  282. public int RecordsAffected {
  283. [MonoTODO]
  284. get {
  285. return recordsAffected;
  286. }
  287. }
  288. public int FieldCount {
  289. [MonoTODO]
  290. get {
  291. return cols;
  292. }
  293. }
  294. public object this[string name] {
  295. [MonoTODO]
  296. get {
  297. int i;
  298. DataRow row;
  299. for(i = 0; i < table.Rows.Count; i++) {
  300. row = table.Rows[i];
  301. if(row["ColumnName"].Equals(name))
  302. return fields[i];
  303. }
  304. for(i = 0; i < table.Rows.Count; i++) {
  305. string ta;
  306. string n;
  307. row = table.Rows[i];
  308. ta = ((string) row["ColumnName"]).ToUpper();
  309. n = name.ToUpper();
  310. if(ta.Equals(n)) {
  311. return fields[i];
  312. }
  313. }
  314. throw new MissingFieldException("Missing field: " + name);
  315. }
  316. }
  317. public object this[int i] {
  318. [MonoTODO]
  319. get {
  320. return fields[i];
  321. }
  322. }
  323. #endregion // Properties
  324. }
  325. }