package org.molgenis.data.postgresql;
import org.molgenis.data.DataService;
import org.molgenis.data.meta.model.Attribute;
import org.molgenis.data.meta.model.EntityType;
import java.util.stream.Stream;
import java.util.stream.StreamSupport;
import static org.molgenis.data.meta.AttributeType.ONE_TO_MANY;
import static org.molgenis.data.support.EntityTypeUtils.isMultipleReferenceType;
import static org.molgenis.util.ApplicationContextProvider.getApplicationContext;
/**
* Utility class used by other PostgreSQL classes
*/
class PostgreSqlQueryUtils
{
static final String JUNCTION_TABLE_ORDER_ATTR_NAME = "order";
private PostgreSqlQueryUtils()
{
}
/**
* Returns the double-quoted table name based on entity name
*
* @param entityType entity meta data
* @return table name for this entity
*/
static String getTableName(EntityType entityType)
{
return getTableName(entityType, true);
}
/**
* Returns the table name based on entity name
*
* @param entityType entity meta data
* @return PostgreSQL table name
*/
static String getTableName(EntityType entityType, boolean quoteSystemIdentifiers)
{
StringBuilder strBuilder = new StringBuilder(32);
if (quoteSystemIdentifiers)
{
strBuilder.append('"');
}
strBuilder.append(entityType.getName());
if (quoteSystemIdentifiers)
{
strBuilder.append('"');
}
return strBuilder.toString();
}
/**
* Returns the junction table name for the given attribute of the given entity
*
* @param entityType entity meta data that owns the attribute
* @param attr attribute
* @return PostgreSQL junction table name
*/
static String getJunctionTableName(EntityType entityType, Attribute attr)
{
return '"' + entityType.getName() + '_' + attr.getName() + '"';
}
/**
* Returns the junction table index name for the given indexed attribute in a junction table
*
* @param entityType entity meta data
* @param attr attribute
* @param idxAttr indexed attribute
* @return PostgreSQL junction table index name
*/
static String getJunctionTableIndexName(EntityType entityType, Attribute attr, Attribute idxAttr)
{
return '"' + entityType.getName() + '_' + attr.getName() + '_' + idxAttr.getName() + "_idx\"";
}
/**
* Returns attributes persisted by PostgreSQL (e.g. no compound attributes and attributes with an expression)
*
* @return stream of persisted attributes
*/
static Stream<Attribute> getPersistedAttributes(EntityType entityType)
{
return StreamSupport.stream(entityType.getAtomicAttributes().spliterator(), false)
.filter(atomicAttr -> atomicAttr.getExpression() == null);
}
/**
* Returns all non-bidirectional attributes persisted by PostgreSQL in junction tables (e.g. no compound attributes and attributes
* with an expression)
*
* @return stream of attributes persisted by PostgreSQL in junction tables
*/
static Stream<Attribute> getJunctionTableAttributes(EntityType entityType)
{
// return all attributes referencing multiple entities except for one-to-many attributes that are mapped by
// another attribute
return getPersistedAttributes(entityType)
.filter(attr -> isMultipleReferenceType(attr) && !(attr.getDataType() == ONE_TO_MANY && attr
.isMappedBy()));
}
/**
* Returns all attributes persisted by PostgreSQL in entity table (e.g. no compound attributes and attributes
* with an expression)
*
* @return stream of persisted non-MREF attributes
*/
static Stream<Attribute> getTableAttributes(EntityType entityType)
{
return getPersistedAttributes(entityType).filter(PostgreSqlQueryUtils::isTableAttribute);
}
static boolean isTableAttribute(Attribute attr)
{
return !isMultipleReferenceType(attr) && !(attr.getDataType() == ONE_TO_MANY && attr.isMappedBy());
}
static Stream<Attribute> getTableAttributesReadonly(EntityType entityType)
{
return getTableAttributes(entityType).filter(Attribute::isReadOnly);
}
/**
* Returns whether the given entity is persisted in PostgreSQL
*
* @param entityType entity meta data
* @return true is the entity is persisted in PostgreSQL
*/
static boolean isPersistedInPostgreSql(EntityType entityType)
{
String backend = entityType.getBackend();
if (backend == null)
{
// TODO remove this check after getBackend always returns the backend
if (null != getApplicationContext())
{
DataService dataService = getApplicationContext().getBean(DataService.class);
backend = dataService.getMeta().getDefaultBackend().getName();
}
else
{
// A workaround for the integration tests. getApplicationContext() should not be null
return true;
}
}
return backend.equals(PostgreSqlRepositoryCollection.POSTGRESQL);
}
}