Skip to content

Commit

Permalink
Support DataSource name configuration (#1710)
Browse files Browse the repository at this point in the history
  • Loading branch information
devbased committed Aug 17, 2022
1 parent ff7e017 commit fbf8c2f
Show file tree
Hide file tree
Showing 2 changed files with 176 additions and 60 deletions.
114 changes: 114 additions & 0 deletions src/Quartz.Tests.Unit/SchedulerBuilderTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@ namespace Quartz.Tests.Unit
{
public class SchedulerBuilderTest
{
private const string TestConnectionString = "Server=localhost;Database=quartznet;";
private const string TestConnectionStringName = "TestConnection";
private const string TestDataSourceName = "TestSource";

[Test]
public void TestRamJobStore()
{
Expand Down Expand Up @@ -200,5 +204,115 @@ public void TestXmlSchedulingPlugin()
Assert.That(builder.Properties["quartz.plugin.xml.failOnSchedulingError"], Is.EqualTo("true"));
Assert.That(builder.Properties["quartz.plugin.xml.scanInterval"], Is.EqualTo("2"));
}

[Test]
public void TestUseGenericDatabaseRespectsDataSourceName()
{
AssertAdoProviderRespectDataSourceNameParameter<NoopDbProvider>(
options => options.UseGenericDatabase("", SetupAdoProviderOptionsWithDefaults, TestDataSourceName),
TestDataSourceName, TestConnectionString, TestConnectionStringName);
}

[Test]
public void TestUseSqlServerRespectsDataSourceName()
{
AssertAdoProviderRespectDataSourceNameParameter<NoopDbProvider>(
options => options.UseSqlServer(SetupAdoProviderOptionsWithDefaults, TestDataSourceName),
TestDataSourceName, TestConnectionString, TestConnectionStringName);
}

[Test]
public void TestUsePostgresRespectsDataSourceName()
{
AssertAdoProviderRespectDataSourceNameParameter<NoopDbProvider>(
options => options.UsePostgres(SetupAdoProviderOptionsWithDefaults, TestDataSourceName),
TestDataSourceName, TestConnectionString, TestConnectionStringName);
}

[Test]
public void TestUseMySqlRespectsDataSourceName()
{
AssertAdoProviderRespectDataSourceNameParameter<NoopDbProvider>(
options => options.UseMySql(SetupAdoProviderOptionsWithDefaults, TestDataSourceName),
TestDataSourceName, TestConnectionString, TestConnectionStringName);
}

[Test]
public void TestUseMySqlConnectorRespectsDataSourceName()
{
AssertAdoProviderRespectDataSourceNameParameter<NoopDbProvider>(
options => options.UseMySqlConnector(SetupAdoProviderOptionsWithDefaults, TestDataSourceName),
TestDataSourceName, TestConnectionString, TestConnectionStringName);
}

[Test]
public void TestUseFirebirdRespectsDataSourceName()
{
AssertAdoProviderRespectDataSourceNameParameter<NoopDbProvider>(
options => options.UseFirebird(SetupAdoProviderOptionsWithDefaults, TestDataSourceName),
TestDataSourceName, TestConnectionString, TestConnectionStringName);
}

[Test]
public void TestUseOracleRespectsDataSourceName()
{
AssertAdoProviderRespectDataSourceNameParameter<NoopDbProvider>(
options => options.UseOracle(SetupAdoProviderOptionsWithDefaults, TestDataSourceName),
TestDataSourceName, TestConnectionString, TestConnectionStringName);
}

[Test]
public void TestUseSqLiteRespectsDataSourceName()
{
AssertAdoProviderRespectDataSourceNameParameter<NoopDbProvider>(
options => options.UseSQLite(SetupAdoProviderOptionsWithDefaults, TestDataSourceName),
TestDataSourceName, TestConnectionString, TestConnectionStringName);
}

[Test]
public void TestUseMicrosoftSqLiteRespectsDataSourceName()
{
AssertAdoProviderRespectDataSourceNameParameter<NoopDbProvider>(
options => options.UseMicrosoftSQLite(SetupAdoProviderOptionsWithDefaults, TestDataSourceName),
TestDataSourceName, TestConnectionString, TestConnectionStringName);
}

private static void AssertAdoProviderRespectDataSourceNameParameter<TExpectedDbProvider>(
Action<SchedulerBuilder.PersistentStoreOptions> useProvider,
string expectedDataSourceName,
string expectedConnectionString,
string expectedConnectionStringName)
where TExpectedDbProvider : IDbProvider
{
var config = SchedulerBuilder.Create();

config.UsePersistentStore(useProvider);

Assert.That(config.Properties[$"quartz.dataSource.{expectedDataSourceName}.connectionString"], Is.EqualTo(expectedConnectionString));
Assert.That(config.Properties[$"quartz.dataSource.{expectedDataSourceName}.connectionStringName"], Is.EqualTo(expectedConnectionStringName));
Assert.That(config.Properties[$"quartz.dataSource.{expectedDataSourceName}.connectionProvider.type"], Is.EqualTo(typeof(TExpectedDbProvider).AssemblyQualifiedNameWithoutVersion()));
Assert.That(config.Properties["quartz.jobStore.dataSource"], Is.EqualTo(expectedDataSourceName));
}

private static void SetupAdoProviderOptionsWithDefaults(SchedulerBuilder.AdoProviderOptions options)
{
options.ConnectionString = TestConnectionString;
options.ConnectionStringName = TestConnectionStringName;
options.UseConnectionProvider<NoopDbProvider>();
}

private class NoopDbProvider : IDbProvider
{
public void Initialize() => throw new NotImplementedException();
public DbCommand CreateCommand() => throw new NotImplementedException();
public DbConnection CreateConnection() => throw new NotImplementedException();
public string ConnectionString
{
get => throw new NotImplementedException();
set => throw new NotImplementedException();
}
public DbMetadata Metadata => throw new NotImplementedException();
public void Shutdown() => throw new NotImplementedException();
}
}
}
122 changes: 62 additions & 60 deletions src/Quartz/SchedulerBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -381,16 +381,14 @@ public void UseClustering(Action<ClusterOptions>? options = null)
/// </summary>
/// <param name="provider">Valid provider name to configure driver details.</param>
/// <param name="configurer">Callback to refine configuration.</param>
/// <param name="dataSourceName">Name of the database. Defaults to '<see cref="AdoProviderOptions.DefaultDataSourceName"/>'.</param>
/// <returns></returns>
public void UseGenericDatabase(
string provider,
Action<AdoProviderOptions>? configurer = null)
Action<AdoProviderOptions>? configurer = null,
string? dataSourceName = null)
{
SetProperty("quartz.jobStore.driverDelegateType", typeof(StdAdoDelegate).AssemblyQualifiedNameWithoutVersion());
SetProperty("quartz.jobStore.dataSource", AdoProviderOptions.DefaultDataSourceName);
SetProperty($"quartz.dataSource.{AdoProviderOptions.DefaultDataSourceName}.provider", provider);

configurer?.Invoke(new AdoProviderOptions(this));
UseGenericDatabase<StdAdoDelegate>(provider, configurer, dataSourceName);
}

