package io.ebeaninternal.server.deploy;
import io.ebean.util.SplitName;
import io.ebeaninternal.server.core.InternString;
import io.ebeaninternal.server.deploy.meta.DeployTableJoin;
import io.ebeaninternal.server.deploy.meta.DeployTableJoinColumn;
import io.ebeaninternal.server.query.SqlJoinType;
public final class TableJoin {
private final String table;
private final SqlJoinType type;
private final InheritInfo inheritInfo;
private final TableJoinColumn[] columns;
private final int queryHash;
private final PropertyForeignKey foreignKey;
public TableJoin(DeployTableJoin deploy) {
this(deploy, null);
}
public TableJoin(DeployTableJoin deploy, PropertyForeignKey foreignKey) {
this.foreignKey = foreignKey;
this.table = InternString.intern(deploy.getTable());
this.type = deploy.getType();
this.inheritInfo = deploy.getInheritInfo();
DeployTableJoinColumn[] deployCols = deploy.columns();
this.columns = new TableJoinColumn[deployCols.length];
for (int i = 0; i < deployCols.length; i++) {
this.columns[i] = new TableJoinColumn(deployCols[i]);
}
this.queryHash = calcQueryHash();
}
private TableJoin(TableJoin source, String overrideColumn) {
this.foreignKey = null;
this.table = source.table;
this.type = source.type;
this.inheritInfo = source.inheritInfo;
this.columns = new TableJoinColumn[1];
this.columns[0] = source.columns[0].withOverrideColumn(overrideColumn);
this.queryHash = calcQueryHash();
}
private int calcQueryHash() {
int hc = type.hashCode();
hc = hc * 92821 + (table == null ? 0 : table.hashCode());
for (TableJoinColumn column : columns) {
hc = hc * 92821 + column.queryHash();
}
return hc;
}
@Override
public int hashCode() {
return queryHash;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
TableJoin that = (TableJoin) o;
if (!table.equals(that.table)) return false;
if (type != that.type) return false;
if (columns.length != that.columns.length) return false;
for (int i = 0; i < columns.length; i++) {
if (!columns[i].equals(that.columns[i])) {
return false;
}
}
return true;
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder(30);
sb.append(type).append(" ").append(table).append(" ");
for (TableJoinColumn column : columns) {
sb.append(column).append(" ");
}
return sb.toString();
}
public PropertyForeignKey getForeignKey() {
return foreignKey;
}
public TableJoinColumn[] columns() {
return columns;
}
public String getTable() {
return table;
}
public void addJoin(SqlJoinType joinType, String prefix, DbSqlContext ctx, String predicate) {
String[] names = SplitName.split(prefix);
String a1 = ctx.getTableAlias(names[0]);
String a2 = ctx.getTableAlias(prefix);
addJoin(joinType, a1, a2, ctx);
ctx.append(" and ").append(a2).append(predicate);
}
public SqlJoinType addJoin(SqlJoinType joinType, String prefix, DbSqlContext ctx) {
String[] names = SplitName.split(prefix);
String a1 = ctx.getTableAlias(names[0]);
String a2 = ctx.getTableAlias(prefix);
return addJoin(joinType, a1, a2, ctx);
}
public SqlJoinType addJoin(SqlJoinType joinType, String a1, String a2, DbSqlContext ctx) {
String joinLiteral = joinType.getLiteral(type);
ctx.addJoin(joinLiteral, table, columns(), a1, a2);
return joinType.autoToOuter(type);
}
public void addJoin(String a1, String a2, StringBuilder sb) {
for (int i = 0; i < columns.length; i++) {
TableJoinColumn pair = columns[i];
if (i > 0) {
sb.append(" and ");
}
sb.append(a1).append(".").append(pair.getLocalDbColumn());
sb.append(" = ");
sb.append(a2).append(".").append(pair.getForeignDbColumn());
}
}
TableJoin withOverrideColumn(String overrideColumn) {
if (columns.length == 1 && overrideColumn != null && !overrideColumn.equals(columns[0].getLocalDbColumn())) {
return new TableJoin(this, overrideColumn);
}
return this;
}
}