[#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:
Lukas Eder 2013-10-16 14:05:09 +02:00
parent be485c7d1b
commit 5b10860d7c
6 changed files with 120 additions and 16 deletions

View File

@ -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());

View File

@ -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}.
*/

View File

@ -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;

View File

@ -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))));
}
}

View File

@ -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 (

View File

@ -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')/