SqlDataReader.cs 7.3 KB

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