forked from hibernate/hibernate-reactive
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[hibernate#929] hibernate-reactive-h2 module
- Loading branch information
Showing
11 changed files
with
461 additions
and
0 deletions.
There are no files selected for viewing
148 changes: 148 additions & 0 deletions
148
hibernate-reactive-core/src/test/java/org/hibernate/reactive/containers/H2Database.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,148 @@ | ||
/* Hibernate, Relational Persistence for Idiomatic Java | ||
* | ||
* SPDX-License-Identifier: Apache-2.0 | ||
* Copyright: Red Hat Inc. and Hibernate Authors | ||
*/ | ||
package org.hibernate.reactive.containers; | ||
|
||
import java.io.Serializable; | ||
import java.math.BigDecimal; | ||
import java.math.BigInteger; | ||
import java.net.URL; | ||
import java.sql.Time; | ||
import java.sql.Timestamp; | ||
import java.time.Duration; | ||
import java.time.Instant; | ||
import java.time.LocalDate; | ||
import java.time.LocalDateTime; | ||
import java.time.LocalTime; | ||
import java.util.Date; | ||
import java.util.HashMap; | ||
import java.util.Map; | ||
import java.util.TimeZone; | ||
import java.util.UUID; | ||
|
||
import org.hibernate.type.NumericBooleanType; | ||
import org.hibernate.type.TextType; | ||
import org.hibernate.type.TrueFalseType; | ||
import org.hibernate.type.YesNoType; | ||
import org.hibernate.type.descriptor.java.PrimitiveByteArrayTypeDescriptor; | ||
|
||
public class H2Database implements TestableDatabase { | ||
public static H2Database INSTANCE = new H2Database(); | ||
|
||
private static Map<Class<?>, String> expectedDBTypeForClass = new HashMap<>(); | ||
|
||
static { | ||
{ | ||
expectedDBTypeForClass.put( boolean.class, "BOOLEAN" ); | ||
expectedDBTypeForClass.put( Boolean.class, "BOOLEAN" ); | ||
expectedDBTypeForClass.put( NumericBooleanType.class, "INTEGER" ); | ||
expectedDBTypeForClass.put( TrueFalseType.class, "CHARACTER" ); | ||
expectedDBTypeForClass.put( YesNoType.class, "CHARACTER" ); | ||
expectedDBTypeForClass.put( int.class, "INTEGER" ); | ||
expectedDBTypeForClass.put( Integer.class, "INTEGER" ); | ||
expectedDBTypeForClass.put( long.class, "BIGINT" ); | ||
expectedDBTypeForClass.put( Long.class, "BIGINT" ); | ||
expectedDBTypeForClass.put( float.class, "DOUBLE PRECISION" ); | ||
expectedDBTypeForClass.put( Float.class, "DOUBLE PRECISION" ); | ||
expectedDBTypeForClass.put( double.class, "DOUBLE PRECISION" ); | ||
expectedDBTypeForClass.put( Double.class, "DOUBLE PRECISION" ); | ||
expectedDBTypeForClass.put( byte.class, "TINYINT" ); | ||
expectedDBTypeForClass.put( Byte.class, "TINYINT" ); | ||
expectedDBTypeForClass.put( PrimitiveByteArrayTypeDescriptor.class, "BINARY VARYING" ); | ||
expectedDBTypeForClass.put( URL.class, "VARCHAR_IGNORECASE" ); | ||
expectedDBTypeForClass.put( TimeZone.class, "VARCHAR_IGNORECASE" ); | ||
expectedDBTypeForClass.put( Date.class, "DATE" ); | ||
expectedDBTypeForClass.put( Timestamp.class, "TIMESTAMP" ); | ||
expectedDBTypeForClass.put( Time.class, "TIME" ); | ||
expectedDBTypeForClass.put( LocalDate.class, "DATE" ); | ||
expectedDBTypeForClass.put( LocalTime.class, "time" ); | ||
expectedDBTypeForClass.put( LocalDateTime.class, "TIMESTAMP" ); | ||
expectedDBTypeForClass.put( BigInteger.class, "NUMERIC" ); | ||
expectedDBTypeForClass.put( BigDecimal.class, "NUMERIC" ); | ||
expectedDBTypeForClass.put( Serializable.class, "BINARY VARYING" ); | ||
expectedDBTypeForClass.put( UUID.class, "binary" ); | ||
expectedDBTypeForClass.put( Instant.class, "datetime" ); | ||
expectedDBTypeForClass.put( Duration.class, "bigint" ); | ||
expectedDBTypeForClass.put( Character.class, "VARCHAR_IGNORECASE" ); | ||
expectedDBTypeForClass.put( char.class, "VARCHAR_IGNORECASE" ); | ||
expectedDBTypeForClass.put( TextType.class, "text" ); | ||
expectedDBTypeForClass.put( String.class, "VARCHAR_IGNORECASE" ); | ||
} | ||
} | ||
|
||
private String getRegularJdbcUrl() { | ||
return "jdbc:h2:~/test;DATABASE_TO_UPPER=FALSE"; | ||
} | ||
|
||
@Override | ||
public String getJdbcUrl() { | ||
return "jdbc:h2:~/test;DATABASE_TO_UPPER=FALSE"; | ||
} | ||
|
||
@Override | ||
public String getUri() { | ||
return "h2:~/test;DATABASE_TO_UPPER=FALSE"; | ||
} | ||
|
||
|
||
@Override | ||
public String getScheme() { | ||
return "h2:"; | ||
} | ||
|
||
@Override | ||
public String getNativeDatatypeQuery(String tableName, String columnName) { | ||
return "SELECT DATA_TYPE FROM INFORMATION_SCHEMA.COLUMNS COLS " + | ||
"WHERE COLS.TABLE_NAME = '" + tableName + "'" + | ||
"AND COLS.COLUMN_NAME= '" + columnName + "'"; | ||
} | ||
|
||
@Override | ||
public String getExpectedNativeDatatype(Class<?> dataType) { | ||
return expectedDBTypeForClass.get( dataType ); | ||
} | ||
|
||
@Override | ||
public String createJdbcUrl(String host, int port, String database, Map<String, String> params) { | ||
// Primary mode for H2 is embedded which uses the URL format: "jdbc:h2:~/test" | ||
// H2 can also be configured as a remote server. | ||
// EXAMPLE 1: jdbc:h2:tcp://localhost/D:/myproject/data/project-name | ||
// EXAMPLE 2: jdbc:h2:tcp://localhost/~/test | ||
// EXAMpLE 3: jdbc:h2:tcp://localhost:9081/~/test | ||
final StringBuilder paramsBuilder = new StringBuilder(); | ||
if ( params != null && !params.isEmpty() ) { | ||
params.forEach( (key, value) -> { | ||
paramsBuilder.append( jdbcParamDelimiter() ); | ||
paramsBuilder.append( key ); | ||
paramsBuilder.append( "=" ); | ||
paramsBuilder.append( value ); | ||
} ); | ||
} | ||
String url = "jdbc:" + getScheme() + "//" + host; | ||
if ( port > -1 ) { | ||
url += ":" + port; | ||
} | ||
if ( paramsBuilder.length() > 0 ) { | ||
url += jdbcStartQuery() + paramsBuilder.substring( 1 ); | ||
} | ||
if ( database != null ) { | ||
return url + ";database=" + database; | ||
} | ||
return url; | ||
} | ||
|
||
@Override | ||
public String jdbcStartQuery() { | ||
return ";"; | ||
} | ||
|
||
@Override | ||
public String jdbcParamDelimiter() { | ||
return ";"; | ||
} | ||
|
||
private H2Database() { | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
ext { | ||
mavenPomName = 'Hibernate Reactive H2' | ||
} | ||
|
||
description = 'The H2 module of Hibernate Reactive' | ||
|
||
apply from: publishScript | ||
|
||
dependencies { | ||
implementation project(':hibernate-reactive-core') | ||
implementation "com.h2database:h2:2.1.210" | ||
|
||
// Dependencies for using H2 with Vert.x: | ||
implementation "io.vertx:vertx-jdbc-client:${vertxVersion}" | ||
implementation 'io.agroal:agroal-api:1.12' | ||
implementation 'io.agroal:agroal-pool:1.12' | ||
|
||
// Testing | ||
testImplementation 'org.assertj:assertj-core:3.20.2' | ||
testImplementation "io.vertx:vertx-unit:${vertxVersion}" | ||
|
||
// log4j | ||
testRuntimeOnly 'org.apache.logging.log4j:log4j-core:2.17.1' | ||
} | ||
|
||
// Print a summary of the results of the tests (number of failures, successes and skipped) | ||
def loggingSummary(db, result, desc) { | ||
if ( !desc.parent ) { // will match the outermost suite | ||
def output = "${db} results: ${result.resultType} (${result.testCount} tests, ${result.successfulTestCount} passed, ${result.failedTestCount} failed, ${result.skippedTestCount} skipped)" | ||
def repeatLength = output.length() + 1 | ||
logger.lifecycle '\n' + ('-' * repeatLength) + '\n' + output + '\n' + ('-' * repeatLength) | ||
} | ||
} | ||
|
||
// Configuration for the tests | ||
tasks.withType(Test) { | ||
defaultCharacterEncoding = "UTF-8" | ||
testLogging { | ||
displayGranularity 1 | ||
showStandardStreams = project.hasProperty('showStandardOutput') | ||
showStackTraces = true | ||
exceptionFormat = 'full' | ||
events 'PASSED', 'FAILED', 'SKIPPED' | ||
} | ||
systemProperty 'org.hibernate.reactive.common.InternalStateAssertions.ENFORCE', 'true' | ||
|
||
if ( project.hasProperty( 'includeTests' ) ) { | ||
// Example: ./gradlew testAll -PincludeTests=DefaultPortTest | ||
filter { | ||
includeTestsMatching project.getProperty( 'includeTests' ) ?: '*' | ||
} | ||
} | ||
} | ||
|
||
test { | ||
afterSuite { desc, result -> | ||
loggingSummary( 'H2', result, desc ) | ||
} | ||
doFirst { | ||
systemProperty 'db', 'H2' | ||
} | ||
} |
18 changes: 18 additions & 0 deletions
18
...nate-reactive-h2/src/main/java/org/hibernate/reactive/boot/impl/H2ServiceContributor.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
/* Hibernate, Relational Persistence for Idiomatic Java | ||
* | ||
* SPDX-License-Identifier: Apache-2.0 | ||
* Copyright: Red Hat Inc. and Hibernate Authors | ||
*/ | ||
package org.hibernate.reactive.boot.impl; | ||
|
||
import org.hibernate.boot.registry.StandardServiceRegistryBuilder; | ||
import org.hibernate.reactive.pool.impl.H2ReactiveConnectionPoolInitiator; | ||
import org.hibernate.service.spi.ServiceContributor; | ||
|
||
public class H2ServiceContributor implements ServiceContributor { | ||
@Override | ||
public void contribute(StandardServiceRegistryBuilder serviceRegistryBuilder) { | ||
serviceRegistryBuilder.addInitiator( H2ReactiveConnectionPoolInitiator.INSTANCE ); | ||
serviceRegistryBuilder.addInitiator( JdbcSqlClientPoolConfigurationInitiator.INSTANCE ); | ||
} | ||
} |
35 changes: 35 additions & 0 deletions
35
...c/main/java/org/hibernate/reactive/boot/impl/JdbcSqlClientPoolConfigurationInitiator.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
/* Hibernate, Relational Persistence for Idiomatic Java | ||
* | ||
* SPDX-License-Identifier: Apache-2.0 | ||
* Copyright: Red Hat Inc. and Hibernate Authors | ||
*/ | ||
package org.hibernate.reactive.boot.impl; | ||
|
||
import java.lang.invoke.MethodHandles; | ||
import java.util.Map; | ||
|
||
import org.hibernate.boot.registry.StandardServiceInitiator; | ||
import org.hibernate.reactive.logging.impl.Log; | ||
import org.hibernate.reactive.logging.impl.LoggerFactory; | ||
import org.hibernate.reactive.pool.impl.H2ClientPoolConfiguration; | ||
import org.hibernate.reactive.pool.impl.JdbcClientPoolConfiguration; | ||
import org.hibernate.service.spi.ServiceRegistryImplementor; | ||
|
||
// TODO: Not sure if we really need this service | ||
public class JdbcSqlClientPoolConfigurationInitiator implements StandardServiceInitiator<JdbcClientPoolConfiguration> { | ||
|
||
private static final Log LOG = LoggerFactory.make( Log.class, MethodHandles.lookup() ); | ||
|
||
public static final JdbcSqlClientPoolConfigurationInitiator INSTANCE = new JdbcSqlClientPoolConfigurationInitiator() { | ||
}; | ||
|
||
@Override | ||
public JdbcClientPoolConfiguration initiateService(Map configurationValues, ServiceRegistryImplementor registry) { | ||
return new H2ClientPoolConfiguration(); | ||
} | ||
|
||
@Override | ||
public Class<JdbcClientPoolConfiguration> getServiceInitiated() { | ||
return JdbcClientPoolConfiguration.class; | ||
} | ||
} |
8 changes: 8 additions & 0 deletions
8
hibernate-reactive-h2/src/main/java/org/hibernate/reactive/package-info.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
/** | ||
// * Hibernate Reactive is an adaptation of Hibernate ORM to the | ||
// * world of reactive programming, and replaces JDBC for database | ||
// * access with a non-blocking database client. | ||
// * <p> | ||
// * <p> | ||
*/ | ||
package org.hibernate.reactive; |
26 changes: 26 additions & 0 deletions
26
...reactive-h2/src/main/java/org/hibernate/reactive/pool/impl/H2ClientPoolConfiguration.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
/* Hibernate, Relational Persistence for Idiomatic Java | ||
* | ||
* SPDX-License-Identifier: Apache-2.0 | ||
* Copyright: Red Hat Inc. and Hibernate Authors | ||
*/ | ||
package org.hibernate.reactive.pool.impl; | ||
|
||
import java.net.URI; | ||
|
||
import io.vertx.jdbcclient.JDBCConnectOptions; | ||
|
||
public class H2ClientPoolConfiguration extends DefaultSqlClientPoolConfiguration | ||
implements JdbcClientPoolConfiguration { | ||
|
||
@Override | ||
public JDBCConnectOptions jdbcConnectOptions(URI uri) { | ||
|
||
return new JDBCConnectOptions() | ||
// H2 connection string | ||
.setJdbcUrl( uri.toString() ) | ||
// username | ||
.setUser( getUser() == null ? "SA" : getUser() ) | ||
// password | ||
.setPassword( getPassword() ); | ||
} | ||
} |
30 changes: 30 additions & 0 deletions
30
...-h2/src/main/java/org/hibernate/reactive/pool/impl/H2ReactiveConnectionPoolInitiator.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
/* Hibernate, Relational Persistence for Idiomatic Java | ||
* | ||
* SPDX-License-Identifier: Apache-2.0 | ||
* Copyright: Red Hat Inc. and Hibernate Authors | ||
*/ | ||
package org.hibernate.reactive.pool.impl; | ||
|
||
import java.util.Map; | ||
|
||
import org.hibernate.internal.util.config.ConfigurationHelper; | ||
import org.hibernate.reactive.pool.ReactiveConnectionPool; | ||
import org.hibernate.reactive.provider.Settings; | ||
import org.hibernate.service.spi.ServiceRegistryImplementor; | ||
|
||
public class H2ReactiveConnectionPoolInitiator extends ReactiveConnectionPoolInitiator { | ||
|
||
public static final H2ReactiveConnectionPoolInitiator INSTANCE = new H2ReactiveConnectionPoolInitiator(); | ||
|
||
@Override | ||
public ReactiveConnectionPool initiateService(Map configurationValues, ServiceRegistryImplementor registry) { | ||
String url = ConfigurationHelper.getString( Settings.URL, configurationValues ); | ||
// Check URL for H2 and return H2 specific pool | ||
if ( url.startsWith( "jdbc:h2:" ) ) { | ||
return new H2SqlClientPool(); | ||
} | ||
|
||
// delegate to super class to initiate the DefaultSqlClientPool | ||
return super.initiateService( configurationValues, registry ); | ||
} | ||
} |
Oops, something went wrong.