root / trunk / org.gvsig.postgresql / org.gvsig.postgresql.provider / src / main / java / org / gvsig / postgresql / dal / PostgreSQLHelper.java @ 650
History | View | Annotate | Download (11.3 KB)
1 | 362 | jjdelcerro | |
---|---|---|---|
2 | package org.gvsig.postgresql.dal; |
||
3 | |||
4 | import java.sql.Connection; |
||
5 | import java.sql.SQLException; |
||
6 | 650 | fdiaz | import org.apache.commons.dbcp2.BasicDataSource; |
7 | 362 | jjdelcerro | import org.apache.commons.lang3.BooleanUtils; |
8 | import org.apache.commons.lang3.StringUtils; |
||
9 | 570 | jjdelcerro | import org.gvsig.expressionevaluator.GeometryExpressionBuilderHelper.GeometrySupportType; |
10 | 362 | jjdelcerro | import org.gvsig.fmap.dal.resource.exception.AccessResourceException; |
11 | import org.gvsig.fmap.dal.store.jdbc.JDBCConnectionParameters; |
||
12 | import org.gvsig.fmap.dal.store.jdbc.JDBCNewStoreParameters; |
||
13 | import org.gvsig.fmap.dal.store.jdbc.JDBCServerExplorerParameters; |
||
14 | import org.gvsig.fmap.dal.store.jdbc.JDBCStoreParameters; |
||
15 | import org.gvsig.fmap.dal.store.jdbc.exception.JDBCDriverClassNotFoundException; |
||
16 | import org.gvsig.fmap.dal.store.jdbc2.OperationsFactory; |
||
17 | import org.gvsig.fmap.dal.store.jdbc2.spi.JDBCHelperBase; |
||
18 | import org.gvsig.fmap.dal.store.jdbc2.spi.JDBCSQLBuilderBase; |
||
19 | 433 | jjdelcerro | import org.gvsig.fmap.dal.store.jdbc2.spi.SRSSolverBase; |
20 | 576 | jjdelcerro | import org.gvsig.fmap.dal.store.jdbc2.spi.SRSSolverDumb; |
21 | 362 | jjdelcerro | import org.gvsig.postgresql.dal.operations.PostgreSQLOperationsFactory; |
22 | import org.slf4j.Logger; |
||
23 | import org.slf4j.LoggerFactory; |
||
24 | |||
25 | public class PostgreSQLHelper extends JDBCHelperBase { |
||
26 | |||
27 | 570 | jjdelcerro | /* friend */ static final Logger LOGGER = LoggerFactory.getLogger(PostgreSQLHelper.class); |
28 | 362 | jjdelcerro | |
29 | public static final String POSTGRESQL_JDBC_DRIVER = "org.postgresql.Driver"; |
||
30 | |||
31 | public static String getConnectionURL(PostgreSQLConnectionParameters params) { |
||
32 | return getConnectionURL(
|
||
33 | params.getHost(), |
||
34 | params.getPort(), |
||
35 | params.getDBName() |
||
36 | ); |
||
37 | } |
||
38 | |||
39 | public static String getConnectionURL(String host, Integer port, String db) { |
||
40 | if( StringUtils.isEmpty(host) ) {
|
||
41 | throw new IllegalArgumentException("Parameter 'host' can't be null."); |
||
42 | } |
||
43 | String connectionURL = "jdbc:postgresql://" + host; |
||
44 | if (port != null) { |
||
45 | connectionURL = connectionURL + ":" + port;
|
||
46 | } |
||
47 | connectionURL = connectionURL + "/" + db;
|
||
48 | 570 | jjdelcerro | LOGGER.debug("connectionURL: {}", connectionURL);
|
49 | 362 | jjdelcerro | return connectionURL;
|
50 | } |
||
51 | |||
52 | private static class ConnectionProvider { |
||
53 | |||
54 | private static boolean needRegisterDriver = true; |
||
55 | |||
56 | private BasicDataSource dataSource = null; |
||
57 | |||
58 | private final PostgreSQLConnectionParameters connectionParameters; |
||
59 | |||
60 | public ConnectionProvider(PostgreSQLConnectionParameters connectionParameters) {
|
||
61 | this.connectionParameters = connectionParameters;
|
||
62 | } |
||
63 | |||
64 | public Connection getConnection() throws SQLException { |
||
65 | if (this.dataSource == null) { |
||
66 | this.dataSource = this.createDataSource(); |
||
67 | } |
||
68 | 570 | jjdelcerro | if( LOGGER.isDebugEnabled() ) {
|
69 | LOGGER.debug("getConnection:\n" + getStatusInformation());
|
||
70 | 433 | jjdelcerro | } |
71 | Connection conn;
|
||
72 | try {
|
||
73 | conn = this.dataSource.getConnection();
|
||
74 | } catch(Throwable ex) { |
||
75 | 570 | jjdelcerro | LOGGER.debug("Error getting connection from pool.",ex);
|
76 | 433 | jjdelcerro | throw ex;
|
77 | } |
||
78 | 650 | fdiaz | try {
|
79 | conn.setNetworkTimeout(null, this.connectionParameters.getNetworkTimeout()); |
||
80 | } catch(Throwable ex) { |
||
81 | LOGGER.warn("Error setting the network timeout.",ex);
|
||
82 | } |
||
83 | 570 | jjdelcerro | if( LOGGER.isDebugEnabled() ) {
|
84 | LOGGER.debug("Created connection: {}\n NumActive: {}\n NumIdle: {}",
|
||
85 | 433 | jjdelcerro | new Object[] { |
86 | conn.hashCode(), |
||
87 | this.dataSource.getNumActive(),
|
||
88 | this.dataSource.getNumIdle()
|
||
89 | } |
||
90 | ); |
||
91 | } |
||
92 | 362 | jjdelcerro | return conn;
|
93 | } |
||
94 | 433 | jjdelcerro | |
95 | public void closeConnection(Connection connection) { |
||
96 | if( connection != null ) { |
||
97 | int connectionId = connection.hashCode();
|
||
98 | try {
|
||
99 | connection.close(); |
||
100 | } catch(Throwable ex) { |
||
101 | 570 | jjdelcerro | LOGGER.warn("Can't close connection.", ex);
|
102 | 433 | jjdelcerro | } |
103 | 570 | jjdelcerro | if( LOGGER.isDebugEnabled() ) {
|
104 | 433 | jjdelcerro | Boolean isClosed;
|
105 | try {
|
||
106 | isClosed = connection.isClosed(); |
||
107 | } catch(Throwable th) { |
||
108 | isClosed = null;
|
||
109 | } |
||
110 | 570 | jjdelcerro | LOGGER.debug("Closed connection: {}\n isClosed: {}\n NumActive: {}\n NumIdle: {}",
|
111 | 433 | jjdelcerro | new Object[] { |
112 | connectionId, |
||
113 | isClosed, |
||
114 | this.dataSource.getNumActive(),
|
||
115 | this.dataSource.getNumIdle()
|
||
116 | } |
||
117 | ); |
||
118 | } |
||
119 | 570 | jjdelcerro | } else if( LOGGER.isDebugEnabled() ) { |
120 | LOGGER.debug("Close connection: null");
|
||
121 | 433 | jjdelcerro | } |
122 | } |
||
123 | |||
124 | public String getStatusInformation() { |
||
125 | StringBuilder builder = new StringBuilder(); |
||
126 | builder.append("BasicDataSource pool status:\n");
|
||
127 | builder.append(" Connection URL: '").append(this.dataSource.getUrl()).append("'\n"); |
||
128 | if( this.dataSource.getInitialSize()>0 ) { |
||
129 | builder.append(" InitialSize: ").append(this.dataSource.getInitialSize()).append(" (The initial number of connections that are created when the pool is started)\n"); |
||
130 | } |
||
131 | if( this.dataSource.isPoolPreparedStatements() ) { |
||
132 | builder.append(" PoolPreparedStatements: ").append(this.dataSource.isPoolPreparedStatements()).append("\n"); |
||
133 | builder.append(" MaxOpenPreparedStatements: ").append(this.dataSource.getMaxOpenPreparedStatements()).append(" (The maximum number of open statements that can be allocated from the statement pool at the same time, or non-positive for no limit)\n"); |
||
134 | } |
||
135 | 650 | fdiaz | builder.append(" MaxTotal: ").append(this.dataSource.getMaxTotal()).append(" (The maximum number of active connections that can be allocated from this pool at the same time)\n"); |
136 | 433 | jjdelcerro | builder.append(" MaxIdle: ").append(this.dataSource.getMaxIdle()).append(" (The maximum number of connections that can remain idle in the pool)\n"); |
137 | builder.append(" NumActive:").append(this.dataSource.getNumActive()).append(" (the current number of active connections)\n"); |
||
138 | builder.append(" NumIdle:").append(this.dataSource.getNumIdle()).append(" (the current number of idle connections)\n"); |
||
139 | return builder.toString();
|
||
140 | } |
||
141 | 362 | jjdelcerro | |
142 | private BasicDataSource createDataSource() throws SQLException { |
||
143 | if (!this.isRegistered()) { |
||
144 | this.registerDriver();
|
||
145 | } |
||
146 | PostgreSQLConnectionParameters params = connectionParameters; |
||
147 | |||
148 | BasicDataSource ds = new BasicDataSource();
|
||
149 | 433 | jjdelcerro | ds.setMaxIdle(params.getMaxIdle()); |
150 | 362 | jjdelcerro | ds.setDriverClassName(params.getJDBCDriverClassName()); |
151 | if( params.getUseSSL() ) {
|
||
152 | String s = BooleanUtils.toStringTrueFalse(params.getUseSSL());
|
||
153 | ds.addConnectionProperty("ssl", s );
|
||
154 | } |
||
155 | if( !StringUtils.isEmpty(params.getUser()) ) {
|
||
156 | ds.setUsername(params.getUser()); |
||
157 | } |
||
158 | if( !StringUtils.isEmpty(params.getPassword()) ) {
|
||
159 | ds.setPassword(params.getPassword()); |
||
160 | } |
||
161 | ds.setUrl(params.getUrl()); |
||
162 | |||
163 | 650 | fdiaz | ds.setMaxWaitMillis(60L * 1000); |
164 | 362 | jjdelcerro | return ds;
|
165 | } |
||
166 | |||
167 | private boolean isRegistered() { |
||
168 | return needRegisterDriver;
|
||
169 | } |
||
170 | |||
171 | public void registerDriver() throws SQLException { |
||
172 | String className = this.connectionParameters.getJDBCDriverClassName(); |
||
173 | if (className == null) { |
||
174 | return;
|
||
175 | } |
||
176 | try {
|
||
177 | Class theClass = Class.forName(className); |
||
178 | if (theClass == null) { |
||
179 | 364 | jjdelcerro | throw new JDBCDriverClassNotFoundException(PostgreSQLLibrary.NAME, className); |
180 | 362 | jjdelcerro | } |
181 | } catch (Exception e) { |
||
182 | throw new SQLException("Can't register JDBC driver '" + className + "'.", e); |
||
183 | } |
||
184 | needRegisterDriver = false;
|
||
185 | } |
||
186 | |||
187 | } |
||
188 | |||
189 | private ConnectionProvider connectionProvider = null; |
||
190 | |||
191 | 576 | jjdelcerro | public PostgreSQLHelper() {
|
192 | super(null); |
||
193 | this.srssolver = new SRSSolverDumb(this); |
||
194 | } |
||
195 | |||
196 | 362 | jjdelcerro | public PostgreSQLHelper(JDBCConnectionParameters connectionParameters) {
|
197 | super(connectionParameters);
|
||
198 | 433 | jjdelcerro | this.srssolver = new SRSSolverBase(this); |
199 | 362 | jjdelcerro | } |
200 | |||
201 | @Override
|
||
202 | public Connection getConnection() throws AccessResourceException { |
||
203 | try {
|
||
204 | if (this.connectionProvider == null) { |
||
205 | 576 | jjdelcerro | if( this.getConnectionParameters()==null ) { |
206 | return null; |
||
207 | } |
||
208 | this.connectionProvider = new ConnectionProvider(this.getConnectionParameters()); |
||
209 | 362 | jjdelcerro | } |
210 | return this.connectionProvider.getConnection(); |
||
211 | } catch (SQLException ex) { |
||
212 | 364 | jjdelcerro | throw new AccessResourceException(PostgreSQLLibrary.NAME, ex); |
213 | 362 | jjdelcerro | } |
214 | } |
||
215 | 433 | jjdelcerro | |
216 | @Override
|
||
217 | public void closeConnection(Connection connection) { |
||
218 | 576 | jjdelcerro | if( connection!=null ) { // In test ??? |
219 | 433 | jjdelcerro | this.connectionProvider.closeConnection(connection);
|
220 | 576 | jjdelcerro | } |
221 | 433 | jjdelcerro | } |
222 | 362 | jjdelcerro | |
223 | @Override
|
||
224 | public PostgreSQLConnectionParameters getConnectionParameters() {
|
||
225 | return (PostgreSQLConnectionParameters) super.getConnectionParameters(); |
||
226 | } |
||
227 | |||
228 | @Override
|
||
229 | public String getConnectionURL() { |
||
230 | return getConnectionURL(this.getConnectionParameters()); |
||
231 | } |
||
232 | |||
233 | @Override
|
||
234 | protected String getResourceType() { |
||
235 | 364 | jjdelcerro | return PostgreSQLLibrary.NAME;
|
236 | 362 | jjdelcerro | } |
237 | |||
238 | @Override
|
||
239 | public String getProviderName() { |
||
240 | 364 | jjdelcerro | return PostgreSQLLibrary.NAME;
|
241 | 362 | jjdelcerro | } |
242 | |||
243 | @Override
|
||
244 | public JDBCSQLBuilderBase createSQLBuilder() {
|
||
245 | return new PostgreSQLBuilder(this); |
||
246 | } |
||
247 | |||
248 | @Override
|
||
249 | public OperationsFactory getOperations() {
|
||
250 | if (this.operationsFactory == null) { |
||
251 | this.operationsFactory = new PostgreSQLOperationsFactory(this); |
||
252 | } |
||
253 | return operationsFactory;
|
||
254 | } |
||
255 | |||
256 | @Override
|
||
257 | 511 | jjdelcerro | public GeometrySupportType getGeometrySupportType() {
|
258 | return GeometrySupportType.WKB;
|
||
259 | 362 | jjdelcerro | } |
260 | |||
261 | @Override
|
||
262 | public boolean hasSpatialFunctions() { |
||
263 | return true; |
||
264 | } |
||
265 | |||
266 | @Override
|
||
267 | public boolean canWriteGeometry(int geometryType, int geometrySubtype) { |
||
268 | return true; |
||
269 | } |
||
270 | |||
271 | @Override
|
||
272 | public String getQuoteForIdentifiers() { |
||
273 | return "\""; |
||
274 | } |
||
275 | |||
276 | @Override
|
||
277 | public boolean allowAutomaticValues() { |
||
278 | return true; |
||
279 | } |
||
280 | |||
281 | @Override
|
||
282 | public boolean supportOffsetInSelect() { |
||
283 | return true; |
||
284 | } |
||
285 | |||
286 | @Override
|
||
287 | public String getQuoteForStrings() { |
||
288 | return "'"; |
||
289 | } |
||
290 | |||
291 | @Override
|
||
292 | public String getSourceId(JDBCStoreParameters parameters) { |
||
293 | return parameters.getDBName() + "." + |
||
294 | parameters.getSchema()+ "." +
|
||
295 | parameters.getTable(); |
||
296 | } |
||
297 | |||
298 | @Override
|
||
299 | public JDBCNewStoreParameters createNewStoreParameters() {
|
||
300 | return new PostgreSQLNewStoreParameters(); |
||
301 | } |
||
302 | |||
303 | @Override
|
||
304 | public JDBCStoreParameters createOpenStoreParameters() {
|
||
305 | return new PostgreSQLStoreParameters(); |
||
306 | } |
||
307 | |||
308 | @Override
|
||
309 | public JDBCServerExplorerParameters createServerExplorerParameters() {
|
||
310 | 385 | jjdelcerro | return new PostgreSQLServerExplorerParameters(); |
311 | 362 | jjdelcerro | } |
312 | } |