Search in sources :

Example 1 with DatabaseDelegate

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 &mdash;
 * 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);
    }
}
Also used : ScriptException(javax.script.ScriptException) DatabaseDelegate(org.testcontainers.delegate.DatabaseDelegate) LinkedList(java.util.LinkedList) ScriptException(javax.script.ScriptException)

Example 2 with DatabaseDelegate

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);
    }
}
Also used : JdbcDatabaseContainerProvider(org.testcontainers.containers.JdbcDatabaseContainerProvider) Matcher(java.util.regex.Matcher) JdbcDatabaseContainer(org.testcontainers.containers.JdbcDatabaseContainer) DatabaseDelegate(org.testcontainers.delegate.DatabaseDelegate)

Aggregations

DatabaseDelegate (org.testcontainers.delegate.DatabaseDelegate)2 LinkedList (java.util.LinkedList)1 Matcher (java.util.regex.Matcher)1 ScriptException (javax.script.ScriptException)1 JdbcDatabaseContainer (org.testcontainers.containers.JdbcDatabaseContainer)1 JdbcDatabaseContainerProvider (org.testcontainers.containers.JdbcDatabaseContainerProvider)1