Automatically detect suitable database drivers

This commit is contained in:
James Agnew 2018-09-25 09:58:08 -04:00
parent c0051f309b
commit dc4c0809a4
3 changed files with 40 additions and 10 deletions

View File

@ -1,18 +1,23 @@
package ca.uhn.fhir.jpa.migrate; package ca.uhn.fhir.jpa.migrate;
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
import org.apache.commons.lang3.Validate; import org.apache.commons.lang3.Validate;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.datasource.DataSourceTransactionManager; import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.jdbc.datasource.SimpleDriverDataSource;
import org.springframework.jdbc.datasource.SingleConnectionDataSource; import org.springframework.jdbc.datasource.SingleConnectionDataSource;
import org.springframework.transaction.TransactionDefinition; import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.support.TransactionTemplate; import org.springframework.transaction.support.TransactionTemplate;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.Driver; import java.sql.Driver;
import java.sql.DriverManager; import java.sql.SQLException;
import java.util.Enumeration; import java.util.Properties;
/*- /*-
* #%L * #%L
@ -23,9 +28,9 @@ import java.util.Enumeration;
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
* *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@ -64,7 +69,21 @@ public enum DriverTypeEnum {
public ConnectionProperties newConnectionProperties(String theUrl, String theUsername, String thePassword) { public ConnectionProperties newConnectionProperties(String theUrl, String theUsername, String thePassword) {
SingleConnectionDataSource dataSource = new SingleConnectionDataSource(); Driver driver;
try {
driver = (Driver) Class.forName(myDriverClassName).newInstance();
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException e) {
throw new InternalErrorException("Unable to find driver class: " + myDriverClassName, e);
}
SingleConnectionDataSource dataSource = new SingleConnectionDataSource(){
@Override
protected Connection getConnectionFromDriver(Properties props) throws SQLException {
Connection connect = driver.connect(theUrl, props);
assert connect != null;
return connect;
}
};
dataSource.setAutoCommit(false); dataSource.setAutoCommit(false);
dataSource.setDriverClassName(myDriverClassName); dataSource.setDriverClassName(myDriverClassName);
dataSource.setUrl(theUrl); dataSource.setUrl(theUrl);
@ -87,13 +106,13 @@ public enum DriverTypeEnum {
public static class ConnectionProperties { public static class ConnectionProperties {
private final DriverTypeEnum myDriverType; private final DriverTypeEnum myDriverType;
private final SingleConnectionDataSource myDataSource; private final DataSource myDataSource;
private final TransactionTemplate myTxTemplate; private final TransactionTemplate myTxTemplate;
/** /**
* Constructor * Constructor
*/ */
public ConnectionProperties(SingleConnectionDataSource theDataSource, TransactionTemplate theTxTemplate, DriverTypeEnum theDriverType) { public ConnectionProperties(DataSource theDataSource, TransactionTemplate theTxTemplate, DriverTypeEnum theDriverType) {
Validate.notNull(theDataSource); Validate.notNull(theDataSource);
Validate.notNull(theTxTemplate); Validate.notNull(theTxTemplate);
Validate.notNull(theDriverType); Validate.notNull(theDriverType);
@ -108,7 +127,7 @@ public enum DriverTypeEnum {
} }
@Nonnull @Nonnull
public SingleConnectionDataSource getDataSource() { public DataSource getDataSource() {
return myDataSource; return myDataSource;
} }
@ -125,7 +144,13 @@ public enum DriverTypeEnum {
} }
public void close() { public void close() {
myDataSource.destroy(); if (myDataSource instanceof DisposableBean) {
try {
((DisposableBean) myDataSource).destroy();
} catch (Exception e) {
ourLog.warn("Could not dispose of driver", e);
}
}
} }
} }
} }

View File

@ -72,7 +72,7 @@ public class Migrator {
public void migrate() { public void migrate() {
ourLog.info("Starting migration with {} tasks", myTasks.size()); ourLog.info("Starting migration with {} tasks", myTasks.size());
myConnectionProperties = DriverTypeEnum.DERBY_EMBEDDED.newConnectionProperties(myConnectionUrl, myUsername, myPassword); myConnectionProperties = myDriverType.newConnectionProperties(myConnectionUrl, myUsername, myPassword);
try { try {
for (BaseTask next : myTasks) { for (BaseTask next : myTasks) {
next.setDriverType(myDriverType); next.setDriverType(myDriverType);

View File

@ -17,6 +17,11 @@
Automatic ID generation for contained resources (in cases where the user hasn't manually specified an ID) Automatic ID generation for contained resources (in cases where the user hasn't manually specified an ID)
has been streamlined to generate more predictable IDs in some cases. has been streamlined to generate more predictable IDs in some cases.
</action> </action>
<action type="fix">
An issue in the HAPI FHIR CLI database mogrator command has been resolved, where
some database drivers did not automatically register and had to be manually added to
the classpath.
</action>
</release> </release>
<release version="3.5.0" date="2018-09-17"> <release version="3.5.0" date="2018-09-17">