public void UpdateNode(CswNbtNode Node, bool ForceUpdate) { // BZ 10240 if ((Node.PendingUpdate || ForceUpdate) && Node.getObjectClass().ObjectClass == CswEnumNbtObjectClass.EquipmentClass) { ((CswNbtObjClassEquipment)Node).SyncEquipmentToAssembly(); } // Case 30126 if (null != Node.getObjectClass().getPropertySet()) { if ((Node.PendingUpdate || ForceUpdate) && Node.getObjectClass().getPropertySet().Name == CswEnumNbtPropertySetName.MaterialSet) { ((CswNbtPropertySetMaterial)Node).onUpdatePropertyValue(); } } // Update all out of date values for a given node foreach (CswNbtNodePropWrapper PropWrapper in Node.Properties) { if (PropWrapper.PendingUpdate || Node.PendingUpdate || ForceUpdate) { switch (PropWrapper.getFieldTypeValue()) { case CswEnumNbtFieldType.Composite: CswNbtNodePropComposite CompositeProp = PropWrapper.AsComposite; CompositeProp.RecalculateCompositeValue(); break; case CswEnumNbtFieldType.Location: CswNbtNodePropLocation LocationProp = PropWrapper.AsLocation; LocationProp.RefreshNodeName(); break; case CswEnumNbtFieldType.LogicalSet: CswNbtNodePropLogicalSet LogicalSetProp = PropWrapper.AsLogicalSet; LogicalSetProp.RefreshStringValue(SetPendingUpdate: false); break; case CswEnumNbtFieldType.NodeTypeSelect: CswNbtNodePropNodeTypeSelect NodeTypeSelectProp = PropWrapper.AsNodeTypeSelect; NodeTypeSelectProp.RefreshSelectedNodeTypeNames(); break; case CswEnumNbtFieldType.PropertyReference: CswNbtNodePropPropertyReference PropertyReferenceProp = PropWrapper.AsPropertyReference; PropertyReferenceProp.RecalculateReferenceValue(); break; case CswEnumNbtFieldType.Quantity: CswNbtNodePropQuantity QuantityProp = PropWrapper.AsQuantity; QuantityProp.RefreshNodeName(); break; case CswEnumNbtFieldType.Relationship: CswNbtNodePropRelationship RelationshipProp = PropWrapper.AsRelationship; RelationshipProp.RefreshNodeName(); break; case CswEnumNbtFieldType.ViewPickList: CswNbtNodePropViewPickList ViewPickListProp = PropWrapper.AsViewPickList; ViewPickListProp.RefreshViewName(); break; case CswEnumNbtFieldType.ViewReference: CswNbtNodePropViewReference ViewReferenceProp = PropWrapper.AsViewReference; ViewReferenceProp.RefreshViewName(); break; case CswEnumNbtFieldType.MTBF: CswNbtNodePropMTBF MTBFProp = PropWrapper.AsMTBF; MTBFProp.RefreshCachedValue(); break; default: if (PropWrapper.PendingUpdate) { PropWrapper.setPendingUpdate(false); } break; } // switch (PropWrapper.FieldType.FieldType) } // if(PropWrapper.PendingUpdate) } // foreach (CswNbtNodePropWrapper PropWrapper in Node.Properties) if (Node.PendingUpdate) { Node.PendingUpdate = false; } } // UpdateNode()
public override void beforeWriteNode(bool IsCopy, bool OverrideUniqueValidation) { List <CswNbtNodePropWrapper> CompoundUniqueProps = new List <CswNbtNodePropWrapper>(); foreach (CswNbtNodePropWrapper CurrentProp in _CswNbtNode.Properties) { if (CurrentProp.WasModified) { // When a property changes, we need to: // 1. recalculate composite property values which include changed properties on this node foreach (CswNbtNodePropWrapper CompositeProp in _CswNbtNode.Properties[(CswEnumNbtFieldType)CswEnumNbtFieldType.Composite]) { if ( CompositeProp.AsComposite.TemplateValue.Contains( CswNbtMetaData.MakeTemplateEntry(CurrentProp.NodeTypePropId.ToString()))) { CompositeProp.AsComposite.RecalculateCompositeValue(); } } // 2. recalculate property references attached to relationships whose values changed if (CurrentProp.getFieldTypeValue() == CswEnumNbtFieldType.Relationship) { foreach (CswNbtNodePropWrapper PropRefPropWrapper in _CswNbtNode.Properties[(CswEnumNbtFieldType)CswEnumNbtFieldType.PropertyReference]) { CswNbtNodePropPropertyReference PropRefProp = PropRefPropWrapper.AsPropertyReference; if ((PropRefProp.RelationshipType == CswEnumNbtViewPropIdType.NodeTypePropId && PropRefProp.RelationshipId == CurrentProp.NodeTypePropId) || (PropRefProp.RelationshipType == CswEnumNbtViewPropIdType.ObjectClassPropId && PropRefProp.RelationshipId == CurrentProp.ObjectClassPropId)) { PropRefProp.RecalculateReferenceValue(); } } } // 3. mark any property references to this property on other nodes as pending update if (CswTools.IsPrimaryKey(CurrentProp.NodeId)) { //BZ 10239 - Fetch the cached value field name. CswNbtFieldTypeRulePropertyReference PropRefFTR = (CswNbtFieldTypeRulePropertyReference)_CswNbtResources.MetaData.getFieldTypeRule(CswEnumNbtFieldType.PropertyReference); CswEnumNbtPropColumn PropRefColumn = PropRefFTR.CachedValueSubField.Column; string SQL = @"update jct_nodes_props set pendingupdate = '" + CswConvert.ToDbVal(true) + @"', " + PropRefColumn.ToString() + @" = '' where jctnodepropid in (select j.jctnodepropid from jct_nodes_props j join nodes n on n.nodeid = j.nodeid join nodetype_props p on p.nodetypepropid = j.nodetypepropid join field_types f on p.fieldtypeid = f.fieldtypeid left outer join jct_nodes_props jntp on (jntp.nodetypepropid = p.fkvalue and jntp.nodeid = n.nodeid and jntp.field1_fk = " + CurrentProp.NodeId.PrimaryKey.ToString() + @") left outer join (select jx.jctnodepropid, ox.objectclasspropid, jx.nodeid from jct_nodes_props jx join nodetype_props px on jx.nodetypepropid = px.nodetypepropid join object_class_props ox on px.objectclasspropid = ox.objectclasspropid where jx.field1_fk = " + CurrentProp.NodeId.PrimaryKey.ToString() + @") jocp on (jocp.objectclasspropid = p.fkvalue and jocp.nodeid = n.nodeid) where f.fieldtype = 'PropertyReference' and ((lower(p.fktype) = 'nodetypepropid' and jntp.jctnodepropid is not null) or (lower(p.fktype) = 'objectclasspropid' and jocp.jctnodepropid is not null)) and ((lower(p.valueproptype) = 'nodetypepropid' and p.valuepropid = " + CurrentProp.NodeTypePropId.ToString() + @") or (lower(p.valueproptype) = 'objectclasspropid' and p.valuepropid = " + CurrentProp.ObjectClassPropId + @")))"; // We're not doing this in a CswTableUpdate because it might be a large operation, // and we don't care about auditing for this change. _CswNbtResources.execArbitraryPlatformNeutralSql(SQL); } // 4. For locations, if this node's location changed, we need to update the pathname on the children if (CurrentProp.getFieldTypeValue() == CswEnumNbtFieldType.Location && CswTools.IsPrimaryKey(_CswNbtNode.NodeId)) { _CswNbtResources.CswNbtNodeFactory.CswNbtNodeWriter.updateRelationsToThisNode(_CswNbtNode); } // 5. Prepare for compound unique validation if (CswConvert.ToBoolean(CurrentProp[CswEnumNbtPropertyAttributeName.CompoundUnique])) { CompoundUniqueProps.Add(CurrentProp); } } // if(CurrentProp.WasModified) } // foreach (CswNbtNodePropWrapper CurrentProp in _CswNbtNode.Properties) if (CompoundUniqueProps.Count > 0 && NodeId != null) { if (false == IsCopy && false == OverrideUniqueValidation) { //check for other compound unique props that were _not_ modified foreach (CswNbtNodePropWrapper CurrentProp in _CswNbtNode.Properties) { if (CswConvert.ToBoolean(CurrentProp[CswEnumNbtPropertyAttributeName.CompoundUnique]) && (false == CompoundUniqueProps.Contains(CurrentProp))) { CompoundUniqueProps.Add(CurrentProp); } } CswNbtView CswNbtView = this.NodeType.CreateDefaultView(); CswNbtView.ViewName = "For compound unique"; CswNbtViewRelationship ViewRelationship = CswNbtView.Root.ChildRelationships[0]; if (CswTools.IsPrimaryKey(NodeId)) { ViewRelationship.NodeIdsToFilterOut.Add(NodeId); } foreach (CswNbtNodePropWrapper CurrentCompoundUniqueProp in CompoundUniqueProps) { //case 27670 - in order to reserve the right for compound unique props to be empty, it has to be explicitly stated when creating the ForCompundUnique view CswNbtViewProperty CswNbtViewProperty = CswNbtView.AddViewProperty(ViewRelationship, CurrentCompoundUniqueProp.NodeTypeProp); ICswNbtFieldTypeRule ftRule = CurrentCompoundUniqueProp.NodeTypeProp.getFieldTypeRule(); ftRule.AddUniqueFilterToView(CswNbtView, CswNbtViewProperty, CurrentCompoundUniqueProp, true); } ICswNbtTree NodeTree = _CswNbtResources.Trees.getTreeFromView(_CswNbtResources.CurrentNbtUser, CswNbtView, true, false, false); if (NodeTree.getChildNodeCount() > 0) { NodeTree.goToNthChild(0); CswNbtNode DuplicateValueNode = NodeTree.getNodeForCurrentPosition(); CswCommaDelimitedString CompoundUniquePropNames = new CswCommaDelimitedString(); CswCommaDelimitedString CompoundUniquePropValues = new CswCommaDelimitedString(); foreach (CswNbtNodePropWrapper CurrentUniqueProp in CompoundUniqueProps) { CompoundUniquePropNames.Add(CurrentUniqueProp.PropName); CompoundUniquePropValues.Add(CurrentUniqueProp.Gestalt); } string ExotericMessage = "The following properties must have unique values: " + CompoundUniquePropNames.ToString(); string EsotericMessage = "The " + CompoundUniquePropNames.ToString() + " of node " + NodeId.ToString() + " are the same as for node " + DuplicateValueNode.NodeId.ToString() + ": " + CompoundUniquePropValues.ToString(); if (false == _CswNbtNode.IsTemp && false == DuplicateValueNode.IsTemp) //only throw an error if we're comparing two REAL nodes { throw (new CswDniException(CswEnumErrorType.Warning, ExotericMessage, EsotericMessage)); } }//we have a duplicate value situation } else { foreach (CswNbtNodePropWrapper CurrentPropWrapper in CompoundUniqueProps) { CurrentPropWrapper.ClearValue(); CurrentPropWrapper.clearModifiedFlag(); } } //if-else we're not a copy and not overridding } //if we have at leaste one modified compound unique prop //_synchNodeName(); // can't do this here, because we miss some of the onBeforeUpdateNodePropRow events // we do it in writer now instead } // beforeWriteNode()
} // beforeWriteNode() //Updates related composite, propertyreference, relationship, and location private void _updateExternalRelatedProps(CswNbtNodePropWrapper CurrentProp) { // When a property changes, we need to: // 1. recalculate composite property values which include changed properties on this node foreach (CswNbtNodePropWrapper CompositeProp in _CswNbtNode.Properties[(CswEnumNbtFieldType)CswEnumNbtFieldType.Composite]) { if (CompositeProp.AsComposite.TemplateValue.Contains(CswNbtMetaData.MakeTemplateEntry(CurrentProp.NodeTypePropId.ToString()))) { CompositeProp.AsComposite.RecalculateCompositeValue(); } } // 2. recalculate property references attached to relationships whose values changed if (CurrentProp.getFieldTypeValue() == CswEnumNbtFieldType.Relationship) { foreach (CswNbtNodePropWrapper PropRefPropWrapper in _CswNbtNode.Properties[(CswEnumNbtFieldType)CswEnumNbtFieldType.PropertyReference]) { CswNbtNodePropPropertyReference PropRefProp = PropRefPropWrapper.AsPropertyReference; if ((PropRefProp.RelationshipType == CswEnumNbtViewPropIdType.NodeTypePropId && PropRefProp.RelationshipId == CurrentProp.NodeTypePropId) || (PropRefProp.RelationshipType == CswEnumNbtViewPropIdType.ObjectClassPropId && PropRefProp.RelationshipId == CurrentProp.ObjectClassPropId)) { PropRefProp.RecalculateReferenceValue(); } } } // 3. mark any property references to this property on other nodes as pending update if (CswTools.IsPrimaryKey(CurrentProp.NodeId)) { //BZ 10239 - Fetch the cached value field name. CswNbtFieldTypeRulePropertyReference PropRefFTR = (CswNbtFieldTypeRulePropertyReference)_CswNbtResources.MetaData.getFieldTypeRule(CswEnumNbtFieldType.PropertyReference); CswEnumNbtPropColumn PropRefColumn = PropRefFTR.CachedValueSubField.Column; string SQL = @"update jct_nodes_props set pendingupdate = '" + CswConvert.ToDbVal(true) + @"', " + PropRefColumn.ToString() + @" = '' where jctnodepropid in (select j.jctnodepropid from jct_nodes_props j join nodes n on n.nodeid = j.nodeid join nodetype_props p on p.nodetypepropid = j.nodetypepropid join field_types f on p.fieldtypeid = f.fieldtypeid left outer join jct_nodes_props jntp on (jntp.nodetypepropid = p.fkvalue and jntp.nodeid = n.nodeid and jntp.field1_fk = " + CurrentProp.NodeId.PrimaryKey.ToString() + @") left outer join (select jx.jctnodepropid, ox.objectclasspropid, jx.nodeid from jct_nodes_props jx join nodetype_props px on jx.nodetypepropid = px.nodetypepropid join object_class_props ox on px.objectclasspropid = ox.objectclasspropid where jx.field1_fk = " + CurrentProp.NodeId.PrimaryKey.ToString() + @") jocp on (jocp.objectclasspropid = p.fkvalue and jocp.nodeid = n.nodeid) where f.fieldtype = 'PropertyReference' and ((lower(p.fktype) = 'nodetypepropid' and jntp.jctnodepropid is not null) or (lower(p.fktype) = 'objectclasspropid' and jocp.jctnodepropid is not null)) and ((lower(p.valueproptype) = 'nodetypepropid' and p.valuepropid = " + CurrentProp.NodeTypePropId.ToString() + @") or (lower(p.valueproptype) = 'objectclasspropid' and p.valuepropid = " + CurrentProp.ObjectClassPropId + @")))"; // We're not doing this in a CswTableUpdate because it might be a large operation, // and we don't care about auditing for this change. _CswNbtResources.execArbitraryPlatformNeutralSql(SQL); } // 4. For locations, if this node's location changed, we need to update the pathname on the children if (CurrentProp.getFieldTypeValue() == CswEnumNbtFieldType.Location && CswTools.IsPrimaryKey(_CswNbtNode.NodeId)) { _CswNbtNode.updateRelationsToThisNode(); } }