org.jooq.impl.InformationSchemaMetaImpl Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of payment-retries-plugin Show documentation
Show all versions of payment-retries-plugin Show documentation
Kill Bill Payment Retries plugin
The newest version!
/*
* Copyright (c) 2009-2016, Data Geekery GmbH (http://www.datageekery.com)
* All rights reserved.
*
* 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
*
* http://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: http://www.jooq.org/licenses
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*/
package org.jooq.impl;
import static java.util.Collections.unmodifiableList;
import static org.jooq.impl.DSL.name;
import static org.jooq.util.xml.jaxb.TableConstraintType.PRIMARY_KEY;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.xml.bind.JAXB;
import org.jooq.Catalog;
import org.jooq.Configuration;
import org.jooq.DataType;
import org.jooq.ForeignKey;
import org.jooq.Meta;
import org.jooq.Name;
import org.jooq.Record;
import org.jooq.Schema;
import org.jooq.Sequence;
import org.jooq.Table;
import org.jooq.TableField;
import org.jooq.UniqueKey;
import org.jooq.exception.SQLDialectNotSupportedException;
import org.jooq.util.xml.jaxb.Column;
import org.jooq.util.xml.jaxb.InformationSchema;
import org.jooq.util.xml.jaxb.KeyColumnUsage;
import org.jooq.util.xml.jaxb.ReferentialConstraint;
import org.jooq.util.xml.jaxb.TableConstraint;
/**
* @author Lukas Eder
*/
final class InformationSchemaMetaImpl implements Meta {
private final Configuration configuration;
private final InformationSchema source;
private final List catalogs;
private final List schemas;
private final Map schemasByName;
private final Map> schemasPerCatalog;
private final List tables;
private final Map tablesByName;
private final Map> tablesPerSchema;
private final List> sequences;
private final Map>> sequencesPerSchema;
private final List> primaryKeys;
private final Map> uniqueKeysByName;
private final Map referentialKeys;
InformationSchemaMetaImpl(Configuration configuration, InformationSchema source) {
this.configuration = configuration;
this.source = source;
this.catalogs = new ArrayList();
this.schemas = new ArrayList();
this.schemasByName = new HashMap();
this.schemasPerCatalog = new HashMap>();
this.tables = new ArrayList();
this.tablesByName = new HashMap();
this.tablesPerSchema = new HashMap>();
this.sequences = new ArrayList>();
this.sequencesPerSchema = new HashMap>>();
this.primaryKeys = new ArrayList>();
this.uniqueKeysByName = new HashMap>();
this.referentialKeys = new HashMap();
init(source);
}
public static void main(String[] args) {
System.out.println(String.format("x y %0$s", "abc"));
}
private final void init(InformationSchema meta) {
List errors = new ArrayList();
// Catalogs / Schemas
// -------------------------------------------------------------------------------------------------------------
for (org.jooq.util.xml.jaxb.Schema xs : meta.getSchemata()) {
InformationSchemaCatalog catalog = new InformationSchemaCatalog(xs.getCatalogName());
if (!catalogs.contains(catalog))
catalogs.add(catalog);
InformationSchemaSchema is = new InformationSchemaSchema(xs.getSchemaName(), catalog);
schemas.add(is);
schemasByName.put(name(xs.getCatalogName(), xs.getSchemaName()), is);
}
// Tables
// -------------------------------------------------------------------------------------------------------------
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(String.format("Schema " + schemaName + " not defined for table " + xt.getTableName()));
continue tableLoop;
}
InformationSchemaTable it = new InformationSchemaTable(xt.getTableName(), schema);
tables.add(it);
tablesByName.put(name(xt.getTableCatalog(), xt.getTableSchema(), xt.getTableName()), it);
}
// Columns
// -------------------------------------------------------------------------------------------------------------
List columns = new ArrayList(meta.getColumns());
Collections.sort(columns, new Comparator() {
@Override
public int compare(Column o1, Column o2) {
Integer p1 = o1.getOrdinalPosition();
Integer p2 = o2.getOrdinalPosition();
if (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 = xc.isIsNullable() == null ? true : xc.isIsNullable();
// 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(String.format("Table " + tableName + " not defined for column " + xc.getColumnName()));
continue columnLoop;
}
AbstractTable.createField(
xc.getColumnName(),
type(typeName, length, precision, scale, nullable),
table
);
}
// Constraints
// -------------------------------------------------------------------------------------------------------------
Map>> columnsByConstraint = new HashMap>>();
List keyColumnUsages = new ArrayList(meta.getKeyColumnUsages());
Collections.sort(keyColumnUsages, new Comparator() {
@Override
public int compare(KeyColumnUsage o1, KeyColumnUsage o2) {
int p1 = o1.getOrdinalPosition();
int p2 = o2.getOrdinalPosition();
return (p1 < p2) ? -1 : ((p1 == p2) ? 0 : 1);
}
});
keyColumnLoop:
for (KeyColumnUsage xc : keyColumnUsages) {
Name constraintName = name(xc.getConstraintCatalog(), xc.getConstraintSchema(), xc.getConstraintName());
List> fields = columnsByConstraint.get(constraintName);
if (fields == null) {
fields = new ArrayList>();
columnsByConstraint.put(constraintName, fields);
}
Name tableName = name(xc.getTableCatalog(), xc.getTableSchema(), xc.getTableName());
InformationSchemaTable table = tablesByName.get(tableName);
if (table == null) {
errors.add(String.format("Table " + tableName + " not defined for constraint " + constraintName));
continue keyColumnLoop;
}
TableField field = (TableField) table.field(xc.getColumnName());
if (field == null) {
errors.add(String.format("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(String.format("Table " + tableName + " not defined for constraint " + constraintName));
continue tableConstraintLoop;
}
List> c = columnsByConstraint.get(constraintName);
if (c == null || c.isEmpty()) {
errors.add(String.format("No columns defined for constraint " + constraintName));
continue tableConstraintLoop;
}
UniqueKeyImpl key = (UniqueKeyImpl) AbstractKeys.createUniqueKey(table, xc.getConstraintName(), c.toArray(new TableField[0]));
if (xc.getConstraintType() == PRIMARY_KEY) {
table.primaryKey = key;
primaryKeys.add(key);
}
table.uniqueKeys.add(key);
uniqueKeysByName.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(String.format("Table " + tableName + " not defined for constraint " + constraintName));
continue tableConstraintLoop;
}
List> c = columnsByConstraint.get(constraintName);
if (c == null || c.isEmpty()) {
errors.add(String.format("No columns defined for constraint " + constraintName));
continue tableConstraintLoop;
}
UniqueKeyImpl uniqueKey = uniqueKeysByName.get(referentialKeys.get(constraintName));
if (uniqueKey == null) {
errors.add(String.format("No unique key defined for foreign key " + constraintName));
continue tableConstraintLoop;
}
ForeignKey key = AbstractKeys.createForeignKey(uniqueKey, table, xc.getConstraintName(), c.toArray(new TableField[0]));
table.foreignKeys.add(key);
break;
}
}
}
// Sequences
// -------------------------------------------------------------------------------------------------------------
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(String.format("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;
@SuppressWarnings({ "rawtypes", "unchecked" })
InformationSchemaSequence is = new InformationSchemaSequence(
xs.getSequenceName(),
schema,
type(typeName, length, precision, scale, nullable)
);
sequences.add(is);
}
// Lookups
// -------------------------------------------------------------------------------------------------------------
for (Schema s : schemas) {
Catalog c = s.getCatalog();
List list = schemasPerCatalog.get(c);
if (list == null) {
list = new ArrayList();
schemasPerCatalog.put(c, list);
}
list.add(s);
}
for (InformationSchemaTable t : tables) {
Schema s = t.getSchema();
List list = tablesPerSchema.get(s);
if (list == null) {
list = new ArrayList();
tablesPerSchema.put(s, list);
}
list.add(t);
}
for (Sequence> q : sequences) {
Schema s = q.getSchema();
List> list = sequencesPerSchema.get(s);
if (list == null) {
list = new ArrayList>();
sequencesPerSchema.put(s, list);
}
list.add(q);
}
if (!errors.isEmpty())
throw new IllegalArgumentException(errors.toString());
}
private final DataType> type(String typeName, int length, int precision, int scale, boolean nullable) {
DataType> type = null;
try {
type = DefaultDataType.getDataType(configuration.family(), typeName);
type = type.nullable(nullable);
if (length != 0)
type = type.length(length);
else if (precision != 0 || scale != 0)
type = type.precision(precision, scale);
}
catch (SQLDialectNotSupportedException e) {
type = SQLDataType.OTHER;
}
return type;
}
@Override
public final List getCatalogs() {
return Collections.unmodifiableList(catalogs);
}
@Override
public final List getSchemas() {
return Collections.unmodifiableList(schemas);
}
@Override
public final List> getTables() {
return Collections.>unmodifiableList(tables);
}
@Override
public final List> getSequences() {
return Collections.>unmodifiableList(sequences);
}
@Override
public final List> getPrimaryKeys() {
return Collections.>unmodifiableList(primaryKeys);
}
private final class InformationSchemaCatalog extends CatalogImpl {
/**
* Generated UID
*/
private static final long serialVersionUID = 87038321849045492L;
InformationSchemaCatalog(String name) {
super(name);
}
@Override
public final List getSchemas() {
return unmodifiableList(schemasPerCatalog.get(this));
}
}
private final class InformationSchemaSchema extends SchemaImpl {
/**
* Generated UID
*/
private static final long serialVersionUID = 7290709749127378187L;
public InformationSchemaSchema(String name, Catalog catalog) {
super(name, catalog);
}
@Override
public final List> getTables() {
return Collections.>unmodifiableList(tablesPerSchema.get(this));
}
@Override
public final List> getSequences() {
return Collections.>unmodifiableList(sequencesPerSchema.get(this));
}
}
private final class InformationSchemaTable extends TableImpl {
/**
* Generated UID
*/
private static final long serialVersionUID = 4314110578549768267L;
UniqueKey primaryKey;
final List> uniqueKeys = new ArrayList>();
final List> foreignKeys = new ArrayList>();
public InformationSchemaTable(String name, Schema schema) {
super(name, schema);
}
@Override
public UniqueKey getPrimaryKey() {
return primaryKey;
}
@Override
public List> getKeys() {
return Collections.>unmodifiableList(uniqueKeys);
}
@Override
public List> getReferences() {
return Collections.>unmodifiableList(foreignKeys);
}
}
private final class InformationSchemaSequence extends SequenceImpl {
/**
* Generated UID
*/
private static final long serialVersionUID = -1246697252597049756L;
InformationSchemaSequence(String name, Schema schema, DataType type) {
super(name, schema, type);
}
}
@Override
public String toString() {
StringWriter writer = new StringWriter();
JAXB.marshal(source, writer);
return writer.toString();
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy