2 // Mono.Data.MySql.MyConnection.cs
5 // Daniel Morgan (danmorg@sc.rr.com)
7 // (C) Daniel Morgan 2002
11 using System.Collections;
12 using System.ComponentModel;
14 using System.Data.Common;
15 using System.Runtime.InteropServices;
18 namespace Mono.Data.MySql {
20 public sealed class MySqlConnection : Component, IDbConnection,
25 private IntPtr mysqlInitStruct = IntPtr.Zero;
26 private IntPtr mysqlConn = IntPtr.Zero;
28 private string connectionString = "";
29 private string mysqlConnectionString = "";
31 //private MySqlTransaction trans = null;
32 private int connectionTimeout = 15;
33 // default for 15 seconds
35 // MySQL connection string parameters
40 uint port = MySql.Port;
41 string socketName = "";
45 private ConnectionState conState = ConnectionState.Closed;
48 //private MySqlDataReader rdr = null;
49 private bool dataReaderOpen = false;
50 // FIXME: if true, throw an exception if SqlConnection
51 // is used for anything other than reading
52 // data using SqlDataReader
54 private string versionString = "Unknown";
55 private bool disposed = false;
61 // A lot of the defaults were initialized in the Fields
63 public MySqlConnection () {
68 public MySqlConnection (String connectionString) {
69 SetConnectionString (connectionString);
72 #endregion // Constructors
77 // [ClassInterface(ClassInterfaceType.AutoDual)]
80 // FIXME: this class need
81 // a destructor to release resources
82 // Also, take a look at Dispose
86 #endregion // Destructors
88 #region Public Methods
90 IDbTransaction IDbConnection.BeginTransaction () {
91 // return BeginTransaction ();
95 //public MySqlTransaction BeginTransaction () {
96 // return TransactionBegin (); // call private method
99 IDbTransaction IDbConnection.BeginTransaction (IsolationLevel
101 //return BeginTransaction (il);
105 //public MySqlTransaction BeginTransaction (IsolationLevel il) {
106 // return TransactionBegin (il); // call private method
110 //public MySqlTransaction BeginTransaction(string transactionName) {
111 // return TransactionBegin (); // call private method
115 //public MySqlTransaction BeginTransaction(IsolationLevel iso,
\r
116 // string transactionName) {
117 // return TransactionBegin (iso); // call private method
121 public void ChangeDatabase (string databaseName) {
122 throw new NotImplementedException ();
125 object ICloneable.Clone() {
126 throw new NotImplementedException ();
130 public void Close () {
131 if(dataReaderOpen == true) {
132 // TODO: what do I do if
133 // the user Closes the connection
134 // without closing the Reader first?
140 IDbCommand IDbConnection.CreateCommand () {
141 return CreateCommand ();
144 public MySqlCommand CreateCommand () {
145 MySqlCommand sqlcmd = new MySqlCommand ("", this);
151 public void Open () {
152 if(dbname.Equals(""))
153 throw new InvalidOperationException(
155 else if(conState == ConnectionState.Open)
156 throw new InvalidOperationException(
157 "ConnnectionState is already Open");
159 // FIXME: check to make sure we have
160 // everything to connect,
161 // otherwise, throw an exception
163 mysqlInitStruct = MySql.Init(IntPtr.Zero);
164 if (mysqlInitStruct == IntPtr.Zero) {
165 // TODO: throw exception instead
166 Console.WriteLine("MySQL Init failed.");
171 // *** this is what it should be ***
172 //mysqlConn = MySql.Connect(mysqlInitStruct,
173 // host.Equals("") ? null : host,
174 // user.Equals("") ? null : user,
175 // passwd.Equals("") ? null : passwd,
176 // dbname.Equals("") ? null : dbname,
178 // socketName.Equals("") ? null : socketName,
181 mysqlConn = MySql.Connect(mysqlInitStruct,
189 if (mysqlConn == IntPtr.Zero) {
190 // TODO: throw exception instead
191 Console.WriteLine("MySQL Connect failed, "+MySql.Error(mysqlInitStruct));
195 Console.WriteLine("MySql Selecting Database: " + dbname + "...");
197 int sdb = MySql.SelectDb(mysqlInitStruct, dbname);
199 Console.WriteLine("Error: Can not select the "+dbname+" database.");
201 Console.WriteLine("MySql Error: " + MySql.Error(mysqlInitStruct));
206 // Successfully Connected
210 #endregion // Public Methods
212 #region Protected Methods
216 protected override void Dispose(bool disposing) {
220 // release any managed resources
222 // release any unmanaged resources
225 this.disposed = true;
228 base.Dispose(disposing);
234 #region Internal Methods
236 // Used to prevent MySqlConnection
237 // from doing anything while
238 // MySqlDataReader is open.
239 // Open the Reader. (called from MySqlCommand)
241 internal void OpenReader(MySqlDataReader reader) {
242 if(dataReaderOpen == true) {
243 // TODO: throw exception here?
249 dataReaderOpen = true;
254 // Used to prevent MySqlConnection
255 // from doing anything while
256 // MySqlDataReader is open
257 // Close the Reader (called from MySqlCommand)
258 // if closeConnection true, Close() the connection
259 // this is based on CommandBehavior.CloseConnection
260 internal void CloseReader(bool closeConnection) {
261 if(closeConnection == true)
264 dataReaderOpen = false;
267 #endregion // Internal Methods
269 #region Private Methods
271 private void SetupConnection() {
272 conState = ConnectionState.Open;
274 versionString = GetDatabaseServerVersion();
276 // May need to set DateTime format to ISO
277 // "YYYY-MM-DD hh:mi:ss.ms"
280 private string GetDatabaseServerVersion() {
281 //MySqlCommand cmd = new MySqlCommand("select version()",this);
282 //return (string) cmd.ExecuteScalar();
286 private void CloseDataSource () {
287 // FIXME: just a quick hack
288 if(conState == ConnectionState.Open) {
291 if(trans.DoingTransaction == true) {
297 conState = ConnectionState.Closed;
298 MySql.Close(mysqlInitStruct);
299 // MySql.ThreadEnd();
300 mysqlConn = IntPtr.Zero;
304 private void SetConnectionString (string connectionString) {
306 this.connectionString = connectionString;
307 mysqlConnectionString = ConvertStringToMySql (
311 private String ConvertStringToMySql (String
312 oleDbConnectionString) {
313 StringBuilder mysqlConnection =
316 string[] connectionParameters;
318 char[] semicolon = new Char[1];
321 // FIXME: what is the max number of value pairs
322 // can there be for the OLE DB
323 // connnection string? what about libgda max?
324 // what about postgres max?
326 // FIXME: currently assuming value pairs are like:
327 // "key1=value1;key2=value2;key3=value3"
328 // Need to deal with values that have
329 // single or double quotes. And error
330 // handling of that too.
331 // "key1=value1;key2='value2';key=\"value3\""
333 // FIXME: put the connection parameters
334 // from the connection
336 // Hashtable (System.Collections)
337 // instead of using private variables
339 connectionParameters = oleDbConnectionString.
341 foreach (string sParameter in connectionParameters) {
342 if(sParameter.Length > 0) {
343 BreakConnectionParameter (sParameter);
349 result = mysqlConnection.ToString ();
353 private bool BreakConnectionParameter (String sParameter) {
357 index = sParameter.IndexOf ("=");
359 string parmKey, parmValue;
361 // separate string "key=value" to
362 // string "key" and "value"
363 parmKey = sParameter.Substring (0, index);
364 parmValue = sParameter.Substring (index + 1,
365 sParameter.Length - index - 1);
374 * unit flags (can be multiple)
376 switch(parmKey.ToLower()) {
378 port = UInt32.Parse(parmValue);
382 // set DataSource property
387 // set Database property
400 socketName = parmValue;
404 // throw an exception?
412 private MySqlTransaction TransactionBegin () {
413 // FIXME: need to keep track of
414 // transaction in-progress
415 trans = new SqlTransaction ();
416 // using internal methods of SqlTransaction
417 trans.SetConnection (this);
423 private MySqlTransaction TransactionBegin (IsolationLevel il) {
424 // FIXME: need to keep track of
425 // transaction in-progress
427 trans.SetIsolationLevel (il);
435 #region Public Properties
438 public ConnectionState State {
444 public string ConnectionString {
446 return connectionString;
449 SetConnectionString (value);
453 public int ConnectionTimeout {
455 return connectionTimeout;
459 public string Database {
465 public string DataSource {
471 public int PacketSize {
473 throw new NotImplementedException ();
477 public string ServerVersion {
479 return versionString;
483 #endregion // Public Properties
485 #region Internal Properties
487 // For Mono.Data.MySql classes
488 // to get the current transaction
489 // in progress - if any
490 internal MySqlTransaction Transaction {
496 // For Mono.Data.MySql classes
497 // to get the unmanaged MySql connection
498 internal IntPtr NativeMySqlConnection {
504 // For Mono.Data.MySql classes
505 // to get the unmanaged MySql connection
506 internal IntPtr NativeMySqlInitStruct {
508 return mysqlInitStruct;
512 // Used to prevent SqlConnection
513 // from doing anything while
514 // SqlDataReader is open
515 internal bool IsReaderOpen {
517 return dataReaderOpen;
521 #endregion // Internal Properties
526 MyInfoMessageEventHandler InfoMessage;
529 StateChangeEventHandler StateChange;