Пример #1
0
        public void DeleteIndex(string name)
        {
            using (IndexDefinitionStorage.TryRemoveIndexContext())
            {
                var instance = IndexDefinitionStorage.GetIndexDefinition(name);
                if (instance == null)
                {
                    return;
                }

                // Set up a flag to signal that this is something we're doing
                TransactionalStorage.Batch(actions => actions.Lists.Set("Raven/Indexes/PendingDeletion", instance.IndexId.ToString(CultureInfo.InvariantCulture), (RavenJObject.FromObject(new
                {
                    TimeOfOriginalDeletion = SystemTime.UtcNow,
                    instance.IndexId,
                    IndexName = instance.Name
                })), UuidType.Tasks));

                // Delete the main record synchronously
                IndexDefinitionStorage.RemoveIndex(name);
                Database.IndexStorage.DeleteIndex(instance.IndexId);

                WorkContext.ClearErrorsFor(name);

                // And delete the data in the background
                StartDeletingIndexDataAsync(instance.IndexId, name);

                // We raise the notification now because as far as we're concerned it is done *now*
                TransactionalStorage.ExecuteImmediatelyOrRegisterForSynchronization(() => Database.Notifications.RaiseNotifications(new IndexChangeNotification
                {
                    Name = name,
                    Type = IndexChangeTypes.IndexRemoved,
                }));
            }
        }
Пример #2
0
        internal void DeleteIndex(IndexDefinition instance, bool removeByNameMapping = true,
                                  bool clearErrors = true, bool removeIndexReplaceDocument = true, bool isSideBySideReplacement = false)
        {
            using (IndexDefinitionStorage.TryRemoveIndexContext())
            {
                if (instance == null)
                {
                    return;
                }

                // Set up a flag to signal that this is something we're doing
                TransactionalStorage.Batch(actions => actions.Lists.Set("Raven/Indexes/PendingDeletion", instance.IndexId.ToString(CultureInfo.InvariantCulture), (RavenJObject.FromObject(new
                {
                    TimeOfOriginalDeletion = SystemTime.UtcNow,
                    instance.IndexId,
                    IndexName = instance.Name,
                    instance.IndexVersion
                })), UuidType.Tasks));

                // Delete the main record synchronously
                IndexDefinitionStorage.RemoveIndex(instance.IndexId, removeByNameMapping);
                Database.IndexStorage.DeleteIndex(instance.IndexId);

                if (clearErrors)
                {
                    WorkContext.ClearErrorsFor(instance.Name);
                }

                var isSideBySide = instance.IsSideBySideIndex ||
                                   instance.Name.StartsWith(Constants.SideBySideIndexNamePrefix, StringComparison.OrdinalIgnoreCase);
                if (removeIndexReplaceDocument && isSideBySide)
                {
                    Database.Documents.Delete(Constants.IndexReplacePrefix + instance.Name, null, null);
                }

                Database.IndexStorage.DeleteSuggestionsData(instance.Name);

                //remove the header information in a sync process
                TransactionalStorage.Batch(actions => actions.Indexing.PrepareIndexForDeletion(instance.IndexId));
                //and delete the data in the background
                Database.Maintenance.StartDeletingIndexDataAsync(instance.IndexId, instance.Name);

                var indexChangeType = isSideBySideReplacement ? IndexChangeTypes.SideBySideReplace : IndexChangeTypes.IndexRemoved;

                // We raise the notification now because as far as we're concerned it is done *now*
                TransactionalStorage.ExecuteImmediatelyOrRegisterForSynchronization(() =>
                                                                                    Database.Notifications.RaiseNotifications(new IndexChangeNotification
                {
                    Name    = instance.Name,
                    Type    = indexChangeType,
                    Version = instance.IndexVersion
                })
                                                                                    );
            }
        }
