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

Conversation

kurtn718
Copy link
Contributor

@kurtn718 kurtn718 commented Apr 5, 2023

Initial data model for Schema SQL Generation.

If we want to have a feature branch (instead of main) that these changes get merged into, I am definitely good with that approach. Please let me know.

  • You have read the Spring Data contribution guidelines.
  • You use the code formatters provided here and have them applied to your changes. Don’t submit any formatting related changes.
  • You submit test cases (unit or integration tests) that back your changes.
  • You added yourself as author in the headers of the classes you touched. Amend the date range in the Apache license header if needed. For new types, add the license header (copy from another file and set the current year only).

kurtn718 added 2 commits April 5, 2023 09:02
Initial model for generating schema SQL.

Closes #1478
@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged label Apr 5, 2023
@kurtn718 kurtn718 requested a review from schauder April 5, 2023 13:20
Copy link
Contributor

@schauder schauder left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A change like this is hard to review since it doesn't really create a usable feature.
For a better change "usable" can be considered rather broadly. For example I'd consider a schema generator that creates a schema consisting of a single table with correct name for each aggregate and with a single dummy column usable. It can be invoked by a user and produces something at least somehow useful.

In such a change one can take a look at the underlying model and form an opinion if the underlying model is fit for purpose.
With the current model this is mostly guess work.

As for the merge target: We should not merge into main until we have something that is really usable for the enduser. Basically something we/you would be willing to present as a new feature of Spring Data JDBC.

Until we have that everything should happen on the feature branch, and we don't need formal PRs.

Let's discuss further details about how to proceed in person.

* Method to build a data model of Tables/Columns and their relationships
* that will be used in SQL Generation.
*/
public SchemaSQLGenerationDataModel generateSchemaSQL() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think the mapping context should create a SchemaSqlGenerationDataModel instead a mapping context should be used to create such a model. Either in the constructor of the class or in a factory.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

About to push up a change for this. Code definitely looks cleaner with this!

private Class<?> type;
private boolean nullable;

public String getName() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Things like column and table names should be SqlIdentifier since we need to consider quoting and identifier processing.

this.name = name;
}

public Class<?> getType() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't see why we would need a type in the sense of a Class. This information is provided by PersistentProperty. Instead we might need a type like Text or Number which represents database types, while abstracting over the database specific representations of those. Possibly by using Liquibase abstractions, if those exist.

}

@Table
static class Luke {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The choice of testdata names doesn't help to understand why these look the way they do look.

I consider names like EntityWithMultipleColumns or stringProperty and so one more expressive.


TableModel t1 = model.getTableData().get(0);
assertThat(t1.getName()).isEqualTo("luke");
assertThat(t1.getColumns().get(0).getName()).isEqualTo("force");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This and the following three assertions basically test the same thing.

@kurtn718
Copy link
Contributor Author

Going to convert the Pull Request to a Draft

@kurtn718 kurtn718 marked this pull request as draft April 11, 2023 17:55
public class SchemaSQLGenerator {

private final IdentifierProcessing identifierProcssing;
public SchemaSQLGenerator(IdentifierProcessing identifierProcessing) {
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 -

Is there a way to get the IdentifierProcessing from the RelationalMappingContext? (or when user's use this class to generate SQL - that they can easily get an IdentifierProcessing object - that matches the one they are using for executing SQL)?

For the Unit Test(s) I think passing it in gives flexibility.

@@ -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.

@@ -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.

@kurtn718 kurtn718 changed the base branch from main to feature/schema-generation April 13, 2023 11:53
@kurtn718 kurtn718 marked this pull request as ready for review April 13, 2023 11:56
@kurtn718 kurtn718 merged commit ad7b087 into feature/schema-generation Apr 13, 2023
@kurtn718 kurtn718 deleted the issue/1478 branch April 13, 2023 11:59
kurtn718 added a commit that referenced this pull request May 20, 2023
Initial Data Model for Schema SQL Generation that can generate SQL for a simple entity.

Closes #1478
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
status: waiting-for-triage An issue we've not yet triaged
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants