Resyncing ByteFX.Data with latest from ByteFX
[mono.git] / mcs / class / ByteFX.Data / mysqlclient / MySqlPool.cs
1 using System;
2 using ByteFX.Data.Common;
3 using System.Collections;
4
5 namespace ByteFX.Data.MySqlClient
6 {
7         /// <summary>
8         /// Summary description for MySqlPool.
9         /// </summary>
10         internal sealed class MySqlPool
11         {
12                 private ArrayList                       inUsePool;
13                 private ArrayList                       idlePool;
14                 private int                                     minSize;
15                 private int                                     maxSize;
16
17                 public MySqlPool(int minSize, int maxSize)
18                 {
19                         this.minSize = minSize;
20                         this.maxSize = maxSize;
21                         inUsePool =new ArrayList(minSize);
22                         idlePool = new ArrayList(minSize);
23                 }
24
25                 private MySqlInternalConnection GetPooledConnection()
26                 {
27                         lock (idlePool.SyncRoot) 
28                         {
29                                 foreach (MySqlInternalConnection conn in idlePool)
30                                 {
31                                         if (conn.IsAlive()) 
32                                         {
33                                                 lock (inUsePool) 
34                                                 {
35                                                         inUsePool.Add( conn );
36                                                 }
37                                                 idlePool.Remove( conn );
38                                                 return conn;
39                                         }
40                                         else 
41                                         {
42                                                 conn.Close();
43                                                 idlePool.Remove(conn);
44                                         }
45                                 }
46                         }
47                         return null;
48                 }
49
50                 private MySqlInternalConnection CreateNewPooledConnection( MySqlConnectionString settings )
51                 {
52                         MySqlInternalConnection conn = new MySqlInternalConnection( settings );
53                         conn.Open();
54                         return conn;
55                 }
56
57                 public void ReleaseConnection( MySqlInternalConnection connection )
58                 {
59                         lock (inUsePool.SyncRoot)
60                                 lock (idlePool.SyncRoot) 
61                                 {
62                                         inUsePool.Remove( connection );
63                                         if (connection.Settings.ConnectionLifetime != 0 && connection.IsTooOld())
64                                                 connection.Close();
65                                         else
66                                                 idlePool.Add( connection );
67                                 }
68                 }
69
70                 public MySqlInternalConnection GetConnection(MySqlConnectionString settings) 
71                 {
72                         MySqlInternalConnection conn;
73
74                         DateTime start = DateTime.Now;
75                         TimeSpan ts;
76                         do 
77                         {
78                                 conn = GetPooledConnection();
79                                 if (conn == null)
80                                         conn = CreateNewPooledConnection( settings );
81                                 ts = DateTime.Now.Subtract( start );
82                         } while (conn == null && ts.Seconds < settings.ConnectTimeout );
83
84                                          
85                         // if pool size is at maximum, then we must have reached our timeout so we simply
86                         // throw our exception
87                         if (conn == null)
88                                 throw new MySqlException("error connecting: Timeout expired.  The timeout period elapsed " + 
89                                         "prior to obtaining a connection from the pool.  This may have occurred because all " +
90                                         "pooled connections were in use and max pool size was reached.");
91
92                         return conn;
93                         //System.Diagnostics.Debug.WriteLine("Creating a new driver");
94 /*                      Driver driver = new Driver();
95                         try 
96                         {
97                                 driver.Connection = conn;
98                                 driver.Open( conn.DataSource, conn.Port, conn.User, conn.Password, conn.UseCompression );
99
100                                 driver.SendCommand( DBCmd.INIT_DB, connString["database"] );
101                         }
102                         catch (Exception ex)
103                         {
104                                 throw new MySqlException("Database initialization failed with message: " + ex.Message);
105                         }
106
107                         pool.Add( driver );
108                         return driver;*/
109                 }
110
111         }
112 }