Search in sources :

Example 21 with QuotingStrategy

use of org.apache.cayenne.dba.QuotingStrategy in project cayenne by apache.

the class UnitDbAdapter method getConstraints.

/**
 * Returns a map of database constraints with DbEntity names used as keys,
 * and Collections of constraint names as values.
 */
protected Map<String, Collection<String>> getConstraints(Connection conn, DataMap map, Collection<String> includeTables) throws SQLException {
    Map<String, Collection<String>> constraintMap = new HashMap<>();
    DatabaseMetaData metadata = conn.getMetaData();
    for (String name : includeTables) {
        DbEntity entity = map.getDbEntity(name);
        if (entity == null) {
            continue;
        }
        QuotingStrategy strategy = adapter.getQuotingStrategy();
        // Get all constraints for the table
        ResultSet rs = metadata.getExportedKeys(entity.getCatalog(), entity.getSchema(), entity.getName());
        try {
            while (rs.next()) {
                String fk = rs.getString("FK_NAME");
                String fkTable = rs.getString("FKTABLE_NAME");
                if (fk != null && fkTable != null) {
                    Collection<String> constraints = constraintMap.get(fkTable);
                    if (constraints == null) {
                        // use a set to avoid duplicate constraints
                        constraints = new HashSet<String>();
                        constraintMap.put(fkTable, constraints);
                    }
                    constraints.add(strategy.quotedIdentifier(entity, fk));
                }
            }
        } finally {
            rs.close();
        }
    }
    return constraintMap;
}
Also used : DbEntity(org.apache.cayenne.map.DbEntity) HashMap(java.util.HashMap) ResultSet(java.sql.ResultSet) Collection(java.util.Collection) QuotingStrategy(org.apache.cayenne.dba.QuotingStrategy) DatabaseMetaData(java.sql.DatabaseMetaData)

Example 22 with QuotingStrategy

use of org.apache.cayenne.dba.QuotingStrategy in project cayenne by apache.

the class FlattenedArcKey method buildJoinSnapshotsForDelete.

/**
 * Returns pk snapshots for join records for the single-step flattened
 * relationship. Multiple joins between the same pair of objects are
 * theoretically possible, so the return value is a list.
 */
List buildJoinSnapshotsForDelete(DataNode node) {
    Map<String, Object> snapshot = eagerJoinSnapshot();
    DbEntity joinEntity = getJoinEntity();
    boolean fetchKey = false;
    for (DbAttribute dbAttr : joinEntity.getPrimaryKeys()) {
        String dbAttrName = dbAttr.getName();
        if (!snapshot.containsKey(dbAttrName)) {
            fetchKey = true;
            break;
        }
    }
    if (!fetchKey) {
        return Collections.singletonList(snapshot);
    }
    // ok, the key is not included in snapshot, must do the fetch...
    // TODO: this should be optimized in the future, but now
    // DeleteBatchQuery
    // expects a PK snapshot, so we must provide it.
    QuotingStrategy quoter = node.getAdapter().getQuotingStrategy();
    StringBuilder sql = new StringBuilder("SELECT ");
    Collection<DbAttribute> pk = joinEntity.getPrimaryKeys();
    final List<DbAttribute> pkList = pk instanceof List ? (List<DbAttribute>) pk : new ArrayList<>(pk);
    for (int i = 0; i < pkList.size(); i++) {
        if (i > 0) {
            sql.append(", ");
        }
        DbAttribute attribute = pkList.get(i);
        sql.append("#result('");
        sql.append(quoter.quotedName(attribute));
        // since the name of the column can potentially be quoted and
        // use reserved keywords as name, let's specify generated column
        // name parameters to ensure the query doesn't explode
        sql.append("' '").append(TypesMapping.getJavaBySqlType(attribute.getType()));
        sql.append("' '").append("pk").append(i);
        sql.append("')");
    }
    sql.append(" FROM ").append(quoter.quotedFullyQualifiedName(joinEntity)).append(" WHERE ");
    int i = snapshot.size();
    for (Object key : snapshot.keySet()) {
        sql.append(quoter.quotedIdentifier(joinEntity, String.valueOf(key))).append(" #bindEqual($").append(key).append(")");
        if (--i > 0) {
            sql.append(" AND ");
        }
    }
    SQLTemplate query = new SQLTemplate(joinEntity.getDataMap(), sql.toString(), true);
    query.setParams(snapshot);
    final List[] result = new List[1];
    node.performQueries(Collections.singleton((Query) query), new DefaultOperationObserver() {

        @Override
        public void nextRows(Query query, List<?> dataRows) {
            if (!dataRows.isEmpty()) {
                // decode results...
                List<DataRow> fixedRows = new ArrayList<>(dataRows.size());
                for (Object o : dataRows) {
                    DataRow row = (DataRow) o;
                    DataRow fixedRow = new DataRow(2);
                    for (int i = 0; i < pkList.size(); i++) {
                        DbAttribute attribute = pkList.get(i);
                        fixedRow.put(attribute.getName(), row.get("pk" + i));
                    }
                    fixedRows.add(fixedRow);
                }
                dataRows = fixedRows;
            }
            result[0] = dataRows;
        }

        @Override
        public void nextQueryException(Query query, Exception ex) {
            throw new CayenneRuntimeException("Raising from query exception.", Util.unwindException(ex));
        }

        @Override
        public void nextGlobalException(Exception ex) {
            throw new CayenneRuntimeException("Raising from underlyingQueryEngine exception.", Util.unwindException(ex));
        }
    });
    return result[0];
}
Also used : SQLTemplate(org.apache.cayenne.query.SQLTemplate) Query(org.apache.cayenne.query.Query) DbAttribute(org.apache.cayenne.map.DbAttribute) CayenneRuntimeException(org.apache.cayenne.CayenneRuntimeException) QuotingStrategy(org.apache.cayenne.dba.QuotingStrategy) DataRow(org.apache.cayenne.DataRow) CayenneRuntimeException(org.apache.cayenne.CayenneRuntimeException) DefaultOperationObserver(org.apache.cayenne.access.util.DefaultOperationObserver) DbEntity(org.apache.cayenne.map.DbEntity) ArrayList(java.util.ArrayList) List(java.util.List)

Example 23 with QuotingStrategy

use of org.apache.cayenne.dba.QuotingStrategy in project cayenne by apache.

the class DefaultSelectTranslator method doTranslate.

@Override
protected void doTranslate() {
    checkLimitAndJointPrefetch();
    DataMap dataMap = queryMetadata.getDataMap();
    JoinStack joins = getJoinStack();
    QuotingStrategy strategy = getAdapter().getQuotingStrategy();
    forcingDistinct = false;
    // build column list
    this.resultColumns = buildResultColumns();
    // build qualifier
    QualifierTranslator qualifierTranslator = adapter.getQualifierTranslator(this);
    StringBuilder whereQualifierBuffer = qualifierTranslator.appendPart(new StringBuilder());
    // build having qualifier
    Expression havingQualifier = getSelectQuery().getHavingQualifier();
    StringBuilder havingQualifierBuffer = null;
    if (havingQualifier != null) {
        haveAggregate = true;
        QualifierTranslator havingQualifierTranslator = adapter.getQualifierTranslator(this);
        havingQualifierTranslator.setQualifier(havingQualifier);
        havingQualifierBuffer = havingQualifierTranslator.appendPart(new StringBuilder());
    }
    if (!haveAggregate && groupByColumns != null) {
        // if no expression with aggregation function found
        // in select columns and there is no having clause
        groupByColumns.clear();
    }
    // build ORDER BY
    OrderingTranslator orderingTranslator = new OrderingTranslator(this);
    StringBuilder orderingBuffer = orderingTranslator.appendPart(new StringBuilder());
    // assemble
    StringBuilder queryBuf = new StringBuilder();
    queryBuf.append("SELECT ");
    // side effect: "suppressingDistinct" flag may end up being flipped here
    if (forcingDistinct || getSelectQuery().isDistinct()) {
        suppressingDistinct = queryMetadata.isSuppressingDistinct();
        if (!suppressingDistinct) {
            for (ColumnDescriptor column : resultColumns) {
                if (isUnsupportedForDistinct(column.getJdbcType())) {
                    suppressingDistinct = true;
                    break;
                }
            }
        }
        if (!suppressingDistinct) {
            queryBuf.append(buildDistinctStatement()).append(" ");
        }
    }
    // convert ColumnDescriptors to column names
    List<String> selectColumnExpList = new ArrayList<>();
    for (ColumnDescriptor column : resultColumns) {
        String fullName;
        if (column.isExpression()) {
            fullName = column.getName();
        } else {
            fullName = strategy.quotedIdentifier(dataMap, column.getNamePrefix(), column.getName());
        }
        selectColumnExpList.add(fullName);
    }
    // uses the DISTINCT modifier
    if (forcingDistinct || getSelectQuery().isDistinct()) {
        List<String> orderByColumnList = orderingTranslator.getOrderByColumnList();
        for (String orderByColumnExp : orderByColumnList) {
            // Convert to ColumnDescriptors??
            if (!selectColumnExpList.contains(orderByColumnExp)) {
                selectColumnExpList.add(orderByColumnExp);
            }
        }
    }
    appendSelectColumns(queryBuf, selectColumnExpList);
    // append from clause
    queryBuf.append(" FROM ");
    // append tables and joins
    joins.appendRootWithQuoteSqlIdentifiers(queryBuf, getQueryMetadata().getDbEntity());
    joins.appendJoins(queryBuf);
    joins.appendQualifier(whereQualifierBuffer, whereQualifierBuffer.length() == 0);
    // append qualifier
    if (whereQualifierBuffer.length() > 0) {
        queryBuf.append(" WHERE ");
        queryBuf.append(whereQualifierBuffer);
    }
    if (groupByColumns != null && !groupByColumns.isEmpty()) {
        queryBuf.append(" GROUP BY ");
        appendGroupByColumns(queryBuf, groupByColumns);
    }
    // append HAVING qualifier
    if (havingQualifierBuffer != null && havingQualifierBuffer.length() > 0) {
        queryBuf.append(" HAVING ");
        queryBuf.append(havingQualifierBuffer);
    }
    // append prebuilt ordering
    if (orderingBuffer.length() > 0) {
        queryBuf.append(" ORDER BY ").append(orderingBuffer);
    }
    if (!isSuppressingDistinct()) {
        appendLimitAndOffsetClauses(queryBuf);
    }
    this.sql = queryBuf.toString();
}
Also used : Expression(org.apache.cayenne.exp.Expression) ColumnDescriptor(org.apache.cayenne.access.jdbc.ColumnDescriptor) ArrayList(java.util.ArrayList) QuotingStrategy(org.apache.cayenne.dba.QuotingStrategy) DataMap(org.apache.cayenne.map.DataMap)

Example 24 with QuotingStrategy

use of org.apache.cayenne.dba.QuotingStrategy in project cayenne by apache.

the class FirebirdMergerTokenFactory method createSetAllowNullToDb.

@Override
public MergerToken createSetAllowNullToDb(DbEntity entity, DbAttribute column) {
    return new SetAllowNullToDb(entity, column) {

        public List<String> createSql(DbAdapter adapter) {
            QuotingStrategy context = adapter.getQuotingStrategy();
            String entityName = context.quotedFullyQualifiedName(getEntity());
            String columnName = context.quotedName(getColumn());
            // but this might be achived by modyfication system tables
            return Collections.singletonList(String.format("UPDATE RDB$RELATION_FIELDS SET RDB$NULL_FLAG = NULL " + " WHERE RDB$FIELD_NAME = '%s' AND RDB$RELATION_NAME = '%s'", columnName, entityName));
        }
    };
}
Also used : DbAdapter(org.apache.cayenne.dba.DbAdapter) SetAllowNullToDb(org.apache.cayenne.dbsync.merge.token.db.SetAllowNullToDb) QuotingStrategy(org.apache.cayenne.dba.QuotingStrategy)

Example 25 with QuotingStrategy

use of org.apache.cayenne.dba.QuotingStrategy in project cayenne by apache.

the class IngresMergerTokenFactory method createSetNotNullToDb.

@Override
public MergerToken createSetNotNullToDb(DbEntity entity, DbAttribute column) {
    return new SetNotNullToDb(entity, column) {

        @Override
        public List<String> createSql(DbAdapter adapter) {
            /*
                 * TODO: we generate this query as in ingres db documentation,
                 * but unfortunately ingres don't support it
                 */
            StringBuilder sqlBuffer = new StringBuilder();
            QuotingStrategy context = adapter.getQuotingStrategy();
            sqlBuffer.append("ALTER TABLE ");
            sqlBuffer.append(getEntity().getFullyQualifiedName());
            sqlBuffer.append(" ALTER COLUMN ");
            sqlBuffer.append(context.quotedName(getColumn()));
            sqlBuffer.append(" ");
            sqlBuffer.append(adapter.externalTypesForJdbcType(getColumn().getType())[0]);
            if (adapter.typeSupportsLength(getColumn().getType()) && getColumn().getMaxLength() > 0) {
                sqlBuffer.append("(");
                sqlBuffer.append(getColumn().getMaxLength());
                sqlBuffer.append(")");
            }
            sqlBuffer.append(" NOT NULL");
            return Collections.singletonList(sqlBuffer.toString());
        }
    };
}
Also used : DbAdapter(org.apache.cayenne.dba.DbAdapter) SetNotNullToDb(org.apache.cayenne.dbsync.merge.token.db.SetNotNullToDb) QuotingStrategy(org.apache.cayenne.dba.QuotingStrategy)

Aggregations

QuotingStrategy (org.apache.cayenne.dba.QuotingStrategy)42 DbAdapter (org.apache.cayenne.dba.DbAdapter)11 DbAttribute (org.apache.cayenne.map.DbAttribute)11 DbEntity (org.apache.cayenne.map.DbEntity)5 DbJoin (org.apache.cayenne.map.DbJoin)5 DbRelationship (org.apache.cayenne.map.DbRelationship)5 CayenneRuntimeException (org.apache.cayenne.CayenneRuntimeException)4 SetAllowNullToDb (org.apache.cayenne.dbsync.merge.token.db.SetAllowNullToDb)3 SetNotNullToDb (org.apache.cayenne.dbsync.merge.token.db.SetNotNullToDb)3 EJBQLException (org.apache.cayenne.ejbql.EJBQLException)3 ArrayList (java.util.ArrayList)2 Collection (java.util.Collection)2 HashMap (java.util.HashMap)2 List (java.util.List)2 DropColumnToDb (org.apache.cayenne.dbsync.merge.token.db.DropColumnToDb)2 EJBQLPath (org.apache.cayenne.ejbql.parser.EJBQLPath)2 DataMap (org.apache.cayenne.map.DataMap)2 ObjRelationship (org.apache.cayenne.map.ObjRelationship)2 UpdateBatchQuery (org.apache.cayenne.query.UpdateBatchQuery)2 ClassDescriptor (org.apache.cayenne.reflect.ClassDescriptor)2