public async Task CreateTextIndexWithOptionAsync()
        {
            // Arrange
            string expectedIndexName = $"{Guid.NewGuid()}";
            var    option            = new IndexCreationOptions
            {
                Name = expectedIndexName
            };
            await textIndexSemaphore.WaitAsync();

            try
            {
                // Act
                var result = await SUT.CreateTextIndexAsync <T, TKey>(x => x.Version, option, PartitionKey);

                // Assert
                var listOfIndexNames = await SUT.GetIndexesNamesAsync <T, TKey>(PartitionKey);

                Assert.Contains(expectedIndexName, listOfIndexNames);

                // Cleanup
                await SUT.DropIndexAsync <T, TKey>(expectedIndexName, PartitionKey);
            }
            finally
            {
                textIndexSemaphore.Release();
            }
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Creates an index with the specified name on the specified table
        /// </summary>
        /// <param name="name"></param>
        /// <param name="table"></param>
        /// <param name="cols"></param>
        /// <param name="options"></param>
        /// <param name="where"></param>
        public void CreateIndex(string name, string table, IndexedColumn[] cols, IndexCreationOptions options, WhereStatement where = null)
        {
            // -----------------------------------------
            // Begin the SQL generation
            // -----------------------------------------
            StringBuilder sql = new StringBuilder("CREATE ", 256);

            sql.AppendIf(options.HasFlag(IndexCreationOptions.Unique), "UNIQUE ");
            sql.Append("INDEX ");
            sql.AppendIf(options.HasFlag(IndexCreationOptions.IfNotExists), "IF NOT EXISTS ");

            // Append index name
            sql.Append($"{name} ON ");
            sql.Append(QuoteIdentifier(table, this.IdentifierQuoteMode, this.IdentifierQuoteKind));
            sql.Append("(");

            // Append columns
            int i = cols.Length;

            foreach (var col in cols)
            {
                --i;
                sql.Append(QuoteIdentifier(col.Name, this.IdentifierQuoteMode, this.IdentifierQuoteKind));
                sql.AppendIf(col.Collate != Collation.Default, $" COLLATE {col.Collate.ToString().ToUpperInvariant()}");
                sql.AppendIf(col.SortOrder == Sorting.Descending, " DESC");
                sql.AppendIf(i > 0, ", ");
            }

            // Close
            sql.Append(")");

            // Add where if we have one
            if (where != null)
            {
                sql.Append(" WHERE ");
                sql.Append(where.BuildStatement());
            }

            // -----------------------------------------
            // Execute the command on the database
            // -----------------------------------------
            using (SQLiteCommand command = CreateCommand(sql.ToString()))
            {
                command.ExecuteNonQuery();
            }
        }
 /// <summary>
 /// Maps a IndexCreationOptions object to a MongoDB.Driver.CreateIndexOptions object
 /// </summary>
 /// <param name="indexCreationOptions">The options for creating an index.</param>
 /// <returns></returns>
 protected virtual CreateIndexOptions MapIndexOptions(IndexCreationOptions indexCreationOptions)
 {
     return(new CreateIndexOptions
     {
         Unique = indexCreationOptions.Unique,
         TextIndexVersion = indexCreationOptions.TextIndexVersion,
         SphereIndexVersion = indexCreationOptions.SphereIndexVersion,
         Sparse = indexCreationOptions.Sparse,
         Name = indexCreationOptions.Name,
         Min = indexCreationOptions.Min,
         Max = indexCreationOptions.Max,
         LanguageOverride = indexCreationOptions.LanguageOverride,
         ExpireAfter = indexCreationOptions.ExpireAfter,
         DefaultLanguage = indexCreationOptions.DefaultLanguage,
         Bits = indexCreationOptions.Bits,
         Background = indexCreationOptions.Background,
         Version = indexCreationOptions.Version
     });
 }
Ejemplo n.º 4
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;
        }
Ejemplo n.º 5
0
 /// <inheritdoc />
 public async virtual Task <string> CreateCombinedTextIndexAsync <TDocument, TKey>(IEnumerable <Expression <Func <TDocument, object> > > fields, IndexCreationOptions indexCreationOptions = null, string partitionKey = null)
     where TDocument : IDocument <TKey>
     where TKey : IEquatable <TKey>
 {
     return(await MongoDbIndexHandler.CreateCombinedTextIndexAsync <TDocument, TKey>(fields, indexCreationOptions, partitionKey));
 }
