Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Sign in / Register
Toggle navigation
S
spring-boot
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
DEMO
spring-boot
Commits
9cc7f0b5
Commit
9cc7f0b5
authored
Mar 26, 2021
by
Andy Wilkinson
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Generalize script-based DB initialization and add R2DBC initializer
See gh-24741
parent
eb120041
Changes
16
Hide whitespace changes
Inline
Side-by-side
Showing
16 changed files
with
361 additions
and
112 deletions
+361
-112
LiquibaseEndpointTests.java
...mework/boot/actuate/liquibase/LiquibaseEndpointTests.java
+5
-4
DataSourceInitializationConfiguration.java
...configure/jdbc/DataSourceInitializationConfiguration.java
+14
-14
SqlInitializationAutoConfiguration.java
...onfigure/sql/init/SqlInitializationAutoConfiguration.java
+9
-9
DataSourceAutoConfigurationTests.java
.../autoconfigure/jdbc/DataSourceAutoConfigurationTests.java
+4
-3
DataSourceScriptDatabaseInitializer.java
...k/boot/jdbc/init/DataSourceScriptDatabaseInitializer.java
+75
-0
DataSourceScriptDatabaseInitializerDetector.java
...dbc/init/DataSourceScriptDatabaseInitializerDetector.java
+4
-3
package-info.java
...java/org/springframework/boot/jdbc/init/package-info.java
+2
-1
R2dbcScriptDatabaseInitializer.java
...ework/boot/r2dbc/init/R2dbcScriptDatabaseInitializer.java
+68
-0
package-info.java
...ava/org/springframework/boot/r2dbc/init/package-info.java
+21
-0
AbstractScriptDatabaseInitializer.java
...work/boot/sql/init/AbstractScriptDatabaseInitializer.java
+10
-36
DatabaseInitializationSettings.java
...amework/boot/sql/init/DatabaseInitializationSettings.java
+3
-5
package-info.java
.../java/org/springframework/boot/sql/init/package-info.java
+20
-0
spring.factories
.../spring-boot/src/main/resources/META-INF/spring.factories
+1
-1
DataSourceScriptDatabaseInitializerTests.java
...t/jdbc/init/DataSourceScriptDatabaseInitializerTests.java
+55
-0
R2dbcScriptDatabaseInitializerTests.java
.../boot/r2dbc/init/R2dbcScriptDatabaseInitializerTests.java
+51
-0
AbstractScriptDatabaseInitializerTests.java
...boot/sql/init/AbstractScriptDatabaseInitializerTests.java
+19
-36
No files found.
spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/liquibase/LiquibaseEndpointTests.java
View file @
9cc7f0b5
...
...
@@ -32,8 +32,8 @@ import org.springframework.boot.autoconfigure.AutoConfigurations;
import
org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration
;
import
org.springframework.boot.autoconfigure.liquibase.LiquibaseAutoConfiguration
;
import
org.springframework.boot.jdbc.EmbeddedDatabaseConnection
;
import
org.springframework.boot.jdbc.init.DataSource
InitializationSettings
;
import
org.springframework.boot.
jdbc.init.ScriptDataSourceInitializer
;
import
org.springframework.boot.jdbc.init.DataSource
ScriptDatabaseInitializer
;
import
org.springframework.boot.
sql.init.DatabaseInitializationSettings
;
import
org.springframework.boot.test.context.runner.ApplicationContextRunner
;
import
org.springframework.context.ApplicationContext
;
import
org.springframework.context.annotation.Bean
;
...
...
@@ -148,9 +148,10 @@ class LiquibaseEndpointTests {
DataSource
dataSource
=
new
EmbeddedDatabaseBuilder
()
.
setType
(
EmbeddedDatabaseConnection
.
get
(
getClass
().
getClassLoader
()).
getType
())
.
setName
(
UUID
.
randomUUID
().
toString
()).
build
();
Data
SourceInitializationSettings
settings
=
new
DataSourc
eInitializationSettings
();
Data
baseInitializationSettings
settings
=
new
Databas
eInitializationSettings
();
settings
.
setSchemaLocations
(
Arrays
.
asList
(
"classpath:/db/create-custom-schema.sql"
));
ScriptDataSourceInitializer
initializer
=
new
ScriptDataSourceInitializer
(
dataSource
,
settings
);
DataSourceScriptDatabaseInitializer
initializer
=
new
DataSourceScriptDatabaseInitializer
(
dataSource
,
settings
);
initializer
.
initializeDatabase
();
return
dataSource
;
}
...
...
spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jdbc/DataSourceInitializationConfiguration.java
View file @
9cc7f0b5
...
...
@@ -41,9 +41,9 @@ import org.springframework.boot.autoconfigure.jdbc.DataSourceInitializationConfi
import
org.springframework.boot.jdbc.DataSourceBuilder
;
import
org.springframework.boot.jdbc.DataSourceInitializationMode
;
import
org.springframework.boot.jdbc.EmbeddedDatabaseConnection
;
import
org.springframework.boot.jdbc.init.DataSourceInitializationSettings
;
import
org.springframework.boot.jdbc.init.ScriptDataSourceInitializer
;
import
org.springframework.boot.jdbc.init.DataSourceScriptDatabaseInitializer
;
import
org.springframework.boot.jdbc.init.dependency.DataSourceInitializationDependencyConfigurer
;
import
org.springframework.boot.sql.init.DatabaseInitializationSettings
;
import
org.springframework.context.annotation.Bean
;
import
org.springframework.context.annotation.ConditionContext
;
import
org.springframework.context.annotation.DependsOn
;
...
...
@@ -56,7 +56,7 @@ import org.springframework.util.StringUtils;
/**
* Configuration for {@link DataSource} initialization using a
* {@link
ScriptDataSourc
eInitializer} with DDL and DML scripts.
* {@link
DataSourceScriptDatabas
eInitializer} with DDL and DML scripts.
*
* @author Andy Wilkinson
*/
...
...
@@ -87,13 +87,13 @@ class DataSourceInitializationConfiguration {
@org
.
springframework
.
context
.
annotation
.
Conditional
(
DifferentCredentialsCondition
.
class
)
@org
.
springframework
.
context
.
annotation
.
Import
(
DataSourceInitializationDependencyConfigurer
.
class
)
@ConditionalOnSingleCandidate
(
DataSource
.
class
)
@ConditionalOnMissingBean
(
ScriptDataSourc
eInitializer
.
class
)
@ConditionalOnMissingBean
(
DataSourceScriptDatabas
eInitializer
.
class
)
static
class
InitializationSpecificCredentialsDataSourceInitializationConfiguration
{
@Bean
ScriptDataSourc
eInitializer
ddlOnlyScriptDataSourceInitializer
(
ObjectProvider
<
DataSource
>
dataSource
,
DataSourceScriptDatabas
eInitializer
ddlOnlyScriptDataSourceInitializer
(
ObjectProvider
<
DataSource
>
dataSource
,
DataSourceProperties
properties
,
ResourceLoader
resourceLoader
)
{
Data
SourceInitializationSettings
settings
=
new
DataSourc
eInitializationSettings
();
Data
baseInitializationSettings
settings
=
new
Databas
eInitializationSettings
();
settings
.
setSchemaLocations
(
scriptLocations
(
properties
.
getSchema
(),
"schema"
,
properties
.
getPlatform
()));
settings
.
setContinueOnError
(
properties
.
isContinueOnError
());
settings
.
setSeparator
(
properties
.
getSeparator
());
...
...
@@ -106,9 +106,9 @@ class DataSourceInitializationConfiguration {
@Bean
@DependsOn
(
"ddlOnlyScriptDataSourceInitializer"
)
ScriptDataSourc
eInitializer
dmlOnlyScriptDataSourceInitializer
(
ObjectProvider
<
DataSource
>
dataSource
,
DataSourceScriptDatabas
eInitializer
dmlOnlyScriptDataSourceInitializer
(
ObjectProvider
<
DataSource
>
dataSource
,
DataSourceProperties
properties
,
ResourceLoader
resourceLoader
)
{
Data
SourceInitializationSettings
settings
=
new
DataSourc
eInitializationSettings
();
Data
baseInitializationSettings
settings
=
new
Databas
eInitializationSettings
();
settings
.
setDataLocations
(
scriptLocations
(
properties
.
getData
(),
"data"
,
properties
.
getPlatform
()));
settings
.
setContinueOnError
(
properties
.
isContinueOnError
());
settings
.
setSeparator
(
properties
.
getSeparator
());
...
...
@@ -144,13 +144,13 @@ class DataSourceInitializationConfiguration {
@org
.
springframework
.
context
.
annotation
.
Import
(
DataSourceInitializationDependencyConfigurer
.
class
)
@org
.
springframework
.
context
.
annotation
.
Conditional
(
DataSourceInitializationCondition
.
class
)
@ConditionalOnSingleCandidate
(
DataSource
.
class
)
@ConditionalOnMissingBean
(
ScriptDataSourc
eInitializer
.
class
)
@ConditionalOnMissingBean
(
DataSourceScriptDatabas
eInitializer
.
class
)
static
class
SharedCredentialsDataSourceInitializationConfiguration
{
@Bean
ScriptDataSourceInitializer
scriptDataSourceInitializer
(
DataSource
dataSource
,
DataSourceProperties
properties
,
ResourceLoader
resourceLoader
)
{
Data
SourceInitializationSettings
settings
=
new
DataSourc
eInitializationSettings
();
DataSourceScriptDatabaseInitializer
scriptDataSourceInitializer
(
DataSource
dataSource
,
DataSourceProperties
properties
,
ResourceLoader
resourceLoader
)
{
Data
baseInitializationSettings
settings
=
new
Databas
eInitializationSettings
();
settings
.
setSchemaLocations
(
scriptLocations
(
properties
.
getSchema
(),
"schema"
,
properties
.
getPlatform
()));
settings
.
setDataLocations
(
scriptLocations
(
properties
.
getData
(),
"data"
,
properties
.
getPlatform
()));
settings
.
setContinueOnError
(
properties
.
isContinueOnError
());
...
...
@@ -188,12 +188,12 @@ class DataSourceInitializationConfiguration {
}
static
class
InitializationModeDataSourceScriptDatabaseInitializer
extends
ScriptDataSourc
eInitializer
{
static
class
InitializationModeDataSourceScriptDatabaseInitializer
extends
DataSourceScriptDatabas
eInitializer
{
private
final
DataSourceInitializationMode
mode
;
InitializationModeDataSourceScriptDatabaseInitializer
(
DataSource
dataSource
,
Data
Sourc
eInitializationSettings
settings
,
DataSourceInitializationMode
mode
)
{
Data
bas
eInitializationSettings
settings
,
DataSourceInitializationMode
mode
)
{
super
(
dataSource
,
settings
);
this
.
mode
=
mode
;
}
...
...
spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/sql/init/SqlInitializationAutoConfiguration.java
View file @
9cc7f0b5
...
...
@@ -29,9 +29,9 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnSingleCandi
import
org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration
;
import
org.springframework.boot.context.properties.EnableConfigurationProperties
;
import
org.springframework.boot.jdbc.DataSourceBuilder
;
import
org.springframework.boot.jdbc.init.DataSourceInitializationSettings
;
import
org.springframework.boot.jdbc.init.ScriptDataSourceInitializer
;
import
org.springframework.boot.jdbc.init.DataSourceScriptDatabaseInitializer
;
import
org.springframework.boot.jdbc.init.dependency.DataSourceInitializationDependencyConfigurer
;
import
org.springframework.boot.sql.init.DatabaseInitializationSettings
;
import
org.springframework.context.annotation.Bean
;
import
org.springframework.context.annotation.Configuration
;
import
org.springframework.context.annotation.Import
;
...
...
@@ -45,7 +45,7 @@ import org.springframework.util.StringUtils;
* @since 2.5.0
*/
@Configuration
(
proxyBeanMethods
=
false
)
@ConditionalOnMissingBean
(
ScriptDataSourc
eInitializer
.
class
)
@ConditionalOnMissingBean
(
DataSourceScriptDatabas
eInitializer
.
class
)
@ConditionalOnSingleCandidate
(
DataSource
.
class
)
@ConditionalOnProperty
(
prefix
=
"spring.sql.init"
,
name
=
"enabled"
,
matchIfMissing
=
true
)
@AutoConfigureAfter
(
DataSourceAutoConfiguration
.
class
)
...
...
@@ -54,15 +54,15 @@ import org.springframework.util.StringUtils;
public
class
SqlInitializationAutoConfiguration
{
@Bean
ScriptDataSourc
eInitializer
dataSourceScriptDatabaseInitializer
(
DataSource
dataSource
,
DataSourceScriptDatabas
eInitializer
dataSourceScriptDatabaseInitializer
(
DataSource
dataSource
,
SqlInitializationProperties
initializationProperties
)
{
Data
Sourc
eInitializationSettings
settings
=
createSettings
(
initializationProperties
);
return
new
ScriptDataSourceInitializer
(
determineDataSource
(
dataSource
,
initializationProperties
.
getUsername
()
,
initializationProperties
.
getPassword
()),
settings
);
Data
bas
eInitializationSettings
settings
=
createSettings
(
initializationProperties
);
return
new
DataSourceScriptDatabaseInitializer
(
determineDataSource
(
dataSource
,
initializationProperties
.
get
Username
(),
initializationProperties
.
get
Password
()),
settings
);
}
private
static
Data
Sourc
eInitializationSettings
createSettings
(
SqlInitializationProperties
properties
)
{
Data
SourceInitializationSettings
settings
=
new
DataSourc
eInitializationSettings
();
private
static
Data
bas
eInitializationSettings
createSettings
(
SqlInitializationProperties
properties
)
{
Data
baseInitializationSettings
settings
=
new
Databas
eInitializationSettings
();
settings
.
setSchemaLocations
(
scriptLocations
(
properties
.
getSchemaLocations
(),
"schema"
,
properties
.
getPlatform
()));
settings
.
setDataLocations
(
scriptLocations
(
properties
.
getDataLocations
(),
"data"
,
properties
.
getPlatform
()));
...
...
spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jdbc/DataSourceAutoConfigurationTests.java
View file @
9cc7f0b5
...
...
@@ -43,7 +43,7 @@ import org.springframework.beans.factory.annotation.Autowired;
import
org.springframework.boot.autoconfigure.AutoConfigurations
;
import
org.springframework.boot.jdbc.DatabaseDriver
;
import
org.springframework.boot.jdbc.EmbeddedDatabaseConnection
;
import
org.springframework.boot.jdbc.init.
ScriptDataSourc
eInitializer
;
import
org.springframework.boot.jdbc.init.
DataSourceScriptDatabas
eInitializer
;
import
org.springframework.boot.jdbc.init.dependency.DependsOnDataSourceInitialization
;
import
org.springframework.boot.test.context.FilteredClassLoader
;
import
org.springframework.boot.test.context.assertj.AssertableApplicationContext
;
...
...
@@ -240,14 +240,15 @@ class DataSourceAutoConfigurationTests {
void
testDataSourceIsInitializedEarly
()
{
this
.
contextRunner
.
withUserConfiguration
(
TestInitializedDataSourceConfiguration
.
class
)
.
withPropertyValues
(
"spring.datasource.initialization-mode=always"
).
run
((
context
)
->
{
assertThat
(
context
).
hasSingleBean
(
ScriptDataSourc
eInitializer
.
class
);
assertThat
(
context
).
hasSingleBean
(
DataSourceScriptDatabas
eInitializer
.
class
);
assertThat
(
context
.
getBean
(
TestInitializedDataSourceConfiguration
.
class
).
called
).
isTrue
();
});
}
@Test
void
whenNoInitializationRelatedSpringDataSourcePropertiesAreConfiguredThenInitializationBacksOff
()
{
this
.
contextRunner
.
run
((
context
)
->
assertThat
(
context
).
doesNotHaveBean
(
ScriptDataSourceInitializer
.
class
));
this
.
contextRunner
.
run
((
context
)
->
assertThat
(
context
).
doesNotHaveBean
(
DataSourceScriptDatabaseInitializer
.
class
));
}
private
static
Function
<
ApplicationContextRunner
,
ApplicationContextRunner
>
hideConnectionPools
()
{
...
...
spring-boot-project/spring-boot/src/main/java/org/springframework/boot/jdbc/init/DataSourceScriptDatabaseInitializer.java
0 → 100644
View file @
9cc7f0b5
/*
* Copyright 2012-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package
org
.
springframework
.
boot
.
jdbc
.
init
;
import
java.nio.charset.Charset
;
import
java.util.List
;
import
javax.sql.DataSource
;
import
org.springframework.beans.factory.InitializingBean
;
import
org.springframework.boot.sql.init.AbstractScriptDatabaseInitializer
;
import
org.springframework.boot.sql.init.DatabaseInitializationSettings
;
import
org.springframework.core.io.Resource
;
import
org.springframework.jdbc.datasource.init.DatabasePopulatorUtils
;
import
org.springframework.jdbc.datasource.init.ResourceDatabasePopulator
;
/**
* {@link InitializingBean} that performs {@link DataSource} initialization using schema
* (DDL) and data (DML) scripts.
*
* @author Andy Wilkinson
* @since 2.5.0
*/
public
class
DataSourceScriptDatabaseInitializer
extends
AbstractScriptDatabaseInitializer
{
private
final
DataSource
dataSource
;
/**
* Creates a new {@link DataSourceScriptDatabaseInitializer} that will initialize the
* given {@code DataSource} using the given settings.
* @param dataSource data source to initialize
* @param settings initialization settings
*/
public
DataSourceScriptDatabaseInitializer
(
DataSource
dataSource
,
DatabaseInitializationSettings
settings
)
{
super
(
settings
);
this
.
dataSource
=
dataSource
;
}
/**
* Returns the {@code DataSource} that will be initialized.
* @return the initialization data source
*/
protected
final
DataSource
getDataSource
()
{
return
this
.
dataSource
;
}
@Override
protected
void
runScripts
(
List
<
Resource
>
resources
,
boolean
continueOnError
,
String
separator
,
Charset
encoding
)
{
ResourceDatabasePopulator
populator
=
new
ResourceDatabasePopulator
();
populator
.
setContinueOnError
(
continueOnError
);
populator
.
setSeparator
(
separator
);
if
(
encoding
!=
null
)
{
populator
.
setSqlScriptEncoding
(
encoding
.
name
());
}
for
(
Resource
resource
:
resources
)
{
populator
.
addScript
(
resource
);
}
DatabasePopulatorUtils
.
execute
(
populator
,
this
.
dataSource
);
}
}
spring-boot-project/spring-boot/src/main/java/org/springframework/boot/jdbc/init/
ScriptDataSourc
eInitializerDetector.java
→
spring-boot-project/spring-boot/src/main/java/org/springframework/boot/jdbc/init/
DataSourceScriptDatabas
eInitializerDetector.java
View file @
9cc7f0b5
...
...
@@ -23,15 +23,16 @@ import org.springframework.boot.jdbc.init.dependency.AbstractBeansOfTypeDataSour
import
org.springframework.boot.jdbc.init.dependency.DataSourceInitializerDetector
;
/**
* A {@link DataSourceInitializerDetector} for {@link ScriptDataSourceInitializer}.
* A {@link DataSourceInitializerDetector} for
* {@link DataSourceScriptDatabaseInitializer}.
*
* @author Andy Wilkinson
*/
class
ScriptDataSourc
eInitializerDetector
extends
AbstractBeansOfTypeDataSourceInitializerDetector
{
class
DataSourceScriptDatabas
eInitializerDetector
extends
AbstractBeansOfTypeDataSourceInitializerDetector
{
@Override
protected
Set
<
Class
<?>>
getDataSourceInitializerBeanTypes
()
{
return
Collections
.
singleton
(
ScriptDataSourc
eInitializer
.
class
);
return
Collections
.
singleton
(
DataSourceScriptDatabas
eInitializer
.
class
);
}
}
spring-boot-project/spring-boot/src/main/java/org/springframework/boot/jdbc/init/package-info.java
View file @
9cc7f0b5
...
...
@@ -15,6 +15,7 @@
*/
/**
* Support for initializaton of a JDBC {@code DataSource}.
* Support for initializaton of an SQL database using a JDBC {@link javax.sql.DataSource
* DataSource}.
*/
package
org
.
springframework
.
boot
.
jdbc
.
init
;
spring-boot-project/spring-boot/src/main/java/org/springframework/boot/r2dbc/init/R2dbcScriptDatabaseInitializer.java
0 → 100644
View file @
9cc7f0b5
/*
* Copyright 2012-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package
org
.
springframework
.
boot
.
r2dbc
.
init
;
import
java.nio.charset.Charset
;
import
java.util.List
;
import
io.r2dbc.spi.ConnectionFactory
;
import
org.springframework.beans.factory.InitializingBean
;
import
org.springframework.boot.sql.init.AbstractScriptDatabaseInitializer
;
import
org.springframework.boot.sql.init.DatabaseInitializationSettings
;
import
org.springframework.core.io.Resource
;
import
org.springframework.r2dbc.connection.init.ResourceDatabasePopulator
;
/**
* An {@link InitializingBean} that initializes a database represented by an R2DBC
* {@link ConnectionFactory}.
*
* @author Andy Wilkinson
* @since 2.5.0
*/
public
class
R2dbcScriptDatabaseInitializer
extends
AbstractScriptDatabaseInitializer
{
private
final
ConnectionFactory
connectionFactory
;
/**
* Creates a new {@code R2dbcScriptDatabaseInitializer} that will initialize the
* database recognized by the given {@code connectionFactory} using the given
* {@code settings}.
* @param connectionFactory connectionFactory for the database
* @param settings initialization settings
*/
public
R2dbcScriptDatabaseInitializer
(
ConnectionFactory
connectionFactory
,
DatabaseInitializationSettings
settings
)
{
super
(
settings
);
this
.
connectionFactory
=
connectionFactory
;
}
@Override
protected
void
runScripts
(
List
<
Resource
>
scripts
,
boolean
continueOnError
,
String
separator
,
Charset
encoding
)
{
ResourceDatabasePopulator
populator
=
new
ResourceDatabasePopulator
();
populator
.
setContinueOnError
(
continueOnError
);
populator
.
setSeparator
(
separator
);
if
(
encoding
!=
null
)
{
populator
.
setSqlScriptEncoding
(
encoding
.
name
());
}
for
(
Resource
script
:
scripts
)
{
populator
.
addScript
(
script
);
}
populator
.
populate
(
this
.
connectionFactory
).
block
();
}
}
spring-boot-project/spring-boot/src/main/java/org/springframework/boot/r2dbc/init/package-info.java
0 → 100644
View file @
9cc7f0b5
/*
* Copyright 2012-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* Support for initializaton of an SQL database using an R2DBC
* {@link io.r2dbc.spi.ConnectionFactory ConnectionFactory}.
*/
package
org
.
springframework
.
boot
.
r2dbc
.
init
;
spring-boot-project/spring-boot/src/main/java/org/springframework/boot/
jdbc/init/ScriptDataSourc
eInitializer.java
→
spring-boot-project/spring-boot/src/main/java/org/springframework/boot/
sql/init/AbstractScriptDatabas
eInitializer.java
View file @
9cc7f0b5
...
...
@@ -14,7 +14,7 @@
* limitations under the License.
*/
package
org
.
springframework
.
boot
.
jdbc
.
init
;
package
org
.
springframework
.
boot
.
sql
.
init
;
import
java.io.IOException
;
import
java.nio.charset.Charset
;
...
...
@@ -23,54 +23,38 @@ import java.util.Arrays;
import
java.util.Collections
;
import
java.util.List
;
import
javax.sql.DataSource
;
import
org.springframework.beans.factory.InitializingBean
;
import
org.springframework.context.ResourceLoaderAware
;
import
org.springframework.core.io.Resource
;
import
org.springframework.core.io.ResourceLoader
;
import
org.springframework.core.io.support.ResourcePatternResolver
;
import
org.springframework.core.io.support.ResourcePatternUtils
;
import
org.springframework.jdbc.datasource.init.DatabasePopulatorUtils
;
import
org.springframework.jdbc.datasource.init.ResourceDatabasePopulator
;
import
org.springframework.util.CollectionUtils
;
/**
*
{@link InitializingBean} that performs {@link DataSource} initialization using schema
* (DDL) and data (DML) scripts.
*
Base class for an {@link InitializingBean} that performs SQL database initialization
*
using schema
(DDL) and data (DML) scripts.
*
* @author Andy Wilkinson
* @since 2.5.0
*/
public
class
ScriptDataSourc
eInitializer
implements
ResourceLoaderAware
,
InitializingBean
{
public
abstract
class
AbstractScriptDatabas
eInitializer
implements
ResourceLoaderAware
,
InitializingBean
{
private
static
final
String
OPTIONAL_LOCATION_PREFIX
=
"optional:"
;
private
final
DataSource
dataSource
;
private
final
DataSourceInitializationSettings
settings
;
private
final
DatabaseInitializationSettings
settings
;
private
volatile
ResourceLoader
resourceLoader
;
/**
* Creates a new {@link ScriptDataSourceInitializer} that will initialize the given
* {@code DataSource} using the given settings.
* @param dataSource data source to initialize
* Creates a new {@link AbstractScriptDatabaseInitializer} that will initialize the
* database using the given settings.
* @param settings initialization settings
*/
public
ScriptDataSourceInitializer
(
DataSource
dataSource
,
DataSourceInitializationSettings
settings
)
{
this
.
dataSource
=
dataSource
;
protected
AbstractScriptDatabaseInitializer
(
DatabaseInitializationSettings
settings
)
{
this
.
settings
=
settings
;
}
/**
* Returns the {@code DataSource} that will be initialized.
* @return the initialization data source
*/
protected
final
DataSource
getDataSource
()
{
return
this
.
dataSource
;
}
@Override
public
void
setResourceLoader
(
ResourceLoader
resourceLoader
)
{
this
.
resourceLoader
=
resourceLoader
;
...
...
@@ -148,18 +132,8 @@ public class ScriptDataSourceInitializer implements ResourceLoaderAware, Initial
this
.
settings
.
getEncoding
());
}
protected
void
runScripts
(
List
<
Resource
>
resources
,
boolean
continueOnError
,
String
separator
,
Charset
encoding
)
{
ResourceDatabasePopulator
populator
=
new
ResourceDatabasePopulator
();
populator
.
setContinueOnError
(
continueOnError
);
populator
.
setSeparator
(
separator
);
if
(
encoding
!=
null
)
{
populator
.
setSqlScriptEncoding
(
encoding
.
name
());
}
for
(
Resource
resource
:
resources
)
{
populator
.
addScript
(
resource
);
}
DatabasePopulatorUtils
.
execute
(
populator
,
this
.
dataSource
);
}
protected
abstract
void
runScripts
(
List
<
Resource
>
resources
,
boolean
continueOnError
,
String
separator
,
Charset
encoding
);
private
static
class
ScriptLocationResolver
{
...
...
spring-boot-project/spring-boot/src/main/java/org/springframework/boot/
jdbc/init/DataSourc
eInitializationSettings.java
→
spring-boot-project/spring-boot/src/main/java/org/springframework/boot/
sql/init/Databas
eInitializationSettings.java
View file @
9cc7f0b5
...
...
@@ -14,20 +14,18 @@
* limitations under the License.
*/
package
org
.
springframework
.
boot
.
jdbc
.
init
;
package
org
.
springframework
.
boot
.
sql
.
init
;
import
java.nio.charset.Charset
;
import
java.util.List
;
import
javax.sql.DataSource
;
/**
* Settings for initializing a
database using a JDBC {@link DataSource}
.
* Settings for initializing a
n SQL database
.
*
* @author Andy Wilkinson
* @since 2.5.0
*/
public
class
Data
Sourc
eInitializationSettings
{
public
class
Data
bas
eInitializationSettings
{
private
List
<
String
>
schemaLocations
;
...
...
spring-boot-project/spring-boot/src/main/java/org/springframework/boot/sql/init/package-info.java
0 → 100644
View file @
9cc7f0b5
/*
* Copyright 2012-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* Support for initializaton of an SQL database.
*/
package
org
.
springframework
.
boot
.
sql
.
init
;
spring-boot-project/spring-boot/src/main/resources/META-INF/spring.factories
View file @
9cc7f0b5
...
...
@@ -82,7 +82,7 @@ org.springframework.boot.diagnostics.LoggingFailureAnalysisReporter
# DataSource Initializer Detectors
org.springframework.boot.jdbc.init.dependency.DataSourceInitializerDetector=\
org.springframework.boot.flyway.FlywayDataSourceInitializerDetector,\
org.springframework.boot.jdbc.init.
ScriptDataSourc
eInitializerDetector,\
org.springframework.boot.jdbc.init.
DataSourceScriptDatabas
eInitializerDetector,\
org.springframework.boot.liquibase.LiquibaseDataSourceInitializerDetector,\
org.springframework.boot.orm.jpa.JpaDataSourceInitializerDetector
...
...
spring-boot-project/spring-boot/src/test/java/org/springframework/boot/jdbc/init/DataSourceScriptDatabaseInitializerTests.java
0 → 100644
View file @
9cc7f0b5
/*
* Copyright 2012-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package
org
.
springframework
.
boot
.
jdbc
.
init
;
import
java.util.UUID
;
import
com.zaxxer.hikari.HikariDataSource
;
import
org.junit.jupiter.api.AfterEach
;
import
org.springframework.boot.jdbc.DataSourceBuilder
;
import
org.springframework.boot.sql.init.AbstractScriptDatabaseInitializer
;
import
org.springframework.boot.sql.init.AbstractScriptDatabaseInitializerTests
;
import
org.springframework.boot.sql.init.DatabaseInitializationSettings
;
import
org.springframework.jdbc.core.JdbcTemplate
;
/**
* Tests for {@link DataSourceScriptDatabaseInitializer}.
*
* @author Andy Wilkinson
*/
class
DataSourceScriptDatabaseInitializerTests
extends
AbstractScriptDatabaseInitializerTests
{
private
final
HikariDataSource
dataSource
=
DataSourceBuilder
.
create
().
type
(
HikariDataSource
.
class
)
.
url
(
"jdbc:h2:mem:"
+
UUID
.
randomUUID
()).
build
();
@AfterEach
void
closeDataSource
()
{
this
.
dataSource
.
close
();
}
@Override
protected
AbstractScriptDatabaseInitializer
createInitializer
(
DatabaseInitializationSettings
settings
)
{
return
new
DataSourceScriptDatabaseInitializer
(
this
.
dataSource
,
settings
);
}
@Override
protected
int
numberOfRows
(
String
sql
)
{
return
new
JdbcTemplate
(
this
.
dataSource
).
queryForObject
(
sql
,
Integer
.
class
);
}
}
spring-boot-project/spring-boot/src/test/java/org/springframework/boot/r2dbc/init/R2dbcScriptDatabaseInitializerTests.java
0 → 100644
View file @
9cc7f0b5
/*
* Copyright 2012-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package
org
.
springframework
.
boot
.
r2dbc
.
init
;
import
java.util.UUID
;
import
io.r2dbc.spi.ConnectionFactory
;
import
org.springframework.boot.r2dbc.ConnectionFactoryBuilder
;
import
org.springframework.boot.sql.init.AbstractScriptDatabaseInitializer
;
import
org.springframework.boot.sql.init.AbstractScriptDatabaseInitializerTests
;
import
org.springframework.boot.sql.init.DatabaseInitializationSettings
;
import
org.springframework.r2dbc.core.DatabaseClient
;
/**
* Tests for {@link R2dbcScriptDatabaseInitializer}.
*
* @author Andy Wilkinson
*/
class
R2dbcScriptDatabaseInitializerTests
extends
AbstractScriptDatabaseInitializerTests
{
private
final
ConnectionFactory
connectionFactory
=
ConnectionFactoryBuilder
.
withUrl
(
"r2dbc:h2:mem:///"
+
UUID
.
randomUUID
()
+
"?options=DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE"
)
.
build
();
@Override
protected
AbstractScriptDatabaseInitializer
createInitializer
(
DatabaseInitializationSettings
settings
)
{
return
new
R2dbcScriptDatabaseInitializer
(
this
.
connectionFactory
,
settings
);
}
@Override
protected
int
numberOfRows
(
String
sql
)
{
return
DatabaseClient
.
create
(
this
.
connectionFactory
).
sql
(
sql
).
map
((
row
,
metadata
)
->
row
.
get
(
0
)).
first
()
.
map
((
number
)
->
((
Number
)
number
).
intValue
()).
block
();
}
}
spring-boot-project/spring-boot/src/test/java/org/springframework/boot/
jdbc/init/ScriptDataSourc
eInitializerTests.java
→
spring-boot-project/spring-boot/src/test/java/org/springframework/boot/
sql/init/AbstractScriptDatabas
eInitializerTests.java
View file @
9cc7f0b5
...
...
@@ -14,105 +14,88 @@
* limitations under the License.
*/
package
org
.
springframework
.
boot
.
jdbc
.
init
;
package
org
.
springframework
.
boot
.
sql
.
init
;
import
java.util.Arrays
;
import
java.util.UUID
;
import
com.zaxxer.hikari.HikariDataSource
;
import
org.junit.jupiter.api.AfterEach
;
import
org.junit.jupiter.api.Test
;
import
org.springframework.boot.jdbc.DataSourceBuilder
;
import
org.springframework.dao.DataAccessException
;
import
org.springframework.jdbc.core.JdbcTemplate
;
import
static
org
.
assertj
.
core
.
api
.
Assertions
.
assertThat
;
import
static
org
.
assertj
.
core
.
api
.
Assertions
.
assertThatExceptionOfType
;
import
static
org
.
assertj
.
core
.
api
.
Assertions
.
assertThatIllegalStateException
;
/**
*
Tests for {@link ScriptDataSourceInitializer}
.
*
Base class for testing {@link AbstractScriptDatabaseInitializer} implementations
.
*
* @author Andy Wilkinson
*/
class
ScriptDataSourceInitializerTests
{
private
final
HikariDataSource
dataSource
=
DataSourceBuilder
.
create
().
type
(
HikariDataSource
.
class
)
.
url
(
"jdbc:h2:mem:"
+
UUID
.
randomUUID
()).
build
();
@AfterEach
void
closeDataSource
()
{
this
.
dataSource
.
close
();
}
public
abstract
class
AbstractScriptDatabaseInitializerTests
{
@Test
void
whenDatabaseIsInitializedThenSchemaAndDataScriptsAreApplied
()
{
Data
SourceInitializationSettings
settings
=
new
DataSourc
eInitializationSettings
();
Data
baseInitializationSettings
settings
=
new
Databas
eInitializationSettings
();
settings
.
setSchemaLocations
(
Arrays
.
asList
(
"schema.sql"
));
settings
.
setDataLocations
(
Arrays
.
asList
(
"data.sql"
));
ScriptDataSourc
eInitializer
initializer
=
createInitializer
(
settings
);
AbstractScriptDatabas
eInitializer
initializer
=
createInitializer
(
settings
);
assertThat
(
initializer
.
initializeDatabase
()).
isTrue
();
assertThat
(
numberOfRows
(
"SELECT COUNT(*) FROM EXAMPLE"
)).
isEqualTo
(
1
);
}
@Test
void
whenContinueOnErrorIsFalseThenInitializationFailsOnError
()
{
Data
SourceInitializationSettings
settings
=
new
DataSourc
eInitializationSettings
();
Data
baseInitializationSettings
settings
=
new
Databas
eInitializationSettings
();
settings
.
setDataLocations
(
Arrays
.
asList
(
"data.sql"
));
ScriptDataSourc
eInitializer
initializer
=
createInitializer
(
settings
);
AbstractScriptDatabas
eInitializer
initializer
=
createInitializer
(
settings
);
assertThatExceptionOfType
(
DataAccessException
.
class
).
isThrownBy
(()
->
initializer
.
initializeDatabase
());
}
@Test
void
whenContinueOnErrorIsTrueThenInitializationDoesNotFailOnError
()
{
Data
SourceInitializationSettings
settings
=
new
DataSourc
eInitializationSettings
();
Data
baseInitializationSettings
settings
=
new
Databas
eInitializationSettings
();
settings
.
setContinueOnError
(
true
);
settings
.
setDataLocations
(
Arrays
.
asList
(
"data.sql"
));
ScriptDataSourc
eInitializer
initializer
=
createInitializer
(
settings
);
AbstractScriptDatabas
eInitializer
initializer
=
createInitializer
(
settings
);
assertThat
(
initializer
.
initializeDatabase
()).
isTrue
();
}
@Test
void
whenNoScriptsExistAtASchemaLocationThenInitializationFails
()
{
Data
SourceInitializationSettings
settings
=
new
DataSourc
eInitializationSettings
();
Data
baseInitializationSettings
settings
=
new
Databas
eInitializationSettings
();
settings
.
setSchemaLocations
(
Arrays
.
asList
(
"does-not-exist.sql"
));
ScriptDataSourc
eInitializer
initializer
=
createInitializer
(
settings
);
AbstractScriptDatabas
eInitializer
initializer
=
createInitializer
(
settings
);
assertThatIllegalStateException
().
isThrownBy
(
initializer:
:
initializeDatabase
)
.
withMessage
(
"No schema scripts found at location 'does-not-exist.sql'"
);
}
@Test
void
whenNoScriptsExistAtADataLocationThenInitializationFails
()
{
Data
SourceInitializationSettings
settings
=
new
DataSourc
eInitializationSettings
();
Data
baseInitializationSettings
settings
=
new
Databas
eInitializationSettings
();
settings
.
setDataLocations
(
Arrays
.
asList
(
"does-not-exist.sql"
));
ScriptDataSourc
eInitializer
initializer
=
createInitializer
(
settings
);
AbstractScriptDatabas
eInitializer
initializer
=
createInitializer
(
settings
);
assertThatIllegalStateException
().
isThrownBy
(
initializer:
:
initializeDatabase
)
.
withMessage
(
"No data scripts found at location 'does-not-exist.sql'"
);
}
@Test
void
whenNoScriptsExistAtAnOptionalSchemaLocationThenInitializationSucceeds
()
{
Data
SourceInitializationSettings
settings
=
new
DataSourc
eInitializationSettings
();
Data
baseInitializationSettings
settings
=
new
Databas
eInitializationSettings
();
settings
.
setSchemaLocations
(
Arrays
.
asList
(
"optional:does-not-exist.sql"
));
ScriptDataSourc
eInitializer
initializer
=
createInitializer
(
settings
);
AbstractScriptDatabas
eInitializer
initializer
=
createInitializer
(
settings
);
assertThat
(
initializer
.
initializeDatabase
()).
isFalse
();
}
@Test
void
whenNoScriptsExistAtAnOptionalDataLocationThenInitializationSucceeds
()
{
Data
SourceInitializationSettings
settings
=
new
DataSourc
eInitializationSettings
();
Data
baseInitializationSettings
settings
=
new
Databas
eInitializationSettings
();
settings
.
setDataLocations
(
Arrays
.
asList
(
"optional:does-not-exist.sql"
));
ScriptDataSourc
eInitializer
initializer
=
createInitializer
(
settings
);
AbstractScriptDatabas
eInitializer
initializer
=
createInitializer
(
settings
);
assertThat
(
initializer
.
initializeDatabase
()).
isFalse
();
}
private
ScriptDataSourceInitializer
createInitializer
(
DataSourceInitializationSettings
settings
)
{
return
new
ScriptDataSourceInitializer
(
this
.
dataSource
,
settings
);
}
protected
abstract
AbstractScriptDatabaseInitializer
createInitializer
(
DatabaseInitializationSettings
settings
);
private
int
numberOfRows
(
String
sql
)
{
return
new
JdbcTemplate
(
this
.
dataSource
).
queryForObject
(
sql
,
Integer
.
class
);
}
protected
abstract
int
numberOfRows
(
String
sql
);
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment