internal Exceptional SetBackwardEdges(Dictionary<AttributeUUID, IObject> userdefinedAttributes, ObjectUUID reference) { var returnVal = new Exceptional(); #region process attributes foreach (var aUserDefinedAttribute in userdefinedAttributes) { #region Data GraphDBType typeOFAttribute = null; TypeAttribute attributesOfType = null; #endregion #region get GraphType of Attribute //attributesOfType = _graphDBType.Attributes[aUserDefinedAttribute.Key]; attributesOfType = _graphDBType.GetTypeAttributeByUUID(aUserDefinedAttribute.Key); typeOFAttribute = _dbContext.DBTypeManager.GetTypeByUUID(attributesOfType.DBTypeUUID); #endregion /* The DBO independent version */ var beEdge = new EdgeKey(_graphDBType.UUID, attributesOfType.UUID); var runMT = DBConstants.RunMT; runMT = false; if (runMT) { #region The parallel version /**/ /* The parallel version */ Parallel.ForEach(((IReferenceEdge)aUserDefinedAttribute.Value).GetAllReferenceIDs(), (uuid) => { var addExcept = _dbContext.DBObjectManager.AddBackwardEdge(uuid, attributesOfType.DBTypeUUID, beEdge, reference); if (!addExcept.Success()) { returnVal.PushIExceptional(addExcept); } }); if (!returnVal.Success()) { return returnVal; } /**/ #endregion } else { #region Single thread foreach (var uuid in ((IReferenceEdge)aUserDefinedAttribute.Value).GetAllReferenceIDs()) { var addExcept = _dbContext.DBObjectManager.AddBackwardEdge(uuid, attributesOfType.DBTypeUUID, beEdge, reference); if (addExcept.Failed()) { return new Exceptional(addExcept); } } #endregion } } #endregion return Exceptional.OK; } private Exceptional AddMandatoryAttributes(DBContext myDBContext, GraphDBType myGraphDBType, ManipulationAttributes myManipulationAttributes) { Boolean mandatoryDefaults = (Boolean)myDBContext.DBSettingsManager.GetSettingValue((new SettingDefaultsOnMandatory()).ID, myDBContext, TypesSettingScope.TYPE, myGraphDBType).Value.Value; TypeAttribute typeAttr = null; GraphDBType typeOfAttr = null; var typeMandatoryAttribs = myGraphDBType.GetMandatoryAttributesUUIDs(myDBContext.DBTypeManager); if ((myManipulationAttributes.MandatoryAttributes.Count < typeMandatoryAttribs.Count()) && !mandatoryDefaults) return new Exceptional(new Error_MandatoryConstraintViolation(myGraphDBType.Name)); foreach (var attrib in typeMandatoryAttribs) { if (!myManipulationAttributes.MandatoryAttributes.Contains(attrib)) { //if we have mandatory attributes in _graphDBType but not in the current statement and USE_DEFAULTS_ON_MANDATORY is true then do this if (mandatoryDefaults) { typeAttr = myGraphDBType.GetTypeAttributeByUUID(attrib); if (typeAttr == null) return new Exceptional(new Error_AttributeIsNotDefined(myGraphDBType.Name, typeAttr.Name)); typeOfAttr = myDBContext.DBTypeManager.GetTypeByUUID(typeAttr.DBTypeUUID); IObject defaultValue = typeAttr.DefaultValue; if (defaultValue == null) defaultValue = typeAttr.GetDefaultValue(myDBContext); myManipulationAttributes.Attributes.Add(new TypeAndAttributeDefinition(typeAttr, typeOfAttr), defaultValue); } else { return new Exceptional(new Error_MandatoryConstraintViolation("Attribute \"" + myGraphDBType.GetTypeAttributeByUUID(attrib).Name + "\" of Type \"" + myGraphDBType.Name + "\" is mandatory.")); } } } return Exceptional.OK; } private Exceptional<Boolean> DeleteObjectReferences(ObjectUUID myObjectUUID, BackwardEdgeStream myObjectBackwardEdges) { foreach (var item in myObjectBackwardEdges) { var type = _dbContext.DBTypeManager.GetTypeByUUID(item.Key.TypeUUID); if (type == null) { return new Exceptional<Boolean>(new Error_TypeDoesNotExist("")); } foreach (var objID in item.Value.GetAllEdgeDestinations(_dbContext.DBObjectCache)) { if (objID.Failed()) { return new Exceptional<Boolean>(objID); } var attr = objID.Value.GetAttribute(item.Key.AttrUUID); if (attr is IReferenceEdge) { var removeResult = ((IReferenceEdge)attr).RemoveUUID(myObjectUUID); if (removeResult) { #region Sucessfully removed the single edge ref - so remove the attribute if (attr is ASingleReferenceEdgeType) { objID.Value.RemoveAttribute(item.Key.AttrUUID); } #endregion } else { return new Exceptional<bool>(new Error_NotImplemented(new System.Diagnostics.StackTrace(true))); } } var flushExcept = _dbContext.DBObjectManager.FlushDBObject(objID.Value); if (!flushExcept.Success()) return new Exceptional<bool>(flushExcept.IErrors.First()); } } return new Exceptional<bool>(true); } private Dictionary<TypeAndAttributeDefinition, IObject> ExtractDefinedAttributes(Dictionary<string, Tuple<TypeAttribute, IObject>> attrsForResult, DBTypeManager myTypeManager) { return attrsForResult.Where(item => !(item.Value.Item1 is UndefinedTypeAttribute)).ToDictionary(key => new TypeAndAttributeDefinition(key.Value.Item1, key.Value.Item1.GetDBType(myTypeManager)), value => value.Value.Item2); } private Dictionary<string, IObject> ExtractUndefindedAttributes(Dictionary<string, Tuple<TypeAttribute, IObject>> attrsForResult) { return attrsForResult.Where(item => (item.Value.Item1 is UndefinedTypeAttribute)).ToDictionary(key => key.Key, value => value.Value.Item2); } private AttributeUUID GetAttributesToCheckForUnique(AAttributeAssignOrUpdateOrRemove myAAttributeAssignOrUpdateOrRemove) { if (myAAttributeAssignOrUpdateOrRemove is AAttributeRemove) return null; if (myAAttributeAssignOrUpdateOrRemove.AttributeIDChain.IsUndefinedAttribute) { return null; } if (myAAttributeAssignOrUpdateOrRemove is AAttributeAssignOrUpdate) { return ((AAttributeAssignOrUpdate)myAAttributeAssignOrUpdateOrRemove).AttributeIDChain.LastAttribute.UUID; } if (myAAttributeAssignOrUpdateOrRemove is AttributeAssignOrUpdateList) return ((AttributeAssignOrUpdateList)myAAttributeAssignOrUpdateOrRemove).AttributeIDChain.LastAttribute.UUID; throw new GraphDBException(new Error_NotImplemented(new System.Diagnostics.StackTrace(true))); } /// <summary> /// Create a readout based on the passed <paramref name="attributes"/>, <paramref name="undefinedAttributes"/>, <paramref name="specialTypeAttributes"/> which are all optional /// </summary> /// <param name="myDBObjectStreamExceptional"></param> /// <param name="attributes"></param> /// <param name="undefinedAttributes"></param> /// <param name="specialTypeAttributes"></param> /// <returns></returns> private Exceptional<Vertex> GetManipulationResultSet(Exceptional<DBObjectStream> myDBObjectStreamExceptional, Dictionary<TypeAndAttributeDefinition, IObject> attributes = null, Dictionary<String, IObject> undefinedAttributes = null, Dictionary<ASpecialTypeAttribute, Object> specialTypeAttributes = null) { Vertex _Vertex = null; #region Return inserted attributes #region attributes if (!attributes.IsNullOrEmpty()) { _Vertex = new Vertex(attributes.ToDictionary(key => key.Key.Definition.Name, value => value.Value.GetReadoutValue())); } else { _Vertex = new Vertex(); } #endregion #region UndefinedAttributes if (!undefinedAttributes.IsNullOrEmpty()) { foreach (var undefAttr in undefinedAttributes) { _Vertex.AddAttribute(undefAttr.Key, undefAttr.Value.GetReadoutValue()); } } #endregion #region SpecialTypeAttributes if (!specialTypeAttributes.IsNullOrEmpty()) { foreach (var specAttr in specialTypeAttributes) { _Vertex.AddAttribute(specAttr.Key.Name, specAttr.Value); } } #endregion #region UUID if (!_Vertex.HasAttribute(SpecialTypeAttribute_UUID.AttributeName)) { var extractedValue = new SpecialTypeAttribute_UUID().ExtractValue(myDBObjectStreamExceptional.Value, _graphDBType, _dbContext); if (extractedValue.Failed()) { return new Exceptional<Vertex>(extractedValue); } _Vertex.AddAttribute(SpecialTypeAttribute_UUID.AttributeName, extractedValue.Value.GetReadoutValue()); } #endregion #region REVISION if (!_Vertex.HasAttribute(SpecialTypeAttribute_REVISION.AttributeName)) // If it was updated by SpecialTypeAttributes we do not need to add them again { var extractedValue = new SpecialTypeAttribute_REVISION().ExtractValue(myDBObjectStreamExceptional.Value, _graphDBType, _dbContext); if (extractedValue.Failed()) { return new Exceptional<Vertex>(extractedValue); } _Vertex.AddAttribute(SpecialTypeAttribute_REVISION.AttributeName, extractedValue.Value.GetReadoutValue()); } #endregion #endregion return new Exceptional<Vertex>(_Vertex); } /// <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: resultExcept.PushIWarning(new Warning_UndefinedAttribute(aAttributeAssign.AttributeIDChain)); 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())); if (attr.KindOfType != KindsOfType.SingleNoneReference) { return new Exceptional<ManipulationAttributes>(new Error_InvalidAttributeKind(attr.KindOfType, KindsOfType.SingleNoneReference)); } 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; } /// <summary> /// Inserts into all indices that are affected if a DBObject is updated on a certain attibute /// </summary> /// <param name="dBObjectStream"></param> /// <param name="attributeUUID"></param> /// <param name="_dbContext"></param> /// <returns></returns> private Exceptional InsertDBObjectIntoIndex(DBObjectStream dBObjectStream, AttributeUUID attributeUUID) { foreach (var aType in _dbContext.DBTypeManager.GetAllParentTypes(_dbContext.DBTypeManager.GetTypeByUUID(dBObjectStream.TypeUUID), true, false)) { foreach (var aAttributeIdx in aType.GetAttributeIndices(_dbContext, attributeUUID)) { var result = aAttributeIdx.Insert(dBObjectStream, aType, _dbContext); if (result.Failed()) { return new Exceptional(result); } } } return new Exceptional(); } /// <summary> /// Removes index entries corresponding to a DBObject /// </summary> /// <param name="dBObjectStream"></param> /// <param name="attributeUUID"></param> /// <param name="_dbContext"></param> /// <returns></returns> private Exceptional RemoveDBObjectFromIndex(DBObjectStream dBObjectStream, AttributeUUID attributeUUID) { foreach (var aType in _dbContext.DBTypeManager.GetAllParentTypes(_dbContext.DBTypeManager.GetTypeByUUID(dBObjectStream.TypeUUID), true, false)) { foreach (var aAttributeIdx in aType.GetAttributeIndices(_dbContext, attributeUUID)) { var result = aAttributeIdx.Remove(dBObjectStream, aType, _dbContext); if (result.Failed()) { return new Exceptional(result); } } } return new Exceptional(); } private Exceptional RemoveUndefAttrs(IEnumerable<Exceptional<DBObjectStream>> myDBObjStream, List<String> myUndefAttrs) { #region delete undefined attributes foreach (var objects in myDBObjStream) { var undefAttrsStream = myUndefAttrs.Where(item => objects.Value.GetUndefinedAttributePayload(_dbContext.DBObjectManager).Value.ContainsKey(item)); foreach (var undefAttr in undefAttrsStream) { var removeExcept = _dbContext.DBObjectManager.RemoveUndefinedAttribute(undefAttr, objects.Value); if (removeExcept.Failed()) return new Exceptional(removeExcept); } } #endregion return Exceptional.OK; } /// <summary> /// setting the default value for the attribute /// </summary> /// <param name="myAttr">the attribute</param> /// <param name="myDBObjectCache">the object cache</param> /// <returns>true if the value was changed</returns> private Exceptional<Boolean> SetDefaultValue(TypeAttribute myAttr, Exceptional<DBObjectStream> myDBO) { if (myDBO.Success()) { IObject defaultValue = myAttr.DefaultValue; if (defaultValue == null) defaultValue = myAttr.GetDefaultValue(_dbContext); var alterExcept = myDBO.Value.AlterAttribute(myAttr.UUID, defaultValue); if (alterExcept.Failed()) return new Exceptional<Boolean>(alterExcept); if (!alterExcept.Value) { return new Exceptional<bool>(false); } } else { return new Exceptional<bool>(false); } return new Exceptional<bool>(true); } /// <summary> /// This is the update method which will change some <paramref name="myDBObjects"/> on behalf of the <paramref name="myListOfUpdates"/> /// </summary> /// <param name="myDBObjects">Some dbobjects</param> /// <param name="myListOfUpdates">The list of update tasks (assign, delete, etc)</param> /// <param name="dbObjectCache"></param> /// <returns></returns> private QueryResult Update(IEnumerable<Exceptional<DBObjectStream>> myDBObjects, IEnumerable<AAttributeAssignOrUpdateOrRemove> myListOfUpdates) { #region Data var queryResultContent = new List<Vertex>(); var queryResult = new QueryResult(); #endregion #region check for undefined attributes setting var undefAttrSetting = _dbContext.DBSettingsManager.GetSetting(SettingUndefAttrBehaviour.UUID, _dbContext, TypesSettingScope.DB); if (!undefAttrSetting.Success()) { return new QueryResult(undefAttrSetting); } var undefSettingVal = ((SettingUndefAttrBehaviour)undefAttrSetting.Value).Behaviour; #endregion #region Validate attributes var definedAttributeAssignments = new Dictionary<AttributeUUID, AAttributeAssignOrUpdate>(); foreach (var updateOrAssign in myListOfUpdates) { System.Diagnostics.Debug.Assert(updateOrAssign != null); if (!(updateOrAssign is AttributeRemove)) { var result = updateOrAssign.AttributeIDChain.Validate(_dbContext, true); if (result.Failed()) { return new QueryResult(result); } if (updateOrAssign.IsUndefinedAttributeAssign) { #region handle undefined attributes switch (undefSettingVal) { case UndefAttributeBehaviour.disallow: return new QueryResult(new Error_UndefinedAttributes()); case UndefAttributeBehaviour.warn: queryResult.PushIWarning(new Warning_UndefinedAttribute(updateOrAssign.AttributeIDChain)); break; } #endregion } else { //here a dictionary is used, because myListOfUpdates will be traversed many times now (maybe CachedEnumerator can be used instead) if (updateOrAssign is AAttributeAssignOrUpdate) definedAttributeAssignments[GetAttributesToCheckForUnique(updateOrAssign)] = updateOrAssign as AAttributeAssignOrUpdate; } } } #endregion #region check unique constraint if (definedAttributeAssignments.CountIsGreater(0)) { Exceptional<Boolean> CheckConstraint = null; IEnumerable<GraphDBType> parentTypes = _dbContext.DBTypeManager.GetAllParentTypes(_graphDBType, true, false); foreach (var entry in myDBObjects) { //here all attributes are listed, that will change their value var changingAttributes = (from CurrentAttribute in entry.Value.GetAttributes() join Update in definedAttributeAssignments on CurrentAttribute.Key equals Update.Key where !CurrentAttribute.Value.Equals(Update.Value.GetValueForAttribute(entry.Value, _dbContext, _graphDBType).Value) select new {Key = CurrentAttribute.Key, Value = CurrentAttribute.Value}).ToDictionary(x=>x.Key, x=>x.Value); CheckConstraint = _dbContext.DBIndexManager.CheckUniqueConstraint(_graphDBType, parentTypes, changingAttributes); if (CheckConstraint.Failed()) return new QueryResult(CheckConstraint.IErrors); } } #endregion #region regular update foreach (var aDBO in myDBObjects) { //key: attribute name //value: TypeAttribute, NewValue Dictionary<String, Tuple<TypeAttribute, IObject>> attrsForResult = new Dictionary<String, Tuple<TypeAttribute, IObject>>(); if (aDBO.Failed()) { return new QueryResult(aDBO); } #region data Boolean sthChanged = false; #endregion #region iterate tasks //Exceptional<Boolean> partialResult; foreach (var attributeUpdateOrAssign in myListOfUpdates) { var updateResult = attributeUpdateOrAssign.Update(_dbContext, aDBO.Value, _graphDBType); if (updateResult.Failed()) { return new QueryResult(updateResult); } if (updateResult.Value.Count > 0) { sthChanged = true; attrsForResult.AddRange(updateResult.Value); } } #endregion if (sthChanged) { var definedAttributes = ExtractDefinedAttributes(attrsForResult, _dbContext.DBTypeManager); #region update Idx foreach (var _AttributeIndex in _graphDBType.GetAllAttributeIndices(_dbContext)) { if(definedAttributes.Exists(item => _AttributeIndex.IndexKeyDefinition.IndexKeyAttributeUUIDs.Contains(item.Key.Definition.UUID))) { //execute update _AttributeIndex.Update(aDBO.Value, _graphDBType, _dbContext); } } #endregion #region update dbobjects on fs var flushResult = _dbContext.DBObjectManager.FlushDBObject(aDBO.Value); if (!flushResult.Success()) { return new QueryResult(flushResult); } #endregion var resultSet = GetManipulationResultSet(aDBO, undefinedAttributes: ExtractUndefindedAttributes(attrsForResult), attributes: definedAttributes); if (!resultSet.Success()) { /* what should happen now this should not break the update */ } queryResultContent.Add(resultSet.Value); } }
/// <summary> /// setting the default value for the attribute /// </summary> /// <param name="myAttr">the attribute</param> /// <param name="myDBObjectCache">the object cache</param> /// <returns>true if the value was changed</returns> private Exceptional<Boolean> SetDefaultValue(TypeAttribute myAttr, Exceptional<DBObjectStream> myDBO, DBContext dbContext) { if (myDBO.Success()) { IObject defaultValue = myAttr.DefaultValue; if (defaultValue == null) defaultValue = myAttr.GetDefaultValue(dbContext); var alterExcept = myDBO.Value.AlterAttribute(myAttr.UUID, defaultValue); if (alterExcept.Failed()) return new Exceptional<Boolean>(alterExcept); if (!alterExcept.Value) { return new Exceptional<bool>(false); } } else { return new Exceptional<bool>(false); } return new Exceptional<bool>(true); }
/// <summary> /// Finds matching result corresponding to a binary expression. /// </summary> /// <param name="myLeftValueObject">The left value of a binary expression.</param> /// <param name="myRightValueObject">The right value of a binary expression.</param> /// <param name="currentTypeDefinitione"></param> /// <param name="dbContext">The TypeManager of the database.</param> /// <param name="typeOfBinExpr">The type of the binary expression.</param> /// <param name="associativity">The associativity of the binary expression.</param> /// <param name="referenceList"></param> /// <param name="queryCache">The per query DBObject/BackwardEdge cache.</param> /// <returns></returns> public override Exceptional<IExpressionGraph> TypeOperation(AExpressionDefinition myLeftValueObject, AExpressionDefinition myRightValueObject, DBContext dbContext, TypesOfBinaryExpression typeOfBinExpr, TypesOfAssociativity associativity, IExpressionGraph resultGr, Boolean aggregateAllowed = true) { #region Data //list of errors List<GraphDBError> errors = new List<GraphDBError>(); //DataContainer for all data that is used by a binary expression/comparer Exceptional<DataContainer> data; //the index of the left attribute IEnumerable<Tuple<GraphDBType, AAttributeIndex>> leftIndex = null; //the index of the right attribute IEnumerable<Tuple<GraphDBType, AAttributeIndex>> rightIndex = null; #endregion #region extract data //data extraction with an eye on the type of the binary expression switch (typeOfBinExpr) { case TypesOfBinaryExpression.Atom: //sth like 3 = 4 #region Get Atom data //no further data has to be generated //data = new DataContainer(null, new Tuple<Object, Object>(myLeftValueObject, myRightValueObject), null); data = new Exceptional<DataContainer>(); #endregion break; case TypesOfBinaryExpression.LeftComplex: //sth like U.Age = 21 #region Get LeftComplex data data = ExtractData(myLeftValueObject, myRightValueObject, ref typeOfBinExpr, dbContext.DBObjectCache, dbContext.SessionSettings, dbContext, aggregateAllowed); if (!data.Success()) { return new Exceptional<IExpressionGraph>(data); } #endregion break; case TypesOfBinaryExpression.RightComplex: //sth like 21 = U.Age #region Get RightComplex data data = ExtractData(myRightValueObject, myLeftValueObject, ref typeOfBinExpr, dbContext.DBObjectCache, dbContext.SessionSettings, dbContext, aggregateAllowed); if (!data.Success()) { return new Exceptional<IExpressionGraph>(data); } #endregion break; case TypesOfBinaryExpression.Complex: //sth like U.Age = F.Alter #region Get Complex data var leftData = ExtractData(myLeftValueObject, myRightValueObject, ref typeOfBinExpr, dbContext.DBObjectCache, dbContext.SessionSettings, dbContext, aggregateAllowed); if (!leftData.Success()) { return new Exceptional<IExpressionGraph>(leftData); } var rightData = ExtractData(myRightValueObject, myLeftValueObject, ref typeOfBinExpr, dbContext.DBObjectCache, dbContext.SessionSettings, dbContext, aggregateAllowed); if (!rightData.Success()) { return new Exceptional<IExpressionGraph>(rightData); } if (typeOfBinExpr == TypesOfBinaryExpression.Unknown) { typeOfBinExpr = SetTypeOfBinaryExpression(leftData, rightData); switch (typeOfBinExpr) { case TypesOfBinaryExpression.Atom: data = new Exceptional<DataContainer>(new DataContainer(new Tuple<IDChainDefinition, IDChainDefinition>(null, null), new Tuple<AExpressionDefinition, AExpressionDefinition>(leftData.Value.Operands.Item1, leftData.Value.Operands.Item1), new Tuple<AExpressionDefinition, AExpressionDefinition>(null, null))); break; case TypesOfBinaryExpression.LeftComplex: data = new Exceptional<DataContainer>(new DataContainer(new Tuple<IDChainDefinition, IDChainDefinition>(leftData.Value.IDChainDefinitions.Item1, null), new Tuple<AExpressionDefinition, AExpressionDefinition>(rightData.Value.Operands.Item1, null), new Tuple<AExpressionDefinition, AExpressionDefinition>(null, null))); break; case TypesOfBinaryExpression.RightComplex: data = new Exceptional<DataContainer>(new DataContainer(new Tuple<IDChainDefinition, IDChainDefinition>(rightData.Value.IDChainDefinitions.Item1, null), new Tuple<AExpressionDefinition, AExpressionDefinition>(leftData.Value.Operands.Item1, null), new Tuple<AExpressionDefinition, AExpressionDefinition>(null, null))); break; case TypesOfBinaryExpression.Complex: case TypesOfBinaryExpression.Unknown: default: throw new GraphDBException(new Error_NotImplemented(new System.Diagnostics.StackTrace(true))); } } else { data = new Exceptional<DataContainer>(JoinData(leftData.Value, rightData.Value)); } #endregion break; default: throw new ArgumentException(); } #region handle errors if (data.Failed()) { return new Exceptional<IExpressionGraph>(data); } #endregion #endregion #region get indexes switch (typeOfBinExpr) { case TypesOfBinaryExpression.LeftComplex: leftIndex = GetIndex(data.Value.IDChainDefinitions.Item1.LastAttribute, dbContext, data.Value.IDChainDefinitions.Item1.LastType, data.Value.Extraordinaries.Item1); break; case TypesOfBinaryExpression.RightComplex: //data.IdNodes.TupelElement1 is correct, because of correct handling in extract data (data.IdNodes.TupelElement2 should be null here) rightIndex = GetIndex(data.Value.IDChainDefinitions.Item1.LastAttribute, dbContext, data.Value.IDChainDefinitions.Item1.LastType, data.Value.Extraordinaries.Item1); break; case TypesOfBinaryExpression.Complex: //both indexe have to be catched leftIndex = GetIndex(data.Value.IDChainDefinitions.Item1.LastAttribute, dbContext, data.Value.IDChainDefinitions.Item1.LastType, data.Value.Extraordinaries.Item1); rightIndex = GetIndex(data.Value.IDChainDefinitions.Item2.LastAttribute, dbContext, data.Value.IDChainDefinitions.Item2.LastType, data.Value.Extraordinaries.Item1); break; } #endregion //time to compare some things Exceptional<Boolean> matchDataResult = null; if (IsValidIndexOperation(data.Value, dbContext, typeOfBinExpr)) { #region match data switch (typeOfBinExpr) { case TypesOfBinaryExpression.Atom: #region Atom //do nothing 3 = 3 (or 2 != 3) doesnt bother U #endregion break; case TypesOfBinaryExpression.LeftComplex: #region LeftComplex matchDataResult = MatchData(data.Value, dbContext, dbContext.DBObjectCache, typeOfBinExpr, leftIndex, resultGr, dbContext.SessionSettings); #endregion break; case TypesOfBinaryExpression.RightComplex: #region RightComplex matchDataResult = MatchData(data.Value, dbContext, dbContext.DBObjectCache, typeOfBinExpr, rightIndex, resultGr, dbContext.SessionSettings); #endregion break; case TypesOfBinaryExpression.Complex: #region Complex matchDataResult = MatchComplexData(associativity, data.Value, dbContext, dbContext.DBObjectCache, typeOfBinExpr, leftIndex, rightIndex, ref errors, ref resultGr, dbContext.SessionSettings); #endregion break; } #endregion } else { return new Exceptional<IExpressionGraph>(new Error_InvalidBinaryExpression(this, data.Value.IDChainDefinitions, data.Value.Operands, typeOfBinExpr)); } if (matchDataResult != null && matchDataResult.Failed()) return new Exceptional<IExpressionGraph>(matchDataResult); else return new Exceptional<IExpressionGraph>(resultGr); }
internal Exceptional SetBackwardEdges(GraphDBType aType, Dictionary<AttributeUUID, IObject> userdefinedAttributes, ObjectUUID reference, DBContext dbContext) { var returnVal = new Exceptional(); #region process attributes foreach (var aUserDefinedAttribute in userdefinedAttributes) { #region Data GraphDBType typeOFAttribute = null; TypeAttribute attributesOfType = null; #endregion #region get GraphType of Attribute //attributesOfType = aType.Attributes[aUserDefinedAttribute.Key]; attributesOfType = aType.GetTypeAttributeByUUID(aUserDefinedAttribute.Key); typeOFAttribute = dbContext.DBTypeManager.GetTypeByUUID(attributesOfType.DBTypeUUID); #endregion /* The DBO independent version */ var beEdge = new EdgeKey(aType.UUID, attributesOfType.UUID); var runMT = DBConstants.RunMT; runMT = false; if (runMT) { #region The parallel version /**/ /* The parallel version */ Parallel.ForEach(((IReferenceEdge)aUserDefinedAttribute.Value).GetAllReferenceIDs(), (uuid) => { var addExcept = dbContext.DBObjectManager.AddBackwardEdge(uuid, attributesOfType.DBTypeUUID, beEdge, reference); if (!addExcept.Success()) { returnVal.PushIExceptional(addExcept); } }); if (!returnVal.Success()) { return returnVal; } /**/ #endregion } else { #region Single thread foreach (var uuid in ((IReferenceEdge)aUserDefinedAttribute.Value).GetAllReferenceIDs()) { var addExcept = dbContext.DBObjectManager.AddBackwardEdge(uuid, attributesOfType.DBTypeUUID, beEdge, reference); if (addExcept.Failed()) { return new Exceptional(addExcept); } } #endregion } } #endregion return Exceptional.OK; }