<commit_before>package foundation.stack.jdbc;

import com.google.common.base.Strings;
import foundation.stack.docker.bootstrap.Bootstrap;
import foundation.stack.docker.management.ContainerSpecification;
import foundation.stack.docker.management.DockerClient;
import foundation.stack.docker.management.SpecificationBuilder;

import java.io.IOException;
import java.net.ServerSocket;
import java.sql.SQLException;
import java.util.concurrent.ExecutionException;
import java.util.logging.Level;
import java.util.logging.Logger;

import static foundation.stack.jdbc.DockerDatabaseServerContainerReferenceManager.ROOT_PASSWORD_PROPERTY;

/**
 * @author <NAME> (<EMAIL>)
 */
public class DockerDatabaseServerPerApplicationConnectionLookup implements ConnectionLookup {

    private static Logger logger = Logger.getLogger(DockerDatabaseServerPerApplicationConnectionLookup.class.getName());

    private static final String BRANCH_DATABASE_NAME = "branch";

    private static final String MYSQL_IMAGE_NAME_PROPERTY = "MYSQL_IMAGE_NAME";
    private static final String MYSQL_IMAGE_NAME = "mysql";

    private static final String MYSQL_IMAGE_TAG_PROPERTY = "MYSQL_IMAGE_TAG";
    private static final String MYSQL_VERSION = "5.7";

    private static final int MYSQL_PORT = 3306;

    private static final String DOCKER_HOST_NAME = "stackfoundation";
    private static final String BYPASS_INSTALLATION = "BYPASS_INSTALLATION";

    private static final String MYSQL_ROOT_PASSWORD = "<PASSWORD>";

    private DockerClient dockerClient;
    private DockerDatabaseServerContainerReferenceManager containerManager;

    private final MySqlDatabaseManager databaseManager = new MySqlDatabaseManager();

    private final Bootstrap bootstrap = new Bootstrap();

    private DockerClient getDockerClient() {
        if (dockerClient == null) {
            try {
                dockerClient = bootstrap.bootstrap(System.getenv().containsKey(BYPASS_INSTALLATION), null)
                        .connect(DOCKER_HOST_NAME);
            } catch (Exception e) {
                logger.log(Level.FINE, "Error building docker client", e);
                throw new RuntimeException(e);
            }
        }
        return dockerClient;
    }

    private DockerDatabaseServerContainerReferenceManager getContainerReferenceManager() {
        if (this.containerManager == null) {
            this.containerManager = new DockerDatabaseServerContainerReferenceManager(getDockerClient());
        }

        return containerManager;
    }

    private String appendDatabaseName(String connectionString, String databaseName) {
        int querySeparator = connectionString.indexOf('?');
        if (querySeparator > 0) {
            return connectionString.substring(0, querySeparator) + '/' + databaseName + connectionString.substring(querySeparator);
        }

        return connectionString + '/' + databaseName;
    }

    @Override
    public String getDefaultPassword() {
        return null;
    }

    @Override
    public String getDefaultUsername() {
        return null;
    }

    @Override
    public String find(String query) {
        String applicationName = NameGenerator.generateContextApplicationName();
        try {
            String imageName = System.getProperty(MYSQL_IMAGE_NAME_PROPERTY, MYSQL_IMAGE_NAME);
            String versionTag = System.getProperty(MYSQL_IMAGE_TAG_PROPERTY, MYSQL_VERSION);

            ContainerSpecification containerSpecification = new ContainerSpecification(imageName, versionTag);
            containerSpecification.addPortMapping(MYSQL_PORT, getAvailablePort());
            addRootPasswordEnvironmentVariable(containerSpecification, applicationName);

            String containerConnectionString = getContainerReferenceManager()
                    .getOrCreateContainer(applicationName,
                            SpecificationBuilder.just(containerSpecification));

            if (BRANCH_DATABASE_NAME.equals(query)) {
                String databaseName = databaseManager.getOrCreateBranchDatabase(containerConnectionString,
                        NameGenerator.generateDatabaseName());
                return appendDatabaseName(containerConnectionString, databaseName);
            } else {
                String databaseName = databaseManager.getOrCreateNamedDatabase(containerConnectionString,
                        NameGenerator.generateDatabaseName());
                return appendDatabaseName(containerConnectionString, databaseName);
            }
        } catch (ExecutionException | SQLException e) {
            logger.log(Level.FINE, "Error getting/creating database for application {0}", applicationName);
            throw new RuntimeException(e);
        }
    }

    private void addRootPasswordEnvironmentVariable(ContainerSpecification containerSpecification, String applicationName) {
        String rootPassword = System.getProperty(ROOT_PASSWORD_PROPERTY);
        if (Strings.isNullOrEmpty(rootPassword)) {
            rootPassword = <PASSWORD>Name;
        }
        containerSpecification.addEnvironmentVariable(MYSQL_ROOT_PASSWORD, rootPassword);
        System.setProperty(ROOT_PASSWORD_PROPERTY, rootPassword);
    }

