Exemple #1
0
        private string PutIndexInternal(string name, IndexDefinition definition, bool disableIndexBeforePut = false,
                                        bool isUpdateBySideSide = false, IndexCreationOptions?creationOptions = null, bool isReplication = false)
        {
            if (name == null)
            {
                throw new ArgumentNullException(nameof(name));
            }

            name = name.Trim();
            IsIndexNameValid(name);

            var existingIndex = IndexDefinitionStorage.GetIndexDefinition(name);

            if (existingIndex != null)
            {
                var newIndexVersion     = definition.IndexVersion;
                var currentIndexVersion = existingIndex.IndexVersion;

                // whether we update the index definition or not,
                // we need to update the index version
                existingIndex.IndexVersion = definition.IndexVersion =
                    Math.Max(currentIndexVersion ?? 0, newIndexVersion ?? 0);

                switch (isReplication)
                {
                case true:
                    if (newIndexVersion != null && currentIndexVersion != null &&
                        newIndexVersion <= currentIndexVersion)
                    {
                        //this new index is an older version of the current one
                        return(null);
                    }

                    // we need to update the lock mode only if it was updated by another server
                    existingIndex.LockMode = definition.LockMode;
                    break;

                default:
                    if (CanUpdateIndex(name, definition, isUpdateBySideSide, existingIndex) == false)
                    {
                        return(null);
                    }
                    break;
                }
            }

            AssertAnalyzersValid(definition);

            switch (creationOptions ?? FindIndexCreationOptions(definition, ref name))
            {
            case IndexCreationOptions.Noop:
                return(null);

            case IndexCreationOptions.UpdateWithoutUpdatingCompiledIndex:
                // ensure that the code can compile
                new DynamicViewCompiler(definition.Name, definition, Database.Extensions, IndexDefinitionStorage.IndexDefinitionsPath, Database.Configuration).GenerateInstance();
                IndexDefinitionStorage.UpdateIndexDefinitionWithoutUpdatingCompiledIndex(definition);
                if (isReplication == false)
                {
                    definition.IndexVersion = (definition.IndexVersion ?? 0) + 1;
                }
                return(null);

            case IndexCreationOptions.Update:
                // ensure that the code can compile
                new DynamicViewCompiler(definition.Name, definition, Database.Extensions, IndexDefinitionStorage.IndexDefinitionsPath, Database.Configuration).GenerateInstance();
                DeleteIndex(name);
                if (isReplication == false)
                {
                    definition.IndexVersion = (definition.IndexVersion ?? 0) + 1;
                }
                break;

            case IndexCreationOptions.Create:
                if (isReplication == false)
                {
                    // we create a new index,
                    // we need to restore its previous IndexVersion (if it was deleted before)
                    var deletedIndexVersion   = IndexDefinitionStorage.GetDeletedIndexVersion(definition);
                    var replacingIndexVersion = GetOriginalIndexVersion(definition.Name);
                    definition.IndexVersion = Math.Max(deletedIndexVersion, replacingIndexVersion);
                    definition.IndexVersion++;
                }

                break;
            }

            PutNewIndexIntoStorage(name, definition, disableIndexBeforePut);

            WorkContext.ClearErrorsFor(name);

            TransactionalStorage.ExecuteImmediatelyOrRegisterForSynchronization(() => Database.Notifications.RaiseNotifications(new IndexChangeNotification
            {
                Name    = name,
                Type    = IndexChangeTypes.IndexAdded,
                Version = definition.IndexVersion
            }));

            return(name);
        }