Skip to content

Commit 5a2d564

Browse files
Merge pull request #13 from ergon/feature/jooq_metamodel_from_yml
add adamGenerateJooqMetamodel
2 parents 2cd816b + af835f3 commit 5a2d564

File tree

10 files changed

+516
-17
lines changed

10 files changed

+516
-17
lines changed

.gitignore

+4
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,7 @@ gradle-plugin-test/gradle/
88
gradle-plugin-test/gradlew*
99
gradle.properties
1010
local.properties
11+
bin/
12+
.settings/
13+
.project
14+
.classpath

gradle-plugin/build.gradle

+1
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ sourceCompatibility = 21
1313
dependencies {
1414
implementation gradleApi()
1515
implementation project(':core')
16+
implementation group: 'org.jooq', name: 'jooq-codegen', version: '3.19.11'
1617
}
1718

1819
apply from: "${rootProject.projectDir}/common.gradle"
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,45 @@
11
package ch.ergon.adam.gradleplugin;
22

3-
import ch.ergon.adam.gradleplugin.tasks.*;
3+
import javax.annotation.Nonnull;
4+
45
import org.gradle.api.Plugin;
56
import org.gradle.api.Project;
67
import org.gradle.api.Task;
78

8-
import javax.annotation.Nonnull;
9+
import ch.ergon.adam.gradleplugin.tasks.CleanDbTask;
10+
import ch.ergon.adam.gradleplugin.tasks.ExportGitHistoryTask;
11+
import ch.ergon.adam.gradleplugin.tasks.ExportMigrationScriptsTask;
12+
import ch.ergon.adam.gradleplugin.tasks.ExportTargetVersionTask;
13+
import ch.ergon.adam.gradleplugin.tasks.GenerateJooqMetamodelTask;
14+
import ch.ergon.adam.gradleplugin.tasks.MigrateDBTask;
915

