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