Added files and folders for TARGET_JVM code base
[mono.git] / mcs / class / System.Data / System.Data.OleDb.jvm / OleDbConnectionFactory.cs
1 /*\r
2   * Copyright (c) 2002-2004 Mainsoft Corporation.\r
3   *\r
4   * Permission is hereby granted, free of charge, to any person obtaining a\r
5   * copy of this software and associated documentation files (the "Software"),\r
6   * to deal in the Software without restriction, including without limitation\r
7   * the rights to use, copy, modify, merge, publish, distribute, sublicense,\r
8   * and/or sell copies of the Software, and to permit persons to whom the\r
9   * Software is furnished to do so, subject to the following conditions:\r
10   *\r
11   * The above copyright notice and this permission notice shall be included in\r
12   * all copies or substantial portions of the Software.\r
13   *\r
14   * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
15   * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
16   * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r
17   * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r
18   * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\r
19   * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\r
20   * DEALINGS IN THE SOFTWARE.\r
21   */\r
22 \r
23 \r
24 using System;\r
25 using System.Data;\r
26 using System.Data.Common;\r
27 using System.Reflection;\r
28 using System.Collections;\r
29 \r
30 namespace System.Data.OleDb\r
31 {\r
32         internal class OleDbConnectionFactory\r
33         {\r
34                 private static Object LockObj = new Object();\r
35                 private static Hashtable dataSourceCache = new Hashtable();\r
36                 private static Type OracleConnectionCacheImplType = Type.GetType("oracle.jdbc.pool.OracleConnectionCacheImpl");\r
37                                                                                                                                                   \r
38                 private static MethodInfo setUrlMethod = OracleConnectionCacheImplType.GetMethod("setURL", BindingFlags.Public | BindingFlags.Instance);\r
39                 private static MethodInfo setUserMethod = OracleConnectionCacheImplType.GetMethod("setUser", BindingFlags.Public | BindingFlags.Instance);\r
40                 private static MethodInfo setPasswordMethod = OracleConnectionCacheImplType.GetMethod("setPassword", BindingFlags.Public | BindingFlags.Instance);\r
41                 private static MethodInfo getActiveSizeMethod = OracleConnectionCacheImplType.GetMethod("getActiveSize", BindingFlags.Public | BindingFlags.Instance);\r
42                 private static MethodInfo closeMethod = OracleConnectionCacheImplType.GetMethod("close", BindingFlags.Public | BindingFlags.Instance);\r
43                 private static MethodInfo setMaxLimitMethod = OracleConnectionCacheImplType.GetMethod("setMaxLimit", BindingFlags.Public | BindingFlags.Instance);\r
44                 private static MethodInfo setMinLimitMethod = OracleConnectionCacheImplType.GetMethod("setMinLimit", BindingFlags.Public | BindingFlags.Instance);\r
45                 private static long timestamp = DateTime.Now.Ticks;\r
46                 private static int MINUTES_TIMEOUT = 60;\r
47 \r
48                 private static DbStringManager StringManager = new DbStringManager("System.Data.System.Data.ProviderBase.jvm.OleDbStrings");\r
49 \r
50                 internal static java.sql.Connection GetConnection(OleDbConnection.PROVIDER_TYPE providerType,String url,String user,String password,int timeout)\r
51                 {\r
52                         CacheKey key = new CacheKey(url,user,password);\r
53                         Object dataSourceObj;\r
54                         lock(LockObj) \r
55                         {\r
56                                 if (TimeIsOver())\r
57                                         Clear();\r
58 \r
59                                 dataSourceObj = dataSourceCache[key];\r
60                                 if (dataSourceObj == null) \r
61                                 {\r
62                                         switch(providerType) \r
63                                         {\r
64                                                 case OleDbConnection.PROVIDER_TYPE.MSDAORA :                                    \r
65                                         \r
66                                                         dataSourceObj = Activator.CreateInstance(OracleConnectionCacheImplType);\r
67                                         \r
68                                                         Object[] setUrlArgs = new Object[1] { url };\r
69                                                         Object[] setUserArgs = new Object[1] { user };\r
70                                                         Object[] setPasswordArgs = new Object[1] { password };\r
71 \r
72                                                         setUrlMethod.Invoke(dataSourceObj,setUrlArgs);\r
73                                                         setUserMethod.Invoke(dataSourceObj,setUserArgs);\r
74                                                         setPasswordMethod.Invoke(dataSourceObj,setPasswordArgs);\r
75 \r
76                                                         int maxLimit = Convert.ToInt32(StringManager.GetString("ORA_CONNECTION_POOLING_MAX_LIMIT","-1"));\r
77                                                         int minLimit = Convert.ToInt32(StringManager.GetString("ORA_CONNECTION_POOLING_MIN_LIMIT","-1"));\r
78 \r
79                                                         if(minLimit != -1)\r
80                                                                 setMinLimitMethod.Invoke(dataSourceObj,new Object[1] { minLimit } );\r
81 \r
82                                                         if(maxLimit != -1)\r
83                                                                 setMaxLimitMethod.Invoke(dataSourceObj,new Object[1] { maxLimit } );\r
84 \r
85                                                         break;\r
86                                         }\r
87                                         dataSourceCache.Add(key,dataSourceObj);\r
88                                 }\r
89                         }\r
90 \r
91                         java.sql.Connection conn;\r
92                         lock(dataSourceObj) {\r
93                                 if (((javax.sql.DataSource)dataSourceObj).getLoginTimeout() != timeout) {\r
94                                         ((javax.sql.DataSource)dataSourceObj).setLoginTimeout(timeout);\r
95                                 }\r
96                                 conn = ((javax.sql.DataSource)dataSourceObj).getConnection();\r
97                         }\r
98                         return conn;\r
99                 }\r
100 \r
101                 private static bool TimeIsOver() \r
102                 {\r
103                                 return (DateTime.Now.Ticks - timestamp > MINUTES_TIMEOUT * TimeSpan.TicksPerMinute);\r
104                 }\r
105 \r
106                 private static void Clear() \r
107                 {\r
108                         ArrayList closedDataSources = new ArrayList();\r
109 \r
110                         // collect all the datasources with no connections in use\r
111                         foreach(DictionaryEntry e in dataSourceCache)\r
112                         {\r
113                                 Object dataSourceObj = e.Value;\r
114                                 Object dataSourceObjKey = e.Key;\r
115 \r
116                                 if (getActiveSizeMethod.Invoke(dataSourceObj,new object[0]).Equals(0)) {\r
117                                         closeMethod.Invoke(dataSourceObj,new object[0]);\r
118                                         closedDataSources.Add(dataSourceObjKey);\r
119                                 }\r
120                         }\r
121 \r
122                         // close and remove all data sources with no connections in use\r
123                         foreach(Object dataSourceObjKey in closedDataSources) {\r
124                                 dataSourceCache.Remove(dataSourceObjKey);\r
125                         }       \r
126                 }\r
127         }\r
128 \r
129         // Key for data sources cache\r
130         // data sources mapped by jdbc url, user and password\r
131         internal class CacheKey\r
132     {\r
133         private String url;\r
134         private String user;\r
135         private String password;\r
136 \r
137         public CacheKey(String url, String user, String password)\r
138         {\r
139             this.url = url;\r
140             this.user = user;\r
141             this.password = password;\r
142         }\r
143 \r
144         public bool equals(Object o)\r
145         {\r
146             if (this == o) return true;\r
147             if (!(o is CacheKey)) return false;\r
148 \r
149             CacheKey cacheKey = (CacheKey) o;\r
150 \r
151             if (!password.Equals(cacheKey.password)) return false;\r
152             if (!url.Equals(cacheKey.url)) return false;\r
153             if (!user.Equals(cacheKey.user)) return false;\r
154 \r
155             return true;\r
156         }\r
157 \r
158         public int hashCode()\r
159         {\r
160             int result;\r
161             result = url.GetHashCode();\r
162             result = 29 * result + user.GetHashCode();\r
163             result = 29 * result + password.GetHashCode();\r
164             return result;\r
165         }\r
166     }\r
167 }\r