/// <summary>
Expand All @@ -408,6 +406,28 @@ public void UseBinarySerializer()
{
SetProperty("quartz.serializer.type", typeof(T).AssemblyQualifiedNameWithoutVersion());
}

/// <summary>
/// Configures persistence to use custom ADO provider.
/// </summary>
/// <typeparam name="TAdoDelegate">Type of the <see cref="StdAdoDelegate"/> inheritor.</typeparam>
/// <param name="provider">Valid provider name to configure driver details.</param>
/// <param name="configurer">Callback to refine configuration.</param>
/// <param name="dataSourceName">Name of the database. Defaults to '<see cref="AdoProviderOptions.DefaultDataSourceName"/>'.</param>
public void UseGenericDatabase<TAdoDelegate>(
string provider,
Action<AdoProviderOptions>? configurer = null,
string? dataSourceName = null)
where TAdoDelegate : StdAdoDelegate
{
dataSourceName ??= AdoProviderOptions.DefaultDataSourceName;

SetProperty("quartz.jobStore.driverDelegateType", typeof(TAdoDelegate).AssemblyQualifiedNameWithoutVersion());
SetProperty("quartz.jobStore.dataSource", dataSourceName);
SetProperty($"quartz.dataSource.{dataSourceName}.provider", provider);

configurer?.Invoke(new AdoProviderOptions(this, dataSourceName));
}
}

public class ClusterOptions : PropertiesHolder
Expand Down Expand Up @@ -456,10 +476,12 @@ public class AdoProviderOptions
public const string DefaultDataSourceName = "default";

private readonly PersistentStoreOptions options;
private readonly string dataSourceName;

protected internal AdoProviderOptions(PersistentStoreOptions options)
protected internal AdoProviderOptions(PersistentStoreOptions options, string dataSourceName)
{
this.options = options;
this.dataSourceName = dataSourceName;
}

