// // System.Data.Odbc.OdbcConnection // // Authors: // Brian Ritchie (brianlritchie@hotmail.com) // // Copyright (C) Brian Ritchie, 2002 // // // Copyright (C) 2004 Novell, Inc (http://www.novell.com) // // 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. // using System.ComponentModel; using System.Data; using System.Data.Common; using System.EnterpriseServices; namespace System.Data.Odbc { [DefaultEvent("InfoMessage")] public sealed class OdbcConnection : Component, ICloneable, IDbConnection { #region Fields string connectionString; int connectionTimeout; internal OdbcTransaction transaction; IntPtr henv=IntPtr.Zero, hdbc=IntPtr.Zero; bool disposed = false; #endregion #region Constructors public OdbcConnection () { connectionTimeout = 15; connectionString = null; } public OdbcConnection (string connectionString) : this () { ConnectionString = connectionString; } #endregion // Constructors #region Properties internal IntPtr hDbc { get { return hdbc; } } [OdbcCategoryAttribute ("DataCategory_Data")] [DefaultValue ("")] [OdbcDescriptionAttribute ("Information used to connect to a Data Source")] [RefreshPropertiesAttribute (RefreshProperties.All)] [EditorAttribute ("Microsoft.VSDesigner.Data.Odbc.Design.OdbcConnectionStringEditor, "+ Consts.AssemblyMicrosoft_VSDesigner, "System.Drawing.Design.UITypeEditor, "+ Consts.AssemblySystem_Drawing )] [RecommendedAsConfigurableAttribute (true)] public string ConnectionString { get { return connectionString; } set { connectionString = value; } } [OdbcDescriptionAttribute ("Current connection timeout value, not settable in the ConnectionString")] [DefaultValue (15)] public int ConnectionTimeout { get { return connectionTimeout; } set { if (value < 0) { throw new ArgumentException("Timout should not be less than zero."); } connectionTimeout = value; } } // public string DataSource { // get { // if (State==ConnectionState.Open) // return _dsn; // else // return null; // } // } [DesignerSerializationVisibilityAttribute (DesignerSerializationVisibility.Hidden)] [OdbcDescriptionAttribute ("Current data source Catlog value, 'Database=X' in the ConnectionString")] public string Database { get { return ""; } } [DesignerSerializationVisibilityAttribute (DesignerSerializationVisibility.Hidden)] [OdbcDescriptionAttribute ("The ConnectionState indicating whether the connection is open or closed")] [BrowsableAttribute (false)] public ConnectionState State { get { if (hdbc!=IntPtr.Zero) { return ConnectionState.Open; } else return ConnectionState.Closed; } } [MonoTODO] [DesignerSerializationVisibilityAttribute (DesignerSerializationVisibility.Hidden)] [OdbcDescriptionAttribute ("Current data source, 'Server=X' in the ConnectionString")] public string DataSource { get { throw new NotImplementedException (); } } [MonoTODO] [DesignerSerializationVisibilityAttribute (DesignerSerializationVisibility.Hidden)] [OdbcDescriptionAttribute ("Current ODBC Driver")] public string Driver { get { throw new NotImplementedException (); } } [MonoTODO] [DesignerSerializationVisibilityAttribute (DesignerSerializationVisibility.Hidden)] [OdbcDescriptionAttribute ("Version of the product accessed by the ODBC Driver")] [BrowsableAttribute (false)] public string ServerVersion { get { throw new NotImplementedException (); } } #endregion // Properties #region Methods public OdbcTransaction BeginTransaction () { return BeginTransaction(IsolationLevel.Unspecified); } IDbTransaction IDbConnection.BeginTransaction () { return (IDbTransaction) BeginTransaction(); } public OdbcTransaction BeginTransaction (IsolationLevel level) { if (transaction==null) { transaction=new OdbcTransaction(this,level); return transaction; } else throw new InvalidOperationException(); } IDbTransaction IDbConnection.BeginTransaction (IsolationLevel level) { return (IDbTransaction) BeginTransaction(level); } public void Close () { OdbcReturn ret = OdbcReturn.Error; if (State == ConnectionState.Open) { // disconnect ret = libodbc.SQLDisconnect (hdbc); if ( (ret!=OdbcReturn.Success) && (ret!=OdbcReturn.SuccessWithInfo)) throw new OdbcException (new OdbcError ("SQLDisconnect", OdbcHandleType.Dbc,hdbc)); // free handles if (hdbc != IntPtr.Zero) { ret = libodbc.SQLFreeHandle ( (ushort) OdbcHandleType.Dbc, hdbc); if ( (ret!=OdbcReturn.Success) && (ret!=OdbcReturn.SuccessWithInfo)) throw new OdbcException (new OdbcError ("SQLFreeHandle", OdbcHandleType.Dbc,hdbc)); } hdbc = IntPtr.Zero; if (henv != IntPtr.Zero) { ret = libodbc.SQLFreeHandle ( (ushort) OdbcHandleType.Env, henv); if ( (ret!=OdbcReturn.Success) && (ret!=OdbcReturn.SuccessWithInfo)) throw new OdbcException (new OdbcError ("SQLFreeHandle", OdbcHandleType.Env,henv)); } henv = IntPtr.Zero; transaction = null; } } public OdbcCommand CreateCommand () { return new OdbcCommand("", this, transaction); } [MonoTODO] public void ChangeDatabase(string Database) { throw new NotImplementedException (); } protected override void Dispose (bool disposing) { if (!this.disposed) { try { // release the native unmananged resources this.Close(); this.disposed = true; } finally { // call Dispose on the base class base.Dispose(disposing); } } } [MonoTODO] object ICloneable.Clone () { throw new NotImplementedException(); } IDbCommand IDbConnection.CreateCommand () { return (IDbCommand) CreateCommand (); } public void Open () { if (State == ConnectionState.Open) throw new InvalidOperationException (); OdbcReturn ret = OdbcReturn.Error; // allocate Environment handle ret = libodbc.SQLAllocHandle (OdbcHandleType.Env, IntPtr.Zero, ref henv); if ( (ret!=OdbcReturn.Success) && (ret!=OdbcReturn.SuccessWithInfo)) throw new OdbcException (new OdbcError ("SQLAllocHandle")); ret=libodbc.SQLSetEnvAttr (henv, OdbcEnv.OdbcVersion, (IntPtr) libodbc.SQL_OV_ODBC3 , 0); if ((ret!=OdbcReturn.Success) && (ret!=OdbcReturn.SuccessWithInfo)) throw new OdbcException (new OdbcError ("SQLSetEnvAttr", OdbcHandleType.Env,henv)); // allocate connection handle ret=libodbc.SQLAllocHandle (OdbcHandleType.Dbc, henv, ref hdbc); if ( (ret!=OdbcReturn.Success) && (ret!=OdbcReturn.SuccessWithInfo)) throw new OdbcException (new OdbcError ("SQLAllocHandle",OdbcHandleType.Env,henv)); // DSN connection if (connectionString.ToLower().IndexOf("dsn=")>=0) { string _uid="", _pwd="", _dsn=""; 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; } } ret=libodbc.SQLConnect(hdbc, _dsn, -3, _uid, -3, _pwd, -3); if ((ret!=OdbcReturn.Success) && (ret!=OdbcReturn.SuccessWithInfo)) throw new OdbcException(new OdbcError("SQLConnect",OdbcHandleType.Dbc,hdbc)); } else { // DSN-less Connection string OutConnectionString=new String(' ',1024); short OutLen=0; ret=libodbc.SQLDriverConnect(hdbc, IntPtr.Zero, connectionString, -3, OutConnectionString, (short) OutConnectionString.Length, ref OutLen, 0); if ((ret!=OdbcReturn.Success) && (ret!=OdbcReturn.SuccessWithInfo)) throw new OdbcException(new OdbcError("SQLDriverConnect",OdbcHandleType.Dbc,hdbc)); } } [MonoTODO] public static void ReleaseObjectPool () { throw new NotImplementedException (); } [MonoTODO] public void EnlistDistributedTransaction ( ITransaction transaction) { throw new NotImplementedException (); } #endregion #region Events and Delegates [OdbcDescription ("DbConnection_StateChange")] [OdbcCategory ("DataCategory_StateChange")] public event StateChangeEventHandler StateChange; [OdbcDescription ("DbConnection_InfoMessage")] [OdbcCategory ("DataCategory_InfoMessage")] public event OdbcInfoMessageEventHandler InfoMessage; #endregion } }