Skip to content

Commit f326508

Browse files
committed
Merge customProperties/clientInfo/initSql when loading config from multiple places
When a config is loaded with loadSettings from different places, the behaviour of customProperties/clientInfo/initSql is not consistent setDefaults did not honor clientInfo / initSql at all. multiple loadSettings should merge customProps/clientInfo/initSql Old behaviour: - initSql is always overwritten - customProps are overwritten, if value is present in config (even if it was empty) - clientInfo is only overwrtitten when configured in properties New behaviour: - all of them are merged. So multiple loadSettings will append initSql or put all props to clientInfo/customProps btw: initSql also supports "delimiter $$"
1 parent 2f3083b commit f326508

File tree

2 files changed

+86
-23
lines changed

2 files changed

+86
-23
lines changed

ebean-datasource-api/src/main/java/io/ebean/datasource/DataSourceConfig.java

Lines changed: 39 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -194,10 +194,23 @@ public DataSourceConfig setDefaults(DataSourceBuilder builder) {
194194
}
195195
if (customProperties == null) {
196196
var otherCustomProps = other.getCustomProperties();
197-
if (otherCustomProps != null) {
197+
if (otherCustomProps != null && !otherCustomProps.isEmpty()) {
198198
customProperties = new LinkedHashMap<>(otherCustomProps);
199199
}
200200
}
201+
if (clientInfo == null) {
202+
var otherClientInfo = other.getClientInfo();
203+
if (otherClientInfo != null && !otherClientInfo.isEmpty()) {
204+
clientInfo = new Properties();
205+
clientInfo.putAll(otherClientInfo);
206+
}
207+
}
208+
if (initSql == null) {
209+
var otherInitSql = other.getInitSql();
210+
if (otherInitSql != null && !otherInitSql.isEmpty()) {
211+
initSql = new ArrayList<>(otherInitSql);
212+
}
213+
}
201214
return this;
202215
}
203216

