Skip to content

Commit f6eca7f

Browse files
authored
Merge branch 'master' into feature/close-async-2
2 parents 3f4bcaf + eea5673 commit f6eca7f

File tree

14 files changed

+179
-88
lines changed

14 files changed

+179
-88
lines changed

ebean-datasource-api/pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
<parent>
55
<artifactId>ebean-datasource-parent</artifactId>
66
<groupId>io.ebean</groupId>
7-
<version>9.5</version>
7+
<version>9.6</version>
88
</parent>
99

1010
<artifactId>ebean-datasource-api</artifactId>

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

Lines changed: 44 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -140,9 +140,12 @@ public DataSourceConfig copy() {
140140
copy.customProperties = new LinkedHashMap<>(customProperties);
141141
}
142142
if (clientInfo != null) {
143-
copy.clientInfo = new Properties(clientInfo);
143+
copy.clientInfo = new Properties();
144+
copy.clientInfo.putAll(clientInfo);
145+
}
146+
if (initSql != null) {
147+
copy.initSql = new ArrayList<>(initSql);
144148
}
145-
copy.initSql = initSql;
146149
copy.alert = alert;
147150
copy.listener = listener;
148151
copy.enforceCleanClose = enforceCleanClose;
@@ -193,10 +196,23 @@ public DataSourceConfig setDefaults(DataSourceBuilder builder) {
193196
}
194197
if (customProperties == null) {
195198
var otherCustomProps = other.getCustomProperties();
196-
if (otherCustomProps != null) {
199+
if (otherCustomProps != null && !otherCustomProps.isEmpty()) {
197200
customProperties = new LinkedHashMap<>(otherCustomProps);
198201
}
199202
}
203+
if (clientInfo == null) {
204+
var otherClientInfo = other.getClientInfo();
205+
if (otherClientInfo != null && !otherClientInfo.isEmpty()) {
206+
clientInfo = new Properties();
207+
clientInfo.putAll(otherClientInfo);
208+
}
209+
}
210+
if (initSql == null) {
211+
var otherInitSql = other.getInitSql();
212+
if (otherInitSql != null && !otherInitSql.isEmpty()) {
213+
initSql = new ArrayList<>(otherInitSql);
214+
}
215+
}
200216
return this;
201217
}
202218

