Skip to content

Commit 341c796

Browse files
committed
#42 - Add dialect resolution for r2dbc-mariadb driver.
We now use the MySQL dialect when using the R2DBC MariaDB driver.
1 parent 7ed68ee commit 341c796

File tree

6 files changed

+544
-1
lines changed

6 files changed

+544
-1
lines changed

Diff for: pom.xml

+31-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
2-
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
2+
<project xmlns="http://maven.apache.org/POM/4.0.0"
3+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
35

46
<modelVersion>4.0.0</modelVersion>
57

@@ -31,8 +33,10 @@
3133
<postgresql.version>42.2.5</postgresql.version>
3234
<mysql.version>5.1.47</mysql.version>
3335
<jasync.version>1.0.14</jasync.version>
36+
<r2dbc-mariadb.version>0.8.1-alpha1</r2dbc-mariadb.version>
3437
<r2dbc-spi-test.version>0.8.0.RELEASE</r2dbc-spi-test.version>
3538
<mssql-jdbc.version>7.1.2.jre8-preview</mssql-jdbc.version>
39+
<mariadb-jdbc.version>2.5.4</mariadb-jdbc.version>
3640
<r2dbc-releasetrain.version>Arabba-SR2</r2dbc-releasetrain.version>
3741
<reactive-streams.version>1.0.3</reactive-streams.version>
3842
<netty>4.1.43.Final</netty>
@@ -195,6 +199,13 @@
195199
<scope>test</scope>
196200
</dependency>
197201

202+
<dependency>
203+
<groupId>org.mariadb.jdbc</groupId>
204+
<artifactId>mariadb-java-client</artifactId>
205+
<version>${mariadb-jdbc.version}</version>
206+
<scope>test</scope>
207+
</dependency>
208+
198209
<dependency>
199210
<groupId>com.microsoft.sqlserver</groupId>
200211
<artifactId>mssql-jdbc</artifactId>
@@ -235,6 +246,13 @@
235246
<scope>test</scope>
236247
</dependency>
237248

249+
<dependency>
250+
<groupId>org.mariadb</groupId>
251+
<artifactId>r2dbc-mariadb</artifactId>
252+
<version>${r2dbc-mariadb.version}</version>
253+
<scope>test</scope>
254+
</dependency>
255+
238256
<dependency>
239257
<groupId>io.r2dbc</groupId>
240258
<artifactId>r2dbc-spi-test</artifactId>
@@ -256,6 +274,18 @@
256274
</exclusions>
257275
</dependency>
258276

277+
<dependency>
278+
<groupId>org.testcontainers</groupId>
279+
<artifactId>mariadb</artifactId>
280+
<scope>test</scope>
281+
<exclusions>
282+
<exclusion>
283+
<groupId>org.slf4j</groupId>
284+
<artifactId>jcl-over-slf4j</artifactId>
285+
</exclusion>
286+
</exclusions>
287+
</dependency>
288+
259289
<dependency>
260290
<groupId>org.testcontainers</groupId>
261291
<artifactId>postgresql</artifactId>

Diff for: src/main/java/org/springframework/data/r2dbc/dialect/DialectResolver.java

