using back.Options; using Microsoft.EntityFrameworkCore; using System.Text.RegularExpressions; namespace back.ServicesExtensions; public enum DatabaseProvider { /* -- Relational databases supported by EF Core -- */ SUPPORTED, // Placeholder for supported databases. InMemory, Sqlite, PostgreSQL, CockroachDB, // CockroachDB is compatible with PostgreSQL. SQLServer, MariaDB, MySQL, Oracle, // Oracle is supported by EF Core but requires a separate package. /* -- NoSQL are not supported by EF -- */ NOT_SUPPORTED, // Placeholder for unsupported databases. Firebird, // Firebird is supported by EF Core but requires a separate package. Db2, // Db2 is supported by EF Core but requires a separate package. SAPHana, // SAP HANA is supported by EF Core but requires a separate package. Sybase, // Sybase is supported by EF Core but requires a separate package. Cosmos, // Cosmos DB is database supported by EF Core. MongoDB, InfluxDB, Redis, Cassandra, ElasticSearch, CouchDB, RavenDB, Neo4j, OrientDB, ArangoDB, ClickHouse, Druid, TimescaleDB, } public static partial class DbContextOptionsBuilderExtensions { private static string SupportedDbs() => string.Join(", ", Enum.GetValues() .Where(db => db > DatabaseProvider.SUPPORTED && db < DatabaseProvider.NOT_SUPPORTED) .OrderBy(db => db) .Select(db => db.ToString())); public static void UseDatabaseConfig(this DbContextOptionsBuilder options, DatabaseConfig config) { var providerName = Enum.GetNames() .FirstOrDefault(name => name.Equals(config.Provider, StringComparison.InvariantCultureIgnoreCase)); if (!Enum.TryParse(providerName, out DatabaseProvider provider)) { throw new InvalidOperationException($"Unsupported database provider: {config.Provider} -- Supported providers are: {SupportedDbs()}"); } switch (provider) { case DatabaseProvider.Sqlite: var match = SQLiteRegex().Match(config.ConnectionString ?? string.Empty); if (match.Success) { string? folder = null; string path = match.Groups[1].Value.Replace("\\", "/"); folder = path.Contains('/') ? path[..path.IndexOf('/')] : path; Directory.CreateDirectory(folder); } options.UseSqlite(config.ConnectionString); break; case DatabaseProvider.InMemory: options.UseInMemoryDatabase(config.ConnectionString); break; case DatabaseProvider.PostgreSQL or DatabaseProvider.CockroachDB: options.UseNpgsql(config.ConnectionString); break; case DatabaseProvider.SQLServer: options.UseSqlServer(config.ConnectionString); break; case DatabaseProvider.MySQL or DatabaseProvider.MariaDB: options.UseMySql(config.ConnectionString, ServerVersion.AutoDetect(config.ConnectionString)); break; default: throw new InvalidOperationException($"Unsupported database provider: {config.Provider}"); } } [GeneratedRegex(@"Data Source=([^;]+)")] private static partial Regex SQLiteRegex(); }