/// <summary>
Expand All @@ -475,15 +497,15 @@ public string TablePrefix
/// </summary>
public string ConnectionString
{
set => options.SetProperty($"quartz.dataSource.{DefaultDataSourceName}.connectionString", value);
set => options.SetProperty($"quartz.dataSource.{dataSourceName}.connectionString", value);
}

/// <summary>
/// Use named connection defined in application configuration file.
/// </summary>
public string ConnectionStringName
{
set => options.SetProperty($"quartz.dataSource.{DefaultDataSourceName}.connectionStringName", value);
set => options.SetProperty($"quartz.dataSource.{dataSourceName}.connectionStringName", value);
}

/// <summary>
Expand All @@ -499,7 +521,7 @@ public string ConnectionStringName
/// </summary>
public void UseConnectionProvider<T>() where T : IDbProvider
{
options.SetProperty($"quartz.dataSource.{DefaultDataSourceName}.connectionProvider.type", typeof(T).AssemblyQualifiedNameWithoutVersion());
options.SetProperty($"quartz.dataSource.{dataSourceName}.connectionProvider.type", typeof(T).AssemblyQualifiedNameWithoutVersion());
}
}
}
Expand All @@ -515,14 +537,10 @@ public static class AdoProviderExtensions

public static void UseSqlServer(
this SchedulerBuilder.PersistentStoreOptions options,
Action<SchedulerBuilder.AdoProviderOptions> configurer)
Action<SchedulerBuilder.AdoProviderOptions> configurer,
string? dataSourceName = null)
{
options.SetProperty("quartz.jobStore.driverDelegateType", typeof(SqlServerDelegate).AssemblyQualifiedNameWithoutVersion());
options.SetProperty("quartz.jobStore.dataSource", SchedulerBuilder.AdoProviderOptions.DefaultDataSourceName);
options.SetProperty($"quartz.dataSource.{SchedulerBuilder.AdoProviderOptions.DefaultDataSourceName}.provider", "SqlServer");

var adoProviderOptions = new SchedulerBuilder.AdoProviderOptions(options);
configurer.Invoke(adoProviderOptions);
options.UseGenericDatabase<SqlServerDelegate>("SqlServer", configurer, dataSourceName);
}

public static void UsePostgres(
Expand All @@ -534,14 +552,10 @@ public static class AdoProviderExtensions

public static void UsePostgres(
this SchedulerBuilder.PersistentStoreOptions options,
Action<SchedulerBuilder.AdoProviderOptions> configurer)
Action<SchedulerBuilder.AdoProviderOptions> configurer,
string? dataSourceName = null)
{
options.SetProperty("quartz.jobStore.driverDelegateType", typeof(PostgreSQLDelegate).AssemblyQualifiedNameWithoutVersion());
options.SetProperty("quartz.jobStore.dataSource", SchedulerBuilder.AdoProviderOptions.DefaultDataSourceName);
options.SetProperty($"quartz.dataSource.{SchedulerBuilder.AdoProviderOptions.DefaultDataSourceName}.provider", "Npgsql");

var adoProviderOptions = new SchedulerBuilder.AdoProviderOptions(options);
configurer.Invoke(adoProviderOptions);
options.UseGenericDatabase<PostgreSQLDelegate>("Npgsql", configurer, dataSourceName);
}

public static void UseMySql(
Expand All @@ -553,29 +567,27 @@ public static class AdoProviderExtensions

public static void UseMySql(
this SchedulerBuilder.PersistentStoreOptions options,
Action<SchedulerBuilder.AdoProviderOptions> configurer)
Action<SchedulerBuilder.AdoProviderOptions> configurer,
string? dataSourceName = null)
{
UseMySqlInternal(options, "MySql", configurer);
UseMySqlInternal(options, "MySql", configurer, dataSourceName);
}

public static void UseMySqlConnector(
this SchedulerBuilder.PersistentStoreOptions options,
Action<SchedulerBuilder.AdoProviderOptions> configurer)
Action<SchedulerBuilder.AdoProviderOptions> configurer,
string? dataSourceName = null)
{
UseMySqlInternal(options, "MySqlConnector", configurer);
UseMySqlInternal(options, "MySqlConnector", configurer, dataSourceName);
}

internal static void UseMySqlInternal(
this SchedulerBuilder.PersistentStoreOptions options,
string provider,
Action<SchedulerBuilder.AdoProviderOptions> configurer)
Action<SchedulerBuilder.AdoProviderOptions> configurer,
string? dataSourceName = null)
{
options.SetProperty("quartz.jobStore.driverDelegateType", typeof(MySQLDelegate).AssemblyQualifiedNameWithoutVersion());
options.SetProperty("quartz.jobStore.dataSource", SchedulerBuilder.AdoProviderOptions.DefaultDataSourceName);
options.SetProperty($"quartz.dataSource.{SchedulerBuilder.AdoProviderOptions.DefaultDataSourceName}.provider", provider);

var adoProviderOptions = new SchedulerBuilder.AdoProviderOptions(options);
configurer.Invoke(adoProviderOptions);
options.UseGenericDatabase<MySQLDelegate>(provider, configurer, dataSourceName);
}

