/// <summary> /// Get attribute assignments for new DBObjects. /// </summary> /// <param name="myAttributeAssigns">The interesting ParseTreeNode.</param> /// <param name="typeManager">The TypeManager of the GraphDB.</param> /// <returns>A Dictionary of AttributeAssignments</returns> private Exceptional<ManipulationAttributes> GetRecursiveAttributes(List<AAttributeAssignOrUpdate> myAttributeAssigns, DBContext myDBContext, GraphDBType myGraphDBType) { #region Data var manipulationAttributes = new ManipulationAttributes(); var resultExcept = new Exceptional<ManipulationAttributes>(); if (myAttributeAssigns == null) { return new Exceptional<ManipulationAttributes>(manipulationAttributes); } TypeAttribute attr; ADBBaseObject typedAttributeValue; BasicType correspondingCSharpType; Warning_UndefinedAttribute undefAttrWarning = null; var typeMandatoryAttribs = myGraphDBType.GetMandatoryAttributesUUIDs(myDBContext.DBTypeManager); var setExcept = myDBContext.DBSettingsManager.GetSetting(SettingUndefAttrBehaviour.UUID, myDBContext, TypesSettingScope.DB); if (!setExcept.Success()) { return new Exceptional<ManipulationAttributes>(setExcept); } var undefAttrBehave = (SettingUndefAttrBehaviour)setExcept.Value; #endregion #region get Data #region proceed list foreach (var aAttributeAssign in myAttributeAssigns) { var validateResult = aAttributeAssign.AttributeIDChain.Validate(myDBContext, true); if (validateResult.Failed()) { return new Exceptional<ManipulationAttributes>(validateResult); } #region Undefined attributes - Refactor and add undefined logic into defined attribute AssignsOrUpdate System.Diagnostics.Debug.Assert(aAttributeAssign.AttributeIDChain != null); //in this case we have an undefined attribute if (aAttributeAssign.AttributeIDChain.IsUndefinedAttribute) { var UndefAttrName = aAttributeAssign.AttributeIDChain.UndefinedAttribute; switch (undefAttrBehave.Behaviour) { case UndefAttributeBehaviour.disallow: return new Exceptional<ManipulationAttributes>(new Error_UndefinedAttributes()); case UndefAttributeBehaviour.warn: if (undefAttrWarning == null) { undefAttrWarning = new Warning_UndefinedAttribute(); } resultExcept.PushIWarning(undefAttrWarning); break; } if (aAttributeAssign is AttributeAssignOrUpdateList) { #region AttributeAssignCollection var colDefinition = (aAttributeAssign as AttributeAssignOrUpdateList).CollectionDefinition; EdgeTypeListOfBaseObjects valueList = new EdgeTypeListOfBaseObjects(); foreach (var tuple in colDefinition.TupleDefinition) { if (tuple.TypeOfValue == BasicType.Unknown) valueList.Add((tuple.Value as ValueDefinition).Value); else if (tuple.Value is ValueDefinition) valueList.Add((tuple.Value as ValueDefinition).Value); else return new Exceptional<ManipulationAttributes>(new Error_NotImplemented(new System.Diagnostics.StackTrace(true))); } if (colDefinition.CollectionType == CollectionType.Set) valueList.UnionWith(valueList); manipulationAttributes.UndefinedAttributes.Add(UndefAttrName, valueList); var undefAttr = new UndefinedAttributeDefinition() { AttributeName = UndefAttrName, AttributeValue = valueList }; var undefAttrAssign = new AttributeAssignOrUpdateUndefined((aAttributeAssign as AttributeAssignOrUpdateList).AttributeIDChain, undefAttr); manipulationAttributes.AttributeToUpdateOrAssign.Add(undefAttrAssign); #endregion } else if (aAttributeAssign is AttributeAssignOrUpdateValue) { #region AttributeAssignValue var value = GraphDBTypeMapper.GetBaseObjectFromCSharpType((aAttributeAssign as AttributeAssignOrUpdateValue).Value); manipulationAttributes.UndefinedAttributes.Add(UndefAttrName, value); var undefAttr = new UndefinedAttributeDefinition() { AttributeName = UndefAttrName, AttributeValue = value }; var undefAttrAssign = new AttributeAssignOrUpdateUndefined((aAttributeAssign as AttributeAssignOrUpdateValue).AttributeIDChain, undefAttr); manipulationAttributes.AttributeToUpdateOrAssign.Add(undefAttrAssign); #endregion } else if (aAttributeAssign is AttributeAssignOrUpdateSetRef) { return new Exceptional<ManipulationAttributes>(new Error_InvalidReferenceAssignmentOfUndefAttr()); } else { return new Exceptional<ManipulationAttributes>(new Error_InvalidUndefinedAttributeName()); } continue; } #endregion attr = aAttributeAssign.AttributeIDChain.LastAttribute; manipulationAttributes.AttributeToUpdateOrAssign.Add(aAttributeAssign); #region checks if (aAttributeAssign.AttributeIDChain.LastType != myGraphDBType) { return new Exceptional<ManipulationAttributes>(new Error_InvalidAttribute(aAttributeAssign.AttributeIDChain.ToString())); } if (attr.GetDBType(myDBContext.DBTypeManager).IsBackwardEdge) { return new Exceptional<ManipulationAttributes>(new Error_Logic("Adding values to BackwardEdges Attributes are not allowed! (" + attr.Name + ") is an BackwardEdge Attribute of GraphType \"" + myGraphDBType.Name + "\".")); } #endregion #region SpecialTypeAttribute if (attr is ASpecialTypeAttribute) { if (!(aAttributeAssign is AttributeAssignOrUpdateValue)) { return new Exceptional<ManipulationAttributes>(new Error_InvalidAttributeValue((attr as ASpecialTypeAttribute).Name, aAttributeAssign.ToString())); } manipulationAttributes.SpecialTypeAttributes.Add((attr as ASpecialTypeAttribute), (aAttributeAssign as AttributeAssignOrUpdateValue).Value); continue; } #endregion #region check & add if (aAttributeAssign.AttributeIDChain.Edges.Count > 1) { //in case of those statements: INSERT INTO Flower VALUES (Colors.Name = 'red') //Colors.Name is an IDNode with 2 Edges. This is not possible. return new Exceptional<ManipulationAttributes>(new Error_Logic("Invalid attribute assignment : " + aAttributeAssign.AttributeIDChain.ToString() + " = " + aAttributeAssign)); } if (aAttributeAssign is AttributeAssignOrUpdateList) { #region SetOfDBObjects #region Check, whether this is valid for SetOfDBObjects if (attr.KindOfType != KindsOfType.SetOfReferences) { if (attr.KindOfType != KindsOfType.ListOfNoneReferences) { if (attr.KindOfType != KindsOfType.SetOfNoneReferences) { return new Exceptional<ManipulationAttributes>(new Error_ReferenceAssignmentExpected(attr));//"Please use SETREF keyword instead of REF/REFERENCE or LISTOF.")); } } } #endregion #region list stuff #region process tuple #region process as list var collectionDefinition = ((AttributeAssignOrUpdateList)aAttributeAssign).CollectionDefinition; var dbType = attr.GetDBType(myDBContext.DBTypeManager); if (dbType.IsUserDefined) { #region List of references var uuids = collectionDefinition.GetEdge(attr, dbType, myDBContext); if (uuids.Failed()) { return new Exceptional<ManipulationAttributes>(uuids); } manipulationAttributes.Attributes.Add(new TypeAndAttributeDefinition(attr, dbType), uuids.Value); if (typeMandatoryAttribs.Contains(attr.UUID)) { manipulationAttributes.MandatoryAttributes.Add(attr.UUID); } #endregion } else { #region List of ADBBaseObjects (Integer, String, etc) var edge = (aAttributeAssign as AttributeAssignOrUpdateList).GetBasicList(myDBContext); if (edge.Failed()) { return new Exceptional<ManipulationAttributes>(edge); } // If the collection was declared as a SETOF insert if (collectionDefinition.CollectionType == CollectionType.Set) edge.Value.Distinction(); manipulationAttributes.Attributes.Add(new TypeAndAttributeDefinition(attr, attr.GetDBType(myDBContext.DBTypeManager)), edge.Value); if (typeMandatoryAttribs.Contains(attr.UUID)) { manipulationAttributes.MandatoryAttributes.Add(attr.UUID); } #endregion } #endregion #endregion #endregion #endregion } else if (aAttributeAssign is AttributeAssignOrUpdateSetRef) { #region reference var aSetRefNode = ((AttributeAssignOrUpdateSetRef)aAttributeAssign).SetRefDefinition; var singleedge = aSetRefNode.GetEdge(attr, myDBContext, attr.GetRelatedType(myDBContext.DBTypeManager)); if (singleedge.Failed()) { return new Exceptional<ManipulationAttributes>(singleedge); } if (attr.GetRelatedType(myDBContext.DBTypeManager).IsUserDefined) { //a list which carries elements of userdefined types consists of GUIDS manipulationAttributes.Attributes.Add(new TypeAndAttributeDefinition(attr, attr.GetDBType(myDBContext.DBTypeManager)), singleedge.Value); if (typeMandatoryAttribs.Contains(attr.UUID)) { manipulationAttributes.MandatoryAttributes.Add(attr.UUID); } } else { return new Exceptional<ManipulationAttributes>(new Error_UnknownDBError("Reference types cannot be basic types.")); } #endregion } else if (aAttributeAssign is AttributeAssignOrUpdateExpression) { #region Expression (aAttributeAssign as AttributeAssignOrUpdateExpression).BinaryExpressionDefinition.Validate(myDBContext); var value = (aAttributeAssign as AttributeAssignOrUpdateExpression).BinaryExpressionDefinition.ResultValue; if (value.Failed()) { return new Exceptional<ManipulationAttributes>(value.IErrors.First()); } if (value.Value is ValueDefinition) { #region AtomValue if (attr.KindOfType == KindsOfType.SetOfReferences || attr.KindOfType == KindsOfType.ListOfNoneReferences || attr.KindOfType == KindsOfType.SetOfNoneReferences) return new Exceptional<ManipulationAttributes>(new Error_InvalidTuple(aAttributeAssign.ToString())); if (!(value.Value as ValueDefinition).IsDefined) { (value.Value as ValueDefinition).ChangeType(attr.GetDBType(myDBContext.DBTypeManager).UUID); } var val = (value.Value as ValueDefinition).Value.Value; correspondingCSharpType = GraphDBTypeMapper.ConvertGraph2CSharp(attr, attr.GetDBType(myDBContext.DBTypeManager)); if (GraphDBTypeMapper.GetEmptyGraphObjectFromType(correspondingCSharpType).IsValidValue(val)) { typedAttributeValue = GraphDBTypeMapper.GetGraphObjectFromType(correspondingCSharpType, val); manipulationAttributes.Attributes.Add(new TypeAndAttributeDefinition(attr, attr.GetDBType(myDBContext.DBTypeManager)), typedAttributeValue); if (typeMandatoryAttribs.Contains(attr.UUID)) manipulationAttributes.MandatoryAttributes.Add(attr.UUID); } else { return new Exceptional<ManipulationAttributes>(new Error_InvalidAttributeValue(attr.Name, (aAttributeAssign as AttributeAssignOrUpdateValue).Value)); } #endregion } else // TupleValue! { #region TupleValue if (attr.KindOfType != KindsOfType.SetOfReferences) return new Exceptional<ManipulationAttributes>(new Error_InvalidTuple(aAttributeAssign.ToString())); if (!(attr.EdgeType is IBaseEdge)) return new Exceptional<ManipulationAttributes>(new Error_InvalidEdgeType(attr.EdgeType.GetType(), typeof(IBaseEdge))); correspondingCSharpType = GraphDBTypeMapper.ConvertGraph2CSharp(attr, attr.GetDBType(myDBContext.DBTypeManager)); if ((value.Value as TupleDefinition).TypeOfOperatorResult != correspondingCSharpType) return new Exceptional<ManipulationAttributes>(new Error_DataTypeDoesNotMatch(correspondingCSharpType.ToString(), (value.Value as TupleDefinition).TypeOfOperatorResult.ToString())); var edge = attr.EdgeType.GetNewInstance() as IBaseEdge; edge.AddRange((value.Value as TupleDefinition).Select(te => (te.Value as ValueDefinition).Value)); manipulationAttributes.Attributes.Add(new TypeAndAttributeDefinition(attr, attr.GetDBType(myDBContext.DBTypeManager)), edge as IBaseEdge); #endregion } #endregion } else if (aAttributeAssign is AttributeAssignOrUpdateValue) { #region Simple value var attrVal = aAttributeAssign as AttributeAssignOrUpdateValue; if (attr.KindOfType == KindsOfType.ListOfNoneReferences) return new Exceptional<ManipulationAttributes>(new Error_InvalidTuple(attrVal.ToString())); correspondingCSharpType = GraphDBTypeMapper.ConvertGraph2CSharp(attr, attr.GetDBType(myDBContext.DBTypeManager)); if (GraphDBTypeMapper.GetEmptyGraphObjectFromType(correspondingCSharpType).IsValidValue(attrVal.Value)) { typedAttributeValue = GraphDBTypeMapper.GetGraphObjectFromType(correspondingCSharpType, attrVal.Value); manipulationAttributes.Attributes.Add(new TypeAndAttributeDefinition(attr, attr.GetDBType(myDBContext.DBTypeManager)), typedAttributeValue); if (typeMandatoryAttribs.Contains(attr.UUID)) manipulationAttributes.MandatoryAttributes.Add(attr.UUID); } else { return new Exceptional<ManipulationAttributes>(new Error_InvalidAttributeValue(attr.Name, attrVal.Value)); } #endregion } else { return new Exceptional<ManipulationAttributes>(new Error_NotImplemented(new System.Diagnostics.StackTrace(true))); } #endregion } #endregion #endregion resultExcept.Value = manipulationAttributes; return resultExcept; }
public AttributeAssignOrUpdateUndefined(IDChainDefinition myIDChainDefinition, UndefinedAttributeDefinition myUndefinedAttribute) : base(myIDChainDefinition) { UndefinedAttribute = myUndefinedAttribute; }