Exemple #1
0
        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);
        }