[jOOQ/jOOQ#9509] Add Meta.getEnums()
- Added ResultQueryDatabase::enums - Added MetaSQL queries - Added MySQL implementation
This commit is contained in:
parent
30b198ea77
commit
6bc82eb3ef
@ -127,6 +127,25 @@ public interface ResultQueryDatabase extends Database {
|
||||
@Nullable
|
||||
ResultQuery<Record12<String, String, String, String, Integer, Integer, Long, Long, BigDecimal, BigDecimal, Boolean, Long>> sequences(List<String> schemas);
|
||||
|
||||
/**
|
||||
* A query that produces enum types and their literals for a set of input schemas.
|
||||
* <p>
|
||||
* The resulting columns are:
|
||||
* <ol>
|
||||
* <li>Catalog name</li>
|
||||
* <li>Schema name</li>
|
||||
* <li>Column name (if applicable, e.g. in MySQL style RDBMS)</li>
|
||||
* <li>Enum type name (if applicable, e.g. in PostgreSQL style RDBMS)</li>
|
||||
* <li>Literal value</li>
|
||||
* <li>Literal position</li>
|
||||
* </ol>
|
||||
*
|
||||
* @return The query or <code>null</code> if this implementation doesn't support the query.
|
||||
*/
|
||||
@Internal
|
||||
@Nullable
|
||||
ResultQuery<Record6<String, String, String, String, String, Integer>> enums(List<String> schemas);
|
||||
|
||||
/**
|
||||
* A query that produces source code for a set of input schemas.
|
||||
* <p>
|
||||
|
||||
@ -445,6 +445,11 @@ public class DerbyDatabase extends AbstractDatabase implements ResultQueryDataba
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResultQuery<Record6<String, String, String, String, String, Integer>> enums(List<String> schemas) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<TableDefinition> getTables0() throws SQLException {
|
||||
List<TableDefinition> result = new ArrayList<>();
|
||||
|
||||
@ -284,6 +284,11 @@ public class DuckDBDatabase extends AbstractDatabase implements ResultQueryDatab
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResultQuery<Record6<String, String, String, String, String, Integer>> enums(List<String> schemas) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<TableDefinition> getTables0() throws SQLException {
|
||||
List<TableDefinition> result = new ArrayList<>();
|
||||
|
||||
@ -504,6 +504,11 @@ public class FirebirdDatabase extends AbstractDatabase implements ResultQueryDat
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResultQuery<Record6<String, String, String, String, String, Integer>> enums(List<String> schemas) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<TableDefinition> getTables0() throws SQLException {
|
||||
List<TableDefinition> result = new ArrayList<>();
|
||||
|
||||
@ -757,6 +757,11 @@ public class H2Database extends AbstractDatabase implements ResultQueryDatabase
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResultQuery<Record6<String, String, String, String, String, Integer>> enums(List<String> schemas) {
|
||||
return null;
|
||||
}
|
||||
|
||||
static record TableRecord(String schema, String table, TableType type, String comment) {}
|
||||
|
||||
@Override
|
||||
|
||||
@ -501,6 +501,11 @@ public class HSQLDBDatabase extends AbstractDatabase implements ResultQueryDatab
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResultQuery<Record6<String, String, String, String, String, Integer>> enums(List<String> schemas) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<TableDefinition> getTables0() throws SQLException {
|
||||
List<TableDefinition> result = new ArrayList<>();
|
||||
|
||||
@ -48,11 +48,19 @@ import static org.jooq.SQLDialect.MYSQL;
|
||||
// ...
|
||||
import static org.jooq.impl.DSL.case_;
|
||||
import static org.jooq.impl.DSL.cast;
|
||||
import static org.jooq.impl.DSL.field;
|
||||
import static org.jooq.impl.DSL.inline;
|
||||
import static org.jooq.impl.DSL.length;
|
||||
import static org.jooq.impl.DSL.name;
|
||||
import static org.jooq.impl.DSL.noCondition;
|
||||
import static org.jooq.impl.DSL.regexpReplaceAll;
|
||||
import static org.jooq.impl.DSL.regexpReplaceFirst;
|
||||
import static org.jooq.impl.DSL.replace;
|
||||
import static org.jooq.impl.DSL.row;
|
||||
import static org.jooq.impl.DSL.select;
|
||||
import static org.jooq.impl.DSL.table;
|
||||
import static org.jooq.impl.DSL.when;
|
||||
import static org.jooq.impl.SQLDataType.CHAR;
|
||||
import static org.jooq.impl.SQLDataType.CLOB;
|
||||
import static org.jooq.impl.SQLDataType.INTEGER;
|
||||
import static org.jooq.impl.SQLDataType.VARCHAR;
|
||||
@ -79,6 +87,7 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import org.jooq.CommonTableExpression;
|
||||
import org.jooq.DSLContext;
|
||||
import org.jooq.Field;
|
||||
import org.jooq.Record;
|
||||
@ -121,6 +130,7 @@ import org.jooq.meta.TableDefinition;
|
||||
import org.jooq.meta.UDTDefinition;
|
||||
import org.jooq.meta.XMLSchemaCollectionDefinition;
|
||||
import org.jooq.meta.mariadb.MariaDBDatabase;
|
||||
import org.jooq.meta.mysql.information_schema.tables.Columns;
|
||||
import org.jooq.meta.mysql.information_schema.tables.Triggers;
|
||||
import org.jooq.meta.mysql.mysql.enums.ProcType;
|
||||
import org.jooq.tools.csv.CSVReader;
|
||||
@ -469,6 +479,71 @@ public class MySQLDatabase extends AbstractDatabase implements ResultQueryDataba
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResultQuery<Record6<String, String, String, String, String, Integer>> enums(List<String> schemas) {
|
||||
|
||||
// Recursive query that works with MySQL 8+ only:
|
||||
// https://stackoverflow.com/a/77057135/521799
|
||||
|
||||
Columns c = COLUMNS;
|
||||
|
||||
Field<String> e = field(name("e"), VARCHAR);
|
||||
Field<String> l = field(name("l"), VARCHAR);
|
||||
Field<Integer> p = field(name("p"), INTEGER);
|
||||
|
||||
CommonTableExpression<?> te = name("e").as(
|
||||
select(
|
||||
c.TABLE_SCHEMA,
|
||||
c.TABLE_NAME,
|
||||
c.COLUMN_NAME,
|
||||
regexpReplaceAll(c.COLUMN_TYPE, inline("enum\\((.*)\\)"), inline("$1")).as(e))
|
||||
.from(c)
|
||||
.where(c.DATA_TYPE.eq(inline("enum")))
|
||||
);
|
||||
|
||||
CommonTableExpression<?> tl = name("l").as(
|
||||
select(
|
||||
te.field(c.TABLE_SCHEMA),
|
||||
te.field(c.TABLE_NAME),
|
||||
te.field(c.COLUMN_NAME),
|
||||
e, cast(inline(""), CHAR(32767)).as(l),
|
||||
inline(0).as(p))
|
||||
.from(te)
|
||||
.unionAll(
|
||||
select(
|
||||
te.field(c.TABLE_SCHEMA),
|
||||
te.field(c.TABLE_NAME),
|
||||
te.field(c.COLUMN_NAME),
|
||||
regexpReplaceFirst(e, inline("'.*?'(?:,|$)(.*)"), inline("$1")),
|
||||
replace(
|
||||
regexpReplaceFirst(e, inline("'(.*?)'(?:,|$).*"), inline("$1")),
|
||||
inline("''"), inline("'")
|
||||
),
|
||||
p.plus(inline(1)))
|
||||
.from(table(name("l")).as(te))
|
||||
.where(length(e).gt(inline(0)))
|
||||
)
|
||||
);
|
||||
|
||||
return create()
|
||||
.withRecursive(te, tl)
|
||||
.select(
|
||||
tl.field(c.TABLE_SCHEMA),
|
||||
tl.field(c.TABLE_NAME),
|
||||
tl.field(c.COLUMN_NAME),
|
||||
inline(null, VARCHAR).as(c.DATA_TYPE),
|
||||
tl.field(l),
|
||||
tl.field(p))
|
||||
.from(tl)
|
||||
.where(p.gt(inline(0)))
|
||||
.and(tl.field(c.TABLE_SCHEMA).in(schemas))
|
||||
.orderBy(
|
||||
tl.field(c.TABLE_SCHEMA),
|
||||
tl.field(c.TABLE_NAME),
|
||||
tl.field(c.COLUMN_NAME),
|
||||
tl.field(p));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<TableDefinition> getTables0() throws SQLException {
|
||||
List<TableDefinition> result = new ArrayList<>();
|
||||
|
||||
@ -779,6 +779,11 @@ public class PostgresDatabase extends AbstractDatabase implements ResultQueryDat
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResultQuery<Record6<String, String, String, String, String, Integer>> enums(List<String> schemas) {
|
||||
return null;
|
||||
}
|
||||
|
||||
static record Identifier(String schema, String name) {}
|
||||
|
||||
@Override
|
||||
|
||||
@ -402,6 +402,11 @@ public class SQLiteDatabase extends AbstractDatabase implements ResultQueryDatab
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResultQuery<Record6<String, String, String, String, String, Integer>> enums(List<String> schemas) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResultQuery<Record6<String, String, String, String, String, Integer>> primaryKeys(List<String> schemas) {
|
||||
return null;
|
||||
|
||||
@ -147,6 +147,11 @@ public class TrinoDatabase extends AbstractDatabase implements ResultQueryDataba
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResultQuery<Record6<String, String, String, String, String, Integer>> enums(List<String> schemas) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final ResultQuery<Record4<String, String, String, String>> sources(List<String> schemas) {
|
||||
return create()
|
||||
|
||||
47
jOOQ/src/main/java/org/jooq/RenamedSchemaElement.java
Normal file
47
jOOQ/src/main/java/org/jooq/RenamedSchemaElement.java
Normal file
@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* Other licenses:
|
||||
* -----------------------------------------------------------------------------
|
||||
* Commercial licenses for this work are available. These replace the above
|
||||
* ASL 2.0 and offer limited warranties, support, maintenance, and commercial
|
||||
* database integrations.
|
||||
*
|
||||
* For more information, please visit: https://www.jooq.org/legal/licensing
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*/
|
||||
package org.jooq;
|
||||
|
||||
/**
|
||||
* A marker interface for renamed schema elements.
|
||||
*
|
||||
* @author Lukas Eder
|
||||
*/
|
||||
interface RenamedSchemaElement {
|
||||
|
||||
}
|
||||
@ -46,7 +46,7 @@ import org.jooq.impl.TableImpl;
|
||||
*
|
||||
* @author Lukas Eder
|
||||
*/
|
||||
final class RenamedTable<R extends Record> extends TableImpl<R> {
|
||||
final class RenamedTable<R extends Record> extends TableImpl<R> implements RenamedSchemaElement {
|
||||
|
||||
RenamedTable(Schema schema, Table<R> delegate, String rename) {
|
||||
super(name(rename), schema);
|
||||
|
||||
@ -44,7 +44,7 @@ import org.jooq.impl.UDTImpl;
|
||||
*
|
||||
* @author Lukas Eder
|
||||
*/
|
||||
final class RenamedUDT<R extends UDTRecord<R>> extends UDTImpl<R> {
|
||||
final class RenamedUDT<R extends UDTRecord<R>> extends UDTImpl<R> implements RenamedSchemaElement {
|
||||
|
||||
RenamedUDT(Schema schema, UDT<R> delegate, String rename) {
|
||||
super(rename, schema, delegate.getPackage(), delegate.isSynthetic());
|
||||
|
||||
@ -540,7 +540,7 @@ public class SchemaMapping implements Serializable {
|
||||
}
|
||||
}
|
||||
|
||||
if (!(result instanceof RenamedTable))
|
||||
if (!(result instanceof RenamedSchemaElement))
|
||||
schemaLoop:
|
||||
for (MappedSchema s : mapping().getSchemata()) {
|
||||
if (matches(s, schemaName)) {
|
||||
|
||||
@ -11,6 +11,7 @@ final class MetaSQL {
|
||||
private static final EnumMap<SQLDialect, String> M_UNIQUE_KEYS = new EnumMap<>(SQLDialect.class);
|
||||
private static final EnumMap<SQLDialect, String> M_SEQUENCES = new EnumMap<>(SQLDialect.class);
|
||||
private static final EnumMap<SQLDialect, String> M_SEQUENCES_INCLUDING_SYSTEM_SEQUENCES = new EnumMap<>(SQLDialect.class);
|
||||
private static final EnumMap<SQLDialect, String> M_ENUMS = new EnumMap<>(SQLDialect.class);
|
||||
private static final EnumMap<SQLDialect, String> M_SOURCES = new EnumMap<>(SQLDialect.class);
|
||||
private static final EnumMap<SQLDialect, String> M_COMMENTS = new EnumMap<>(SQLDialect.class);
|
||||
|
||||
@ -29,6 +30,11 @@ final class MetaSQL {
|
||||
return result != null ? result : M_SEQUENCES_INCLUDING_SYSTEM_SEQUENCES.get(dialect.family());
|
||||
}
|
||||
|
||||
static final String M_ENUMS(SQLDialect dialect) {
|
||||
String result = M_ENUMS.get(dialect);
|
||||
return result != null ? result : M_ENUMS.get(dialect.family());
|
||||
}
|
||||
|
||||
static final String M_SOURCES(SQLDialect dialect) {
|
||||
String result = M_SOURCES.get(dialect);
|
||||
return result != null ? result : M_SOURCES.get(dialect.family());
|
||||
@ -202,6 +208,30 @@ final class MetaSQL {
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
M_ENUMS.put(MARIADB, "with recursive e as (select information_schema.COLUMNS.TABLE_SCHEMA, information_schema.COLUMNS.TABLE_NAME, information_schema.COLUMNS.COLUMN_NAME, regexp_replace(information_schema.COLUMNS.COLUMN_TYPE, 'enum\\((.*)\\)', '$1') as e from information_schema.COLUMNS where information_schema.COLUMNS.DATA_TYPE = 'enum'), l as (select e.TABLE_SCHEMA, e.TABLE_NAME, e.COLUMN_NAME, e, cast('' as char(32767)) as l, 0 as p from e union all select e.TABLE_SCHEMA, e.TABLE_NAME, e.COLUMN_NAME, regexp_replace(e, '''.*?''(?:,|$)(.*)', '$1', 1, 1), replace(regexp_replace(e, '''(.*?)''(?:,|$).*', '$1', 1, 1), '''''', ''''), (p + 1) from l as e where char_length(e) > 0) select l.TABLE_SCHEMA, l.TABLE_NAME, l.COLUMN_NAME, null as DATA_TYPE, l.l, l.p from l where (p > 0 and l.TABLE_SCHEMA in (?)) order by l.TABLE_SCHEMA, l.TABLE_NAME, l.COLUMN_NAME, l.p");
|
||||
M_ENUMS.put(MYSQL, "with recursive e as (select information_schema.COLUMNS.TABLE_SCHEMA, information_schema.COLUMNS.TABLE_NAME, information_schema.COLUMNS.COLUMN_NAME, regexp_replace(information_schema.COLUMNS.COLUMN_TYPE, 'enum\\((.*)\\)', '$1') as e from information_schema.COLUMNS where information_schema.COLUMNS.DATA_TYPE = 'enum'), l as (select e.TABLE_SCHEMA, e.TABLE_NAME, e.COLUMN_NAME, e, cast('' as char(32767)) as l, 0 as p from e union all select e.TABLE_SCHEMA, e.TABLE_NAME, e.COLUMN_NAME, regexp_replace(e, '''.*?''(?:,|$)(.*)', '$1', 1, 1), replace(regexp_replace(e, '''(.*?)''(?:,|$).*', '$1', 1, 1), '''''', ''''), (p + 1) from l as e where char_length(e) > 0) select l.TABLE_SCHEMA, l.TABLE_NAME, l.COLUMN_NAME, null as DATA_TYPE, l.l, l.p from l where (p > 0 and l.TABLE_SCHEMA in (?)) order by l.TABLE_SCHEMA, l.TABLE_NAME, l.COLUMN_NAME, l.p");
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user