    private Integer getAvailablePort() {
        try (ServerSocket socket = new ServerSocket(0)) {<commit_msg>Allow named databases to be created with the provided name.<commit_after>package foundation.stack.jdbc;

import com.google.common.base.Strings;
import foundation.stack.docker.bootstrap.Bootstrap;
import foundation.stack.docker.management.ContainerSpecification;
import foundation.stack.docker.management.DockerClient;
import foundation.stack.docker.management.SpecificationBuilder;

import java.io.IOException;
import java.net.ServerSocket;
import java.sql.SQLException;
import java.util.concurrent.ExecutionException;
import java.util.logging.Level;
import java.util.logging.Logger;

import static foundation.stack.jdbc.DockerDatabaseServerContainerReferenceManager.ROOT_PASSWORD_PROPERTY;

/**
 * @author <NAME> (<EMAIL>)
 */
public class DockerDatabaseServerPerApplicationConnectionLookup implements ConnectionLookup {

    private static Logger logger = Logger.getLogger(DockerDatabaseServerPerApplicationConnectionLookup.class.getName());

    private static final String BRANCH_DATABASE_NAME = "branch";

    private static final String MYSQL_IMAGE_NAME_PROPERTY = "MYSQL_IMAGE_NAME";
    private static final String MYSQL_IMAGE_NAME = "mysql";

    private static final String MYSQL_IMAGE_TAG_PROPERTY = "MYSQL_IMAGE_TAG";
    private static final String MYSQL_VERSION = "5.7";

    private static final int MYSQL_PORT = 3306;

    private static final String DOCKER_HOST_NAME = "stackfoundation";
    private static final String BYPASS_INSTALLATION = "BYPASS_INSTALLATION";

    private static final String MYSQL_ROOT_PASSWORD = "<PASSWORD>";

    private DockerClient dockerClient;
    private DockerDatabaseServerContainerReferenceManager containerManager;

    private final MySqlDatabaseManager databaseManager = new MySqlDatabaseManager();

    private final Bootstrap bootstrap = new Bootstrap();

    private DockerClient getDockerClient() {
        if (dockerClient == null) {
            try {
                dockerClient = bootstrap.bootstrap(System.getenv().containsKey(BYPASS_INSTALLATION), null)
                        .connect(DOCKER_HOST_NAME);
            } catch (Exception e) {
                logger.log(Level.FINE, "Error building docker client", e);
                throw new RuntimeException(e);
            }
        }
        return dockerClient;
    }

    private DockerDatabaseServerContainerReferenceManager getContainerReferenceManager() {
        if (this.containerManager == null) {
            this.containerManager = new DockerDatabaseServerContainerReferenceManager(getDockerClient());
        }

        return containerManager;
    }

    private String appendDatabaseName(String connectionString, String databaseName) {
        int querySeparator = connectionString.indexOf('?');
        if (querySeparator > 0) {
            return connectionString.substring(0, querySeparator) + '/' + databaseName + connectionString.substring(querySeparator);
        }

        return connectionString + '/' + databaseName;
    }

    @Override
    public String getDefaultPassword() {
        return null;
    }

    @Override
    public String getDefaultUsername() {
        return null;
    }

    @Override
    public String find(String query) {
        String applicationName = NameGenerator.generateContextApplicationName();
        try {
            String imageName = System.getProperty(MYSQL_IMAGE_NAME_PROPERTY, MYSQL_IMAGE_NAME);
            String versionTag = System.getProperty(MYSQL_IMAGE_TAG_PROPERTY, MYSQL_VERSION);

            ContainerSpecification containerSpecification = new ContainerSpecification(imageName, versionTag);
            containerSpecification.addPortMapping(MYSQL_PORT, getAvailablePort());
            addRootPasswordEnvironmentVariable(containerSpecification, applicationName);

            String containerConnectionString = getContainerReferenceManager()
                    .getOrCreateContainer(applicationName,
                            SpecificationBuilder.just(containerSpecification));

            if (BRANCH_DATABASE_NAME.equals(query)) {
                String databaseName = databaseManager.getOrCreateBranchDatabase(containerConnectionString,
                        NameGenerator.generateDatabaseName());
                return appendDatabaseName(containerConnectionString, databaseName);
            } else {
                String databaseName = databaseManager.getOrCreateNamedDatabase(containerConnectionString, query);
                return appendDatabaseName(containerConnectionString, databaseName);
            }
        } catch (ExecutionException | SQLException e) {
            logger.log(Level.FINE, "Error getting/creating database for application {0}", applicationName);
            throw new RuntimeException(e);
        }
    }

    private void addRootPasswordEnvironmentVariable(ContainerSpecification containerSpecification, String applicationName) {
        String rootPassword = System.getProperty(ROOT_PASSWORD_PROPERTY);
        if (Strings.isNullOrEmpty(rootPassword)) {
            rootPassword = <PASSWORD>;
        }
        containerSpecification.addEnvironmentVariable(MYSQL_ROOT_PASSWORD, rootPassword);
        System.setProperty(ROOT_PASSWORD_PROPERTY, <PASSWORD>Password);
    }

    private Integer getAvailablePort() {
        try (ServerSocket socket = new ServerSocket(0)) {
{'fraction_non_alphanumeric': 0.07275468853076995, 'fraction_numerical': 0.0018848364904344547, 'mean_word_length': 3.485207100591716, 'pattern_counts': {'":': 0, '<': 12, '<?xml version=': 0, '>': 14, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '144948', 'n_tokens_mistral': 2544, 'n_tokens_neox': 2475, 'n_words': 545}