Modified SQLDescribeCol to work around bug in pinvoke...when doing a ref on a typed...
[mono.git] / mcs / class / System.Data / System.Data.Odbc / OdbcConnection.cs
1 //
2 // System.Data.Odbc.OdbcConnection
3 //
4 // Authors:
5 //  Brian Ritchie (brianlritchie@hotmail.com) 
6 //
7 // Copyright (C) Brian Ritchie, 2002
8 //
9
10 using System.ComponentModel;
11 using System.Data;
12 using System.Data.Common;
13
14 namespace System.Data.Odbc
15 {
16         public sealed class OdbcConnection : Component, ICloneable, IDbConnection
17         {
18                 #region Fields
19
20                 string connectionString;
21                 int connectionTimeout;
22                 OdbcDataReader dataReader;
23                 internal OdbcTransaction transaction;
24                 IntPtr henv=IntPtr.Zero, hdbc=IntPtr.Zero;
25                 
26                 #endregion
27
28                 #region Constructors
29                 
30                 public OdbcConnection ()
31                 {
32                         OdbcReturn ret;
33                 
34                         // allocate Environment handle  
35                         ret=libodbc.SQLAllocHandle(OdbcHandleType.Env, IntPtr.Zero, ref henv);
36                         libodbchelper.DisplayError("SQLAllocHandle", ret);
37                 
38                         ret=libodbc.SQLSetEnvAttr(henv, OdbcEnv.OdbcVersion, (IntPtr) 3 , 0); 
39                         libodbchelper.DisplayError("SQLSetEnvAttr", ret);
40                 
41                         //Console.WriteLine("ODBCInit Complete.");
42                         connectionTimeout = 15;
43                         connectionString = null;
44                         dataReader = null;
45                 }
46
47                 public OdbcConnection (string connectionString) : this ()
48                 {
49                         ConnectionString = connectionString;
50                 }
51
52                 #endregion // Constructors
53
54                 #region Properties
55
56                 internal IntPtr hDbc
57                 {
58                         get { return hdbc; }
59                 }
60                 
61                 public string ConnectionString {
62                         get {
63                                 return connectionString;
64                         }
65                         set {
66                                 connectionString = value;
67                         }
68                 }
69
70                 public int ConnectionTimeout {
71                         get {
72                                 return connectionTimeout;
73                         }
74                 }
75
76 //              public string DataSource {
77 //                      get {
78 //                              if (State==ConnectionState.Open)
79 //                                      return _dsn;
80 //                              else
81 //                                      return null;
82 //                      }
83 //              }
84
85                 public string Database {
86                         get {
87                                 return "";
88                         }
89                 }
90
91                 public ConnectionState State
92                 {
93                         get {
94                                 if (hdbc!=IntPtr.Zero) {
95                                         return ConnectionState.Open;
96                                 }
97                                 else
98                                         return ConnectionState.Closed;
99                         }
100                 }
101
102                 internal OdbcDataReader DataReader
103                 {
104                         get {
105                                 return dataReader;
106                         }
107                         set {
108                                 dataReader = value;
109                         }
110                 }
111                 
112                 #endregion // Properties
113         
114                 #region Methods
115         
116                 public OdbcTransaction BeginTransaction ()
117                 {
118                         return BeginTransaction(IsolationLevel.Unspecified);
119         }
120               
121                 IDbTransaction IDbConnection.BeginTransaction ()
122                 {
123                         return (IDbTransaction) BeginTransaction();
124                 }
125                 
126                 public OdbcTransaction BeginTransaction (IsolationLevel level)
127                 {
128                         if (transaction==null)
129                         {
130                                 transaction=new OdbcTransaction(this,level);
131                                 return transaction;
132                         }
133                         else
134                                 throw new InvalidOperationException();
135                 }
136
137                 IDbTransaction IDbConnection.BeginTransaction (IsolationLevel level)
138                 {
139                         return (IDbTransaction) BeginTransaction(level);
140                 }
141
142                 public void Close ()
143                 {
144                         if (State == ConnectionState.Open) {
145                                 // TODO: Free handles
146                                 dataReader = null;
147                                 hdbc = IntPtr.Zero;
148                                 transaction=null;
149                         }
150                         else
151                                 throw new InvalidOperationException();
152                 }
153
154                 public OdbcCommand CreateCommand ()
155                 {
156                         return new OdbcCommand("", this, transaction); 
157                 }
158
159                 [MonoTODO]
160                 public void ChangeDatabase(string Database)
161                 {
162                         throw new NotImplementedException ();
163                 }
164                 
165                 [MonoTODO]
166                 protected override void Dispose (bool disposing)
167                 {
168                 }
169
170                 [MonoTODO]
171                 object ICloneable.Clone ()
172                 {
173                         throw new NotImplementedException();
174                 }
175
176                 IDbCommand IDbConnection.CreateCommand ()
177                 {
178                         return (IDbCommand) CreateCommand ();
179                 }
180
181                 public void Open ()
182                 {
183                         if (State == ConnectionState.Open)
184                                 throw new InvalidOperationException ();
185                                                 
186                         // allocate connection handle
187                         OdbcReturn ret=libodbc.SQLAllocHandle(OdbcHandleType.Dbc, henv, ref hdbc);
188                         libodbchelper.DisplayError("SQLAllocHandle(hdbc)", ret);
189                         
190                         // DSN connection
191                         if (connectionString.ToLower().IndexOf("dsn=")>=0)
192                         {
193                                 string _uid="", _pwd="", _dsn="";
194                                 string[] items=connectionString.Split(new char[1]{';'});
195                                 foreach (string item in items)
196                                 {
197                                         string[] parts=item.Split(new char[1] {'='});
198                                         switch (parts[0].Trim().ToLower())
199                                         {
200                                                 case "dsn":
201                                                         _dsn=parts[1].Trim();
202                                                         break;
203                                                 case "uid":
204                                                         _uid=parts[1].Trim();
205                                                         break;
206                                                 case "pwd":
207                                                         _pwd=parts[1].Trim();
208                                                         break;
209                                         }
210                                 }
211                                 ret=libodbc.SQLConnect(hdbc, _dsn, -3, _uid, -3, _pwd, -3);
212                                 libodbchelper.DisplayError("SQLConnect",ret);
213                         }
214                         else 
215                         {
216                                 // DSN-less Connection
217                                 string OutConnectionString=new String(' ',1024);
218                                 short OutLen=0;
219                                 ret=libodbc.SQLDriverConnect(hdbc, IntPtr.Zero, connectionString, -3, 
220                                         OutConnectionString, (short) OutConnectionString.Length, ref OutLen, 0);
221                                 libodbchelper.DisplayError("SQLConnect",ret);
222                         }
223
224                 }
225
226                 [MonoTODO]
227                 public static void ReleaseObjectPool ()
228                 {
229                         throw new NotImplementedException ();
230                 }
231
232                 #endregion
233
234                 #region Events and Delegates
235
236                 public event StateChangeEventHandler StateChange;
237
238                 #endregion
239         }
240 }