1 // ByteFX.Data data access components for .Net
\r
2 // Copyright (C) 2002-2003 ByteFX, Inc.
\r
4 // This library is free software; you can redistribute it and/or
\r
5 // modify it under the terms of the GNU Lesser General Public
\r
6 // License as published by the Free Software Foundation; either
\r
7 // version 2.1 of the License, or (at your option) any later version.
\r
9 // This library is distributed in the hope that it will be useful,
\r
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
\r
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
\r
12 // Lesser General Public License for more details.
\r
14 // You should have received a copy of the GNU Lesser General Public
\r
15 // License along with this library; if not, write to the Free Software
\r
16 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
\r
20 using System.Collections.Specialized;
\r
22 using System.ComponentModel;
\r
23 using System.Globalization;
\r
24 using ByteFX.Data.Common;
\r
26 namespace ByteFX.Data.MySqlClient
\r
29 /// Represents an open connection to a MySQL Server database. This class cannot be inherited.
\r
31 /// <include file='docs/MySqlConnection.xml' path='MyDocs/MyMembers[@name="Class"]/*'/>
\r
32 [System.Drawing.ToolboxBitmap( typeof(MySqlConnection), "MySqlClient.resources.connection.bmp")]
\r
33 [System.ComponentModel.DesignerCategory("Code")]
\r
35 public sealed class MySqlConnection : Component, IDbConnection, ICloneable
\r
37 internal ConnectionState state;
\r
38 private MySqlInternalConnection internalConnection;
\r
39 private MySqlDataReader dataReader;
\r
40 private NumberFormatInfo numberFormat;
\r
41 private MySqlConnectionString settings;
\r
44 /// Occurs when the state of the connection changes.
\r
46 public event StateChangeEventHandler StateChange;
\r
50 /// Creates a new connection
\r
52 public MySqlConnection()
\r
54 settings = new MySqlConnectionString("server=localhost");
\r
58 /// Creates a new connection
\r
60 /// <param name="container"></param>
\r
61 public MySqlConnection(System.ComponentModel.IContainer container)
\r
63 settings = new MySqlConnectionString();
\r
67 // Have a constructor that takes a connection string.
\r
69 /// Creates a new connection using the specified connection string.
\r
71 /// <param name="connectString"></param>
\r
72 public MySqlConnection(string connectString)
\r
74 settings = new MySqlConnectionString(connectString);
\r
78 /// Gets the name of the MySQL server to which to connect.
\r
82 public string DataSource
\r
84 get { return settings.Server; }
\r
88 /// Gets the time to wait while trying to establish a connection before terminating the attempt and generating an error.
\r
90 /// <include file='docs/MySqlConnection.xml' path='MyDocs/MyMembers[@name="ConnectionTimeout"]/*'/>
\r
92 public int ConnectionTimeout
\r
94 get { return settings.ConnectionTimeout; }
\r
98 /// Gets the name of the current database or the database to be used after a connection is opened.
\r
101 public string Database
\r
103 get { return settings.Database; }
\r
107 /// Indicates if this connection should use compression when communicating with the server.
\r
110 public bool UseCompression
\r
112 get { return settings.UseCompression; }
\r
116 /// Gets the current state of the connection.
\r
119 public ConnectionState State
\r
121 get { return state; }
\r
124 internal MySqlDataReader Reader
\r
126 get { return dataReader; }
\r
127 set { dataReader = value; }
\r
130 internal MySqlInternalConnection InternalConnection
\r
132 get { return internalConnection; }
\r
135 internal NumberFormatInfo NumberFormat
\r
139 if (numberFormat == null)
\r
141 numberFormat = new NumberFormatInfo();
\r
142 numberFormat = (NumberFormatInfo)NumberFormatInfo.InvariantInfo.Clone();
\r
143 numberFormat.NumberDecimalSeparator = ".";
\r
145 return numberFormat;
\r
150 /// Gets a string containing the version of the MySQL server to which the client is connected.
\r
153 public string ServerVersion
\r
155 get { return internalConnection.Driver.VersionString; }
\r
158 internal Encoding Encoding
\r
162 if (internalConnection == null)
\r
163 return System.Text.Encoding.Default;
\r
165 return internalConnection.Driver.Encoding;
\r
171 /// Gets or sets the string used to connect to a MySQL Server database.
\r
173 /// <include file='docs/MySqlConnection.xml' path='MyDocs/MyMembers[@name="ConnectionString"]/*'/>
\r
175 [Editor("ByteFX.Data.MySqlClient.Design.ConnectionStringTypeEditor,MySqlClient.Design", typeof(System.Drawing.Design.UITypeEditor))]
\r
179 [Description("Information used to connect to a DataSource, such as 'Server=xxx;UserId=yyy;Password=zzz;Database=dbdb'.")]
\r
180 public string ConnectionString
\r
184 // Always return exactly what the user set.
\r
185 // Security-sensitive information may be removed.
\r
186 return settings.GetConnectionString();
\r
190 if (this.State != ConnectionState.Closed)
\r
191 throw new MySqlException("Not allowed to change the 'ConnectionString' property while the connection (state=" + State + ").");
\r
193 settings.SetConnectionString(value);
\r
194 if (internalConnection != null)
\r
195 internalConnection.Settings = settings;
\r
201 #region Transactions
\r
203 /// Begins a database transaction.
\r
205 /// <returns></returns>
\r
206 public MySqlTransaction BeginTransaction()
\r
208 if (state != ConnectionState.Open)
\r
209 throw new MySqlException("Invalid operation: The connection is closed");
\r
211 MySqlTransaction t = new MySqlTransaction();
\r
212 t.Connection = this;
\r
213 InternalConnection.Driver.Send( DBCmd.QUERY, "BEGIN");
\r
220 IDbTransaction IDbConnection.BeginTransaction()
\r
222 return BeginTransaction();
\r
228 /// <param name="level"></param>
\r
229 /// <returns></returns>
\r
230 public MySqlTransaction BeginTransaction(IsolationLevel level)
\r
232 if (state != ConnectionState.Open)
\r
233 throw new MySqlException("Invalid operation: The connection is closed");
\r
235 MySqlTransaction t = new MySqlTransaction();
\r
236 t.Connection = this;
\r
237 t.IsolationLevel = level;
\r
238 string cmd = "SET SESSION TRANSACTION ISOLATION LEVEL ";
\r
241 case IsolationLevel.ReadCommitted:
\r
242 cmd += "READ COMMITTED"; break;
\r
243 case IsolationLevel.ReadUncommitted:
\r
244 cmd += "READ UNCOMMITTED"; break;
\r
245 case IsolationLevel.RepeatableRead:
\r
246 cmd += "REPEATABLE READ"; break;
\r
247 case IsolationLevel.Serializable:
\r
248 cmd += "SERIALIZABLE"; break;
\r
249 case IsolationLevel.Chaos:
\r
250 throw new NotSupportedException("Chaos isolation level is not supported");
\r
252 InternalConnection.Driver.Send( DBCmd.QUERY, cmd );
\r
253 InternalConnection.Driver.Send( DBCmd.QUERY, "BEGIN");
\r
260 /// <param name="level"></param>
\r
261 /// <returns></returns>
\r
262 IDbTransaction IDbConnection.BeginTransaction(IsolationLevel level)
\r
264 return BeginTransaction(level);
\r
269 /// Changes the current database for an open MySqlConnection.
\r
271 /// <param name="dbName"></param>
\r
272 public void ChangeDatabase(string dbName)
\r
274 if (state != ConnectionState.Open)
\r
275 throw new MySqlException("Invalid operation: The connection is closed");
\r
277 //TODOinternalConnection.ChangeDatabase( dbName );
\r
278 InternalConnection.Driver.Send( DBCmd.INIT_DB, dbName );
\r
281 internal void SetState( ConnectionState newState )
\r
283 ConnectionState oldState = state;
\r
285 if (this.StateChange != null)
\r
286 StateChange(this, new StateChangeEventArgs( oldState, newState ));
\r
290 /// Opens a database connection with the property settings specified by the ConnectionString.
\r
294 if (state == ConnectionState.Open)
\r
295 throw new MySqlException("error connecting: The connection is already Open (state=Open).");
\r
297 SetState( ConnectionState.Connecting );
\r
301 if (settings.Pooling)
\r
303 internalConnection = MySqlPoolManager.GetConnection( settings );
\r
307 internalConnection = new MySqlInternalConnection( settings );
\r
308 internalConnection.Open();
\r
311 catch (Exception ex)
\r
313 SetState( ConnectionState.Closed );
\r
318 SetState( ConnectionState.Open );
\r
319 internalConnection.SetServerVariables(this);
\r
320 if (settings.Database != null && settings.Database != String.Empty)
\r
321 ChangeDatabase( settings.Database );
\r
326 /// Closes the connection to the database. This is the preferred method of closing any open connection.
\r
328 public void Close()
\r
330 if (state == ConnectionState.Closed) return;
\r
332 if (dataReader != null)
\r
333 dataReader.Close();
\r
335 if (settings.Pooling)
\r
336 MySqlPoolManager.ReleaseConnection( internalConnection );
\r
338 internalConnection.Close();
\r
340 SetState( ConnectionState.Closed );
\r
343 IDbCommand IDbConnection.CreateCommand()
\r
345 return CreateCommand();
\r
349 /// Creates and returns a MySqlCommand object associated with the MySqlConnection.
\r
351 /// <returns></returns>
\r
352 public MySqlCommand CreateCommand()
\r
354 // Return a new instance of a command object.
\r
355 MySqlCommand c = new MySqlCommand();
\r
356 c.Connection = this;
\r
362 /// Creates a new MySqlConnection object with the exact same ConnectionString value
\r
364 /// <returns>A cloned MySqlConnection object</returns>
\r
365 object ICloneable.Clone()
\r
367 MySqlConnection clone = new MySqlConnection();
\r
368 clone.ConnectionString = this.ConnectionString;
\r
369 //TODO: how deep should this go?
\r
374 #region IDisposeable
\r
376 /// Releases the resources used by the MySqlConnection.
\r
378 public new void Dispose()
\r
380 if (State == ConnectionState.Open)
\r