3 // Ben Motmans <ben.motmans@gmail.com>
5 // Copyright (c) 2007 Ben Motmans
7 // Permission is hereby granted, free of charge, to any person obtaining a copy
8 // of this software and associated documentation files (the "Software"), to deal
9 // in the Software without restriction, including without limitation the rights
10 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 // copies of the Software, and to permit persons to whom the Software is
12 // furnished to do so, subject to the following conditions:
14 // The above copyright notice and this permission notice shall be included in
15 // all copies or substantial portions of the Software.
17 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
28 using System
.Collections
.Generic
;
30 namespace MonoDevelop
.Database
.Sql
32 public class DefaultConnectionPool
: IConnectionPool
34 protected int minSize
= 1;
35 protected int maxSize
= 20;
36 protected int growSize
= 3;
37 protected int shrinkSize
= 5;
39 protected bool hasErrors
;
40 protected string error
;
42 protected IDbFactory factory
;
43 protected DatabaseConnectionContext context
;
44 protected IConnectionProvider connectionProvider
;
46 protected bool hasVersion
;
47 protected Version databaseVersion
;
49 protected bool isInitialized
;
51 protected List
<IPooledDbConnection
> connections
;
52 protected Queue
<IPooledDbConnection
> freeConnections
;
54 protected object sync
= new object ();
56 public DefaultConnectionPool (IDbFactory factory
, IConnectionProvider connectionProvider
, DatabaseConnectionContext context
)
59 throw new ArgumentNullException ("factory");
60 if (connectionProvider
== null)
61 throw new ArgumentNullException ("connectionProvider");
63 throw new ArgumentNullException ("context");
65 this.factory
= factory
;
66 this.connectionProvider
= connectionProvider
;
67 this.context
= context
;
69 connections
= new List
<IPooledDbConnection
> ();
70 freeConnections
= new Queue
<IPooledDbConnection
> ();
73 public virtual IDbFactory DbFactory
{
74 get { return factory; }
77 public virtual DatabaseConnectionContext ConnectionContext
{
78 get { return context; }
81 public virtual IConnectionProvider ConnectionProvider
{
82 get { return connectionProvider; }
85 public virtual bool IsInitialized
{
86 get { return isInitialized; }
89 public virtual bool HasErrors
{
90 get { return hasErrors; }
93 public virtual string Error
{
97 public virtual bool HasVersion
{
98 get { return hasVersion; }
101 public virtual Version DatabaseVersion
{
102 get { return databaseVersion; }
105 public virtual int MinSize
{
106 get { return minSize; }
108 if (value < 1 || value > maxSize
)
109 throw new IndexOutOfRangeException ("MinSize");
114 public virtual int MaxSize
{
115 get { return maxSize; }
118 throw new IndexOutOfRangeException ("MaxSize");
123 public virtual int GrowSize
{
124 get { return growSize; }
126 if (value < 1 || value > 10)
127 throw new IndexOutOfRangeException ("GrowSize");
132 public virtual int ShrinkSize
{
133 get { return shrinkSize; }
135 if (value < 1 || value > 10)
136 throw new IndexOutOfRangeException ("GrowSize");
141 public virtual int ConnectionCount
{
144 return connections
.Count
+ freeConnections
.Count
;
148 public virtual int FreeConnectionCount
{
151 return freeConnections
.Count
;
155 public virtual bool HasFreeConnection
{
158 return freeConnections
.Count
> 0;
162 public virtual IPooledDbConnection
Request ()
164 IPooledDbConnection conn
= null;
165 if (HasFreeConnection
) {
167 conn
= freeConnections
.Dequeue ();
168 connections
.Add (conn
);
179 public virtual void Release (IPooledDbConnection connection
)
181 if (connection
== null)
185 if (freeConnections
.Contains (connection
))
188 if (connectionProvider
.CheckConnection (connection
, context
.ConnectionSettings
))
189 freeConnections
.Enqueue (connection
);
190 connections
.Remove (connection
);
195 public virtual bool Initialize ()
200 isInitialized
= CreateNewConnections (minSize
);
204 return isInitialized
;
207 protected virtual bool CreateNewConnections (int count
)
209 for (int i
=0; i
<count
; i
++) {
210 if (!CreateNewConnection ())
216 protected virtual bool CreateNewConnection ()
218 IPooledDbConnection conn
= connectionProvider
.CreateConnection (this, context
.ConnectionSettings
, out error
);
219 if (conn
== null || !conn
.IsOpen
) {
225 databaseVersion
= conn
.DatabaseVersion
;
231 freeConnections
.Enqueue (conn
);
236 public virtual void Close ()
239 isInitialized
= false;
245 protected virtual void Cleanup ()
248 foreach (IPooledDbConnection conn
in connections
)
250 foreach (IPooledDbConnection conn
in freeConnections
)
255 protected virtual bool Grow ()
257 return CreateNewConnections (growSize
);
260 protected virtual void Shrink ()
262 if (FreeConnectionCount
< shrinkSize
)
265 for (int i
=0; i
<shrinkSize
; i
++) {
266 if (HasFreeConnection
) {
268 IPooledDbConnection conn
= freeConnections
.Dequeue ();