Пример #3
0
        public string[] PutIndexes(string[] names, IndexDefinition[] definitions, IndexingPriority[] priorities)
        {
            var createdIndexes = new List <string>();
            var prioritiesList = new List <IndexingPriority>();

            try
            {
                for (int i = 0; i < names.Length; i++)
                {
                    var name       = names[i];
                    var definition = definitions[i];
                    var priority   = priorities[i];
                    if (name == null)
                    {
                        throw new ArgumentNullException("names", "Names cannot contain null values");
                    }

                    IsIndexNameValid(name);

                    var existingIndex = IndexDefinitionStorage.GetIndexDefinition(name);

                    if (existingIndex != null)
                    {
                        switch (existingIndex.LockMode)
                        {
                        case IndexLockMode.SideBySide:
                            Log.Info("Index {0} not saved because it might be only updated by side-by-side index");
                            throw new InvalidOperationException("Can not overwrite locked index: " + name + ". This index can be only updated by side-by-side index.");

                        case IndexLockMode.LockedIgnore:
                            Log.Info("Index {0} not saved because it was lock (with ignore)", name);
                            continue;

                        case IndexLockMode.LockedError:
                            throw new InvalidOperationException("Can not overwrite locked index: " + name);
                        }
                    }

                    name = name.Trim();

                    if (name.Equals("dynamic", StringComparison.OrdinalIgnoreCase) ||
                        name.StartsWith("dynamic/", StringComparison.OrdinalIgnoreCase))
                    {
                        throw new ArgumentException("Cannot use index name " + name + " because it clashes with reserved dynamic index names", "name");
                    }

                    if (name.Contains("//"))
                    {
                        throw new ArgumentException("Cannot use an index with // in the name, but got: " + name, "name");
                    }

                    AssertAnalyzersValid(definition);

                    switch (FindIndexCreationOptions(definition, ref name))
                    {
                    case IndexCreationOptions.Noop:
                        continue;

                    case IndexCreationOptions.UpdateWithoutUpdatingCompiledIndex:
                        // ensure that the code can compile
                        new DynamicViewCompiler(definition.Name, definition, Database.Extensions, IndexDefinitionStorage.IndexDefinitionsPath, Database.Configuration).GenerateInstance();
                        IndexDefinitionStorage.UpdateIndexDefinitionWithoutUpdatingCompiledIndex(definition);
                        break;

                    case IndexCreationOptions.Update:
                        // ensure that the code can compile
                        new DynamicViewCompiler(definition.Name, definition, Database.Extensions, IndexDefinitionStorage.IndexDefinitionsPath, Database.Configuration).GenerateInstance();
                        DeleteIndex(name);
                        break;
                    }

                    PutNewIndexIntoStorage(name, definition, true);

                    WorkContext.ClearErrorsFor(name);

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

                    createdIndexes.Add(name);
                    prioritiesList.Add(priority);
                }

                var indexesIds = createdIndexes.Select(x => Database.IndexStorage.GetIndexInstance(x).indexId).ToArray();
                Database.TransactionalStorage.Batch(accessor => accessor.Indexing.SetIndexesPriority(indexesIds, prioritiesList.ToArray()));

                return(createdIndexes.ToArray());
            }
            catch (Exception e)
            {
                Log.WarnException("Could not create index batch", e);
                foreach (var index in createdIndexes)
                {
                    DeleteIndex(index);
                }
                throw;
            }
        }
Пример #4
0
        public string PutIndex(string name, IndexDefinition definition)
        {
            if (name == null)
            {
                throw new ArgumentNullException("name");
            }

            IsIndexNameValid(name);

            var existingIndex = IndexDefinitionStorage.GetIndexDefinition(name);

            if (existingIndex != null)
            {
                switch (existingIndex.LockMode)
                {
                case IndexLockMode.SideBySide:
                    Log.Info("Index {0} not saved because it might be only updated by side-by-side index");
                    throw new InvalidOperationException("Can not overwrite locked index: " + name + ". This index can be only updated by side-by-side index.");

                case IndexLockMode.LockedIgnore:
                    Log.Info("Index {0} not saved because it was lock (with ignore)", name);
                    return(name);

                case IndexLockMode.LockedError:
                    throw new InvalidOperationException("Can not overwrite locked index: " + name);
                }
            }

            name = name.Trim();

            if (name.Equals("dynamic", StringComparison.OrdinalIgnoreCase) ||
                name.StartsWith("dynamic/", StringComparison.OrdinalIgnoreCase))
            {
                throw new ArgumentException("Cannot use index name " + name + " because it clashes with reserved dynamic index names", "name");
            }

            if (name.Contains("//"))
            {
                throw new ArgumentException("Cannot use an index with // in the name, but got: " + name, "name");
            }

            AssertAnalyzersValid(definition);

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

            case IndexCreationOptions.UpdateWithoutUpdatingCompiledIndex:
                // ensure that the code can compile
                new DynamicViewCompiler(definition.Name, definition, Database.Extensions, IndexDefinitionStorage.IndexDefinitionsPath, Database.Configuration).GenerateInstance();
                IndexDefinitionStorage.UpdateIndexDefinitionWithoutUpdatingCompiledIndex(definition);
                return(name);

            case IndexCreationOptions.Update:
                // ensure that the code can compile
                new DynamicViewCompiler(definition.Name, definition, Database.Extensions, IndexDefinitionStorage.IndexDefinitionsPath, Database.Configuration).GenerateInstance();
                DeleteIndex(name);
                break;
            }

            PutNewIndexIntoStorage(name, definition);

            WorkContext.ClearErrorsFor(name);

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

            return(name);
        }
Пример #5
0
        private string PutIndexInternal(string name, IndexDefinition definition, bool disableIndexBeforePut = false, bool isUpdateBySideSide = false, IndexCreationOptions?creationOptions = null)
        {
            if (name == null)
            {
                throw new ArgumentNullException("name");
            }

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

            var existingIndex = IndexDefinitionStorage.GetIndexDefinition(name);

            if (existingIndex != null)
            {
                switch (existingIndex.LockMode)
                {
                case IndexLockMode.SideBySide:
                    if (isUpdateBySideSide == false)
                    {
                        Log.Info("Index {0} not saved because it might be only updated by side-by-side index");
                        throw new InvalidOperationException("Can not overwrite locked index: " + name + ". This index can be only updated by side-by-side index.");
                    }
                    break;

                case IndexLockMode.LockedIgnore:
                    Log.Info("Index {0} not saved because it was lock (with ignore)", name);
                    return(null);

                case IndexLockMode.LockedError:
                    throw new InvalidOperationException("Can not overwrite locked index: " + name);
                }
            }

            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);
                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);
                break;
            }

            PutNewIndexIntoStorage(name, definition, disableIndexBeforePut);

            WorkContext.ClearErrorsFor(name);

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

            return(name);
        }
Пример #6
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);
        }