void MappingLevel::attemptMapping(IDefRecordElement const * diskRecord, unsigned diskFieldNum, bool diskFieldKeyed, IDefRecordElement const * activityRecord, unsigned activityFieldNum, bool activityFieldKeyed) { IDefRecordElement const * diskField = diskRecord->queryChild(diskFieldNum); IDefRecordElement const * activityField = activityRecord->queryChild(activityFieldNum); IDefRecordElement const * diskChild = NULL; IDefRecordElement const * diskBlob = NULL; queryCheckFieldChild(diskField, "Disk", diskChild, diskBlob); IDefRecordElement const * activityChild = NULL; IDefRecordElement const * activityBlob = NULL; queryCheckFieldChild(activityField, "Activity", activityChild, activityBlob); if(diskBlob) { if(!activityBlob) throw makeFailure(IRecordLayoutTranslator::Failure::UntranslatableField)->append("Field ")->appendFieldName(topLevel ? NULL : scope.str(), activityRecord->queryChild(activityFieldNum))->append(" is blob on disk but not in activity"); if(!isSameBasicType(diskBlob->queryType(), activityBlob->queryType())) throw makeFailure(IRecordLayoutTranslator::Failure::UntranslatableField)->append("Blob field ")->appendFieldName(topLevel ? NULL : scope.str(), activityRecord->queryChild(activityFieldNum))->append(" has differing referenced types on disk and in activity"); } else { if(activityBlob) throw makeFailure(IRecordLayoutTranslator::Failure::UntranslatableField)->append("Field ")->appendFieldName(topLevel ? NULL : scope.str(), activityRecord->queryChild(activityFieldNum))->append(" is blob in activity but not on disk"); } if(diskChild) { if(!activityChild) throw makeFailure(IRecordLayoutTranslator::Failure::UntranslatableField)->append("Field ")->appendFieldName(topLevel ? NULL : scope.str(), activityRecord->queryChild(activityFieldNum))->append(" is child dataset on disk but not in activity"); if(activityFieldKeyed) throw makeFailure(IRecordLayoutTranslator::Failure::BadStructure)->append("Activity record metadata had unexpected structure (keyed field ")->appendFieldName(topLevel ? NULL : scope.str(), activityRecord->queryChild(activityFieldNum))->append(" is child dataset)"); if(*activityChild == *diskChild) { mappings.append(*new FieldMapping(FieldMapping::Simple, diskRecord, diskFieldNum, false, activityRecord, activityFieldNum, false)); } else { Owned<FieldMapping> mapping(new FieldMapping(FieldMapping::ChildDataset, diskRecord, diskFieldNum, false, activityRecord, activityFieldNum, false)); MappingLevel childMappingLevel(this, diskField->queryName()->str(), mapping->queryChildMappings()); childMappingLevel.calculateMappings(diskChild, 0, activityChild, 0); mappings.append(*mapping.getClear()); } } else { if(activityChild) throw makeFailure(IRecordLayoutTranslator::Failure::UntranslatableField)->append("Field ")->appendFieldName(topLevel ? NULL : scope.str(), activityRecord->queryChild(activityFieldNum))->append(" is child dataset in activity but not on disk"); if(!isSameBasicType(diskField->queryType(), activityField->queryType())) throw makeFailure(IRecordLayoutTranslator::Failure::UntranslatableField)->append("Field ")->appendFieldName(topLevel ? NULL : scope.str(), activityRecord->queryChild(activityFieldNum))->append(" has differing types on disk and in activity"); mappings.append(*new FieldMapping(FieldMapping::Simple, diskRecord, diskFieldNum, diskFieldKeyed, activityRecord, activityFieldNum, activityFieldKeyed)); } }
bool CDefRecordElement::operator==(IDefRecordElement const & other) const { if((kind != other.getKind()) || (name != other.queryName()) || (maxSize != other.getMaxSize()) || (queryCompareValue() != other.queryCompareValue()) || (children.ordinality() != other.numChildren())) return false; if(type) { if((!other.queryType()) || !isSameBasicType(type, other.queryType())) return false; } else { if(other.queryType()) return false; } ForEachItemIn(idx, children) if(!(children.item(idx) == *other.queryChild(idx))) return false; return true; }