2 // Mono.Data.PostgreSqlClient.PgSqlDataReader.cs
5 // Rodrigo Moya (rodrigo@ximian.com)
6 // Daniel Morgan (danmorg@sc.rr.com)
8 // (C) Ximian, Inc 2002
9 // (C) Daniel Morgan 2002
12 // SQL and concepts were used from libgda 0.8.190 (GNOME Data Access)
\r
13 // http://www.gnome-db.org/
\r
14 // with permission from the authors of the
\r
15 // PostgreSQL provider in libgda:
\r
16 // Michael Lausch <michael@lausch.at>
17 // Rodrigo Moya <rodrigo@gnome-db.org>
18 // Vivien Malerba <malerba@gnome-db.org>
19 // Gonzalo Paniagua Javier <gonzalo@gnome-db.org>
22 // *** uncomment #define to get debug messages, comment for production ***
23 //#define DEBUG_SqlDataReader
27 using System.Collections;
28 using System.ComponentModel;
31 namespace Mono.Data.PostgreSqlClient {
33 /// Provides a means of reading one or more forward-only streams
34 /// of result sets obtained by executing a command
35 /// at a SQL database.
37 //public sealed class PgSqlDataReader : MarshalByRefObject,
38 // IEnumerable, IDataReader, IDisposable, IDataRecord
39 public sealed class PgSqlDataReader : IEnumerable,
40 IDataReader, IDataRecord {
43 private PgSqlCommand cmd;
44 private DataTable table = null;
47 private object[] fields; // data value in a .NET type
48 private string[] types; // PostgreSQL Type
49 private bool[] isNull; // is NULL?
50 private int[] actualLength; // ActualLength of data
51 private DbType[] dbTypes; // DB data type
52 // actucalLength = -1 is variable-length
54 private bool open = false;
55 IntPtr pgResult; // PGresult
59 private int recordsAffected = -1; // TODO: get this value
61 private int currentRow = -1; // no Read() has been done yet
67 internal PgSqlDataReader (PgSqlCommand sqlCmd) {
76 #region Public Methods
82 // free SqlDataReader resources in SqlCommand
83 // and allow SqlConnection to be used again
86 // TODO: get parameters from result
88 // clear unmanaged PostgreSQL result set
89 PostgresLibrary.PQclear (pgResult);
90 pgResult = IntPtr.Zero;
94 public DataTable GetSchemaTable() {
99 public bool NextResult() {
106 pgResult = IntPtr.Zero;
110 recordsAffected = -1;
112 res = cmd.NextResult();
113 resultReturned = res.ResultReturned;
115 if(resultReturned == true) {
117 pgResult = res.PgResult;
119 cols = res.FieldCount;
121 recordsAffected = res.RecordsAffected;
125 return resultReturned;
134 if(currentRow < rows - 1) {
139 fields = new object[cols];
140 //dbTypes = new DbType[cols];
141 actualLength = new int[cols];
142 isNull = new bool[cols];
144 for(c = 0; c < cols; c++) {
147 dataValue = PostgresLibrary.
153 //isNull[c] = PostgresLibrary.
154 // PQgetisnull(pgResult,
158 actualLength[c] = PostgresLibrary.
159 PQgetlength(pgResult,
163 dbType = PostgresHelper.
164 TypnameToSqlDbType(types[c]);
166 if(dataValue == null) {
170 else if(dataValue.Equals("")) {
176 fields[c] = PostgresHelper.
177 ConvertDbTypeToSystem (
188 public byte GetByte(int i) {
189 throw new NotImplementedException ();
193 public long GetBytes(int i, long fieldOffset,
194 byte[] buffer, int bufferOffset,
196 throw new NotImplementedException ();
200 public char GetChar(int i) {
201 throw new NotImplementedException ();
205 public long GetChars(int i, long fieldOffset,
206 char[] buffer, int bufferOffset,
208 throw new NotImplementedException ();
212 public IDataReader GetData(int i) {
213 throw new NotImplementedException ();
217 public string GetDataTypeName(int i) {
222 public DateTime GetDateTime(int i) {
223 return (DateTime) fields[i];
227 public decimal GetDecimal(int i) {
228 return (decimal) fields[i];
232 public double GetDouble(int i) {
233 return (double) fields[i];
237 public Type GetFieldType(int i) {
239 DataRow row = table.Rows[i];
240 return Type.GetType((string)row["DataType"]);
244 public float GetFloat(int i) {
245 return (float) fields[i];
249 public Guid GetGuid(int i) {
250 throw new NotImplementedException ();
254 public short GetInt16(int i) {
255 return (short) fields[i];
259 public int GetInt32(int i) {
260 return (int) fields[i];
264 public long GetInt64(int i) {
265 return (long) fields[i];
269 public string GetName(int i) {
271 DataRow row = table.Rows[i];
272 return (string) row["ColumnName"];
276 public int GetOrdinal(string name) {
281 for(i = 0; i < table.Rows.Count; i++) {
283 if(((string) row["ColumnName"]).Equals(name))
287 for(i = 0; i < table.Rows.Count; i++) {
292 ta = ((string) row["ColumnName"]).ToUpper();
300 throw new MissingFieldException("Missing field: " + name);
304 public string GetString(int i) {
305 return (string) fields[i];
309 public object GetValue(int i) {
314 public int GetValues(object[] values)
316 Array.Copy (fields, values, fields.Length);
317 return fields.Length;
321 public bool IsDBNull(int i) {
326 public bool GetBoolean(int i) {
327 return (bool) fields[i];
331 public IEnumerator GetEnumerator() {
332 throw new NotImplementedException ();
335 #endregion // Public Methods
340 public void Dispose () {
344 //~PgSqlDataReader() {
347 #endregion // Destructors
354 return 0; // always return zero, unless
355 // this provider will allow
360 public bool IsClosed {
370 public int RecordsAffected {
373 return recordsAffected;
377 public int FieldCount {
384 public object this[string name] {
390 for(i = 0; i < table.Rows.Count; i++) {
392 if(row["ColumnName"].Equals(name))
396 for(i = 0; i < table.Rows.Count; i++) {
401 ta = ((string) row["ColumnName"]).ToUpper();
409 throw new MissingFieldException("Missing field: " + name);
413 public object this[int i] {
420 #endregion // Properties