2002-10-09 Rodrigo Moya <rodrigo@ximian.com>
authorRodrigo Moya <rodrigo@mono-cvs.ximian.com>
Wed, 9 Oct 2002 17:15:22 +0000 (17:15 -0000)
committerRodrigo Moya <rodrigo@mono-cvs.ximian.com>
Wed, 9 Oct 2002 17:15:22 +0000 (17:15 -0000)
* list: added System.Data.Odbc files.

2002-10-09  Brian Ritchie <brianlritchie@hotmail.com>

* System.Data.Odbc/*: added first version of ODBC managed provider.

svn path=/trunk/mcs/; revision=8103

mcs/class/System.Data/ChangeLog
mcs/class/System.Data/System.Data.Odbc/OdbcCommand.cs [new file with mode: 0644]
mcs/class/System.Data/System.Data.Odbc/OdbcConnection.cs [new file with mode: 0644]
mcs/class/System.Data/System.Data.Odbc/OdbcDataReader.cs [new file with mode: 0644]
mcs/class/System.Data/System.Data.Odbc/OdbcParameter.cs [new file with mode: 0644]
mcs/class/System.Data/System.Data.Odbc/OdbcParameterCollection.cs [new file with mode: 0644]
mcs/class/System.Data/System.Data.Odbc/OdbcType.cs [new file with mode: 0644]
mcs/class/System.Data/System.Data.Odbc/libodbc.cs [new file with mode: 0644]
mcs/class/System.Data/list

index deca056d2aab29a10a37fada770d5bb4e72ae726..22bb4398de9730163f438b6a862defcfeea1f3ef 100644 (file)
@@ -1,3 +1,11 @@
+2002-10-09  Rodrigo Moya <rodrigo@ximian.com>
+
+       * list: added System.Data.Odbc files.
+
+2002-10-09  Brian Ritchie <brianlritchie@hotmail.com>
+
+       * System.Data.Odbc/*: added first version of ODBC managed provider.
+
 2002-10-07  Gonzalo Paniagua Javier <gonzalo@ximian.com>
 
        * System.Data/ConstraintCollection.cs:
diff --git a/mcs/class/System.Data/System.Data.Odbc/OdbcCommand.cs b/mcs/class/System.Data/System.Data.Odbc/OdbcCommand.cs
new file mode 100644 (file)
index 0000000..20553bc
--- /dev/null
@@ -0,0 +1,307 @@
+//
+// System.Data.Odbc.OdbcCommand
+//
+// Authors:
+//   Brian Ritchie (brianlritchie@hotmail.com)
+//
+// Copyright (C) Brian Ritchie, 2002
+//
+
+using System.ComponentModel;
+using System.Data;
+using System.Data.Common;
+using System.Collections;
+using System.Runtime.InteropServices;
+
+namespace System.Data.Odbc
+{
+       /// <summary>
+       /// Represents an SQL statement or stored procedure to execute against a data source.
+       /// </summary>
+       public sealed class OdbcCommand : Component, ICloneable, IDbCommand
+       {
+               #region Fields
+
+               string commandText;
+               int timeout;
+               CommandType commandType;
+               OdbcConnection connection;
+               OdbcParameterCollection parameters;
+               //OdbcTransaction transaction;
+               bool designTimeVisible;
+               bool prepared=false;
+               OdbcDataReader dataReader;
+               CommandBehavior behavior;
+               public int hstmt;
+
+               #endregion // Fields
+
+               #region Constructors
+
+               public OdbcCommand ()
+               {
+                       commandText = String.Empty;
+                       timeout = 30; // default timeout
+                       commandType = CommandType.Text;
+                       connection = null;
+                       parameters = new OdbcParameterCollection ();
+                       //transaction = null;
+                       designTimeVisible = false;
+                       dataReader = null;
+                       behavior = CommandBehavior.Default;
+               }
+
+               public OdbcCommand (string cmdText) : this ()
+               {
+                       CommandText = cmdText;
+               }
+
+               public OdbcCommand (string cmdText, OdbcConnection connection)
+                       : this (cmdText)
+               {
+                       Connection = connection;
+               }
+
+//             public OdbcCommand (string cmdText,
+//                                  OdbcConnection connection,
+//                                  OdbcTransaction transaction) : this (cmdText, connection)
+//             {
+//                     this.transaction = transaction;
+//             }
+
+               #endregion // Constructors
+
+               #region Properties
+
+               public int hStmt
+               {
+                       get { return hstmt; }
+               }
+
+               public string CommandText
+               {
+                       get {
+                               return commandText;
+                       }
+                       set {
+                               prepared=false;
+                               commandText = value;
+                       }
+               }
+
+               public int CommandTimeout {
+                       get {
+                               return timeout;
+                       }
+                       set {
+                               timeout = value;
+                       }
+               }
+
+               public CommandType CommandType {
+                       get {
+                               return commandType;
+                       }
+                       set {
+                               commandType = value;
+                       }
+               }
+
+               public OdbcConnection Connection {
+                       get {
+                               return connection;
+                       }
+                       set {
+                               connection = value;
+                       }
+               }
+
+               public bool DesignTimeVisible {
+                       get {
+                               return designTimeVisible;
+                       }
+                       set {
+                               designTimeVisible = value;
+                       }
+               }
+
+               public OdbcParameterCollection Parameters {
+                       get {
+                               return parameters;
+                       }
+                       set {
+                               parameters = value;
+                       }
+               }
+
+//             public OdbcTransaction Transaction {
+//                     get {
+//                             return transaction;
+//                     }
+//                     set {
+//                             transaction = value;
+//                     }
+//             }
+
+               public UpdateRowSource UpdatedRowSource {
+                       [MonoTODO]
+                       get {
+                               throw new NotImplementedException ();
+                       }
+                       [MonoTODO]
+                       set {
+                               throw new NotImplementedException ();
+                       }
+               }
+
+               IDbConnection IDbCommand.Connection {
+                       get {
+                               return Connection;
+                       }
+                       set {
+                               Connection = (OdbcConnection) value;
+                       }
+               }
+
+               IDataParameterCollection IDbCommand.Parameters  {
+                       get {
+                               throw new NotImplementedException ();
+                               //return Parameters;
+                       }
+               }
+
+               IDbTransaction IDbCommand.Transaction  {
+                       get {
+                               throw new NotImplementedException ();
+                               //return Transaction;
+                       }
+                       set {
+                               throw new NotImplementedException ();
+                       }
+               }
+
+               #endregion // Properties
+
+               #region Methods
+
+               [MonoTODO]
+               public void Cancel ()
+               {
+                       throw new NotImplementedException ();
+               }
+
+               public OdbcParameter CreateParameter ()
+               {
+                       return new OdbcParameter ();
+               }
+
+               IDbDataParameter IDbCommand.CreateParameter ()
+               {
+                       return CreateParameter ();
+               }
+
+               [MonoTODO]
+               protected override void Dispose (bool disposing)
+               {
+                       throw new NotImplementedException ();
+               }
+
+               protected void ExecSQL(string sql)
+               {
+                       OdbcReturn ret;
+
+                       if (!prepared)
+                       {
+                               Prepare();
+                               if (Parameters.Count>0)
+                                       Parameters.Bind(hstmt);
+                       }
+
+                       if (prepared)
+                       {
+                               ret=libodbc.SQLExecute(hstmt);
+                               libodbc.DisplayError("SQLExecute",ret);
+                       }
+                       else
+                       {
+                               ret=libodbc.SQLAllocHandle((ushort) OdbcHandleType.Stmt, 
+Connection.hDbc, ref hstmt);
+                               libodbc.DisplayError("SQLAllocHandle(hstmt)",ret);
+                               ret=libodbc.SQLExecDirect(hstmt, sql, sql.Length);
+                               libodbc.DisplayError("SQLExecDirect",ret);
+                       }
+               }
+
+               public int ExecuteNonQuery ()
+               {
+                       if (connection == null)
+                               throw new InvalidOperationException ();
+                       if (connection.State == ConnectionState.Closed)
+                               throw new InvalidOperationException ();
+                       // FIXME: a third check is mentioned in .NET docs
+                       if (connection.DataReader != null)
+                               throw new InvalidOperationException ();
+
+                       ExecSQL(CommandText);
+
+                       if (!prepared)
+                               libodbc.SQLFreeHandle( (ushort) OdbcHandleType.Stmt, hstmt);
+                       return 0;
+               }
+
+               public void Prepare()
+               {
+                       OdbcReturn ret;
+                       ret=libodbc.SQLAllocHandle((ushort) OdbcHandleType.Stmt, Connection.hDbc, 
+ref hstmt);
+                       libodbc.DisplayError("SQLAlloc(Prepare)",ret);
+                       ret=libodbc.SQLPrepare(hstmt, CommandText, CommandText.Length);
+                       libodbc.DisplayError("SQLPrepare",ret);
+                       prepared=true;
+               }
+
+               public OdbcDataReader ExecuteReader ()
+               {
+                       return ExecuteReader (CommandBehavior.Default);
+               }
+
+               IDataReader IDbCommand.ExecuteReader ()
+               {
+                       return ExecuteReader ();
+               }
+
+               public OdbcDataReader ExecuteReader (CommandBehavior behavior)
+               {
+                       ExecuteNonQuery();
+                       dataReader=new OdbcDataReader(this);
+                       return dataReader;
+               }
+
+               IDataReader IDbCommand.ExecuteReader (CommandBehavior behavior)
+               {
+                       return ExecuteReader (behavior);
+               }
+
+               public object ExecuteScalar ()
+               {
+                                       throw new NotImplementedException ();
+//                     if (connection.DataReader != null)
+//                             throw new InvalidOperationException ();
+//
+               }
+
+               [MonoTODO]
+               object ICloneable.Clone ()
+               {
+                       throw new NotImplementedException ();
+               }
+
+               public void ResetCommandTimeout ()
+               {
+                       timeout = 30;
+               }
+
+               #endregion
+       }
+}
+
diff --git a/mcs/class/System.Data/System.Data.Odbc/OdbcConnection.cs b/mcs/class/System.Data/System.Data.Odbc/OdbcConnection.cs
new file mode 100644 (file)
index 0000000..0b9f307
--- /dev/null
@@ -0,0 +1,250 @@
+
+//
+// System.Data.Odbc.OdbcConnection
+//
+// Authors:
+//  Brian Ritchie (brianlritchie@hotmail.com)
+//
+// Copyright (C) Brian Ritchie, 2002
+//
+
+using System.ComponentModel;
+using System.Data;
+using System.Data.Common;
+
+namespace System.Data.Odbc
+{
+       public sealed class OdbcConnection : Component, ICloneable, IDbConnection
+       {
+               #region Fields
+
+               string connectionString;
+               int connectionTimeout;
+               OdbcDataReader dataReader;
+               int henv=0, hdbc=0;
+               private string _uid, _pwd, _dsn;
+
+               #endregion
+
+               #region Constructors
+
+               public OdbcConnection ()
+               {
+                       OdbcReturn ret;
+
+                       // allocate Environment handle
+                       ret=libodbc.SQLAllocHandle((ushort) OdbcHandleType.Env, 0, ref henv);
+                       libodbc.DisplayError("SQLAllocHandle", ret);
+
+                       ret=libodbc.SQLSetEnvAttr(henv, (ushort) OdbcEnv.OdbcVersion, (IntPtr) 3 
+, 0);
+                       libodbc.DisplayError("SQLSetEnvAttr", ret);
+
+                       Console.WriteLine("ODBCInit Complete.");
+                       connectionTimeout = 15;
+                       connectionString = null;
+                       dataReader = null;
+               }
+
+               public OdbcConnection (string connectionString) : this ()
+               {
+                       ConnectionString = connectionString;
+               }
+
+               #endregion // Constructors
+
+               #region Properties
+
+               public int hDbc
+               {
+                       get { return hdbc; }
+               }
+
+               public string ConnectionString {
+                       get {
+                               return connectionString;
+                       }
+                       set {
+                               connectionString = value;
+
+                               string[] items=connectionString.Split(new char[1]{';'});
+                               foreach (string item in items)
+                               {
+                                       string[] parts=item.Split(new char[1] {'='});
+                                       switch (parts[0].Trim().ToLower())
+                                       {
+                                               case "dsn":
+                                                       _dsn=parts[1].Trim();
+                                                       break;
+                                               case "uid":
+                                                       _uid=parts[1].Trim();
+                                                       break;
+                                               case "pwd":
+                                                       _pwd=parts[1].Trim();
+                                                       break;
+                                       }
+                               }
+                       }
+               }
+
+               public int ConnectionTimeout {
+                       get {
+                               return connectionTimeout;
+                       }
+               }
+
+               public string DataSource {
+                       get {
+                               if (State==ConnectionState.Open)
+                                       return _dsn;
+                               else
+                                       return null;
+                       }
+               }
+
+               public string Database {
+                       get {
+                               return "";
+                       }
+               }
+
+               public ConnectionState State
+               {
+                       get {
+                               if (hdbc!=0) {
+                                       return ConnectionState.Open;
+                               }
+                               else
+                                       return ConnectionState.Closed;
+                       }
+               }
+
+               internal OdbcDataReader DataReader
+               {
+                       get {
+                               return dataReader;
+                       }
+                       set {
+                               dataReader = value;
+                       }
+               }
+
+               #endregion // Properties
+
+               #region Methods
+
+               public void BeginTransaction()
+               {
+                       OdbcReturn ret;
+                       // Set Auto-commit to false
+                       ret=libodbc.SQLSetConnectAttr(hdbc, 102, 0, 0);
+                       libodbc.DisplayError("SQLSetConnectAttr(NoAutoCommit)", ret);
+               }
+
+               public void CommitTransaction()
+               {
+                       OdbcReturn ret;
+                       ret=libodbc.SQLEndTran((short) OdbcHandleType.Dbc, hdbc, 0);
+                       libodbc.DisplayError("SQLEndTran(commit)", ret);
+               }
+
+               public void RollbackTransaction()
+               {
+                       OdbcReturn ret;
+                       ret=libodbc.SQLEndTran((short) OdbcHandleType.Dbc, hdbc, 1);
+                       libodbc.DisplayError("SQLEndTran(rollback)", ret);
+               }
+
+//             public OdbcTransaction BeginTransaction ()
+//             {
+//              }
+
+               IDbTransaction IDbConnection.BeginTransaction ()
+               {
+                       throw new NotImplementedException ();
+       //              return BeginTransaction ();
+               }
+
+//             public OdbcTransaction BeginTransaction (IsolationLevel level)
+//             {
+//
+//             }
+
+               IDbTransaction IDbConnection.BeginTransaction (IsolationLevel level)
+               {
+                       throw new NotImplementedException ();
+               //      return BeginTransaction (level);
+               }
+
+               public void Close ()
+               {
+                       if (State == ConnectionState.Open) {
+                               hdbc = 0;
+                       }
+
+                       dataReader = null;
+               }
+
+               public OdbcCommand CreateCommand ()
+               {
+                       throw new NotImplementedException ();
+               }
+
+               [MonoTODO]
+               public void ChangeDatabase(string Database)
+               {
+                       throw new NotImplementedException ();
+               }
+
+
+               [MonoTODO]
+               protected override void Dispose (bool disposing)
+               {
+                       throw new NotImplementedException ();
+               }
+
+               [MonoTODO]
+               object ICloneable.Clone ()
+               {
+                       throw new NotImplementedException();
+               }
+
+               IDbCommand IDbConnection.CreateCommand ()
+               {
+                       throw new NotImplementedException();
+       //              return CreateCommand ();
+               }
+
+               public void Open ()
+               {
+                       if (State == ConnectionState.Open)
+                               throw new InvalidOperationException ();
+
+                       OdbcReturn ret;
+
+                       // allocate connection handle
+                       ret=libodbc.SQLAllocHandle((ushort) OdbcHandleType.Dbc, henv, ref hdbc);
+                       libodbc.DisplayError("SQLAllocHandle(hdbc)", ret);
+
+                       // Connect to data source
+                       ret=libodbc.SQLConnect(hdbc, _dsn, -3, _uid, -3, _pwd, -3);
+                       libodbc.DisplayError("SQLConnect",ret);
+
+               }
+
+               [MonoTODO]
+               public static void ReleaseObjectPool ()
+               {
+                       throw new NotImplementedException ();
+               }
+
+               #endregion
+
+               #region Events and Delegates
+
+               public event StateChangeEventHandler StateChange;
+
+               #endregion
+       }
+}
+
diff --git a/mcs/class/System.Data/System.Data.Odbc/OdbcDataReader.cs b/mcs/class/System.Data/System.Data.Odbc/OdbcDataReader.cs
new file mode 100644 (file)
index 0000000..e20c7f7
--- /dev/null
@@ -0,0 +1,422 @@
+//
+// System.Data.Odbc.OdbcDataReader
+//
+// Author:
+//   Brian Ritchie (brianlritchie@hotmail.com)
+//
+// Copyright (C) Brian Ritchie, 2002
+//
+
+using System.Collections;
+using System.ComponentModel;
+using System.Data;
+using System.Data.Common;
+using System.Runtime.InteropServices;
+
+namespace System.Data.Odbc
+{
+       public sealed class OdbcDataReader : MarshalByRefObject, IDataReader, 
+IDisposable, IDataRecord, IEnumerable
+       {
+               #region Fields
+
+               private OdbcCommand command;
+               private bool open;
+               private int currentRow;
+               private DataColumn[] cols;
+               private int hstmt;
+
+               #endregion
+
+               #region Constructors
+
+               internal OdbcDataReader (OdbcCommand command)
+               {
+                       this.command = command;
+                       this.command.Connection.DataReader = this;
+                       open = true;
+                       currentRow = -1;
+                       hstmt=command.hStmt;
+                       LoadColumns();
+               }
+
+               #endregion
+
+               #region Properties
+
+               public int Depth {
+                       get {
+                               return 0; // no nested selects supported
+                       }
+               }
+
+               public int FieldCount {
+                       get {
+
+                       return cols.Length;
+                       }
+               }
+
+               public bool IsClosed {
+                       get {
+                               return !open;
+                       }
+               }
+
+               public DataColumn[] Columns
+               {
+                       get {
+                               return cols;
+                       }
+               }
+
+               public object this[string name] {
+                       get {
+                               ushort pos;
+
+                               if (currentRow == -1)
+                                       throw new InvalidOperationException ();
+
+                               pos = ColIndex(name);
+
+                               if (pos == -1)
+                                       throw new IndexOutOfRangeException ();
+
+                               return this[pos];
+                       }
+               }
+
+               public object this[int index] {
+                       get {
+                               return (object) GetODBCData (index);
+                       }
+               }
+
+               public int RecordsAffected {
+                       get {
+                               return -1;
+                       }
+               }
+
+               #endregion
+
+               #region Methods
+
+               private Type SQLTypeToCILType(short DataType)
+               {
+                       switch (DataType)
+                       {
+                               case 12:
+                               case 1:
+                                       return typeof(string);
+                               case 4:
+                                       return typeof(int);
+                               case 5:
+                                       return typeof(short);
+                               case 2:
+                               case 3:
+                               case 6:
+                               case 7:
+                               case 8:
+                                       return typeof(float);
+                               case 90:
+                               case 91:
+                               case 92:
+                               case 9:
+                                       return typeof(DateTime);
+                               default:
+                                       Console.WriteLine("WARNING: Unknown type {0}", DataType);
+                                       return typeof(string);
+                       }
+               }
+
+               private short CILTypeToSQLType(Type type)
+               {
+                       if (type==typeof(int))
+                               return 4;
+                       else if (type==typeof(string))
+                               return 12;
+                       else
+                               return 12;
+               }
+
+               private void LoadColumns()
+               {
+                       ArrayList colsArray=new ArrayList();
+                       short colcount=0;
+                       short bufsize=255;
+                       byte[] colname_buffer=new byte[bufsize];
+                       string colname;
+                       short colname_size=0;
+                       short DataType=0, ColSize=0, DecDigits=0, Nullable=0;
+
+                       libodbc.SQLNumResultCols(hstmt, ref colcount);
+                       for (ushort i=1;i<=colcount;i++)
+                       {
+                               libodbc.SQLDescribeCol(hstmt, i, colname_buffer, bufsize, ref 
+colname_size, ref DataType, ref ColSize, ref DecDigits, ref Nullable);
+                               colname=System.Text.Encoding.Default.GetString(colname_buffer);
+                               DataColumn c=new DataColumn(colname, SQLTypeToCILType(DataType));
+                               c.AllowDBNull=(Nullable!=0);
+                               if (c.DataType==typeof(string))
+                                       c.MaxLength=ColSize;
+                               colsArray.Add(c);
+                       }
+                       cols=(DataColumn[]) colsArray.ToArray(typeof(DataColumn));
+               }
+
+               private ushort ColIndex(string colname)
+               {
+                       ushort i=0;
+                       foreach (DataColumn col in cols)
+                       {
+                               if (col.ColumnName==colname)
+                                       return i;
+                               i++;
+                       }
+                       return 0;
+               }
+
+               private object GetODBCData(int colindex)
+               {
+                       return GetODBCData(Convert.ToUInt16(colindex));
+               }
+
+               private object GetODBCData(ushort colindex)
+               {
+                       OdbcReturn ret;
+                       int outsize=0;
+                       DataColumn col=cols[colindex];
+                       colindex+=1;
+                       if (col.DataType==typeof(int))
+                       {
+                               int data=0;
+                               ret=libodbc.SQLGetData(hstmt, colindex, 4, ref data, 0, ref outsize);
+                               libodbc.DisplayError("SQLGetData(int)",ret);
+                               return data;
+                       }
+                       else if (col.DataType==typeof(string))
+                       {
+                               byte[] strbuffer=new byte[255];
+                               ret=libodbc.SQLGetData(hstmt, colindex, 1, strbuffer, 255, ref outsize);
+                               libodbc.DisplayError("SQLGetData("+col.ColumnName+","+colindex.ToString()+")",ret);
+                               return System.Text.Encoding.Default.GetString(strbuffer);
+                       }
+                       else if (col.DataType==typeof(float))
+                       {
+                               float data=0;
+                               ret=libodbc.SQLGetData(hstmt, colindex, 7, ref data, 0, ref outsize);
+                               return data;
+                       }
+                       else if (col.DataType==typeof(DateTime))
+                       {
+                               OdbcTimestamp data=new OdbcTimestamp();
+                               ret=libodbc.SQLGetData(hstmt, colindex, 91, ref data, 0, ref outsize);
+                               return new 
+DateTime(data.year,data.month,data.day,data.hour,data.minute,data.second,Convert.ToInt32(data.fraction));
+                       }
+                       else return "";
+               }
+
+
+               public void Close ()
+               {
+                       // libodbc.SQLFreeHandle((ushort) OdbcHandleType.Stmt, hstmt);
+
+                       OdbcReturn ret=libodbc.SQLCloseCursor(hstmt);
+                       libodbc.DisplayError("SQLCancel",ret);
+
+                       open = false;
+                       currentRow = -1;
+
+                       this.command.Connection.DataReader = null;
+               }
+
+               ~OdbcDataReader ()
+               {
+                       if (open)
+                               Close ();
+               }
+
+               public bool GetBoolean (int ordinal)
+               {
+                       throw new NotImplementedException ();
+               }
+
+               public byte GetByte (int ordinal)
+               {
+                       throw new NotImplementedException ();
+               }
+
+               [MonoTODO]
+               public long GetBytes (int ordinal, long dataIndex, byte[] buffer, int 
+bufferIndex, int length)
+               {
+                       throw new NotImplementedException ();
+               }
+
+               public char GetChar (int ordinal)
+               {
+                       throw new NotImplementedException ();
+               }
+
+               [MonoTODO]
+               public long GetChars (int ordinal, long dataIndex, char[] buffer, int 
+bufferIndex, int length)
+               {
+                       throw new NotImplementedException ();
+               }
+
+               [MonoTODO]
+               public OdbcDataReader GetData (int ordinal)
+               {
+                       throw new NotImplementedException ();
+               }
+
+               public string GetDataTypeName (int index)
+               {
+                       return "";
+               }
+
+               public DateTime GetDateTime (int ordinal)
+               {
+                       throw new NotImplementedException ();
+               }
+
+               [MonoTODO]
+               public decimal GetDecimal (int ordinal)
+               {
+                       throw new NotImplementedException ();
+               }
+
+               public double GetDouble (int ordinal)
+               {
+                       throw new NotImplementedException ();
+               }
+
+               [MonoTODO]
+               public Type GetFieldType (int index)
+               {
+                       throw new NotImplementedException ();
+               }
+
+               public float GetFloat (int ordinal)
+               {
+                       throw new NotImplementedException ();
+               }
+
+               [MonoTODO]
+               public Guid GetGuid (int ordinal)
+               {
+                       throw new NotImplementedException ();
+               }
+
+               public short GetInt16 (int ordinal)
+               {
+                       throw new NotImplementedException ();
+               }
+
+               public int GetInt32 (int ordinal)
+               {
+                       throw new NotImplementedException ();
+               }
+
+               public long GetInt64 (int ordinal)
+               {
+                       throw new NotImplementedException ();
+               }
+
+               public string GetName (int index)
+               {
+                       if (currentRow == -1)
+                               return null;
+                       return cols[index].ColumnName;
+               }
+
+               public int GetOrdinal (string name)
+               {
+                       if (currentRow == -1)
+                               throw new IndexOutOfRangeException ();
+
+                       int i=ColIndex(name);
+
+                       if (i==-1)
+                               throw new IndexOutOfRangeException ();
+                       else
+                               return i;
+               }
+
+               public DataTable GetSchemaTable ()
+               {
+                       DataTable table = new DataTable ();
+
+                       // FIXME: implement
+                       return table;
+               }
+
+               public string GetString (int ordinal)
+               {
+                       throw new NotImplementedException ();
+               }
+
+               [MonoTODO]
+               public TimeSpan GetTimeSpan (int ordinal)
+               {
+                       throw new NotImplementedException ();
+               }
+
+               public object GetValue (int ordinal)
+               {
+                       if (currentRow == -1)
+                               throw new IndexOutOfRangeException ();
+
+                       if (ordinal>cols.Length-1 || ordinal<0)
+                               throw new IndexOutOfRangeException ();
+
+                       return (object) GetODBCData(ordinal);
+               }
+
+               [MonoTODO]
+               public int GetValues (object[] values)
+               {
+                       throw new NotImplementedException ();
+               }
+
+               [MonoTODO]
+               IDataReader IDataRecord.GetData (int ordinal)
+               {
+                       throw new NotImplementedException ();
+               }
+
+               [MonoTODO]
+               void IDisposable.Dispose ()
+               {
+                       throw new NotImplementedException ();
+               }
+
+               [MonoTODO]
+               IEnumerator IEnumerable.GetEnumerator ()
+               {
+                       throw new NotImplementedException ();
+               }
+
+               public bool IsDBNull (int ordinal)
+               {
+                       throw new NotImplementedException ();
+               }
+
+               public bool NextResult ()
+               {
+                       OdbcReturn ret=libodbc.SQLFetch(hstmt);
+                       return (ret==OdbcReturn.Success);
+               }
+
+               public bool Read ()
+               {
+                       return NextResult();
+               }
+
+               #endregion
+       }
+}
+
diff --git a/mcs/class/System.Data/System.Data.Odbc/OdbcParameter.cs b/mcs/class/System.Data/System.Data.Odbc/OdbcParameter.cs
new file mode 100644 (file)
index 0000000..fbf5c04
--- /dev/null
@@ -0,0 +1,188 @@
+//
+// System.Data.Odbc.OdbcParameter
+//
+// Authors:
+//   Brian Ritchie (brianlritchie@hotmail.com)
+//
+// Copyright (C) Brian Ritchie, 2002
+//
+
+using System;
+using System.Data;
+using System.Data.Common;
+
+namespace System.Data.Odbc
+{
+       public sealed class OdbcParameter : MarshalByRefObject, IDbDataParameter, 
+IDataParameter, ICloneable
+       {
+               #region Fields
+
+               string name;
+               object value;
+               int size;
+               bool isNullable;
+               byte precision;
+               byte scale;
+               DataRowVersion sourceVersion;
+               string sourceColumn;
+               ParameterDirection direction;
+               OdbcType odbcType;
+               DbType dbType;
+
+               int IntValue;
+
+               #endregion
+
+               #region Constructors
+
+               public OdbcParameter ()
+               {
+                       name = String.Empty;
+                       value = null;
+                       size = 0;
+                       isNullable = true;
+                       precision = 0;
+                       scale = 0;
+                       sourceColumn = String.Empty;
+               }
+
+               public OdbcParameter (string name, object value)
+                       : this ()
+               {
+                       this.name = name;
+                       this.value = value;
+               }
+
+               public OdbcParameter (string name, OdbcType dataType)
+                       : this ()
+               {
+                       this.name = name;
+                       OdbcType = dataType;
+               }
+
+               public OdbcParameter (string name, OdbcType dataType, int size)
+                       : this (name, dataType)
+               {
+                       this.size = size;
+               }
+
+               public OdbcParameter (string name, OdbcType dataType, int size, string 
+srcColumn)
+                       : this (name, dataType, size)
+               {
+                       this.sourceColumn = srcColumn;
+               }
+
+               public OdbcParameter(string name, OdbcType dataType, int size, 
+ParameterDirection direction, bool isNullable, byte precision, byte scale, 
+string srcColumn, DataRowVersion srcVersion, object value)
+                       : this (name, dataType, size, srcColumn)
+               {
+                       this.direction = direction;
+                       this.isNullable = isNullable;
+                       this.precision = precision;
+                       this.scale = scale;
+                       this.sourceVersion = srcVersion;
+                       this.value = value;
+               }
+
+               #endregion
+
+               #region Properties
+
+               public DbType DbType {
+                       get { return dbType; }
+                       set {
+                               dbType = value;
+                       }
+               }
+
+               public ParameterDirection Direction {
+                       get { return direction; }
+                       set { direction = value; }
+               }
+
+               public bool IsNullable {
+                       get { return isNullable; }
+               }
+
+               public OdbcType OdbcType {
+                       get { return odbcType; }
+                       set {
+                               odbcType = value;
+                       }
+               }
+
+               public string ParameterName {
+                       get { return name; }
+                       set { name = value; }
+               }
+
+               public byte Precision {
+                       get { return precision; }
+                       set { precision = value; }
+               }
+
+               public byte Scale {
+                       get { return scale; }
+                       set { scale = value; }
+               }
+
+               public int Size {
+                       get { return size; }
+                       set { size = value; }
+               }
+
+               public string SourceColumn {
+                       get { return sourceColumn; }
+                       set { sourceColumn = value; }
+               }
+
+               public DataRowVersion SourceVersion {
+                       get { return sourceVersion; }
+                       set { sourceVersion = value; }
+               }
+
+               public object Value {
+                       get {
+                               return IntValue;
+                       }
+                       set { this.IntValue =(int) value; }
+               }
+
+               #endregion // Properties
+
+               #region Internal Properties
+
+               internal void Bind(int hstmt,int ParamNum)
+               {
+                       if (OdbcType==OdbcType.Integer)
+                       {
+                               OdbcReturn ret=libodbc.SQLBindParam(hstmt, Convert.ToInt16(ParamNum), 4, 
+4, 0,0,ref IntValue, 0);
+                               libodbc.DisplayError("SQLBindParam",ret);
+
+                       }
+                       else Console.WriteLine("Unknown Paramter Type");
+
+               }
+
+               #endregion // Internal Properties
+
+               #region Methods
+
+               [MonoTODO]
+               object ICloneable.Clone ()
+               {
+                       throw new NotImplementedException ();
+               }
+
+               public override string ToString ()
+               {
+                       return ParameterName;
+               }
+               #endregion
+       }
+}
+
diff --git a/mcs/class/System.Data/System.Data.Odbc/OdbcParameterCollection.cs b/mcs/class/System.Data/System.Data.Odbc/OdbcParameterCollection.cs
new file mode 100644 (file)
index 0000000..a259faf
--- /dev/null
@@ -0,0 +1,207 @@
+
+//
+// System.Data.Odbc.OdbcParameterCollection
+//
+// Author:
+//   Brian Ritchie (brianlritchie@hotmail.com)
+//
+// Copyright (C) Brian Ritchie, 2002
+//
+
+using System.Collections;
+using System.Data;
+using System.Data.Common;
+
+namespace System.Data.Odbc
+{
+       public sealed class OdbcParameterCollection : MarshalByRefObject,
+               IDataParameterCollection, IList, ICollection, IEnumerable
+       {
+               #region Fields
+
+               ArrayList list = new ArrayList ();
+
+               #endregion // Fields
+
+               #region Properties
+
+               public int Count {
+                       get { return list.Count; }
+               }
+
+               public OdbcParameter this[int index] {
+                       get { return (OdbcParameter) list[index]; }
+                       set { list[index] = value; }
+               }
+
+               public OdbcParameter this[string parameterName] {
+                       [MonoTODO]
+                       get { throw new NotImplementedException (); }
+                       [MonoTODO]
+                       set { throw new NotImplementedException (); }
+               }
+
+               int ICollection.Count {
+                       get { return list.Count; }
+               }
+
+               bool IList.IsFixedSize {
+                       get { return false; }
+               }
+
+               bool IList.IsReadOnly {
+                       get { return false; }
+               }
+
+               bool ICollection.IsSynchronized {
+                       get { return list.IsSynchronized; }
+               }
+
+               object ICollection.SyncRoot {
+                       get { return list.SyncRoot; }
+               }
+
+               object IList.this[int index] {
+                       get { return list[index]; }
+                       set { list[index] = value; }
+               }
+
+               object IDataParameterCollection.this[string name]
+               {
+                       [MonoTODO]
+                       get {
+                               throw new NotImplementedException ();
+                       }
+                       [MonoTODO]
+                       set {
+                               throw new NotImplementedException ();
+                       }
+               }
+
+               #endregion // Properties
+
+               #region Methods
+
+
+               public OdbcParameter Add (OdbcParameter parameter)
+               {
+                       list.Add (parameter);
+                       return parameter;
+               }
+
+               public OdbcParameter Add (string name, object value)
+               {
+                       OdbcParameter parameter = new OdbcParameter (name, value);
+                       list.Add (parameter);
+                       return parameter;
+               }
+
+               public OdbcParameter Add (string name, OdbcType type)
+               {
+                       OdbcParameter parameter = new OdbcParameter (name, type);
+                       list.Add (parameter);
+                       return parameter;
+               }
+
+               public OdbcParameter Add (string name, OdbcType type, int width)
+               {
+                       OdbcParameter parameter = new OdbcParameter (name, type, width);
+                       list.Add (parameter);
+                       return parameter;
+               }
+
+               public OdbcParameter Add (string name, OdbcType type,
+                                          int width, string src_col)
+               {
+                       OdbcParameter parameter = new OdbcParameter (name, type, width, src_col);
+                       list.Add (parameter);
+                       return parameter;
+               }
+
+
+               internal void Bind(int hstmt)
+               {
+                       for (int i=0;i<Count;i++)
+                       {
+                               this[i].Bind(hstmt,i+1);
+
+                       }
+               }
+
+               int IList.Add (object value)
+               {
+                       if (!(value is IDataParameter))
+                               throw new InvalidCastException ();
+
+
+                       list.Add (value);
+                       return list.IndexOf (value);
+               }
+
+               void IList.Clear ()
+               {
+                       list.Clear ();
+               }
+
+               bool IList.Contains (object value)
+               {
+                       return list.Contains (value);
+               }
+
+               bool IDataParameterCollection.Contains (string value)
+               {
+                       for (int i = 0; i < list.Count; i++) {
+                               IDataParameter parameter;
+
+                               parameter = (IDataParameter) list[i];
+                               if (parameter.ParameterName == value)
+                                       return true;
+                       }
+
+                       return false;
+               }
+
+               void ICollection.CopyTo (Array array, int index)
+               {
+                       ((OdbcParameter[])(list.ToArray ())).CopyTo (array, index);
+               }
+
+               IEnumerator IEnumerable.GetEnumerator ()
+               {
+                       return list.GetEnumerator ();
+               }
+
+               int IList.IndexOf (object value)
+               {
+                       return list.IndexOf (value);
+               }
+
+               int IDataParameterCollection.IndexOf (string name)
+               {
+                       return list.IndexOf (((IDataParameterCollection) this)[name]);
+               }
+
+               void IList.Insert (int index, object value)
+               {
+                       list.Insert (index, value);
+               }
+
+               void IList.Remove (object value)
+               {
+                       list.Remove (value);
+               }
+
+               void IList.RemoveAt (int index)
+               {
+                       list.Remove ((object) list[index]);
+               }
+
+               void IDataParameterCollection.RemoveAt (string name)
+               {
+                       list.Remove (((IDataParameterCollection) this)[name]);
+               }
+
+               #endregion // Methods
+       }
+}
+
diff --git a/mcs/class/System.Data/System.Data.Odbc/OdbcType.cs b/mcs/class/System.Data/System.Data.Odbc/OdbcType.cs
new file mode 100644 (file)
index 0000000..cf7622c
--- /dev/null
@@ -0,0 +1,55 @@
+//
+// System.Data.Odbc.OdbcType
+//
+// Author:
+//   Brian Ritchie
+//
+// Copyright (C) Brian Ritchie, 2002
+//
+
+using System.Data;
+using System.Data.Common;
+
+namespace System.Data.Odbc
+{
+       public enum OdbcType {
+               BigInt,
+               Binary,
+               Boolean,
+               BSTR,
+               Char,
+               Currency,
+               Date,
+               DBDate,
+               DBTime,
+               DBTimeStamp,
+               Decimal,
+               Double,
+               Empty,
+               Error,
+               Filetime,
+               Guid,
+               IDispatch,
+               Integer,
+               IUnknown,
+               LongVarBinary,
+               LongVarChar,
+               LongVarWChar,
+               Numeric,
+               PropVariant,
+               Single,
+               SmallInt,
+               TinyInt,
+               UnsignedBigInt,
+               UnsignedInt,
+               UnsignedSmallInt,
+               UnsignedTinyInt,
+               VarBinary,
+               VarChar,
+               Variant,
+               VarNumeric,
+               VarWChar,
+               WChar
+       }
+}
+
diff --git a/mcs/class/System.Data/System.Data.Odbc/libodbc.cs b/mcs/class/System.Data/System.Data.Odbc/libodbc.cs
new file mode 100644 (file)
index 0000000..95b7fca
--- /dev/null
@@ -0,0 +1,161 @@
+//
+// System.Data.Odbc.libodbc
+//
+// Authors:
+//   Brian Ritchie (brianlritchie@hotmail.com)
+//
+//
+// Copyright (C) Brian Ritchie, 2002
+//
+//
+
+using System.Data;
+using System.Data.Common;
+using System.Runtime.InteropServices;
+
+namespace System.Data.Odbc
+{
+       internal enum OdbcHandleType {
+               Env = 1,
+               Dbc = 2,
+               Stmt = 3,
+               Desc = 4
+       };
+
+       internal enum OdbcReturn {
+               Error = -1,
+               InvalidHandle = -2,
+               StillExecuting = 2,
+               NeedData = 99,
+               Success = 0,
+               SuccessWithInfo = 1
+       }
+
+       internal enum OdbcEnv {
+               OdbcVersion = 200,
+               ConnectionPooling = 201,
+               CPMatch = 202
+       }
+
+       [StructLayout(LayoutKind.Sequential)]
+       public struct OdbcTimestamp
+       {
+               public short year;
+               public ushort month;
+               public ushort day;
+               public ushort hour;
+               public ushort minute;
+               public ushort second;
+               public ulong fraction;
+       }
+
+       sealed internal class libodbc
+       {
+               public static void DisplayError(string Msg, OdbcReturn Ret)
+               {
+                       if ((Ret!=OdbcReturn.Success) && (Ret!=OdbcReturn.SuccessWithInfo)) {
+                               Console.WriteLine("ERROR: {0}: <{1}>",Msg,Ret);
+
+                       }
+               }
+
+
+
+               [DllImport("libodbc")]
+               public static extern OdbcReturn SQLAllocHandle (ushort HandleType, int 
+InputHandle, ref int OutputHandlePtr);
+
+
+               [DllImport("libodbc")]
+               public static extern OdbcReturn SQLSetEnvAttr (int EnvHandle, ushort 
+Attribute, IntPtr Value, int StringLength);
+
+
+               [DllImport("libodbc")]
+               public static extern OdbcReturn SQLConnect (int ConnectionHandle, string 
+ServerName, short NameLength1, string UserName, short NameLength2, string 
+Authentication, short NameLength3);
+
+               [DllImport("libodbc")]
+               public static extern OdbcReturn SQLExecDirect (int StatementHandle, string 
+StatementText, int TextLength);
+
+               [DllImport("libodbc")]
+               public static extern OdbcReturn SQLRowCount (int StatementHandle, ref int 
+RowCount);
+
+               [DllImport("libodbc")]
+               public static extern OdbcReturn SQLNumResultCols (int StatementHandle, ref 
+short ColumnCount);
+
+               [DllImport("libodbc")]
+               public static extern OdbcReturn SQLFetch (int StatementHandle);
+
+               [DllImport("libodbc")]
+               public static extern OdbcReturn SQLGetData (int StatementHandle, ushort 
+ColumnNumber, short TargetType, ref int TargetPtr, int BufferLen, ref int 
+Len);
+
+               [DllImport("libodbc")]
+               public static extern OdbcReturn SQLGetData (int StatementHandle, ushort 
+ColumnNumber, short TargetType, byte[] TargetPtr, int BufferLen, ref int 
+Len);
+
+               [DllImport("libodbc")]
+               public static extern OdbcReturn SQLGetData (int StatementHandle, ushort 
+ColumnNumber, short TargetType, ref float TargetPtr, int BufferLen, ref int 
+Len);
+
+               [DllImport("libodbc")]
+               public static extern OdbcReturn SQLGetData (int StatementHandle, ushort 
+ColumnNumber, short TargetType, ref OdbcTimestamp TargetPtr, int BufferLen, 
+ref int Len);
+
+               [DllImport("libodbc")]
+               public static extern OdbcReturn SQLDescribeCol(int StatmentHandle, ushort 
+ColumnNumber, byte[] ColumnName, short BufferLength, ref short NameLength, 
+ref short DataType, ref short ColumnSize, ref short DecimalDigits, ref short 
+Nullable);
+
+               [DllImport("libodbc")]
+               public static extern OdbcReturn SQLFreeHandle(ushort HandleType, int 
+SqlHandle);
+
+               [DllImport("libodbc")]
+               public static extern OdbcReturn SQLDisconnect(int ConnectionHandle);
+
+               [DllImport("libodbc")]
+               public static extern OdbcReturn SQLPrepare(int StatementHandle, string 
+Statement, int TextLength);
+
+               [DllImport("libodbc")]
+               public static extern OdbcReturn SQLExecute(int StatementHandle);
+
+               [DllImport("libodbc")]
+               public static extern OdbcReturn SQLSetConnectAttr(int ConnectionHandle, 
+int Attribute, uint Value, int Length);
+
+               [DllImport("libodbc")]
+               public static extern OdbcReturn SQLEndTran(int HandleType, int Handle, 
+short CompletionType);
+
+               [DllImport("libodbc")]
+               public static extern OdbcReturn SQLBindParam(int StatementHandle, short 
+ParamNum, short ValueType,
+                               short ParamType, int LenPrecision, short ParamScale, ref int ParamValue, 
+int StrLen);
+
+               [DllImport("libodbc")]
+               public static extern OdbcReturn SQLBindParam(int StatementHandle, short 
+ParamNum, short ValueType,
+                               short ParamType, int LenPrecision, short ParamScale, byte[] ParamValue, 
+int StrLen);
+
+               [DllImport("libodbc")]
+               public static extern OdbcReturn SQLCancel(int StatementHandle);
+
+               [DllImport("libodbc")]
+               public static extern OdbcReturn SQLCloseCursor(int StatementHandle);
+       }
+}
+
index 22108d8820de4942c7106b2254c46545aa5984ad..35c62c3a3b2dd2be8d7a6323be7eed7321e3ff85 100755 (executable)
@@ -150,3 +150,10 @@ System.Data.SqlTypes/SqlSingle.cs
 System.Data.SqlTypes/SqlString.cs
 System.Data.SqlTypes/SqlTruncateException.cs
 System.Data.SqlTypes/SqlTypeException.cs
+System.Data.Odbc/OdbcCommand.cs
+System.Data.Odbc/OdbcConnection.cs
+System.Data.Odbc/OdbcDataReader.cs
+System.Data.Odbc/OdbcParameter.cs
+System.Data.Odbc/OdbcParameterCollection.cs
+System.Data.Odbc/OdbcType.cs
+System.Data.Odbc/libodbc.cs