Skip to content
This repository was archived by the owner on Oct 24, 2020. It is now read-only.

Commit 149b88c

Browse files
committed
Add the InitialScriptLoader class to load a import.sql file on startup
1 parent b082b60 commit 149b88c

File tree

16 files changed

+451
-27
lines changed

16 files changed

+451
-27
lines changed

README.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ Quarkus Extension for Doma provides the following features:
77

88
- Hot reload
99
- Automatic bean register
10+
- Automatic SQL execution on startup
1011
- Configuration
1112
- Support for native images
1213

@@ -18,6 +19,10 @@ In development mode, SQL and Script files are hot reloaded.
1819

1920
Our extension registers all DAO beans to the Quarkus CDI container automatically.
2021

22+
### Automatic SQL import on startup
23+
24+
Our extension executes ``import.sql`` automatically when Doma starts.
25+
2126
### Configuration
2227

2328
You can write the following configurations in your application.properties file:
@@ -32,6 +37,7 @@ quarkus.doma.batch-size=0
3237
quarkus.doma.fetch-size=0
3338
quarkus.doma.max-rows=0
3439
quarkus.doma.query-timeout=0
40+
quarkus-doma_quarkus.doma.sql-load-script=import.sql
3541
3642
quarkus.doma.log.sql=false
3743
quarkus.doma.log.dao=false

deployment/src/main/java/org/seasar/doma/quarkus/deployment/DomaConfigurationMerger.java

Lines changed: 54 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,46 @@
11
package org.seasar.doma.quarkus.deployment;
22

33
import io.quarkus.agroal.deployment.JdbcDataSourceBuildItem;
4+
import io.quarkus.deployment.builditem.ApplicationArchivesBuildItem;
5+
import io.quarkus.deployment.builditem.LaunchModeBuildItem;
6+
import io.quarkus.runtime.LaunchMode;
7+
import java.nio.file.Files;
8+
import java.nio.file.Path;
49
import java.util.List;
510
import java.util.Objects;
611
import java.util.Optional;
712
import java.util.stream.Stream;
813
import org.jboss.logging.Logger;
914
import org.seasar.doma.quarkus.runtime.DomaConfiguration;
15+
import org.seasar.doma.quarkus.runtime.InitialScript;
1016

1117
public class DomaConfigurationMerger {
1218

1319
private static final Logger LOGGER = Logger.getLogger(DomaConfigurationMerger.class);
1420

1521
private final DomaConfiguration configuration;
1622
private final List<JdbcDataSourceBuildItem> dataSources;
23+
private final ApplicationArchivesBuildItem applicationArchives;
24+
private final LaunchModeBuildItem launchMode;
1725

1826
DomaConfigurationMerger(
19-
DomaConfiguration configuration, List<JdbcDataSourceBuildItem> dataSources) {
27+
DomaConfiguration configuration,
28+
List<JdbcDataSourceBuildItem> dataSources,
29+
ApplicationArchivesBuildItem applicationArchives,
30+
LaunchModeBuildItem launchMode) {
2031
this.configuration = Objects.requireNonNull(configuration);
2132
this.dataSources = Objects.requireNonNull(dataSources);
33+
this.applicationArchives = Objects.requireNonNull(applicationArchives);
34+
this.launchMode = Objects.requireNonNull(launchMode);
2235
}
2336

2437
void merge() {
38+
mergeDataSourceDependentItems();
39+
mergeSqlLoadScript();
40+
LOGGER.debugf("configuration: %s", configuration);
41+
}
42+
43+
private void mergeDataSourceDependentItems() {
2544
Optional<String> dataSourceName = configuration.datasourceName;
2645
Optional<DomaConfiguration.DialectType> dialect = configuration.dialect;
2746

@@ -38,11 +57,10 @@ void merge() {
3857
configuration.dialect = Optional.of(inferDialectType(dbKind));
3958
} else {
4059
throw new IllegalStateException(
41-
"The quarkus.doma.datasource-name \""
42-
+ dataSourceName.get()
43-
+ "\" is found, but quarkus.datasource named \""
44-
+ dataSourceName.get()
45-
+ "\" is not found.");
60+
String.format(
61+
"'quarkus.doma.datasource-name=%s' is found, "
62+
+ "but 'quarkus.datasource.\"datasource-name\"' is not found.",
63+
dataSourceName.get()));
4664
}
4765
}
4866
} else {
@@ -65,8 +83,6 @@ void merge() {
6583
+ "Specify the configuration in your application.properties.");
6684
}
6785
}
68-
69-
LOGGER.debugf("configuration: %s", configuration);
7086
}
7187

