// ========================================================================== // Squidex Headless CMS // ========================================================================== // Copyright (c) Squidex UG (haftungsbeschraenkt) // All rights reserved. Licensed under the MIT license. // ========================================================================== using System.Globalization; using MongoDB.Driver; using Squidex.Hosting; using Squidex.Hosting.Configuration; #pragma warning disable RECS0108 // Warns about static fields in generic types namespace Squidex.Infrastructure.MongoDb { public abstract class MongoRepositoryBase : IInitializable { private const string CollectionFormat = "{0}Set"; protected static readonly BulkWriteOptions BulkUnordered = new BulkWriteOptions { IsOrdered = true }; protected static readonly FieldDefinitionBuilder FieldBuilder = FieldDefinitionBuilder.Instance; protected static readonly FilterDefinitionBuilder Filter = Builders.Filter; protected static readonly IndexKeysDefinitionBuilder Index = Builders.IndexKeys; protected static readonly InsertManyOptions InsertUnordered = new InsertManyOptions { IsOrdered = true }; protected static readonly ProjectionDefinitionBuilder Projection = Builders.Projection; protected static readonly ReplaceOptions UpsertReplace = new ReplaceOptions { IsUpsert = true }; protected static readonly SortDefinitionBuilder Sort = Builders.Sort; protected static readonly UpdateDefinitionBuilder Update = Builders.Update; protected static readonly UpdateOptions Upsert = new UpdateOptions { IsUpsert = true }; private readonly IMongoDatabase mongoDatabase; private IMongoCollection mongoCollection; protected IMongoCollection Collection { get { if (mongoCollection == null) { ThrowHelper.InvalidOperationException("Collection has not been initialized yet."); return default!; } return mongoCollection; } } protected IMongoDatabase Database { get => mongoDatabase; } static MongoRepositoryBase() { TypeConverterStringSerializer.Register(); InstantSerializer.Register(); DomainIdSerializer.Register(); } protected MongoRepositoryBase(IMongoDatabase database, bool setup = false) { Guard.NotNull(database); mongoDatabase = database; if (setup) { CreateCollection(); } } protected virtual MongoCollectionSettings CollectionSettings() { return new MongoCollectionSettings(); } protected virtual string CollectionName() { return string.Format(CultureInfo.InvariantCulture, CollectionFormat, typeof(TEntity).Name); } protected virtual Task SetupCollectionAsync(IMongoCollection collection, CancellationToken ct) { return Task.CompletedTask; } public virtual async Task ClearAsync( CancellationToken ct = default) { try { await Database.DropCollectionAsync(CollectionName(), ct); } catch (MongoCommandException ex) { if (ex.Code != 26) { throw; } } await InitializeAsync(ct); } public async Task InitializeAsync( CancellationToken ct) { try { CreateCollection(); await SetupCollectionAsync(Collection, ct); } catch (Exception ex) { var databaseName = Database.DatabaseNamespace.DatabaseName; var error = new ConfigurationError($"MongoDb connection failed to connect to database {databaseName}."); throw new ConfigurationException(error, ex); } } private void CreateCollection() { mongoCollection = mongoDatabase.GetCollection( CollectionName(), CollectionSettings() ?? new MongoCollectionSettings()); } } }