Example usage for org.hibernate.hql.internal.ast.tree AssignmentSpecification affectsTable

List of usage examples for org.hibernate.hql.internal.ast.tree AssignmentSpecification affectsTable

Introduction

In this page you can find the example usage for org.hibernate.hql.internal.ast.tree AssignmentSpecification affectsTable.

Prototype

public boolean affectsTable(String tableName) 

Source Link

Usage

From source file:com.blazebit.persistence.integration.hibernate.CustomTableBasedUpdateHandlerImpl.java

License:Apache License

public CustomTableBasedUpdateHandlerImpl(TableBasedUpdateHandlerImpl delegate, HqlSqlWalker walker) {
    this.delegate = delegate;
    // Here comes the madness...
    // We need to somehow execute our code within the temporary table scope, but since there is no way for use to do this externally,
    // we need to use invocation handlers to get a callback at the right time
    // First, we reduce the update statements
    String[] updates = delegate.getSqlStatements();
    UpdateStatement updateStatement = (UpdateStatement) walker.getAST();
    FromElement fromElement = updateStatement.getFromClause().getFromElement();
    AbstractEntityPersister targetedPersister = (AbstractEntityPersister) fromElement.getQueryable();
    String[] tableNames = targetedPersister.getConstraintOrderedTableNameClosure();
    String[][] columnNames = targetedPersister.getContraintOrderedTableKeyColumnClosure();

    int subclassCount = delegate.getTargetedQueryable().getEntityMetamodel().getSubclassEntityNames().size();
    Set<String> subclassTableNames = new HashSet<>();
    for (int i = 0; i < subclassCount; i++) {
        subclassTableNames.add(delegate.getTargetedQueryable().getSubclassTableName(i));
    }/*from w w  w.  ja  va 2  s  .co m*/

    final String[] secondaryTableUpdates = updates.clone();
    final String[] secondaryTableInserts = new String[updates.length];

    StringBuilder sb = new StringBuilder();
    StringBuilder selectSb = new StringBuilder();
    String selectString = "select ";
    String inString = "IN (";
    for (int tableIndex = 0; tableIndex < tableNames.length; tableIndex++) {
        if (updates[tableIndex] != null) {
            // We introduce a dummy update statement that we react upon
            if (subclassTableNames.contains(tableNames[tableIndex])) {
                secondaryTableUpdates[tableIndex] = null;
            } else {
                sb.setLength(0);
                selectSb.setLength(0);

                boolean affected = false;
                String idSubselect = updates[tableIndex].substring(
                        updates[tableIndex].lastIndexOf(inString) + inString.length(),
                        updates[tableIndex].length() - 1);

                sb.append("insert into ").append(tableNames[tableIndex]);
                String[] keyColumnNames = columnNames[tableIndex];
                sb.append('(');

                final List<AssignmentSpecification> assignmentSpecifications = walker
                        .getAssignmentSpecifications();
                for (AssignmentSpecification assignmentSpecification : assignmentSpecifications) {
                    if (assignmentSpecification.affectsTable(tableNames[tableIndex])) {
                        String sqlAssignmentFragment = assignmentSpecification.getSqlAssignmentFragment();
                        int eqIndex = sqlAssignmentFragment.indexOf('=');
                        sb.append(sqlAssignmentFragment, 0, eqIndex);
                        sb.append(',');
                        selectSb.append(sqlAssignmentFragment, eqIndex + 1, sqlAssignmentFragment.length());
                        selectSb.append(',');

                        affected = true;
                    }
                }
                if (affected) {
                    for (int i = 0; i < keyColumnNames.length; i++) {
                        sb.append(keyColumnNames[i]);
                        sb.append(',');
                    }
                    sb.setCharAt(sb.length() - 1, ')');
                    sb.append(' ').append(selectString);
                    sb.append(selectSb);
                    sb.append(idSubselect, selectString.length(), idSubselect.length());
                    sb.append(" where not exists (select 1 from ");
                    sb.append(tableNames[tableIndex]);
                    sb.append(" a where ");

                    for (int i = 0; i < keyColumnNames.length; i++) {
                        sb.append("a.");
                        sb.append(keyColumnNames[i]);
                        sb.append(" = ");
                        sb.append(keyColumnNames[i]);
                        sb.append(" and ");
                    }

                    sb.setLength(sb.length() - " and ".length());
                    sb.append(")");

                    secondaryTableInserts[tableIndex] = sb.toString();
                }

                updates[tableIndex] = "";
            }
        }
    }

    this.secondaryTableUpdates = secondaryTableUpdates;
    this.secondaryTableInserts = secondaryTableInserts;
}