Ejemplo n.º 6
0
 /// <summary>
 /// Creates a hashed index on the given field.
 /// IndexCreationOptions can be supplied to further specify
 /// how the creation should be done.
 /// </summary>
 /// <typeparam name="TDocument">The type representing a Document.</typeparam>
 /// <param name="field">The field we want to index.</param>
 /// <param name="indexCreationOptions">Options for creating an index.</param>
 /// <param name="partitionKey">An optional partition key.</param>
 /// <returns>The result of the create index operation.</returns>
 public async Task <string> CreateHashedIndexAsync <TDocument>(Expression <Func <TDocument, object> > field, IndexCreationOptions indexCreationOptions = null, string partitionKey = null)
     where TDocument : IDocument <Guid>
 {
     return(await MongoDbIndexHandler.CreateHashedIndexAsync <TDocument, Guid>(field, indexCreationOptions, partitionKey));
 }
        /// <inheritdoc />
        public async Task <string> CreateHashedIndexAsync <TDocument, TKey>(Expression <Func <TDocument, object> > field, IndexCreationOptions indexCreationOptions = null, string partitionKey = null)
            where TDocument : IDocument <TKey>
            where TKey : IEquatable <TKey>
        {
            var collection    = HandlePartitioned <TDocument, TKey>(partitionKey);
            var createOptions = indexCreationOptions == null ? null : MapIndexOptions(indexCreationOptions);
            var indexKey      = Builders <TDocument> .IndexKeys;

            return(await collection.Indexes
                   .CreateOneAsync(
                       new CreateIndexModel <TDocument>(indexKey.Hashed(field), createOptions)));
        }
 /// <inheritdoc />
 public async Task <string> CreateDescendingIndexAsync <TDocument>(Expression <Func <TDocument, object> > field, IndexCreationOptions indexCreationOptions = null, string partitionKey = null)
     where TDocument : IDocument
 {
     return(await CreateDescendingIndexAsync <TDocument, Guid>(field, indexCreationOptions, partitionKey));
 }
 /// <inheritdoc />
 public async Task <string> CreateTextIndexAsync <TDocument, TKey>(Expression <Func <TDocument, object> > field, IndexCreationOptions indexCreationOptions = null, string partitionKey = null)
     where TDocument : IDocument <TKey>
     where TKey : IEquatable <TKey>
 {
     return(await HandlePartitioned <TDocument, TKey>(partitionKey).Indexes
            .CreateOneAsync(
                new CreateIndexModel <TDocument>(
                    Builders <TDocument> .IndexKeys.Text(field),
                    indexCreationOptions == null ? null : MapIndexOptions(indexCreationOptions)
                    )));
 }
        /// <inheritdoc />
        public async Task <string> CreateCombinedTextIndexAsync <TDocument, TKey>(IEnumerable <Expression <Func <TDocument, object> > > fields, IndexCreationOptions indexCreationOptions = null, string partitionKey = null)
            where TDocument : IDocument <TKey>
            where TKey : IEquatable <TKey>
        {
            var collection    = HandlePartitioned <TDocument, TKey>(partitionKey);
            var createOptions = indexCreationOptions == null ? null : MapIndexOptions(indexCreationOptions);
            var listOfDefs    = new List <IndexKeysDefinition <TDocument> >();

            foreach (var field in fields)
            {
                listOfDefs.Add(Builders <TDocument> .IndexKeys.Text(field));
            }
            return(await collection.Indexes
                   .CreateOneAsync(new CreateIndexModel <TDocument>(Builders <TDocument> .IndexKeys.Combine(listOfDefs), createOptions)));
        }
 /// <inheritdoc />
 public async Task <string> CreateCombinedTextIndexAsync <TDocument>(IEnumerable <Expression <Func <TDocument, object> > > fields, IndexCreationOptions indexCreationOptions = null, string partitionKey = null) where TDocument : IDocument
 {
     return(await CreateCombinedTextIndexAsync <TDocument, Guid>(fields, indexCreationOptions, partitionKey));
 }
Ejemplo n.º 12
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("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;
        }
Ejemplo n.º 13
0
 /// <summary>
 /// Creates an index on the given field in descending order.
 /// IndexCreationOptions can be supplied to further specify
 /// how the creation should be done.
 /// </summary>
 /// <typeparam name="TDocument">The type representing a Document.</typeparam>
 /// <param name="field">The field we want to index.</param>
 /// <param name="indexCreationOptions">Options for creating an index.</param>
 /// <param name="partitionKey">An optional partition key.</param>
 /// <returns>The result of the create index operation.</returns>
 public async virtual Task <string> CreateDescendingIndexAsync <TDocument>(Expression <Func <TDocument, object> > field, IndexCreationOptions indexCreationOptions = null, string partitionKey = null)
     where TDocument : IDocument <TKey>
 {
     return(await MongoDbIndexHandler.CreateDescendingIndexAsync <TDocument, TKey>(field, indexCreationOptions, partitionKey));
 }
Ejemplo n.º 14
0
 public Task Alter(IndexCreationOptions options)
 {
     throw new NotImplementedException();
 }