gu.sql2java.RowMetaData Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of sql2java-base Show documentation
Show all versions of sql2java-base Show documentation
sql2java common class package
package gu.sql2java;
import static com.google.common.base.Preconditions.*;
import static com.google.common.base.MoreObjects.*;
import static gu.sql2java.SimpleLog.*;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.NoSuchElementException;
import java.util.ServiceConfigurationError;
import java.util.ServiceLoader;
import java.util.concurrent.ExecutionException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import com.google.common.base.Function;
import com.google.common.base.Joiner;
import com.google.common.base.Objects;
import com.google.common.base.Predicate;
import com.google.common.base.Strings;
import com.google.common.base.Throwables;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import com.google.common.collect.Collections2;
import com.google.common.collect.ImmutableBiMap;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Ordering;
import com.google.common.primitives.Ints;
import com.google.common.util.concurrent.UncheckedExecutionException;
/**
* meta data used to define a table
* @author guyadong
*
*/
public class RowMetaData implements IRowMetaData{
protected static final String UNKNOW_TABLENAME="UNKNOWN";
protected static final String UNKNOW_TABLETYPE="UNKNOWN";
public final String tablename;
public final String tableType;
public final Class extends BaseBean> beanType;
public final String coreClass;
public final Class extends TableManager>> managerInterfaceClass;
public final String alias;
public final ImmutableList columnNames;
public final String columnFields;
public final String columnFullFields;
public final ImmutableList columnJavaNames;
public final ImmutableList getterMethods;
public final ImmutableList setterMethods;
public final ImmutableList> columnTypes;
private final ImmutableMap nameIndexsMap;
private final ImmutableMap javaNameIndexsMap;
public final int[] defaultColumnIdList;
public final int[] columnSizes;
public final int[] sqlTypes;
public final ImmutableMap> typesMap;
public final int columnCount;
public final int[] primaryKeyIds;
public final String[] primaryKeyNames;
public final int primaryKeyCount;
public final Class>[] primaryKeyTypes;
/** lazy load */
private volatile ImmutableMap junctionTablePkMap;
private final Map junctionTablePkStrMap;
public final Class> lockColumnType;
public final String lockColumnName;
/**
* tablename-ForeignKeyMetaData map
*/
public final Map foreignKeys;
/**
* universal name-ForeignKeyMetaData map
*/
public final Map foreignKeysRn;
private final List importedFknames;
public final Map indices;
public final Map indicesRn;
public final Function COLUMNID_FUN = new Function(){
@Override
public Integer apply(String input) {
return columnIDOf(input);
}};
public final Function COLUMNNAME_FUN = new Function(){
@Override
public String apply(Integer input) {
return columnNameOf(input);
}};
public final Function> COLUMNTYPE_FUN = new Function>(){
@Override
public Class> apply(String input) {
return columnTypeOf(input);
}};
/** lazy load */
private volatile ImmutableList importedKeys;
/** lazy load */
private volatile Map importKeysMap;
public final int autoincrementColumnId;
protected RowMetaData(
String tablename,
String tableType,
Class extends BaseBean> beanType,
String coreClass,
Class extends TableManager>> managerInterfaceClass,
String alias,
List columnNames,
List columnJavaNames,
List getters,
List setters,
Class>[] columnTypes,
int[] columnSizes,
int[] sqlTypes,
List primaryKeyNames,
Map junctionTablePkMap,
Class> lockColumnType,
String lockColumnName,
List foreignKeys,
List importedFknames,
List indices,
String autoincrement) {
columnJavaNames = firstNonNull(columnJavaNames,Collections.emptyList());
getters = firstNonNull(getters,Collections.emptyList());
setters = firstNonNull(setters,Collections.emptyList());
this.junctionTablePkStrMap = firstNonNull(junctionTablePkMap, Collections.emptyMap());
primaryKeyNames = firstNonNull(primaryKeyNames, Collections.emptyList());
foreignKeys = firstNonNull(foreignKeys, Collections.emptyList());
indices = firstNonNull(indices, Collections.emptyList());
autoincrement = firstNonNull(autoincrement, "");
this.tablename = checkNotNull(tablename,"tablename is null");
this.tableType = checkNotNull(tableType,"tableType is null");
this.beanType = checkNotNull(beanType,"beanType is null");
this.coreClass = coreClass;
this.managerInterfaceClass = managerInterfaceClass;
this.alias = Strings.emptyToNull(alias);
this.columnNames = ImmutableList.copyOf(checkNotNull(columnNames,"columnNames is null"));
this.columnJavaNames = ImmutableList.copyOf(columnJavaNames);
this.columnTypes = ImmutableList.copyOf(checkNotNull(columnTypes,"columnTypes is null"));
this.columnSizes = null == columnSizes ? null : Arrays.copyOf(columnSizes,columnSizes.length);
this.sqlTypes = Arrays.copyOf(checkNotNull(sqlTypes,"sqlTypes is null"),sqlTypes.length);
checkArgument(this.columnNames.size() == this.columnTypes.size() && this.columnTypes.size() == this.sqlTypes.length,
"MISMATCH LENGTH for input list");
checkArgument(this.columnJavaNames.isEmpty() || this.columnJavaNames.size() == this.sqlTypes.length,
"MISMATCH LENGTH for columnJavaNames");
checkArgument(getters.isEmpty() || getters.size() == this.sqlTypes.length,
"MISMATCH LENGTH for getters");
checkArgument(setters.isEmpty() || setters.size() == this.sqlTypes.length,
"MISMATCH LENGTH for setters");
ImmutableMap.Builder nameIndexBuilder = ImmutableMap.builder();
ImmutableMap.Builder javaNameIndexBuilder = ImmutableMap.builder();
ImmutableMap.Builder> nameTypeBuilder = ImmutableMap.builder();
this.defaultColumnIdList = new int[sqlTypes.length];
for(int i = 0; i < sqlTypes.length; ++i){
defaultColumnIdList[i] = i;
nameIndexBuilder.put(columnNames.get(i), i);
nameTypeBuilder.put(columnNames.get(i), columnTypes[i]);
if(!columnJavaNames.isEmpty()){
javaNameIndexBuilder.put(columnJavaNames.get(i), i);
}
}
columnFields = Joiner.on(",").join(columnNames);
columnFullFields = Joiner.on(",").join(Lists.transform(columnNames, new Function(){
@Override
public String apply(String input) {
if("UNKNOWN".equals(RowMetaData.this.tableType)){
return input;
}
return RowMetaData.this.tablename + "." + input;
}}));
this.nameIndexsMap = nameIndexBuilder.build();
this.autoincrementColumnId = firstNonNull(nameIndexsMap.get(autoincrement), -1).intValue();
this.javaNameIndexsMap = javaNameIndexBuilder.build();
this.typesMap = nameTypeBuilder.build();
this.columnCount = sqlTypes.length;
this.primaryKeyNames = primaryKeyNames.toArray(new String[0]);
this.primaryKeyCount = primaryKeyNames.size();
this.primaryKeyIds = new int[primaryKeyNames.size()];
for(int i = 0 ; i < primaryKeyIds.length; ++i){
String name = primaryKeyNames.get(i);
checkArgument(primaryKeyIds[i]>=0,"INVALID primary key name %s",name);
primaryKeyIds[i] = columnIDOf(name);
}
this.primaryKeyTypes = Lists.transform(primaryKeyNames, COLUMNTYPE_FUN).toArray(new Class>[0]);
this.lockColumnType = lockColumnType;
this.lockColumnName = lockColumnName;
LinkedHashMap fkBuilder = Maps.newLinkedHashMap();
LinkedHashMap fkRnameBuilder = Maps.newLinkedHashMap();
for(String fk:foreignKeys){
ForeignKeyMetaData data = new ForeignKeyMetaData(fk, tablename);
fkBuilder.put(data.name,data);
fkRnameBuilder.put(data.readableName,data);
}
this.foreignKeys = Collections.unmodifiableMap(fkBuilder);
this.foreignKeysRn = Collections.unmodifiableMap(fkRnameBuilder);
this.importedFknames = Collections.unmodifiableList(firstNonNull(importedFknames,Collections.emptyList()));
LinkedHashMap indexBuilder = Maps.newLinkedHashMap();
LinkedHashMap indexRnameBuilder = Maps.newLinkedHashMap();
for(String fk:indices){
IndexMetaData data = new IndexMetaData(fk, tablename);
indexBuilder.put(data.name,data);
indexRnameBuilder.put(data.readableName,data);
}
this.indices = Collections.unmodifiableMap(indexBuilder);
this.indicesRn = Collections.unmodifiableMap(indexRnameBuilder);
ImmutableList.Builder getterMethodBuilder = ImmutableList.builder();
ImmutableList.Builder setterMethodBuilder = ImmutableList.builder();
for(int i = 0; i < sqlTypes.length; ++i){
try {
if(!getters.isEmpty()){
getterMethodBuilder.add(beanType.getMethod(getters.get(i)));
}
if(!setters.isEmpty()){
setterMethodBuilder.add(beanType.getMethod(setters.get(i), columnTypes[i]));
}
} catch (Exception e) {
Throwables.throwIfUnchecked(e);
throw new RuntimeException(e);
}
}
this.getterMethods = getterMethodBuilder.build();
this.setterMethods = setterMethodBuilder.build();
}
/**
* compatibility for previous version
* @param tablename
* @param tableType
* @param beanType
* @param coreClass
* @param managerInterfaceClass
* @param columnNames
* @param columnJavaNames
* @param getters
* @param setters
* @param columnTypes
* @param columnSizes
* @param sqlTypes
* @param primaryKeyNames
* @param junctionTablePkMap
* @param lockColumnType
* @param lockColumnName
* @param foreignKeys
* @param indices
* @param autoincrement
*/
protected RowMetaData(
String tablename,
String tableType,
Class extends BaseBean> beanType,
String coreClass,
Class extends TableManager>> managerInterfaceClass,
List columnNames,
List columnJavaNames,
List getters,
List setters,
Class>[] columnTypes,
int[] columnSizes,
int[] sqlTypes,
List primaryKeyNames,
Map junctionTablePkMap,
Class> lockColumnType,
String lockColumnName,
List foreignKeys,
List indices,
String autoincrement) {
this(tablename, tableType, beanType, coreClass, managerInterfaceClass, null, columnNames, columnJavaNames, getters, setters,
columnTypes, columnSizes, sqlTypes, primaryKeyNames, junctionTablePkMap, lockColumnType, lockColumnName, foreignKeys,
null, indices, autoincrement);
}
/**
* return column name specified by column id
* @param columnId column id
* @return column name or null if columnId is invalid
*/
public String columnNameOf(int columnId){
try{
return columnNames.get(columnId);
} catch(IndexOutOfBoundsException e){
return null;
}
}
/**
* return column full name(with table name,such as tablename.columnname) specified by column id
* @param columnId column id
* @return column full name or null if columnId is invalid
*/
public String fullNameOf(int columnId){
try{
if(tablename.startsWith(UNKNOW_TABLENAME)){
return columnNames.get(columnId);
}
return tablename + "." + columnNames.get(columnId);
} catch(IndexOutOfBoundsException e){
return null;
}
}
/**
* return column ordinal id(base 0) specified by column name
* @param column column name or full name,or java field name
* @return column ordinal id(base 0) or -1 if column name is invalid
*/
public final int columnIDOf(String column){
if(null != column){
String prefix = tablename + ".";
if(column.startsWith(prefix)){
column = column.substring(prefix.length());
}
return firstNonNull(nameIndexsMap.get(column),
firstNonNull(javaNameIndexsMap.get(column), -1));
}
return -1;
}
/**
* return column ordinal id(base 0) specified by column names
* @param columns array of column name or full name,or java field name
* @return array of column ordinal id(base 0) or empty array if columns is null
* @see #columnIDOf(String)
*/
public final int[] columnIDsOf(String... columns){
return null == columns ? new int[0] : Ints.toArray(Lists.transform(Arrays.asList(columns), COLUMNID_FUN));
}
/**
* return column ordinal id(base 0) specified by column names
* @param columns collection of column name or full name,or java field name
* @return array of column ordinal id(base 0) or empty array if columns is null
* @see #columnIDOf(String)
*/
public final int[] columnIDsOf(Collection columns){
return null == columns ? new int[0] : Ints.toArray(Collections2.transform(columns, COLUMNID_FUN));
}
/**
* return column names by column names
* @param columnIds array of column id
* @return array of column name or empty array if columnIds is null
* @see #columnNameOf(int)
*/
public final List columnNamesOf(int... columnIds){
return null == columnIds ? Collections.emptyList() : Lists.transform(Ints.asList(columnIds), COLUMNNAME_FUN);
}
/**
* @param columnId column id
* @return java type of column,or NULL if columnId is invalid
*/
public Class> columnTypeOf(int columnId){
try{
return columnTypes.get(columnId);
} catch(IndexOutOfBoundsException e){
return null;
}
}
/**
* @param column column name
* @return java type of column,or NULL if column is invalid
*/
public Class> columnTypeOf(String column){
try{
return columnTypes.get(columnIDOf(column));
} catch(IndexOutOfBoundsException e){
return null;
}
}
/**
* @param columnId column id
* @return SQL type of column,or throw {@link IllegalArgumentException} if columnId is invalid
* @see java.sql.Types
*/
public int sqlTypeOf(int columnId){
try{
return sqlTypes[columnId];
} catch(IndexOutOfBoundsException e){
throw new IllegalArgumentException(String.format("INVALID columnID %d",columnId));
}
}
/**
* lazy load
*/
private final LoadingCache checkLinkedTableCache = CacheBuilder.newBuilder().build(
new CacheLoader(){
@Override
public Boolean load(final String tablename) throws Exception {
return Iterables.tryFind(getJunctionTablePkMap().values(), new Predicate
© 2015 - 2025 Weber Informatics LLC | Privacy Policy