1 | /* |
2 | * Copyright 2004-2014 H2 Group. Multiple-Licensed under the MPL 2.0, |
3 | * and the EPL 1.0 (http://h2database.com/html/license.html). |
4 | * Initial Developer: H2 Group |
5 | */ |
6 | package org.h2; |
7 | |
8 | import java.sql.Connection; |
9 | import java.sql.DriverManager; |
10 | import java.sql.DriverPropertyInfo; |
11 | import java.sql.SQLException; |
12 | import java.util.Properties; |
13 | import org.h2.engine.Constants; |
14 | import org.h2.jdbc.JdbcConnection; |
15 | import org.h2.message.DbException; |
16 | import org.h2.upgrade.DbUpgrade; |
17 | |
18 | //## Java 1.7 ## |
19 | import java.util.logging.Logger; |
20 | //*/ |
21 | |
22 | /** |
23 | * The database driver. An application should not use this class directly. The |
24 | * only thing the application needs to do is load the driver. This can be done |
25 | * using Class.forName. To load the driver and open a database connection, use |
26 | * the following code: |
27 | * |
28 | * <pre> |
29 | * Class.forName("org.h2.Driver"); |
30 | * Connection conn = DriverManager.getConnection( |
31 | * "jdbc:h2:˜/test", "sa", "sa"); |
32 | * </pre> |
33 | */ |
34 | public class Driver implements java.sql.Driver { |
35 | |
36 | private static final Driver INSTANCE = new Driver(); |
37 | private static final String DEFAULT_URL = "jdbc:default:connection"; |
38 | private static final ThreadLocal<Connection> DEFAULT_CONNECTION = |
39 | new ThreadLocal<Connection>(); |
40 | |
41 | private static volatile boolean registered; |
42 | |
43 | static { |
44 | load(); |
45 | } |
46 | |
47 | /** |
48 | * Open a database connection. |
49 | * This method should not be called by an application. |
50 | * Instead, the method DriverManager.getConnection should be used. |
51 | * |
52 | * @param url the database URL |
53 | * @param info the connection properties |
54 | * @return the new connection or null if the URL is not supported |
55 | */ |
56 | @Override |
57 | public Connection connect(String url, Properties info) throws SQLException { |
58 | try { |
59 | if (info == null) { |
60 | info = new Properties(); |
61 | } |
62 | if (!acceptsURL(url)) { |
63 | return null; |
64 | } |
65 | if (url.equals(DEFAULT_URL)) { |
66 | return DEFAULT_CONNECTION.get(); |
67 | } |
68 | Connection c = DbUpgrade.connectOrUpgrade(url, info); |
69 | if (c != null) { |
70 | return c; |
71 | } |
72 | return new JdbcConnection(url, info); |
73 | } catch (Exception e) { |
74 | throw DbException.toSQLException(e); |
75 | } |
76 | } |
77 | |
78 | /** |
79 | * Check if the driver understands this URL. |
80 | * This method should not be called by an application. |
81 | * |
82 | * @param url the database URL |
83 | * @return if the driver understands the URL |
84 | */ |
85 | @Override |
86 | public boolean acceptsURL(String url) { |
87 | if (url != null) { |
88 | if (url.startsWith(Constants.START_URL)) { |
89 | return true; |
90 | } else if (url.equals(DEFAULT_URL)) { |
91 | return DEFAULT_CONNECTION.get() != null; |
92 | } |
93 | } |
94 | return false; |
95 | } |
96 | |
97 | /** |
98 | * Get the major version number of the driver. |
99 | * This method should not be called by an application. |
100 | * |
101 | * @return the major version number |
102 | */ |
103 | @Override |
104 | public int getMajorVersion() { |
105 | return Constants.VERSION_MAJOR; |
106 | } |
107 | |
108 | /** |
109 | * Get the minor version number of the driver. |
110 | * This method should not be called by an application. |
111 | * |
112 | * @return the minor version number |
113 | */ |
114 | @Override |
115 | public int getMinorVersion() { |
116 | return Constants.VERSION_MINOR; |
117 | } |
118 | |
119 | /** |
120 | * Get the list of supported properties. |
121 | * This method should not be called by an application. |
122 | * |
123 | * @param url the database URL |
124 | * @param info the connection properties |
125 | * @return a zero length array |
126 | */ |
127 | @Override |
128 | public DriverPropertyInfo[] getPropertyInfo(String url, Properties info) { |
129 | return new DriverPropertyInfo[0]; |
130 | } |
131 | |
132 | /** |
133 | * Check if this driver is compliant to the JDBC specification. |
134 | * This method should not be called by an application. |
135 | * |
136 | * @return true |
137 | */ |
138 | @Override |
139 | public boolean jdbcCompliant() { |
140 | return true; |
141 | } |
142 | |
143 | /** |
144 | * [Not supported] |
145 | */ |
146 | //## Java 1.7 ## |
147 | public Logger getParentLogger() { |
148 | return null; |
149 | } |
150 | //*/ |
151 | |
152 | /** |
153 | * INTERNAL |
154 | */ |
155 | public static synchronized Driver load() { |
156 | try { |
157 | if (!registered) { |
158 | registered = true; |
159 | DriverManager.registerDriver(INSTANCE); |
160 | } |
161 | } catch (SQLException e) { |
162 | DbException.traceThrowable(e); |
163 | } |
164 | return INSTANCE; |
165 | } |
166 | |
167 | /** |
168 | * INTERNAL |
169 | */ |
170 | public static synchronized void unload() { |
171 | try { |
172 | if (registered) { |
173 | registered = false; |
174 | DriverManager.deregisterDriver(INSTANCE); |
175 | } |
176 | } catch (SQLException e) { |
177 | DbException.traceThrowable(e); |
178 | } |
179 | } |
180 | |
181 | /** |
182 | * INTERNAL |
183 | * Sets, on a per-thread basis, the default-connection for |
184 | * user-defined functions. |
185 | */ |
186 | public static void setDefaultConnection(Connection c) { |
187 | if (c == null) { |
188 | DEFAULT_CONNECTION.remove(); |
189 | } else { |
190 | DEFAULT_CONNECTION.set(c); |
191 | } |
192 | } |
193 | |
194 | /** |
195 | * INTERNAL |
196 | */ |
197 | public static void setThreadContextClassLoader(Thread thread) { |
198 | // Apache Tomcat: use the classloader of the driver to avoid the |
199 | // following log message: |
200 | // org.apache.catalina.loader.WebappClassLoader clearReferencesThreads |
201 | // SEVERE: The web application appears to have started a thread named |
202 | // ... but has failed to stop it. |
203 | // This is very likely to create a memory leak. |
204 | try { |
205 | thread.setContextClassLoader(Driver.class.getClassLoader()); |
206 | } catch (Throwable t) { |
207 | // ignore |
208 | } |
209 | } |
210 | |
211 | } |