public IIndexDefinition CreateIndex(IndexPredefinition myIndexDefinition, SecurityToken mySecurity, Int64 myTransaction, bool myIsUserDefined = true) { myIndexDefinition.CheckNull("myIndexDefinition"); if (myIndexDefinition.Name != null && myIndexDefinition.Name.StartsWith("sones")) { throw new Exception("It is not allowed to add an index with a name, that starts with 'sones'."); } var vertexType = _vertexTypeManager.ExecuteManager.GetType(myIndexDefinition.VertexTypeName, myTransaction, mySecurity); var indexName = myIndexDefinition.Name ?? CreateIndexName(myIndexDefinition, vertexType); if (_ownIndex.ContainsKey(indexName)) { //TODO a better exception here. throw new Exception("An index with that name already exists."); } if (myIndexDefinition.Properties == null) { throw new Exception("Index without properties is not allowed."); } foreach (var prop in myIndexDefinition.Properties) { var propDef = vertexType.GetPropertyDefinition(prop); if (!vertexType.HasProperty(prop) || (propDef.RelatedType.ID != vertexType.ID && !HasIndex(propDef, mySecurity, myTransaction))) { //TODO a better exception here. throw new AttributeDoesNotExistException("The property is not defined on the vertex type " + vertexType.Name + ", it is defined on a parent type."); } } var indexID = _idManager.GetVertexTypeUniqeID((long)BaseTypes.Index).GetNextID(); var info = new VertexInformation((long)BaseTypes.Index, indexID, 0, myIndexDefinition.Edition); var typeClass = myIndexDefinition.TypeName ?? GetBestMatchingIndexName(false, false); var parameter = (_indexPluginParameter.ContainsKey(typeClass)) ? _indexPluginParameter[typeClass].PluginParameter : new Dictionary <string, object>(); var options = ValidateOptions(myIndexDefinition.IndexOptions, typeClass); // load propertyIDs for indexed properties var propertyIDs = myIndexDefinition.Properties.Select(prop => vertexType.GetPropertyDefinition(prop).ID).ToList(); // add propertyIDs for indexing parameter.Add(IndexConstants.PROPERTY_IDS_OPTIONS_KEY, propertyIDs); parameter = FillOptions(parameter, options); // HACK: manually inject eventuall existing PersistenceLocation (btk, 23.09.2011) #region Hack if (_applicationSettings.Get <PersistenceLocation>() != null) { // if not already, initialize if (parameter == null) { parameter = new Dictionary <string, object>(); } if (!parameter.ContainsKey("Path")) // only add when not already in there... { parameter.Add("Path", _applicationSettings.Get <PersistenceLocation>()); } } #endregion var index = _pluginManager.GetAndInitializePlugin <ISonesIndex>(typeClass, parameter, indexID); var props = myIndexDefinition.Properties.Select(prop => new VertexInformation((long)BaseTypes.Property, vertexType.GetPropertyDefinition(prop).ID)).ToList(); var date = DateTime.UtcNow.ToBinary(); var indexVertex = _baseStorageManager.StoreIndex( _vertexStore, info, indexName, myIndexDefinition.Comment, date, myIndexDefinition.TypeName, //GetIsSingleValue(index), GetIsRangeValue(index), GetIsVersionedValue(index), true, myIndexDefinition.IndexOptions, new VertexInformation((long)BaseTypes.VertexType, vertexType.ID), null, props, mySecurity, myTransaction); _ownIndex.Add(indexName, indexID); _indices.Add(indexID, index); foreach (var childType in vertexType.GetDescendantVertexTypes()) { var childID = _idManager.GetVertexTypeUniqeID((long)BaseTypes.Index).GetNextID(); var childName = CreateIndexName(myIndexDefinition, childType); var childIndex = _pluginManager.GetAndInitializePlugin <ISonesIndex>(typeClass, parameter, childID); _baseStorageManager.StoreIndex( _vertexStore, new VertexInformation((long)BaseTypes.Index, childID), childName, indexName, //we store the source index name as comment date, myIndexDefinition.TypeName, //GetIsSingleValue(index), GetIsRangeValue(index), GetIsVersionedValue(index), false, myIndexDefinition.IndexOptions, new VertexInformation((long)BaseTypes.VertexType, childType.ID), info, props, mySecurity, myTransaction); _ownIndex.Add(childName, childID); _indices.Add(childID, childIndex); } var indexDefinition = _baseStorageManager.CreateIndexDefinition(indexVertex, vertexType); _vertexTypeManager.ExecuteManager.CleanUpTypes(); var reloadedVertexType = _vertexTypeManager.ExecuteManager.GetType(vertexType.Name, myTransaction, mySecurity); foreach (var type in reloadedVertexType.GetDescendantVertexTypesAndSelf()) { RebuildIndices(type, myTransaction, mySecurity); } return(indexDefinition); }