All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.soffa.commons.data.DataSourceProperties Maven / Gradle / Ivy

package io.soffa.commons.data;

import io.soffa.commons.exceptions.TechnicalException;
import io.soffa.commons.lang.TextUtil;
import lombok.Builder;
import lombok.Data;
import lombok.SneakyThrows;
import org.jdbi.v3.core.Jdbi;
import org.springframework.util.MultiValueMap;
import org.springframework.web.util.UriComponentsBuilder;

import java.net.URL;
import java.net.URLDecoder;
import java.nio.charset.StandardCharsets;

@Data
@Builder
public class DataSourceProperties {

    private String name;
    private String url;
    private String username;
    private String password;
    private String driverClassName;
    private String schema;

    public static final String H2 = "h2";
    public static final String PG = "postgresql";

    public boolean hasSchema() {
        return TextUtil.isNotEmpty(schema);
    }

    @SneakyThrows
    public static DataSourceProperties create(final String name, final String datasourceUrl) {

        String databaseUrl = datasourceUrl.trim();
        String provider;

        if (databaseUrl.startsWith("h2://")) {
            provider = H2;
        } else if (databaseUrl.matches("^(pg|postgres(ql)?)://.*")) {
            provider = PG;
        } else {
            throw new TechnicalException("Database protocol not implemented yet: " + databaseUrl);
        }

        URL url = new URL(databaseUrl.replaceAll("^([^:]+)://(.*)$", "http://$2"));
        String userInfos = url.getUserInfo();
        String username = "";
        String password = null;
        String jdbcUrl;
        String jdbcDriver;
        String hostname = url.getHost();
        String path = url.getPath().replaceAll("^/", "");

        MultiValueMap parameters = UriComponentsBuilder.fromUriString(url.toString()).build().getQueryParams();
        String schema = TextUtil.trimToEmpty(parameters.getFirst("schema"));

        if (userInfos != null) {
            if (userInfos.contains(":")) {
                String[] userAndPassword = userInfos.trim().split(":");
                password = URLDecoder.decode(userAndPassword[1], StandardCharsets.UTF_8.toString());
                username = URLDecoder.decode(userAndPassword[0], StandardCharsets.UTF_8.toString());
            } else {
                username = userInfos.trim();
            }
        }

        if (H2.equals(provider)) {
            jdbcDriver = H2_DRIVER;
            jdbcUrl = String.format("jdbc:h2:%1$s:%2$s;MODE=PostgreSQL;DB_CLOSE_ON_EXIT=FALSE", hostname, path);
            if (TextUtil.isNotEmpty(schema)) {
                schema = schema.toUpperCase();
                createSchema(jdbcUrl, username, password, schema);
                jdbcUrl += String.format(";INIT=CREATE SCHEMA IF NOT EXISTS %1$s", schema);
            }
        } else {
            jdbcDriver = "org.postgresql.Driver";
            if (url.getPort() == -1) {
                hostname += ":5432";
            } else {
                hostname += ":" + url.getPort();
            }
            jdbcUrl = String.format("jdbc:postgresql://%1$s/%2$s", hostname, path);
            if (TextUtil.isNotEmpty(schema)) {
                schema = schema.toLowerCase();
                createSchema(jdbcUrl, username, password, schema);
                jdbcUrl += "?currentSchema=" + schema;
            }
        }
        return DataSourceProperties.builder()
            .name(name)
            .username(username)
            .password(password)
            .schema(schema)
            .url(jdbcUrl)
            .driverClassName(jdbcDriver)
            .build();
    }

    private static void createSchema(String jdbcUrl, String username, String password, String schema) {
        // Automatic schema creation if possible
        Jdbi jdbi = Jdbi.create(jdbcUrl, username, password);
        jdbi.inTransaction(handle -> {
            handle.execute("CREATE SCHEMA IF NOT EXISTS " + schema);
            return null;
        });
    }

    public static final String H2_DRIVER = "org.h2.Driver";
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy