**** Merged from MCS ****
[mono-project.git] / mcs / class / System.Data / System.Data.Odbc / OdbcConnection.cs
blobde362a24d9d9260daf7e760ab10318b90207952e
1 //
2 // System.Data.Odbc.OdbcConnection
3 //
4 // Authors:
5 // Brian Ritchie (brianlritchie@hotmail.com)
6 //
7 // Copyright (C) Brian Ritchie, 2002
8 //
11 // Copyright (C) 2004 Novell, Inc (http://www.novell.com)
13 // Permission is hereby granted, free of charge, to any person obtaining
14 // a copy of this software and associated documentation files (the
15 // "Software"), to deal in the Software without restriction, including
16 // without limitation the rights to use, copy, modify, merge, publish,
17 // distribute, sublicense, and/or sell copies of the Software, and to
18 // permit persons to whom the Software is furnished to do so, subject to
19 // the following conditions:
20 //
21 // The above copyright notice and this permission notice shall be
22 // included in all copies or substantial portions of the Software.
23 //
24 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
25 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
26 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
27 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
28 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
29 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
30 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
33 using System.ComponentModel;
34 using System.Data;
35 using System.Data.Common;
36 using System.EnterpriseServices;
38 namespace System.Data.Odbc
40 [DefaultEvent("InfoMessage")]
41 public sealed class OdbcConnection : Component, ICloneable, IDbConnection
43 #region Fields
45 string connectionString;
46 int connectionTimeout;
47 internal OdbcTransaction transaction;
48 IntPtr henv=IntPtr.Zero, hdbc=IntPtr.Zero;
49 bool disposed = false;
51 #endregion
53 #region Constructors
55 public OdbcConnection ()
57 connectionTimeout = 15;
58 connectionString = null;
61 public OdbcConnection (string connectionString) : this ()
63 ConnectionString = connectionString;
66 #endregion // Constructors
68 #region Properties
70 internal IntPtr hDbc
72 get { return hdbc; }
75 [OdbcCategoryAttribute ("DataCategory_Data")]
76 [DefaultValue ("")]
77 [OdbcDescriptionAttribute ("Information used to connect to a Data Source")]
78 [RefreshPropertiesAttribute (RefreshProperties.All)]
79 [EditorAttribute ("Microsoft.VSDesigner.Data.Odbc.Design.OdbcConnectionStringEditor, "+ Consts.AssemblyMicrosoft_VSDesigner, "System.Drawing.Design.UITypeEditor, "+ Consts.AssemblySystem_Drawing )]
80 [RecommendedAsConfigurableAttribute (true)]
81 public string ConnectionString {
82 get {
83 return connectionString;
85 set {
86 connectionString = value;
90 [OdbcDescriptionAttribute ("Current connection timeout value, not settable in the ConnectionString")]
91 [DefaultValue (15)]
92 public int ConnectionTimeout {
93 get {
94 return connectionTimeout;
96 set {
97 if (value < 0) {
98 throw new ArgumentException("Timout should not be less than zero.");
100 connectionTimeout = value;
104 // public string DataSource {
105 // get {
106 // if (State==ConnectionState.Open)
107 // return _dsn;
108 // else
109 // return null;
110 // }
111 // }
113 [DesignerSerializationVisibilityAttribute (DesignerSerializationVisibility.Hidden)]
114 [OdbcDescriptionAttribute ("Current data source Catlog value, 'Database=X' in the ConnectionString")]
115 public string Database {
116 get {
117 return "";
121 [DesignerSerializationVisibilityAttribute (DesignerSerializationVisibility.Hidden)]
122 [OdbcDescriptionAttribute ("The ConnectionState indicating whether the connection is open or closed")]
123 [BrowsableAttribute (false)]
124 public ConnectionState State
126 get {
127 if (hdbc!=IntPtr.Zero) {
128 return ConnectionState.Open;
130 else
131 return ConnectionState.Closed;
135 [MonoTODO]
136 [DesignerSerializationVisibilityAttribute (DesignerSerializationVisibility.Hidden)]
137 [OdbcDescriptionAttribute ("Current data source, 'Server=X' in the ConnectionString")]
138 public string DataSource {
139 get {
140 throw new NotImplementedException ();
144 [MonoTODO]
145 [DesignerSerializationVisibilityAttribute (DesignerSerializationVisibility.Hidden)]
146 [OdbcDescriptionAttribute ("Current ODBC Driver")]
147 public string Driver {
148 get {
149 throw new NotImplementedException ();
153 [MonoTODO]
154 [DesignerSerializationVisibilityAttribute (DesignerSerializationVisibility.Hidden)]
155 [OdbcDescriptionAttribute ("Version of the product accessed by the ODBC Driver")]
156 [BrowsableAttribute (false)]
157 public string ServerVersion {
158 get {
159 throw new NotImplementedException ();
164 #endregion // Properties
166 #region Methods
168 public OdbcTransaction BeginTransaction ()
170 return BeginTransaction(IsolationLevel.Unspecified);
173 IDbTransaction IDbConnection.BeginTransaction ()
175 return (IDbTransaction) BeginTransaction();
178 public OdbcTransaction BeginTransaction (IsolationLevel level)
180 if (transaction==null)
182 transaction=new OdbcTransaction(this,level);
183 return transaction;
185 else
186 throw new InvalidOperationException();
189 IDbTransaction IDbConnection.BeginTransaction (IsolationLevel level)
191 return (IDbTransaction) BeginTransaction(level);
194 public void Close ()
196 OdbcReturn ret = OdbcReturn.Error;
197 if (State == ConnectionState.Open) {
198 // disconnect
199 ret = libodbc.SQLDisconnect (hdbc);
200 if ( (ret!=OdbcReturn.Success) && (ret!=OdbcReturn.SuccessWithInfo))
201 throw new OdbcException (new OdbcError ("SQLDisconnect", OdbcHandleType.Dbc,hdbc));
203 // free handles
204 if (hdbc != IntPtr.Zero) {
205 ret = libodbc.SQLFreeHandle ( (ushort) OdbcHandleType.Dbc, hdbc);
206 if ( (ret!=OdbcReturn.Success) && (ret!=OdbcReturn.SuccessWithInfo))
207 throw new OdbcException (new OdbcError ("SQLFreeHandle", OdbcHandleType.Dbc,hdbc));
209 hdbc = IntPtr.Zero;
211 if (henv != IntPtr.Zero) {
212 ret = libodbc.SQLFreeHandle ( (ushort) OdbcHandleType.Env, henv);
213 if ( (ret!=OdbcReturn.Success) && (ret!=OdbcReturn.SuccessWithInfo))
214 throw new OdbcException (new OdbcError ("SQLFreeHandle", OdbcHandleType.Env,henv));
216 henv = IntPtr.Zero;
218 transaction = null;
222 public OdbcCommand CreateCommand ()
224 return new OdbcCommand("", this, transaction);
227 [MonoTODO]
228 public void ChangeDatabase(string Database)
230 throw new NotImplementedException ();
233 protected override void Dispose (bool disposing)
235 if (!this.disposed) {
236 try
238 // release the native unmananged resources
239 this.Close();
240 this.disposed = true;
242 finally
244 // call Dispose on the base class
245 base.Dispose(disposing);
250 [MonoTODO]
251 object ICloneable.Clone ()
253 throw new NotImplementedException();
256 IDbCommand IDbConnection.CreateCommand ()
258 return (IDbCommand) CreateCommand ();
261 public void Open ()
263 if (State == ConnectionState.Open)
264 throw new InvalidOperationException ();
266 OdbcReturn ret = OdbcReturn.Error;
268 // allocate Environment handle
269 ret = libodbc.SQLAllocHandle (OdbcHandleType.Env, IntPtr.Zero, ref henv);
270 if ( (ret!=OdbcReturn.Success) && (ret!=OdbcReturn.SuccessWithInfo))
271 throw new OdbcException (new OdbcError ("SQLAllocHandle"));
273 ret=libodbc.SQLSetEnvAttr (henv, OdbcEnv.OdbcVersion, (IntPtr) libodbc.SQL_OV_ODBC3 , 0);
274 if ((ret!=OdbcReturn.Success) && (ret!=OdbcReturn.SuccessWithInfo))
275 throw new OdbcException (new OdbcError ("SQLSetEnvAttr", OdbcHandleType.Env,henv));
277 // allocate connection handle
278 ret=libodbc.SQLAllocHandle (OdbcHandleType.Dbc, henv, ref hdbc);
279 if ( (ret!=OdbcReturn.Success) && (ret!=OdbcReturn.SuccessWithInfo))
280 throw new OdbcException (new OdbcError ("SQLAllocHandle",OdbcHandleType.Env,henv));
282 // DSN connection
283 if (connectionString.ToLower().IndexOf("dsn=")>=0)
285 string _uid="", _pwd="", _dsn="";
286 string[] items=connectionString.Split(new char[1]{';'});
287 foreach (string item in items)
289 string[] parts=item.Split(new char[1] {'='});
290 switch (parts[0].Trim().ToLower())
292 case "dsn":
293 _dsn=parts[1].Trim();
294 break;
295 case "uid":
296 _uid=parts[1].Trim();
297 break;
298 case "pwd":
299 _pwd=parts[1].Trim();
300 break;
303 ret=libodbc.SQLConnect(hdbc, _dsn, -3, _uid, -3, _pwd, -3);
304 if ((ret!=OdbcReturn.Success) && (ret!=OdbcReturn.SuccessWithInfo))
305 throw new OdbcException(new OdbcError("SQLConnect",OdbcHandleType.Dbc,hdbc));
307 else
309 // DSN-less Connection
310 string OutConnectionString=new String(' ',1024);
311 short OutLen=0;
312 ret=libodbc.SQLDriverConnect(hdbc, IntPtr.Zero, connectionString, -3,
313 OutConnectionString, (short) OutConnectionString.Length, ref OutLen, 0);
314 if ((ret!=OdbcReturn.Success) && (ret!=OdbcReturn.SuccessWithInfo))
315 throw new OdbcException(new OdbcError("SQLDriverConnect",OdbcHandleType.Dbc,hdbc));
320 [MonoTODO]
321 public static void ReleaseObjectPool ()
323 throw new NotImplementedException ();
326 [MonoTODO]
327 public void EnlistDistributedTransaction ( ITransaction transaction) {
328 throw new NotImplementedException ();
332 #endregion
334 #region Events and Delegates
336 [OdbcDescription ("DbConnection_StateChange")]
337 [OdbcCategory ("DataCategory_StateChange")]
338 public event StateChangeEventHandler StateChange;
340 [OdbcDescription ("DbConnection_InfoMessage")]
341 [OdbcCategory ("DataCategory_InfoMessage")]
342 public event OdbcInfoMessageEventHandler InfoMessage;
344 #endregion