Skip to content

Commit

Permalink
[#5437] Support unique keys and primary keys
Browse files Browse the repository at this point in the history
  • Loading branch information
lukaseder committed Jul 29, 2016
1 parent d624923 commit c23cc2a
Showing 1 changed file with 102 additions and 41 deletions.
143 changes: 102 additions & 41 deletions jOOQ/src/main/java/org/jooq/impl/InformationSchemaMetaImpl.java
Expand Up @@ -41,6 +41,8 @@
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.util.ArrayList;
import java.util.Collections;
Expand All @@ -54,41 +56,45 @@
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.TableConstraint;

/**
* @author Lukas Eder
*/
final class InformationSchemaMetaImpl implements Meta {

private final Configuration configuration;
private final List<Catalog> catalogs;
private final List<Schema> schemas;
private final Map<String, Schema> schemasByName;
private final Map<Catalog, List<Schema>> schemasPerCatalog;
private final List<Table<?>> tables;
private final Map<String, Table<?>> tablesByName;
private final Map<Schema, List<Table<?>>> tablesPerSchema;
private final List<Sequence<?>> sequences;
private final Map<Schema, List<Sequence<?>>> sequencesPerSchema;
private final List<UniqueKey<?>> primaryKeys;
private final Configuration configuration;
private final List<Catalog> catalogs;
private final List<Schema> schemas;
private final Map<Name, Schema> schemasByName;
private final Map<Catalog, List<Schema>> schemasPerCatalog;
private final List<InformationSchemaTable> tables;
private final Map<Name, InformationSchemaTable> tablesByName;
private final Map<Schema, List<InformationSchemaTable>> tablesPerSchema;
private final List<Sequence<?>> sequences;
private final Map<Schema, List<Sequence<?>>> sequencesPerSchema;
private final List<UniqueKey<?>> primaryKeys;

InformationSchemaMetaImpl(Configuration configuration, InformationSchema schema) {
this.configuration = configuration;
this.catalogs = new ArrayList<Catalog>();
this.schemas = new ArrayList<Schema>();
this.schemasByName = new HashMap<String, Schema>();
this.schemasByName = new HashMap<Name, Schema>();
this.schemasPerCatalog = new HashMap<Catalog, List<Schema>>();
this.tables = new ArrayList<Table<?>>();
this.tablesByName = new HashMap<String, Table<?>>();
this.tablesPerSchema = new HashMap<Schema, List<Table<?>>>();
this.tables = new ArrayList<InformationSchemaTable>();
this.tablesByName = new HashMap<Name, InformationSchemaTable>();
this.tablesPerSchema = new HashMap<Schema, List<InformationSchemaTable>>();
this.sequences = new ArrayList<Sequence<?>>();
this.sequencesPerSchema = new HashMap<Schema, List<Sequence<?>>>();
this.primaryKeys = new ArrayList<UniqueKey<?>>();
Expand All @@ -107,30 +113,13 @@ private final void init(InformationSchema meta) {

InformationSchemaSchema is = new InformationSchemaSchema(xs.getSchemaName(), catalog);
schemas.add(is);
schemasByName.put(xs.getSchemaName(), is);
schemasByName.put(name(xs.getCatalogName(), xs.getSchemaName()), is);
}

for (org.jooq.util.xml.jaxb.Table xt : meta.getTables()) {
InformationSchemaTable it = new InformationSchemaTable(xt.getTableName(), schemasByName.get(xt.getTableSchema()));
InformationSchemaTable it = new InformationSchemaTable(xt.getTableName(), schemasByName.get(name(xt.getTableCatalog(), xt.getTableSchema())));
tables.add(it);
tablesByName.put(xt.getTableName(), it);
}

for (org.jooq.util.xml.jaxb.Sequence xs : meta.getSequences()) {
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(),
schemasByName.get(xs.getSequenceSchema()),
type(typeName, length, precision, scale, nullable)
);

sequences.add(is);
tablesByName.put(name(xt.getTableCatalog(), xt.getTableSchema(), xt.getTableName()), it);
}

List<Column> columns = new ArrayList<Column>(meta.getColumns());
Expand Down Expand Up @@ -162,10 +151,79 @@ public int compare(Column o1, Column o2) {
AbstractTable.createField(
xc.getColumnName(),
type(typeName, length, precision, scale, nullable),
tablesByName.get(xc.getTableName())
tablesByName.get(name(xc.getTableCatalog(), xc.getTableSchema(), xc.getTableName()))
);
}

Map<Name, List<TableField<Record, ?>>> columnsByConstraint = new HashMap<Name, List<TableField<Record, ?>>>();
List<KeyColumnUsage> keyColumnUsages = new ArrayList<KeyColumnUsage>(meta.getKeyColumnUsages());
Collections.sort(keyColumnUsages, new Comparator<KeyColumnUsage>() {
@Override
public int compare(KeyColumnUsage o1, KeyColumnUsage 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);
}
});

for (KeyColumnUsage xc : keyColumnUsages) {
Name name = name(xc.getConstraintCatalog(), xc.getConstraintSchema(), xc.getConstraintName());
List<TableField<Record, ?>> fields = columnsByConstraint.get(name);

if (fields == null) {
fields = new ArrayList<TableField<Record, ?>>();
columnsByConstraint.put(name, fields);
}

InformationSchemaTable table = tablesByName.get(name(xc.getTableCatalog(), xc.getTableSchema(), xc.getTableName()));
fields.add((TableField<Record, ?>) table.field(xc.getColumnName()));
}

for (TableConstraint xc : meta.getTableConstraints()) {
switch (xc.getConstraintType()) {
case PRIMARY_KEY:
case UNIQUE: {
InformationSchemaTable table = tablesByName.get(name(xc.getTableCatalog(), xc.getTableSchema(), xc.getTableName()));
List<TableField<Record, ?>> c = columnsByConstraint.get(name(xc.getConstraintCatalog(), xc.getConstraintSchema(), xc.getConstraintName()));
UniqueKey<Record> key = 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);

break;
}
}
}

for (org.jooq.util.xml.jaxb.Sequence xs : meta.getSequences()) {
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(),
schemasByName.get(name(xs.getSequenceCatalog(), xs.getSequenceSchema())),
type(typeName, length, precision, scale, nullable)
);

sequences.add(is);
}

// Initialise indexes
for (Schema s : schemas) {
Catalog c = s.getCatalog();
Expand All @@ -179,12 +237,12 @@ public int compare(Column o1, Column o2) {
list.add(s);
}

for (Table<?> t : tables) {
for (InformationSchemaTable t : tables) {
Schema s = t.getSchema();
List<Table<?>> list = tablesPerSchema.get(s);
List<InformationSchemaTable> list = tablesPerSchema.get(s);

if (list == null) {
list = new ArrayList<Table<?>>();
list = new ArrayList<InformationSchemaTable>();
tablesPerSchema.put(s, list);
}

Expand Down Expand Up @@ -294,18 +352,21 @@ private final class InformationSchemaTable extends TableImpl<Record> {
*/
private static final long serialVersionUID = 4314110578549768267L;

UniqueKey<Record> primaryKey;
List<UniqueKey<Record>> uniqueKeys = new ArrayList<UniqueKey<Record>>();

public InformationSchemaTable(String name, Schema schema) {
super(name, schema);
}

@Override
public UniqueKey<Record> getPrimaryKey() {
return super.getPrimaryKey();
return primaryKey;
}

@Override
public List<UniqueKey<Record>> getKeys() {
return super.getKeys();
return Collections.unmodifiableList(uniqueKeys);
}

@Override
Expand Down

0 comments on commit c23cc2a

Please sign in to comment.