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:
Catalog, Schema, TableInformationSchema object, which can be read from XMLThe 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
respectColumnOrder is set)Meta needs additional API to find these types: https://github.com/jOOQ/jOOQ/issues/9509)MigrationConfigurationJust 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)alterTableDropCascade: To use the CASCADE syntax when dropping columns or constraints (default: false)dropTypeCascade: To use the CASCADE syntax when dropping types (default: false)createOrReplaceView: Whether modified views should be replaced, or dropped and created (default: false)respectColumnOrder: Whether column order is relevant (default: false)Some more advanced things are out of scope for 3.13 and will be implemented later, tracked as #9656
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.
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?
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.
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());
}
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.
In fact, I had already implemented Meta.apply() in the Diff tests 馃槈
Meta.apply(Queries) was implemented with #9436
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
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)
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.
Most helpful comment
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
RENAMErather than in aDROP/CREATEpair or vice versa.I suppose the user could already achieve this using
Queries#concat()(with some calls toddl()andmeta()). But possibly we should also add aMeta#combine(Meta)(orconcat()) as a counterpart todiff(), which would make this much easier.