/*
  * Example with target node:
  *
  * MATCH (n:ENTITY:table {id: {0}}) -[r:role] -  (t {id: {1}})
  * RETURN r
  *
  * Example with relationship indexes:
  *
  * MATCH (n:ENTITY:table {id: {0}}) -[r:role {index: {1}}] -  (t)
  * RETURN r
  */
 private static String initFindRelationshipQuery(
     EntityKeyMetadata ownerEntityKeyMetadata, AssociationKeyMetadata associationKeyMetadata) {
   int offset = 0;
   StringBuilder queryBuilder = new StringBuilder("MATCH ");
   queryBuilder.append("(n:");
   queryBuilder.append(ENTITY);
   queryBuilder.append(":");
   appendLabel(ownerEntityKeyMetadata, queryBuilder);
   appendProperties(ownerEntityKeyMetadata, queryBuilder);
   queryBuilder.append(") - ");
   queryBuilder.append("[r");
   queryBuilder.append(":");
   appendRelationshipType(queryBuilder, associationKeyMetadata);
   offset = ownerEntityKeyMetadata.getColumnNames().length;
   if (associationKeyMetadata.getRowKeyIndexColumnNames().length > 0) {
     appendProperties(queryBuilder, associationKeyMetadata.getRowKeyIndexColumnNames(), offset);
     queryBuilder.append("] - (t");
   } else {
     queryBuilder.append("] - (t");
     appendProperties(
         queryBuilder,
         associationKeyMetadata
             .getAssociatedEntityKeyMetadata()
             .getEntityKeyMetadata()
             .getColumnNames(),
         offset);
   }
   queryBuilder.append(")");
   queryBuilder.append(" RETURN r");
   return queryBuilder.toString();
 }
 private Map<EntityKeyMetadata, EmbeddedNeo4jEntityQueries> initializeEntityQueries(
     SessionFactoryImplementor sessionFactoryImplementor,
     Map<AssociationKeyMetadata, EmbeddedNeo4jAssociationQueries> associationQueries) {
   Map<EntityKeyMetadata, EmbeddedNeo4jEntityQueries> entityQueries =
       initializeEntityQueries(sessionFactoryImplementor);
   for (AssociationKeyMetadata associationKeyMetadata : associationQueries.keySet()) {
     EntityKeyMetadata entityKeyMetadata =
         associationKeyMetadata.getAssociatedEntityKeyMetadata().getEntityKeyMetadata();
     if (!entityQueries.containsKey(entityKeyMetadata)) {
       // Embeddables metadata
       entityQueries.put(entityKeyMetadata, new EmbeddedNeo4jEntityQueries(entityKeyMetadata));
     }
   }
   return entityQueries;
 }
  // TODO replace with method provided by OGM-1035
  private boolean isRowKeyColumn(AssociationKeyMetadata metadata, String column) {
    for (String rowKeyColumn : metadata.getRowKeyColumnNames()) {
      if (rowKeyColumn.equals(column)) {
        return true;
      }
    }

    return false;
  }
 /*
  * Example with association:
  *
  * MATCH (n:ENTITY:table {id: {0}}) -[r:role] - (e)
  * DELETE r
  *
  * Example with embedded collection:
  *
  * MATCH (n:ENTITY:table {id: {0}}) -[r:role] - (e:EMBEDDED)
  * DELETE r, e
  *
  * Example with indexes:
  *
  * MATCH (n:ENTITY:table {id: {0}}) -[r:role {index: {1}}] - (e)
  * DELETE r
  */
 private static String initRemoveAssociationRowQuery(
     EntityKeyMetadata ownerEntityKeyMetadata, AssociationKeyMetadata associationKeyMetadata) {
   StringBuilder queryBuilder = new StringBuilder("MATCH ");
   queryBuilder.append("(n:");
   queryBuilder.append(ENTITY);
   queryBuilder.append(":");
   appendLabel(ownerEntityKeyMetadata, queryBuilder);
   appendProperties(ownerEntityKeyMetadata, queryBuilder);
   queryBuilder.append(") - ");
   queryBuilder.append("[r");
   queryBuilder.append(":");
   appendRelationshipType(queryBuilder, associationKeyMetadata);
   int offset = ownerEntityKeyMetadata.getColumnNames().length;
   boolean hasIndexColumns = associationKeyMetadata.getRowKeyIndexColumnNames().length > 0;
   if (hasIndexColumns) {
     appendProperties(queryBuilder, associationKeyMetadata.getRowKeyIndexColumnNames(), offset);
   }
   queryBuilder.append("] - (e");
   if (associationKeyMetadata.getAssociationKind() == AssociationKind.EMBEDDED_COLLECTION) {
     queryBuilder.append(":");
     queryBuilder.append(EMBEDDED);
   }
   if (!hasIndexColumns) {
     appendProperties(
         queryBuilder,
         associationKeyMetadata
             .getAssociatedEntityKeyMetadata()
             .getEntityKeyMetadata()
             .getColumnNames(),
         offset);
   }
   queryBuilder.append(")");
   queryBuilder.append(" DELETE r");
   if (associationKeyMetadata.getAssociationKind() == AssociationKind.EMBEDDED_COLLECTION) {
     queryBuilder.append(", e");
   }
   return queryBuilder.toString();
 }
 /*
  * Example with association:
  *
  * MATCH (n:ENTITY:table {id: {0}}) -[r:role] - ()
  * DELETE r
  *
  * Example with embedded:
  *
  * MATCH (n:ENTITY:table {id: {0}}) -[r:role] - (e:EMBEDDED)
  * DELETE r, e
  */
 private static String initRemoveAssociationQuery(
     EntityKeyMetadata ownerEntityKeyMetadata, AssociationKeyMetadata associationKeyMetadata) {
   StringBuilder queryBuilder = new StringBuilder("MATCH ");
   queryBuilder.append("(n:");
   queryBuilder.append(ENTITY);
   queryBuilder.append(":");
   appendLabel(ownerEntityKeyMetadata, queryBuilder);
   appendProperties(ownerEntityKeyMetadata, queryBuilder);
   queryBuilder.append(") - ");
   queryBuilder.append("[r");
   queryBuilder.append(":");
   appendRelationshipType(queryBuilder, associationKeyMetadata);
   queryBuilder.append("]");
   if (associationKeyMetadata.getAssociationKind() == AssociationKind.EMBEDDED_COLLECTION) {
     queryBuilder.append(" - (e:");
     queryBuilder.append(EMBEDDED);
     queryBuilder.append(") DELETE r, e");
   } else {
     queryBuilder.append(" - () DELETE r");
   }
   return queryBuilder.toString();
 }
 private static void appendRelationshipType(
     StringBuilder queryBuilder, AssociationKeyMetadata associationKeyMetadata) {
   escapeIdentifier(queryBuilder, associationKeyMetadata.getCollectionRole());
 }