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)
13 // http://www.gnome-db.org/
14 // with permission from the authors of the
15 // PostgreSQL provider in libgda:
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>
23 // Permission is hereby granted, free of charge, to any person obtaining
24 // a copy of this software and associated documentation files (the
25 // "Software"), to deal in the Software without restriction, including
26 // without limitation the rights to use, copy, modify, merge, publish,
27 // distribute, sublicense, and/or sell copies of the Software, and to
28 // permit persons to whom the Software is furnished to do so, subject to
29 // the following conditions:
31 // The above copyright notice and this permission notice shall be
32 // included in all copies or substantial portions of the Software.
34 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
35 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
36 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
37 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
38 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
39 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
40 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
43 // *** uncomment #define to get debug messages, comment for production ***
44 //#define DEBUG_SqlDataReader
48 using System
.Collections
;
49 using System
.ComponentModel
;
51 using System
.Data
.Common
;
53 namespace Mono
.Data
.PostgreSqlClient
{
55 /// Provides a means of reading one or more forward-only streams
56 /// of result sets obtained by executing a command
57 /// at a SQL database.
59 public sealed class PgSqlDataReader
: MarshalByRefObject
,
60 IEnumerable
, IDataReader
, IDisposable
, IDataRecord
{
64 private PgSqlCommand cmd
;
65 private DataTable table
= null;
68 private object[] fields
; // data value in a .NET type
69 private string[] types
; // PostgreSQL Type
70 private bool[] isNull
; // is NULL?
71 private int[] actualLength
; // ActualLength of data
72 private DbType
[] dbTypes
; // DB data type
73 // actucalLength = -1 is variable-length
75 private bool open
= false;
76 IntPtr pgResult
; // PGresult
80 private int recordsAffected
= -1; // TODO: get this value
82 private int currentRow
= -1; // no Read() has been done yet
84 private bool disposed
= false;
90 internal PgSqlDataReader (PgSqlCommand sqlCmd
) {
99 #region Public Methods
102 public void Close() {
105 // free PgSqlDataReader resources in PgSqlCommand
106 // and allow PgSqlConnection to be used again
109 // TODO: get parameters from result
115 public DataTable
GetSchemaTable() {
120 public bool NextResult() {
127 pgResult
= IntPtr
.Zero
;
131 recordsAffected
= -1;
133 res
= cmd
.NextResult();
134 resultReturned
= res
.ResultReturned
;
136 if(resultReturned
== true) {
138 pgResult
= res
.PgResult
;
140 cols
= res
.FieldCount
;
142 recordsAffected
= res
.RecordsAffected
;
146 return resultReturned
;
155 if(currentRow
< rows
- 1) {
160 fields
= new object[cols
];
161 //dbTypes = new DbType[cols];
162 actualLength
= new int[cols
];
163 isNull
= new bool[cols
];
165 for(c
= 0; c
< cols
; c
++) {
168 dataValue
= PostgresLibrary
.
174 //isNull[c] = PostgresLibrary.
175 // PQgetisnull(pgResult,
179 actualLength
[c
] = PostgresLibrary
.
180 PQgetlength(pgResult
,
184 dbType
= PostgresHelper
.
185 TypnameToSqlDbType(types
[c
]);
187 if(dataValue
== null) {
191 else if(dataValue
.Equals("")) {
197 fields
[c
] = PostgresHelper
.
198 ConvertDbTypeToSystem (
209 public byte GetByte(int i
) {
210 throw new NotImplementedException ();
214 public long GetBytes(int i
, long fieldOffset
,
215 byte[] buffer
, int bufferOffset
,
217 throw new NotImplementedException ();
221 public char GetChar(int i
) {
222 throw new NotImplementedException ();
226 public long GetChars(int i
, long fieldOffset
,
227 char[] buffer
, int bufferOffset
,
229 throw new NotImplementedException ();
233 public IDataReader
GetData(int i
) {
234 throw new NotImplementedException ();
238 public string GetDataTypeName(int i
) {
243 public DateTime
GetDateTime(int i
) {
244 return (DateTime
) fields
[i
];
248 public decimal GetDecimal(int i
) {
249 return (decimal) fields
[i
];
253 public double GetDouble(int i
) {
254 return (double) fields
[i
];
258 public Type
GetFieldType(int i
) {
260 DataRow row
= table
.Rows
[i
];
261 return Type
.GetType((string)row
["DataType"]);
265 public float GetFloat(int i
) {
266 return (float) fields
[i
];
270 public Guid
GetGuid(int i
) {
271 throw new NotImplementedException ();
275 public short GetInt16(int i
) {
276 return (short) fields
[i
];
280 public int GetInt32(int i
) {
281 return (int) fields
[i
];
285 public long GetInt64(int i
) {
286 return (long) fields
[i
];
290 public string GetName(int i
) {
292 DataRow row
= table
.Rows
[i
];
293 return (string) row
["ColumnName"];
297 public int GetOrdinal(string name
) {
302 for(i
= 0; i
< table
.Rows
.Count
; i
++) {
304 if(((string) row
["ColumnName"]).Equals(name
))
308 for(i
= 0; i
< table
.Rows
.Count
; i
++) {
313 ta
= ((string) row
["ColumnName"]).ToUpper();
321 throw new MissingFieldException("Missing field: " + name
);
325 public string GetString(int i
) {
326 return (string) fields
[i
];
330 public object GetValue(int i
) {
335 public int GetValues(object[] values
)
337 Array
.Copy (fields
, values
, fields
.Length
);
338 return fields
.Length
;
342 public bool IsDBNull(int i
) {
347 public bool GetBoolean(int i
) {
348 return (bool) fields
[i
];
352 IEnumerator IEnumerable
.GetEnumerator () {
353 return new DbEnumerator (this);
356 #endregion // Public Methods
360 private void Dispose(bool disposing
) {
363 // release any managed resources
372 // release any unmanaged resources
374 // clear unmanaged PostgreSQL result set
375 if (pgResult
!= IntPtr
.Zero
) {
376 PostgresLibrary
.PQclear (pgResult
);
377 pgResult
= IntPtr
.Zero
;
381 this.disposed
= true;
385 void IDisposable
.Dispose() {
393 #endregion // Destructors
400 return 0; // always return zero, unless
401 // this provider will allow
406 public bool IsClosed
{
416 public int RecordsAffected
{
419 return recordsAffected
;
423 public int FieldCount
{
430 public object this[string name
] {
436 for(i
= 0; i
< table
.Rows
.Count
; i
++) {
438 if(row
["ColumnName"].Equals(name
))
442 for(i
= 0; i
< table
.Rows
.Count
; i
++) {
447 ta
= ((string) row
["ColumnName"]).ToUpper();
455 throw new MissingFieldException("Missing field: " + name
);
459 public object this[int i
] {
466 #endregion // Properties