@@ -809,49 +822,58 @@ private void loadSettings(ConfigPropertiesHelper properties) {
809822

810823
String isoLevel = properties.get("isolationLevel", _isolationLevel(isolationLevel));
811824
this.isolationLevel = _isolationLevel(isoLevel);
812-
this.initSql = parseSql(properties.get("initSql", null));
825+
String sql = properties.get("initSql", null);
826+
if (sql != null && !sql.isEmpty()) {
827+
if (this.initSql == null) {
828+
this.initSql = new ArrayList<>();
829+
}
830+
parseSql(sql, this.initSql);
831+
}
813832
this.failOnStart = properties.getBoolean("failOnStart", failOnStart);
814833

815834
String customProperties = properties.get("customProperties", null);
816835
if (customProperties != null && !customProperties.isEmpty()) {
817-
this.customProperties = parseCustom(customProperties);
836+
if (this.customProperties == null) {
837+
this.customProperties = new LinkedHashMap<>();
838+
}
839+
parseCustom(customProperties, this.customProperties);
818840
}
819841
String infoProperties = properties.get("clientInfo", null);
820842
if (infoProperties != null && !infoProperties.isEmpty()) {
821-
Map<String, String> pairs = parseCustom(infoProperties);
822-
if (!pairs.isEmpty()) {
843+
if (this.clientInfo == null) {
823844
this.clientInfo = new Properties();
824-
for (Map.Entry<String, String> entry : pairs.entrySet()) {
825-
this.clientInfo.setProperty(entry.getKey(), entry.getValue());
826-
}
827845
}
846+
parseCustom(infoProperties, this.clientInfo);
828847
}
829848
}
830849

831-
private List<String> parseSql(String sql) {
832-
List<String> ret = new ArrayList<>();
850+
void parseSql(String sql, List<String> target) {
833851
if (sql != null) {
834-
String[] queries = sql.split(";");
852+
String splitter = ";";
853+
if (sql.toLowerCase().startsWith("delimiter $$")) {
854+
sql = sql.substring("delimiter $$".length());
855+
splitter = "\\$\\$";
856+
}
857+
String[] queries = sql.split(splitter);
835858
for (String query : queries) {
836859
query = query.trim();
837860
if (!query.isEmpty()) {
838-
ret.add(query);
861+
target.add(query);
839862
}
840863
}
841864
}
842-
return ret;
843865
}
844866

845-
Map<String, String> parseCustom(String customProperties) {
846-
Map<String, String> propertyMap = new LinkedHashMap<>();
867+
@SuppressWarnings("unchecked")
868+
// we use raw map type here, so that we can also accept Properties as target
869+
void parseCustom(String customProperties, Map target) {
847870
String[] pairs = customProperties.split(";");
848871
for (String pair : pairs) {
849872
String[] split = pair.split("=");
850873
if (split.length == 2) {
851-
propertyMap.put(split[0], split[1]);
874+
target.put(split[0], split[1]);
852875
}
853876
}
854-
return propertyMap;
855877
}
856878

857879
@Override

ebean-datasource-api/src/test/java/io/ebean/datasource/DataSourceConfigTest.java

Lines changed: 47 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,10 @@
33
import org.junit.jupiter.api.Test;
44

55
import java.io.IOException;
6+
import java.util.ArrayList;
7+
import java.util.HashMap;
68
import java.util.LinkedHashMap;
9+
import java.util.List;
710
import java.util.Map;
811
import java.util.Properties;
912

@@ -37,12 +40,50 @@ public void addProperty() {
3740
public void parseCustom() {
3841

3942
DataSourceConfig config = new DataSourceConfig();
40-
Map<String, String> map = config.parseCustom("a=1;b=2;c=3");
43+
Map<String, String> map = new HashMap<>();
44+
config.parseCustom("a=1;b=2;c=3", map);
4145

4246
assertThat(map).hasSize(3);
4347
assertThat(map.get("a")).isEqualTo("1");
4448
assertThat(map.get("b")).isEqualTo("2");
4549
assertThat(map.get("c")).isEqualTo("3");
50+
51+
config.parseCustom("a=4;b=5;d=6", map);
52+
assertThat(map).hasSize(4);
53+
assertThat(map.get("a")).isEqualTo("4");
54+
assertThat(map.get("b")).isEqualTo("5");
55+
assertThat(map.get("c")).isEqualTo("3");
56+
assertThat(map.get("d")).isEqualTo("6");
57+
}
58+
59+
@Test
60+
public void parseSql() {
61+
62+
DataSourceConfig config = new DataSourceConfig();
63+
List<String> list = new ArrayList<>();
64+
config.parseSql("SET NAMES utf8mb4;SET collation_connection = 'utf8mb4_bin';SET wait_timeout = 28800", list);
65+
assertThat(list).containsExactly("SET NAMES utf8mb4", "SET collation_connection = 'utf8mb4_bin'", "SET wait_timeout = 28800");
66+
67+
config.parseSql("delimiter $$CREATE PROCEDURE test1\n" +
68+
"BEGIN\n" +
69+
"DECLARE xy INT DEFAULT FALSE;\n" +
70+
"END$$CREATE PROCEDURE test2\n" +
71+
"BEGIN\n" +
72+
"DECLARE ab INT DEFAULT FALSE;\n" +
73+
"END$$", list);
74+
assertThat(list).containsExactly(
75+
"SET NAMES utf8mb4",
76+
"SET collation_connection = 'utf8mb4_bin'",
77+
"SET wait_timeout = 28800",
78+
"CREATE PROCEDURE test1\n" +
79+
"BEGIN\n" +
80+
"DECLARE xy INT DEFAULT FALSE;\n" +
81+
"END",
82+
"CREATE PROCEDURE test2\n" +
83+
"BEGIN\n" +
84+
"DECLARE ab INT DEFAULT FALSE;\n" +
85+
"END");
86+
4687
}
4788

4889
@Test
@@ -79,9 +120,9 @@ public void copy() {
79120
source.setSchema("sch");
80121
source.catalog("cat");
81122

82-
Map<String,String> customSource = new LinkedHashMap<>();
83-
customSource.put("a","a");
84-
customSource.put("b","b");
123+
Map<String, String> customSource = new LinkedHashMap<>();
124+
customSource.put("a", "a");
125+
customSource.put("b", "b");
85126
source.setCustomProperties(customSource);
86127

87128

@@ -95,8 +136,8 @@ public void copy() {
95136
assertEquals(42, copy.getMinConnections());
96137
assertEquals(45, copy.getMaxConnections());
97138

98-
customSource.put("a","modifiedA");
99-
customSource.put("c","newC");
139+
customSource.put("a", "modifiedA");
140+
customSource.put("c", "newC");
100141

101142
assertEquals("a", copy.getCustomProperties().get("a"));
102143
assertEquals("b", copy.getCustomProperties().get("b"));

0 commit comments

Comments
 (0)