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

Commit bbd406e

Browse files
committed
Support multiple datasources
1 parent 095620f commit bbd406e

File tree

17 files changed

+653
-584
lines changed

17 files changed

+653
-584
lines changed

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

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

3+
import io.quarkus.runtime.annotations.ConfigDocMapKey;
4+
import io.quarkus.runtime.annotations.ConfigDocSection;
35
import io.quarkus.runtime.annotations.ConfigGroup;
46
import io.quarkus.runtime.annotations.ConfigItem;
57
import io.quarkus.runtime.annotations.ConfigRoot;
8+
import java.util.Map;
69
import java.util.Optional;
710
import org.seasar.doma.jdbc.Config;
811
import org.seasar.doma.jdbc.SqlLogType;
@@ -14,13 +17,15 @@ public class DomaBuildTimeConfig {
1417
public static final String SQL_LOAD_SCRIPT_DEFAULT = "import.sql";
1518
public static final String SQL_LOAD_SCRIPT_NO_FILE = "no-file";
1619

17-
/**
18-
* The SQL dialect.
19-
*
20-
* @see Config#getDialect()
21-
*/
22-
@ConfigItem(defaultValueDocumentation = "depends on 'quarkus.datasource.db-kind'")
23-
public Optional<DomaSettings.DialectType> dialect;
20+
/** The default datasource. */
21+
@ConfigItem(name = ConfigItem.PARENT)
22+
public DataSourceBuildTimeConfig defaultDataSource;
23+
24+
/** Additional named datasources. */
25+
@ConfigDocSection
26+
@ConfigDocMapKey("datasource-name")
27+
@ConfigItem(name = ConfigItem.PARENT)
28+
public Map<String, DataSourceBuildTimeConfig> namedDataSources;
2429

2530
/**
2631
* The SQL file repository.
@@ -46,63 +51,83 @@ public class DomaBuildTimeConfig {
4651
@ConfigItem(defaultValue = "none")
4752
public SqlLogType exceptionSqlLogType;
4853

49-
/**
50-
* The name of the data source.
51-
*
52-
* @see Config#getDataSourceName()
53-
*/
54-
@ConfigItem(
55-
defaultValueDocumentation = "depends on 'quarkus.datasource.\"datasource-name\".db-kind'")
56-
public Optional<String> datasourceName;
57-
58-
/**
59-
* The batch size.
60-
*
61-
* @see Config#getBatchSize()
62-
*/
63-
@ConfigItem(defaultValue = "0")
64-
public int batchSize;
65-
66-
/**
67-
* The fetch size.
68-
*
69-
* @see Config#getFetchSize()
70-
*/
71-
@ConfigItem(defaultValue = "0")
72-
public int fetchSize;
73-
74-
/**
75-
* The max rows.
76-
*
77-
* @see Config#getMaxRows()
78-
*/
79-
@ConfigItem(defaultValue = "0")
80-
public int maxRows;
81-
82-
/**
83-
* The query timeout limit in seconds.
84-
*
85-
* @see Config#getQueryTimeout()
86-
*/
87-
@ConfigItem(defaultValue = "0")
88-
public int queryTimeout;
89-
90-
/**
91-
* Name of the file containing the SQL statements to execute when Doma starts. Its default value
92-
* differs depending on the Quarkus launch mode:
93-
*
94-
* <p>* In dev and test modes, it defaults to `import.sql`. Simply add an `import.sql` file in the
95-
* root of your resources directory and it will be picked up without having to set this property.
96-
* Pass `no-file` to force Doma to ignore the SQL import file. * In production mode, it defaults
97-
* to `no-file`. It means Doma won't try to execute any SQL import file by default. Pass an
98-
* explicit value to force Doma to execute the SQL import file.
99-
*/
100-
@ConfigItem(defaultValueDocumentation = "import.sql in DEV, TEST ; no-file otherwise")
101-
public Optional<String> sqlLoadScript;
102-
10354
/** The log configuration. */
10455
@ConfigItem public LogBuildTimeConfig log;
10556

57+
@ConfigGroup
58+
public static class DataSourceBuildTimeConfig {
59+
/**
60+
* The SQL dialect.
61+
*
62+
* @see Config#getDialect()
63+
*/
64+
@ConfigItem(defaultValueDocumentation = "depends on 'quarkus.datasource.db-kind'")
65+
public Optional<DomaSettings.DialectType> dialect = Optional.empty();
66+
67+
/**
68+
* The batch size.
69+
*
70+
* @see Config#getBatchSize()
71+
*/
72+
@ConfigItem(defaultValue = "0")
73+
public int batchSize = 0;
74+
75+
/**
76+
* The fetch size.
77+
*
78+
* @see Config#getFetchSize()
79+
*/
80+
@ConfigItem(defaultValue = "0")
81+
public int fetchSize = 0;
82+
83+
/**
84+
* The max rows.
85+
*
86+
* @see Config#getMaxRows()
87+
*/
88+
@ConfigItem(defaultValue = "0")
89+
public int maxRows = 0;
90+
91+
/**
92+
* The query timeout limit in seconds.
93+
*
94+
* @see Config#getQueryTimeout()
95+
*/
96+
@ConfigItem(defaultValue = "0")
97+
public int queryTimeout = 0;
98+
99+
/**
100+
* Name of the file containing the SQL statements to execute when Doma starts. Its default value
101+
* differs depending on the Quarkus launch mode:
102+
*
103+
* <p>* In dev and test modes, it defaults to `import.sql`. Simply add an `import.sql` file in
104+
* the root of your resources directory and it will be picked up without having to set this
105+
* property. Pass `no-file` to force Doma to ignore the SQL import file. * In production mode,
106+
* it defaults to `no-file`. It means Doma won't try to execute any SQL import file by default.
107+
* Pass an explicit value to force Doma to execute the SQL import file.
108+
*/
109+
@ConfigItem(defaultValueDocumentation = "import.sql in DEV, TEST ; no-file otherwise")
110+
public Optional<String> sqlLoadScript = Optional.empty();
111+
112+
@Override
113+
public String toString() {
114+
return "DataSourceBuildTimeConfig{"
115+
+ "dialect="
116+
+ dialect
117+
+ ", batchSize="
118+
+ batchSize
119+
+ ", fetchSize="
120+
+ fetchSize
121+
+ ", maxRows="
122+
+ maxRows
123+
+ ", queryTimeout="
124+
+ queryTimeout
125+
+ ", sqlLoadScript="
126+
+ sqlLoadScript
127+
+ '}';
128+
}
129+
}
130+
106131
@ConfigGroup
107132
public static class LogBuildTimeConfig {
108133

@@ -130,25 +155,17 @@ public String toString() {
130155

131156
@Override
132157
public String toString() {
133-
return "DomaConfiguration{"
134-
+ "dialect="
135-
+ dialect
158+
return "DomaBuildTimeConfig{"
159+
+ "defaultDataSource="
160+
+ defaultDataSource
161+
+ ", namedDataSources="
162+
+ namedDataSources
136163
+ ", sqlFileRepository="
137164
+ sqlFileRepository
138165
+ ", naming="
139166
+ naming
140167
+ ", exceptionSqlLogType="
141168
+ exceptionSqlLogType
142-
+ ", datasourceName="
143-
+ datasourceName
144-
+ ", batchSize="
145-
+ batchSize
146-
+ ", fetchSize="
147-
+ fetchSize
148-
+ ", maxRows="
149-
+ maxRows
150-
+ ", queryTimeout="
151-
+ queryTimeout
152169
+ ", log="
153170
+ log
154171
+ '}';

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

Lines changed: 90 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,16 @@
11
package org.seasar.doma.quarkus.deployment;
22

33
import static io.quarkus.deployment.annotations.ExecutionTime.STATIC_INIT;
4+
import static java.util.stream.Collectors.toList;
45

6+
import io.quarkus.agroal.DataSource;
57
import io.quarkus.agroal.deployment.JdbcDataSourceBuildItem;
68
import io.quarkus.arc.deployment.AdditionalBeanBuildItem;
79
import io.quarkus.arc.deployment.BeanArchiveIndexBuildItem;
810
import io.quarkus.arc.deployment.BeanContainerListenerBuildItem;
911
import io.quarkus.arc.deployment.BeanDefiningAnnotationBuildItem;
12+
import io.quarkus.arc.deployment.SyntheticBeanBuildItem;
13+
import io.quarkus.deployment.annotations.BuildProducer;
1014
import io.quarkus.deployment.annotations.BuildStep;
1115
import io.quarkus.deployment.annotations.Record;
1216
import io.quarkus.deployment.builditem.ApplicationArchivesBuildItem;
@@ -17,11 +21,20 @@
1721
import io.quarkus.deployment.builditem.nativeimage.ReflectiveClassBuildItem;
1822
import java.util.ArrayList;
1923
import java.util.List;
20-
import java.util.Optional;
24+
import java.util.Objects;
25+
import java.util.function.Function;
26+
import java.util.function.Supplier;
27+
import javax.enterprise.context.Dependent;
28+
import javax.enterprise.inject.Default;
2129
import org.jboss.jandex.DotName;
2230
import org.seasar.doma.DaoImplementation;
31+
import org.seasar.doma.jdbc.Config;
32+
import org.seasar.doma.jdbc.criteria.Entityql;
33+
import org.seasar.doma.jdbc.criteria.NativeSql;
34+
import org.seasar.doma.quarkus.runtime.DomaConfig;
2335
import org.seasar.doma.quarkus.runtime.DomaProducer;
2436
import org.seasar.doma.quarkus.runtime.DomaRecorder;
37+
import org.seasar.doma.quarkus.runtime.DomaSettings;
2538
import org.seasar.doma.quarkus.runtime.JtaRequiresNewController;
2639
import org.seasar.doma.quarkus.runtime.ScriptExecutor;
2740
import org.seasar.doma.quarkus.runtime.UnsupportedTransactionManager;
@@ -38,7 +51,10 @@ FeatureBuildItem feature() {
3851
@BuildStep
3952
AdditionalBeanBuildItem additionalBeans() {
4053
return new AdditionalBeanBuildItem(
41-
DomaProducer.class, JtaRequiresNewController.class, UnsupportedTransactionManager.class);
54+
DomaProducer.class,
55+
JtaRequiresNewController.class,
56+
ScriptExecutor.class,
57+
UnsupportedTransactionManager.class);
4258
}
4359

4460
@BuildStep
@@ -59,22 +75,21 @@ DomaSettingsBuildItem domaSettings(
5975
}
6076

6177
@BuildStep
62-
Optional<HotDeploymentWatchedFileBuildItem> hotDeploymentWatchedFile(
63-
DomaSettingsBuildItem settings) {
64-
var sqlLoadScript = settings.getSettings().sqlLoadScript;
65-
if (sqlLoadScript == null) {
66-
return Optional.empty();
67-
}
68-
return Optional.of(new HotDeploymentWatchedFileBuildItem(sqlLoadScript));
78+
List<HotDeploymentWatchedFileBuildItem> hotDeploymentWatchedFile(DomaSettingsBuildItem settings) {
79+
return settings.getSettings().dataSources.stream()
80+
.map(it -> it.sqlLoadScript)
81+
.filter(Objects::nonNull)
82+
.map(HotDeploymentWatchedFileBuildItem::new)
83+
.collect(toList());
6984
}
7085

7186
@BuildStep
7287
NativeImageResourceBuildItem nativeImageResources(DomaSettingsBuildItem settings) {
7388
List<String> resources = new ArrayList<>();
74-
var sqlLoadScript = settings.getSettings().sqlLoadScript;
75-
if (sqlLoadScript != null) {
76-
resources.add(sqlLoadScript);
77-
}
89+
settings.getSettings().dataSources.stream()
90+
.map(it -> it.sqlLoadScript)
91+
.filter(Objects::nonNull)
92+
.forEach(resources::add);
7893
var scanner = new DomaResourceScanner();
7994
var scannedResources = scanner.scan();
8095
resources.addAll(scannedResources);
@@ -94,9 +109,67 @@ ReflectiveClassBuildItem reflectiveClasses(BeanArchiveIndexBuildItem beanArchive
94109

95110
@BuildStep
96111
@Record(STATIC_INIT)
97-
BeanContainerListenerBuildItem beanContainerListener(
98-
DomaRecorder recorder, DomaSettingsBuildItem settings, LaunchModeBuildItem launchMode) {
99-
return new BeanContainerListenerBuildItem(
100-
recorder.configure(settings.getSettings(), launchMode.getLaunchMode()));
112+
void registerBeans(
113+
DomaRecorder recorder,
114+
LaunchModeBuildItem launchMode,
115+
DomaSettingsBuildItem settings,
116+
BuildProducer<BeanContainerListenerBuildItem> beanContainerListeners,
117+
BuildProducer<SyntheticBeanBuildItem> syntheticBeans) {
118+
119+
var domaSettings = settings.getSettings();
120+
121+
beanContainerListeners.produce(
122+
new BeanContainerListenerBuildItem(
123+
recorder.configure(domaSettings, launchMode.getLaunchMode())));
124+
125+
registerSyntheticBeans(
126+
domaSettings.dataSources,
127+
syntheticBeans,
128+
DomaConfig.class,
129+
Config.class,
130+
recorder::configureConfig);
131+
132+
registerSyntheticBeans(
133+
domaSettings.dataSources,
134+
syntheticBeans,
135+
Entityql.class,
136+
Entityql.class,
137+
recorder::configureEntityql);
138+
139+
registerSyntheticBeans(
140+
domaSettings.dataSources,
141+
syntheticBeans,
142+
NativeSql.class,
143+
NativeSql.class,
144+
recorder::configureNativeSql);
145+
}
146+
147+
private <BEAN> void registerSyntheticBeans(
148+
List<DomaSettings.DataSourceSettings> dataSourceSettingsList,
149+
BuildProducer<SyntheticBeanBuildItem> syntheticBeans,
150+
Class<?> implClazz,
151+
Class<BEAN> typeClazz,
152+
Function<DomaSettings.DataSourceSettings, Supplier<BEAN>> supplierCreator) {
153+
dataSourceSettingsList.stream()
154+
.map(
155+
dataSourceSettings -> {
156+
var configurator =
157+
SyntheticBeanBuildItem.configure(implClazz)
158+
.addType(DotName.createSimple(typeClazz.getName()))
159+
.scope(Dependent.class)
160+
.unremovable()
161+
.supplier(supplierCreator.apply(dataSourceSettings));
162+
if (dataSourceSettings.isDefault) {
163+
configurator.addQualifier().annotation(Default.class).done();
164+
} else {
165+
configurator
166+
.addQualifier()
167+
.annotation(DataSource.class)
168+
.addValue("value", dataSourceSettings.name)
169+
.done();
170+
}
171+
return configurator.done();
172+
})
173+
.forEach(syntheticBeans::produce);
101174
}
102175
}

0 commit comments

Comments
 (0)