use of org.jooq.Table in project jOOQ by jOOQ.
the class JavaGenerator method generateSchema.
protected void generateSchema(SchemaDefinition schema, JavaWriter out) {
final String catalogId = out.ref(getStrategy().getFullJavaIdentifier(schema.getCatalog()), 2);
final String schemaId = getStrategy().getJavaIdentifier(schema);
final String schemaName = !schema.getQualifiedOutputName().isEmpty() ? schema.getQualifiedOutputName() : schemaId;
final String className = getStrategy().getJavaClassName(schema);
final List<String> interfaces = out.ref(getStrategy().getJavaClassImplements(schema, Mode.DEFAULT));
printPackage(out, schema);
if (scala) {
out.println("object %s {", className);
out.javadoc("The reference instance of <code>%s</code>", schemaName);
out.println("val %s = new %s", schemaId, className);
out.println("}");
out.println();
}
generateSchemaClassJavadoc(schema, out);
printClassAnnotations(out, schema, Mode.DEFAULT);
if (scala) {
out.println("%sclass %s extends %s(\"%s\", %s)[[before= with ][separator= with ][%s]] {", visibility(), className, SchemaImpl.class, escapeString(schema.getOutputName()), catalogId, interfaces);
} else if (kotlin) {
out.println("%sopen class %s : %s(\"%s\", %s)[[before=, ][%s]] {", visibility(), className, SchemaImpl.class, escapeString(schema.getOutputName()), catalogId, interfaces);
out.println("public companion object {");
out.javadoc("The reference instance of <code>%s</code>", schemaName);
out.println("%sval %s: %s = %s()", visibility(), scalaWhitespaceSuffix(schemaId), className, className);
out.println("}");
} else {
out.println("%sclass %s extends %s[[before= implements ][%s]] {", visibility(), className, SchemaImpl.class, interfaces);
out.printSerial();
out.javadoc("The reference instance of <code>%s</code>", schemaName);
out.println("%sstatic final %s %s = new %s();", visibility(), className, schemaId, className);
}
if (generateGlobalTableReferences()) {
Set<String> memberNames = getMemberNames(schema);
for (TableDefinition table : schema.getTables()) {
// reference in the schema, and the function call
if (scala && table.isTableValuedFunction() && table.getParameters().isEmpty())
continue;
final String tableClassName = out.ref(getStrategy().getFullJavaClassName(table));
final String tableId = getStrategy().getJavaIdentifier(table);
final String tableShortId = getShortId(out, memberNames, table);
final String tableComment = escapeEntities(comment(table));
out.javadoc(isBlank(tableComment) ? "The table <code>" + table.getQualifiedOutputName() + "</code>." : tableComment);
if (scala)
out.println("%sdef %s = %s", visibility(), tableId, tableShortId);
else if (kotlin)
out.println("%sval %s: %s get() = %s", visibility(), scalaWhitespaceSuffix(tableId), tableClassName, tableShortId);
else
out.println("%sfinal %s %s = %s;", visibility(), tableClassName, tableId, tableShortId);
// globalObjectReferences
if (table.isTableValuedFunction())
printTableValuedFunction(out, table, getStrategy().getJavaIdentifier(table));
}
}
if (!scala && !kotlin) {
out.javadoc(NO_FURTHER_INSTANCES_ALLOWED);
out.println("private %s() {", className);
out.println("super(\"%s\", null);", escapeString(schema.getOutputName()));
out.println("}");
}
out.println();
if (scala) {
out.println("%soverride def getCatalog: %s = %s", visibilityPublic(), Catalog.class, catalogId);
} else if (kotlin) {
out.println("%soverride fun getCatalog(): %s = %s", visibilityPublic(), Catalog.class, catalogId);
} else {
out.overrideInherit();
printNonnullAnnotation(out);
out.println("%s%s getCatalog() {", visibilityPublic(), Catalog.class);
out.println("return %s;", catalogId);
out.println("}");
}
// [#2255] Avoid referencing sequence literals, if they're not generated
if (generateGlobalSequenceReferences())
printReferences(out, database.getSequences(schema), Sequence.class, true);
// [#681] Avoid referencing domain literals, if they're not generated
if (generateGlobalDomainReferences())
printReferences(out, database.getDomains(schema), Domain.class, true);
// [#9685] Avoid referencing table literals if they're not generated
if (generateTables())
printReferences(out, database.getTables(schema), Table.class, true);
// [#9685] Avoid referencing UDT literals if they're not generated
if (generateUDTs())
printReferences(out, database.getUDTs(schema), UDT.class, true);
generateSchemaClassFooter(schema, out);
out.println("}");
}
use of org.jooq.Table in project jOOQ by jOOQ.
the class SelectQueryImpl method toSQLReference0.
/**
* This method renders the main part of a query without the LIMIT clause.
* This part is common to any type of limited query
*/
@SuppressWarnings("unchecked")
private final void toSQLReference0(Context<?> context, List<Field<?>> originalFields, List<Field<?>> alternativeFields) {
SQLDialect family = context.family();
boolean qualify = context.qualify();
int unionOpSize = unionOp.size();
boolean unionParensRequired = false;
boolean unionOpNesting = false;
// The SQL standard specifies:
//
// <query expression> ::=
// [ <with clause> ] <query expression body>
// [ <order by clause> ] [ <result offset clause> ] [ <fetch first clause> ]
//
// Depending on the dialect and on various syntax elements, parts of the above must be wrapped in
// synthetic parentheses
boolean wrapQueryExpressionInDerivedTable;
boolean wrapQueryExpressionBodyInDerivedTable;
boolean applySeekOnDerivedTable = applySeekOnDerivedTable();
wrapQueryExpressionInDerivedTable = false;
if (wrapQueryExpressionInDerivedTable)
context.visit(K_SELECT).sql(" *").formatSeparator().visit(K_FROM).sql(" (").formatIndentStart().formatNewLine();
wrapQueryExpressionBodyInDerivedTable = false || // predicate must be applied on a derived table, not on the individual subqueries
applySeekOnDerivedTable;
if (wrapQueryExpressionBodyInDerivedTable) {
context.visit(K_SELECT).sql(' ');
context.formatIndentStart().formatNewLine().sql("t.*");
if (alternativeFields != null && originalFields.size() < alternativeFields.size())
context.sql(", ").formatSeparator().declareFields(true, c -> c.visit(alternativeFields.get(alternativeFields.size() - 1)));
context.formatIndentEnd().formatSeparator().visit(K_FROM).sql(" (").formatIndentStart().formatNewLine();
}
// all databases, we need to wrap relevant subqueries in parentheses.
if (unionOpSize > 0) {
if (!TRUE.equals(context.data(DATA_NESTED_SET_OPERATIONS)))
context.data(DATA_NESTED_SET_OPERATIONS, unionOpNesting = unionOpNesting());
for (int i = unionOpSize - 1; i >= 0; i--) {
switch(unionOp.get(i)) {
case EXCEPT:
context.start(SELECT_EXCEPT);
break;
case EXCEPT_ALL:
context.start(SELECT_EXCEPT_ALL);
break;
case INTERSECT:
context.start(SELECT_INTERSECT);
break;
case INTERSECT_ALL:
context.start(SELECT_INTERSECT_ALL);
break;
case UNION:
context.start(SELECT_UNION);
break;
case UNION_ALL:
context.start(SELECT_UNION_ALL);
break;
}
// [#3676] There might be cases where nested set operations do not
// imply required parentheses in some dialects, but better
// play safe than sorry
unionParenthesis(context, '(', alternativeFields != null ? alternativeFields : getSelect(), derivedTableRequired(context, this), unionParensRequired = unionOpNesting || unionParensRequired(context));
}
}
traverseJoins(getFrom(), t -> {
if (t instanceof TableImpl)
context.scopeRegister(t, true);
});
for (Entry<QueryPart, QueryPart> entry : localQueryPartMapping.entrySet()) context.scopeRegister(entry.getKey(), true, entry.getValue());
// SELECT clause
// -------------
context.start(SELECT_SELECT).visit(K_SELECT).separatorRequired(true);
// [#1493] Oracle hints come directly after the SELECT keyword
if (!StringUtils.isBlank(hint))
context.sql(' ').sql(hint).separatorRequired(true);
if (Tools.isNotEmpty(distinctOn))
context.visit(K_DISTINCT_ON).sql(" (").visit(distinctOn).sql(')').separatorRequired(true);
else if (distinct)
context.visit(K_DISTINCT).separatorRequired(true);
if (TRUE.equals(context.data(BooleanDataKey.DATA_RENDERING_DATA_CHANGE_DELTA_TABLE)))
context.qualify(false);
context.declareFields(true);
// non-ambiguous column names as ambiguous column names are not allowed in subqueries
if (alternativeFields != null)
if (wrapQueryExpressionBodyInDerivedTable && originalFields.size() < alternativeFields.size())
context.visit(new SelectFieldList<>(alternativeFields.subList(0, originalFields.size())));
else
context.visit(new SelectFieldList<>(alternativeFields));
else
// The default behaviour
context.visit(getSelectResolveUnsupportedAsterisks(context.configuration()));
if (TRUE.equals(context.data(BooleanDataKey.DATA_RENDERING_DATA_CHANGE_DELTA_TABLE)))
context.qualify(qualify);
context.declareFields(false).end(SELECT_SELECT);
// only in top level SELECTs
if (!context.subquery()) {
context.start(SELECT_INTO);
QueryPart actualIntoTable = (QueryPart) context.data(DATA_SELECT_INTO_TABLE);
if (actualIntoTable == null)
actualIntoTable = intoTable;
if (actualIntoTable != null && !TRUE.equals(context.data(DATA_OMIT_INTO_CLAUSE)) && (SUPPORT_SELECT_INTO_TABLE.contains(context.dialect()) || !(actualIntoTable instanceof Table))) {
context.formatSeparator().visit(K_INTO).sql(' ').visit(actualIntoTable);
}
context.end(SELECT_INTO);
}
// FROM and JOIN clauses
// ---------------------
context.start(SELECT_FROM).declareTables(true);
// [#....] Some SQL dialects do not require a FROM clause. Others do and
// jOOQ generates a "DUAL" table or something equivalent.
// See also org.jooq.impl.Dual for details.
boolean hasFrom = !getFrom().isEmpty() || !OPTIONAL_FROM_CLAUSE.contains(context.dialect());
List<Condition> semiAntiJoinPredicates = null;
ConditionProviderImpl where = getWhere(context);
if (hasFrom) {
Object previousCollect = context.data(DATA_COLLECT_SEMI_ANTI_JOIN, true);
Object previousCollected = context.data(DATA_COLLECTED_SEMI_ANTI_JOIN, null);
TableList tablelist = getFrom();
tablelist = transformInlineDerivedTables(tablelist, where);
context.formatSeparator().visit(K_FROM).separatorRequired(true).visit(tablelist);
semiAntiJoinPredicates = (List<Condition>) context.data(DATA_COLLECTED_SEMI_ANTI_JOIN, previousCollected);
context.data(DATA_COLLECT_SEMI_ANTI_JOIN, previousCollect);
}
context.declareTables(false).end(SELECT_FROM);
// WHERE clause
// ------------
context.start(SELECT_WHERE);
if (TRUE.equals(context.data().get(BooleanDataKey.DATA_SELECT_NO_DATA)))
context.formatSeparator().visit(K_WHERE).sql(' ').visit(falseCondition());
else if (!where.hasWhere() && semiAntiJoinPredicates == null)
;
else {
ConditionProviderImpl actual = new ConditionProviderImpl();
if (semiAntiJoinPredicates != null)
actual.addConditions(semiAntiJoinPredicates);
if (where.hasWhere())
actual.addConditions(where.getWhere());
context.formatSeparator().visit(K_WHERE).sql(' ').visit(actual);
}
context.end(SELECT_WHERE);
// GROUP BY and HAVING clause
// --------------------------
context.start(SELECT_GROUP_BY);
if (!getGroupBy().isEmpty()) {
context.formatSeparator().visit(K_GROUP_BY);
if (groupByDistinct)
context.sql(' ').visit(K_DISTINCT);
context.separatorRequired(true);
context.visit(groupBy);
}
context.end(SELECT_GROUP_BY);
// HAVING clause
// -------------
context.start(SELECT_HAVING);
if (getHaving().hasWhere())
context.formatSeparator().visit(K_HAVING).sql(' ').visit(getHaving());
context.end(SELECT_HAVING);
// WINDOW clause
// -------------
context.start(SELECT_WINDOW);
if (Tools.isNotEmpty(window) && !NO_SUPPORT_WINDOW_CLAUSE.contains(context.dialect()))
context.formatSeparator().visit(K_WINDOW).separatorRequired(true).declareWindows(true, c -> c.visit(window));
context.end(SELECT_WINDOW);
if (getQualify().hasWhere())
context.formatSeparator().visit(K_QUALIFY).sql(' ').visit(getQualify());
// ORDER BY clause for local subselect
// -----------------------------------
toSQLOrderBy(context, originalFields, alternativeFields, false, wrapQueryExpressionBodyInDerivedTable, orderBy, limit);
// --------------------------------------------
if (unionOpSize > 0) {
unionParenthesis(context, ')', null, derivedTableRequired(context, this), unionParensRequired);
for (int i = 0; i < unionOpSize; i++) {
CombineOperator op = unionOp.get(i);
for (Select<?> other : union.get(i)) {
boolean derivedTableRequired = derivedTableRequired(context, other);
context.formatSeparator().visit(op.toKeyword(family));
if (unionParensRequired)
context.sql(' ');
else
context.formatSeparator();
unionParenthesis(context, '(', other.getSelect(), derivedTableRequired, unionParensRequired);
context.visit(other);
unionParenthesis(context, ')', null, derivedTableRequired, unionParensRequired);
}
// [#1658] Close parentheses opened previously
if (i < unionOpSize - 1)
unionParenthesis(context, ')', null, derivedTableRequired(context, this), unionParensRequired);
switch(unionOp.get(i)) {
case EXCEPT:
context.end(SELECT_EXCEPT);
break;
case EXCEPT_ALL:
context.end(SELECT_EXCEPT_ALL);
break;
case INTERSECT:
context.end(SELECT_INTERSECT);
break;
case INTERSECT_ALL:
context.end(SELECT_INTERSECT_ALL);
break;
case UNION:
context.end(SELECT_UNION);
break;
case UNION_ALL:
context.end(SELECT_UNION_ALL);
break;
}
}
if (unionOpNesting)
context.data().remove(DATA_NESTED_SET_OPERATIONS);
}
if (wrapQueryExpressionBodyInDerivedTable) {
context.formatIndentEnd().formatNewLine().sql(") t");
if (applySeekOnDerivedTable) {
context.formatSeparator().visit(K_WHERE).sql(' ').qualify(false, c -> c.visit(getSeekCondition()));
}
}
// ORDER BY clause for UNION
// -------------------------
context.qualify(false, c -> toSQLOrderBy(context, originalFields, alternativeFields, wrapQueryExpressionInDerivedTable, wrapQueryExpressionBodyInDerivedTable, unionOrderBy, unionLimit));
}
use of org.jooq.Table in project jOOQ by jOOQ.
the class SelectQueryImpl method getSelectResolveSomeAsterisks0.
private final SelectFieldList<SelectFieldOrAsterisk> getSelectResolveSomeAsterisks0(Configuration c, boolean resolveSupported) {
SelectFieldList<SelectFieldOrAsterisk> result = new SelectFieldList<>();
// [#7921] Only H2 supports the * EXCEPT (..) syntax
boolean resolveExcept = resolveSupported || !SUPPORT_NATIVE_EXCEPT.contains(c.dialect());
boolean resolveUnqualifiedCombined = resolveSupported || NO_SUPPORT_UNQUALIFIED_COMBINED.contains(c.dialect());
// [#7921] TODO Find a better, more efficient way to resolve asterisks
SelectFieldList<SelectFieldOrAsterisk> list = getSelectResolveImplicitAsterisks();
for (SelectFieldOrAsterisk s : list) if (s instanceof Field)
result.add(getResolveProjection(c, (Field<?>) s));
else if (s instanceof QualifiedAsteriskImpl) {
QualifiedAsteriskImpl q = (QualifiedAsteriskImpl) s;
if (q.fields.isEmpty())
if (resolveSupported)
result.addAll(Arrays.asList(q.qualifier().fields()));
else
result.add(s);
else if (resolveExcept)
result.addAll(subtract(Arrays.asList(((QualifiedAsterisk) s).qualifier().fields()), (((QualifiedAsteriskImpl) s).fields)));
else
result.add(s);
} else if (s instanceof AsteriskImpl) {
AsteriskImpl a = (AsteriskImpl) s;
if (a.fields.isEmpty())
if (resolveSupported || resolveUnqualifiedCombined && list.size() > 1)
result.addAll(resolveAsterisk(new QueryPartList<>()));
else
result.add(s);
else if (resolveExcept)
result.addAll(resolveAsterisk(new QueryPartList<>(), a.fields));
else
result.add(s);
} else if (s instanceof Row)
result.add(getResolveProjection(c, new RowAsField<Row, Record>((Row) s)));
else if (s instanceof Table)
result.add(getResolveProjection(c, new TableAsField<>((Table<?>) s)));
else
throw new AssertionError("Type not supported: " + s);
return result;
}
use of org.jooq.Table in project jOOQ by jOOQ.
the class InformationSchemaMetaImpl method init.
@SuppressWarnings({ "unchecked", "rawtypes" })
private final void init(InformationSchema meta) {
List<String> errors = new ArrayList<>();
// Catalogs
// -------------------------------------------------------------------------------------------------------------
boolean hasCatalogs = false;
for (org.jooq.util.xml.jaxb.Catalog xc : meta.getCatalogs()) {
InformationSchemaCatalog ic = new InformationSchemaCatalog(xc.getCatalogName(), xc.getComment());
catalogs.add(ic);
catalogsByName.put(name(xc.getCatalogName()), ic);
hasCatalogs = true;
}
// -------------------------------------------------------------------------------------------------------------
schemaLoop: for (org.jooq.util.xml.jaxb.Schema xs : meta.getSchemata()) {
// [#6662] This is kept for backwards compatibility reasons
if (!hasCatalogs) {
InformationSchemaCatalog ic = new InformationSchemaCatalog(xs.getCatalogName(), null);
if (!catalogs.contains(ic)) {
catalogs.add(ic);
catalogsByName.put(name(xs.getCatalogName()), ic);
}
}
Name catalogName = name(xs.getCatalogName());
Catalog catalog = catalogsByName.get(catalogName);
if (catalog == null) {
errors.add("Catalog " + catalogName + " not defined for schema " + xs.getSchemaName());
continue schemaLoop;
}
InformationSchemaSchema is = new InformationSchemaSchema(xs.getSchemaName(), catalog, xs.getComment());
schemas.add(is);
schemasByName.put(name(xs.getCatalogName(), xs.getSchemaName()), is);
}
// -------------------------------------------------------------------------------------------------------------
domainLoop: for (org.jooq.util.xml.jaxb.Domain d : meta.getDomains()) {
Name schemaName = name(d.getDomainCatalog(), d.getDomainSchema());
Schema schema = schemasByName.get(schemaName);
if (schema == null) {
errors.add("Schema " + schemaName + " not defined for domain " + d.getDomainName());
continue domainLoop;
}
Name domainName = name(d.getDomainCatalog(), d.getDomainSchema(), d.getDomainName());
int length = d.getCharacterMaximumLength() == null ? 0 : d.getCharacterMaximumLength();
int precision = d.getNumericPrecision() == null ? 0 : d.getNumericPrecision();
int scale = d.getNumericScale() == null ? 0 : d.getNumericScale();
// TODO [#10239] Support NOT NULL constraints
boolean nullable = true;
List<Check<?>> checks = new ArrayList<>();
for (org.jooq.util.xml.jaxb.DomainConstraint dc : meta.getDomainConstraints()) {
if (domainName.equals(name(dc.getDomainCatalog(), dc.getDomainSchema(), dc.getDomainName()))) {
Name constraintName = name(dc.getConstraintCatalog(), dc.getConstraintSchema(), dc.getConstraintName());
for (org.jooq.util.xml.jaxb.CheckConstraint cc : meta.getCheckConstraints()) if (constraintName.equals(name(cc.getConstraintCatalog(), cc.getConstraintSchema(), cc.getConstraintName())))
checks.add(new CheckImpl<>(null, constraintName, DSL.condition(cc.getCheckClause()), true));
}
}
InformationSchemaDomain<?> id = new InformationSchemaDomain<Object>(schema, name(d.getDomainName()), (DataType) type(d.getDataType(), length, precision, scale, nullable, false, null, null), checks.toArray(EMPTY_CHECK));
domains.add(id);
domainsByName.put(domainName, id);
}
// -------------------------------------------------------------------------------------------------------------
tableLoop: for (org.jooq.util.xml.jaxb.Table xt : meta.getTables()) {
Name schemaName = name(xt.getTableCatalog(), xt.getTableSchema());
Schema schema = schemasByName.get(schemaName);
if (schema == null) {
errors.add("Schema " + schemaName + " not defined for table " + xt.getTableName());
continue tableLoop;
}
TableType tableType;
switch(xt.getTableType()) {
case GLOBAL_TEMPORARY:
tableType = TableType.TEMPORARY;
break;
case VIEW:
tableType = TableType.VIEW;
break;
case BASE_TABLE:
default:
tableType = TableType.TABLE;
break;
}
String sql = null;
if (tableType == TableType.VIEW) {
viewLoop: for (org.jooq.util.xml.jaxb.View vt : meta.getViews()) {
if (StringUtils.equals(defaultIfNull(xt.getTableCatalog(), ""), defaultIfNull(vt.getTableCatalog(), "")) && StringUtils.equals(defaultIfNull(xt.getTableSchema(), ""), defaultIfNull(vt.getTableSchema(), "")) && StringUtils.equals(defaultIfNull(xt.getTableName(), ""), defaultIfNull(vt.getTableName(), ""))) {
sql = vt.getViewDefinition();
break viewLoop;
}
}
}
InformationSchemaTable it = new InformationSchemaTable(xt.getTableName(), schema, xt.getComment(), tableType, sql);
tables.add(it);
tablesByName.put(name(xt.getTableCatalog(), xt.getTableSchema(), xt.getTableName()), it);
}
// Columns
// -------------------------------------------------------------------------------------------------------------
List<Column> columns = new ArrayList<>(meta.getColumns());
columns.sort((o1, o2) -> {
Integer p1 = o1.getOrdinalPosition();
Integer p2 = o2.getOrdinalPosition();
if (Objects.equals(p1, p2))
return 0;
if (p1 == null)
return -1;
if (p2 == null)
return 1;
return p1.compareTo(p2);
});
columnLoop: for (Column xc : columns) {
String typeName = xc.getDataType();
int length = xc.getCharacterMaximumLength() == null ? 0 : xc.getCharacterMaximumLength();
int precision = xc.getNumericPrecision() == null ? 0 : xc.getNumericPrecision();
int scale = xc.getNumericScale() == null ? 0 : xc.getNumericScale();
boolean nullable = !FALSE.equals(xc.isIsNullable());
boolean readonly = TRUE.equals(xc.isReadonly());
Field<?> generatedAlwaysAs = TRUE.equals(xc.isIsGenerated()) ? DSL.field(xc.getGenerationExpression()) : null;
GenerationOption generationOption = TRUE.equals(xc.isIsGenerated()) ? "STORED".equalsIgnoreCase(xc.getGenerationOption()) ? STORED : "VIRTUAL".equalsIgnoreCase(xc.getGenerationOption()) ? VIRTUAL : null : null;
// TODO: Exception handling should be moved inside SQLDataType
Name tableName = name(xc.getTableCatalog(), xc.getTableSchema(), xc.getTableName());
InformationSchemaTable table = tablesByName.get(tableName);
if (table == null) {
errors.add("Table " + tableName + " not defined for column " + xc.getColumnName());
continue columnLoop;
}
AbstractTable.createField(name(xc.getColumnName()), type(typeName, length, precision, scale, nullable, readonly, generatedAlwaysAs, generationOption), table, xc.getComment());
}
// Indexes
// -------------------------------------------------------------------------------------------------------------
Map<Name, List<SortField<?>>> columnsByIndex = new HashMap<>();
List<IndexColumnUsage> indexColumnUsages = new ArrayList<>(meta.getIndexColumnUsages());
indexColumnUsages.sort(comparingInt(IndexColumnUsage::getOrdinalPosition));
indexColumnLoop: for (IndexColumnUsage ic : indexColumnUsages) {
Name indexName = name(ic.getIndexCatalog(), ic.getIndexSchema(), ic.getTableName(), ic.getIndexName());
List<SortField<?>> fields = columnsByIndex.computeIfAbsent(indexName, k -> new ArrayList<>());
Name tableName = name(ic.getTableCatalog(), ic.getTableSchema(), ic.getTableName());
InformationSchemaTable table = tablesByName.get(tableName);
if (table == null) {
errors.add("Table " + tableName + " not defined for index " + indexName);
continue indexColumnLoop;
}
TableField<Record, ?> field = (TableField<Record, ?>) table.field(ic.getColumnName());
if (field == null) {
errors.add("Column " + ic.getColumnName() + " not defined for table " + tableName);
continue indexColumnLoop;
}
fields.add(Boolean.TRUE.equals(ic.isIsDescending()) ? field.desc() : field.asc());
}
indexLoop: for (org.jooq.util.xml.jaxb.Index i : meta.getIndexes()) {
Name tableName = name(i.getTableCatalog(), i.getTableSchema(), i.getTableName());
Name indexName = name(i.getIndexCatalog(), i.getIndexSchema(), i.getTableName(), i.getIndexName());
InformationSchemaTable table = tablesByName.get(tableName);
if (table == null) {
errors.add("Table " + tableName + " not defined for index " + indexName);
continue indexLoop;
}
List<SortField<?>> c = columnsByIndex.get(indexName);
if (c == null || c.isEmpty()) {
errors.add("No columns defined for index " + indexName);
continue indexLoop;
}
IndexImpl index = (IndexImpl) Internal.createIndex(i.getIndexName(), table, c.toArray(EMPTY_SORTFIELD), Boolean.TRUE.equals(i.isIsUnique()));
table.indexes.add(index);
indexesByName.put(indexName, index);
}
// Constraints
// -------------------------------------------------------------------------------------------------------------
Map<Name, List<TableField<Record, ?>>> columnsByConstraint = new HashMap<>();
List<KeyColumnUsage> keyColumnUsages = new ArrayList<>(meta.getKeyColumnUsages());
keyColumnUsages.sort(comparing(KeyColumnUsage::getOrdinalPosition));
keyColumnLoop: for (KeyColumnUsage xc : keyColumnUsages) {
Name constraintName = name(xc.getConstraintCatalog(), xc.getConstraintSchema(), xc.getConstraintName());
List<TableField<Record, ?>> fields = columnsByConstraint.computeIfAbsent(constraintName, k -> new ArrayList<>());
Name tableName = name(xc.getTableCatalog(), xc.getTableSchema(), xc.getTableName());
InformationSchemaTable table = tablesByName.get(tableName);
if (table == null) {
errors.add("Table " + tableName + " not defined for constraint " + constraintName);
continue keyColumnLoop;
}
TableField<Record, ?> field = (TableField<Record, ?>) table.field(xc.getColumnName());
if (field == null) {
errors.add("Column " + xc.getColumnName() + " not defined for table " + tableName);
continue keyColumnLoop;
}
fields.add(field);
}
tableConstraintLoop: for (TableConstraint xc : meta.getTableConstraints()) {
switch(xc.getConstraintType()) {
case PRIMARY_KEY:
case UNIQUE:
{
Name tableName = name(xc.getTableCatalog(), xc.getTableSchema(), xc.getTableName());
Name constraintName = name(xc.getConstraintCatalog(), xc.getConstraintSchema(), xc.getConstraintName());
InformationSchemaTable table = tablesByName.get(tableName);
if (table == null) {
errors.add("Table " + tableName + " not defined for constraint " + constraintName);
continue tableConstraintLoop;
}
List<TableField<Record, ?>> c = columnsByConstraint.get(constraintName);
if (c == null || c.isEmpty()) {
errors.add("No columns defined for constraint " + constraintName);
continue tableConstraintLoop;
}
UniqueKeyImpl<Record> key = (UniqueKeyImpl<Record>) Internal.createUniqueKey(table, xc.getConstraintName(), c.toArray(new TableField[0]));
if (xc.getConstraintType() == PRIMARY_KEY) {
table.primaryKey = key;
primaryKeys.add(key);
} else
table.uniqueKeys.add(key);
keysByName.put(constraintName, key);
break;
}
}
}
for (ReferentialConstraint xr : meta.getReferentialConstraints()) {
referentialKeys.put(name(xr.getConstraintCatalog(), xr.getConstraintSchema(), xr.getConstraintName()), name(xr.getUniqueConstraintCatalog(), xr.getUniqueConstraintSchema(), xr.getUniqueConstraintName()));
}
tableConstraintLoop: for (TableConstraint xc : meta.getTableConstraints()) {
switch(xc.getConstraintType()) {
case FOREIGN_KEY:
{
Name tableName = name(xc.getTableCatalog(), xc.getTableSchema(), xc.getTableName());
Name constraintName = name(xc.getConstraintCatalog(), xc.getConstraintSchema(), xc.getConstraintName());
InformationSchemaTable table = tablesByName.get(tableName);
if (table == null) {
errors.add("Table " + tableName + " not defined for constraint " + constraintName);
continue tableConstraintLoop;
}
List<TableField<Record, ?>> c = columnsByConstraint.get(constraintName);
if (c == null || c.isEmpty()) {
errors.add("No columns defined for constraint " + constraintName);
continue tableConstraintLoop;
}
UniqueKeyImpl<Record> uniqueKey = keysByName.get(referentialKeys.get(constraintName));
if (uniqueKey == null) {
errors.add("No unique key defined for foreign key " + constraintName);
continue tableConstraintLoop;
}
ForeignKey<Record, Record> key = Internal.createForeignKey(uniqueKey, table, xc.getConstraintName(), c.toArray(new TableField[0]));
table.foreignKeys.add(key);
break;
}
}
}
tableConstraintLoop: for (TableConstraint xc : meta.getTableConstraints()) {
switch(xc.getConstraintType()) {
case CHECK:
{
Name tableName = name(xc.getTableCatalog(), xc.getTableSchema(), xc.getTableName());
Name constraintName = name(xc.getConstraintCatalog(), xc.getConstraintSchema(), xc.getConstraintName());
InformationSchemaTable table = tablesByName.get(tableName);
if (table == null) {
errors.add("Table " + tableName + " not defined for constraint " + constraintName);
continue tableConstraintLoop;
}
for (CheckConstraint cc : meta.getCheckConstraints()) {
if (constraintName.equals(name(cc.getConstraintCatalog(), cc.getConstraintSchema(), cc.getConstraintName()))) {
table.checks.add(new CheckImpl<>(table, constraintName, DSL.condition(cc.getCheckClause()), true));
continue tableConstraintLoop;
}
}
errors.add("No check clause found for check constraint " + constraintName);
continue tableConstraintLoop;
}
}
}
// -------------------------------------------------------------------------------------------------------------
sequenceLoop: for (org.jooq.util.xml.jaxb.Sequence xs : meta.getSequences()) {
Name schemaName = name(xs.getSequenceCatalog(), xs.getSequenceSchema());
Schema schema = schemasByName.get(schemaName);
if (schema == null) {
errors.add("Schema " + schemaName + " not defined for sequence " + xs.getSequenceName());
continue sequenceLoop;
}
String typeName = xs.getDataType();
int length = xs.getCharacterMaximumLength() == null ? 0 : xs.getCharacterMaximumLength();
int precision = xs.getNumericPrecision() == null ? 0 : xs.getNumericPrecision();
int scale = xs.getNumericScale() == null ? 0 : xs.getNumericScale();
boolean nullable = true;
BigInteger startWith = xs.getStartValue();
BigInteger incrementBy = xs.getIncrement();
BigInteger minvalue = xs.getMinimumValue();
BigInteger maxvalue = xs.getMaximumValue();
Boolean cycle = xs.isCycleOption();
BigInteger cache = xs.getCache();
InformationSchemaSequence is = new InformationSchemaSequence(xs.getSequenceName(), schema, type(typeName, length, precision, scale, nullable, false, null, null), startWith, incrementBy, minvalue, maxvalue, cycle, cache);
sequences.add(is);
}
// -------------------------------------------------------------------------------------------------------------
for (Schema s : schemas) initLookup(schemasPerCatalog, s.getCatalog(), s);
for (InformationSchemaDomain<?> d : domains) initLookup(domainsPerSchema, d.getSchema(), d);
for (InformationSchemaTable t : tables) initLookup(tablesPerSchema, t.getSchema(), t);
for (Sequence<?> q : sequences) initLookup(sequencesPerSchema, q.getSchema(), q);
if (!errors.isEmpty())
throw new IllegalArgumentException(errors.toString());
}
use of org.jooq.Table in project jOOQ by jOOQ.
the class InformationSchemaExport method exportTable0.
private static final void exportTable0(Configuration configuration, InformationSchema result, Table<?> t, Set<Table<?>> includedTables) {
org.jooq.util.xml.jaxb.Table it = new org.jooq.util.xml.jaxb.Table();
String catalogName = catalogName(t);
String schemaName = schemaName(t);
if (!isBlank(catalogName))
it.setTableCatalog(catalogName);
if (!isBlank(schemaName))
it.setTableSchema(schemaName);
switch(t.getOptions().type()) {
case MATERIALIZED_VIEW:
case VIEW:
it.setTableType(TableType.VIEW);
break;
case TEMPORARY:
it.setTableType(TableType.GLOBAL_TEMPORARY);
break;
case FUNCTION:
case TABLE:
case EXPRESSION:
case UNKNOWN:
default:
it.setTableType(TableType.BASE_TABLE);
break;
}
it.setTableName(t.getName());
it.setComment(t.getComment());
result.getTables().add(it);
if (t.getOptions().type() == org.jooq.TableOptions.TableType.VIEW) {
org.jooq.util.xml.jaxb.View iv = new org.jooq.util.xml.jaxb.View();
if (!isBlank(catalogName))
iv.setTableCatalog(catalogName);
if (!isBlank(schemaName))
iv.setTableSchema(schemaName);
iv.setTableName(t.getName());
iv.setViewDefinition(t.getOptions().source());
result.getViews().add(iv);
}
Field<?>[] fields = t.fields();
for (int i = 0; i < fields.length; i++) {
Field<?> f = fields[i];
DataType<?> type = f.getDataType();
Column ic = new Column();
if (!isBlank(catalogName))
ic.setTableCatalog(catalogName);
if (!isBlank(schemaName))
ic.setTableSchema(schemaName);
ic.setTableName(t.getName());
ic.setColumnName(f.getName());
ic.setComment(f.getComment());
ic.setDataType(type.getTypeName(configuration));
if (type.lengthDefined())
ic.setCharacterMaximumLength(type.length());
if (type.precisionDefined())
ic.setNumericPrecision(type.precision());
if (type.scaleDefined())
ic.setNumericScale(type.scale());
ic.setColumnDefault(DSL.using(configuration).render(type.defaultValue()));
ic.setIsNullable(type.nullable());
ic.setOrdinalPosition(i + 1);
ic.setReadonly(type.readonly());
if (type.computed()) {
ic.setIsGenerated(type.computed());
ic.setGenerationExpression(DSL.using(configuration).render(type.generatedAlwaysAs()));
ic.setGenerationOption(type.generationOption() == VIRTUAL ? "VIRTUAL" : type.generationOption() == STORED ? "STORED" : null);
}
result.getColumns().add(ic);
}
for (UniqueKey<?> key : t.getKeys()) exportKey0(result, t, key, key.isPrimary() ? PRIMARY_KEY : UNIQUE);
for (ForeignKey<?, ?> fk : t.getReferences()) if (includedTables.contains(fk.getKey().getTable()))
exportKey0(result, t, fk, FOREIGN_KEY);
for (Check<?> chk : t.getChecks()) if (includedTables.contains(chk.getTable()))
exportCheck0(configuration, result, t, chk);
for (Index index : t.getIndexes()) exportIndex0(result, t, index);
}
Aggregations