* OdbcCommand.cs: No longer use OdbcConnection.Datareader, in order
[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         [DefaultEvent("InfoMessage")]
17         public sealed class OdbcConnection : Component, ICloneable, IDbConnection
18         {
19                 #region Fields
20
21                 string connectionString;
22                 int connectionTimeout;
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                         if ((ret!=OdbcReturn.Success) && (ret!=OdbcReturn.SuccessWithInfo)) 
37                                 throw new OdbcException(new OdbcError("SQLAllocHandle"));
38                 
39                         ret=libodbc.SQLSetEnvAttr(henv, OdbcEnv.OdbcVersion, (IntPtr) 3 , 0); 
40                         if ((ret!=OdbcReturn.Success) && (ret!=OdbcReturn.SuccessWithInfo)) 
41                                 throw new OdbcException(new OdbcError("SQLSetEnvAttr",OdbcHandleType.Env,henv));
42                 
43                         connectionTimeout = 15;
44                         connectionString = 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                         }\r
74                         set {\r
75                                 if (value < 0) {\r
76                                         throw new ArgumentException("Timout should not be less than zero.");\r
77                                 }\r
78                                 connectionTimeout = value;\r
79                         }\r
80                 }
81
82 //              public string DataSource {
83 //                      get {
84 //                              if (State==ConnectionState.Open)
85 //                                      return _dsn;
86 //                              else
87 //                                      return null;
88 //                      }
89 //              }
90
91                 public string Database {
92                         get {
93                                 return "";
94                         }
95                 }
96
97                 public ConnectionState State
98                 {
99                         get {
100                                 if (hdbc!=IntPtr.Zero) {
101                                         return ConnectionState.Open;
102                                 }
103                                 else
104                                         return ConnectionState.Closed;
105                         }
106                 }
107
108                 #endregion // Properties
109         
110                 #region Methods
111         
112                 public OdbcTransaction BeginTransaction ()
113                 {
114                         return BeginTransaction(IsolationLevel.Unspecified);
115         }
116               
117                 IDbTransaction IDbConnection.BeginTransaction ()
118                 {
119                         return (IDbTransaction) BeginTransaction();
120                 }
121                 
122                 public OdbcTransaction BeginTransaction (IsolationLevel level)
123                 {
124                         if (transaction==null)
125                         {
126                                 transaction=new OdbcTransaction(this,level);
127                                 return transaction;
128                         }
129                         else
130                                 throw new InvalidOperationException();
131                 }
132
133                 IDbTransaction IDbConnection.BeginTransaction (IsolationLevel level)
134                 {
135                         return (IDbTransaction) BeginTransaction(level);
136                 }
137
138                 public void Close ()
139                 {
140                         if (State == ConnectionState.Open) {
141                                 // TODO: Free handles
142                                 hdbc = IntPtr.Zero;
143                                 transaction=null;
144                         }
145                         else
146                                 throw new InvalidOperationException();
147                 }
148
149                 public OdbcCommand CreateCommand ()
150                 {
151                         return new OdbcCommand("", this, transaction); 
152                 }
153
154                 [MonoTODO]
155                 public void ChangeDatabase(string Database)
156                 {
157                         throw new NotImplementedException ();
158                 }
159                 
160                 [MonoTODO]
161                 protected override void Dispose (bool disposing)
162                 {
163                 }
164
165                 [MonoTODO]
166                 object ICloneable.Clone ()
167                 {
168                         throw new NotImplementedException();
169                 }
170
171                 IDbCommand IDbConnection.CreateCommand ()
172                 {
173                         return (IDbCommand) CreateCommand ();
174                 }
175
176                 public void Open ()
177                 {
178                         if (State == ConnectionState.Open)
179                                 throw new InvalidOperationException ();
180                                                 
181                         // allocate connection handle
182                         OdbcReturn ret=libodbc.SQLAllocHandle(OdbcHandleType.Dbc, henv, ref hdbc);
183                         if ((ret!=OdbcReturn.Success) && (ret!=OdbcReturn.SuccessWithInfo)) 
184                                 throw new OdbcException(new OdbcError("SQLAllocHandle",OdbcHandleType.Env,henv));
185                         
186                         // DSN connection
187                         if (connectionString.ToLower().IndexOf("dsn=")>=0)
188                         {
189                                 string _uid="", _pwd="", _dsn="";
190                                 string[] items=connectionString.Split(new char[1]{';'});
191                                 foreach (string item in items)
192                                 {
193                                         string[] parts=item.Split(new char[1] {'='});
194                                         switch (parts[0].Trim().ToLower())
195                                         {
196                                                 case "dsn":
197                                                         _dsn=parts[1].Trim();
198                                                         break;
199                                                 case "uid":
200                                                         _uid=parts[1].Trim();
201                                                         break;
202                                                 case "pwd":
203                                                         _pwd=parts[1].Trim();
204                                                         break;
205                                         }
206                                 }
207                                 ret=libodbc.SQLConnect(hdbc, _dsn, -3, _uid, -3, _pwd, -3);
208                                 if ((ret!=OdbcReturn.Success) && (ret!=OdbcReturn.SuccessWithInfo)) 
209                                         throw new OdbcException(new OdbcError("SQLConnect",OdbcHandleType.Dbc,hdbc));
210                         }
211                         else 
212                         {
213                                 // DSN-less Connection
214                                 string OutConnectionString=new String(' ',1024);
215                                 short OutLen=0;
216                                 ret=libodbc.SQLDriverConnect(hdbc, IntPtr.Zero, connectionString, -3, 
217                                         OutConnectionString, (short) OutConnectionString.Length, ref OutLen, 0);
218                                 if ((ret!=OdbcReturn.Success) && (ret!=OdbcReturn.SuccessWithInfo)) 
219                                         throw new OdbcException(new OdbcError("SQLDriverConnect",OdbcHandleType.Dbc,hdbc));
220                         }
221
222                 }
223
224                 [MonoTODO]
225                 public static void ReleaseObjectPool ()
226                 {
227                         throw new NotImplementedException ();
228                 }
229
230                 #endregion
231
232                 #region Events and Delegates
233
234                 public event StateChangeEventHandler StateChange;
235
236                 #endregion
237         }
238 }