diff --git a/ebean-datasource-api/src/main/java/io/ebean/datasource/DataSourceConfig.java b/ebean-datasource-api/src/main/java/io/ebean/datasource/DataSourceConfig.java index 5008fcc..001106b 100644 --- a/ebean-datasource-api/src/main/java/io/ebean/datasource/DataSourceConfig.java +++ b/ebean-datasource-api/src/main/java/io/ebean/datasource/DataSourceConfig.java @@ -143,7 +143,9 @@ public DataSourceConfig copy() { copy.clientInfo = new Properties(); copy.clientInfo.putAll(clientInfo); } - copy.initSql = initSql; + if (initSql != null) { + copy.initSql = new ArrayList<>(initSql); + } copy.alert = alert; copy.listener = listener; copy.enforceCleanClose = enforceCleanClose; @@ -194,10 +196,23 @@ public DataSourceConfig setDefaults(DataSourceBuilder builder) { } if (customProperties == null) { var otherCustomProps = other.getCustomProperties(); - if (otherCustomProps != null) { + if (otherCustomProps != null && !otherCustomProps.isEmpty()) { customProperties = new LinkedHashMap<>(otherCustomProps); } } + if (clientInfo == null) { + var otherClientInfo = other.getClientInfo(); + if (otherClientInfo != null && !otherClientInfo.isEmpty()) { + clientInfo = new Properties(); + clientInfo.putAll(otherClientInfo); + } + } + if (initSql == null) { + var otherInitSql = other.getInitSql(); + if (otherInitSql != null && !otherInitSql.isEmpty()) { + initSql = new ArrayList<>(otherInitSql); + } + } return this; } @@ -809,49 +824,58 @@ private void loadSettings(ConfigPropertiesHelper properties) { String isoLevel = properties.get("isolationLevel", _isolationLevel(isolationLevel)); this.isolationLevel = _isolationLevel(isoLevel); - this.initSql = parseSql(properties.get("initSql", null)); + String sql = properties.get("initSql", null); + if (sql != null && !sql.isEmpty()) { + if (this.initSql == null) { + this.initSql = new ArrayList<>(); + } + parseSql(sql, this.initSql); + } this.failOnStart = properties.getBoolean("failOnStart", failOnStart); String customProperties = properties.get("customProperties", null); if (customProperties != null && !customProperties.isEmpty()) { - this.customProperties = parseCustom(customProperties); + if (this.customProperties == null) { + this.customProperties = new LinkedHashMap<>(); + } + parseCustom(customProperties, this.customProperties); } String infoProperties = properties.get("clientInfo", null); if (infoProperties != null && !infoProperties.isEmpty()) { - Map pairs = parseCustom(infoProperties); - if (!pairs.isEmpty()) { + if (this.clientInfo == null) { this.clientInfo = new Properties(); - for (Map.Entry entry : pairs.entrySet()) { - this.clientInfo.setProperty(entry.getKey(), entry.getValue()); - } } + parseCustom(infoProperties, this.clientInfo); } } - private List parseSql(String sql) { - List ret = new ArrayList<>(); + void parseSql(String sql, List target) { if (sql != null) { - String[] queries = sql.split(";"); + String splitter = ";"; + if (sql.toLowerCase().startsWith("delimiter $$")) { + sql = sql.substring("delimiter $$".length()); + splitter = "\\$\\$"; + } + String[] queries = sql.split(splitter); for (String query : queries) { query = query.trim(); if (!query.isEmpty()) { - ret.add(query); + target.add(query); } } } - return ret; } - Map parseCustom(String customProperties) { - Map propertyMap = new LinkedHashMap<>(); + @SuppressWarnings("unchecked") + // we use raw map type here, so that we can also accept Properties as target + void parseCustom(String customProperties, Map target) { String[] pairs = customProperties.split(";"); for (String pair : pairs) { String[] split = pair.split("="); if (split.length == 2) { - propertyMap.put(split[0], split[1]); + target.put(split[0], split[1]); } } - return propertyMap; } @Override diff --git a/ebean-datasource-api/src/test/java/io/ebean/datasource/DataSourceConfigTest.java b/ebean-datasource-api/src/test/java/io/ebean/datasource/DataSourceConfigTest.java index 3bb0a02..c36a2bd 100644 --- a/ebean-datasource-api/src/test/java/io/ebean/datasource/DataSourceConfigTest.java +++ b/ebean-datasource-api/src/test/java/io/ebean/datasource/DataSourceConfigTest.java @@ -3,7 +3,10 @@ import org.junit.jupiter.api.Test; import java.io.IOException; +import java.util.ArrayList; +import java.util.HashMap; import java.util.LinkedHashMap; +import java.util.List; import java.util.Map; import java.util.Properties; @@ -37,12 +40,50 @@ public void addProperty() { public void parseCustom() { DataSourceConfig config = new DataSourceConfig(); - Map map = config.parseCustom("a=1;b=2;c=3"); + Map map = new HashMap<>(); + config.parseCustom("a=1;b=2;c=3", map); assertThat(map).hasSize(3); assertThat(map.get("a")).isEqualTo("1"); assertThat(map.get("b")).isEqualTo("2"); assertThat(map.get("c")).isEqualTo("3"); + + config.parseCustom("a=4;b=5;d=6", map); + assertThat(map).hasSize(4); + assertThat(map.get("a")).isEqualTo("4"); + assertThat(map.get("b")).isEqualTo("5"); + assertThat(map.get("c")).isEqualTo("3"); + assertThat(map.get("d")).isEqualTo("6"); + } + + @Test + public void parseSql() { + + DataSourceConfig config = new DataSourceConfig(); + List list = new ArrayList<>(); + config.parseSql("SET NAMES utf8mb4;SET collation_connection = 'utf8mb4_bin';SET wait_timeout = 28800", list); + assertThat(list).containsExactly("SET NAMES utf8mb4", "SET collation_connection = 'utf8mb4_bin'", "SET wait_timeout = 28800"); + + config.parseSql("delimiter $$CREATE PROCEDURE test1\n" + + "BEGIN\n" + + "DECLARE xy INT DEFAULT FALSE;\n" + + "END$$CREATE PROCEDURE test2\n" + + "BEGIN\n" + + "DECLARE ab INT DEFAULT FALSE;\n" + + "END$$", list); + assertThat(list).containsExactly( + "SET NAMES utf8mb4", + "SET collation_connection = 'utf8mb4_bin'", + "SET wait_timeout = 28800", + "CREATE PROCEDURE test1\n" + + "BEGIN\n" + + "DECLARE xy INT DEFAULT FALSE;\n" + + "END", + "CREATE PROCEDURE test2\n" + + "BEGIN\n" + + "DECLARE ab INT DEFAULT FALSE;\n" + + "END"); + } @Test @@ -79,9 +120,9 @@ public void copy() { source.setSchema("sch"); source.catalog("cat"); - Map customSource = new LinkedHashMap<>(); - customSource.put("a","a"); - customSource.put("b","b"); + Map customSource = new LinkedHashMap<>(); + customSource.put("a", "a"); + customSource.put("b", "b"); source.setCustomProperties(customSource); @@ -95,8 +136,8 @@ public void copy() { assertEquals(42, copy.getMinConnections()); assertEquals(45, copy.getMaxConnections()); - customSource.put("a","modifiedA"); - customSource.put("c","newC"); + customSource.put("a", "modifiedA"); + customSource.put("c", "newC"); assertEquals("a", copy.getCustomProperties().get("a")); assertEquals("b", copy.getCustomProperties().get("b"));