Skip to content

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

Merged
merged 8 commits into from
Apr 13, 2023
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
Expand Up @@ -29,16 +29,16 @@ public class ColumnModel implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
private final SqlIdentifier name;
private final Class<?> type;
private final String type;
Copy link
Contributor Author

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.

private final boolean nullable;

public ColumnModel(SqlIdentifier name, Class<?> type, boolean nullable) {
public ColumnModel(SqlIdentifier name, String type, boolean nullable) {
this.name = name;
this.type = type;
this.nullable = nullable;
}

public ColumnModel(SqlIdentifier name, Class<?> type) {
public ColumnModel(SqlIdentifier name, String type) {
this.name = name;
this.type = type;
this.nullable = false;
Expand All @@ -48,7 +48,7 @@ public SqlIdentifier getName() {
return name;
}

public Class<?> getType() {
public String getType() {
return type;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import java.io.Serial;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;

Expand All @@ -36,6 +37,7 @@ 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
Expand All @@ -48,6 +50,10 @@ public SchemaSQLGenerationDataModel() {
*/
public SchemaSQLGenerationDataModel(RelationalMappingContext context) {

if (typeMapper == null) {
typeMapper = new BaseTypeMapper();
}

for (RelationalPersistentEntity entity : context.getPersistentEntities()) {
TableModel tableModel = new TableModel(entity.getTableName());

Expand All @@ -56,7 +62,9 @@ public SchemaSQLGenerationDataModel(RelationalMappingContext context) {

while (iter.hasNext()) {
BasicRelationalPersistentProperty p = iter.next();
ColumnModel columnModel = new ColumnModel(p.getColumnName(), p.getActualType());
ColumnModel columnModel = new ColumnModel(p.getColumnName(),
typeMapper.databaseTypeFromClass(p.getActualType()),
Copy link
Contributor Author

Choose a reason for hiding this comment

The 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);
Expand Down