/// <summary> /// This method adds a bunch of new GraphTypeDefinitions (comes from a CREATE TYPE(S) statement) to the TypeManager. /// If a certain PType can't be added (because of some inheritance or /// attribute errors), this method tries to add it in a second /// step. /// </summary> /// <param name="TypeList">List of GraphType definitions that should /// be added to the TypeManager</param> /// <returns>List of GraphError</returns> public Exceptional<QueryResult> AddBulkTypes(List<GraphDBTypeDefinition> TypeList, DBContext currentContext) { #region Input Exceptions if (TypeList == null) { return new Exceptional<QueryResult>(new QueryResult()); } if (TypeList.Count.Equals(0)) { return new Exceptional<QueryResult>(new QueryResult()); } #endregion #region Data var errors = new List<GraphDBError>(); List<GraphDBType> addedTypes = new List<GraphDBType>(); List<AttributeUUID> uniqueAttrIDs = new List<AttributeUUID>(); QueryResult result = new QueryResult(); #endregion try { #region Create the types without attributes foreach (GraphDBTypeDefinition aTypeDef in TypeList) { #region Input validation if (String.IsNullOrEmpty(aTypeDef.Name)) return new Exceptional<QueryResult>(new Error_ArgumentNullOrEmpty("myTypeName")); if (String.IsNullOrEmpty(aTypeDef.ParentType)) return new Exceptional<QueryResult>(new Error_ArgumentNullOrEmpty("myParentType")); if (aTypeDef.Attributes == null) return new Exceptional<QueryResult>(new Error_ArgumentNullOrEmpty("myAttributes")); #endregion GraphDBType thisType = GetTypeByName(aTypeDef.Name); #region Check if the name of the type is already used if (thisType != null) { return new Exceptional<QueryResult>(new Error_TypeAlreadyExist(aTypeDef.Name)); } #endregion GraphDBType parentType = GetTypeByName(aTypeDef.ParentType); Dictionary<AttributeUUID, TypeAttribute> attributes = new Dictionary<AttributeUUID, TypeAttribute>(); #region objectDirectoryShards var objectDirectoryShards = UInt16.Parse(currentContext.GraphAppSettings.Get<ObjectsDirectoryShardsSetting>()); #endregion #region Add type TypeUUID parentUUID = (parentType == null) ? null : parentType.UUID; #region hack GraphDBType _NewGraphType = new GraphDBType(null, new ObjectLocation(_DatabaseRootPath), aTypeDef.Name, parentUUID, attributes, true, aTypeDef.IsAbstract, aTypeDef.Comment, objectDirectoryShards); #endregion addedTypes.Add(_NewGraphType); _UserDefinedTypes.Add(_NewGraphType.UUID, _NewGraphType); _TypesNameLookUpTable.Add(_NewGraphType.Name, _NewGraphType); #endregion } #endregion var backwardEdgesToBeAddedAfterwards = new Dictionary<GraphDBType, List<BackwardEdgeDefinition>>(); #region Validate the previously added types and add the attributes and backwardEdges foreach (var aTypeDef in TypeList) { GraphDBType aType = addedTypes.Where(item => item.Name == aTypeDef.Name).FirstOrDefault(); #region Check and set parent GraphDBType parentType; #region Verify base type existence if (aType.ParentTypeUUID == null) { parentType = addedTypes.Where(item => item.Name == aTypeDef.ParentType).FirstOrDefault(); if (parentType == null) { RemoveRecentlyAddedTypes(addedTypes); return new Exceptional<QueryResult>(new Error_ParentTypeDoesNotExist(aTypeDef.ParentType, aTypeDef.Name)); } aType.SetParentTypeUUID(parentType.UUID); } else { parentType = aType.GetParentType(this); } #endregion #region Verify that the type inherit DBReference var parentTypeExcept = HasParentType(parentType.UUID, DBReference.UUID); if (parentTypeExcept.Failed()) { return new Exceptional<QueryResult>(parentTypeExcept); } if (!parentTypeExcept.Value) { RemoveRecentlyAddedTypes(addedTypes); return new Exceptional<QueryResult>(new Error_InvalidBaseType(parentType.Name)); } #endregion #endregion //add TypeAttributeLookuptable to current type aType.AttributeLookupTable.AddRange(parentType.AttributeLookupTable); #region check and set type of attributes UInt16 attributeCounter = 0; foreach (var attributeDef in aTypeDef.Attributes) { var attribute = attributeDef.Key.CreateTypeAttribute(currentContext, addedTypes, attributeCounter); if (attribute.Failed()) { return new Exceptional<QueryResult>(attribute); } if (attribute.Value.Name == aType.Name) { RemoveRecentlyAddedTypes(addedTypes); return new Exceptional<QueryResult>(new Error_InvalidAttributeName("The attribute " + attribute.Value.Name + " can not be added, because it has the same name as its related type.")); } GraphDBType attrType = GetTypeByName(attributeDef.Value); if (attrType == null) { attrType = addedTypes.Where(item => item.Name == attributeDef.Value).FirstOrDefault(); if (attrType == null) { RemoveRecentlyAddedTypes(addedTypes); return new Exceptional<QueryResult>(new Error_TypeDoesNotExist(attributeDef.Value)); } } attributeCounter++; TypeAttribute newAttr = attribute.Value; newAttr.DBTypeUUID = attrType.UUID; newAttr.RelatedGraphDBTypeUUID = aType.UUID; #region we had not defined a special EdgeType - for single reference attributes we need to set the EdgeTypeSingle NOW! if (newAttr.KindOfType == KindsOfType.SingleReference && attrType.IsUserDefined && newAttr.EdgeType == null) newAttr.EdgeType = new EdgeTypeSingleReference(null, newAttr.DBTypeUUID); #endregion #region Validate EdgeType in terms of List & Single if (newAttr.KindOfType == KindsOfType.SingleReference && attrType.IsUserDefined && !(newAttr.EdgeType is ASingleReferenceEdgeType)) { RemoveRecentlyAddedTypes(addedTypes); return new Exceptional<QueryResult>(new Error_InvalidEdgeType(newAttr.EdgeType.GetType(), typeof(ASingleReferenceEdgeType))); } else if (newAttr.KindOfType == KindsOfType.SetOfReferences || newAttr.KindOfType == KindsOfType.SetOfNoneReferences) { if (attrType.IsUserDefined && !(newAttr.EdgeType is ASetOfReferencesEdgeType)) { RemoveRecentlyAddedTypes(addedTypes); return new Exceptional<QueryResult>(new Error_InvalidEdgeType(newAttr.EdgeType.GetType(), typeof(ASetOfReferencesEdgeType))); } else if (!attrType.IsUserDefined && !(newAttr.EdgeType is ASetOfBaseEdgeType)) { RemoveRecentlyAddedTypes(addedTypes); return new Exceptional<QueryResult>(new Error_InvalidEdgeType(newAttr.EdgeType.GetType(), typeof(AListOfBaseEdgeType))); } } #endregion aType.AddAttribute(newAttr, this, true); } #endregion #region Set BackwardEdges if (!aTypeDef.BackwardEdgeNodes.IsNullOrEmpty()) { backwardEdgesToBeAddedAfterwards.Add(aType, aTypeDef.BackwardEdgeNodes); } #endregion } #endregion #region Add the BackwardEdges foreach (var beDefinition in backwardEdgesToBeAddedAfterwards) { var aType = beDefinition.Key; UInt16 beAttrCounter = 0; foreach (var be in beDefinition.Value) { var bedgeAttribute = CreateBackwardEdgeAttribute(be, aType, beAttrCounter); if (!bedgeAttribute.Success()) { RemoveRecentlyAddedTypes(addedTypes); return new Exceptional<QueryResult>(bedgeAttribute); } aType.AddAttribute(bedgeAttribute.Value, this, true); beAttrCounter++; } } #endregion #region Validate Attribute dependencies var _Vertices = new List<Vertex>(); foreach (var _GraphDBType in addedTypes) { foreach (var _GraphDBType2 in GetAllParentTypes(_GraphDBType, false, true)) { var _MandatoryAttributes = _GraphDBType2.GetMandatoryAttributesUUIDs(this); var _UniqueAttributes = _GraphDBType2.GetAllUniqueAttributes(false, this); foreach (var _TypeAttribute in _GraphDBType.Attributes.Values) { if (_GraphDBType2.GetTypeAttributeByName(_TypeAttribute.Name) != null) { // Todo: Use notification here RemoveRecentlyAddedTypes(addedTypes); return new Exceptional<QueryResult>(new Error_AttributeExistsInSupertype(_TypeAttribute.Name, _GraphDBType.Name)); } #region unique and mandatory attributes if (_TypeAttribute.TypeCharacteristics.IsUnique && !_UniqueAttributes.Contains(_TypeAttribute.UUID)) { //if the attrbute has been marked unique and it is not contained in uniques of super types if (!uniqueAttrIDs.Contains(_TypeAttribute.UUID)) { uniqueAttrIDs.Add(_TypeAttribute.UUID); } } if (_TypeAttribute.TypeCharacteristics.IsMandatory && !_MandatoryAttributes.Contains(_TypeAttribute.UUID)) { _GraphDBType.AddMandatoryAttribute(_TypeAttribute.UUID, this); } #endregion } } //Add the unique attribute ids for the current type var AddUniqueAttrExcept = _GraphDBType.AddUniqueAttributes(uniqueAttrIDs, currentContext); if(AddUniqueAttrExcept.Failed()) return new Exceptional<QueryResult>(AddUniqueAttrExcept); uniqueAttrIDs.Clear(); } #endregion #region Create indices foreach (GraphDBType aType in addedTypes) { #region Create userdefined Indices var aTypeDef = TypeList.Where(item => item.Name == aType.Name).FirstOrDefault(); if (!aTypeDef.Indices.IsNullOrEmpty()) { foreach (var index in aTypeDef.Indices) { if (!index.IndexAttributeDefinitions.All(node => !node.IndexAttribute.Validate(currentContext, false, aType).Failed())) { RemoveRecentlyAddedTypes(addedTypes); return new Exceptional<QueryResult>(new Error_AttributeIsNotDefined(aType.Name, aType.Name)); } var idxName = index.IndexName; if (String.IsNullOrEmpty(index.IndexName)) { idxName = index.IndexAttributeDefinitions.Aggregate(new StringBuilder(DBConstants.IndexKeyPrefix), (stringB, elem) => { stringB.Append(String.Concat(DBConstants.IndexKeySeperator, elem.IndexAttribute.LastAttribute.Name)); return stringB; }).ToString(); } List<AttributeUUID> indexAttrs = new List<AttributeUUID>(index.IndexAttributeDefinitions.Select(node => node.IndexAttribute.LastAttribute.UUID)); foreach (var item in GetAllSubtypes(aType)) { var CreateIdxExcept = item.CreateAttributeIndex(currentContext, idxName, indexAttrs, index.Edition, index.IndexType); if (!CreateIdxExcept.Success()) return new Exceptional<QueryResult>(CreateIdxExcept); } } } #endregion //UUID index var createIndexExcept = aType.CreateUUIDIndex(_DBContext, GetUUIDTypeAttribute().UUID); if (!createIndexExcept.Success()) { return new Exceptional<QueryResult>(createIndexExcept); } List<AttributeUUID> UniqueIDs = aType.GetAllUniqueAttributes(true, this); if (UniqueIDs.Count() > 0) { var idxName = _DBContext.DBIndexManager.GetUniqueIndexName(UniqueIDs, aType); // UniqueIDs.Aggregate<AttributeUUID, String>("Idx", (result, item) => result = result + "_" + aType.GetTypeAttributeByUUID(item).Name); var createIdxExcept = aType.CreateUniqueAttributeIndex(currentContext, idxName, UniqueIDs, DBConstants.UNIQUEATTRIBUTESINDEX); if (!createIdxExcept.Success()) return new Exceptional<QueryResult>(createIdxExcept); } } #endregion #region flush to fs foreach (var item in addedTypes) { var createException = CreateTypeOnFS(item); if (!createException.Success()) return new Exceptional<QueryResult>(createException); #region get system attributes from type var readOut = GetVertexForType(item); if (!readOut.Success()) return new Exceptional<QueryResult>(readOut.IErrors.First()); _Vertices.Add(readOut.Value); #endregion } result.Vertices = _Vertices; #endregion } catch (GraphDBException ee) { RemoveRecentlyAddedTypes(addedTypes); var _Exceptional = new Exceptional<QueryResult>(); foreach (var _ex in ee.GraphDBErrors) _Exceptional.PushIError(_ex); return _Exceptional; } catch (GraphDBWarningException ee) { RemoveRecentlyAddedTypes(addedTypes); return new Exceptional<QueryResult>(ee.GraphDBWarning); } catch (Exception e) //finally { //if (!succeeded) //{ addedTypes.ForEach(item => { _UserDefinedTypes.Remove(item.UUID); _TypesNameLookUpTable.Remove(item.Name); }); //} return new Exceptional<QueryResult>(new Error_UnknownDBError(e)); } return new Exceptional<QueryResult>(result); }
private Exceptional<ResultType> AddAttributeToDBObject(GraphDBType myTypeOfDBObject, ObjectUUID myUUID, AttributeUUID myAttributeUUID, IObject myAttributeValue) { //myGraphType is needed due to correctness concerning the attribute name #region Input exceptions if ((myTypeOfDBObject == null) || (myUUID == null) || (myAttributeUUID == null) || (myAttributeValue == null)) { throw new ArgumentNullException(); } #endregion #region Check GraphType for new Attribute TypeAttribute typeAttribute = myTypeOfDBObject.GetTypeAttributeByUUID(myAttributeUUID); if (typeAttribute == null) { //Todo: add notification here (the user has to be informed about the detailed circumstances) GraphDBError aError = new Error_AttributeIsNotDefined(myTypeOfDBObject.Name, myAttributeUUID.ToString()); return new Exceptional<ResultType>(aError); } #endregion #region Data var objectLocation = new ObjectLocation(myTypeOfDBObject.ObjectLocation, DBConstants.DBObjectsLocation, myUUID.ToString()); Exceptional<DBObjectStream> aNewDBObject; Exceptional<ResultType> result = new Exceptional<ResultType>(); #endregion #region add attribute aNewDBObject = _DBContext.DBObjectManager.LoadDBObject(myTypeOfDBObject, myUUID); if (aNewDBObject.Failed()) { result.PushIError(new Error_LoadObject(aNewDBObject.Value.ObjectLocation)); return result; } result = aNewDBObject.Value.AddAttribute(typeAttribute.UUID, myAttributeValue); if (result.Failed()) return result; try { _DBContext.DBObjectManager.FlushDBObject(aNewDBObject.Value); } catch (Exception ex) { result.PushIError(new Error_FlushObject(aNewDBObject.Value.ObjectLocation, ex)); aNewDBObject.Value.RemoveAttribute(typeAttribute.UUID); } #endregion return result; }
public Exceptional<ResultType> RebuildIndex(String myIndexName, String myIndexEdition, GraphDBType myDBTypeStream, IndexSetStrategy myIndexSetStrategy) { var objectLocation = new ObjectLocation(myDBTypeStream.ObjectLocation, DBConstants.DBObjectsLocation); IEnumerable<String> allDBOLocations = null; try { allDBOLocations = _DBContext.DBObjectManager.GetAllStreamsRecursive(objectLocation, DBConstants.DBOBJECTSTREAM); } catch (Exception e) { return new Exceptional<ResultType>(new Error_RebuildIndexFailed(myIndexName, myIndexEdition, e.Message)); } try { var index = myDBTypeStream.GetAttributeIndex(myIndexName, myIndexEdition); index.ClearAndRemoveFromDisc(this); foreach (var loc in allDBOLocations) { var dbo = _DBContext.DBObjectManager.LoadDBObject(new ObjectLocation(myDBTypeStream.ObjectLocation, DBConstants.DBObjectsLocation, _DBContext.DBObjectManager.GetDBObjectStreamShard(myDBTypeStream, new ObjectUUID(loc)), loc)); if (dbo.Failed()) { return new Exceptional<ResultType>(dbo); } if (!dbo.Value.ObjectLocation.Contains(loc)) { //NLOG: temporarily commented ////_Logger.Error("Could not found the correct DBObject for Location " + loc + " the ObjectUUID is now " + dbo.Value.ObjectUUID.ToString()); } else { if (dbo.Value.HasAtLeastOneAttribute(index.IndexKeyDefinition.IndexKeyAttributeUUIDs, myDBTypeStream, null)) { var insertResult = index.Insert(dbo.Value, myIndexSetStrategy, myDBTypeStream, _DBContext); if (!insertResult.Success()) { return new Exceptional<ResultType>(insertResult); } } } } } catch (GraphDBException pe) { var _Exceptional = new Exceptional<ResultType>(); foreach (var _ex in pe.GraphDBErrors) _Exceptional.PushIError(_ex); return _Exceptional; } catch (GraphFSException_IndexKeyAlreadyExist) { //NLOG: temporarily commented ////_Logger.ErrorException("GraphFSException_IndexKeyAlreadyExist", ikae); return new Exceptional<ResultType>(new Error_UniqueConstrainViolation(myDBTypeStream.Name, myIndexName)); } catch { return new Exceptional<ResultType>(new Error_IndexDoesNotExist(myIndexName, myIndexEdition)); } return new Exceptional<ResultType>(ResultType.Successful); }
public Exceptional<ResultType> RebuildIndex(String myIndexName, String myIndexEdition, GraphDBType myDBTypeStream, IndexSetStrategy myIndexSetStrategy) { var objectLocation = new ObjectLocation(myDBTypeStream.ObjectLocation, DBConstants.DBObjectsLocation); var allDBOLocations = _IGraphFSSession.GetFilteredDirectoryListing(objectLocation, null, null, null, new List<String>(new String[] { DBConstants.DBOBJECTSTREAM }), null, null, null, null, null, null); if (allDBOLocations.Failed() && allDBOLocations.IErrors.First().GetType() != typeof(GraphFSError_ObjectLocatorNotFound)) return new Exceptional<ResultType>(allDBOLocations); try { var index = myDBTypeStream.GetAttributeIndex(myIndexName, myIndexEdition); index.ClearAndRemoveFromDisc(this); if (allDBOLocations.Value != null) { foreach (var loc in allDBOLocations.Value) { var dbo = _DBContext.DBObjectManager.LoadDBObject(new ObjectLocation(myDBTypeStream.ObjectLocation, DBConstants.DBObjectsLocation, loc)); if (dbo.Failed()) { return new Exceptional<ResultType>(dbo); } if (!dbo.Value.ObjectLocation.Contains(loc)) { //NLOG: temporarily commented ////_Logger.Error("Could not found the correct DBObject for Location " + loc + " the ObjectUUID is now " + dbo.Value.ObjectUUID.ToString()); } else { if (dbo.Value.HasAtLeastOneAttribute(index.IndexKeyDefinition.IndexKeyAttributeUUIDs, myDBTypeStream, null)) { var insertResult = index.Insert(dbo.Value, myIndexSetStrategy, myDBTypeStream, _DBContext); if (!insertResult.Success()) { return new Exceptional<ResultType>(insertResult); } } } } } } catch (GraphDBException pe) { var _Exceptional = new Exceptional<ResultType>(); foreach (var _ex in pe.GraphDBErrors) _Exceptional.PushIError(_ex); return _Exceptional; } catch (GraphFSException_IndexKeyAlreadyExist) { //NLOG: temporarily commented ////_Logger.ErrorException("GraphFSException_IndexKeyAlreadyExist", ikae); return new Exceptional<ResultType>(new Error_UniqueConstrainViolation(myDBTypeStream.Name, myIndexName)); } catch { return new Exceptional<ResultType>(new Error_IndexDoesNotExist(myIndexName, myIndexEdition)); } return new Exceptional<ResultType>(ResultType.Successful); }
/// <summary> /// Executes the removal of certain myAttributes. /// <seealso cref=" AAlterTypeCommand"/> /// </summary> public override Exceptional Execute(DBContext myDBContext, GraphDBType myGraphDBType) { Exceptional result = new Exceptional(); foreach (String aAttributeName in _ListOfAttributes) { var attr = myGraphDBType.GetTypeAttributeByName(aAttributeName); if (attr != null) { var idxs = new List<Indices.AAttributeIndex>(myGraphDBType.GetAttributeIndices(myDBContext, attr.UUID)); foreach (var item in idxs) { var remIdxResult = myGraphDBType.RemoveIndex(item.IndexName, item.IndexEdition, myDBContext); if (remIdxResult.Failed()) { result.PushIExceptional(remIdxResult); } } } else { result.PushIError(new Error_AttributeIsNotDefined(aAttributeName)); return result; } //Hack: remove myAttributes in DBObjects var aTempResult = myDBContext.DBTypeManager.RemoveAttributeFromType(myGraphDBType.Name, aAttributeName, myDBContext.DBTypeManager); if (aTempResult.Failed()) { result.PushIExceptional(aTempResult); return result; } } return result; }
public override Exceptional<FuncParameter> ExecFunc(DBContext dbContext, params FuncParameter[] myParams) { // The edge we starting of (e.g. Friends) var typeAttribute = CallingAttribute; // The destination DBObjects, they are of the type "typeAttribute.RelatedDBType" var destDBOs = (myParams[0].Value as DBEdge).GetDBObjects(); byte maxDepth = Convert.ToByte((myParams[1].Value as DBInt64).GetValue()); byte maxPathLength = Convert.ToByte((myParams[2].Value as DBInt64).GetValue()); //check if values incorrect if (maxDepth < 1 && maxPathLength < 2) { Exceptional<FuncParameter> errorResult = new Exceptional<FuncParameter>(); IError error = new Error_InvalidFunctionParameter("maxDepth", ">= 1", maxDepth); errorResult.PushIError(error); error = new Error_InvalidFunctionParameter("maxPathLength", ">= 2", maxPathLength); errorResult.PushIError(error); return errorResult; } else if (maxDepth < 1) { return new Exceptional<FuncParameter>(new Error_InvalidFunctionParameter("maxDepth", ">= 1", maxDepth)); } else if (maxPathLength < 2) { return new Exceptional<FuncParameter>(new Error_InvalidFunctionParameter("maxPathLength", ">= 2", maxPathLength)); } bool onlyShortestPath = (myParams[3].Value as DBBoolean).GetValue(); bool allPaths = (myParams[4].Value as DBBoolean).GetValue(); if (!onlyShortestPath && !allPaths) { allPaths = true; } #region Call graph function if (destDBOs.Count() != 1) throw new GraphDBException(new Error_NotImplemented(new StackTrace(true))); var dbObject = destDBOs.First(); if (dbObject.Failed()) { throw new GraphDBException(dbObject.IErrors); } HashSet<List<ObjectUUID>> paths; if (onlyShortestPath && allPaths) //use bi-directional search for "all shortest paths" { //normal BFS //paths = new BreadthFirstSearch().Find(typeAttribute, typeManager, cache, mySourceDBObject, dbObject, onlyShortestPath, allPaths, maxDepth, maxPathLength); //bidirectional BFS paths = new BidirectionalBFS().Find(typeAttribute, dbContext, CallingDBObjectStream as DBObjectStream, CallingObject as IReferenceEdge, dbObject.Value, onlyShortestPath, allPaths, maxDepth, maxPathLength); } else //use uni-directional search for "shortest path and all paths up to given depth" { //normal BFS //paths = new BreadthFirstSearch().Find(typeAttribute, dbContext.DBTypeManager, dbContext.DBObjectCache, CallingDBObjectStream as DBObjectStream, dbObject.Value, onlyShortestPath, allPaths, maxDepth, maxPathLength); //bidirectional BFS paths = new BidirectionalBFS().Find(typeAttribute, dbContext, CallingDBObjectStream as DBObjectStream, CallingObject as IReferenceEdge, dbObject.Value, onlyShortestPath, allPaths, maxDepth, maxPathLength); } //This variable will be returned Exceptional<FuncParameter> pResult = new Exceptional<FuncParameter>(); if (paths != null) { pResult.Value = new FuncParameter(new EdgeTypePath(paths, typeAttribute, typeAttribute.GetDBType(dbContext.DBTypeManager)), typeAttribute); } else { return new Exceptional<FuncParameter>(new FuncParameter(new EdgeTypePath(new HashSet<List<ObjectUUID>>(), typeAttribute, typeAttribute.GetDBType(dbContext.DBTypeManager)), typeAttribute)); } #endregion return pResult; }