/** * Copyright (C) 2009-2013 FoundationDB, LLC * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package com.foundationdb.ais.model; import com.foundationdb.ais.model.validation.AISInvariants; import java.util.ArrayList; import java.util.Collections; import java.util.LinkedList; import java.util.List; public class Join implements HasGroup, Constraint { public static Join create(AkibanInformationSchema ais, String joinName, Table parent, Table child) { ais.checkMutability(); Join join = new Join(joinName, parent, child); join.parent.addCandidateChildJoin(join); join.child.addCandidateParentJoin(join); AISInvariants.checkDuplicateConstraintsInSchema(ais, join.getConstraintName()); ais.addJoin(join); ais.addConstraint(join); return join; } // used by the Foreign Key to track internal joins. protected static Join create (String joinName, Table parent, Table child) { Join join = new Join (joinName, parent, child); return join; } @Override public String toString() { return getGroup() == null ? "Join(" + joinName + ": " + child + " -> " + parent + ")" : "Join(" + joinName + ": " + child + " -> " + parent + ", group(" + getGroup().getName() + "))"; } public JoinColumn addJoinColumn(Column parent, Column child) { assert this.childColumns == null : "Modifying fixed Join child columns"; assert this.parentColumns == null: "Modifying fixed Join parent columns"; JoinColumn joinColumn = new JoinColumn(this, parent, child); joinColumns.add(joinColumn); return joinColumn; } public String getDescription() { StringBuilder buffer = new StringBuilder(); buffer.append(parent); buffer.append(" <- "); buffer.append(child); return buffer.toString(); } public String getName() { return joinName; } public Table getParent() { return parent; } public Table getChild() { return child; } public Group getGroup() { return group; } public void setGroup(Group group) { this.group = group; } public List<JoinColumn> getJoinColumns() { return joinColumns; } public List<Column> getChildColumns() { if (this.childColumns == null) { List<Column> childColumns = new ArrayList<Column>(joinColumns.size()); for (JoinColumn joinColumn : joinColumns) { childColumns.add(joinColumn.getChild()); } this.childColumns = Collections.unmodifiableList(childColumns); } return this.childColumns; } public List<Column> getParentColumns() { if (this.parentColumns == null) { List<Column> parentColumns = new ArrayList<Column>(joinColumns.size()); for (JoinColumn joinColumn : joinColumns) { parentColumns.add(joinColumn.getParent()); } this.parentColumns = Collections.unmodifiableList(parentColumns); } return this.parentColumns; } public Column getMatchingChild(Column parentColumn) { for (JoinColumn joinColumn : joinColumns) { if (joinColumn.getParent() == parentColumn) { return joinColumn.getChild(); } } return null; } public Column getMatchingParent(Column childColumn) { for (JoinColumn joinColumn : joinColumns) { if (joinColumn.getChild() == childColumn) { return joinColumn.getParent(); } } return null; } public void replaceName(String newName) { joinName = newName; } @Override public Table getConstraintTable() { return child; } @Override public TableName getConstraintName(){ return constraintName; } private Join (String joinName, Table parent, Table child) { this.joinName = joinName; this.parent = parent; this.child = child; joinColumns = new LinkedList<>(); this.constraintName = new TableName(parent.getName().getSchemaName(), joinName); } // State private final Table parent; private final Table child; private final List<JoinColumn> joinColumns; private List<Column> childColumns; private List<Column> parentColumns; private String joinName; private Group group; private TableName constraintName; }