Skip to content

Commit 9a7bb2b

Browse files
committed
Model fot Generating Schema SQL
Initial model for generating schema SQL. Closes #1478
1 parent a30d01a commit 9a7bb2b

File tree

6 files changed

+315
-0
lines changed

6 files changed

+315
-0
lines changed

spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/RelationalMappingContext.java

+32
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,14 @@
1919
import org.springframework.data.mapping.context.MappingContext;
2020
import org.springframework.data.mapping.model.Property;
2121
import org.springframework.data.mapping.model.SimpleTypeHolder;
22+
import org.springframework.data.relational.core.mapping.schemasqlgeneration.ColumnModel;
23+
import org.springframework.data.relational.core.mapping.schemasqlgeneration.SchemaSQLGenerationDataModel;
24+
import org.springframework.data.relational.core.mapping.schemasqlgeneration.TableModel;
2225
import org.springframework.data.util.TypeInformation;
2326
import org.springframework.util.Assert;
2427

28+
import java.util.Iterator;
29+
2530
/**
2631
* {@link MappingContext} implementation.
2732
*
@@ -102,4 +107,31 @@ public NamingStrategy getNamingStrategy() {
102107
return this.namingStrategy;
103108
}
104109

110+
/**
111+
* Method to build a data model of Tables/Columns and their relationships
112+
* that will be used in SQL Generation.
113+
*/
114+
public SchemaSQLGenerationDataModel generateSchemaSQL() {
115+
116+
SchemaSQLGenerationDataModel model = new SchemaSQLGenerationDataModel();
117+
118+
for (RelationalPersistentEntity entity : getPersistentEntities()) {
119+
TableModel tableModel = new TableModel();
120+
tableModel.setName(entity.getTableName().getReference());
121+
122+
Iterator<BasicRelationalPersistentProperty> iter =
123+
entity.getPersistentProperties(Column.class).iterator();
124+
125+
while (iter.hasNext()) {
126+
BasicRelationalPersistentProperty p = iter.next();
127+
ColumnModel columnModel = new ColumnModel();
128+
columnModel.setName(p.getColumnName().getReference());
129+
columnModel.setType(p.getActualType());
130+
tableModel.getColumns().add(columnModel);
131+
}
132+
model.getTableData().add(tableModel);
133+
}
134+
135+
return model;
136+
}
105137
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
/*
2+
* Copyright 2023 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package org.springframework.data.relational.core.mapping.schemasqlgeneration;
17+
18+
/**
19+
* Class that models a Column for generating SQL for Schema generation.
20+
*
21+
* @author Kurt Niemi
22+
*/
23+
public class ColumnModel {
24+
private String name;
25+
private Class<?> type;
26+
private boolean nullable;
27+
28+
public String getName() {
29+
return name;
30+
}
31+
32+
public void setName(String name) {
33+
this.name = name;
34+
}
35+
36+
public Class<?> getType() {
37+
return type;
38+
}
39+
40+
public void setType(Class<?> type) {
41+
this.type = type;
42+
}
43+
44+
public boolean isNullable() {
45+
return nullable;
46+
}
47+
48+
public void setNullable(boolean nullable) {
49+
this.nullable = nullable;
50+
}
51+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
/*
2+
* Copyright 2023 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package org.springframework.data.relational.core.mapping.schemasqlgeneration;
17+
18+
/**
19+
* Class that models a Foreign Key relationship for generating SQL for Schema generation.
20+
*
21+
* @author Kurt Niemi
22+
*/
23+
public class ForeignKeyColumnModel {
24+
private TableModel foreignTable;
25+
private ColumnModel foreignColumn;
26+
private ColumnModel column;
27+
28+
public ForeignKeyColumnModel(TableModel foreignTable, ColumnModel foreignColumn, ColumnModel column) {
29+
this.foreignTable = foreignTable;
30+
this.foreignColumn = foreignColumn;
31+
this.column = column;
32+
}
33+
34+
public TableModel getForeignTable() {
35+
return foreignTable;
36+
}
37+
38+
public ColumnModel getForeignColumn() {
39+
return foreignColumn;
40+
}
41+
42+
public ColumnModel getColumn() {
43+
return column;
44+
}
45+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
/*
2+
* Copyright 2023 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package org.springframework.data.relational.core.mapping.schemasqlgeneration;
17+
18+
import java.util.ArrayList;
19+
import java.util.List;
20+
21+
/**
22+
* Model class that contains Table/Column information that can be used
23+
* to generate SQL for Schema generation.
24+
*
25+
* @author Kurt Niemi
26+
*/
27+
public class SchemaSQLGenerationDataModel {
28+
private List<TableModel> tableData = new ArrayList<TableModel>();
29+
30+
public List<TableModel> getTableData() {
31+
return tableData;
32+
}
33+
34+
public void setTableData(List<TableModel> tableData) {
35+
this.tableData = tableData;
36+
}
37+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
/*
2+
* Copyright 2023 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package org.springframework.data.relational.core.mapping.schemasqlgeneration;
17+
18+
import java.util.ArrayList;
19+
import java.util.List;
20+
21+
/**
22+
* Class that models a Table for generating SQL for Schema generation.
23+
*
24+
* @author Kurt Niemi
25+
*/
26+
public class TableModel {
27+
private String schema;
28+
private String name;
29+
private List<ColumnModel> columns = new ArrayList<ColumnModel>();
30+
private List<ColumnModel> keyColumns = new ArrayList<ColumnModel>();
31+
private List<ForeignKeyColumnModel> foreignKeyColumns = new ArrayList<ForeignKeyColumnModel>();
32+
33+
public String getSchema() {
34+
return schema;
35+
}
36+
37+
public void setSchema(String schema) {
38+
this.schema = schema;
39+
}
40+
41+
public String getName() {
42+
return name;
43+
}
44+
45+
public void setName(String name) {
46+
this.name = name;
47+
}
48+
49+
public List<ColumnModel> getColumns() {
50+
return columns;
51+
}
52+
53+
public void setColumns(List<ColumnModel> columns) {
54+
this.columns = columns;
55+
}
56+
57+
public List<ColumnModel> getKeyColumns() {
58+
return keyColumns;
59+
}
60+
61+
public void setKeyColumns(List<ColumnModel> keyColumns) {
62+
this.keyColumns = keyColumns;
63+
}
64+
65+
public List<ForeignKeyColumnModel> getForeignKeyColumns() {
66+
return foreignKeyColumns;
67+
}
68+
69+
public void setForeignKeyColumns(List<ForeignKeyColumnModel> foreignKeyColumns) {
70+
this.foreignKeyColumns = foreignKeyColumns;
71+
}
72+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
/*
2+
* Copyright 2023 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package org.springframework.data.relational.schemasqlgeneration;
17+
18+
import org.junit.jupiter.api.Test;
19+
import org.springframework.data.relational.core.mapping.Column;
20+
import org.springframework.data.relational.core.mapping.RelationalMappingContext;
21+
import org.springframework.data.relational.core.mapping.Table;
22+
import org.springframework.data.relational.core.mapping.schemasqlgeneration.SchemaSQLGenerationDataModel;
23+
import org.springframework.data.relational.core.mapping.schemasqlgeneration.TableModel;
24+
25+
import static org.assertj.core.api.Assertions.assertThat;
26+
27+
/**
28+
* Unit tests for the {@link SchemaSQLGenerationDataModel}.
29+
*
30+
* @author Kurt Niemi
31+
*/
32+
public class SchemaSQLGenerationDataModelTests {
33+
34+
@Test
35+
void testBasicModelGeneration() {
36+
RelationalMappingContext context = new RelationalMappingContext();
37+
context.getRequiredPersistentEntity(SchemaSQLGenerationDataModelTests.Luke.class);
38+
context.getRequiredPersistentEntity(SchemaSQLGenerationDataModelTests.Vader.class);
39+
40+
SchemaSQLGenerationDataModel model = context.generateSchemaSQL();
41+
42+
assertThat(model.getTableData().size()).isEqualTo(2);
43+
44+
TableModel t1 = model.getTableData().get(0);
45+
assertThat(t1.getName()).isEqualTo("luke");
46+
assertThat(t1.getColumns().get(0).getName()).isEqualTo("force");
47+
assertThat(t1.getColumns().get(1).getName()).isEqualTo("be");
48+
assertThat(t1.getColumns().get(2).getName()).isEqualTo("with");
49+
assertThat(t1.getColumns().get(3).getName()).isEqualTo("you");
50+
51+
TableModel t2 = model.getTableData().get(1);
52+
assertThat(t2.getName()).isEqualTo("vader");
53+
assertThat(t2.getColumns().get(0).getName()).isEqualTo("luke_i_am_your_father");
54+
assertThat(t2.getColumns().get(1).getName()).isEqualTo("dark_side");
55+
}
56+
57+
@Table
58+
static class Luke {
59+
@Column
60+
public String force;
61+
@Column
62+
public String be;
63+
@Column
64+
public String with;
65+
@Column
66+
public String you;
67+
}
68+
69+
@Table
70+
static class Vader {
71+
@Column
72+
public String lukeIAmYourFather;
73+
@Column
74+
public Boolean darkSide;
75+
}
76+
77+
78+
}

0 commit comments

Comments
 (0)