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.Field;
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.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.NoSuchElementException;
import java.util.ServiceConfigurationError;
import java.util.Set;
import java.util.concurrent.ExecutionException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import com.alibaba.fastjson.serializer.ObjectSerializer;
import com.gitee.l0km.common.spring.core.annotation.AnnotationUtils;
import com.gitee.l0km.common.spring.core.annotation.MergedAnnotation;
import com.gitee.l0km.common.spring.core.annotation.TypeMappedAnnotations;
import com.google.common.base.Function;
import com.google.common.base.Functions;
import com.google.common.base.Joiner;
import com.google.common.base.Objects;
import com.google.common.base.Optional;
import com.google.common.base.Predicate;
import com.google.common.base.Predicates;
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.FluentIterable;
import com.google.common.collect.ImmutableBiMap;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
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;
import gu.sql2java.annotations.ColumnCodecConfig;
import gu.sql2java.annotations.RowMeta;
import gu.sql2java.utils.SPIUtils;
import com.alibaba.fastjson.annotation.JSONField;
import static gu.sql2java.BaseTypeColumnCodec.BASE_CODEC;
import static gu.sql2java.BaseTypeColumnCodec.isBaseColumnType;
import static gu.sql2java.BaseTypeColumnCodec.isJdbcType;
import static gu.sql2java.Sql2javaSupport.findSubClass;
/**
* 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;
/**
* @since 3.18.0
*/
public final ImmutableList columnTypeNames;
public final String columnFields;
public final String columnFullFields;
public ImmutableList columnFullFieldList;
public final ImmutableList columnJavaNames;
public final ImmutableList getterMethods;
public final ImmutableList setterMethods;
/**
* @since 3.18.0
*/
public final List readMethods;
/**
* @since 3.18.0
*/
public final List writeMethods;
public final ImmutableList> columnTypes;
/**
* @since 3.18.1
*/
public final ImmutableList> fieldTypes;
/**
* @since 3.21.0
*/
public final ImmutableList> jdbcTypes;
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);
}};
/**
* @since 3.22.0
*/
public final Function> JDBCTYPE_FUN = new Function>(){
@Override
public Class> apply(String input) {
return jdbcTypeOf(columnIDOf(input));
}};
/** lazy load */
private volatile ImmutableList importedKeys;
/** lazy load */
private volatile Map importKeysMap;
public final int autoincrementColumnId;
private volatile Optional> manager;
/**
* @since 3.21.0
*/
public final ColumnCodec[] columnCodecs;
/**
* @since 3.27.0
*/
public final ObjectSerializer[] columnJsonSerializers;
private volatile RowMeta rowMetaAnnot;
private volatile Set primaryKeyIdSet;
/**
* @since 3.32.0
*/
public final ImmutableList visibilities;
protected RowMetaData(
String tablename,
String tableType,
Class extends BaseBean> beanType,
String coreClass,
Class extends TableManager>> managerInterfaceClass,
String alias,
List columnNames,
List columnTypeNames,
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.columnTypeNames = ImmutableList.copyOf(checkNotNull(columnTypeNames,"columnTypeNames 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();
ImmutableList.Builder> fieldTypeBuilder = ImmutableList.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);
try {
fieldTypeBuilder.add(beanType.getDeclaredField(columnJavaNames.get(i)).getType());
} catch (NoSuchFieldException | SecurityException e) {
throw new RuntimeException(e);
}
}
}
columnFields = Joiner.on(",").join(columnNames);
columnFullFieldList = ImmutableList.copyOf(Lists.transform(columnNames, new Function(){
@Override
public String apply(String input) {
if("UNKNOWN".equals(RowMetaData.this.tableType)){
return input;
}
return RowMetaData.this.tablename + "." + input;
}}));
columnFullFields = Joiner.on(",").join(columnFullFieldList);
this.nameIndexsMap = nameIndexBuilder.build();
this.autoincrementColumnId = firstNonNull(nameIndexsMap.get(autoincrement), -1).intValue();
this.javaNameIndexsMap = javaNameIndexBuilder.build();
this.typesMap = nameTypeBuilder.build();
this.fieldTypes = fieldTypeBuilder.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();
List readMethodBuffer = Lists.newArrayList();
List writeMethodBuffer = Lists.newArrayList();
ImmutableList.Builder> jdbcTypeBuilder = ImmutableList.builder();
for(int i = 0; i < sqlTypes.length; ++i){
try {
Method readMethod = null;
Method writeMethod = null;
if(!getters.isEmpty()){
Method getterMethod = beanType.getMethod(getters.get(i));
getterMethodBuilder.add(getterMethod);
try {
readMethod = beanType.getMethod("read" + getters.get(i).replaceFirst("(is|get)", ""));
} catch (NoSuchMethodException e) {
}
readMethodBuffer.add(readMethod);
if(null != readMethod) {
if(isJdbcType(fieldTypeOf(i))) {
jdbcTypeBuilder.add(fieldTypeOf(i));
}else {
if(fieldTypeOf(i).equals(readMethod.getReturnType())) {
jdbcTypeBuilder.add(getterMethod.getReturnType());
}else {
jdbcTypeBuilder.add(readMethod.getReturnType());
}
}
}else {
jdbcTypeBuilder.add(getterMethod.getReturnType());
}
}
if(!setters.isEmpty()){
setterMethodBuilder.add(beanType.getMethod(setters.get(i), columnTypes[i]));
if(null != readMethod) {
try {
writeMethod = beanType.getMethod("write" + setters.get(i).replaceFirst("set", ""),readMethod.getReturnType());
} catch (NoSuchMethodException e) {
}
}
writeMethodBuffer.add(writeMethod);
}
} catch (Exception e) {
Throwables.throwIfUnchecked(e);
throw new RuntimeException(e);
}
}
this.getterMethods = getterMethodBuilder.build();
this.setterMethods = setterMethodBuilder.build();
this.readMethods = Collections.unmodifiableList(readMethodBuffer);
this.writeMethods = Collections.unmodifiableList(writeMethodBuffer);
this.jdbcTypes = jdbcTypeBuilder.build();
this.columnCodecs = new ColumnCodec[columnCount];
this.columnJsonSerializers = new ObjectSerializer[columnCount];
this.visibilities= buildVisibilities();
if(!columnJavaNames.isEmpty()) {
for(int i=0;i 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, null, columnJavaNames, getters,
setters, columnTypes, columnSizes, sqlTypes, primaryKeyNames, junctionTablePkMap, lockColumnType, lockColumnName,
foreignKeys, null, indices, autoincrement);
}
private ColumnCodec columnCodecOf(Field field) throws InstantiationException, IllegalAccessException {
ColumnCodecConfig annot = field.getAnnotation(ColumnCodecConfig.class);
if(null != annot) {
if(!ColumnCodec.class.equals(annot.value())) {
return annot.value().newInstance();
}
}else {
Class extends ColumnCodec> ct = columnCodecOf(field.getType());
if(null != ct) {
return ct.newInstance();
}
}
return null;
}
/**
* find valid {@link ColumnCodecConfig} from input class,
* if not found try to find in superclass or interfaces recursively
* @param clazz
*/
private Class extends ColumnCodec> columnCodecOf(Class> clazz){
if(null != clazz) {
ColumnCodecConfig annot = clazz.getAnnotation(ColumnCodecConfig.class);
if(null != annot && !ColumnCodec.class.equals(annot.value())) {
return annot.value();
}
for(Class> iface: clazz.getInterfaces()) {
Class extends ColumnCodec> ct = columnCodecOf(iface);
if(null != ct) {
return ct;
}
}
return columnCodecOf(clazz.getSuperclass());
}
return null;
}
private ObjectSerializer jsonSerializeOf(Field field) throws InstantiationException, IllegalAccessException {
JSONField annot = field.getAnnotation(JSONField.class);
if(null != annot) {
Class> serializrClazz = annot.serializeUsing();
if(!Void.class.equals(serializrClazz)) {
return (ObjectSerializer) serializrClazz.newInstance();
}
}else {
Class> ct = jsonSerializerOf(field.getType());
if(null != ct) {
return (ObjectSerializer) ct.newInstance();
}
}
return null;
}
/**
* find valid {@link ColumnCodecConfig} from input class,
* if not found try to find in superclass or interfaces recursively
* @param clazz
*/
@SuppressWarnings("unchecked")
private Class> jsonSerializerOf(Class> clazz){
if(null != clazz) {
JSONField annot = clazz.getAnnotation(JSONField.class);
if(null != annot && !Void.class.equals(annot.serializeUsing())) {
return (Class extends ObjectSerializer>) annot.serializeUsing();
}
for(Class> iface: clazz.getInterfaces()) {
Class> ct = jsonSerializerOf(iface);
if(null != ct) {
return ct;
}
}
return jsonSerializerOf(clazz.getSuperclass());
}
return null;
}
public ObjectSerializer jsonSerializerOf(int columnId) {
try{
return columnJsonSerializers[columnId];
} catch(IndexOutOfBoundsException e){
return null;
}
}
/**
* 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 camel-case Java name of column specified by column id
* @param columnId column id
* @return column name or null if columnId is invalid
*/
public String columnJavaNameOf(int columnId){
try{
return columnJavaNames.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 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(Iterable columns){
return null == columns ? new int[0] : Ints.toArray(Lists.newArrayList(Iterables.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);
}
/**
* 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)
* @since 3.15.0
*/
public final List columnNamesOf(IterablecolumnIds){
return null == columnIds
? Collections.emptyList()
: Lists.newArrayList(Iterables.transform(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 columnId column id
* @return java field type of column,or NULL if columnId is invalid
* @since 3.18.1
*/
public Class> fieldTypeOf(int columnId){
if(fieldTypes.isEmpty()) {
return columnTypeOf(columnId);
}else {
try{
return fieldTypes.get(columnId);
} catch(IndexOutOfBoundsException e){
return null;
}
}
}
/**
* @param columnId column id
* @return java type of column for JDBC driver,or NULL if columnId is invalid
* @since 3.21.0
*/
public Class> jdbcTypeOf(int columnId){
try{
return jdbcTypes.get(columnId);
} catch(IndexOutOfBoundsException e){
return null;
}
}
/**
* @param columnId column id
* @return Field instance of column,or NULL if columnId is invalid
* @since 3.17.7
*/
public Field fieldOf(int columnId){
try{
String name = columnJavaNameOf(columnId);
return null == name ? null : beanType.getDeclaredField(name);
} catch (Exception e) {
Throwables.throwIfUnchecked(e);
throw new RuntimeException(e);
}
}
/**
* @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
* @return ColumnCodec instance of NULL if column is invalid
* @since 3.21.0
*/
public ColumnCodec columnCodecOf(int columnId) {
try{
return columnCodecs[columnId];
} catch(IndexOutOfBoundsException e){
return null;
}
}
public boolean isValidColumnID(Integer columnId){
return null != columnId && columnId >= 0 && columnId < columnCount;
}
public boolean isValidColumnName(String column){
return isValidColumnID(columnIDOf(column));
}
public int[] validColumnIDsOrAll(int... fieldList)
{
if (null == fieldList || 0 == fieldList.length){
return defaultColumnIdList.clone();
}
List validIds = Lists.newArrayListWithCapacity(64);
for (int columnId:fieldList) {
if(isValidColumnID(columnId)){
// valid column id only
validIds.add(columnId);
}
}
return Ints.toArray(validIds);
}
public int[] validColumnIDsOrAll(IterablefieldList){
if (null == fieldList || 0 == Iterables.size(fieldList)){
return defaultColumnIdList.clone();
}
int[] array;
if(fieldList instanceof Collection){
array = Ints.toArray(Collections2.filter((Collection)fieldList, Predicates.notNull()));
}else{
array = Ints.toArray(Lists.newArrayList(Iterables.filter(fieldList, Predicates.notNull())));
}
return validColumnIDsOrAll(array);
}
public int[] validColumnIDsOrAllOf(String... fieldList){
if (null == fieldList || 0 == fieldList.length){
return defaultColumnIdList.clone();
}
return validColumnIDsOrAll(columnIDsOf(fieldList));
}
public int[] validColumnIDsOrAllOf(Iterable fieldList){
if (null == fieldList || 0 == Iterables.size(fieldList)){
return defaultColumnIdList.clone();
}
return validColumnIDsOrAll(columnIDsOf(fieldList));
}
/**
* @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));
}
}
/**
* @param columnId
* @return return true if columnId is a primary key Id
*/
public boolean isPrimaryKeyId(int columnId){
if(columnId >= 0 && columnId < columnCount){
for(int id : primaryKeyIds){
if(columnId == id){
return true;
}
}
}
return false;
}
/**
* @param column
* @return return true if columnId is a primary key Id
*/
public boolean isPrimaryKey(String column){
return isPrimaryKeyId(columnIDOf(column));
}
public boolean isForeignKeyId(int columnId){
if(columnId >= 0 && columnId < columnCount){
for(String fkName : foreignKeys.keySet()){
int[] fkids = foreignKeyIdArrayOf(fkName);
for(int id : fkids){
if(id == columnId){
return true;
}
}
}
}
return false;
}
public boolean isForeignKey(String column){
return isForeignKeyId(columnIDOf(column));
}
/**
* 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