public static void UseFirebird(
Expand All @@ -587,14 +599,10 @@ public static class AdoProviderExtensions

public static void UseFirebird(
this SchedulerBuilder.PersistentStoreOptions options,
Action<SchedulerBuilder.AdoProviderOptions> configurer)
Action<SchedulerBuilder.AdoProviderOptions> configurer,
string? dataSourceName = null)
{
options.SetProperty("quartz.jobStore.driverDelegateType", typeof(FirebirdDelegate).AssemblyQualifiedNameWithoutVersion());
options.SetProperty("quartz.jobStore.dataSource", SchedulerBuilder.AdoProviderOptions.DefaultDataSourceName);
options.SetProperty($"quartz.dataSource.{SchedulerBuilder.AdoProviderOptions.DefaultDataSourceName}.provider", "Firebird");

var adoProviderOptions = new SchedulerBuilder.AdoProviderOptions(options);
configurer.Invoke(adoProviderOptions);
options.UseGenericDatabase<FirebirdDelegate>("Firebird", configurer, dataSourceName);
}

public static void UseOracle(
Expand All @@ -606,14 +614,10 @@ public static class AdoProviderExtensions

public static void UseOracle(
this SchedulerBuilder.PersistentStoreOptions options,
Action<SchedulerBuilder.AdoProviderOptions> configurer)
Action<SchedulerBuilder.AdoProviderOptions> configurer,
string? dataSourceName = null)
{
options.SetProperty("quartz.jobStore.driverDelegateType", typeof(OracleDelegate).AssemblyQualifiedNameWithoutVersion());
options.SetProperty("quartz.jobStore.dataSource", SchedulerBuilder.AdoProviderOptions.DefaultDataSourceName);
options.SetProperty($"quartz.dataSource.{SchedulerBuilder.AdoProviderOptions.DefaultDataSourceName}.provider", "OracleODPManaged");

var adoProviderOptions = new SchedulerBuilder.AdoProviderOptions(options);
configurer.Invoke(adoProviderOptions);
options.UseGenericDatabase<OracleDelegate>("OracleODPManaged", configurer, dataSourceName);
}

/// <summary>
Expand All @@ -631,9 +635,10 @@ public static class AdoProviderExtensions
/// </summary>
public static void UseSQLite(
this SchedulerBuilder.PersistentStoreOptions options,
Action<SchedulerBuilder.AdoProviderOptions> configurer)
Action<SchedulerBuilder.AdoProviderOptions> configurer,
string? dataSourceName = null)
{
options.UseSQLite("SQLite", configurer);
options.UseSQLite("SQLite", configurer, dataSourceName);
}

/// <summary>
Expand All @@ -651,22 +656,19 @@ public static class AdoProviderExtensions
/// </summary>
public static void UseMicrosoftSQLite(
this SchedulerBuilder.PersistentStoreOptions options,
Action<SchedulerBuilder.AdoProviderOptions> configurer)
Action<SchedulerBuilder.AdoProviderOptions> configurer,
string? dataSourceName = null)
{
options.UseSQLite("SQLite-Microsoft", configurer);
options.UseSQLite("SQLite-Microsoft", configurer, dataSourceName);
}

private static void UseSQLite(
this SchedulerBuilder.PersistentStoreOptions options,
string provider,
Action<SchedulerBuilder.AdoProviderOptions> configurer)
Action<SchedulerBuilder.AdoProviderOptions> configurer,
string? dataSourceName)
{
options.SetProperty("quartz.jobStore.driverDelegateType", typeof(SQLiteDelegate).AssemblyQualifiedNameWithoutVersion());
options.SetProperty("quartz.jobStore.dataSource", SchedulerBuilder.AdoProviderOptions.DefaultDataSourceName);
options.SetProperty($"quartz.dataSource.{SchedulerBuilder.AdoProviderOptions.DefaultDataSourceName}.provider", provider);

var adoProviderOptions = new SchedulerBuilder.AdoProviderOptions(options);
configurer.Invoke(adoProviderOptions);
options.UseGenericDatabase<SQLiteDelegate>(provider, configurer, dataSourceName);
}
}
}

0 comments on commit fbf8c2f

Please sign in to comment.