Skip to content
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

Add Meta.migrateTo(Meta):Queries to generate a migration script between two Meta versions #9425

Closed
53 tasks done
lukaseder opened this issue Oct 23, 2019 · 11 comments
Closed
53 tasks done

Comments

@lukaseder
Copy link
Member

lukaseder commented Oct 23, 2019

org.jooq.Meta instances are becoming increasingly important representations of runtime schema meta information. Historically, they were implemented purely using JDBC's DatabaseMetaData, which queries the actual database dictionary views directly. But we now also have implementations taking:

  • Arbitrary jOOQ meta objects, including Catalog, Schema, Table
  • The jOOQ InformationSchema object, which can be read from XML
  • DDL statements that are parsed and interpreted

The above implementations are all immutable and do not depend on a live database connection. With those immutable implementations, we can now compare two versions of the meta model, and try to derive a migration script between the two versions

Things that can be detected automatically:

Things that can be detected using some heuristics (based on likeliness):

MigrationConfiguration

Just like the DDLExportConfiguration, we should have a MigrationConfiguration that governs the style of produced queries. Some examples:

  • alterTableAddMultiple: To add multiple columns and constraints in one single statement (default: false)
  • alterTableDropMultiple: To drop multiple columns and constraints in one single statement (default: false)
  • dropSchemaCascade: To use the CASCADE syntax when dropping schemas (default: false)
  • dropTableCascade: To use the CASCADE syntax when dropping tables (default: false)
  • createOrReplaceView: Whether modified views should be replaced, or dropped and created (default: false)

More have been moved to #13654

Out of scope for 3.13

Some more advanced things are out of scope for 3.13 and will be implemented later, tracked as #9656

@lukaseder lukaseder added this to the Version 3.13.0 milestone Oct 23, 2019
@lukaseder lukaseder self-assigned this Oct 23, 2019
@lukaseder lukaseder added this to To do in 3.13 DDL interpretation via automation Oct 23, 2019
lukaseder added a commit that referenced this issue Oct 23, 2019
lukaseder added a commit that referenced this issue Oct 23, 2019
- Do not use lambda expressions
lukaseder added a commit that referenced this issue Oct 23, 2019
lukaseder added a commit that referenced this issue Oct 23, 2019
lukaseder added a commit that referenced this issue Oct 23, 2019
@knutwannheden
Copy link
Contributor

I think it could also be interesting to allow the user to "guide" the diff, in case it gets something wrong. E.g. when the diff results in a RENAME rather than in a DROP / CREATE pair or vice versa.

I suppose the user could already achieve this using Queries#concat() (with some calls to ddl() and meta()). But possibly we should also add a Meta#combine(Meta) (or concat()) as a counterpart to diff(), which would make this much easier.

lukaseder added a commit that referenced this issue Oct 23, 2019
@lukaseder
Copy link
Member Author

I think it could also be interesting to allow the user to "guide" the diff, in case it gets something wrong. E.g. when the diff results in a RENAME rather than in a DROP / CREATE pair or vice versa.

Yes, clearly the "heuristics" I've mentioned should be configurable

I suppose the user could already achieve this using Queries#concat() (with some calls to ddl() and meta()). But possibly we should also add a Meta#combine(Meta) (or concat()) as a counterpart to diff(), which would make this much easier.

Not sure if I understand this?

@knutwannheden
Copy link
Contributor

Not sure if I understand this?

To guide the rename heuristics the user could for instance take the Meta and "manually" rename a table by using the Meta as a baseline with the DDLInterpreter and interpret an ALTER TABLE ... RENAME to produce a new Meta. Then the diff would not have to apply the heuristic anymore.

I was first thinking that a new Meta#combine(Meta) which essentially does a "union" of two Meta would be useful here, but that of course doesn't make sense. Something like Meta#apply(Query...) (or Meta#transform(Query...)) would make more sense.

Possibly Meta#combine(Meta) could also be useful for other use cases, but I guess that remains to be seen.

@knutwannheden
Copy link
Contributor

knutwannheden commented Oct 23, 2019

So a utility method like this is what I had in mind:

    public Meta apply(Query... queries) {
        return dsl().meta(ddl().concat(dsl().queries(queries)).queries());
    }

lukaseder added a commit that referenced this issue Oct 23, 2019
@lukaseder
Copy link
Member Author

To guide the rename heuristics the user could for instance take the Meta and "manually" rename a table by using the Meta as a baseline with the DDLInterpreter and interpret an ALTER TABLE ... RENAME to produce a new Meta. Then the diff would not have to apply the heuristic anymore.

Ah yes, that's something I also had in mind. In fact, I even thought of the same name as you for the method 👌

public Meta apply(Query... queries) { ... }

I was first thinking that a new Meta#combine(Meta) which essentially does a "union" of two Meta would be useful here, but that of course doesn't make sense.

Well, we already do that when we apply several information_schema XML files, but I agree I'm not convinced of the usefulness of this.

We'll see if we need it for Meta in general.

@lukaseder
Copy link
Member Author

In fact, I had already implemented Meta.apply() in the Diff tests 😉

@lukaseder
Copy link
Member Author

Meta.apply(Queries) was implemented with #9436

lukaseder added a commit that referenced this issue Oct 25, 2019
@lukaseder
Copy link
Member Author

I'm running a poll about method naming, which is probably too confusing:
https://twitter.com/lukaseder/status/1204689766324854785

A better name for the method will be discussed soon

@lukaseder lukaseder changed the title Add Meta.diff(Meta):Queries to generate a migration script between two Meta versions Add Meta.migrateTo(Meta):Queries to generate a migration script between two Meta versions Dec 12, 2019
@lukaseder
Copy link
Member Author

lukaseder commented Dec 12, 2019

We'll use the term A.migrateTo(B) to describe a migration from A to B. This applies to both Meta.migrateTo(Meta) and Version.migrateTo(Version)

@lukaseder
Copy link
Member Author

After careful thought, I've decided that this is going to be a very central feature of the new migration APIs. Adoption of these APIs depends on the success of this feature, which is why we'll be open sourcing it.

The distinction between editions will be done on a more fine-grained level.

@lukaseder
Copy link
Member Author

Not sure why this issue hadn't been closed at the time. There's still work, yes: #13654, but we've delivered quite a bit of functionality nonetheless.

Closing it now. Continuing work in #13654

3.15 jOOQ Migrations automation moved this from To do to Done Jun 10, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Development

No branches or pull requests

2 participants