/// <summary> /// Checks if the attribute names on vertex type definitions are unique, containing parent myAttributes. /// </summary> /// <param name="myTopologicallySortedPointer">A pointer to a vertex type predefinitions in a topologically sorted linked list.</param> /// <param name="myAttributes">A dictionary vertex type name to attribute names, that is build up during the process of CanAddCheckWithFS.</param> /// <param name="myTransaction">A transaction token for this operation.</param> /// <param name="mySecurity">A security token for this operation.</param> private void CanAddCheckAttributeNameUniquenessWithFS(LinkedListNode<VertexTypePredefinition> myTopologicallySortedPointer, IDictionary<string, HashSet<string>> myAttributes, TransactionToken myTransaction, SecurityToken mySecurity) { var parentPredef = GetParentPredefinitionOnTopologicallySortedList(myTopologicallySortedPointer); if (parentPredef == null) { //Get the parent type from FS. var parent = Get(myTopologicallySortedPointer.Value.SuperVertexTypeName, myTransaction, mySecurity); if (parent == null) //No parent type was found. throw new InvalidBaseVertexTypeException(myTopologicallySortedPointer.Value.SuperVertexTypeName); if (parent.GetProperty<bool>((long)AttributeDefinitions.BaseTypeDotIsSealed)) //The parent type is sealed. throw new SealedBaseVertexTypeException(myTopologicallySortedPointer.Value.VertexTypeName, parent.GetPropertyAsString((long)AttributeDefinitions.AttributeDotName)); var parentType = new VertexType(parent); var attributeNames = parentType.GetAttributeDefinitions(true).Select(_=>_.Name); myAttributes[myTopologicallySortedPointer.Value.VertexTypeName] = new HashSet<string>(attributeNames); } else { myAttributes[myTopologicallySortedPointer.Value.VertexTypeName] = new HashSet<string>(myAttributes[parentPredef.Value.VertexTypeName]); } var attributeNamesSet = myAttributes[myTopologicallySortedPointer.Value.VertexTypeName]; CheckIncomingEdgesUniqueName(myTopologicallySortedPointer.Value, attributeNamesSet); CheckOutgoingEdgesUniqueName(myTopologicallySortedPointer.Value, attributeNamesSet); CheckPropertiesUniqueName(myTopologicallySortedPointer.Value, attributeNamesSet); }
private IEnumerable<IVertexType> Add(IEnumerable<VertexTypePredefinition> myVertexTypeDefinitions, TransactionToken myTransaction, SecurityToken mySecurity) { //Perf: count is necessary, fast if it is an ICollection var count = myVertexTypeDefinitions.Count(); //This operation reserves #count ids for this operation. var firstTypeID = _idManager.VertexTypeID.ReserveIDs(count); //Contains dictionary of vertex name to vertex predefinition. var defsByVertexName = CanAddCheckDuplicates(myVertexTypeDefinitions); //Contains dictionary of parent vertex name to list of vertex predefinitions. var defsByParentVertexName = myVertexTypeDefinitions .GroupBy(def => def.SuperVertexTypeName) .ToDictionary(group => group.Key, group => group.AsEnumerable()); //Contains list of vertex predefinitions sorted topologically. var defsTopologically = CanAddSortTopolocically(defsByVertexName, defsByParentVertexName); CanAddCheckWithFS(defsTopologically, defsByVertexName, myTransaction, mySecurity); var typeInfos = GenerateTypeInfos(defsTopologically, defsByVertexName, firstTypeID, myTransaction, mySecurity); //we can add each type separately var creationDate = DateTime.UtcNow.ToBinary(); var resultPos = 0; var result = new IVertex[count]; //now we store each vertex type for (var current = defsTopologically.First; current != null; current = current.Next) { var newVertexType = BaseGraphStorageManager.StoreVertexType( _vertexManager.ExecuteManager.VertexStore, typeInfos[current.Value.VertexTypeName].VertexInfo, current.Value.VertexTypeName, current.Value.Comment, creationDate, current.Value.IsAbstract, current.Value.IsSealed, true, typeInfos[current.Value.SuperVertexTypeName].VertexInfo, null, mySecurity, myTransaction); result[resultPos++] = newVertexType; _indexManager.GetIndex(BaseUniqueIndex.VertexTypeDotName).Add(current.Value.VertexTypeName, typeInfos[current.Value.VertexTypeName].VertexInfo.VertexID); _nameIndex.Add(current.Value.VertexTypeName, typeInfos[current.Value.VertexTypeName].VertexInfo.VertexID); } #region Store Attributes //The order of adds is important. First property, then outgoing edges (that might point to properties) and finally incoming edges (that might point to outgoing edges) //Do not try to merge it into one for block. #region Store properties for (var current = defsTopologically.First; current != null; current = current.Next) { if (current.Value.Properties == null) continue; var firstAttrID = _idManager[(long)BaseTypes.Attribute].ReserveIDs(current.Value.PropertyCount); var currentExternID = typeInfos[current.Value.VertexTypeName].AttributeCountWithParents - current.Value.PropertyCount - 1; foreach (var prop in current.Value.Properties) { BaseGraphStorageManager.StoreProperty( _vertexManager.ExecuteManager.VertexStore, new VertexInformation((long)BaseTypes.Property, firstAttrID++), prop.AttributeName, prop.Comment, creationDate, prop.IsMandatory, prop.Multiplicity, prop.DefaultValue, true, typeInfos[current.Value.VertexTypeName].VertexInfo, ConvertBasicType(prop.AttributeType), mySecurity, myTransaction); } } #endregion #region Store binary properties for (var current = defsTopologically.First; current != null; current = current.Next) { if (current.Value.BinaryProperties == null) continue; var firstAttrID = _idManager[(long)BaseTypes.Attribute].ReserveIDs(current.Value.BinaryPropertyCount); var currentExternID = typeInfos[current.Value.VertexTypeName].AttributeCountWithParents - current.Value.PropertyCount - current.Value.BinaryPropertyCount - 1; foreach (var prop in current.Value.BinaryProperties) { BaseGraphStorageManager.StoreBinaryProperty( _vertexManager.ExecuteManager.VertexStore, new VertexInformation((long)BaseTypes.BinaryProperty, firstAttrID++), prop.AttributeName, prop.Comment, true, creationDate, typeInfos[current.Value.VertexTypeName].VertexInfo, mySecurity, myTransaction); } } #endregion #region Store outgoing edges for (var current = defsTopologically.First; current != null; current = current.Next) { if (current.Value.OutgoingEdges == null) continue; var firstAttrID = _idManager[(long)BaseTypes.Attribute].ReserveIDs(current.Value.OutgoingEdgeCount); var currentExternID = typeInfos[current.Value.VertexTypeName].AttributeCountWithParents - current.Value.PropertyCount - current.Value.OutgoingEdgeCount - current.Value.BinaryPropertyCount - 1; foreach (var edge in current.Value.OutgoingEdges) { VertexInformation? innerEdgeType = null; if (edge.Multiplicity == EdgeMultiplicity.MultiEdge) { innerEdgeType = new VertexInformation((long)BaseTypes.EdgeType, _edgeManager.ExecuteManager.GetEdgeType(edge.InnerEdgeType, myTransaction, mySecurity).ID); } BaseGraphStorageManager.StoreOutgoingEdge( _vertexManager.ExecuteManager.VertexStore, new VertexInformation((long)BaseTypes.OutgoingEdge, firstAttrID++), edge.AttributeName, edge.Comment, true, creationDate, edge.Multiplicity, typeInfos[current.Value.VertexTypeName].VertexInfo, new VertexInformation((long)BaseTypes.EdgeType, _edgeManager.ExecuteManager.GetEdgeType(edge.EdgeType, myTransaction, mySecurity).ID), innerEdgeType, typeInfos[edge.AttributeType].VertexInfo, mySecurity, myTransaction); } } #endregion #region Store incoming edges for (var current = defsTopologically.First; current != null; current = current.Next) { if (current.Value.IncomingEdges == null) continue; var firstAttrID = _idManager[(long)BaseTypes.Attribute].ReserveIDs(current.Value.IncomingEdgeCount); var currentExternID = typeInfos[current.Value.VertexTypeName].AttributeCountWithParents - current.Value.PropertyCount - current.Value.BinaryPropertyCount - current.Value.OutgoingEdgeCount - current.Value.IncomingEdgeCount - 1; foreach (var edge in current.Value.IncomingEdges) { BaseGraphStorageManager.StoreIncomingEdge( _vertexManager.ExecuteManager.VertexStore, new VertexInformation((long)BaseTypes.IncomingEdge, firstAttrID++), edge.AttributeName, edge.Comment, true, creationDate, typeInfos[current.Value.VertexTypeName].VertexInfo, GetOutgoingEdgeVertexInformation(GetTargetVertexTypeFromAttributeType(edge.AttributeType), GetTargetEdgeNameFromAttributeType(edge.AttributeType), myTransaction, mySecurity), mySecurity, myTransaction); } } #endregion var resultTypes = new VertexType[result.Length]; //reload the IVertex objects, that represents the type. for (int i = 0; i < result.Length; i++) { result[i] = _vertexManager.ExecuteManager.VertexStore.GetVertex(mySecurity, myTransaction, result[i].VertexID, result[i].VertexTypeID, String.Empty); var newVertexType = new VertexType(result[i]); resultTypes[i] = newVertexType; _baseTypes.Add(typeInfos[newVertexType.Name].VertexInfo.VertexID, newVertexType); } #endregion #region Add Indices if (_indexManager != null) { var uniqueIdx = _indexManager.GetBestMatchingIndexName(true, false, false); var indexIdx = _indexManager.GetBestMatchingIndexName(false, false, false); resultPos = 0; for (var current = defsTopologically.First; current != null; current = current.Next, resultPos++) { #region Uniqueness #region own uniques if (current.Value.Uniques != null) { var indexPredefs = current.Value.Uniques.Select(unique => new IndexPredefinition().AddProperty(unique.Properties).SetIndexType(uniqueIdx).SetVertexType(current.Value.VertexTypeName)); var indexDefs = indexPredefs.Select(indexPredef => _indexManager.CreateIndex(indexPredef, mySecurity, myTransaction, false)).ToArray(); //only own unique indices are connected to the vertex type on the UniquenessDefinitions attribute ConnectVertexToUniqueIndex(typeInfos[current.Value.VertexTypeName], indexDefs, mySecurity, myTransaction); } #endregion #region parent uniques foreach (var unique in resultTypes[resultPos].ParentVertexType.GetUniqueDefinitions(true)) { _indexManager.CreateIndex( new IndexPredefinition().AddProperty(unique.UniquePropertyDefinitions.Select(x => x.Name)).SetIndexType(uniqueIdx).SetVertexType(unique.DefiningVertexType.Name), mySecurity, myTransaction, false); } #endregion #endregion #region Indices if (current.Value.Indices != null) foreach (var index in current.Value.Indices) { _indexManager.CreateIndex(index, mySecurity, myTransaction); } foreach (var index in resultTypes[resultPos].ParentVertexType.GetIndexDefinitions(true)) { _indexManager.CreateIndex( new IndexPredefinition().AddProperty(index.IndexedProperties.Select(x => x.Name)).SetVertexType(current.Value.VertexTypeName).SetIndexType(index.IndexTypeName), mySecurity, myTransaction); } #endregion } } #endregion CleanUpTypes(); return resultTypes; }
public override IVertexType GetVertexType(long myTypeId, TransactionToken myTransaction, SecurityToken mySecurity) { #region get static types if (_baseTypes.ContainsKey(myTypeId)) { return _baseTypes[myTypeId]; } #endregion #region get from fs var vertex = Get(myTypeId, myTransaction, mySecurity); if (vertex == null) throw new KeyNotFoundException(string.Format("A vertex type with ID {0} was not found.", myTypeId)); var result = new VertexType(vertex); _baseTypes.Add(result.ID, result); _nameIndex.Add(result.Name, result.ID); return result; #endregion }
public override IVertexType GetVertexType(string myTypeName, TransactionToken myTransaction, SecurityToken mySecurity) { if (String.IsNullOrWhiteSpace(myTypeName)) throw new ArgumentOutOfRangeException("myTypeName", "The type name must contain at least one character."); #region get static types if (_nameIndex.ContainsKey(myTypeName)) { return _baseTypes[_nameIndex[myTypeName]]; } #endregion #region get from fs var vertex = Get(myTypeName, myTransaction, mySecurity); if (vertex == null) throw new KeyNotFoundException(string.Format("A vertex type with name {0} was not found.", myTypeName)); var result = new VertexType(vertex); _baseTypes.Add(result.ID, result); _nameIndex.Add(result.Name, result.ID); return result; #endregion }
private Dictionary<String, TypeInfo> GenerateTypeInfos( LinkedList<VertexTypePredefinition> myDefsSortedTopologically, IDictionary<string, VertexTypePredefinition> myDefsByName, long myFirstID, TransactionToken myTransaction, SecurityToken mySecurity) { var neededVertexTypes = new HashSet<string>(); foreach (var def in myDefsByName) { neededVertexTypes.Add(def.Value.VertexTypeName); neededVertexTypes.Add(def.Value.SuperVertexTypeName); if (def.Value.OutgoingEdges != null) foreach (var edge in def.Value.OutgoingEdges) { neededVertexTypes.Add(edge.AttributeType); } } //At most all vertex types are needed. var result = new Dictionary<String, TypeInfo>((int)myFirstID + myDefsByName.Count); foreach (var vertexType in neededVertexTypes) { if (myDefsByName.ContainsKey(vertexType)) { result.Add(vertexType, new TypeInfo { AttributeCountWithParents = myDefsByName[vertexType].AttributeCount, VertexInfo = new VertexInformation((long)BaseTypes.VertexType, myFirstID++) }); } else { var vertex = _vertexManager.ExecuteManager.GetSingleVertex(new BinaryExpression(new SingleLiteralExpression(vertexType), BinaryOperator.Equals, _vertexTypeNameExpression), myTransaction, mySecurity); IVertexType neededVertexType = new VertexType(vertex); result.Add(vertexType, new TypeInfo { AttributeCountWithParents = neededVertexType.GetAttributeDefinitions(true).LongCount(), VertexInfo = new VertexInformation((long)BaseTypes.VertexType, BaseGraphStorageManager.GetUUID(vertex)) }); } } //accumulate attribute counts for (var current = myDefsSortedTopologically.First; current != null; current = current.Next) { if (!result.ContainsKey(current.Value.VertexTypeName)) continue; var info = result[current.Value.VertexTypeName]; info.AttributeCountWithParents = info.AttributeCountWithParents + result[current.Value.SuperVertexTypeName].AttributeCountWithParents; result[current.Value.VertexTypeName] = info; } return result; }