Class AbstractSqlLikeQueryBuilder

java.lang.Object
io.micronaut.data.model.query.builder.AbstractSqlLikeQueryBuilder
All Implemented Interfaces:
QueryBuilder
Direct Known Subclasses:
JpaQueryBuilder, SqlQueryBuilder

public abstract class AbstractSqlLikeQueryBuilder extends Object implements QueryBuilder
An abstract class for builders that build SQL-like queries.
Since:
1.0.0
Author:
graemerocher
  • Field Details

  • Constructor Details

    • AbstractSqlLikeQueryBuilder

      public AbstractSqlLikeQueryBuilder()
  • Method Details

    • getDialect

      protected Dialect getDialect()
      Get dialect.
      Returns:
      dialect
    • asLiterals

      protected void asLiterals(StringBuilder sb, @Nullable @Nullable Object value)
      Appends values as literals to the sql query builder.
      Parameters:
      sb - the sql string builder
      value - the value to be added
    • asLiteral

      @NonNull protected @NonNull String asLiteral(@Nullable @Nullable Object value)
      Convert the literal value to it's SQL representation.
      Parameters:
      value - The literal value
      Returns:
      converter value
    • concat

      protected void concat(StringBuilder writer, Collection<Runnable> partsWriters)
      Parameters:
      writer - The writer
      partsWriters - The parts writers
    • buildQuery

      public QueryResult buildQuery(@NonNull @NonNull io.micronaut.core.annotation.AnnotationMetadata annotationMetadata, @NonNull @NonNull QueryModel query)
      Description copied from interface: QueryBuilder
      Encode the given query for the passed annotation metadata and query.
      Specified by:
      buildQuery in interface QueryBuilder
      Parameters:
      annotationMetadata - The annotation metadata
      query - The query model
      Returns:
      The query result
    • getTableName

      protected abstract String getTableName(PersistentEntity entity)
      Get the table name for the given entity.
      Parameters:
      entity - The entity
      Returns:
      The table name
    • getUnescapedTableName

      protected String getUnescapedTableName(PersistentEntity entity)
      Get the table name for the given entity.
      Parameters:
      entity - The entity
      Returns:
      The table name
    • getAliasName

      protected String getAliasName(PersistentEntity entity)
      Get an alias name for the given entity.
      Parameters:
      entity - The entity
      Returns:
      The alias name
    • getAliasName

      public String getAliasName(JoinPath joinPath)
      Get the alias name.
      Parameters:
      joinPath - The join path
      Returns:
      The alias
    • getPathOnlyAliasName

      @NonNull protected @NonNull String getPathOnlyAliasName(JoinPath joinPath)
      Get the alias name for just the join path.
      Parameters:
      joinPath - The join path
      Returns:
      The alias
    • buildJoin

      protected abstract String[] buildJoin(String alias, JoinPath joinPath, String joinType, StringBuilder stringBuilder, Map<String,String> appliedJoinPaths, AbstractSqlLikeQueryBuilder.QueryState queryState)
      Build a join expression for the given alias, association, join type and builder.
      Parameters:
      alias - The alias
      joinPath - The join path
      joinType - The join type string
      stringBuilder - The target builder
      appliedJoinPaths - The applied joins paths
      queryState - The query state
      Returns:
      An array representing the aliases for each join association in the specified join path
    • getColumnName

      protected abstract String getColumnName(PersistentProperty persistentProperty)
      Get the column name for the given property.
      Parameters:
      persistentProperty - The property
      Returns:
      The column name
    • selectAllColumns

      protected abstract void selectAllColumns(io.micronaut.core.annotation.AnnotationMetadata annotationMetadata, AbstractSqlLikeQueryBuilder.QueryState queryState, StringBuilder queryBuffer)
      Obtain the string that selects all columns from the entity.
      Parameters:
      annotationMetadata - The annotation metadata
      queryState - The query state
      queryBuffer -
    • selectAllColumns

      protected void selectAllColumns(PersistentEntity entity, String alias, StringBuilder queryBuffer)
      Selects all columns for the given entity and alias.
      Parameters:
      entity - The entity
      alias - The alias
      queryBuffer - The buffer to append the columns
    • selectAllColumns

      protected abstract void selectAllColumns(io.micronaut.core.annotation.AnnotationMetadata annotationMetadata, PersistentEntity entity, String alias, StringBuilder queryBuffer)
      Selects all columns for the given entity and alias.
      Parameters:
      annotationMetadata - The annotation metadata
      entity - The entity
      alias - The alias
      queryBuffer - The buffer to append the columns
    • selectAllColumnsFromJoinPaths

      @Internal protected void selectAllColumnsFromJoinPaths(AbstractSqlLikeQueryBuilder.QueryState queryState, StringBuilder queryBuffer, Collection<JoinPath> allPaths, @Nullable @Nullable Map<JoinPath,String> joinAliasOverride)
    • shouldEscape

      protected boolean shouldEscape(@NonNull @NonNull PersistentEntity entity)
      Whether queries should be escaped for the given entity.
      Parameters:
      entity - The entity
      Returns:
      True if they should be escaped
    • getTableAsKeyword

      protected String getTableAsKeyword()
      Get the AS keyword to use for table aliases.
      Returns:
      The AS keyword if any
    • quote

      protected String quote(String persistedName)
      Quote a column name for the dialect.
      Parameters:
      persistedName - The persisted name.
      Returns:
      The quoted name
    • buildSelect

      protected void buildSelect(io.micronaut.core.annotation.AnnotationMetadata annotationMetadata, AbstractSqlLikeQueryBuilder.QueryState queryState, StringBuilder queryString, List<QueryModel.Projection> projectionList, String tableAlias, PersistentEntity entity)
      Build select statement.
      Parameters:
      annotationMetadata - the annotation metadata
      queryState - the query state
      queryString - the query string builder
      projectionList - projection list (can be empty, then selects all columns)
      tableAlias - the table alias
      entity - the persistent entity
    • appendAssociationProjection

      protected boolean appendAssociationProjection(AbstractSqlLikeQueryBuilder.QueryState queryState, StringBuilder queryString, PersistentProperty property, PersistentPropertyPath propertyPath)
      Appends selection projection for the property which is association.
      Parameters:
      queryState - the query state
      queryString - the query string builder
      property - the persistent property
      propertyPath - the persistent property path
      Returns:
      true if association projection is appended, otherwise false
    • getNamingStrategy

      protected NamingStrategy getNamingStrategy(PersistentPropertyPath propertyPath)
      Gets NamingStrategy for the property path. Subclasses might override and potentially provide different strategy in some cases.
      Parameters:
      propertyPath - the property path representation
      Returns:
      naming strategy for the property path
    • getNamingStrategy

      protected NamingStrategy getNamingStrategy(PersistentEntity entity)
      Gets NamingStrategy for the entity. Subclasses might override and potentially provide different strategy in some cases.
      Parameters:
      entity - the persistent entity
      Returns:
      naming strategy for the entity
    • getMappedName

      @NonNull protected @NonNull String getMappedName(@NonNull @NonNull NamingStrategy namingStrategy, @NonNull @NonNull PersistentProperty property)
      Gets the mapped name from the property using NamingStrategy.
      Parameters:
      namingStrategy - the naming strategy being used
      property - the persistent property
      Returns:
      the mapped name for the property
    • getMappedName

      @NonNull protected @NonNull String getMappedName(@NonNull @NonNull NamingStrategy namingStrategy, @NonNull @NonNull Association association)
      Gets the mapped name from the association using NamingStrategy.
      Parameters:
      namingStrategy - the naming strategy being used
      association - the associatioon
      Returns:
      the mapped name for the association
    • getMappedName

      @NonNull protected @NonNull String getMappedName(@NonNull @NonNull NamingStrategy namingStrategy, @NonNull @NonNull List<Association> associations, @NonNull @NonNull PersistentProperty property)
      Gets the mapped name from for the list of associations and property using NamingStrategy.
      Parameters:
      namingStrategy - the naming strategy
      associations - the association list
      property - the property
      Returns:
      the mappen name for the list of associations and property using given naming strategy
    • appendProjectionRowCount

      protected abstract void appendProjectionRowCount(StringBuilder queryString, String logicalName)
      Appends a row count projection to the query string.
      Parameters:
      queryString - The query string
      logicalName - The alias to the table name
    • buildWhereClause

      protected void buildWhereClause(io.micronaut.core.annotation.AnnotationMetadata annotationMetadata, QueryModel.Junction criteria, AbstractSqlLikeQueryBuilder.QueryState queryState)
      Builds where clause.
      Parameters:
      annotationMetadata - the annotation metadata for the method
      criteria - the criteria
      queryState - the query state
    • buildAdditionalWhereClause

      protected String buildAdditionalWhereClause(AbstractSqlLikeQueryBuilder.QueryState queryState, io.micronaut.core.annotation.AnnotationMetadata annotationMetadata)
      Builds additional where clause if there is Where annotation on the entity.
      Parameters:
      queryState - the query state
      annotationMetadata - the annotation metadata
      Returns:
      where clause if there was Where annotation on the entity (or joins for JPA implementation)
    • buildAdditionalWhereString

      protected String buildAdditionalWhereString(String alias, PersistentEntity entity, io.micronaut.core.annotation.AnnotationMetadata annotationMetadata)
      Builds WHERE clause for the entity and given alias if IgnoreWhere is not present.
      Parameters:
      alias - the entity alias
      entity - the entity
      annotationMetadata - the entity metadata
      Returns:
      the WHERE clause
    • buildAdditionalWhereString

      protected final String buildAdditionalWhereString(JoinPath joinPath, io.micronaut.core.annotation.AnnotationMetadata annotationMetadata)
      Builds WHERE clause based on Where annotation on the metadata.
      Parameters:
      joinPath - the join path
      annotationMetadata - the annotation metadata
      Returns:
      WHERE clause if Where annotation is declared and IgnoreWhere is not present, otherwise empty string
    • resolveWhereForAnnotationMetadata

      protected final String resolveWhereForAnnotationMetadata(String alias, io.micronaut.core.annotation.AnnotationMetadata annotationMetadata)
      Resolves where clause if there is Where annotation on the entity.
      Parameters:
      alias - the entity alias
      annotationMetadata - the entity annotation metadata
      Returns:
      where clause with entity alias if entity has declared where annotation
    • appendOrder

      protected void appendOrder(io.micronaut.core.annotation.AnnotationMetadata annotationMetadata, QueryModel query, AbstractSqlLikeQueryBuilder.QueryState queryState)
      Appends order to the query.
      Parameters:
      annotationMetadata - the annotation metadata
      query - the query model
      queryState - the query state
    • appendForUpdate

      protected void appendForUpdate(AbstractSqlLikeQueryBuilder.QueryPosition queryPosition, QueryModel query, StringBuilder queryBuilder)
      Adds "forUpdate" pisimmistic locking.
      Parameters:
      queryPosition - The query position
      query - The query
      queryBuilder - The builder
    • appendPropertyRef

      protected void appendPropertyRef(StringBuilder sb, io.micronaut.core.annotation.AnnotationMetadata annotationMetadata, PersistentEntity entity, AbstractSqlLikeQueryBuilder.QueryPropertyPath propertyPath)
      Appends property to the sql string builder.
      Parameters:
      sb - the sql string builder
      annotationMetadata - the annotation metadata
      entity - the persistent entity
      propertyPath - the query property path
    • handleSubQuery

      protected void handleSubQuery(AbstractSqlLikeQueryBuilder.CriteriaContext ctx, QueryModel.SubqueryCriterion subqueryCriterion, String comparisonExpression)
      For handling subqueries.
      Parameters:
      ctx - The criteria context
      subqueryCriterion - The subquery criterion
      comparisonExpression - The comparison expression
    • isExpandEmbedded

      protected boolean isExpandEmbedded()
      Should embedded queries by expanded by the implementation.
      Returns:
      True if they should
    • appendUpdateSetParameter

      protected void appendUpdateSetParameter(StringBuilder sb, String alias, PersistentProperty prop, Runnable appendParameter)
      Appends the SET=? call to the query string.
      Parameters:
      sb - The string builder
      alias - The alias
      prop - The property
      appendParameter - The append parameter action
    • appendTransformed

      protected void appendTransformed(StringBuilder sb, String transformed, Runnable appendParameter)
      Appends custom query part.
      Parameters:
      sb - The string builder
      transformed - The transformed query part
      appendParameter - The append parameter action
    • computePropertyPaths

      protected abstract boolean computePropertyPaths()
      Whether property path expressions require computation by the implementation. In a certain query dialects property paths are supported (such as JPA-QL where you can do select foo.bar) whilst for explicit SQL queries paths like this have to be computed into aliases / column name references.
      Returns:
      True if property path computation is required.
    • buildUpdate

      public QueryResult buildUpdate(@NonNull @NonNull io.micronaut.core.annotation.AnnotationMetadata annotationMetadata, @NonNull @NonNull QueryModel query, @NonNull @NonNull List<String> propertiesToUpdate)
      Description copied from interface: QueryBuilder
      Encode the given query into the encoded query instance.
      Specified by:
      buildUpdate in interface QueryBuilder
      Parameters:
      annotationMetadata - The annotation metadata
      query - The query
      propertiesToUpdate - The property names to update
      Returns:
      The encoded query
    • buildUpdate

      public QueryResult buildUpdate(@NonNull @NonNull io.micronaut.core.annotation.AnnotationMetadata annotationMetadata, @NonNull @NonNull QueryModel query, @NonNull @NonNull Map<String,Object> propertiesToUpdate)
      Description copied from interface: QueryBuilder
      Encode the given query into the encoded query instance.
      Specified by:
      buildUpdate in interface QueryBuilder
      Parameters:
      annotationMetadata - The annotation metadata
      query - The query
      propertiesToUpdate - The property names to update
      Returns:
      The encoded query
    • buildDelete

      public QueryResult buildDelete(@NonNull @NonNull io.micronaut.core.annotation.AnnotationMetadata annotationMetadata, @NonNull @NonNull QueryModel query)
      Description copied from interface: QueryBuilder
      Encode the given query into the encoded query instance.
      Specified by:
      buildDelete in interface QueryBuilder
      Parameters:
      annotationMetadata - The annotation metadata
      query - The query
      Returns:
      The encoded query
    • isAliasForBatch

      protected abstract boolean isAliasForBatch(PersistentEntity persistentEntity, io.micronaut.core.annotation.AnnotationMetadata annotationMetadata)
      Should aliases be used in batch statements.
      Parameters:
      persistentEntity - the persistent entity
      annotationMetadata - the method annotation metadata
      Returns:
      True if they should
    • appendDeleteClause

      @NonNull protected @NonNull StringBuilder appendDeleteClause(StringBuilder queryString)
      Append the delete clause.
      Parameters:
      queryString - The query string
      Returns:
      The delete clause
    • buildOrderBy

      @NonNull public @NonNull QueryResult buildOrderBy(@NonNull @NonNull PersistentEntity entity, @NonNull @NonNull Sort sort)
      Description copied from interface: QueryBuilder
      Encode the given query into the encoded query instance.
      Specified by:
      buildOrderBy in interface QueryBuilder
      Parameters:
      entity - The root entity
      sort - The sort
      Returns:
      The encoded query
    • buildOrderBy

      @NonNull public @NonNull QueryResult buildOrderBy(String query, @NonNull @NonNull PersistentEntity entity, @NonNull @NonNull io.micronaut.core.annotation.AnnotationMetadata annotationMetadata, @NonNull @NonNull Sort sort)
      Encode the given query into the encoded query instance.
      Parameters:
      query - The query
      entity - The root entity
      annotationMetadata - The annotation metadata
      sort - The sort
      Returns:
      The encoded query
    • asPath

      protected String asPath(List<Association> associations, PersistentProperty property)
      Join associations and property as path.
      Parameters:
      associations - The associations
      property - The property
      Returns:
      joined path
    • traversePersistentProperties

      protected void traversePersistentProperties(PersistentProperty property, BiConsumer<List<Association>,PersistentProperty> consumer)
      Traverses persistent properties.
      Parameters:
      property - The property to start traversing from
      consumer - The function to invoke on every property
    • traversePersistentProperties

      protected void traversePersistentProperties(PersistentEntity persistentEntity, BiConsumer<List<Association>,PersistentProperty> consumer)
      Traverses persistent properties.
      Parameters:
      persistentEntity - The persistent entity
      consumer - The function to invoke on every property
    • traversePersistentProperties

      protected void traversePersistentProperties(PersistentEntity persistentEntity, boolean includeIdentity, boolean includeVersion, BiConsumer<List<Association>,PersistentProperty> consumer)
      Traverses persistent properties.
      Parameters:
      persistentEntity - The persistent entity
      includeIdentity - Should be identifier included
      includeVersion - Should be version included
      consumer - The function to invoke on every property
    • traversePersistentProperties

      protected void traversePersistentProperties(List<Association> associations, PersistentProperty property, BiConsumer<List<Association>,PersistentProperty> consumerProperty)
      Traverses persistent properties.
      Parameters:
      associations - The association list being traversed with the property
      property - The persistent property
      consumerProperty - The function to invoke on every property
    • newBindingContext

      protected BindingParameter.BindingContext newBindingContext(@Nullable @Nullable PersistentPropertyPath ref)
      Creates new binding parameter context.
      Parameters:
      ref - the persistent property reference
      Returns:
      new binding parameter context
    • getDataTransformerReadValue

      protected Optional<String> getDataTransformerReadValue(String alias, PersistentProperty prop)
      Returns transformed value if the data transformer id defined.
      Parameters:
      alias - query table alias
      prop - a property
      Returns:
      optional transformed value
    • getDataTransformerWriteValue

      protected Optional<String> getDataTransformerWriteValue(String alias, PersistentProperty prop)
      Returns transformed value if the data transformer id defined.
      Parameters:
      alias - query table alias
      prop - a property
      Returns:
      optional transformed value
    • formatParameter

      protected abstract AbstractSqlLikeQueryBuilder.Placeholder formatParameter(int index)
      Format the parameter at the given index.
      Parameters:
      index - The parameter
      Returns:
      The index
    • resolveJoinType

      public abstract String resolveJoinType(Join.Type jt)
      Resolves the join type.
      Parameters:
      jt - The join type
      Returns:
      The join type.
    • addCriterionHandler

      protected <T extends QueryModel.Criterion> void addCriterionHandler(Class<T> clazz, AbstractSqlLikeQueryBuilder.CriterionHandler<T> handler)
      Adds criterion handler.
      Type Parameters:
      T - The criterion type
      Parameters:
      clazz - The handler class
      handler - The handler
    • getColumnAlias

      protected final String getColumnAlias(PersistentProperty property)
      Gets column alias if defined as alias field on MappedProperty annotation on the mapping field.
      Parameters:
      property - the persisent propert
      Returns:
      column alias if defined, otherwise an empty string
    • checkDialectSupportsJsonEntity

      protected void checkDialectSupportsJsonEntity(PersistentEntity entity)
      If and when EntityRepresentation annotation with JSON type is used for the repository method but dialect does not support JSON entity representations this will throw IllegalArgumentException.
      Parameters:
      entity - the persistent entity
    • isJsonEntity

      protected boolean isJsonEntity(io.micronaut.core.annotation.AnnotationMetadata annotationMetadata, PersistentEntity entity)
      Checks whether EntityRepresentation annotation with JSON type is used for the repository method. If current dialect does not support handling JSON entity representations, IllegalArgumentException is thrown.
      Parameters:
      annotationMetadata - the annotation metadata
      entity - the persistent entity
      Returns:
      true if EntityRepresentation annotation with JSON type is used for the repository method