use of org.jooq.impl.QOM.GenerationOption.VIRTUAL 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());
}
Aggregations