Add licensing info
[mono.git] / mcs / class / Mono.Data.PostgreSqlClient / Mono.Data.PostgreSqlClient / PgSqlDataReader.cs
index b52a876f016b102354d7c70e0bc0bd6deabc2035..68107b0ceb9f854b54170f5aebc9d5cdccbc7e34 100644 (file)
@@ -1,5 +1,5 @@
 //
-// System.Data.SqlClient.SqlDataReader.cs
+// Mono.Data.PostgreSqlClient.PgSqlDataReader.cs
 //
 // Author:
 //   Rodrigo Moya (rodrigo@ximian.com)
 //        Gonzalo Paniagua Javier <gonzalo@gnome-db.org>
 //
 
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+// 
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+// 
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
 // *** uncomment #define to get debug messages, comment for production ***
 //#define DEBUG_SqlDataReader
 
@@ -27,21 +48,21 @@ using System;
 using System.Collections;
 using System.ComponentModel;
 using System.Data;
+using System.Data.Common;
 
-namespace System.Data.SqlClient {
+namespace Mono.Data.PostgreSqlClient {
        /// <summary>
        /// Provides a means of reading one or more forward-only streams
        /// of result sets obtained by executing a command 
        /// at a SQL database.
        /// </summary>
-       //public sealed class SqlDataReader : MarshalByRefObject,
-       //      IEnumerable, IDataReader, IDisposable, IDataRecord
-       public sealed class SqlDataReader : IEnumerable, 
-               IDataReader, IDataRecord {
+       public sealed class PgSqlDataReader : MarshalByRefObject,
+               IEnumerable, IDataReader, IDisposable, IDataRecord {
+
                #region Fields
 
-               private SqlCommand cmd;
-               private DataTable table;
+               private PgSqlCommand cmd;
+               private DataTable table = null;
 
                // columns in a row
                private object[] fields; // data value in a .NET type
@@ -56,23 +77,21 @@ namespace System.Data.SqlClient {
                private int rows;
                private int cols;
 
+               private int recordsAffected = -1; // TODO: get this value
+
                private int currentRow = -1; // no Read() has been done yet
 
+               private bool disposed = false;
+
                #endregion // Fields
 
                #region Constructors
 
-               internal SqlDataReader (SqlCommand sqlCmd, 
-                       DataTable dataTableSchema, IntPtr pg_result,
-                       int rowCount, int fieldCount, string[] pgtypes) {
+               internal PgSqlDataReader (PgSqlCommand sqlCmd) {
 
                        cmd = sqlCmd;
-                       table = dataTableSchema;
-                       pgResult = pg_result;
-                       rows = rowCount;
-                       cols = fieldCount;
-                       types = pgtypes;
                        open = true;
+                       cmd.OpenReader(this);
                }
 
                #endregion
@@ -81,10 +100,15 @@ namespace System.Data.SqlClient {
 
                [MonoTODO]
                public void Close() {
-                       // close result set
-                       PostgresLibrary.PQclear (pgResult);
                        open = false;
-                       // TODO: change busy state on SqlConnection to not busy
+                       
+                       // free PgSqlDataReader resources in PgSqlCommand
+                       // and allow PgSqlConnection to be used again
+                       cmd.CloseReader();
+
+                       // TODO: get parameters from result
+
+                       Dispose (true);
                }
 
                [MonoTODO]
@@ -94,22 +118,44 @@ namespace System.Data.SqlClient {
 
                [MonoTODO]
                public bool NextResult() {
-                       throw new NotImplementedException ();
+                       PgSqlResult res;
+                       currentRow = -1;
+                       bool resultReturned;
+                       
+                       // reset
+                       table = null;
+                       pgResult = IntPtr.Zero;
+                       rows = 0;
+                       cols = 0;
+                       types = null;
+                       recordsAffected = -1;
+
+                       res = cmd.NextResult();
+                       resultReturned = res.ResultReturned;
+
+                       if(resultReturned == true) {
+                               table = res.Table;
+                               pgResult = res.PgResult;
+                               rows = res.RowCount;
+                               cols = res.FieldCount;
+                               types = res.PgTypes;
+                               recordsAffected = res.RecordsAffected;
+                       }
+                       
+                       res = null;
+                       return resultReturned;
                }
 
                [MonoTODO]
                public bool Read() {
+                       
                        string dataValue;
                        int c = 0;
                        
-                       //Console.WriteLine("if current row: " + currentRow + " rows: " + rows); 
                        if(currentRow < rows - 1)  {
                                
-                               //Console.WriteLine("currentRow++: ");
                                currentRow++;
-
-                               //Console.WriteLine("re-init row --- cols: " + cols);
-
+                       
                                // re-init row
                                fields = new object[cols];
                                //dbTypes = new DbType[cols];
@@ -211,7 +257,8 @@ namespace System.Data.SqlClient {
                [MonoTODO]
                public Type GetFieldType(int i) {
 
-                       return table.Columns[i].DataType;
+                       DataRow row = table.Rows[i];
+                       return Type.GetType((string)row["DataType"]);
                }
 
                [MonoTODO]
@@ -241,24 +288,29 @@ namespace System.Data.SqlClient {
 
                [MonoTODO]
                public string GetName(int i) {
-                       return table.Columns[i].ColumnName;
+
+                       DataRow row = table.Rows[i];
+                       return (string) row["ColumnName"];
                }
 
                [MonoTODO]
                public int GetOrdinal(string name) {
+
                        int i;
-                       for(i = 0; i < cols; i ++) {
-                               if(table.Columns[i].ColumnName.Equals(name)) {
-                                       return i;
-                               }
+                       DataRow row;
 
+                       for(i = 0; i < table.Rows.Count; i++) {
+                               row = table.Rows[i];
+                               if(((string) row["ColumnName"]).Equals(name))
+                                       return i;
                        }
-       
-                       for(i = 0; i < cols; i++) {
+
+                       for(i = 0; i < table.Rows.Count; i++) {
                                string ta;
                                string n;
-                                               
-                               ta = table.Columns[i].ColumnName.ToUpper();
+                                       
+                               row = table.Rows[i];
+                               ta = ((string) row["ColumnName"]).ToUpper();
                                n = name.ToUpper();
                                                
                                if(ta.Equals(n)) {
@@ -297,20 +349,45 @@ namespace System.Data.SqlClient {
                }
 
                [MonoTODO]
-               public IEnumerator GetEnumerator() {
-                       throw new NotImplementedException ();
+               IEnumerator IEnumerable.GetEnumerator () {
+                       return new DbEnumerator (this);
                }
 
                #endregion // Public Methods
 
                #region Destructors
 
-               [MonoTODO]
-               public void Dispose () {
+               private void Dispose(bool disposing) {
+                       if(!this.disposed) {
+                               if(disposing) {
+                                       // release any managed resources
+                                       cmd = null;
+                                       table = null;
+                                       fields = null;
+                                       types = null;
+                                       isNull = null;
+                                       actualLength = null;
+                                       dbTypes = null;
+                               }
+                               // release any unmanaged resources
+
+                               // clear unmanaged PostgreSQL result set
+                               if (pgResult != IntPtr.Zero) {
+                                       PostgresLibrary.PQclear (pgResult);
+                                       pgResult = IntPtr.Zero;
+                               }
+
+                               // close any handles
+                               this.disposed = true;
+                       }
                }
 
-               [MonoTODO]
-               ~SqlDataReader() {
+               void IDisposable.Dispose() {
+                       Dispose(true);
+               }
+
+               ~PgSqlDataReader() {
+                       Dispose(false);
                }
 
                #endregion // Destructors
@@ -320,7 +397,9 @@ namespace System.Data.SqlClient {
                public int Depth {
                        [MonoTODO]
                        get { 
-                               throw new NotImplementedException (); 
+                               return 0; // always return zero, unless
+                                         // this provider will allow
+                                         // nesting of a row
                        }
                }
 
@@ -337,7 +416,7 @@ namespace System.Data.SqlClient {
                public int RecordsAffected {
                        [MonoTODO]
                        get { 
-                               throw new NotImplementedException (); 
+                               return recordsAffected;
                        }
                }
        
@@ -352,18 +431,20 @@ namespace System.Data.SqlClient {
                        [MonoTODO]
                        get { 
                                int i;
-                               for(i = 0; i < cols; i ++) {
-                                       if(table.Columns[i].ColumnName.Equals(name)) {
-                                               return fields[i];
-                                       }
+                               DataRow row;
 
+                               for(i = 0; i < table.Rows.Count; i++) {
+                                       row = table.Rows[i];
+                                       if(row["ColumnName"].Equals(name))
+                                               return fields[i];
                                }
-       
-                               for(i = 0; i < cols; i++) {
+
+                               for(i = 0; i < table.Rows.Count; i++) {
                                        string ta;
                                        string n;
-                                               
-                                       ta = table.Columns[i].ColumnName.ToUpper();
+                                       
+                                       row = table.Rows[i];
+                                       ta = ((string) row["ColumnName"]).ToUpper();
                                        n = name.ToUpper();
                                                
                                        if(ta.Equals(n)) {