@@ -808,49 +824,58 @@ private void loadSettings(ConfigPropertiesHelper properties) {
808824

809825
String isoLevel = properties.get("isolationLevel", _isolationLevel(isolationLevel));
810826
this.isolationLevel = _isolationLevel(isoLevel);
811-
this.initSql = parseSql(properties.get("initSql", null));
827+
String sql = properties.get("initSql", null);
828+
if (sql != null && !sql.isEmpty()) {
829+
if (this.initSql == null) {
830+
this.initSql = new ArrayList<>();
831+
}
832+
parseSql(sql, this.initSql);
833+
}
812834
this.failOnStart = properties.getBoolean("failOnStart", failOnStart);
813835

814836
String customProperties = properties.get("customProperties", null);
815837
if (customProperties != null && !customProperties.isEmpty()) {
816-
this.customProperties = parseCustom(customProperties);
838+
if (this.customProperties == null) {
839+
this.customProperties = new LinkedHashMap<>();
840+
}
841+
parseCustom(customProperties, this.customProperties);
817842
}
818843
String infoProperties = properties.get("clientInfo", null);
819844
if (infoProperties != null && !infoProperties.isEmpty()) {
820-
Map<String, String> pairs = parseCustom(infoProperties);
821-
if (!pairs.isEmpty()) {
845+
if (this.clientInfo == null) {
822846
this.clientInfo = new Properties();
823-
for (Map.Entry<String, String> entry : pairs.entrySet()) {
824-
this.clientInfo.setProperty(entry.getKey(), entry.getValue());
825-
}
826847
}
848+
parseCustom(infoProperties, this.clientInfo);
827849
}
828850
}
829851

830-
private List<String> parseSql(String sql) {
831-
List<String> ret = new ArrayList<>();
852+
void parseSql(String sql, List<String> target) {
832853
if (sql != null) {
833-
String[] queries = sql.split(";");
854+
String splitter = ";";
855+
if (sql.toLowerCase().startsWith("delimiter $$")) {
856+
sql = sql.substring("delimiter $$".length());
857+
splitter = "\\$\\$";
858+
}
859+
String[] queries = sql.split(splitter);
834860
for (String query : queries) {
835861
query = query.trim();
836862
if (!query.isEmpty()) {
837-
ret.add(query);
863+
target.add(query);
838864
}
839865
}
840866
}
841-
return ret;
842867
}
843868

844-
Map<String, String> parseCustom(String customProperties) {
845-
Map<String, String> propertyMap = new LinkedHashMap<>();
869+
@SuppressWarnings("unchecked")
870+
// we use raw map type here, so that we can also accept Properties as target
871+
void parseCustom(String customProperties, Map target) {
846872
String[] pairs = customProperties.split(";");
847873
for (String pair : pairs) {
848874
String[] split = pair.split("=");
849875
if (split.length == 2) {
850-
propertyMap.put(split[0], split[1]);
876+
target.put(split[0], split[1]);
851877
}
852878
}
853-
return propertyMap;
854879
}
855880

856881
@Override

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,9 @@ static DataSourceBuilder builder() {
8484
/**
8585
* Shutdown the pool.
8686
* <p>
87+
* This will close all the free connections, and then go into a wait loop,
88+
* waiting for the busy connections to be freed.
89+
* <p>
8790
* This is functionally the same as {@link #offline()} but generally we expect to only
8891
* shut down the pool once whereas we can expect to make many calls to offline() and
8992
* online().

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

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,12 +31,14 @@ public interface PoolStatus {
3131
int waiting();
3232

3333
/**
34-
* Return the busy connection high water mark.
34+
* Return the busy connection highwater mark.
3535
*/
3636
int highWaterMark();
3737

3838
/**
3939
* Return the number of times threads had to wait for connections.
40+
* <p>
41+
* This occurs when the pool is full and threads are waiting for a connection.
4042
*/
4143
int waitCount();
4244

@@ -45,6 +47,18 @@ public interface PoolStatus {
4547
*/
4648
int hitCount();
4749

50+
/**
51+
* Return the total time acquiring a connection from the pool.
52+
*/
53+
long totalAcquireMicros();
54+
55+
/**
56+
* Return the total time waiting in micros for a free connection when the pool has hit maxConnections.
57+
* <p>
58+
* When the pool is full and threads are waiting for a connection, this is the total time spent waiting.
59+
*/
60+
long totalWaitMicros();
61+
4862
/**
4963
* Return the max acquire time in micros.
5064
*/

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

Lines changed: 66 additions & 8 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"));
@@ -121,13 +162,30 @@ public void defaults() {
121162
}
122163

123164
@Test
124-
public void defaults_someOverride() {
165+
void setDefaults_expect_connectionsDefault() {
166+
DataSourceConfig readOnly = new DataSourceConfig();
167+
readOnly.setDefaults(create());
168+
assertThat(readOnly.getMinConnections()).isEqualTo(1);
169+
assertThat(readOnly.getMaxConnections()).isEqualTo(20);
170+
}
125171

172+
@Test
173+
void setDefaults_when_explicit() {
174+
DataSourceConfig readOnly = new DataSourceConfig();
175+
readOnly.setMinConnections(21);
176+
readOnly.setMaxConnections(22);
177+
readOnly.setDefaults(create());
178+
assertThat(readOnly.getMinConnections()).isEqualTo(21);
179+
assertThat(readOnly.getMaxConnections()).isEqualTo(22);
180+
}
181+
182+
@Test
183+
public void defaults_someOverride() {
126184
DataSourceConfig readOnly = new DataSourceConfig();
127-
readOnly.setMinConnections(3);
128185
readOnly.setUsername("foo2");
129186
readOnly.setUrl("jdbc:postgresql://127.0.0.2:5432/unit");
130187
readOnly.validateOnHeartbeat(false);
188+
readOnly.setMinConnections(3);
131189

132190
DataSourceBuilder configBuilder = create();
133191
DataSourceConfig readOnly2 = readOnly.setDefaults(configBuilder);

ebean-datasource/pom.xml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
<parent>
55
<groupId>io.ebean</groupId>
66
<artifactId>ebean-datasource-parent</artifactId>
7-
<version>9.5</version>
7+
<version>9.6</version>
88
</parent>
99

1010
<artifactId>ebean-datasource</artifactId>
@@ -16,7 +16,7 @@
1616
<dependency>
1717
<groupId>io.ebean</groupId>
1818
<artifactId>ebean-datasource-api</artifactId>
19-
<version>9.5</version>
19+
<version>9.6</version>
2020
</dependency>
2121

2222
<dependency>
@@ -29,7 +29,7 @@
2929
<dependency>
3030
<groupId>io.ebean</groupId>
3131
<artifactId>ebean-test-containers</artifactId>
32-
<version>7.6</version>
32+
<version>7.8</version>
3333
<scope>test</scope>
3434
</dependency>
3535

ebean-datasource/src/main/java/io/ebean/datasource/pool/BusyConnectionBuffer.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ private void closeBusyConnection(PooledConnection pc) {
119119
*/
120120
String busyConnectionInformation(boolean toLogger) {
121121
if (toLogger) {
122-
Log.info("Dumping [{0}] busy connections: (Use datasource.xxx.capturestacktrace=true ... to get stackTraces)", size());
122+
Log.info("Dumping [{0}] busy connections: (Use datasource.xxx.captureStackTrace=true ... to get stackTraces)", size());
123123
}
124124
StringBuilder sb = new StringBuilder();
125125
for (PooledConnection pc : slots) {

0 commit comments

Comments
 (0)