use of org.testcontainers.delegate.DatabaseDelegate in project testcontainers-java by testcontainers.
the class ScriptUtils method executeDatabaseScript.
/**
* Execute the given database script.
* <p>Statement separators and comments will be removed before executing
* individual statements within the supplied script.
* <p><b>Do not use this method to execute DDL if you expect rollback.</b>
* @param databaseDelegate database delegate for script execution
* @param scriptPath the resource (potentially associated with a specific encoding)
* to load the SQL script from
* @param script the raw script content
*@param continueOnError whether or not to continue without throwing an exception
* in the event of an error
* @param ignoreFailedDrops whether or not to continue in the event of specifically
* an error on a {@code DROP} statement
* @param commentPrefix the prefix that identifies comments in the SQL script —
* typically "--"
* @param separator the script statement separator; defaults to
* {@value #DEFAULT_STATEMENT_SEPARATOR} if not specified and falls back to
* {@value #FALLBACK_STATEMENT_SEPARATOR} as a last resort
* @param blockCommentStartDelimiter the <em>start</em> block comment delimiter; never
* {@code null} or empty
* @param blockCommentEndDelimiter the <em>end</em> block comment delimiter; never
* {@code null} or empty @throws ScriptException if an error occurred while executing the SQL script
*/
public static void executeDatabaseScript(DatabaseDelegate databaseDelegate, String scriptPath, String script, boolean continueOnError, boolean ignoreFailedDrops, String commentPrefix, String separator, String blockCommentStartDelimiter, String blockCommentEndDelimiter) throws ScriptException {
try {
if (LOGGER.isInfoEnabled()) {
LOGGER.info("Executing database script from " + scriptPath);
}
long startTime = System.currentTimeMillis();
List<String> statements = new LinkedList<>();
if (separator == null) {
separator = DEFAULT_STATEMENT_SEPARATOR;
}
if (!containsSqlScriptDelimiters(script, separator)) {
separator = FALLBACK_STATEMENT_SEPARATOR;
}
splitSqlScript(scriptPath, script, separator, commentPrefix, blockCommentStartDelimiter, blockCommentEndDelimiter, statements);
try (DatabaseDelegate closeableDelegate = databaseDelegate) {
closeableDelegate.execute(statements, scriptPath, continueOnError, ignoreFailedDrops);
}
long elapsedTime = System.currentTimeMillis() - startTime;
if (LOGGER.isInfoEnabled()) {
LOGGER.info("Executed database script from " + scriptPath + " in " + elapsedTime + " ms.");
}
} catch (Exception ex) {
if (ex instanceof ScriptException) {
throw (ScriptException) ex;
}
throw new UncategorizedScriptException("Failed to execute database script from resource [" + script + "]", ex);
}
}
use of org.testcontainers.delegate.DatabaseDelegate in project testcontainers-java by testcontainers.
the class ContainerDatabaseDriver method connect.
@Override
public synchronized Connection connect(String url, final Properties info) throws SQLException {
/*
The driver should return "null" if it realizes it is the wrong kind of driver to connect to the given URL.
*/
if (!acceptsURL(url)) {
return null;
}
synchronized (jdbcUrlContainerCache) {
String queryString = "";
/*
If we already have a running container for this exact connection string, we want to connect
to that rather than create a new container
*/
JdbcDatabaseContainer container = jdbcUrlContainerCache.get(url);
if (container == null) {
/*
Extract from the JDBC connection URL:
* The database type (e.g. mysql, postgresql, ...)
* The docker tag, if provided.
* The URL query string, if provided
*/
Matcher urlMatcher = URL_MATCHING_PATTERN.matcher(url);
if (!urlMatcher.matches()) {
throw new IllegalArgumentException("JDBC URL matches jdbc:tc: prefix but the database or tag name could not be identified");
}
String databaseType = urlMatcher.group(1);
String tag = urlMatcher.group(3);
if (tag == null) {
tag = "latest";
}
queryString = urlMatcher.group(4);
if (queryString == null) {
queryString = "";
}
Map<String, String> parameters = getContainerParameters(url);
/*
Find a matching container type using ServiceLoader.
*/
ServiceLoader<JdbcDatabaseContainerProvider> databaseContainers = ServiceLoader.load(JdbcDatabaseContainerProvider.class);
for (JdbcDatabaseContainerProvider candidateContainerType : databaseContainers) {
if (candidateContainerType.supports(databaseType)) {
container = candidateContainerType.newInstance(tag);
delegate = container.getJdbcDriverInstance();
}
}
if (container == null) {
throw new UnsupportedOperationException("Database name " + databaseType + " not supported");
}
/*
Cache the container before starting to prevent race conditions when a connection
pool is started up
*/
jdbcUrlContainerCache.put(url, container);
/*
Pass possible container-specific parameters
*/
container.setParameters(parameters);
/*
Start the container
*/
container.start();
}
/*
Create a connection using the delegated driver. The container must be ready to accept connections.
*/
Connection connection = container.createConnection(queryString);
/*
If this container has not been initialized, AND
an init script or function has been specified, use it
*/
if (!initializedContainers.contains(container.getContainerId())) {
DatabaseDelegate databaseDelegate = new JdbcDatabaseDelegate(container);
runInitScriptIfRequired(url, databaseDelegate);
runInitFunctionIfRequired(url, connection);
initializedContainers.add(container.getContainerId());
}
return wrapConnection(connection, container, url);
}
}
Aggregations