+1
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,7 @@ static class BuiltInDialectProvider implements R2dbcDialectProvider {
114114
BUILTIN.put("H2", H2Dialect.INSTANCE);
115115
BUILTIN.put("Microsoft SQL Server", SqlServerDialect.INSTANCE);
116116
BUILTIN.put("MySQL", MySqlDialect.INSTANCE);
117+
BUILTIN.put("MariaDB", MySqlDialect.INSTANCE);
117118
BUILTIN.put("PostgreSQL", PostgresDialect.INSTANCE);
118119
}
119120

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,185 @@
1+
/*
2+
* Copyright 2019-2020 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package org.springframework.data.r2dbc.core;
17+
18+
import static org.assertj.core.api.Assertions.*;
19+
20+
import io.r2dbc.spi.ConnectionFactory;
21+
import lombok.Data;
22+
import reactor.test.StepVerifier;
23+
24+
import java.util.Arrays;
25+
import java.util.Collections;
26+
import java.util.UUID;
27+
28+
import javax.sql.DataSource;
29+
30+
import org.junit.ClassRule;
31+
import org.junit.Test;
32+
33+
import org.springframework.core.convert.converter.Converter;
34+
import org.springframework.dao.DataAccessException;
35+
import org.springframework.data.annotation.Id;
36+
import org.springframework.data.convert.ReadingConverter;
37+
import org.springframework.data.convert.WritingConverter;
38+
import org.springframework.data.r2dbc.dialect.MySqlDialect;
39+
import org.springframework.data.r2dbc.query.Criteria;
40+
import org.springframework.data.r2dbc.testing.ExternalDatabase;
41+
import org.springframework.data.r2dbc.testing.MariaDbTestSupport;
42+
import org.springframework.data.relational.core.mapping.Table;
43+
import org.springframework.jdbc.core.JdbcTemplate;
44+
45+
/**
46+
* Integration tests for {@link DatabaseClient} against MariaDB.
47+
*
48+
* @author Mark Paluch
49+
*/
50+
public class MariaDbDatabaseClientIntegrationTests extends AbstractDatabaseClientIntegrationTests {
51+
52+
@ClassRule public static final ExternalDatabase database = MariaDbTestSupport.database();
53+
54+
@Override
55+
protected DataSource createDataSource() {
56+
return MariaDbTestSupport.createDataSource(database);
57+
}
58+
59+
@Override
60+
protected ConnectionFactory createConnectionFactory() {
61+
return MariaDbTestSupport.createConnectionFactory(database);
62+
}
63+
64+
@Override
65+
protected String getCreateTableStatement() {
66+
return MariaDbTestSupport.CREATE_TABLE_LEGOSET;
67+
}
68+
69+
@Test // gh-166
70+
public void considersBuiltInConverters() {
71+
72+
ConnectionFactory connectionFactory = createConnectionFactory();
73+
JdbcTemplate jdbc = createJdbcTemplate(createDataSource());
74+
75+
try {
76+
jdbc.execute("DROP TABLE boolean_mapping");
77+
} catch (DataAccessException e) {}
78+
jdbc.execute("CREATE TABLE boolean_mapping (id int, flag1 TINYINT, flag2 TINYINT)");
79+
80+
BooleanMapping mapping = new BooleanMapping();
81+
mapping.setId(42);
82+
mapping.setFlag1(true);
83+
84+
DatabaseClient databaseClient = DatabaseClient.create(connectionFactory);
85+
86+
databaseClient.insert().into(BooleanMapping.class).using(mapping).then() //
87+
.as(StepVerifier::create) //
88+
.verifyComplete();
89+
90+
databaseClient.select().from(BooleanMapping.class).fetch().first() //
91+
.as(StepVerifier::create) //
92+
.consumeNextWith(actual -> assertThat(actual.isFlag1()).isTrue()) //
93+
.verifyComplete();
94+
}
95+
96+
@Test // gh-305
97+
public void shouldApplyCustomConverters() {
98+
99+
ConnectionFactory connectionFactory = createConnectionFactory();
100+
JdbcTemplate jdbc = createJdbcTemplate(createDataSource());
101+
ReactiveDataAccessStrategy strategy = new DefaultReactiveDataAccessStrategy(MySqlDialect.INSTANCE,
102+
Arrays.asList(UuidToStringConverter.INSTANCE, StringToUuidConverter.INSTANCE));
103+
104+
try {
105+
jdbc.execute("DROP TABLE uuid_type");
106+
} catch (DataAccessException e) {}
107+
jdbc.execute("CREATE TABLE uuid_type (id varchar(255), uuid_value varchar(255))");
108+
109+
UuidType uuidType = new UuidType();
110+
uuidType.setId(UUID.randomUUID());
111+
uuidType.setUuidValue(UUID.randomUUID());
112+
113+
DatabaseClient databaseClient = DatabaseClient.builder().connectionFactory(connectionFactory)
114+
.dataAccessStrategy(strategy).build();
115+
116+
databaseClient.insert().into(UuidType.class).using(uuidType).then() //
117+
.as(StepVerifier::create) //
118+
.verifyComplete();
119+
120+
databaseClient.select().from(UuidType.class).matching(Criteria.where("id").is(uuidType.getId())) //
121+
.fetch().first() //
122+
.as(StepVerifier::create) //
123+
.consumeNextWith(actual -> assertThat(actual.getUuidValue()).isEqualTo(uuidType.getUuidValue())) //
124+
.verifyComplete();
125+
126+
uuidType.setUuidValue(null);
127+
databaseClient.update().table(UuidType.class).using(uuidType).then() //
128+
.as(StepVerifier::create) //
129+
.verifyComplete();
130+
131+
databaseClient.execute("SELECT * FROM uuid_type WHERE id = ?") //
132+
.bind(0, uuidType.getId()) //
133+
.as(UuidType.class) //
134+
.fetch().first() //
135+
.as(StepVerifier::create) //
136+
.consumeNextWith(actual -> assertThat(actual.getUuidValue()).isNull()) //
137+
.verifyComplete();
138+
139+
databaseClient.execute("SELECT * FROM uuid_type WHERE id in (:ids)") //
140+
.bind("ids", Collections.singleton(uuidType.getId())) //
141+
.as(UuidType.class) //
142+
.fetch().first() //
143+
.as(StepVerifier::create) //
144+
.consumeNextWith(actual -> assertThat(actual.getUuidValue()).isNull()) //
145+
.verifyComplete();
146+
}
147+
148+
@Table("boolean_mapping")
149+
@Data
150+
static class BooleanMapping {
151+
152+
int id;
153+
boolean flag1;
154+
boolean flag2;
155+
}
156+
157+
@Table("uuid_type")
158+
@Data
159+
static class UuidType {
160+
161+
@Id UUID id;
162+
UUID uuidValue;
163+
}
164+
165+
@WritingConverter
166+
enum UuidToStringConverter implements Converter<UUID, String> {
167+
INSTANCE;
168+
169+
@Override
170+
public String convert(UUID uuid) {
171+
return uuid.toString();
172+
}
173+
}
174+
175+
@ReadingConverter
176+
enum StringToUuidConverter implements Converter<String, UUID> {
177+
INSTANCE;
178+
179+
@Override
180+
public UUID convert(String value) {
181+
return UUID.fromString(value);
182+
}
183+
}
184+
185+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
/*
2+
* Copyright 2019-2020 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package org.springframework.data.r2dbc.core;
17+
18+
import io.r2dbc.spi.ConnectionFactory;
19+
import reactor.core.publisher.Mono;
20+
21+
import java.time.Duration;
22+
23+
import javax.sql.DataSource;
24+
25+
import org.junit.ClassRule;
26+
27+
import org.springframework.data.r2dbc.testing.ExternalDatabase;
28+
import org.springframework.data.r2dbc.testing.MariaDbTestSupport;
29+
30+
/**
31+
* Transactional integration tests for {@link DatabaseClient} against MariaDb.
32+
*
33+
* @author Mark Paluch
34+
*/
35+
public class MariaDbTransactionalDatabaseClientIntegrationTests
36+
extends AbstractTransactionalDatabaseClientIntegrationTests {
37+
38+
@ClassRule public static final ExternalDatabase database = MariaDbTestSupport.database();
39+
40+
@Override
41+
protected DataSource createDataSource() {
42+
return MariaDbTestSupport.createDataSource(database);
43+
}
44+
45+
@Override
46+
protected ConnectionFactory createConnectionFactory() {
47+
return MariaDbTestSupport.createConnectionFactory(database);
48+
}
49+
50+
@Override
51+
protected String getCreateTableStatement() {
52+
return MariaDbTestSupport.CREATE_TABLE_LEGOSET;
53+
}
54+
55+
@Override
56+
protected Mono<Void> prepareForTransaction(DatabaseClient client) {
57+
58+
/*
59+
* We have to execute a sql statement first.
60+
* Otherwise Mariadb don't have a transaction id.
61+
* And we need to delay emitting the result so that Mariadb has time to write the transaction id, which is done in
62+
* batches every now and then.
63+
*/
64+
return client.execute(getInsertIntoLegosetStatement()) //
65+
.bind(0, 42055) //
66+
.bind(1, "SCHAUFELRADBAGGER") //
67+
.bindNull(2, Integer.class) //
68+
.fetch().rowsUpdated() //
69+
.delayElement(Duration.ofMillis(50)) //
70+
.then();
71+
}
72+
73+
@Override
74+
protected String getCurrentTransactionIdStatement() {
75+
return "SELECT tx.trx_id FROM information_schema.innodb_trx tx WHERE tx.trx_mysql_thread_id = connection_id()";
76+
}
77+
}

0 commit comments

Comments
 (0)