io.ebeaninternal.server.deploy.TableJoin Maven / Gradle / Ivy
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;
/**
* Represents a join to another table.
*/
public final class TableJoin {
/**
* The joined table.
*/
private final String table;
/**
* The type of join as per deployment (cardinality and optionality).
*/
private final SqlJoinType type;
/**
* Columns as an array.
*/
private final TableJoinColumn[] columns;
/**
* A hash that can be used with the query plan.
*/
private final int queryHash;
private final PropertyForeignKey foreignKey;
private final String extraWhere;
public TableJoin(DeployTableJoin deploy) {
this(deploy, null);
}
/**
* Create a TableJoin.
*/
public TableJoin(DeployTableJoin deploy, PropertyForeignKey foreignKey) {
this.foreignKey = foreignKey;
this.extraWhere = deploy.getExtraWhere();
this.table = InternString.intern(deploy.getTable());
this.type = deploy.getType();
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.extraWhere = source.extraWhere;
this.table = source.table;
this.type = source.type;
this.columns = new TableJoinColumn[1];
this.columns[0] = source.columns[0].withOverrideColumn(overrideColumn);
this.queryHash = calcQueryHash();
}
/**
* Calculate a hash value for adding to a query plan.
*/
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();
}
/**
* Return the foreign key options.
*/
public PropertyForeignKey getForeignKey() {
return foreignKey;
}
/**
* Return the join columns.
*/
public TableJoinColumn[] columns() {
return columns;
}
/**
* Return the joined table name.
*/
public String getTable() {
return table;
}
public void addJoin(SqlJoinType joinType, String prefix, DbSqlContext ctx, String predicate) {
String[] names = SplitName.split(prefix);
String a1 = ctx.tableAlias(names[0]);
String a2 = ctx.tableAlias(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.tableAlias(names[0]);
String a2 = ctx.tableAlias(prefix);
return addJoin(joinType, a1, a2, ctx);
}
public SqlJoinType addJoin(SqlJoinType joinType, String a1, String a2, DbSqlContext ctx) {
String joinLiteral = joinType.literal(type);
ctx.addJoin(joinLiteral, table, columns(), a1, a2, extraWhere);
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;
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy