Search in sources :

Example 6 with DbAttribute

use of org.apache.cayenne.map.DbAttribute in project cayenne by apache.

the class DataDomainFlattenedBucket method addFlattenedDelete.

void addFlattenedDelete(DbEntity flattenedEntity, FlattenedArcKey flattenedDeleteInfo) {
    DeleteBatchQuery relationDeleteQuery = flattenedDeleteQueries.get(flattenedEntity);
    if (relationDeleteQuery == null) {
        Collection<DbAttribute> pk = flattenedEntity.getPrimaryKeys();
        List<DbAttribute> pkList = pk instanceof List ? (List<DbAttribute>) pk : new ArrayList<>(pk);
        relationDeleteQuery = new DeleteBatchQuery(flattenedEntity, pkList, Collections.<String>emptySet(), 50);
        relationDeleteQuery.setUsingOptimisticLocking(false);
        flattenedDeleteQueries.put(flattenedEntity, relationDeleteQuery);
    }
    DataNode node = parent.getDomain().lookupDataNode(flattenedEntity.getDataMap());
    List<Map<String, Object>> flattenedSnapshots = flattenedDeleteInfo.buildJoinSnapshotsForDelete(node);
    if (!flattenedSnapshots.isEmpty()) {
        for (Map<String, Object> flattenedSnapshot : flattenedSnapshots) {
            relationDeleteQuery.add(flattenedSnapshot);
        }
    }
}
Also used : DeleteBatchQuery(org.apache.cayenne.query.DeleteBatchQuery) DbAttribute(org.apache.cayenne.map.DbAttribute) ArrayList(java.util.ArrayList) List(java.util.List) HashMap(java.util.HashMap) Map(java.util.Map)

Example 7 with DbAttribute

use of org.apache.cayenne.map.DbAttribute in project cayenne by apache.

the class DataDomainUpdateBucket method appendQueriesInternal.

@Override
void appendQueriesInternal(Collection<Query> queries) {
    DataDomainDBDiffBuilder diffBuilder = new DataDomainDBDiffBuilder();
    DataNodeSyncQualifierDescriptor qualifierBuilder = new DataNodeSyncQualifierDescriptor();
    for (DbEntity dbEntity : dbEntities) {
        Collection<DbEntityClassDescriptor> descriptors = descriptorsByDbEntity.get(dbEntity);
        Map<Object, Query> batches = new LinkedHashMap<>();
        for (DbEntityClassDescriptor descriptor : descriptors) {
            ObjEntity entity = descriptor.getEntity();
            diffBuilder.reset(descriptor);
            qualifierBuilder.reset(descriptor);
            boolean isRootDbEntity = entity.getDbEntity() == dbEntity;
            for (Persistent o : objectsByDescriptor.get(descriptor.getClassDescriptor())) {
                ObjectDiff diff = parent.objectDiff(o.getObjectId());
                Map<String, Object> snapshot = diffBuilder.buildDBDiff(diff);
                // check whether MODIFIED object has real db-level modifications
                if (snapshot == null) {
                    continue;
                }
                // after we filtered out "fake" modifications, check if an
                // attempt is made to modify a read only entity
                checkReadOnly(entity);
                Map<String, Object> qualifierSnapshot = qualifierBuilder.createQualifierSnapshot(diff);
                // organize batches by the updated columns + nulls in qualifier
                Set<String> snapshotSet = snapshot.keySet();
                Set<String> nullQualifierNames = new HashSet<>();
                for (Map.Entry<String, Object> entry : qualifierSnapshot.entrySet()) {
                    if (entry.getValue() == null) {
                        nullQualifierNames.add(entry.getKey());
                    }
                }
                List<Set<String>> batchKey = Arrays.asList(snapshotSet, nullQualifierNames);
                UpdateBatchQuery batch = (UpdateBatchQuery) batches.get(batchKey);
                if (batch == null) {
                    batch = new UpdateBatchQuery(dbEntity, qualifierBuilder.getAttributes(), updatedAttributes(dbEntity, snapshot), nullQualifierNames, 10);
                    batch.setUsingOptimisticLocking(qualifierBuilder.isUsingOptimisticLocking());
                    batches.put(batchKey, batch);
                }
                batch.add(qualifierSnapshot, snapshot, o.getObjectId());
                // update replacement id with meaningful PK changes
                if (isRootDbEntity) {
                    Map<String, Object> replacementId = o.getObjectId().getReplacementIdMap();
                    for (DbAttribute pk : dbEntity.getPrimaryKeys()) {
                        String name = pk.getName();
                        if (snapshot.containsKey(name) && !replacementId.containsKey(name)) {
                            replacementId.put(name, snapshot.get(name));
                        }
                    }
                }
            }
        }
        queries.addAll(batches.values());
    }
}
Also used : Set(java.util.Set) HashSet(java.util.HashSet) Query(org.apache.cayenne.query.Query) UpdateBatchQuery(org.apache.cayenne.query.UpdateBatchQuery) DbAttribute(org.apache.cayenne.map.DbAttribute) Persistent(org.apache.cayenne.Persistent) LinkedHashMap(java.util.LinkedHashMap) ObjEntity(org.apache.cayenne.map.ObjEntity) DbEntity(org.apache.cayenne.map.DbEntity) UpdateBatchQuery(org.apache.cayenne.query.UpdateBatchQuery) LinkedHashMap(java.util.LinkedHashMap) Map(java.util.Map) HashSet(java.util.HashSet)

Example 8 with DbAttribute

use of org.apache.cayenne.map.DbAttribute in project cayenne by apache.

the class DataNodeSyncQualifierDescriptor method createQualifierSnapshot.

Map<String, Object> createQualifierSnapshot(ObjectDiff diff) {
    int len = attributes.size();
    Map<String, Object> map = new HashMap<>(len * 2);
    for (int i = 0; i < len; i++) {
        DbAttribute attribute = attributes.get(i);
        if (!map.containsKey(attribute.getName())) {
            Object value = valueTransformers.get(i).apply(diff);
            map.put(attribute.getName(), value);
        }
    }
    return map;
}
Also used : HashMap(java.util.HashMap) DbAttribute(org.apache.cayenne.map.DbAttribute)

Example 9 with DbAttribute

use of org.apache.cayenne.map.DbAttribute in project cayenne by apache.

the class DataNodeSyncQualifierDescriptor method reset.

void reset(DbEntityClassDescriptor descriptor) {
    attributes = new ArrayList<>(3);
    valueTransformers = new ArrayList<>(3);
    usingOptimisticLocking = descriptor.getEntity().getLockType() == ObjEntity.LOCK_TYPE_OPTIMISTIC;
    // master PK columns
    if (descriptor.isMaster()) {
        for (final DbAttribute attribute : descriptor.getDbEntity().getPrimaryKeys()) {
            attributes.add(attribute);
            valueTransformers.add(input -> {
                ObjectId id = (ObjectId) input.getNodeId();
                return id.getIdSnapshot().get(attribute.getName());
            });
        }
    } else {
        // TODO: andrus 12/23/2007 - only one step relationship is supported...
        if (descriptor.getPathFromMaster().size() != 1) {
            throw new CayenneRuntimeException("Only single step dependent relationships are currently supported. Actual path length: %d", descriptor.getPathFromMaster().size());
        }
        DbRelationship masterDependentDbRel = descriptor.getPathFromMaster().get(0);
        if (masterDependentDbRel != null) {
            for (final DbJoin dbAttrPair : masterDependentDbRel.getJoins()) {
                DbAttribute dbAttribute = dbAttrPair.getTarget();
                if (!attributes.contains(dbAttribute)) {
                    attributes.add(dbAttribute);
                    valueTransformers.add(input -> {
                        ObjectId id = (ObjectId) input.getNodeId();
                        return id.getIdSnapshot().get(dbAttrPair.getSourceName());
                    });
                }
            }
        }
    }
    if (usingOptimisticLocking) {
        for (final ObjAttribute attribute : descriptor.getEntity().getAttributes()) {
            if (attribute.isUsedForLocking()) {
                // only care about first step in a flattened attribute
                DbAttribute dbAttribute = (DbAttribute) attribute.getDbPathIterator().next();
                // only use qualifier if dbEntities match
                if (dbAttribute.getEntity().equals(descriptor.getDbEntity()) && !attributes.contains(dbAttribute)) {
                    attributes.add(dbAttribute);
                    valueTransformers.add(input -> input.getSnapshotValue(attribute.getName()));
                }
            }
        }
        for (final ObjRelationship relationship : descriptor.getEntity().getRelationships()) {
            if (relationship.isUsedForLocking()) {
                // only care about the first DbRelationship
                DbRelationship dbRelationship = relationship.getDbRelationships().get(0);
                for (final DbJoin dbAttrPair : dbRelationship.getJoins()) {
                    DbAttribute dbAttribute = dbAttrPair.getSource();
                    // relationship transformers override attribute transformers for meaningful FK's...
                    // why meaningful FKs can go out of sync is another story (CAY-595)
                    int index = attributes.indexOf(dbAttribute);
                    if (index >= 0 && !dbAttribute.isForeignKey()) {
                        continue;
                    }
                    Function<ObjectDiff, Object> transformer = input -> {
                        ObjectId targetId = input.getArcSnapshotValue(relationship.getName());
                        return targetId != null ? targetId.getIdSnapshot().get(dbAttrPair.getTargetName()) : null;
                    };
                    if (index < 0) {
                        attributes.add(dbAttribute);
                        valueTransformers.add(transformer);
                    } else {
                        valueTransformers.set(index, transformer);
                    }
                }
            }
        }
    }
}
Also used : ObjEntity(org.apache.cayenne.map.ObjEntity) ObjAttribute(org.apache.cayenne.map.ObjAttribute) HashMap(java.util.HashMap) Function(java.util.function.Function) DbAttribute(org.apache.cayenne.map.DbAttribute) ArrayList(java.util.ArrayList) List(java.util.List) ObjectId(org.apache.cayenne.ObjectId) DbJoin(org.apache.cayenne.map.DbJoin) ObjRelationship(org.apache.cayenne.map.ObjRelationship) Map(java.util.Map) CayenneRuntimeException(org.apache.cayenne.CayenneRuntimeException) DbRelationship(org.apache.cayenne.map.DbRelationship) ObjRelationship(org.apache.cayenne.map.ObjRelationship) ObjAttribute(org.apache.cayenne.map.ObjAttribute) ObjectId(org.apache.cayenne.ObjectId) DbAttribute(org.apache.cayenne.map.DbAttribute) CayenneRuntimeException(org.apache.cayenne.CayenneRuntimeException) DbRelationship(org.apache.cayenne.map.DbRelationship) DbJoin(org.apache.cayenne.map.DbJoin)

Example 10 with DbAttribute

use of org.apache.cayenne.map.DbAttribute in project cayenne by apache.

the class ObjectResolver method createObjectId.

ObjectId createObjectId(DataRow dataRow, ObjEntity objEntity, String namePrefix) {
    Collection<DbAttribute> pk = objEntity == this.descriptor.getEntity() ? this.primaryKey : objEntity.getDbEntity().getPrimaryKeys();
    boolean prefix = namePrefix != null && namePrefix.length() > 0;
    if (pk.size() == 1) {
        DbAttribute attribute = pk.iterator().next();
        String key = (prefix) ? namePrefix + attribute.getName() : attribute.getName();
        Object val = dataRow.get(key);
        // this is possible when processing left outer joint prefetches
        if (val == null) {
            if (!dataRow.containsKey(key)) {
                throw new CayenneRuntimeException("No PK column '%s' found in data row.", key);
            }
            return null;
        }
        // PUT without a prefix
        return new ObjectId(objEntity.getName(), attribute.getName(), val);
    }
    // ... handle generic case - PK.size > 1
    Map<String, Object> idMap = new HashMap<>(pk.size() * 2);
    for (final DbAttribute attribute : pk) {
        String key = (prefix) ? namePrefix + attribute.getName() : attribute.getName();
        Object val = dataRow.get(key);
        // this is possible when processing left outer joint prefetches
        if (val == null) {
            if (!dataRow.containsKey(key)) {
                throw new CayenneRuntimeException("No PK column '%s' found in data row.", key);
            }
            return null;
        }
        // PUT without a prefix
        idMap.put(attribute.getName(), val);
    }
    return new ObjectId(objEntity.getName(), idMap);
}
Also used : ObjectId(org.apache.cayenne.ObjectId) HashMap(java.util.HashMap) DbAttribute(org.apache.cayenne.map.DbAttribute) CayenneRuntimeException(org.apache.cayenne.CayenneRuntimeException) DataObject(org.apache.cayenne.DataObject)

Aggregations

DbAttribute (org.apache.cayenne.map.DbAttribute)194 DbEntity (org.apache.cayenne.map.DbEntity)109 Test (org.junit.Test)67 ObjEntity (org.apache.cayenne.map.ObjEntity)36 DbRelationship (org.apache.cayenne.map.DbRelationship)35 ObjAttribute (org.apache.cayenne.map.ObjAttribute)32 CayenneRuntimeException (org.apache.cayenne.CayenneRuntimeException)21 DbJoin (org.apache.cayenne.map.DbJoin)18 HashMap (java.util.HashMap)16 ObjRelationship (org.apache.cayenne.map.ObjRelationship)16 ArrayList (java.util.ArrayList)14 DbAttributeBinding (org.apache.cayenne.access.translator.DbAttributeBinding)12 DataMap (org.apache.cayenne.map.DataMap)11 JdbcAdapter (org.apache.cayenne.dba.JdbcAdapter)10 QuotingStrategy (org.apache.cayenne.dba.QuotingStrategy)10 MergerToken (org.apache.cayenne.dbsync.merge.token.MergerToken)10 DeleteBatchQuery (org.apache.cayenne.query.DeleteBatchQuery)10 ClassDescriptor (org.apache.cayenne.reflect.ClassDescriptor)10 ObjectId (org.apache.cayenne.ObjectId)9 Expression (org.apache.cayenne.exp.Expression)8