37
37
import org .apache .logging .log4j .LogManager ;
38
38
import org .apache .logging .log4j .Logger ;
39
39
40
- import org .exist .dom .QName ;
41
40
import org .exist .xquery .*;
42
41
42
+ import java .sql .Array ;
43
+ import java .sql .Blob ;
44
+ import java .sql .CallableStatement ;
45
+ import java .sql .Clob ;
43
46
import java .sql .Connection ;
47
+ import java .sql .DatabaseMetaData ;
48
+ import java .sql .NClob ;
49
+ import java .sql .PreparedStatement ;
50
+ import java .sql .SQLClientInfoException ;
44
51
import java .sql .SQLException ;
45
-
52
+ import java .sql .SQLWarning ;
53
+ import java .sql .SQLXML ;
54
+ import java .sql .Savepoint ;
55
+ import java .sql .Statement ;
56
+ import java .sql .Struct ;
57
+ import java .util .Date ;
46
58
import java .util .List ;
47
59
import java .util .Map ;
48
60
import java .util .Map .Entry ;
49
61
import java .util .Properties ;
50
62
import java .util .concurrent .ConcurrentHashMap ;
63
+ import java .util .concurrent .Executor ;
51
64
import java .util .regex .Matcher ;
52
65
import java .util .regex .Pattern ;
53
66
54
67
import org .exist .xquery .modules .ModuleUtils ;
55
68
import org .exist .xquery .modules .ModuleUtils .ContextMapEntryModifier ;
56
- import org .exist .xquery .value .FunctionParameterSequenceType ;
57
- import org .exist .xquery .value .FunctionReturnSequenceType ;
58
-
59
69
import javax .annotation .Nullable ;
60
70
61
71
import static org .exist .xquery .FunctionDSL .functionDefs ;
@@ -86,6 +96,7 @@ public class SQLModule extends AbstractInternalModule {
86
96
public final static String PREPARED_STATEMENTS_CONTEXTVAR = "_eXist_sql_prepared_statements" ;
87
97
88
98
private static final Map <String , HikariDataSource > CONNECTION_POOLS = new ConcurrentHashMap <>();
99
+ private static final Map <String , Date > NO_CONNECTION_POOLS = new ConcurrentHashMap <>();
89
100
private static final Pattern POOL_NAME_PATTERN = Pattern .compile ("(pool\\ .[0-9]+)\\ .name" );
90
101
91
102
public SQLModule (final Map <String , List <?>> parameters ) {
@@ -105,7 +116,8 @@ public SQLModule(final Map<String, List<?>> parameters) {
105
116
final String poolId = poolNameMatcher .group (1 );
106
117
final String poolName = parameter .getValue ().get (0 ).toString ();
107
118
if (poolName != null && !poolName .isEmpty ()) {
108
- if (!CONNECTION_POOLS .containsKey (poolName )) {
119
+ boolean connectionFailure = NO_CONNECTION_POOLS .size () > 0 ;
120
+ if (!CONNECTION_POOLS .containsKey (poolName ) && !connectionFailure ) {
109
121
110
122
final Properties poolProperties = new Properties ();;
111
123
poolProperties .setProperty ("poolName" , poolName );
@@ -121,9 +133,18 @@ public SQLModule(final Map<String, List<?>> parameters) {
121
133
}
122
134
}
123
135
124
- final HikariConfig hikariConfig = new HikariConfig (poolProperties );
125
- final HikariDataSource hikariDataSource = new HikariDataSource (hikariConfig );
126
- CONNECTION_POOLS .put (poolName , hikariDataSource );
136
+ try {
137
+ final HikariConfig hikariConfig = new HikariConfig (poolProperties );
138
+ final HikariDataSource hikariDataSource = new HikariDataSource (hikariConfig );
139
+ CONNECTION_POOLS .put (poolName , hikariDataSource );
140
+ } catch (Exception ex ) {
141
+ connectionFailure = true ;
142
+ }
143
+ }
144
+ if (connectionFailure && !NO_CONNECTION_POOLS .containsKey (poolName )) {
145
+ LOG .warn ("No database connection for " +poolName +" could be made. Also not for " +String .join (", " , NO_CONNECTION_POOLS .keySet ()));
146
+ CONNECTION_POOLS .put (poolName , new NoConnectionHikariDataSource ());
147
+ NO_CONNECTION_POOLS .put (poolName , new Date ());
127
148
}
128
149
}
129
150
}
@@ -291,4 +312,185 @@ public void modifyEntry(final Entry<Long, PreparedStatementWithSQL> entry) {
291
312
}
292
313
});
293
314
}
315
+
316
+ class NoConnectionHikariDataSource extends HikariDataSource {
317
+ @ Override
318
+ public Connection getConnection () throws SQLException
319
+ {
320
+ return new Connection () {
321
+
322
+ @ Override
323
+ public <T > T unwrap (Class <T > iface ) throws SQLException { return null ; }
324
+
325
+ @ Override
326
+ public boolean isWrapperFor (Class <?> iface ) throws SQLException { return false ; }
327
+
328
+ @ Override
329
+ public Statement createStatement () throws SQLException { return null ; }
330
+
331
+ @ Override
332
+ public PreparedStatement prepareStatement (String sql ) throws SQLException { return null ; }
333
+
334
+ @ Override
335
+ public CallableStatement prepareCall (String sql ) throws SQLException { return null ; }
336
+
337
+ @ Override
338
+ public String nativeSQL (String sql ) throws SQLException { return null ; }
339
+
340
+ @ Override
341
+ public void setAutoCommit (boolean autoCommit ) throws SQLException {}
342
+
343
+ @ Override
344
+ public boolean getAutoCommit () throws SQLException { return false ; }
345
+
346
+ @ Override
347
+ public void commit () throws SQLException {}
348
+
349
+ @ Override
350
+ public void rollback () throws SQLException {}
351
+
352
+ @ Override
353
+ public void close () throws SQLException {}
354
+
355
+ @ Override
356
+ public boolean isClosed () throws SQLException { return false ; }
357
+
358
+ @ Override
359
+ public DatabaseMetaData getMetaData () throws SQLException { return null ; }
360
+
361
+ @ Override
362
+ public void setReadOnly (boolean readOnly ) throws SQLException {}
363
+
364
+ @ Override
365
+ public boolean isReadOnly () throws SQLException { return false ; }
366
+
367
+ @ Override
368
+ public void setCatalog (String catalog ) throws SQLException {}
369
+
370
+ @ Override
371
+ public String getCatalog () throws SQLException { return null ; }
372
+
373
+ @ Override
374
+ public void setTransactionIsolation (int level ) throws SQLException {}
375
+
376
+ @ Override
377
+ public int getTransactionIsolation () throws SQLException { return 0 ;}
378
+
379
+ @ Override
380
+ public SQLWarning getWarnings () throws SQLException { return null ; }
381
+
382
+ @ Override
383
+ public void clearWarnings () throws SQLException {}
384
+
385
+ @ Override
386
+ public Statement createStatement (int resultSetType , int resultSetConcurrency )
387
+ throws SQLException { return null ; }
388
+
389
+ @ Override
390
+ public PreparedStatement prepareStatement (String sql , int resultSetType ,
391
+ int resultSetConcurrency ) throws SQLException { return null ; }
392
+
393
+ @ Override
394
+ public CallableStatement prepareCall (String sql , int resultSetType ,
395
+ int resultSetConcurrency ) throws SQLException { return null ; }
396
+
397
+ @ Override
398
+ public Map <String , Class <?>> getTypeMap () throws SQLException { return null ; }
399
+
400
+ @ Override
401
+ public void setTypeMap (Map <String , Class <?>> map ) throws SQLException {}
402
+
403
+ @ Override
404
+ public void setHoldability (int holdability ) throws SQLException {}
405
+
406
+ @ Override
407
+ public int getHoldability () throws SQLException { return 0 ; }
408
+
409
+ @ Override
410
+ public Savepoint setSavepoint () throws SQLException { return null ; }
411
+
412
+ @ Override
413
+ public Savepoint setSavepoint (String name ) throws SQLException { return null ; }
414
+
415
+ @ Override
416
+ public void rollback (Savepoint savepoint ) throws SQLException {}
417
+
418
+ @ Override
419
+ public void releaseSavepoint (Savepoint savepoint ) throws SQLException {}
420
+
421
+ @ Override
422
+ public Statement createStatement (int resultSetType , int resultSetConcurrency ,
423
+ int resultSetHoldability ) throws SQLException { return null ; }
424
+
425
+ @ Override
426
+ public PreparedStatement prepareStatement (String sql , int resultSetType ,
427
+ int resultSetConcurrency , int resultSetHoldability ) throws SQLException { return null ; }
428
+
429
+ @ Override
430
+ public CallableStatement prepareCall (String sql , int resultSetType ,
431
+ int resultSetConcurrency , int resultSetHoldability ) throws SQLException { return null ; }
432
+
433
+ @ Override
434
+ public PreparedStatement prepareStatement (String sql , int autoGeneratedKeys )
435
+ throws SQLException { return null ; }
436
+
437
+ @ Override
438
+ public PreparedStatement prepareStatement (String sql , int [] columnIndexes )
439
+ throws SQLException { return null ; }
440
+
441
+ @ Override
442
+ public PreparedStatement prepareStatement (String sql , String [] columnNames )
443
+ throws SQLException { return null ; }
444
+
445
+ @ Override
446
+ public Clob createClob () throws SQLException { return null ; }
447
+
448
+ @ Override
449
+ public Blob createBlob () throws SQLException { return null ; }
450
+
451
+ @ Override
452
+ public NClob createNClob () throws SQLException { return null ; }
453
+
454
+ @ Override
455
+ public SQLXML createSQLXML () throws SQLException { return null ; }
456
+
457
+ @ Override
458
+ public boolean isValid (int timeout ) throws SQLException { return false ; }
459
+
460
+ @ Override
461
+ public void setClientInfo (String name , String value ) throws SQLClientInfoException {}
462
+
463
+ @ Override
464
+ public void setClientInfo (Properties properties ) throws SQLClientInfoException {}
465
+
466
+ @ Override
467
+ public String getClientInfo (String name ) throws SQLException { return null ; }
468
+
469
+ @ Override
470
+ public Properties getClientInfo () throws SQLException { return null ; }
471
+
472
+ @ Override
473
+ public Array createArrayOf (String typeName , Object [] elements ) throws SQLException { return null ; }
474
+
475
+ @ Override
476
+ public Struct createStruct (String typeName , Object [] attributes ) throws SQLException { return null ; }
477
+
478
+ @ Override
479
+ public void setSchema (String schema ) throws SQLException {}
480
+
481
+ @ Override
482
+ public String getSchema () throws SQLException { return null ; }
483
+
484
+ @ Override
485
+ public void abort (Executor executor ) throws SQLException {}
486
+
487
+ @ Override
488
+ public void setNetworkTimeout (Executor executor , int milliseconds )
489
+ throws SQLException {}
490
+
491
+ @ Override
492
+ public int getNetworkTimeout () throws SQLException { return 0 ; }
493
+ };
494
+ }
495
+ }
294
496
}
0 commit comments