7288
private DomaConfiguration.DialectType inferDialectType(String dbKind) {
@@ -89,4 +105,34 @@ private DomaConfiguration.DialectType inferDialectType(String dbKind) {
89105
+ "\". The dbKind is illegal or not supported.");
90106
}
91107
}
108+
109+
private void mergeSqlLoadScript() {
110+
Optional<String> sqlLoadScript = configuration.sqlLoadScript;
111+
if (sqlLoadScript.isPresent()) {
112+
if (sqlLoadScript.get().equals(InitialScript.NO_FILE)) {
113+
configuration.sqlLoadScript = Optional.empty();
114+
} else {
115+
Path path = applicationArchives.getRootArchive().getChildPath(sqlLoadScript.get());
116+
if (path == null || Files.isDirectory(path)) {
117+
throw new IllegalStateException(
118+
String.format(
119+
"Can't find the file referenced in 'quarkus.doma.sql-load-script=%s'. "
120+
+ "Remove property or add file to your path.",
121+
sqlLoadScript.get()));
122+
}
123+
}
124+
} else {
125+
LaunchMode mode = launchMode.getLaunchMode();
126+
if (mode == LaunchMode.DEVELOPMENT || mode == LaunchMode.TEST) {
127+
Path path = applicationArchives.getRootArchive().getChildPath(InitialScript.DEFAULT);
128+
if (path == null || Files.isDirectory(path)) {
129+
configuration.sqlLoadScript = Optional.empty();
130+
} else {
131+
configuration.sqlLoadScript = Optional.of(InitialScript.DEFAULT);
132+
}
133+
} else {
134+
configuration.sqlLoadScript = Optional.empty();
135+
}
136+
}
137+
}
92138
}

deployment/src/main/java/org/seasar/doma/quarkus/deployment/DomaProcessor.java

Lines changed: 52 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -10,18 +10,24 @@
1010
import io.quarkus.deployment.annotations.BuildProducer;
1111
import io.quarkus.deployment.annotations.BuildStep;
1212
import io.quarkus.deployment.annotations.Record;
13+
import io.quarkus.deployment.builditem.ApplicationArchivesBuildItem;
1314
import io.quarkus.deployment.builditem.FeatureBuildItem;
15+
import io.quarkus.deployment.builditem.HotDeploymentWatchedFileBuildItem;
1416
import io.quarkus.deployment.builditem.LaunchModeBuildItem;
1517
import io.quarkus.deployment.builditem.nativeimage.NativeImageResourceBuildItem;
1618
import io.quarkus.deployment.builditem.nativeimage.ReflectiveClassBuildItem;
1719
import io.quarkus.runtime.LaunchMode;
20+
import java.util.ArrayList;
21+
import java.util.Collections;
1822
import java.util.List;
23+
import java.util.Optional;
1924
import org.jboss.jandex.DotName;
2025
import org.jboss.jandex.IndexView;
2126
import org.seasar.doma.DaoImplementation;
2227
import org.seasar.doma.quarkus.runtime.DomaConfiguration;
2328
import org.seasar.doma.quarkus.runtime.DomaProducer;
2429
import org.seasar.doma.quarkus.runtime.DomaRecorder;
30+
import org.seasar.doma.quarkus.runtime.InitialScriptLoader;
2531

