public async Task InitializeMembershipTable(GlobalConfiguration config, bool tryInitTableVersion, TraceLogger traceLogger) { logger = traceLogger; deploymentId = config.DeploymentId; if (logger.IsVerbose3) { logger.Verbose3("SqlMembershipTable.InitializeMembershipTable called."); } database = RelationalStorageUtilities.CreateGenericStorageInstance(config.AdoInvariant, config.DataConnectionString); //This initializes all of Orleans operational queries from the database using a well known view //and assumes the database with appropriate defintions exists already. queryConstants = await database.InitializeOrleansQueriesAsync(); // even if I am not the one who created the table, // try to insert an initial table version if it is not already there, // so we always have a first table version row, before this silo starts working. if (tryInitTableVersion) { var wasCreated = await InitTableAsync(); if (wasCreated) { logger.Info("Created new table version row."); } } }
/// <summary> /// Initializes Orleans queries from the database. Orleans uses only these queries and the variables therein, nothing more. /// </summary> /// <param name="storage">The storage to use.</param> /// <returns>Orleans queries have been loaded to silo or client memory.</returns> /// <remarks>This is public only to be usable to the statistics providers. Not intended for public use otherwise.</remarks> public static async Task <QueryConstantsBag> InitializeOrleansQueriesAsync(this IRelationalStorage storage) { var queryConstants = new QueryConstantsBag(); var query = queryConstants.GetConstant(storage.InvariantName, QueryKeys.OrleansQueriesKey); var orleansQueries = await storage.ReadAsync(query, _ => { }, (selector, _) => { return(Tuple.Create(selector.GetValue <string>("QueryKey"), selector.GetValue <string>("QueryText"))); }).ConfigureAwait(continueOnCapturedContext: false); //The queries need to be added to be used later with a given key. foreach (var orleansQuery in orleansQueries) { queryConstants.AddOrModifyQueryConstant(storage.InvariantName, orleansQuery.Item1, orleansQuery.Item2); } //Check that all the required keys are loaded and throw an exception giving the keys expected but not loaded. var loadedQueriesKeys = queryConstants.GetAllConstants(storage.InvariantName).Keys; var missingQueryKeys = QueryKeys.Keys.Except(loadedQueriesKeys); if (missingQueryKeys.Any()) { throw new ArgumentException(string.Format("Not all required queries found when loading from the database. Missing are: {0}", string.Join(",", missingQueryKeys))); } return(await Task.FromResult(queryConstants)); }
/// <summary> /// Creates a new instance of the storage based on the old connection string by changing the database name. /// </summary> /// <param name="storage">The old storage instance connectionstring of which to base the new one.</param> /// <param name="newDatabaseName">Connection string instance name of the database.</param> /// <returns>A new <see cref="IRelationalStorage"/> instance with having the same connection string as <paramref name="storage"/>but with with a new databaseName.</returns> public static IRelationalStorage CreateNewStorageInstance(this IRelationalStorage storage, string newDatabaseName) { string databaseKey = string.Empty; switch (storage.InvariantName) { case (AdoNetInvariants.InvariantNameSqlServer): { databaseKey = "Database"; break; } default: { databaseKey = "Database"; break; } } var csb = new DbConnectionStringBuilder(); csb.ConnectionString = storage.ConnectionString; csb[databaseKey] = newDatabaseName; return(RelationalStorage.CreateInstance(storage.InvariantName, csb.ConnectionString)); }
async Task IClientMetricsDataPublisher.Init(ClientConfiguration config, IPAddress address, string clientId) { //TODO: Orleans does not yet provide the type of database used (to, e.g., to load dlls), so SQL Server is assumed. database = RelationalStorageUtilities.CreateGenericStorageInstance(WellKnownRelationalInvariants.SqlServer, config.DataConnectionString); await InitOrleansQueriesAsync(); }
public async Task InitializeMembershipTable(GlobalConfiguration config, bool tryInitTableVersion, TraceLogger traceLogger) { logger = traceLogger; deploymentId = config.DeploymentId; if (logger.IsVerbose3) logger.Verbose3("SqlMembershipTable.InitializeMembershipTable called."); database = RelationalStorageUtilities.CreateGenericStorageInstance(config.AdoInvariant, config.DataConnectionString); //This initializes all of Orleans operational queries from the database using a well known view //and assumes the database with appropriate defintions exists already. queryConstants = await database.InitializeOrleansQueriesAsync(); // even if I am not the one who created the table, // try to insert an initial table version if it is not already there, // so we always have a first table version row, before this silo starts working. if(tryInitTableVersion) { var wasCreated = await InitTableAsync(); if(wasCreated) { logger.Info("Created new table version row."); } } }
public SqlReminderTable(GlobalConfiguration config) { serviceId = config.ServiceId.ToString(); deploymentId = config.DeploymentId; //TODO: Orleans does not yet provide the type of database used (to, e.g., to load dlls), so SQL Server is assumed. database = RelationalStorageUtilities.CreateGenericStorageInstance(WellKnownRelationalInvariants.SqlServer, config.DataConnectionString); }
public async Task Init(GlobalConfiguration config, TraceLogger logger) { serviceId = config.ServiceId.ToString(); deploymentId = config.DeploymentId; database = RelationalStorageUtilities.CreateGenericStorageInstance(config.AdoInvariantForReminders, config.DataConnectionStringForReminders); queryConstants = await database.InitializeOrleansQueriesAsync(); }
/// <summary> /// Returns a native implementation of <see cref="DbDataReader.GetStream(int)"/> for those providers /// which support it. Otherwise returns a chuncked read using <see cref="DbDataReader.GetBytes(int, long, byte[], int, int)"/>. /// </summary> /// <param name="reader">The reader from which to return the stream.</param> /// <param name="ordinal">The ordinal column for which to return the stream.</param> /// <param name="storage">The storage that gives the invariant.</param> /// <returns></returns> public static Stream GetStream(this DbDataReader reader, int ordinal, IRelationalStorage storage) { if (storage.SupportsStreamNatively()) { return(reader.GetStream(ordinal)); } return(new OrleansRelationalDownloadStream(reader, ordinal)); }
public Task Init(Guid serviceId, string deploymentId, string connectionString) { this.serviceId = serviceId.ToString(); this.deploymentId = deploymentId; database = RelationalStorageUtilities.CreateGenericStorageInstance(WellKnownRelationalInvariants.SqlServer, connectionString); return(TaskDone.Done); }
public static void ClassInitialize(TestContext testContext) { TraceLogger.Initialize(new NodeConfiguration()); TraceLogger.AddTraceLevelOverride("SQLReminderTableTests", Logger.Severity.Verbose3); // Set shorter init timeout for these tests OrleansSiloInstanceManager.initTimeout = TimeSpan.FromSeconds(20); relationalStorage = SqlTestsEnvironment.Setup(testDatabaseName); }
public Task Init(Guid serviceId, string deploymentId, string connectionString) { this.serviceId = serviceId.ToString(); this.deploymentId = deploymentId; database = RelationalStorageUtilities.CreateGenericStorageInstance(WellKnownRelationalInvariants.SqlServer, connectionString); return TaskDone.Done; }
/// <summary> /// Uses <see cref="IRelationalStorage"/> with <see cref="DbExtensions.ReflectionParameterProvider{T}(IDbCommand, T, IReadOnlyDictionary{string, string})"/>. /// </summary> /// <typeparam name="TResult">The type of the result.</typeparam> /// <param name="storage">The storage to use.</param> /// <param name="query">Executes a given statement. Especially intended to use with <em>SELECT</em> statement, but works with other queries too.</param> /// <param name="parameters">Adds parameters to the query. Parameter names must match those defined in the query.</param> /// <param name="cancellationToken">The cancellation token. Defaults to <see cref="CancellationToken.None"/>.</param> /// <returns>A list of objects as a result of the <see paramref="query"/>.</returns> /// <example>This uses reflection to read results and match the parameters. /// <code> /// //This struct holds the return value in this example. /// public struct Information /// { /// public string TABLE_CATALOG { get; set; } /// public string TABLE_NAME { get; set; } /// } /// /// //Here reflection (<seealso cref="DbExtensions.ReflectionParameterProvider{T}(IDbCommand, T, IReadOnlyDictionary{string, string})"/>) /// is used to match parameter names as well as to read back the results (<seealso cref="DbExtensions.ReflectionSelector{TResult}(IDataRecord)"/>). /// var query = "SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = @tname;"; /// IEnumerable<Information> informationData = await db.ReadAsync<Information>(query, new { tname = 200000 }); /// </code> /// </example> public static Task <IEnumerable <TResult> > ReadAsync <TResult>(this IRelationalStorage storage, string query, object parameters, CancellationToken cancellationToken = default(CancellationToken)) { return(storage.ReadAsync(query, command => { if (parameters != null) { command.ReflectionParameterProvider(parameters); } }, (selector, resultSetCount, token) => Task.FromResult(selector.ReflectionSelector <TResult>()), cancellationToken)); }
/// <summary> /// Uses <see cref="IRelationalStorage"/> with <see cref="DbExtensions.ReflectionSelector{TResult}(System.Data.IDataRecord)"/>. /// </summary> /// <param name="storage">The storage to use.</param> /// <param name="query">Executes a given statement. Especially intended to use with <em>INSERT</em>, <em>UPDATE</em>, <em>DELETE</em> or <em>DDL</em> queries.</param> /// <param name="parameters">Adds parameters to the query. Parameter names must match those defined in the query.</param> /// <returns>Affected rows count.</returns> /// <example>This uses reflection to provide parameters to an execute /// query that reads only affected rows count if available. /// <code> /// //Here reflection (<seealso cref="DbExtensions.ReflectionParameterProvider{T}(IDbCommand, T, IReadOnlyDictionary{string, string})"/>) /// is used to match parameter names as well as to read back the results (<seealso cref="DbExtensions.ReflectionSelector{TResult}(IDataRecord)"/>). /// var query = "IF NOT EXISTS(SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = @tname) CREATE TABLE Test(Id INT PRIMARY KEY IDENTITY(1, 1) NOT NULL);" /// await db.ExecuteAsync(query, new { tname = "test_table" }); /// </code> /// </example> public static async Task <int> ExecuteAsync(this IRelationalStorage storage, string query, object parameters) { return(await storage.ExecuteAsync(query, command => { if (parameters != null) { command.ReflectionParameterProvider(parameters); } }).ConfigureAwait(continueOnCapturedContext: false)); }
/// <summary> /// Uses <see cref="IRelationalStorage"/> with <see cref="DbExtensions.ReflectionParameterProvider{T}(IDbCommand, T, IReadOnlyDictionary{string, string})"/>. /// </summary> /// <typeparam name="TResult">The type of the result.</typeparam> /// <param name="storage">The storage to use.</param> /// <param name="query">Executes a given statement. Especially intended to use with <em>SELECT</em> statement, but works with other queries too.</param> /// <param name="parameters">Adds parameters to the query. Parameter names must match those defined in the query.</param> /// <returns>A list of objects as a result of the <see paramref="query"/>.</returns> /// <example>This uses reflection to read results and match the parameters. /// <code> /// //This struct holds the return value in this example. /// public struct Information /// { /// public string TABLE_CATALOG { get; set; } /// public string TABLE_NAME { get; set; } /// } /// /// //Here reflection (<seealso cref="DbExtensions.ReflectionParameterProvider{T}(IDbCommand, T, IReadOnlyDictionary{string, string})"/>) /// is used to match parameter names as well as to read back the results (<seealso cref="DbExtensions.ReflectionSelector{TResult}(IDataRecord)"/>). /// var query = "SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = @tname;"; /// IEnumerable<Information> informationData = await db.ReadAsync<Information>(query, new { tname = 200000 }); /// </code> /// </example> public static async Task <IEnumerable <TResult> > ReadAsync <TResult>(this IRelationalStorage storage, string query, object parameters) { return(await storage.ReadAsync(query, command => { if (parameters != null) { command.ReflectionParameterProvider(parameters); } }, (selector, resultSetCount) => selector.ReflectionSelector <TResult>()).ConfigureAwait(continueOnCapturedContext: false)); }
/// <summary> /// Uses <see cref="IRelationalStorage"/> with <see cref="DbExtensions.ReflectionSelector{TResult}(System.Data.IDataRecord)"/>. /// </summary> /// <param name="storage">The storage to use.</param> /// <param name="query">Executes a given statement. Especially intended to use with <em>INSERT</em>, <em>UPDATE</em>, <em>DELETE</em> or <em>DDL</em> queries.</param> /// <param name="parameters">Adds parameters to the query. Parameter names must match those defined in the query.</param> /// <param name="cancellationToken">The cancellation token. Defaults to <see cref="CancellationToken.None"/>.</param> /// <returns>Affected rows count.</returns> /// <example>This uses reflection to provide parameters to an execute /// query that reads only affected rows count if available. /// <code> /// //Here reflection (<seealso cref="DbExtensions.ReflectionParameterProvider{T}(IDbCommand, T, IReadOnlyDictionary{string, string})"/>) /// is used to match parameter names as well as to read back the results (<seealso cref="DbExtensions.ReflectionSelector{TResult}(IDataRecord)"/>). /// var query = "IF NOT EXISTS(SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = @tname) CREATE TABLE Test(Id INT PRIMARY KEY IDENTITY(1, 1) NOT NULL);" /// await db.ExecuteAsync(query, new { tname = "test_table" }); /// </code> /// </example> public static Task <int> ExecuteAsync(this IRelationalStorage storage, string query, object parameters, CancellationToken cancellationToken = default(CancellationToken)) { return(storage.ExecuteAsync(query, command => { if (parameters != null) { command.ReflectionParameterProvider(parameters); } }, cancellationToken)); }
public async Task Init(string name, IProviderRuntime providerRuntime, IProviderConfiguration config) { Name = name; logger = providerRuntime.GetLogger("SqlStatisticsPublisher"); //TODO: Orleans does not yet provide the type of database used (to, e.g., to load dlls), so SQL Server is assumed. database = RelationalStorageUtilities.CreateGenericStorageInstance(WellKnownRelationalInvariants.SqlServer, config.Properties["ConnectionString"]); await InitOrleansQueriesAsync(); }
public static void ClassInitialize(TestContext context) { Console.WriteLine("TestContext.DeploymentDirectory={0}", context.DeploymentDirectory); Console.WriteLine("TestContext="); Console.WriteLine(DumpTestContext(context)); Console.WriteLine("Initializing relational databases..."); relationalStorage = SqlTestsEnvironment.Setup(testDatabaseName); siloOptions.DataConnectionString = relationalStorage.ConnectionString; }
public Task InitializeGatewayListProvider(ClientConfiguration config, TraceLogger traceLogger) { logger.Verbose3("SqlMembershipTable.InitializeGatewayListProvider called."); deploymentId = config.DeploymentId; maxStaleness = config.GatewayListRefreshPeriod; //TODO: Orleans does not yet provide the type of database used (to, e.g., to load dlls), so SQL Server is assumed. database = RelationalStorageUtilities.CreateGenericStorageInstance(WellKnownRelationalInvariants.SqlServer, config.DataConnectionString); return TaskDone.Done; }
/// <summary> /// Creates a transaction scope in which the storage operates. /// </summary> /// <param name="storage">The storage object.</param> /// <returns>Returns a default transaction scope for the given storage.</returns> /// <remarks>Does not set <c>System.Transactions.TransactionScopeAsyncFlowOption.Enabled">TransactionScopeAsyncFlowOption</c>as it is .NET 4.5.1. /// This is required to support transaction scopes in async-await type of flows.</remarks> public static TransactionScope CreateTransactionScope(this IRelationalStorage storage) { //By default transaction scope is set to serializable and a timeout for one minute. //The timeout is regardless of what has been set on the command object itself and //the query would be rolled back in the end. These defaults are more usable and //can be customized per database. var transactionOptions = new TransactionOptions { IsolationLevel = IsolationLevel.ReadCommitted, Timeout = TransactionManager.MaximumTimeout }; return(new TransactionScope(TransactionScopeOption.Required, transactionOptions)); }
/// <summary> /// Checks the existence of a database using the given <see paramref="storage"/> storage object. /// </summary> /// <param name="storage">The storage to use.</param> /// <param name="databaseName">The name of the database existence of which to check.</param> /// <returns><em>TRUE</em> if the given database exists. <em>FALSE</em> otherwise.</returns> public static async Task <bool> ExistsDatabaseAsync(this IRelationalStorage storage, string query, string databaseName) { var ret = await storage.ReadAsync(string.Format(query, databaseName), command => { var p = command.CreateParameter(); p.ParameterName = "databaseName"; p.Value = databaseName; command.Parameters.Add(p); }, (selector, resultSetCount) => { return(selector.GetBoolean(0)); }).ConfigureAwait(continueOnCapturedContext: false); return(ret.First()); }
public async Task Init(string name, IProviderRuntime providerRuntime, IProviderConfiguration config) { Name = name; logger = providerRuntime.GetLogger("SqlStatisticsPublisher"); string adoInvariant = AdoNetInvariants.InvariantNameSqlServer; if (config.Properties.ContainsKey("AdoInvariant")) adoInvariant = config.Properties["AdoInvariant"]; database = RelationalStorageUtilities.CreateGenericStorageInstance(adoInvariant, config.Properties["ConnectionString"]); queryConstants = await database.InitializeOrleansQueriesAsync(); }
public async Task InitializeGatewayListProvider(ClientConfiguration config, TraceLogger traceLogger) { logger = traceLogger; if (logger.IsVerbose3) logger.Verbose3("SqlMembershipTable.InitializeGatewayListProvider called."); deploymentId = config.DeploymentId; maxStaleness = config.GatewayListRefreshPeriod; database = RelationalStorageUtilities.CreateGenericStorageInstance(config.AdoInvariant, config.DataConnectionString); //This initializes all of Orleans operational queries from the database using a well known view //and assumes the database with appropriate defintions exists already. queryConstants = await database.InitializeOrleansQueriesAsync(); }
public Task InitializeGatewayListProvider(ClientConfiguration config, TraceLogger traceLogger) { if (logger.IsVerbose3) { logger.Verbose3("SqlMembershipTable.InitializeGatewayListProvider called."); } deploymentId = config.DeploymentId; maxStaleness = config.GatewayListRefreshPeriod; //TODO: Orleans does not yet provide the type of database used (to, e.g., to load dlls), so SQL Server is assumed. database = RelationalStorageUtilities.CreateGenericStorageInstance(WellKnownRelationalInvariants.SqlServer, config.DataConnectionString); return(TaskDone.Done); }
public async Task InitializeGatewayListProvider(ClientConfiguration config, TraceLogger traceLogger) { logger = traceLogger; if (logger.IsVerbose3) logger.Verbose3("SqlMembershipTable.InitializeGatewayListProvider called."); deploymentId = config.DeploymentId; maxStaleness = config.GatewayListRefreshPeriod; //TODO: Orleans does not yet provide the type of database used (to, e.g., to load dlls), so SQL Server is assumed. database = RelationalStorageUtilities.CreateGenericStorageInstance(WellKnownRelationalInvariants.SqlServer, config.DataConnectionString); //This initializes all of Orleans operational queries from the database using a well known view //and assumes the database with appropriate defintions exists already. await InitializeOrleansQueriesAsync(); }
public async Task InitializeGatewayListProvider(ClientConfiguration config, TraceLogger traceLogger) { logger = traceLogger; if (logger.IsVerbose3) { logger.Verbose3("SqlMembershipTable.InitializeGatewayListProvider called."); } deploymentId = config.DeploymentId; maxStaleness = config.GatewayListRefreshPeriod; database = RelationalStorageUtilities.CreateGenericStorageInstance(config.AdoInvariant, config.DataConnectionString); //This initializes all of Orleans operational queries from the database using a well known view //and assumes the database with appropriate defintions exists already. queryConstants = await database.InitializeOrleansQueriesAsync(); }
public async Task Init(string name, IProviderRuntime providerRuntime, IProviderConfiguration config) { Name = name; logger = providerRuntime.GetLogger("SqlStatisticsPublisher"); string adoInvariant = AdoNetInvariants.InvariantNameSqlServer; if (config.Properties.ContainsKey("AdoInvariant")) { adoInvariant = config.Properties["AdoInvariant"]; } database = RelationalStorageUtilities.CreateGenericStorageInstance(adoInvariant, config.Properties["ConnectionString"]); queryConstants = await database.InitializeOrleansQueriesAsync(); }
public async Task InitializeGatewayListProvider(ClientConfiguration config, TraceLogger traceLogger) { logger = traceLogger; if (logger.IsVerbose3) { logger.Verbose3("SqlMembershipTable.InitializeGatewayListProvider called."); } deploymentId = config.DeploymentId; maxStaleness = config.GatewayListRefreshPeriod; //TODO: Orleans does not yet provide the type of database used (to, e.g., to load dlls), so SQL Server is assumed. database = RelationalStorageUtilities.CreateGenericStorageInstance(WellKnownRelationalInvariants.SqlServer, config.DataConnectionString); //This initializes all of Orleans operational queries from the database using a well known view //and assumes the database with appropriate defintions exists already. await InitializeOrleansQueriesAsync(); }
/// <summary> /// Creates an instance of a database of type <see cref="RelationalOrleansQueries"/> and Initializes Orleans queries from the database. /// Orleans uses only these queries and the variables therein, nothing more. /// </summary> /// <param name="storage">the underlying storage instance</param> public static async Task<RelationalOrleansQueries> CreateInstance(IRelationalStorage storage) { //this will probably be the same for all relational dbs const string orleansQueriesSelectTemplate = "SELECT QueryKey, QueryText FROM OrleansQuery;"; var orleansQueries = new OrleansQueries(); var propertiesDictionary = typeof(OrleansQueries).GetFields().ToDictionary(p => p.Name, p => p); var populatedKeys = await storage.ReadAsync(orleansQueriesSelectTemplate, _ => { }, (selector, _) => { var queryKey = selector.GetValue<string>("QueryKey"); var queryText = selector.GetValue<string>("QueryText"); propertiesDictionary[queryKey].SetValue(orleansQueries, queryText); return queryKey; }).ConfigureAwait(continueOnCapturedContext: false); //Check that all the required keys are loaded and throw an exception giving the keys expected but not loaded. var missingQueryKeys = populatedKeys.Except(propertiesDictionary.Keys); if (missingQueryKeys.Any()) { throw new ArgumentException(string.Format("Not all required queries found when loading from the database. Missing are: {0}", string.Join(",", missingQueryKeys))); } return new RelationalOrleansQueries(storage, orleansQueries); }
public static void ClassInitialize(TestContext testContext) { TraceLogger.Initialize(new NodeConfiguration()); TraceLogger.AddTraceLevelOverride("SQLMembershipTableTests", Logger.Severity.Verbose3); // Set shorter init timeout for these tests OrleansSiloInstanceManager.initTimeout = TimeSpan.FromSeconds(20); Console.WriteLine("Initializing relational databases..."); relationalStorage = RelationalStorageUtilities.CreateDefaultSqlServerStorageInstance(); Console.WriteLine("Dropping and recreating database '{0}' with connectionstring '{1}'", testDatabaseName, relationalStorage.ConnectionString); if (relationalStorage.ExistsDatabaseAsync(testDatabaseName).Result) { relationalStorage.DropDatabaseAsync(testDatabaseName).Wait(); } relationalStorage.CreateDatabaseAsync(testDatabaseName).Wait(); //The old storage instance has the previous connection string, time have a new handle with a new connection string... relationalStorage = relationalStorage.CreateNewStorageInstance(testDatabaseName); Console.WriteLine("Creating database tables..."); var creationScripts = RelationalStorageUtilities.RemoveBatchSeparators(File.ReadAllText("CreateOrleansTables_SqlServer.sql")); foreach (var creationScript in creationScripts) { var res = relationalStorage.ExecuteAsync(creationScript).Result; } //Currently there's only one database under test, SQL Server. So this as the other //setup is hardcoded here: putting the database in simple recovery mode. //This removes the use of recovery log in case of database crashes, which //improves performance to some degree, depending on usage. For non-performance testing only. var simpleModeRes = relationalStorage.ExecuteAsync(string.Format("ALTER DATABASE [{0}] SET RECOVERY SIMPLE;", testDatabaseName)).Result; Console.WriteLine("Initializing relational databases done."); }
public static void ClassInitialize(TestContext context) { Console.WriteLine("TestContext.DeploymentDirectory={0}", context.DeploymentDirectory); Console.WriteLine("TestContext="); Console.WriteLine(DumpTestContext(context)); Console.WriteLine("Initializing relational databases..."); relationalStorage = RelationalStorageUtilities.CreateDefaultSqlServerStorageInstance(); Console.WriteLine("Dropping and recreating database '{0}' with connectionstring '{1}'", testDatabaseName, relationalStorage.ConnectionString); if (relationalStorage.ExistsDatabaseAsync(testDatabaseName).Result) { relationalStorage.DropDatabaseAsync(testDatabaseName).Wait(); } relationalStorage.CreateDatabaseAsync(testDatabaseName).Wait(); //The old storage instance has the previous connection string, time have a new handle with a new connection string... relationalStorage = relationalStorage.CreateNewStorageInstance(testDatabaseName); Console.WriteLine("Creating database tables..."); var creationScripts = RelationalStorageUtilities.RemoveBatchSeparators(File.ReadAllText("CreateOrleansTables_SqlServer.sql")); foreach (var creationScript in creationScripts) { var res = relationalStorage.ExecuteAsync(creationScript).Result; } //Currently there's only one database under test, SQL Server. So this as the other //setup is hardcoded here: putting the database in simple recovery mode. //This removes the use of recovery log in case of database crashes, which //improves performance to some degree, depending on usage. For non-performance testing only. var simpleModeRes = relationalStorage.ExecuteAsync(string.Format("ALTER DATABASE [{0}] SET RECOVERY SIMPLE;", testDatabaseName)).Result; Console.WriteLine("Initializing relational databases done."); siloOptions.DataConnectionString = relationalStorage.ConnectionString; }
public static void ClassInitialize(TestContext testContext) { TraceLogger.Initialize(new NodeConfiguration()); TraceLogger.AddTraceLevelOverride("SQLMembershipTableTests", Logger.Severity.Verbose3); // Set shorter init timeout for these tests OrleansSiloInstanceManager.initTimeout = TimeSpan.FromSeconds(20); Console.WriteLine("Initializing relational databases..."); relationalStorage = RelationalStorageUtilities.CreateDefaultSqlServerStorageInstance(); Console.WriteLine("Dropping and recreating database '{0}' with connectionstring '{1}'", testDatabaseName, relationalStorage.ConnectionString); if(relationalStorage.ExistsDatabaseAsync(testDatabaseName).Result) { relationalStorage.DropDatabaseAsync(testDatabaseName).Wait(); } relationalStorage.CreateDatabaseAsync(testDatabaseName).Wait(); //The old storage instance has the previous connection string, time have a new handle with a new connection string... relationalStorage = relationalStorage.CreateNewStorageInstance(testDatabaseName); Console.WriteLine("Creating database tables..."); var creationScripts = RelationalStorageUtilities.RemoveBatchSeparators(File.ReadAllText("CreateOrleansTables_SqlServer.sql")); foreach(var creationScript in creationScripts) { var res = relationalStorage.ExecuteAsync(creationScript).Result; } //Currently there's only one database under test, SQL Server. So this as the other //setup is hardcoded here: putting the database in simple recovery mode. //This removes the use of recovery log in case of database crashes, which //improves performance to some degree, depending on usage. For non-performance testing only. var simpleModeRes = relationalStorage.ExecuteAsync(string.Format("ALTER DATABASE [{0}] SET RECOVERY SIMPLE;", testDatabaseName)).Result; Console.WriteLine("Initializing relational databases done."); }
/// <summary> /// Uses <see cref="IRelationalStorage"/> with <see cref="DbExtensions.ReflectionSelector{TResult}(System.Data.IDataRecord)"/>. /// </summary> /// <param name="storage">The storage to use.</param> /// <param name="query">Executes a given statement. Especially intended to use with <em>INSERT</em>, <em>UPDATE</em>, <em>DELETE</em> or <em>DDL</em> queries.</param> /// <returns>Affected rows count.</returns> public static async Task <int> ExecuteAsync(this IRelationalStorage storage, string query) { return(await ExecuteAsync(storage, query, null).ConfigureAwait(continueOnCapturedContext: false)); }
/// <summary> /// Executes a multi-record insert query clause with <em>SELECT UNION ALL</em>. /// </summary> /// <typeparam name="T"></typeparam> /// <param name="storage">The storage to use.</param> /// <param name="tableName">The table name to against which to execute the query.</param> /// <param name="parameters">The parameters to insert.</param> /// <param name="nameMap">If provided, maps property names from <typeparamref name="T"/> to ones provided in the map.</param> /// <param name="onlyOnceColumns">If given, SQL parameter values for the given <typeparamref name="T"/> property types are generated only once. Effective only when <paramref name="useSqlParams"/> is <em>TRUE</em>.</param> /// <param name="useSqlParams"><em>TRUE</em> if the query should be in parameterized form. <em>FALSE</em> otherwise.</param> /// <returns>The rows affected.</returns> public static Task <int> ExecuteMultipleInsertIntoAsync <T>(this IRelationalStorage storage, string tableName, IEnumerable <T> parameters, IReadOnlyDictionary <string, string> nameMap = null, IEnumerable <string> onlyOnceColumns = null, bool useSqlParams = true) { if (string.IsNullOrWhiteSpace(tableName)) { throw new ArgumentException("The name must be a legal SQL table name", "tableName"); } if (parameters == null) { throw new ArgumentNullException("parameters"); } var storageConsts = DbConstantsStore.GetDbConstants(storage.InvariantName); var startEscapeIndicator = storageConsts.StartEscapeIndicator; var endEscapeIndicator = storageConsts.EndEscapeIndicator; //SqlParameters map is needed in case the query needs to be parameterized in order to avoid two //reflection passes as first a query needs to be constructed and after that when a database //command object has been created, parameters need to be provided to them. var sqlParameters = new Dictionary <string, object>(); const string insertIntoValuesTemplate = "INSERT INTO {0} ({1}) SELECT {2};"; var columns = string.Empty; var values = new List <string>(); if (parameters.Any()) { //Type and property information are the same for all of the objects. //The following assumes the property names will be retrieved in the same //order as is the index iteration done. var onlyOnceRow = new List <string>(); var properties = parameters.First().GetType().GetProperties(); columns = string.Join(",", nameMap == null ? properties.Select(pn => string.Format("{0}{1}{2}", startEscapeIndicator, pn.Name, endEscapeIndicator)) : properties.Select(pn => string.Format("{0}{1}{2}", startEscapeIndicator, (nameMap.ContainsKey(pn.Name) ? nameMap[pn.Name] : pn.Name), endEscapeIndicator))); if (onlyOnceColumns != null && onlyOnceColumns.Any()) { var onlyOnceProperties = properties.Where(pn => onlyOnceColumns.Contains(pn.Name)).Select(pn => pn).ToArray(); var onlyOnceData = parameters.First(); for (int i = 0; i < onlyOnceProperties.Length; ++i) { var currentProperty = onlyOnceProperties[i]; var parameterValue = currentProperty.GetValue(onlyOnceData, null); if (useSqlParams) { var parameterName = string.Format("@{0}", (nameMap.ContainsKey(onlyOnceProperties[i].Name) ? nameMap[onlyOnceProperties[i].Name] : onlyOnceProperties[i].Name)); onlyOnceRow.Add(parameterName); sqlParameters.Add(parameterName, parameterValue); } else { onlyOnceRow.Add(string.Format(sqlFormatProvider, "{0}", parameterValue)); } } } var dataRows = new List <string>(); var multiProperties = onlyOnceColumns == null ? properties : properties.Where(pn => !onlyOnceColumns.Contains(pn.Name)).Select(pn => pn).ToArray(); int parameterCount = 0; foreach (var row in parameters) { for (int i = 0; i < multiProperties.Length; ++i) { var currentProperty = multiProperties[i]; var parameterValue = currentProperty.GetValue(row, null); if (useSqlParams) { var parameterName = string.Format(indexedParameterTemplate, parameterCount); dataRows.Add(parameterName); sqlParameters.Add(parameterName, parameterValue); ++parameterCount; } else { dataRows.Add(string.Format(sqlFormatProvider, "{0}", parameterValue)); } } values.Add(string.Format("{0}", string.Join(",", onlyOnceRow.Concat(dataRows)))); dataRows.Clear(); } } var query = string.Format(insertIntoValuesTemplate, tableName, columns, string.Join(storageConsts.UnionAllSelectTemplate, values)); return(storage.ExecuteAsync(query, command => { if (useSqlParams) { foreach (var sp in sqlParameters) { var p = command.CreateParameter(); p.ParameterName = sp.Key; p.Value = sp.Value ?? DBNull.Value; p.Direction = ParameterDirection.Input; command.Parameters.Add(p); } } })); }
/// <summary> /// Uses <see cref="IRelationalStorage"/> with <see cref="DbExtensions.ReflectionParameterProvider{T}(System.Data.IDbCommand, T, IReadOnlyDictionary{string, string})">DbExtensions.ReflectionParameterProvider</see>. /// </summary> /// <typeparam name="TResult">The type of the result.</typeparam> /// <param name="storage">The storage to use.</param> /// <param name="query">Executes a given statement. Especially intended to use with <em>SELECT</em> statement, but works with other queries too.</param> /// <returns>A list of objects as a result of the <see paramref="query"/>.</returns> public static async Task <IEnumerable <TResult> > ReadAsync <TResult>(this IRelationalStorage storage, string query) { return(await ReadAsync <TResult>(storage, query, null).ConfigureAwait(continueOnCapturedContext: false)); }
async Task IClientMetricsDataPublisher.Init(ClientConfiguration config, IPAddress address, string clientId) { database = RelationalStorageUtilities.CreateGenericStorageInstance(config.AdoInvariant, config.DataConnectionString); queryConstants = await database.InitializeOrleansQueriesAsync(); }
/// <summary> /// Constructor /// </summary> /// <param name="invariantName"></param> /// <param name="connectionString"></param> protected RelationalStorageForTesting(string invariantName, string connectionString) { storage = RelationalStorage.CreateInstance(invariantName, connectionString); }
/// <summary> /// Constructor /// </summary> /// <param name="storage">the underlying relational storage</param> /// <param name="orleansQueries">Orleans functional queries</param> private RelationalOrleansQueries(IRelationalStorage storage, OrleansQueries orleansQueries) { this.storage = storage; this.orleansQueries = orleansQueries; }
/// <summary> /// If the underlying storage supports cancellation or not. /// </summary> /// <param name="storage">The storage used.</param> /// <returns><em>TRUE</em> if cancellation is supported. <em>FALSE</em> otherwise.</returns> public static bool SupportsCommandCancellation(this IRelationalStorage storage) { return(SupportsCommandCancellation(storage.InvariantName)); }
/// <summary> /// If the underlying storage supports streaming natively. /// </summary> /// <param name="storage">The storage used.</param> /// <returns><em>TRUE</em> if streaming is supported natively. <em>FALSE</em> otherwise.</returns> public static bool SupportsStreamNatively(this IRelationalStorage storage) { return(SupportsStreamNatively(storage.InvariantName)); }
/// <summary> /// If the underlying ADO.NET implementation is known to be synchronous. /// </summary> /// <param name="storage">The storage used.</param> /// <returns></returns> public static bool IsSynchronousAdoNetImplementation(this IRelationalStorage storage) { //Currently the assumption is all but MySQL are asynchronous. return(IsSynchronousAdoNetImplementation(storage.InvariantName)); }
/// <summary> /// Uses <see cref="IRelationalStorage"/> with <see cref="DbExtensions.ReflectionSelector{TResult}(System.Data.IDataRecord)"/>. /// </summary> /// <param name="storage">The storage to use.</param> /// <param name="query">Executes a given statement. Especially intended to use with <em>INSERT</em>, <em>UPDATE</em>, <em>DELETE</em> or <em>DDL</em> queries.</param> /// <param name="cancellationToken">The cancellation token. Defaults to <see cref="CancellationToken.None"/>.</param> /// <returns>Affected rows count.</returns> public static Task <int> ExecuteAsync(this IRelationalStorage storage, string query, CancellationToken cancellationToken = default(CancellationToken)) { return(ExecuteAsync(storage, query, null, cancellationToken)); }
public static void ClassInitialize(TestContext context) { Console.WriteLine("TestContext.DeploymentDirectory={0}", context.DeploymentDirectory); Console.WriteLine("TestContext="); Console.WriteLine(DumpTestContext(context)); Console.WriteLine("Initializing relational databases..."); relationalStorage = RelationalStorageUtilities.CreateDefaultSqlServerStorageInstance(); Console.WriteLine("Dropping and recreating database '{0}' with connectionstring '{1}'", testDatabaseName, relationalStorage.ConnectionString); if(relationalStorage.ExistsDatabaseAsync(testDatabaseName).Result) { relationalStorage.DropDatabaseAsync(testDatabaseName).Wait(); } relationalStorage.CreateDatabaseAsync(testDatabaseName).Wait(); //The old storage instance has the previous connection string, time have a new handle with a new connection string... relationalStorage = relationalStorage.CreateNewStorageInstance(testDatabaseName); Console.WriteLine("Creating database tables..."); var creationScripts = RelationalStorageUtilities.RemoveBatchSeparators(File.ReadAllText("CreateOrleansTables_SqlServer.sql")); foreach(var creationScript in creationScripts) { var res = relationalStorage.ExecuteAsync(creationScript).Result; } //Currently there's only one database under test, SQL Server. So this as the other //setup is hardcoded here: putting the database in simple recovery mode. //This removes the use of recovery log in case of database crashes, which //improves performance to some degree, depending on usage. For non-performance testing only. var simpleModeRes = relationalStorage.ExecuteAsync(string.Format("ALTER DATABASE [{0}] SET RECOVERY SIMPLE;", testDatabaseName)).Result; Console.WriteLine("Initializing relational databases done."); siloOptions.DataConnectionString = relationalStorage.ConnectionString; }