1016
public class AdamPlugin implements Plugin<Project> {
1117

12-
public static final String ADAM_EXTENSION = "adam";
18+
public static final String ADAM_EXTENSION = "adam";
19+
20+
@Override
21+
public void apply(@Nonnull Project project) {
1322

14-
@Override
15-
public void apply(@Nonnull Project project) {
23+
project.getExtensions().create(ADAM_EXTENSION, AdamExtension.class, project);
1624

17-
project.getExtensions().create(ADAM_EXTENSION, AdamExtension.class, project);
25+
project.getTasks().create("adamExportMigrationScripts", ExportMigrationScriptsTask.class)
26+
.setGroup(ADAM_EXTENSION);
1827

19-
project.getTasks().create("adamExportMigrationScripts", ExportMigrationScriptsTask.class).setGroup(ADAM_EXTENSION);
28+
project.getTasks().create("adamExportGitHistory", ExportGitHistoryTask.class).setGroup(ADAM_EXTENSION);
2029

21-
project.getTasks().create("adamExportGitHistory", ExportGitHistoryTask.class).setGroup(ADAM_EXTENSION);
30+
project.getTasks().create("adamExportTargetVersion", ExportTargetVersionTask.class).setGroup(ADAM_EXTENSION);
2231

23-
project.getTasks().create("adamExportTargetVersion", ExportTargetVersionTask.class).setGroup(ADAM_EXTENSION);
32+
project.getTasks().create("adamGenerateJooqMetamodel", GenerateJooqMetamodelTask.class)
33+
.setGroup(ADAM_EXTENSION);
2434

25-
Task adamExportTask = project.getTasks().create("adamExport", Task.class);
26-
adamExportTask.setGroup(ADAM_EXTENSION);
27-
adamExportTask.dependsOn("adamExportTargetVersion", "adamExportGitHistory", "adamExportMigrationScripts");
35+
Task adamExportTask = project.getTasks().create("adamExport", Task.class);
36+
adamExportTask.setGroup(ADAM_EXTENSION);
37+
adamExportTask.dependsOn("adamExportTargetVersion", "adamExportGitHistory", "adamExportMigrationScripts");
2838

29-
Task migrateDbTask = project.getTasks().create("adamMigrateDb", MigrateDBTask.class);
30-
migrateDbTask.setGroup(ADAM_EXTENSION);
31-
migrateDbTask.dependsOn(adamExportTask);
39+
Task migrateDbTask = project.getTasks().create("adamMigrateDb", MigrateDBTask.class);
40+
migrateDbTask.setGroup(ADAM_EXTENSION);
41+
migrateDbTask.dependsOn(adamExportTask);
3242

33-
project.getTasks().create("adamCleanDb", CleanDbTask.class).setGroup(ADAM_EXTENSION);
34-
}
43+
project.getTasks().create("adamCleanDb", CleanDbTask.class).setGroup(ADAM_EXTENSION);
44+
}
3545
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
package ch.ergon.adam.gradleplugin.tasks;
2+
3+
import java.nio.file.Path;
4+
import java.nio.file.Paths;
5+
6+
import org.gradle.api.DefaultTask;
7+
import org.gradle.api.file.Directory;
8+
import org.gradle.api.tasks.Input;
9+
import org.gradle.api.tasks.Optional;
10+
import org.gradle.api.tasks.TaskAction;
11+
12+
import ch.ergon.adam.gradleplugin.util.AdamJooqMetamodelGenerator;
13+
14+
public class GenerateJooqMetamodelTask extends DefaultTask {
15+
16+
@Input
17+
@Optional
18+
private String jooqConfig;
19+
20+
@Input
21+
private String packageName;
22+
23+
@Input
24+
private String outputPath;
25+
26+
@Input
27+
private String source;
28+
29+
@TaskAction
30+
public void generateJooqMetamodel() throws Exception {
31+
Path output = getProject().getLayout().getProjectDirectory().dir(outputPath).getAsFile().toPath();
32+
AdamJooqMetamodelGenerator generator = new AdamJooqMetamodelGenerator(packageName, output, getSource(),
33+
jooqConfig);
34+
generator.run();
35+
}
36+
37+
public String getJooqConfig() {
38+
return jooqConfig;
39+
}
40+
41+
public void setJooqConfig(String jooqConfig) {
42+
this.jooqConfig = jooqConfig;
43+
}
44+
45+
public String getPackageName() {
46+
return packageName;
47+
}
48+
49+
public void setPackageName(String packageName) {
50+
this.packageName = packageName;
51+
}
52+
53+
public String getOutputPath() {
54+
return outputPath;
55+
}
56+
57+
public void setOutputPath(String outputPath) {
58+
this.outputPath = outputPath;
59+
}
60+
61+
public String getSource() {
62+
return source;
63+
}
64+
65+
public void setSource(String source) {
66+
this.source = source;
67+
}
68+
69+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,186 @@
1+
package ch.ergon.adam.gradleplugin.util;
2+
3+
import java.sql.SQLException;
4+
import java.util.ArrayList;
5+
import java.util.List;
6+
import java.util.function.Consumer;
7+
import java.util.function.Predicate;
8+
9+
import org.jooq.DSLContext;
10+
import org.jooq.impl.DSL;
11+
import org.jooq.meta.AbstractDatabase;
12+
import org.jooq.meta.ArrayDefinition;
13+
import org.jooq.meta.CatalogDefinition;
14+
import org.jooq.meta.DefaultEnumDefinition;
15+
import org.jooq.meta.DefaultRelations;
16+
import org.jooq.meta.DomainDefinition;
17+
import org.jooq.meta.EnumDefinition;
18+
import org.jooq.meta.PackageDefinition;
19+
import org.jooq.meta.RoutineDefinition;
20+
import org.jooq.meta.SchemaDefinition;
21+
import org.jooq.meta.SequenceDefinition;
22+
import org.jooq.meta.TableDefinition;
23+
import org.jooq.meta.UDTDefinition;
24+
import org.jooq.meta.XMLSchemaCollectionDefinition;
25+
26+
import ch.ergon.adam.core.db.SourceAndSinkFactory;
27+
import ch.ergon.adam.core.db.schema.Field;
28+
import ch.ergon.adam.core.db.schema.ForeignKey;
29+
import ch.ergon.adam.core.db.schema.Index;
30+
import ch.ergon.adam.core.db.schema.Schema;
31+
import ch.ergon.adam.core.db.schema.Table;
32+
33+
public class AdamDatabase extends AbstractDatabase {
34+
public static final String SOURCE_PROPERTY = "source";
35+
private Schema schema;
36+
private SchemaDefinition schemaDefinition;
37+
38+
@Override
39+
protected DSLContext create0() {
40+
return DSL.using(getConnection());
41+
}
42+
43+
@Override
44+
protected void loadPrimaryKeys(DefaultRelations r) throws SQLException {
45+
handleIndexes(i -> i.isPrimary(), i -> {
46+
TableDefinition td = getTable(i.getTable());
47+
String name = i.getName();
48+
for (Field field : i.getFields()) {
49+
r.addPrimaryKey(name, td, td.getColumn(field.getName()));
50+
}
51+
});
52+
}
53+
54+
@Override
55+
protected void loadUniqueKeys(DefaultRelations r) throws SQLException {
56+
handleIndexes(i -> i.isUnique() && !i.isPrimary(), i -> {
57+
TableDefinition td = getTable(i.getTable());
58+
String name = i.getName();
59+
for (Field field : i.getFields()) {
60+
r.addUniqueKey(name, td, td.getColumn(field.getName()));
61+
}
62+
});
63+
}
64+
65+
private void handleIndexes(Predicate<Index> filter, Consumer<Index> consumer) {
66+
for (Table table : schema.getTables()) {
67+
TableDefinition td = getTable(table);
68+
if (td == null) {
69+
// table is excluded from build
70+
continue;
71+
}
72+
table.getIndexes().stream().filter(filter).forEach(consumer);
73+
}
74+
75+
}
76+
77+
@Override
78+
protected void loadForeignKeys(DefaultRelations r) throws SQLException {
79+
for (Table table : schema.getTables()) {
80+
TableDefinition td = getTable(table);
81+
if (td == null) {
82+
// table is excluded from build
83+
continue;
84+
}
85+
for (ForeignKey fkey : table.getForeignKeys()) {
86+
TableDefinition target = getTable(fkey.getTargetIndex().getTable());
87+
if (target != null) {
88+
r.addForeignKey(fkey.getName(), td, td.getColumn(fkey.getField().getName()),
89+
fkey.getTargetIndex().getName(), target);
90+
}
91+
}
92+
}
93+
}
94+
95+
@Override
96+
protected void loadCheckConstraints(DefaultRelations r) throws SQLException {
97+
// not supported
98+
}
99+
100+
@Override
101+
protected List<CatalogDefinition> getCatalogs0() throws SQLException {
102+
ensureSchema();
103+
return mutableList(new CatalogDefinition(this, "", ""));
104+
}
105+
106+
@Override
107+
protected List<SchemaDefinition> getSchemata0() throws SQLException {
108+
ensureSchema();
109+
return mutableList(new SchemaDefinition(this, "", null));
110+
}
111+
112+
@Override
113+
protected List<SequenceDefinition> getSequences0() throws SQLException {
114+
// not supported
115+
return List.of();
116+
}
117+
118+
@Override
119+
protected List<TableDefinition> getTables0() throws SQLException {
120+
return schema.getTables().stream().map(t -> (TableDefinition) new AdamTableDefinition(schemaDefinition, t))
121+
.toList();
122+
}
123+
124+
@Override
125+
protected List<RoutineDefinition> getRoutines0() throws SQLException {
126+
// not supported
127+
return List.of();
128+
}
129+
130+
@Override
131+
protected List<PackageDefinition> getPackages0() throws SQLException {
132+
// not supported
133+
return List.of();
134+
}
135+
136+
@Override
137+
protected List<EnumDefinition> getEnums0() throws SQLException {
138+
return schema.getEnums().stream().map(e -> {
139+
DefaultEnumDefinition definition = new DefaultEnumDefinition(schemaDefinition, e.getName(), null);
140+
definition.addLiterals(e.getValues());
141+
return (EnumDefinition) definition;
142+
}).toList();
143+
}
144+
145+
@Override
146+
protected List<DomainDefinition> getDomains0() throws SQLException {
147+
// not supported
148+
return List.of();
149+
}
150+
151+
@Override
152+
protected List<XMLSchemaCollectionDefinition> getXMLSchemaCollections0() throws SQLException {
153+
// not supported
154+
return List.of();
155+
}
156+
157+
@Override
158+
protected List<UDTDefinition> getUDTs0() throws SQLException {
159+
// not supported
160+
return List.of();
161+
}
162+
163+
@Override
164+
protected List<ArrayDefinition> getArrays0() throws SQLException {
165+
// not supported
166+
return List.of();
167+
}
168+
169+
private TableDefinition getTable(Table table) {
170+
return getTable(schemaDefinition, table.getName());
171+
}
172+
173+
private <T> List<T> mutableList(T value) {
174+
List<T> list = new ArrayList<>();
175+
list.add(value);
176+
return list;
177+
}
178+
179+
private void ensureSchema() {
180+
if (schema == null) {
181+
String source = (String) getProperties().get(SOURCE_PROPERTY);
182+
schema = SourceAndSinkFactory.getInstance().getSource(source).getSchema();
183+
schemaDefinition = new SchemaDefinition(this, "", null);
184+
}
185+
}
186+
}

0 commit comments

Comments
 (0)