2632
class DomaProcessor {
2733

@@ -33,41 +39,69 @@ FeatureBuildItem feature() {
3339
}
3440

3541
@BuildStep
36-
NativeImageResourceBuildItem resources() {
37-
DomaResourceScanner scanner = new DomaResourceScanner();
38-
List<String> resources = scanner.scan();
39-
return new NativeImageResourceBuildItem(resources);
42+
AdditionalBeanBuildItem additionalBeans() {
43+
return new AdditionalBeanBuildItem(DomaProducer.class);
4044
}
4145

4246
@BuildStep
43-
ReflectiveClassBuildItem classes(BeanArchiveIndexBuildItem beanArchiveIndex) {
44-
IndexView indexView = beanArchiveIndex.getIndex();
45-
DomaClassScanner scanner = new DomaClassScanner(indexView);
46-
List<String> classes = scanner.scan();
47-
return new ReflectiveClassBuildItem(true, true, classes.toArray(new String[0]));
47+
BeanDefiningAnnotationBuildItem beanDefiningAnnotation() {
48+
return new BeanDefiningAnnotationBuildItem(
49+
DotName.createSimple(DaoImplementation.class.getName()));
4850
}
4951

5052
@BuildStep
51-
AdditionalBeanBuildItem additionalBeans() {
52-
return new AdditionalBeanBuildItem(DomaProducer.class);
53+
MergedConfigurationBuildItem mergedConfiguration(
54+
DomaConfiguration configuration,
55+
List<JdbcDataSourceBuildItem> dataSources,
56+
ApplicationArchivesBuildItem applicationArchives,
57+
LaunchModeBuildItem launchMode) {
58+
DomaConfigurationMerger merger =
59+
new DomaConfigurationMerger(configuration, dataSources, applicationArchives, launchMode);
60+
merger.merge();
61+
return new MergedConfigurationBuildItem(configuration);
5362
}
5463

5564
@BuildStep
56-
BeanDefiningAnnotationBuildItem beanDefiningAnnotation() {
57-
return new BeanDefiningAnnotationBuildItem(
58-
DotName.createSimple(DaoImplementation.class.getName()));
65+
List<HotDeploymentWatchedFileBuildItem> hotDeploymentWatchedFile(
66+
MergedConfigurationBuildItem mergedConfiguration) {
67+
DomaConfiguration configuration = mergedConfiguration.getConfiguration();
68+
Optional<String> sqlLoadScript = configuration.sqlLoadScript;
69+
return sqlLoadScript
70+
.map(it -> Collections.singletonList(new HotDeploymentWatchedFileBuildItem(it)))
71+
.orElse(Collections.emptyList());
72+
}
73+
74+
@BuildStep
75+
NativeImageResourceBuildItem resources(MergedConfigurationBuildItem mergedConfiguration) {
76+
List<String> resources = new ArrayList<>();
77+
DomaConfiguration configuration = mergedConfiguration.getConfiguration();
78+
Optional<String> sqlLoadScript = configuration.sqlLoadScript;
79+
sqlLoadScript.ifPresent(resources::add);
80+
DomaResourceScanner scanner = new DomaResourceScanner();
81+
List<String> scannedResources = scanner.scan();
82+
resources.addAll(scannedResources);
83+
return new NativeImageResourceBuildItem(resources);
84+
}
85+
86+
@BuildStep
87+
ReflectiveClassBuildItem classes(BeanArchiveIndexBuildItem beanArchiveIndex) {
88+
List<String> classes = new ArrayList<>();
89+
IndexView indexView = beanArchiveIndex.getIndex();
90+
DomaClassScanner scanner = new DomaClassScanner(indexView);
91+
List<String> scannedClasses = scanner.scan();
92+
classes.add(InitialScriptLoader.class.getName());
93+
classes.addAll(scannedClasses);
94+
return new ReflectiveClassBuildItem(true, true, classes.toArray(new String[0]));
5995
}
6096

6197
@BuildStep
6298
@Record(STATIC_INIT)
6399
void configure(
64100
DomaRecorder recorder,
65-
DomaConfiguration configuration,
66-
List<JdbcDataSourceBuildItem> dataSources,
101+
MergedConfigurationBuildItem mergedConfiguration,
67102
LaunchModeBuildItem launchMode,
68103
BuildProducer<BeanContainerListenerBuildItem> beanContainerListeners) {
69-
DomaConfigurationMerger merger = new DomaConfigurationMerger(configuration, dataSources);
70-
merger.merge();
104+
DomaConfiguration configuration = mergedConfiguration.getConfiguration();
71105
beanContainerListeners.produce(
72106
new BeanContainerListenerBuildItem(recorder.configure(configuration)));
73107
if (launchMode.getLaunchMode() == LaunchMode.DEVELOPMENT) {
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
package org.seasar.doma.quarkus.deployment;
2+
3+
import io.quarkus.builder.item.SimpleBuildItem;
4+
import java.util.Objects;
5+
import org.seasar.doma.quarkus.runtime.DomaConfiguration;
6+
7+
public final class MergedConfigurationBuildItem extends SimpleBuildItem {
8+
9+
private final DomaConfiguration configuration;
10+
11+
public MergedConfigurationBuildItem(DomaConfiguration configuration) {
12+
this.configuration = Objects.requireNonNull(configuration);
13+
}
14+
15+
public DomaConfiguration getConfiguration() {
16+
return configuration;
17+
}
18+
}
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
package org.seasar.doma.quarkus.deployment;
2+
3+
import static org.junit.jupiter.api.Assertions.assertEquals;
4+
5+
import io.quarkus.test.QuarkusUnitTest;
6+
import java.sql.Connection;
7+
import java.sql.ResultSet;
8+
import java.sql.Statement;
9+
import javax.inject.Inject;
10+
import javax.sql.DataSource;
11+
import org.jboss.shrinkwrap.api.ShrinkWrap;
12+
import org.jboss.shrinkwrap.api.asset.StringAsset;
13+
import org.jboss.shrinkwrap.api.spec.JavaArchive;
14+
import org.junit.jupiter.api.Test;
15+
import org.junit.jupiter.api.extension.RegisterExtension;
16+
17+
public class InitialScriptLoaderCustomTest {
18+
19+
@RegisterExtension
20+
static QuarkusUnitTest runner =
21+
new QuarkusUnitTest()
22+
.setArchiveProducer(
23+
() ->
24+
ShrinkWrap.create(JavaArchive.class)
25+
.add(
26+
new StringAsset(
27+
"quarkus.datasource.db-kind=h2\n"
28+
+ "quarkus.datasource.username=USERNAME-NAMED\n"
29+
+ "quarkus.datasource.jdbc.url=jdbc:h2:tcp://localhost/mem:testing\n"
30+
+ "quarkus.datasource.jdbc.driver=org.h2.Driver\n"
31+
+ "quarkus.doma.sql-load-script=import2.sql\n"
32+
+ "quarkus.doma.log.sql=true\n"),
33+
"application.properties")
34+
.addAsResource("import2.sql"));
35+
36+
@Inject DataSource dataSource;
37+
38+
@Test
39+
public void test() throws Exception {
40+
int count = 0;
41+
try (Connection connection = dataSource.getConnection()) {
42+
try (Statement statement = connection.createStatement()) {
43+
try (ResultSet resultSet = statement.executeQuery("select id from department")) {
44+
while (resultSet.next()) {
45+
count++;
46+
}
47+
}
48+
}
49+
}
50+
assertEquals(2, count);
51+
}
52+
}
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
package org.seasar.doma.quarkus.deployment;
2+
3+
import static org.junit.jupiter.api.Assertions.assertEquals;
4+
5+
import io.quarkus.test.QuarkusUnitTest;
6+
import java.sql.Connection;
7+
import java.sql.ResultSet;
8+
import java.sql.Statement;
9+
import javax.inject.Inject;
10+
import javax.sql.DataSource;
11+
import org.jboss.shrinkwrap.api.ShrinkWrap;
12+
import org.jboss.shrinkwrap.api.asset.StringAsset;
13+
import org.jboss.shrinkwrap.api.spec.JavaArchive;
14+
import org.junit.jupiter.api.Test;
15+
import org.junit.jupiter.api.extension.RegisterExtension;
16+
17+
public class InitialScriptLoaderTest {
18+
19+
@RegisterExtension
20+
static QuarkusUnitTest runner =
21+
new QuarkusUnitTest()
22+
.setArchiveProducer(
23+
() ->
24+
ShrinkWrap.create(JavaArchive.class)
25+
.add(
26+
new StringAsset(
27+
"quarkus.datasource.db-kind=h2\n"
28+
+ "quarkus.datasource.username=USERNAME-NAMED\n"
29+
+ "quarkus.datasource.jdbc.url=jdbc:h2:tcp://localhost/mem:testing\n"
30+
+ "quarkus.datasource.jdbc.driver=org.h2.Driver\n"
31+
+ "quarkus.doma.log.sql=true\n"),
32+
"application.properties")
33+
.addAsResource("import.sql"));
34+
35+
@Inject DataSource dataSource;
36+
37+
@Test
38+
public void test() throws Exception {
39+
int count = 0;
40+
try (Connection connection = dataSource.getConnection()) {
41+
try (Statement statement = connection.createStatement()) {
42+
try (ResultSet resultSet = statement.executeQuery("select id from employee")) {
43+
while (resultSet.next()) {
44+
count++;
45+
}
46+
}
47+
}
48+
}
49+
assertEquals(2, count);
50+
}
51+
}

0 commit comments

Comments
 (0)