英文:
What are the ways to modify or hack the jOOQ-generated DDL?
问题
抱歉,我不能提供代码的翻译。如果您有其他非代码部分需要翻译,请告诉我,我会尽力帮助您。
英文:
I am using the schema exporting feature of jOOQ extensively. Unfortunately, in some cases, jOOQ generates incorrect or inaccurate DDL for database objects. Are there any standard ways to slightly modify the generated DDL, besides using replace/regex commands on the generated DDL string?
Let's take a look at an example.
- Create a table (disabling
NO_ZERO_DATE
mode):
set sql_mode='';
create table test_date_types_table (
timestamp_column_nullable timestamp null,
timestamp_column_not_null timestamp not null,
timestamp_column_default timestamp
);
- Run this Java code to generate DDL for the table:
Connection conn = DriverManager.getConnection("jdbc:mysql://127.0.0.1:6000/sakila", "root", "admin");
Configuration configuration = new DefaultConfiguration().set(conn).set(SQLDialect.MYSQL.family());
Meta currentMeta = using(configuration).meta();
Query[] queries = currentMeta
.filterSchemas(v -> v.getName().equalsIgnoreCase("sakila"))
.ddl()
.queries();
for (Query query : queries) {
System.out.println(query);
}
- As a result, I received this DDL from jOOQ:
create table `sakila`.`test_date_types_table` (
`timestamp_column_nullable` timestamp,
`timestamp_column_not_null` timestamp not null default null,
`timestamp_column_default` timestamp not null default null
)
- That DDL doesn't work, because we have
not null
columns withnull
value by default:
Invalid default value for 'timestamp_column_not_null'
-
And our nullable column
timestamp_column_default
is no longer nullable -
I believe the valid DDL script should look something like our source DDL:
create table `sakila`.`test_date_types_table` (
`timestamp_column_nullable` timestamp,
`timestamp_column_not_null` timestamp not null,
`timestamp_column_default` timestamp
)
How could I fix this and similar cases on my end without changing anything in the jOOQ core?
答案1
得分: 1
以下是您要翻译的内容:
"非正则表达式方式修补 jOOQ 表达式树的方法是使用实验性的(截至 jOOQ 3.18 版本)查询对象模型 API,例如来自ExecuteListener
。您可以匹配整个查询,直到找到正确的替换位置,或者使用内置的查询对象模型替换 API。这允许在渲染之前替换查询部分。
使用替换 API 的简单示例如下:
System.out.println(ctx
.parser()
.parseQuery("create table t (i int not null)")
.$replace(q -> {
if (q instanceof QOM.CreateTable ct) {
UnmodifiableCollection<? extends TableElement> te1 =
ct.$tableElements();
UnmodifiableCollection<? extends TableElement> te2 =
(UnmodifiableCollection<? extends TableElement>)
te1.$replace(x -> x instanceof Field<?> f
&& !f.getDataType().nullable()
? DSL.field(
f.getQualifiedName(),
f.getDataType().nullable(true)
)
: x
);
if (te1 != te2)
return ct.$tableElements(te2);
}
return q;
})
);
它将替换所有 NOT NULL
约束在 CREATE TABLE
语句上,结果如下:
create table T (
I int
)
另一种更复杂的替代方法是使用 VisitListener
,它允许在将 QueryPart 渲染为输出 SQL 时替换 QueryPart 类型。
英文:
The non-regular expression way of patching the jOOQ expression tree would be to use the experimental (as of jOOQ 3.18) query object model API, for example from an ExecuteListener
. You can either pattern match the entire query until you find the right place to replace, or use the built-in query object model replacement API. This allows for replacing the query parts before rendering it.
A simple example for using the replacement API is this:
System.out.println(ctx
.parser()
.parseQuery("create table t (i int not null)")
.$replace(q -> {
if (q instanceof QOM.CreateTable ct) {
UnmodifiableCollection<? extends TableElement> te1 =
ct.$tableElements();
UnmodifiableCollection<? extends TableElement> te2 =
(UnmodifiableCollection<? extends TableElement>)
te1.$replace(x -> x instanceof Field<?> f
&& !f.getDataType().nullable()
? DSL.field(
f.getQualifiedName(),
f.getDataType().nullable(true)
)
: x
);
if (te1 != te2)
return ct.$tableElements(te2);
}
return q;
})
);
It will replace all NOT NULL
constraints on CREATE TABLE
statements, resulting in:
create table T (
I int
)
An alternative, which is more complicated to do, would be to use a VisitListener
, which allows for replacing QueryPart
types while they're being rendered to output SQL.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论