Validate that an api table doesn't have more than 1 field with the same name (which can happen if it's in the removed set along with main set)

This commit is contained in:
2024-06-19 16:50:00 -05:00
parent fcae58168e
commit c748977a1b
2 changed files with 81 additions and 2 deletions

View File

@ -25,9 +25,11 @@ package com.kingsrook.qqq.api.actions;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.Set;
import com.kingsrook.qqq.api.model.APIVersion;
import com.kingsrook.qqq.api.model.APIVersionRange;
import com.kingsrook.qqq.api.model.actions.GetTableApiFieldsInput;
@ -76,7 +78,27 @@ public class GetTableApiFieldsAction extends AbstractQActionFunction<GetTableApi
{
if(!fieldMapCache.containsKey(apiNameVersionAndTableName))
{
Map<String, QFieldMetaData> map = getTableApiFieldList(apiNameVersionAndTableName).stream().collect(Collectors.toMap(f -> (ApiFieldMetaData.getEffectiveApiFieldName(apiNameVersionAndTableName.apiName(), f)), f -> f));
List<QFieldMetaData> tableApiFieldList = getTableApiFieldList(apiNameVersionAndTableName);
Map<String, QFieldMetaData> map = new LinkedHashMap<>();
Set<String> duplicateFieldNames = new HashSet<>();
for(QFieldMetaData qFieldMetaData : tableApiFieldList)
{
String effectiveApiFieldName = ApiFieldMetaData.getEffectiveApiFieldName(apiNameVersionAndTableName.apiName(), qFieldMetaData);
if(map.containsKey(effectiveApiFieldName))
{
duplicateFieldNames.add(effectiveApiFieldName);
}
else
{
map.put(effectiveApiFieldName, qFieldMetaData);
}
}
if(!duplicateFieldNames.isEmpty())
{
throw (new QException("The field names [" + duplicateFieldNames + "] appear in this api table more than once. (Do you need to exclude a field that is still in the table, but is also marked as removed?)"));
}
fieldMapCache.put(apiNameVersionAndTableName, map);
}

View File

@ -25,6 +25,14 @@ package com.kingsrook.qqq.api.model.metadata.tables;
import java.util.LinkedHashMap;
import java.util.Map;
import com.kingsrook.qqq.api.ApiSupplementType;
import com.kingsrook.qqq.api.actions.GetTableApiFieldsAction;
import com.kingsrook.qqq.api.model.APIVersion;
import com.kingsrook.qqq.api.model.metadata.ApiInstanceMetaData;
import com.kingsrook.qqq.api.model.metadata.ApiInstanceMetaDataContainer;
import com.kingsrook.qqq.backend.core.context.CapturedContext;
import com.kingsrook.qqq.backend.core.context.QContext;
import com.kingsrook.qqq.backend.core.instances.QInstanceValidator;
import com.kingsrook.qqq.backend.core.logging.QLogger;
import com.kingsrook.qqq.backend.core.model.metadata.QInstance;
import com.kingsrook.qqq.backend.core.model.metadata.tables.QSupplementalTableMetaData;
import com.kingsrook.qqq.backend.core.model.metadata.tables.QTableMetaData;
@ -36,6 +44,8 @@ import com.kingsrook.qqq.backend.core.utils.CollectionUtils;
*******************************************************************************/
public class ApiTableMetaDataContainer extends QSupplementalTableMetaData
{
private static final QLogger LOG = QLogger.getLogger(ApiTableMetaDataContainer.class);
private Map<String, ApiTableMetaData> apis;
@ -172,4 +182,51 @@ public class ApiTableMetaDataContainer extends QSupplementalTableMetaData
return (this);
}
/*******************************************************************************
**
*******************************************************************************/
@Override
public void validate(QInstance qInstance, QTableMetaData tableMetaData, QInstanceValidator qInstanceValidator)
{
super.validate(qInstance, tableMetaData, qInstanceValidator);
////////////////////////////////////////
// iterate over apis this table is in //
////////////////////////////////////////
for(String apiName : CollectionUtils.nonNullMap(apis).keySet())
{
ApiInstanceMetaData apiInstanceMetaData = ApiInstanceMetaDataContainer.of(qInstance).getApis().get(apiName);
//////////////////////////////////////////////////
// iterate over supported versions for this api //
//////////////////////////////////////////////////
for(APIVersion version : apiInstanceMetaData.getSupportedVersions())
{
CapturedContext capturedContext = QContext.capture();
try
{
QContext.setQInstance(qInstance);
///////////////////////////////////////////////////////////////////////////////////////////////////
// try to get the field-map for this table. note that this will (implicitly) throw an exception //
// if we have the same field name more than once, which can happen if a field is both in the //
// removed-list and the table's normal field list. //
///////////////////////////////////////////////////////////////////////////////////////////////////
GetTableApiFieldsAction.getTableApiFieldMap(new GetTableApiFieldsAction.ApiNameVersionAndTableName(apiName, version.toString(), tableMetaData.getName()));
}
catch(Exception e)
{
String message = "Error validating ApiTableMetaData for table: " + tableMetaData.getName() + ", api: " + apiName + ", version: " + version;
LOG.warn(message, e);
qInstanceValidator.getErrors().add(message + ": " + e.getMessage());
}
finally
{
QContext.init(capturedContext);
}
}
}
}
}