[#2777] Let code generator reflect PostgreSQL table inheritance in generated tables, records, pojos, daos
- Added inheritance capability to jOOQ-Meta
This commit is contained in:
parent
be485c7d1b
commit
5b10860d7c
@ -44,6 +44,7 @@ package org.jooq.util;
|
||||
import static org.jooq.impl.DSL.table;
|
||||
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.jooq.Record;
|
||||
@ -65,9 +66,14 @@ implements TableDefinition {
|
||||
private UniqueKeyDefinition primaryKey;
|
||||
private boolean identityLoaded;
|
||||
private IdentityDefinition identity;
|
||||
private TableDefinition parentTable;
|
||||
private List<TableDefinition> childTables;
|
||||
|
||||
public AbstractTableDefinition(SchemaDefinition schema, String name, String comment) {
|
||||
super(schema, name, comment);
|
||||
|
||||
parentTable = null;
|
||||
childTables = new ArrayList<TableDefinition>();
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -130,6 +136,20 @@ implements TableDefinition {
|
||||
return identity;
|
||||
}
|
||||
|
||||
public final void setParentTable(TableDefinition parentTable) {
|
||||
this.parentTable = parentTable;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final TableDefinition getParentTable() {
|
||||
return parentTable;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final List<TableDefinition> getChildTables() {
|
||||
return childTables;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Table<Record> getTable() {
|
||||
return table(getQualifiedName());
|
||||
|
||||
@ -99,6 +99,16 @@ public interface TableDefinition extends Definition {
|
||||
*/
|
||||
IdentityDefinition getIdentity();
|
||||
|
||||
/**
|
||||
* Get the parent table if table inheritance is applicable.
|
||||
*/
|
||||
TableDefinition getParentTable();
|
||||
|
||||
/**
|
||||
* Get the child tables if table inheritance is applicable.
|
||||
*/
|
||||
List<TableDefinition> getChildTables();
|
||||
|
||||
/**
|
||||
* This TableDefinition as a {@link Table}.
|
||||
*/
|
||||
|
||||
@ -44,6 +44,7 @@ package org.jooq.util.postgres;
|
||||
import static org.jooq.impl.DSL.count;
|
||||
import static org.jooq.impl.DSL.decode;
|
||||
import static org.jooq.impl.DSL.field;
|
||||
import static org.jooq.impl.DSL.max;
|
||||
import static org.jooq.impl.DSL.name;
|
||||
import static org.jooq.impl.DSL.select;
|
||||
import static org.jooq.impl.DSL.selectOne;
|
||||
@ -58,21 +59,28 @@ import static org.jooq.util.postgres.information_schema.Tables.ROUTINES;
|
||||
import static org.jooq.util.postgres.information_schema.Tables.SEQUENCES;
|
||||
import static org.jooq.util.postgres.information_schema.Tables.TABLES;
|
||||
import static org.jooq.util.postgres.information_schema.Tables.TABLE_CONSTRAINTS;
|
||||
import static org.jooq.util.postgres.pg_catalog.Tables.PG_CLASS;
|
||||
import static org.jooq.util.postgres.pg_catalog.Tables.PG_ENUM;
|
||||
import static org.jooq.util.postgres.pg_catalog.Tables.PG_INHERITS;
|
||||
import static org.jooq.util.postgres.pg_catalog.Tables.PG_NAMESPACE;
|
||||
import static org.jooq.util.postgres.pg_catalog.Tables.PG_TYPE;
|
||||
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.jooq.DSLContext;
|
||||
import org.jooq.Name;
|
||||
import org.jooq.Record;
|
||||
import org.jooq.Record2;
|
||||
import org.jooq.Record4;
|
||||
import org.jooq.Record5;
|
||||
import org.jooq.Result;
|
||||
import org.jooq.SQLDialect;
|
||||
import org.jooq.impl.DSL;
|
||||
import org.jooq.tools.JooqLogger;
|
||||
import org.jooq.util.AbstractDatabase;
|
||||
import org.jooq.util.ArrayDefinition;
|
||||
import org.jooq.util.ColumnDefinition;
|
||||
@ -93,6 +101,9 @@ import org.jooq.util.hsqldb.HSQLDBDatabase;
|
||||
import org.jooq.util.postgres.information_schema.tables.CheckConstraints;
|
||||
import org.jooq.util.postgres.information_schema.tables.Routines;
|
||||
import org.jooq.util.postgres.information_schema.tables.TableConstraints;
|
||||
import org.jooq.util.postgres.pg_catalog.tables.PgClass;
|
||||
import org.jooq.util.postgres.pg_catalog.tables.PgInherits;
|
||||
import org.jooq.util.postgres.pg_catalog.tables.PgNamespace;
|
||||
|
||||
/**
|
||||
* Postgres uses the ANSI default INFORMATION_SCHEMA, but unfortunately ships
|
||||
@ -103,6 +114,8 @@ import org.jooq.util.postgres.information_schema.tables.TableConstraints;
|
||||
*/
|
||||
public class PostgresDatabase extends AbstractDatabase {
|
||||
|
||||
private static final JooqLogger log = JooqLogger.getLogger(PostgresDatabase.class);
|
||||
|
||||
@Override
|
||||
protected void loadPrimaryKeys(DefaultRelations relations) throws SQLException {
|
||||
for (Record record : fetchKeys("PRIMARY KEY")) {
|
||||
@ -232,6 +245,7 @@ public class PostgresDatabase extends AbstractDatabase {
|
||||
@Override
|
||||
protected List<TableDefinition> getTables0() throws SQLException {
|
||||
List<TableDefinition> result = new ArrayList<TableDefinition>();
|
||||
Map<Name, PostgresTableDefinition> map = new HashMap<Name, PostgresTableDefinition>();
|
||||
|
||||
for (Record record : create()
|
||||
.select(
|
||||
@ -248,7 +262,51 @@ public class PostgresDatabase extends AbstractDatabase {
|
||||
String name = record.getValue(TABLES.TABLE_NAME);
|
||||
String comment = "";
|
||||
|
||||
result.add(new PostgresTableDefinition(schema, name, comment));
|
||||
PostgresTableDefinition t = new PostgresTableDefinition(schema, name, comment);
|
||||
result.add(t);
|
||||
map.put(name(schema.getName(), name), t);
|
||||
}
|
||||
|
||||
PgClass ct = PG_CLASS.as("ct");
|
||||
PgNamespace cn = PG_NAMESPACE.as("cn");
|
||||
PgInherits i = PG_INHERITS.as("i");
|
||||
PgClass pt = PG_CLASS.as("pt");
|
||||
PgNamespace pn = PG_NAMESPACE.as("pn");
|
||||
|
||||
for (Record5<String, String, String, String, Integer> inheritance : create()
|
||||
.select(
|
||||
cn.NSPNAME,
|
||||
ct.RELNAME,
|
||||
pn.NSPNAME,
|
||||
pt.RELNAME,
|
||||
max(i.INHSEQNO).over().partitionBy(i.INHRELID).as("m")
|
||||
)
|
||||
.from(ct)
|
||||
.join(cn).on("{0} = {1}.oid", ct.RELNAMESPACE, cn)
|
||||
.join(i).on("{0} = {1}.oid", i.INHRELID, ct)
|
||||
.join(pt).on("{0} = {1}.oid", i.INHPARENT, pt)
|
||||
.join(pn).on("{0} = {1}.oid", pt.RELNAMESPACE, pn)
|
||||
.fetch()) {
|
||||
|
||||
Name child = name(inheritance.value1(), inheritance.value2());
|
||||
Name parent = name(inheritance.value3(), inheritance.value4());
|
||||
|
||||
if (inheritance.value5() > 1) {
|
||||
log.info("Multiple inheritance",
|
||||
"Multiple inheritance is not supported by jOOQ: " +
|
||||
child +
|
||||
" inherits from " +
|
||||
parent);
|
||||
}
|
||||
else {
|
||||
PostgresTableDefinition childTable = map.get(child);
|
||||
PostgresTableDefinition parentTable = map.get(parent);
|
||||
|
||||
if (childTable != null && parentTable != null) {
|
||||
childTable.setParentTable(parentTable);
|
||||
parentTable.getChildTables().add(childTable);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
|
||||
@ -59,7 +59,7 @@ import static org.jooq.test.postgres.generatedclasses.Tables.T_DATES;
|
||||
import static org.jooq.test.postgres.generatedclasses.Tables.T_EXOTIC_TYPES;
|
||||
import static org.jooq.test.postgres.generatedclasses.Tables.T_IDENTITY;
|
||||
import static org.jooq.test.postgres.generatedclasses.Tables.T_IDENTITY_PK;
|
||||
import static org.jooq.test.postgres.generatedclasses.Tables.T_INHERITANCE_CITIES;
|
||||
import static org.jooq.test.postgres.generatedclasses.Tables.T_INHERITANCE_1;
|
||||
import static org.jooq.test.postgres.generatedclasses.Tables.T_PG_EXTENSIONS;
|
||||
import static org.jooq.test.postgres.generatedclasses.Tables.T_TRIGGERS;
|
||||
import static org.jooq.test.postgres.generatedclasses.Tables.T_UNSIGNED;
|
||||
@ -1065,7 +1065,7 @@ public class PostgresTest extends jOOQAbstractTest<
|
||||
|
||||
@Test
|
||||
public void testPostgresOnlyClause() throws Exception {
|
||||
assertEquals(3, create().fetchCount(selectOne().from(T_INHERITANCE_CITIES)));
|
||||
assertEquals(2, create().fetchCount(selectOne().from(only(T_INHERITANCE_CITIES))));
|
||||
assertEquals(3, create().fetchCount(selectOne().from(T_INHERITANCE_1)));
|
||||
assertEquals(2, create().fetchCount(selectOne().from(only(T_INHERITANCE_1))));
|
||||
}
|
||||
}
|
||||
|
||||
@ -64,8 +64,11 @@ DROP TABLE IF EXISTS t_booleans/
|
||||
DROP TABLE IF EXISTS t_identity/
|
||||
DROP TABLE IF EXISTS t_identity_pk/
|
||||
DROP TABLE IF EXISTS t_pg_extensions/
|
||||
DROP TABLE IF EXISTS t_inheritance_capitals/
|
||||
DROP TABLE IF EXISTS t_inheritance_cities/
|
||||
DROP TABLE IF EXISTS t_inheritance_1_all/
|
||||
DROP TABLE IF EXISTS t_inheritance_1_2_1/
|
||||
DROP TABLE IF EXISTS t_inheritance_1_2/
|
||||
DROP TABLE IF EXISTS t_inheritance_1_1/
|
||||
DROP TABLE IF EXISTS t_inheritance_1/
|
||||
|
||||
DROP TYPE IF EXISTS u_address_type/
|
||||
DROP TYPE IF EXISTS u_street_type/
|
||||
@ -110,16 +113,29 @@ CREATE TYPE u_address_type AS (
|
||||
)
|
||||
/
|
||||
|
||||
CREATE TABLE t_inheritance_cities (
|
||||
name text,
|
||||
population int,
|
||||
altitude int
|
||||
CREATE TABLE t_inheritance_1 (
|
||||
text_1 text
|
||||
)
|
||||
/
|
||||
|
||||
CREATE TABLE t_inheritance_capitals (
|
||||
state char(2)
|
||||
) INHERITS (t_inheritance_cities)
|
||||
CREATE TABLE t_inheritance_1_1 (
|
||||
text_1_1 text
|
||||
) INHERITS (t_inheritance_1)
|
||||
/
|
||||
|
||||
CREATE TABLE t_inheritance_1_2 (
|
||||
text_1_2 text
|
||||
) INHERITS (t_inheritance_1)
|
||||
/
|
||||
|
||||
CREATE TABLE t_inheritance_1_2_1 (
|
||||
text_1_2_1 text
|
||||
) INHERITS (t_inheritance_1_2)
|
||||
/
|
||||
|
||||
CREATE TABLE t_inheritance_all (
|
||||
text_1_all text
|
||||
) INHERITS (t_inheritance_1_1, t_inheritance_1_2)
|
||||
/
|
||||
|
||||
CREATE TABLE t_pg_extensions (
|
||||
|
||||
@ -54,6 +54,6 @@ INSERT INTO t_arrays VALUES (2, '{}', '{}', '{}', '{}', '{}', '{}')/
|
||||
INSERT INTO t_arrays VALUES (3, '{"a"}', '{1}', ARRAY[TO_DATE('1981-07-10', 'YYYY-MM-DD')], ARRAY[ROW('Downing Street', '10', null, E'\\x6969')]::u_street_type[], '{"England"}', ARRAY[ARRAY[1]])/
|
||||
INSERT INTO t_arrays VALUES (4, '{"a", "b"}', '{1, 2}', ARRAY[TO_DATE('1981-07-10', 'YYYY-MM-DD'), TO_DATE('2000-01-01', 'YYYY-MM-DD')], ARRAY[ROW('Downing Street', '10', '{}', E'\\x6969'), ROW('Bahnhofstrasse', '12', '{1, 2}', E'\\x6969')]::u_street_type[], '{"England", "Germany"}', ARRAY[ARRAY[1], ARRAY[2]])/
|
||||
|
||||
INSERT INTO t_inheritance_capitals VALUES ('Zurich', 396389, 408, 'ZH')/
|
||||
INSERT INTO t_inheritance_cities VALUES ('Winterthur', 103075, 439)/
|
||||
INSERT INTO t_inheritance_cities VALUES ('Uster', 32577, 464)/
|
||||
INSERT INTO t_inheritance_1_1 VALUES ('1', '1')/
|
||||
INSERT INTO t_inheritance_1 VALUES ('2')/
|
||||
INSERT INTO t_inheritance_1 VALUES ('3')/
|
||||
Loading…
Reference in New Issue
Block a user