package org.jooq.impl;
import static org.jooq.Clause.TABLE;
import static org.jooq.Clause.TABLE_ALIAS;
import static org.jooq.Clause.TABLE_REFERENCE;
import static org.jooq.SQLDialect.FIREBIRD;
import static org.jooq.SQLDialect.HSQLDB;
import static org.jooq.SQLDialect.POSTGRES;
import static org.jooq.impl.Internal.createPathAlias;
import static org.jooq.impl.Keywords.K_TABLE;
import static org.jooq.impl.QueryPartListView.wrap;
import static org.jooq.impl.SchemaImpl.DEFAULT_SCHEMA;
import static org.jooq.impl.Tools.getMappedTable;
import static org.jooq.tools.StringUtils.defaultIfNull;
import java.util.Arrays;
import java.util.Set;
import org.jooq.Clause;
import org.jooq.Comment;
import org.jooq.Context;
import org.jooq.Field;
import org.jooq.ForeignKey;
import org.jooq.Name;
import org.jooq.Record;
import org.jooq.Row;
import org.jooq.SQLDialect;
import org.jooq.Schema;
import org.jooq.Table;
import org.jooq.TableOptions;
import org.jooq.tools.StringUtils;
@org.jooq.Internal
public class TableImpl<R extends Record> extends AbstractTable<R> {
private static final long serialVersionUID = 261033315221985068L;
private static final Clause[] CLAUSES_TABLE_REFERENCE = { TABLE, TABLE_REFERENCE };
private static final Clause[] CLAUSES_TABLE_ALIAS = { TABLE, TABLE_ALIAS };
private static final Set<SQLDialect> NO_SUPPORT_QUALIFIED_TVF_CALLS = SQLDialect.supportedBy(HSQLDB, POSTGRES);
private static final Set<SQLDialect> REQUIRES_TVF_TABLE_CONSTRUCTOR = SQLDialect.supportedBy(HSQLDB);
final Fields<R> fields;
final Alias<Table<R>> alias;
protected final Field<?>[] parameters;
final Table<?> child;
final ForeignKey<?, R> childPath;
@Deprecated
public TableImpl(String name) {
this(DSL.name(name));
}
@Deprecated
public TableImpl(String name, Schema schema) {
this(DSL.name(name), schema);
}
@Deprecated
public TableImpl(String name, Schema schema, Table<R> aliased) {
this(DSL.name(name), schema, aliased);
}
@Deprecated
public TableImpl(String name, Schema schema, Table<R> aliased, Field<?>[] parameters) {
this(DSL.name(name), schema, aliased, parameters);
}
@Deprecated
public TableImpl(String name, Schema schema, Table<R> aliased, Field<?>[] parameters, String comment) {
this(DSL.name(name), schema, aliased, parameters, comment);
}
public TableImpl(Name name) {
this(name, null, null, null, null, null, (Comment) null);
}
public TableImpl(Name name, Schema schema) {
this(name, schema, null, null, null, null, (Comment) null);
}
public TableImpl(Name name, Schema schema, Table<R> aliased) {
this(name, schema, null, null, aliased, null, (Comment) null);
}
public TableImpl(Name name, Schema schema, Table<R> aliased, Field<?>[] parameters) {
this(name, schema, null, null, aliased, parameters, (Comment) null);
}
@Deprecated
public TableImpl(Name name, Schema schema, Table<R> aliased, Field<?>[] parameters, String comment) {
this(name, schema, null, null, aliased, parameters, DSL.comment(comment));
}
public (Name name, Schema schema, Table<R> aliased, Field<?>[] parameters, Comment comment) {
this(name, schema, null, null, aliased, parameters, comment);
}
public (Name name, Schema schema, Table<R> aliased, Field<?>[] parameters, Comment comment, TableOptions options) {
this(name, schema, null, null, aliased, parameters, comment, options);
}
public TableImpl(Table<?> child, ForeignKey<?, R> path, Table<R> parent) {
this(createPathAlias(child, path), null, child, path, parent, null, parent.getCommentPart());
}
public (Name name, Schema schema, Table<?> child, ForeignKey<?, R> path, Table<R> aliased, Field<?>[] parameters, Comment comment) {
this(name, schema, child, path, aliased, parameters, comment, TableOptions.table());
}
@SuppressWarnings({ "rawtypes", "unchecked" })
public (Name name, Schema schema, Table<?> child, ForeignKey<?, R> path, Table<R> aliased, Field<?>[] parameters, Comment comment, TableOptions options) {
super(options, name, schema, comment);
this.fields = new Fields<>();
this.child = child;
this.childPath = path == null ? null : Tools.aliasedKey((ForeignKey) path, child, this);
if (aliased != null) {
Alias<Table<R>> existingAlias = Tools.alias(aliased);
if (existingAlias != null)
alias = new Alias<>(existingAlias.wrapped, this, name, existingAlias.fieldAliases, existingAlias.wrapInParentheses);
else
alias = new Alias<>(aliased, this, name);
}
else
alias = null;
this.parameters = parameters;
}
Table<R> getAliasedTable() {
if (alias != null)
return alias.wrapped();
return null;
}
@org.jooq.Internal
protected boolean aliased() {
return getAliasedTable() != null;
}
@Override
final Fields<R> fields0() {
return fields;
}
@Override
public Row fieldsRow() {
return super.fieldsRow();
}
@Override
public final Clause[] clauses(Context<?> ctx) {
return alias != null ? CLAUSES_TABLE_ALIAS : CLAUSES_TABLE_REFERENCE;
}
@Override
public final void accept(Context<?> ctx) {
if (child != null)
ctx.scopeRegister(this);
if (alias != null) {
ctx.visit(alias);
}
else {
if (parameters != null && REQUIRES_TVF_TABLE_CONSTRUCTOR.contains(ctx.dialect()) && ctx.declareTables()) {
ctx.visit(K_TABLE)
.sql('(');
accept0(ctx);
ctx.sql(')');
if (ctx.declareAliases())
ctx.sql(' ')
.visit(Tools.getMappedTable(ctx.configuration(), this).getUnqualifiedName());
}
else
accept0(ctx);
}
}
private void accept0(Context<?> ctx) {
if (ctx.declareTables())
ctx.scopeMarkStart(this);
if (ctx.qualify() &&
(!NO_SUPPORT_QUALIFIED_TVF_CALLS.contains(ctx.dialect()) || parameters == null || ctx.declareTables())) {
Schema mappedSchema = Tools.getMappedSchema(ctx.configuration(), getSchema());
if (mappedSchema != null && !"".equals(mappedSchema.getName())) {
ctx.visit(mappedSchema);
ctx.sql('.');
}
}
ctx.visit(getMappedTable(ctx.configuration(), this).getUnqualifiedName());
if (parameters != null && ctx.declareTables()) {
if (ctx.family() == FIREBIRD && parameters.length == 0)
ctx.visit(wrap(parameters));
else
ctx.sql('(')
.visit(wrap(parameters))
.sql(')');
}
if (ctx.declareTables())
ctx.scopeMarkEnd(this);
}
@Override
public Table<R> as(Name as) {
if (alias != null)
return alias.wrapped().as(as);
else
return new TableAlias<>(this, as);
}
@Override
public Table<R> as(Name as, Name... fieldAliases) {
if (alias != null)
return alias.wrapped().as(as, fieldAliases);
else
return new TableAlias<>(this, as, fieldAliases);
}
public Table<R> rename(String rename) {
return new TableImpl<>(rename, getSchema());
}
public Table<R> rename(Name rename) {
return new TableImpl<>(rename, getSchema());
}
@SuppressWarnings("unchecked")
@Override
public Class<? extends R> getRecordType() {
return (Class<? extends R>) RecordImplN.class;
}
@Override
public boolean declaresTables() {
return true;
}
@Override
public boolean equals(Object that) {
if (this == that)
return true;
if (that instanceof TableImpl) {
TableImpl<?> other = (TableImpl<?>) that;
return
StringUtils.equals(
defaultIfNull(getSchema(), DEFAULT_SCHEMA),
defaultIfNull(other.getSchema(), DEFAULT_SCHEMA)
) &&
StringUtils.equals(getName(), other.getName()) &&
Arrays.equals(parameters, other.parameters);
}
return super.equals(that);
}
}