-
Notifications
You must be signed in to change notification settings - Fork 762
refactor: EXPOSED-561 Restructure code in MigrationUtils and SchemaUtils to avoid calling currentDialect.tableColumns(*tables) in MigrationUtils.statementsRequiredForDatabaseMigration twice
#2279
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
base: main
Are you sure you want to change the base?
Conversation
1d0acf3 to
29873e5
Compare
|
|
||
| object MigrationUtils { | ||
| /** Utility functions that assist with performing database migrations. */ | ||
| object MigrationUtils : BaseSchemaUtils() { |
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.
I would say that in terms of OOP (at least from my current understanding of MigrationUtils's purpose) MigrationUtils should not extend SchemaUtils (BaseSchemaUtils) but should use it, because MigrationUtils is more abstract than SchemaUtils (SchemaUtils is responsible for manipulating with single db objects like tables, but MigrationUtils are supposed to move the whole DB from one state to another).
And as I can see MigrationUtils overrides nothing from base class.
| @@ -102,16 +105,21 @@ object MigrationUtils { | |||
| */ | |||
| fun dropUnmappedColumnsStatements(vararg tables: Table, withLogs: Boolean = true): List<String> { | |||
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.
Not a problem of that particular PR, but this is a public method, and there is only one test that check that function returns empty list. Probably it would be nice to add one more test, that check for non empty result of that function)
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.
That case is tested, but not by directly calling dropUnmappedColumnsStatements, in testDropUnmappedColumns.
| @@ -102,16 +105,21 @@ object MigrationUtils { | |||
| */ | |||
| fun dropUnmappedColumnsStatements(vararg tables: Table, withLogs: Boolean = true): List<String> { | |||
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.
And do we have any requests for such functionality? Looks like it's already used in statementsRequiredForDatabaseMigration that should returns All statements for migration. Probably, the method that checks columns of one (or multiple) tables for deleting could be a part of SchemaUtils. But it's discussable, just some thoughts on how it could be.
|
|
||
| object MigrationUtils { | ||
| /** Utility functions that assist with performing database migrations. */ | ||
| object MigrationUtils : BaseSchemaUtils() { |
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.
Also not a problem of that PR, and can't say I finally understand how users will use it, but this class has a method generateMigrationScript that accepts the list of tables as an argument.
But if you want to create a script, and has hundreds of tables, it could be painful to collect all of them into collection and pass here.
If I use a migration tool, I'd expect that it should search for table objects automatically. As a variant for future improvements we could add one more method that accepts package, and searches for all the table objects (with reflection) within this package.
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.
Yes, this is already an improvement that I have on my to-do list.
| import java.math.BigDecimal | ||
|
|
||
| /** Base class housing shared code between [SchemaUtils] and [MigrationUtils]. */ | ||
| abstract class BaseSchemaUtils { |
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.
There is one another idea of how common part could be extracted.
At the current moment the whole SchemaUtils looks a bit overloaded. It has methods to generate DDL, and has methods to execute commands to manipulate DB.
We could try to split it into the way to extract DDL generation part into another class, let's call it for now DDLUtils; and keep inside SchemaUtils responsibility to execute these DDLs on the database.
In this case we will have common part with DDL statements generation, and two consumers of that class. SchemaUtils that directly performs it on the DB, and MigrationUtils that prepare it as a migration scripts.
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.
@obabichevjb In that case, how would we make the following function visible only to SchemaUtils and MigrationUtils? We don't want it to be public.
fun addMissingColumnsStatements(vararg tables: Table, existingTablesColumns: Map<Table, List<ColumnMetadata>>, withLogs: Boolean = true): List<String>
…aUtils` to avoid calling `currentDialect.tableColumns(*tables)` in `MigrationUtils.statementsRequiredForDatabaseMigration` twice `SchemaUtils` and `MigrationUtils` reside in separate modules and need to share non-public functions, so using a common abstract base class with protected functions in the exposed-core module is the most effective and clean solution.
29873e5 to
51ef0f5
Compare
Description
Detailed description:
Restructure code in
MigrationUtilsandSchemaUtils.To avoid calling
currentDialect.tableColumns(*tables)inMigrationUtils.statementsRequiredForDatabaseMigrationtwice.SchemaUtilsandMigrationUtilsreside in separate modules and need to share non-public functions, so using a common abstract base class with protected functions in theexposed-coremodule is the most effective and clean solution. For the functionsaddMissingColumnsStatementsanddropUnmappedColumnsStatements, two corresponding private functions with a different signature were created, with the difference being that the new functions expectexistingTablesColumnsto be passed as a parameter. Since the new privateaddMissingColumnsStatementsfunction is common to bothSchemaUtilsandMigrationUtils, it was placed inBaseSchemaUtils, and the same thing was done for thelogTimeSpentfunction.Type of Change
Please mark the relevant options with an "X":
Updates/remove existing public API methods:
Affected databases:
Checklist
Related Issues