-
Notifications
You must be signed in to change notification settings - Fork 356
Initial Data Model for Schema SQL Generation #1481
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 6 commits
a30d01a
9a7bb2b
38aeaaf
c59f8a7
e183e9e
5762a06
985b703
aed2adf
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
/* | ||
* Copyright 2023 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.data.relational.core.mapping.schemasqlgeneration; | ||
|
||
import java.util.HashMap; | ||
|
||
public class BaseTypeMapper { | ||
|
||
final HashMap<Class<?>,String> mapClassToDatabaseType = new HashMap<Class<?>,String>(); | ||
|
||
public BaseTypeMapper() { | ||
mapClassToDatabaseType.put(String.class, "VARCHAR(255)"); | ||
mapClassToDatabaseType.put(Boolean.class, "TINYINT"); | ||
mapClassToDatabaseType.put(Double.class, "DOUBLE"); | ||
mapClassToDatabaseType.put(Float.class, "FLOAT"); | ||
mapClassToDatabaseType.put(Integer.class, "INT"); | ||
} | ||
public String databaseTypeFromClass(Class<?> type) { | ||
return mapClassToDatabaseType.get(type); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
/* | ||
* Copyright 2023 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.data.relational.core.mapping.schemasqlgeneration; | ||
|
||
import org.springframework.data.relational.core.sql.SqlIdentifier; | ||
|
||
import java.io.Serial; | ||
import java.io.Serializable; | ||
|
||
/** | ||
* Class that models a Column for generating SQL for Schema generation. | ||
* | ||
* @author Kurt Niemi | ||
*/ | ||
public class ColumnModel implements Serializable { | ||
@Serial | ||
private static final long serialVersionUID = 1L; | ||
private final SqlIdentifier name; | ||
private final String type; | ||
private final boolean nullable; | ||
|
||
public ColumnModel(SqlIdentifier name, String type, boolean nullable) { | ||
this.name = name; | ||
this.type = type; | ||
this.nullable = nullable; | ||
} | ||
|
||
public ColumnModel(SqlIdentifier name, String type) { | ||
this.name = name; | ||
this.type = type; | ||
this.nullable = false; | ||
} | ||
|
||
public SqlIdentifier getName() { | ||
return name; | ||
} | ||
|
||
public String getType() { | ||
return type; | ||
} | ||
|
||
public boolean isNullable() { | ||
return nullable; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
/* | ||
* Copyright 2023 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.data.relational.core.mapping.schemasqlgeneration; | ||
|
||
import java.io.Serial; | ||
import java.io.Serializable; | ||
|
||
/** | ||
* Class that models a Foreign Key relationship for generating SQL for Schema generation. | ||
* | ||
* @author Kurt Niemi | ||
*/ | ||
public class ForeignKeyColumnModel implements Serializable { | ||
@Serial | ||
private static final long serialVersionUID = 1L; | ||
private final TableModel foreignTable; | ||
private final ColumnModel foreignColumn; | ||
private final ColumnModel column; | ||
|
||
public ForeignKeyColumnModel(TableModel foreignTable, ColumnModel foreignColumn, ColumnModel column) { | ||
this.foreignTable = foreignTable; | ||
this.foreignColumn = foreignColumn; | ||
this.column = column; | ||
} | ||
|
||
public TableModel getForeignTable() { | ||
return foreignTable; | ||
} | ||
|
||
public ColumnModel getForeignColumn() { | ||
return foreignColumn; | ||
} | ||
|
||
public ColumnModel getColumn() { | ||
return column; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
/* | ||
* Copyright 2023 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.data.relational.core.mapping.schemasqlgeneration; | ||
|
||
import org.springframework.data.relational.core.mapping.BasicRelationalPersistentProperty; | ||
import org.springframework.data.relational.core.mapping.Column; | ||
import org.springframework.data.relational.core.mapping.RelationalMappingContext; | ||
import org.springframework.data.relational.core.mapping.RelationalPersistentEntity; | ||
|
||
import java.io.Serial; | ||
import java.io.Serializable; | ||
import java.util.ArrayList; | ||
import java.util.HashMap; | ||
import java.util.Iterator; | ||
import java.util.List; | ||
|
||
/** | ||
* Model class that contains Table/Column information that can be used | ||
* to generate SQL for Schema generation. | ||
* | ||
* @author Kurt Niemi | ||
*/ | ||
public class SchemaSQLGenerationDataModel implements Serializable { | ||
@Serial | ||
private static final long serialVersionUID = 1L; | ||
private final List<TableModel> tableData = new ArrayList<TableModel>(); | ||
BaseTypeMapper typeMapper; | ||
|
||
/** | ||
* Default constructor so that we can deserialize a model | ||
*/ | ||
public SchemaSQLGenerationDataModel() { | ||
} | ||
|
||
/** | ||
* Create model from a RelationalMappingContext | ||
*/ | ||
public SchemaSQLGenerationDataModel(RelationalMappingContext context) { | ||
|
||
if (typeMapper == null) { | ||
typeMapper = new BaseTypeMapper(); | ||
} | ||
|
||
for (RelationalPersistentEntity entity : context.getPersistentEntities()) { | ||
TableModel tableModel = new TableModel(entity.getTableName()); | ||
|
||
Iterator<BasicRelationalPersistentProperty> iter = | ||
entity.getPersistentProperties(Column.class).iterator(); | ||
|
||
while (iter.hasNext()) { | ||
BasicRelationalPersistentProperty p = iter.next(); | ||
ColumnModel columnModel = new ColumnModel(p.getColumnName(), | ||
typeMapper.databaseTypeFromClass(p.getActualType()), | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @schauder - I know initially I had wanted to modify the @column annotation to have a gazillion modifiers :-) to match what was in JPA. After implementing the default behavior (and the change to the Column model) - I think adding just one annotation (databaseType) would be sufficient. We would let developers specify whatever they want there, and that is exactly what would be in the generated SQL. If the user wishes to change our defaults, they can optionally subclass BaseTypeMapper. I stayed with what I think are datatypes that are supported by all Databases. Will add more comments to the code - to document/describe to users how to extend/change behavior. |
||
true); | ||
tableModel.getColumns().add(columnModel); | ||
} | ||
tableData.add(tableModel); | ||
} | ||
} | ||
|
||
public List<TableModel> getTableData() { | ||
return tableData; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
/* | ||
* Copyright 2023 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.data.relational.core.mapping.schemasqlgeneration; | ||
|
||
import org.springframework.data.relational.core.sql.SqlIdentifier; | ||
|
||
import java.io.Serial; | ||
import java.io.Serializable; | ||
import java.util.ArrayList; | ||
import java.util.List; | ||
|
||
/** | ||
* Class that models a Table for generating SQL for Schema generation. | ||
* | ||
* @author Kurt Niemi | ||
*/ | ||
public class TableModel implements Serializable { | ||
@Serial | ||
private static final long serialVersionUID = 1L; | ||
private final String schema; | ||
private final SqlIdentifier name; | ||
private final List<ColumnModel> columns = new ArrayList<ColumnModel>(); | ||
private final List<ColumnModel> keyColumns = new ArrayList<ColumnModel>(); | ||
private final List<ForeignKeyColumnModel> foreignKeyColumns = new ArrayList<ForeignKeyColumnModel>(); | ||
|
||
public TableModel(String schema, SqlIdentifier name) { | ||
this.schema = schema; | ||
this.name = name; | ||
} | ||
public TableModel(SqlIdentifier name) { | ||
this(null, name); | ||
} | ||
|
||
public String getSchema() { | ||
return schema; | ||
} | ||
|
||
public SqlIdentifier getName() { | ||
return name; | ||
} | ||
|
||
public List<ColumnModel> getColumns() { | ||
return columns; | ||
} | ||
|
||
public List<ColumnModel> getKeyColumns() { | ||
return keyColumns; | ||
} | ||
|
||
public List<ForeignKeyColumnModel> getForeignKeyColumns() { | ||
return foreignKeyColumns; | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Decided to simplify the model to be a String value. Whatever is in here is what gets in the generated SQL.