From 757048a6230be272221520a9314fadc3146df5f1 Mon Sep 17 00:00:00 2001 From: Chebotov Nikolay Date: Tue, 31 Aug 2021 11:36:07 +0300 Subject: [PATCH] feat(DatabaseStorageBase): Add SchemaName parameter --- .../SqlServerStorage.cs | 56 ++++++++++--------- .../Storage/DatabaseStorageBase.cs | 15 +++-- .../Storage/SqlServerStorageTests.cs | 3 +- 3 files changed, 43 insertions(+), 31 deletions(-) diff --git a/src/MiniProfiler.Providers.SqlServer/SqlServerStorage.cs b/src/MiniProfiler.Providers.SqlServer/SqlServerStorage.cs index 89de67fb6..d2474835f 100644 --- a/src/MiniProfiler.Providers.SqlServer/SqlServerStorage.cs +++ b/src/MiniProfiler.Providers.SqlServer/SqlServerStorage.cs @@ -28,28 +28,29 @@ public SqlServerStorage(string connectionString) : base(connectionString) { /* b /// The table name to use for MiniProfilers. /// The table name to use for MiniProfiler Timings. /// The table name to use for MiniProfiler Client Timings. - public SqlServerStorage(string connectionString, string profilersTable, string timingsTable, string clientTimingsTable) - : base(connectionString, profilersTable, timingsTable, clientTimingsTable) { } + /// The database schema to use for MiniProfiler tables. + public SqlServerStorage(string connectionString, string profilersTable = null, string timingsTable = null, string clientTimingsTable = null, string schemaName = null) + : base(connectionString, profilersTable, timingsTable, clientTimingsTable, schemaName) { } private string _saveSql, _saveTimingsSql, _saveClientTimingsSql; private string SaveSql => _saveSql ??= $@" -INSERT INTO {MiniProfilersTable} +INSERT INTO {SchemaName}.{MiniProfilersTable} (Id, RootTimingId, Name, Started, DurationMilliseconds, [User], HasUserViewed, MachineName, CustomLinksJson, ClientTimingsRedirectCount) SELECT @Id, @RootTimingId, @Name, @Started, @DurationMilliseconds, @User, @HasUserViewed, @MachineName, @CustomLinksJson, @ClientTimingsRedirectCount -WHERE NOT EXISTS (SELECT 1 FROM {MiniProfilersTable} WHERE Id = @Id)"; +WHERE NOT EXISTS (SELECT 1 FROM {SchemaName}.{MiniProfilersTable} WHERE Id = @Id)"; private string SaveTimingsSql => _saveTimingsSql ??= $@" -INSERT INTO {MiniProfilerTimingsTable} +INSERT INTO {SchemaName}.{MiniProfilerTimingsTable} (Id, MiniProfilerId, ParentTimingId, Name, DurationMilliseconds, StartMilliseconds, IsRoot, Depth, CustomTimingsJson) SELECT @Id, @MiniProfilerId, @ParentTimingId, @Name, @DurationMilliseconds, @StartMilliseconds, @IsRoot, @Depth, @CustomTimingsJson -WHERE NOT EXISTS (SELECT 1 FROM {MiniProfilerTimingsTable} WHERE Id = @Id)"; +WHERE NOT EXISTS (SELECT 1 FROM {SchemaName}.{MiniProfilerTimingsTable} WHERE Id = @Id)"; private string SaveClientTimingsSql => _saveClientTimingsSql ??= $@" -INSERT INTO {MiniProfilerClientTimingsTable} +INSERT INTO {SchemaName}.{MiniProfilerClientTimingsTable} (Id, MiniProfilerId, Name, Start, Duration) SELECT @Id, @MiniProfilerId, @Name, @Start, @Duration -WHERE NOT EXISTS (SELECT 1 FROM {MiniProfilerClientTimingsTable} WHERE Id = @Id)"; +WHERE NOT EXISTS (SELECT 1 FROM {SchemaName}.{MiniProfilerClientTimingsTable} WHERE Id = @Id)"; /// /// Stores to dbo.MiniProfilers under its ; @@ -181,9 +182,9 @@ public override async Task SaveAsync(MiniProfiler profiler) private string _loadSql; private string LoadSql => _loadSql ??= $@" -SELECT * FROM {MiniProfilersTable} WHERE Id = @id; -SELECT * FROM {MiniProfilerTimingsTable} WHERE MiniProfilerId = @id ORDER BY StartMilliseconds; -SELECT * FROM {MiniProfilerClientTimingsTable} WHERE MiniProfilerId = @id ORDER BY Start;"; +SELECT * FROM {SchemaName}.{MiniProfilersTable} WHERE Id = @id; +SELECT * FROM {SchemaName}.{MiniProfilerTimingsTable} WHERE MiniProfilerId = @id ORDER BY StartMilliseconds; +SELECT * FROM {SchemaName}.{MiniProfilerClientTimingsTable} WHERE MiniProfilerId = @id ORDER BY Start;"; /// /// Loads the MiniProfiler identified by 'id' from the database. @@ -272,7 +273,7 @@ public override async Task LoadAsync(Guid id) private string _toggleViewedSql; private string ToggleViewedSql => _toggleViewedSql ??= $@" -Update {MiniProfilersTable} +Update {SchemaName}.{MiniProfilersTable} Set HasUserViewed = @hasUserVeiwed Where Id = @id And [User] = @user"; @@ -297,7 +298,7 @@ private async Task ToggleViewedAsync(string user, Guid id, bool hasUserVeiwed) private string GetUnviewedIdsSql => _getUnviewedIdsSql ??= $@" Select Id - From {MiniProfilersTable} + From {SchemaName}.{MiniProfilersTable} Where [User] = @user And HasUserViewed = 0 Order By Started"; @@ -367,7 +368,7 @@ private string BuildListQuery(DateTime? start = null, DateTime? finish = null, L var sb = StringBuilderCache.Get(); sb.Append(@" Select Top {=maxResults} Id - From ").Append(MiniProfilersTable).Append(@" + From ").Append(SchemaName).Append(".").Append(MiniProfilersTable).Append(@" "); if (finish != null) { @@ -395,9 +396,12 @@ private string BuildListQuery(DateTime? start = null, DateTime? finish = null, L protected override IEnumerable GetTableCreationScripts() { yield return $@" -CREATE TABLE {MiniProfilersTable} +-- creating schema name if not exists +IF NOT EXISTS ( SELECT * FROM sys.schemas WHERE name = N'{SchemaName}') EXEC('CREATE SCHEMA [{SchemaName}]'); + +CREATE TABLE {SchemaName}.{MiniProfilersTable} ( - RowId integer not null identity constraint PK_{MiniProfilersTable} primary key clustered, -- Need a clustered primary key for SQL Azure + RowId integer not null identity constraint PK_{SchemaName}_{MiniProfilersTable} primary key clustered, -- Need a clustered primary key for SQL Azure Id uniqueidentifier not null, -- don't cluster on a guid RootTimingId uniqueidentifier null, Name nvarchar(200) null, @@ -410,14 +414,14 @@ CustomLinksJson nvarchar(max), ClientTimingsRedirectCount int null ); -- displaying results selects everything based on the main MiniProfilers.Id column -CREATE UNIQUE NONCLUSTERED INDEX IX_{MiniProfilersTable}_Id ON {MiniProfilersTable} (Id); +CREATE UNIQUE NONCLUSTERED INDEX IX_{SchemaName}_{MiniProfilersTable}_Id ON {SchemaName}.{MiniProfilersTable} (Id); -- speeds up a query that is called on every .Stop() -CREATE NONCLUSTERED INDEX IX_{MiniProfilersTable}_User_HasUserViewed_Includes ON {MiniProfilersTable} ([User], HasUserViewed) INCLUDE (Id, [Started]); +CREATE NONCLUSTERED INDEX IX_{SchemaName}_{MiniProfilersTable}_User_HasUserViewed_Includes ON {SchemaName}.{MiniProfilersTable} ([User], HasUserViewed) INCLUDE (Id, [Started]); -CREATE TABLE {MiniProfilerTimingsTable} +CREATE TABLE {SchemaName}.{MiniProfilerTimingsTable} ( - RowId integer not null identity constraint PK_{MiniProfilerTimingsTable} primary key clustered, + RowId integer not null identity constraint PK_{SchemaName}_{MiniProfilerTimingsTable} primary key clustered, Id uniqueidentifier not null, MiniProfilerId uniqueidentifier not null, ParentTimingId uniqueidentifier null, @@ -429,12 +433,12 @@ StartMilliseconds decimal(15,3) not null, CustomTimingsJson nvarchar(max) null ); -CREATE UNIQUE NONCLUSTERED INDEX IX_{MiniProfilerTimingsTable}_Id ON {MiniProfilerTimingsTable} (Id); -CREATE NONCLUSTERED INDEX IX_{MiniProfilerTimingsTable}_MiniProfilerId ON {MiniProfilerTimingsTable} (MiniProfilerId); +CREATE UNIQUE NONCLUSTERED INDEX IX_{SchemaName}_{MiniProfilerTimingsTable}_Id ON {SchemaName}.{MiniProfilerTimingsTable} (Id); +CREATE NONCLUSTERED INDEX IX_{SchemaName}_{MiniProfilerTimingsTable}_MiniProfilerId ON {SchemaName}.{MiniProfilerTimingsTable} (MiniProfilerId); -CREATE TABLE {MiniProfilerClientTimingsTable} +CREATE TABLE {SchemaName}.{MiniProfilerClientTimingsTable} ( - RowId integer not null identity constraint PK_{MiniProfilerClientTimingsTable} primary key clustered, + RowId integer not null identity constraint PK_{SchemaName}_{MiniProfilerClientTimingsTable} primary key clustered, Id uniqueidentifier not null, MiniProfilerId uniqueidentifier not null, Name nvarchar(200) not null, @@ -442,8 +446,8 @@ Start decimal(9, 3) not null, Duration decimal(9, 3) not null ); -CREATE UNIQUE NONCLUSTERED INDEX IX_{MiniProfilerClientTimingsTable}_Id on {MiniProfilerClientTimingsTable} (Id); -CREATE NONCLUSTERED INDEX IX_{MiniProfilerClientTimingsTable}_MiniProfilerId on {MiniProfilerClientTimingsTable} (MiniProfilerId); +CREATE UNIQUE NONCLUSTERED INDEX IX_{SchemaName}_{MiniProfilerClientTimingsTable}_Id on {SchemaName}.{MiniProfilerClientTimingsTable} (Id); +CREATE NONCLUSTERED INDEX IX_{SchemaName}_{MiniProfilerClientTimingsTable}_MiniProfilerId on {SchemaName}.{MiniProfilerClientTimingsTable} (MiniProfilerId); "; } } diff --git a/src/MiniProfiler.Shared/Storage/DatabaseStorageBase.cs b/src/MiniProfiler.Shared/Storage/DatabaseStorageBase.cs index 2682d489d..73afa8eae 100644 --- a/src/MiniProfiler.Shared/Storage/DatabaseStorageBase.cs +++ b/src/MiniProfiler.Shared/Storage/DatabaseStorageBase.cs @@ -26,6 +26,11 @@ public abstract class DatabaseStorageBase : IAsyncStorage, IDatabaseStorageConne /// public readonly string MiniProfilerClientTimingsTable = "MiniProfilerClientTimings"; + /// + /// The database schema to use for MiniProfiler tables. + /// + public readonly string SchemaName = "dbo"; + /// /// Gets or sets how we connect to the database used to save/load MiniProfiler results. /// @@ -49,12 +54,14 @@ protected DatabaseStorageBase(string connectionString) /// The table name to use for MiniProfilers. /// The table name to use for MiniProfiler Timings. /// The table name to use for MiniProfiler Client Timings. - protected DatabaseStorageBase(string connectionString, string profilersTable, string timingsTable, string clientTimingsTable) + /// The database schema to use for MiniProfiler tables. + protected DatabaseStorageBase(string connectionString, string profilersTable = null, string timingsTable = null, string clientTimingsTable = null, string schemaName = null) { ConnectionString = connectionString; - MiniProfilersTable = profilersTable; - MiniProfilerTimingsTable = timingsTable; - MiniProfilerClientTimingsTable = clientTimingsTable; + MiniProfilersTable = profilersTable ?? MiniProfilersTable; + MiniProfilerTimingsTable = timingsTable ?? MiniProfilerTimingsTable; + MiniProfilerClientTimingsTable = clientTimingsTable ?? MiniProfilerClientTimingsTable; + SchemaName = schemaName ?? SchemaName; } /// diff --git a/tests/MiniProfiler.Tests/Storage/SqlServerStorageTests.cs b/tests/MiniProfiler.Tests/Storage/SqlServerStorageTests.cs index 397398a10..4ca9a7fdb 100644 --- a/tests/MiniProfiler.Tests/Storage/SqlServerStorageTests.cs +++ b/tests/MiniProfiler.Tests/Storage/SqlServerStorageTests.cs @@ -22,7 +22,8 @@ public SqlServerStorageFixture() TestConfig.Current.SQLServerConnectionString, "MPTest" + TestId, "MPTimingsTest" + TestId, - "MPClientTimingsTest" + TestId); + "MPClientTimingsTest" + TestId, + "MPSchemaNameTest" + TestId); try { Storage.CreateSchema();