package jef.database.query;
import java.util.IdentityHashMap;
import java.util.Map;
import jef.database.DbUtils;
import jef.database.Field;
import jef.database.ORMConfig;
import jef.database.dialect.DatabaseDialect;
import jef.database.dialect.type.ColumnMapping;
import jef.database.meta.AliasProvider;
import jef.database.meta.IReferenceAllTable;
import jef.database.meta.ISelectProvider;
import jef.database.meta.ITableMetadata;
import jef.database.meta.MetaHolder;
import org.apache.commons.lang.RandomStringUtils;
public final class AllTableColumns implements IReferenceAllTable {
/**
* 表中列的别名规则
*/
public enum AliasMode {
/**
* SQL语句中的列别名:t.* 省略模式
*/
OMIT,
/**
* SQL语句中的列别名:直接用列名,不修改
*/
RAWNAME,
/**
* SQL语句中的列别名:缺省,即 T1__XXXXX的模式
*/
DEFAULT,
/**
* SQL语句中的列别名:使用随机数做别名
*/
RANDOM,
/**
* SQL语句中的列别名:将COlUMN名称转换为默认的JavaField名称
*/
JAVA_NAME
}
private String name; // 要装配到的字段,默认没有的情况下装配到根对象上
private Query<?> table;// 对应的表
private AliasMode aliasType;
private ITableMetadata customType;
private final Map<Field, String> aliasMap = new IdentityHashMap<Field, String>(16);// 别名索引
private int projection; // 只有 count 和 normal两种
private String countAlias; // 只有当count时才有用.描述count后的别名
private boolean lazyLob;
/**
* 设置查询列为count(*) as alias
*
* @param alias
* @return
*/
public AllTableColumns countAs(String alias) {
this.projection = PROJECTION_COUNT;
this.countAlias = alias;
return this;
}
public void setLazyLob(boolean lazyLob) {
if (lazyLob) {
if (table.getMeta().getLobFieldNames() == null) {// 如果没有LOB字段,不能设置为true
return;
}
}
this.lazyLob = lazyLob;
}
public boolean isLazyLob() {
return lazyLob;
}
/**
* 禁止从数据库中查询rownum / rowid等虚拟列
*
* @return
*/
public AllTableColumns noVirtualColumn() {
this.projection = PROJECTION_NORMAL_NOVIRTUAL;
return this;
}
/**
* 获取当count时的count列的别名
*
* @return
*/
protected String getCountAlias() {
return countAlias;
}
private String getAlias(Field f) {
return aliasMap.get(f);
}
AllTableColumns(Query<?> table) {
this.table = table;
this.aliasType = ORMConfig.getInstance().isSpecifyAllColumnName() ? AliasMode.RAWNAME : AliasMode.OMIT;
}
/**
* 获取别名的方案
*
* @return
*/
public AliasMode getAliasType() {
return aliasType;
}
/**
* 设置在select语句中对列名的描述,可取 <li>ALIAS_MODE_SIMPLE</li> //SQL语句中的列别名:t.* 省略模式
* <li>ALIAS_MODE_RAWNAME</li> //SQL语句中的列别名:直接用列名,不修改 <li>ALIAS_MODE_DEFAULT
* </li> //SQL语句中的列别名:缺省,即 T1__XXXXX的模式 <li>ALIAS_MODE_RANDOM</li>;
* //SQL语句中的列别名:使用随机数做别名
*
* @param aliasType
*/
public void setAliasType(AliasMode aliasType) {
this.aliasType = aliasType;
}
/**
* 设置这个查询不要选择任何列出来
*/
protected void notSelectAnyColumn() {
this.projection = ISelectProvider.PROJECTION_NOT_SELECT;
}
public String getSelectedAliasOf(ColumnMapping f, DatabaseDialect profile, String schema) {
String value;
Field field = f.field();
switch (aliasType) {
case OMIT:
// 这个地方不可抛出异常.因为对于AllColumn来说,还是有可能位于join当中的。
// 此外,如果LOB字段延迟加载,也会出现OMIT参数无效的情况
// throw new
// IllegalArgumentException("the type should use 't.*' on select columns. ");
case RAWNAME:
value = f.getColumnName(profile, false);
aliasMap.put(field, value);
return null;// 无需转义
case DEFAULT: {
String alias = getAlias(field);
if (alias != null)
return alias;
value = AliasProvider.DEFAULT.getSelectedAliasOf(f, profile, schema);
aliasMap.put(field, value);
return value;
}
case RANDOM: {
String alias = getAlias(field);
if (alias != null)
return alias;
value = "C".concat(RandomStringUtils.randomNumeric(12));
aliasMap.put(field, value);
return value;
}
case JAVA_NAME: {
String alias = getAlias(f.field());
if (alias != null)
return DbUtils.escapeColumn(profile, alias);
value = field.name();
aliasMap.put(field, value);
return value;
}
default:
throw new IllegalArgumentException();
}
}
@Override
public String getResultAliasOf(ColumnMapping f, String schema) {
String alias = getAlias(f.field());
if (alias != null)
return alias.toUpperCase();
return f.upperColumnName();
}
protected void setName(String name) {
this.name = name;
}
/**
* 可以设置一个自定义的结果拼装类型
*
* @param customType
*/
public void setCustomType(ITableMetadata customType) {
this.customType = customType;
}
/*
* (non-Javadoc)
*
* @see jef.database.meta.IReferenceField#getFullModeTargetType()
*/
public ITableMetadata getFullModeTargetType() {
return customType == null ? MetaHolder.getMeta(table.getInstance()) : customType;
}
public String getName() {
return name;
}
public int getProjection() {
return projection;
}
/**
* 内部使用获取,返回以非每列显式指定的SQL select子句项。 即如果使用了PROJECTION_COUNT,或者使用了省略模式(*),则返回值
* 否则返回null (表示要显式指定每个列)
*/
public String simpleModeSql(String tableAlias) {
if (lazyLob) {
return null;
}
// TODO distinct的情况下的处理
if ((projection & PROJECTION_COUNT) > 0) {
return "count(" + tableAlias + ".*)";
}
if (aliasType == AliasMode.OMIT) {
return tableAlias.concat(".*");
}
return null;
}
public boolean isSingleColumn() {
return false;
}
}