From b492cce83b0a14e7d9da6555c718dca188b3444d Mon Sep 17 00:00:00 2001 From: DevM900 <173990884+DevM900@users.noreply.github.com> Date: Thu, 27 Jun 2024 14:15:48 +0200 Subject: [PATCH 01/13] Creation of backup and restore statistics can be switched off to support Firebird Server 2.0. --- src/FirebirdSql.Data.FirebirdClient/Services/FbBackup.cs | 7 +++++-- src/FirebirdSql.Data.FirebirdClient/Services/FbRestore.cs | 7 +++++-- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/src/FirebirdSql.Data.FirebirdClient/Services/FbBackup.cs b/src/FirebirdSql.Data.FirebirdClient/Services/FbBackup.cs index 35c83387..12537116 100644 --- a/src/FirebirdSql.Data.FirebirdClient/Services/FbBackup.cs +++ b/src/FirebirdSql.Data.FirebirdClient/Services/FbBackup.cs @@ -32,6 +32,7 @@ public sealed class FbBackup : FbService public int Factor { get; set; } public string SkipData { get; set; } public FbBackupFlags Options { get; set; } + public bool IncludeStatistics { get; set; } = true; public FbBackupRestoreStatistics Statistics { get; set; } public FbBackup(string connectionString = null) @@ -67,7 +68,8 @@ public void Execute() if (!string.IsNullOrEmpty(SkipData)) startSpb.Append2(IscCodes.isc_spb_bkp_skip_data, SkipData); startSpb.Append(IscCodes.isc_spb_options, (int)Options); - startSpb.Append2(IscCodes.isc_spb_bkp_stat, Statistics.BuildConfiguration()); + if (IncludeStatistics) + startSpb.Append2(IscCodes.isc_spb_bkp_stat, Statistics.BuildConfiguration()); if (ConnectionStringOptions.ParallelWorkers > 0) startSpb.Append(IscCodes.isc_spb_bkp_parallel_workers, ConnectionStringOptions.ParallelWorkers); StartTask(startSpb); @@ -113,7 +115,8 @@ public async Task ExecuteAsync(CancellationToken cancellationToken = default) if (!string.IsNullOrEmpty(SkipData)) startSpb.Append2(IscCodes.isc_spb_bkp_skip_data, SkipData); startSpb.Append(IscCodes.isc_spb_options, (int)Options); - startSpb.Append2(IscCodes.isc_spb_bkp_stat, Statistics.BuildConfiguration()); + if (IncludeStatistics) + startSpb.Append2(IscCodes.isc_spb_bkp_stat, Statistics.BuildConfiguration()); if (ConnectionStringOptions.ParallelWorkers > 0) startSpb.Append(IscCodes.isc_spb_bkp_parallel_workers, ConnectionStringOptions.ParallelWorkers); await StartTaskAsync(startSpb, cancellationToken).ConfigureAwait(false); diff --git a/src/FirebirdSql.Data.FirebirdClient/Services/FbRestore.cs b/src/FirebirdSql.Data.FirebirdClient/Services/FbRestore.cs index b52c01c6..27a724b7 100644 --- a/src/FirebirdSql.Data.FirebirdClient/Services/FbRestore.cs +++ b/src/FirebirdSql.Data.FirebirdClient/Services/FbRestore.cs @@ -46,6 +46,7 @@ public int? PageSize public bool ReadOnly { get; set; } public string SkipData { get; set; } public FbRestoreFlags Options { get; set; } + public bool IncludeStatistics { get; set; } = true; public FbBackupRestoreStatistics Statistics { get; set; } public FbRestore(string connectionString = null) @@ -82,7 +83,8 @@ public void Execute() if (!string.IsNullOrEmpty(SkipData)) startSpb.Append2(IscCodes.isc_spb_res_skip_data, SkipData); startSpb.Append(IscCodes.isc_spb_options, (int)Options); - startSpb.Append2(IscCodes.isc_spb_res_stat, Statistics.BuildConfiguration()); + if (IncludeStatistics) + startSpb.Append2(IscCodes.isc_spb_res_stat, Statistics.BuildConfiguration()); if (ConnectionStringOptions.ParallelWorkers > 0) startSpb.Append(IscCodes.isc_spb_res_parallel_workers, ConnectionStringOptions.ParallelWorkers); StartTask(startSpb); @@ -129,7 +131,8 @@ public async Task ExecuteAsync(CancellationToken cancellationToken = default) if (!string.IsNullOrEmpty(SkipData)) startSpb.Append2(IscCodes.isc_spb_res_skip_data, SkipData); startSpb.Append(IscCodes.isc_spb_options, (int)Options); - startSpb.Append2(IscCodes.isc_spb_res_stat, Statistics.BuildConfiguration()); + if (IncludeStatistics) + startSpb.Append2(IscCodes.isc_spb_res_stat, Statistics.BuildConfiguration()); if (ConnectionStringOptions.ParallelWorkers > 0) startSpb.Append(IscCodes.isc_spb_res_parallel_workers, ConnectionStringOptions.ParallelWorkers); await StartTaskAsync(startSpb, cancellationToken).ConfigureAwait(false); From c39be07278739dd5951c11708bfd05dff1be741d Mon Sep 17 00:00:00 2001 From: pg <173990884+DevM900@users.noreply.github.com> Date: Fri, 28 Jun 2024 07:47:58 +0200 Subject: [PATCH 02/13] Determination of the correct number of reads, inserts, deletes, etc. per table since the last connection to the database --- .../Common/Extensions.cs | 18 +++++ .../Common/IscHelper.cs | 19 +++--- .../FirebirdClient/FbDatabaseInfo.cs | 65 +++++++++---------- 3 files changed, 61 insertions(+), 41 deletions(-) diff --git a/src/FirebirdSql.Data.FirebirdClient/Common/Extensions.cs b/src/FirebirdSql.Data.FirebirdClient/Common/Extensions.cs index b3d5d432..48c625c0 100644 --- a/src/FirebirdSql.Data.FirebirdClient/Common/Extensions.cs +++ b/src/FirebirdSql.Data.FirebirdClient/Common/Extensions.cs @@ -20,6 +20,8 @@ using System.IO; using System.Linq; using System.Net.Sockets; +using System.Security.Cryptography; +using System.Text; namespace FirebirdSql.Data.Common; @@ -51,6 +53,22 @@ public static string ToHexString(this byte[] b) return BitConverter.ToString(b).Replace("-", string.Empty); } + public static IDictionary GetTableStatistic(this byte[] b, int aLength) + { + int capacity = aLength > 3 ? + (aLength - 3) / 6 + 1 : + 0; + var tableStatistic = new Dictionary(capacity); + for (var i = 3; i < aLength; i += 6) + { + var tableId = (uint)IscHelper.VaxInteger(b, i, 2); + var count = (ulong)IscHelper.VaxInteger(b, i + 2, 4); + tableStatistic.Add(tableId, count); + } + + return tableStatistic; + } + public static IEnumerable> Split(this T[] array, int size) { for (var i = 0; i < (float)array.Length / size; i++) diff --git a/src/FirebirdSql.Data.FirebirdClient/Common/IscHelper.cs b/src/FirebirdSql.Data.FirebirdClient/Common/IscHelper.cs index 578895f7..0b47db5e 100644 --- a/src/FirebirdSql.Data.FirebirdClient/Common/IscHelper.cs +++ b/src/FirebirdSql.Data.FirebirdClient/Common/IscHelper.cs @@ -54,14 +54,6 @@ public static List ParseDatabaseInfo(byte[] buffer, Charset charset) case IscCodes.isc_info_marks: case IscCodes.isc_info_reads: case IscCodes.isc_info_writes: - case IscCodes.isc_info_backout_count: - case IscCodes.isc_info_delete_count: - case IscCodes.isc_info_expunge_count: - case IscCodes.isc_info_insert_count: - case IscCodes.isc_info_purge_count: - case IscCodes.isc_info_read_idx_count: - case IscCodes.isc_info_read_seq_count: - case IscCodes.isc_info_update_count: case IscCodes.isc_info_db_size_in_pages: case IscCodes.isc_info_oldest_transaction: case IscCodes.isc_info_oldest_active: @@ -77,6 +69,17 @@ public static List ParseDatabaseInfo(byte[] buffer, Charset charset) info.Add(VaxInteger(buffer, pos, length)); break; + case IscCodes.isc_info_backout_count: + case IscCodes.isc_info_delete_count: + case IscCodes.isc_info_expunge_count: + case IscCodes.isc_info_insert_count: + case IscCodes.isc_info_purge_count: + case IscCodes.isc_info_update_count: + case IscCodes.isc_info_read_seq_count: + case IscCodes.isc_info_read_idx_count: + info.Add( buffer.GetTableStatistic( length ) ); + break; + case IscCodes.isc_info_no_reserve: case IscCodes.isc_info_forced_writes: case IscCodes.isc_info_db_read_only: diff --git a/src/FirebirdSql.Data.FirebirdClient/FirebirdClient/FbDatabaseInfo.cs b/src/FirebirdSql.Data.FirebirdClient/FirebirdClient/FbDatabaseInfo.cs index 7f6dc6c9..a01f9313 100644 --- a/src/FirebirdSql.Data.FirebirdClient/FirebirdClient/FbDatabaseInfo.cs +++ b/src/FirebirdSql.Data.FirebirdClient/FirebirdClient/FbDatabaseInfo.cs @@ -17,7 +17,6 @@ using System; using System.Collections.Generic; -using System.Data; using System.Linq; using System.Threading; using System.Threading.Tasks; @@ -225,76 +224,76 @@ public Task GetWritesAsync(CancellationToken cancellationToken = default) return GetValueAsync(IscCodes.isc_info_writes, cancellationToken); } - public int GetBackoutCount() + public IDictionary GetBackoutCount() { - return GetValue(IscCodes.isc_info_backout_count); + return GetValue>( IscCodes.isc_info_backout_count ); } - public Task GetBackoutCountAsync(CancellationToken cancellationToken = default) + public Task> GetBackoutCountAsync( CancellationToken cancellationToken = default ) { - return GetValueAsync(IscCodes.isc_info_backout_count, cancellationToken); + return GetValueAsync>( IscCodes.isc_info_backout_count, cancellationToken ); } - public int GetDeleteCount() + public IDictionary GetDeleteCount() { - return GetValue(IscCodes.isc_info_delete_count); + return GetValue>( IscCodes.isc_info_delete_count ); } - public Task GetDeleteCountAsync(CancellationToken cancellationToken = default) + public Task> GetDeleteCountAsync( CancellationToken cancellationToken = default ) { - return GetValueAsync(IscCodes.isc_info_delete_count, cancellationToken); + return GetValueAsync>( IscCodes.isc_info_delete_count, cancellationToken ); } - public int GetExpungeCount() + public IDictionary GetExpungeCount() { - return GetValue(IscCodes.isc_info_expunge_count); + return GetValue>( IscCodes.isc_info_expunge_count ); } - public Task GetExpungeCountAsync(CancellationToken cancellationToken = default) + public Task> GetExpungeCountAsync( CancellationToken cancellationToken = default ) { - return GetValueAsync(IscCodes.isc_info_expunge_count, cancellationToken); + return GetValueAsync>( IscCodes.isc_info_expunge_count, cancellationToken ); } - public int GetInsertCount() + public IDictionary GetInsertCount() { - return GetValue(IscCodes.isc_info_insert_count); + return GetValue>( IscCodes.isc_info_insert_count ); } - public Task GetInsertCountAsync(CancellationToken cancellationToken = default) + public Task> GetInsertCountAsync( CancellationToken cancellationToken = default ) { - return GetValueAsync(IscCodes.isc_info_insert_count, cancellationToken); + return GetValueAsync>( IscCodes.isc_info_insert_count, cancellationToken ); } - public int GetPurgeCount() + public IDictionary GetPurgeCount() { - return GetValue(IscCodes.isc_info_purge_count); + return GetValue>( IscCodes.isc_info_purge_count ); } - public Task GetPurgeCountAsync(CancellationToken cancellationToken = default) + public Task> GetPurgeCountAsync( CancellationToken cancellationToken = default ) { - return GetValueAsync(IscCodes.isc_info_purge_count, cancellationToken); + return GetValueAsync>( IscCodes.isc_info_purge_count, cancellationToken ); } - public long GetReadIdxCount() + public IDictionary GetReadIdxCount() { - return GetValue(IscCodes.isc_info_read_idx_count); + return GetValue>( IscCodes.isc_info_read_idx_count ); } - public Task GetReadIdxCountAsync(CancellationToken cancellationToken = default) + public Task> GetReadIdxCountAsync( CancellationToken cancellationToken = default ) { - return GetValueAsync(IscCodes.isc_info_read_idx_count, cancellationToken); + return GetValueAsync>( IscCodes.isc_info_read_idx_count, cancellationToken ); } - public long GetReadSeqCount() + public IDictionary GetReadSeqCount() { - return GetValue(IscCodes.isc_info_read_seq_count); + return GetValue>( IscCodes.isc_info_read_seq_count ); } - public Task GetReadSeqCountAsync(CancellationToken cancellationToken = default) + public Task> GetReadSeqCountAsync( CancellationToken cancellationToken = default ) { - return GetValueAsync(IscCodes.isc_info_read_seq_count, cancellationToken); + return GetValueAsync>( IscCodes.isc_info_read_seq_count, cancellationToken ); } - public long GetUpdateCount() + public IDictionary GetUpdateCount() { - return GetValue(IscCodes.isc_info_update_count); + return GetValue>( IscCodes.isc_info_update_count ); } - public Task GetUpdateCountAsync(CancellationToken cancellationToken = default) + public Task> GetUpdateCountAsync( CancellationToken cancellationToken = default ) { - return GetValueAsync(IscCodes.isc_info_update_count, cancellationToken); + return GetValueAsync>( IscCodes.isc_info_update_count, cancellationToken ); } public int GetDatabaseSizeInPages() From 1fd2464e82a32dbf6ea49abe54c7518460b67ff7 Mon Sep 17 00:00:00 2001 From: pg <173990884+DevM900@users.noreply.github.com> Date: Fri, 28 Jun 2024 07:47:58 +0200 Subject: [PATCH 03/13] Determination of the correct number of reads, inserts, deletes, etc. per table since the last connection to the database. fixes #1157 --- .../Common/Extensions.cs | 18 +++++ .../Common/IscHelper.cs | 19 +++--- .../FirebirdClient/FbDatabaseInfo.cs | 65 +++++++++---------- 3 files changed, 61 insertions(+), 41 deletions(-) diff --git a/src/FirebirdSql.Data.FirebirdClient/Common/Extensions.cs b/src/FirebirdSql.Data.FirebirdClient/Common/Extensions.cs index b3d5d432..48c625c0 100644 --- a/src/FirebirdSql.Data.FirebirdClient/Common/Extensions.cs +++ b/src/FirebirdSql.Data.FirebirdClient/Common/Extensions.cs @@ -20,6 +20,8 @@ using System.IO; using System.Linq; using System.Net.Sockets; +using System.Security.Cryptography; +using System.Text; namespace FirebirdSql.Data.Common; @@ -51,6 +53,22 @@ public static string ToHexString(this byte[] b) return BitConverter.ToString(b).Replace("-", string.Empty); } + public static IDictionary GetTableStatistic(this byte[] b, int aLength) + { + int capacity = aLength > 3 ? + (aLength - 3) / 6 + 1 : + 0; + var tableStatistic = new Dictionary(capacity); + for (var i = 3; i < aLength; i += 6) + { + var tableId = (uint)IscHelper.VaxInteger(b, i, 2); + var count = (ulong)IscHelper.VaxInteger(b, i + 2, 4); + tableStatistic.Add(tableId, count); + } + + return tableStatistic; + } + public static IEnumerable> Split(this T[] array, int size) { for (var i = 0; i < (float)array.Length / size; i++) diff --git a/src/FirebirdSql.Data.FirebirdClient/Common/IscHelper.cs b/src/FirebirdSql.Data.FirebirdClient/Common/IscHelper.cs index 578895f7..0b47db5e 100644 --- a/src/FirebirdSql.Data.FirebirdClient/Common/IscHelper.cs +++ b/src/FirebirdSql.Data.FirebirdClient/Common/IscHelper.cs @@ -54,14 +54,6 @@ public static List ParseDatabaseInfo(byte[] buffer, Charset charset) case IscCodes.isc_info_marks: case IscCodes.isc_info_reads: case IscCodes.isc_info_writes: - case IscCodes.isc_info_backout_count: - case IscCodes.isc_info_delete_count: - case IscCodes.isc_info_expunge_count: - case IscCodes.isc_info_insert_count: - case IscCodes.isc_info_purge_count: - case IscCodes.isc_info_read_idx_count: - case IscCodes.isc_info_read_seq_count: - case IscCodes.isc_info_update_count: case IscCodes.isc_info_db_size_in_pages: case IscCodes.isc_info_oldest_transaction: case IscCodes.isc_info_oldest_active: @@ -77,6 +69,17 @@ public static List ParseDatabaseInfo(byte[] buffer, Charset charset) info.Add(VaxInteger(buffer, pos, length)); break; + case IscCodes.isc_info_backout_count: + case IscCodes.isc_info_delete_count: + case IscCodes.isc_info_expunge_count: + case IscCodes.isc_info_insert_count: + case IscCodes.isc_info_purge_count: + case IscCodes.isc_info_update_count: + case IscCodes.isc_info_read_seq_count: + case IscCodes.isc_info_read_idx_count: + info.Add( buffer.GetTableStatistic( length ) ); + break; + case IscCodes.isc_info_no_reserve: case IscCodes.isc_info_forced_writes: case IscCodes.isc_info_db_read_only: diff --git a/src/FirebirdSql.Data.FirebirdClient/FirebirdClient/FbDatabaseInfo.cs b/src/FirebirdSql.Data.FirebirdClient/FirebirdClient/FbDatabaseInfo.cs index 7f6dc6c9..a01f9313 100644 --- a/src/FirebirdSql.Data.FirebirdClient/FirebirdClient/FbDatabaseInfo.cs +++ b/src/FirebirdSql.Data.FirebirdClient/FirebirdClient/FbDatabaseInfo.cs @@ -17,7 +17,6 @@ using System; using System.Collections.Generic; -using System.Data; using System.Linq; using System.Threading; using System.Threading.Tasks; @@ -225,76 +224,76 @@ public Task GetWritesAsync(CancellationToken cancellationToken = default) return GetValueAsync(IscCodes.isc_info_writes, cancellationToken); } - public int GetBackoutCount() + public IDictionary GetBackoutCount() { - return GetValue(IscCodes.isc_info_backout_count); + return GetValue>( IscCodes.isc_info_backout_count ); } - public Task GetBackoutCountAsync(CancellationToken cancellationToken = default) + public Task> GetBackoutCountAsync( CancellationToken cancellationToken = default ) { - return GetValueAsync(IscCodes.isc_info_backout_count, cancellationToken); + return GetValueAsync>( IscCodes.isc_info_backout_count, cancellationToken ); } - public int GetDeleteCount() + public IDictionary GetDeleteCount() { - return GetValue(IscCodes.isc_info_delete_count); + return GetValue>( IscCodes.isc_info_delete_count ); } - public Task GetDeleteCountAsync(CancellationToken cancellationToken = default) + public Task> GetDeleteCountAsync( CancellationToken cancellationToken = default ) { - return GetValueAsync(IscCodes.isc_info_delete_count, cancellationToken); + return GetValueAsync>( IscCodes.isc_info_delete_count, cancellationToken ); } - public int GetExpungeCount() + public IDictionary GetExpungeCount() { - return GetValue(IscCodes.isc_info_expunge_count); + return GetValue>( IscCodes.isc_info_expunge_count ); } - public Task GetExpungeCountAsync(CancellationToken cancellationToken = default) + public Task> GetExpungeCountAsync( CancellationToken cancellationToken = default ) { - return GetValueAsync(IscCodes.isc_info_expunge_count, cancellationToken); + return GetValueAsync>( IscCodes.isc_info_expunge_count, cancellationToken ); } - public int GetInsertCount() + public IDictionary GetInsertCount() { - return GetValue(IscCodes.isc_info_insert_count); + return GetValue>( IscCodes.isc_info_insert_count ); } - public Task GetInsertCountAsync(CancellationToken cancellationToken = default) + public Task> GetInsertCountAsync( CancellationToken cancellationToken = default ) { - return GetValueAsync(IscCodes.isc_info_insert_count, cancellationToken); + return GetValueAsync>( IscCodes.isc_info_insert_count, cancellationToken ); } - public int GetPurgeCount() + public IDictionary GetPurgeCount() { - return GetValue(IscCodes.isc_info_purge_count); + return GetValue>( IscCodes.isc_info_purge_count ); } - public Task GetPurgeCountAsync(CancellationToken cancellationToken = default) + public Task> GetPurgeCountAsync( CancellationToken cancellationToken = default ) { - return GetValueAsync(IscCodes.isc_info_purge_count, cancellationToken); + return GetValueAsync>( IscCodes.isc_info_purge_count, cancellationToken ); } - public long GetReadIdxCount() + public IDictionary GetReadIdxCount() { - return GetValue(IscCodes.isc_info_read_idx_count); + return GetValue>( IscCodes.isc_info_read_idx_count ); } - public Task GetReadIdxCountAsync(CancellationToken cancellationToken = default) + public Task> GetReadIdxCountAsync( CancellationToken cancellationToken = default ) { - return GetValueAsync(IscCodes.isc_info_read_idx_count, cancellationToken); + return GetValueAsync>( IscCodes.isc_info_read_idx_count, cancellationToken ); } - public long GetReadSeqCount() + public IDictionary GetReadSeqCount() { - return GetValue(IscCodes.isc_info_read_seq_count); + return GetValue>( IscCodes.isc_info_read_seq_count ); } - public Task GetReadSeqCountAsync(CancellationToken cancellationToken = default) + public Task> GetReadSeqCountAsync( CancellationToken cancellationToken = default ) { - return GetValueAsync(IscCodes.isc_info_read_seq_count, cancellationToken); + return GetValueAsync>( IscCodes.isc_info_read_seq_count, cancellationToken ); } - public long GetUpdateCount() + public IDictionary GetUpdateCount() { - return GetValue(IscCodes.isc_info_update_count); + return GetValue>( IscCodes.isc_info_update_count ); } - public Task GetUpdateCountAsync(CancellationToken cancellationToken = default) + public Task> GetUpdateCountAsync( CancellationToken cancellationToken = default ) { - return GetValueAsync(IscCodes.isc_info_update_count, cancellationToken); + return GetValueAsync>( IscCodes.isc_info_update_count, cancellationToken ); } public int GetDatabaseSizeInPages() From 9112e2847f6738ac8101bd3adf3a65f9ec4ba7b4 Mon Sep 17 00:00:00 2001 From: DevM900 <173990884+DevM900@users.noreply.github.com> Date: Fri, 28 Jun 2024 12:14:34 +0200 Subject: [PATCH 04/13] Added comments. --- .../FirebirdClient/FbDatabaseInfo.cs | 113 ++++++++++++++---- 1 file changed, 89 insertions(+), 24 deletions(-) diff --git a/src/FirebirdSql.Data.FirebirdClient/FirebirdClient/FbDatabaseInfo.cs b/src/FirebirdSql.Data.FirebirdClient/FirebirdClient/FbDatabaseInfo.cs index a01f9313..e370a2ca 100644 --- a/src/FirebirdSql.Data.FirebirdClient/FirebirdClient/FbDatabaseInfo.cs +++ b/src/FirebirdSql.Data.FirebirdClient/FirebirdClient/FbDatabaseInfo.cs @@ -224,76 +224,141 @@ public Task GetWritesAsync(CancellationToken cancellationToken = default) return GetValueAsync(IscCodes.isc_info_writes, cancellationToken); } + /// + /// Returns the number of removals of a version of a record of the affected tables. + /// + /// Dictionary with the number of removals, with table id (field RDB$RELATION_ID of the system table RDB$RELATIONS) as key. public IDictionary GetBackoutCount() { - return GetValue>( IscCodes.isc_info_backout_count ); + return GetValue>(IscCodes.isc_info_backout_count); } - public Task> GetBackoutCountAsync( CancellationToken cancellationToken = default ) + /// + /// Returns the number of removals of a version of a record of the affected tables. + /// + /// Dictionary with the number of removals, with table id (field RDB$RELATION_ID of the system table RDB$RELATIONS) as key. + public Task> GetBackoutCountAsync(CancellationToken cancellationToken = default) { - return GetValueAsync>( IscCodes.isc_info_backout_count, cancellationToken ); + return GetValueAsync>(IscCodes.isc_info_backout_count, cancellationToken); } + /// + /// Returns the number of database deletes of the affected tables since the database was last attached. + /// + /// Dictionary with the number of deletes, with table id (field RDB$RELATION_ID of the system table RDB$RELATIONS) as key. public IDictionary GetDeleteCount() { - return GetValue>( IscCodes.isc_info_delete_count ); + return GetValue>(IscCodes.isc_info_delete_count); } - public Task> GetDeleteCountAsync( CancellationToken cancellationToken = default ) + /// + /// Returns the number of database deletes of the affected tables since the database was last attached. + /// + /// Dictionary with the number of deletes, with table id (field RDB$RELATION_ID of the system table RDB$RELATIONS) as key. + public Task> GetDeleteCountAsync(CancellationToken cancellationToken = default) { - return GetValueAsync>( IscCodes.isc_info_delete_count, cancellationToken ); + return GetValueAsync>(IscCodes.isc_info_delete_count, cancellationToken); } + /// + /// Returns the number of removals of a record and all of its ancestors, for records whose deletions have been committed of the affected tables since the database was last attached. + /// + /// Dictionary with the number of removals, with table id (field RDB$RELATION_ID of the system table RDB$RELATIONS) as key. public IDictionary GetExpungeCount() { - return GetValue>( IscCodes.isc_info_expunge_count ); + return GetValue>(IscCodes.isc_info_expunge_count); } - public Task> GetExpungeCountAsync( CancellationToken cancellationToken = default ) + + /// + /// Returns the number of removals of a record and all of its ancestors, for records whose deletions have been committed of the affected tables since the database was last attached. + /// + /// Dictionary with the number of removals, with table id (field RDB$RELATION_ID of the system table RDB$RELATIONS) as key. + public Task> GetExpungeCountAsync(CancellationToken cancellationToken = default) { - return GetValueAsync>( IscCodes.isc_info_expunge_count, cancellationToken ); + return GetValueAsync>(IscCodes.isc_info_expunge_count, cancellationToken); } + /// + /// Returns the number of inserts into the database of the affected tables since the database was last attached. + /// + /// Dictionary with the number of inserts, with table id (field RDB$RELATION_ID of the system table RDB$RELATIONS) as key. public IDictionary GetInsertCount() { - return GetValue>( IscCodes.isc_info_insert_count ); + return GetValue>(IscCodes.isc_info_insert_count); } - public Task> GetInsertCountAsync( CancellationToken cancellationToken = default ) + /// + /// Returns the number of inserts into the database of the affected tables since the database was last attached. + /// + /// Dictionary with the number of inserts, with table id (field RDB$RELATION_ID of the system table RDB$RELATIONS) as key. + public Task> GetInsertCountAsync(CancellationToken cancellationToken = default) { - return GetValueAsync>( IscCodes.isc_info_insert_count, cancellationToken ); + return GetValueAsync>(IscCodes.isc_info_insert_count, cancellationToken); } + /// + /// Returns the number of removals of old versions of fully mature records (records that are committed, so that older ancestor versions are no longer needed) of the affected tables. + /// + /// Dictionary with the number of removals, with table id (field RDB$RELATION_ID of the system table RDB$RELATIONS) as key. public IDictionary GetPurgeCount() { - return GetValue>( IscCodes.isc_info_purge_count ); + return GetValue>(IscCodes.isc_info_purge_count); } - public Task> GetPurgeCountAsync( CancellationToken cancellationToken = default ) + /// + /// Returns the number of removals of old versions of fully mature records (records that are committed, so that older ancestor versions are no longer needed) of the affected tables. + /// + /// Dictionary with the number of removals, with table id (field RDB$RELATION_ID of the system table RDB$RELATIONS) as key. + public Task> GetPurgeCountAsync(CancellationToken cancellationToken = default) { - return GetValueAsync>( IscCodes.isc_info_purge_count, cancellationToken ); + return GetValueAsync>(IscCodes.isc_info_purge_count, cancellationToken); } + /// + /// Returns the number of reads done via an index of the affected tables since the database was last attached. + /// + /// Dictionary with the number of reads, with table id (field RDB$RELATION_ID of the system table RDB$RELATIONS) as key. public IDictionary GetReadIdxCount() { - return GetValue>( IscCodes.isc_info_read_idx_count ); + return GetValue>(IscCodes.isc_info_read_idx_count); } - public Task> GetReadIdxCountAsync( CancellationToken cancellationToken = default ) + /// + /// Returns the number of reads done via an index of the affected tables since the database was last attached. + /// + /// Dictionary with the number of reads, with table id (field RDB$RELATION_ID of the system table RDB$RELATIONS) as key. + public Task> GetReadIdxCountAsync(CancellationToken cancellationToken = default) { - return GetValueAsync>( IscCodes.isc_info_read_idx_count, cancellationToken ); + return GetValueAsync>(IscCodes.isc_info_read_idx_count, cancellationToken); } + /// + /// Returns the number of sequential table scans (row reads) of the affected tables since the database was last attached. + /// + /// Dictionary with the number of reads, with table id (field RDB$RELATION_ID of the system table RDB$RELATIONS) as key. public IDictionary GetReadSeqCount() { - return GetValue>( IscCodes.isc_info_read_seq_count ); + return GetValue>(IscCodes.isc_info_read_seq_count); } - public Task> GetReadSeqCountAsync( CancellationToken cancellationToken = default ) + /// + /// Returns the number of sequential table scans (row reads) of the affected tables since the database was last attached. + /// + /// Dictionary with the number of reads, with table id (field RDB$RELATION_ID of the system table RDB$RELATIONS) as key. + public Task> GetReadSeqCountAsync(CancellationToken cancellationToken = default) { - return GetValueAsync>( IscCodes.isc_info_read_seq_count, cancellationToken ); + return GetValueAsync>(IscCodes.isc_info_read_seq_count, cancellationToken); } + /// + /// Returns the number of database updates of the affected tables since the database was last attached. + /// + /// Dictionary with the number of updates, with table id (field RDB$RELATION_ID of the system table RDB$RELATIONS) as key. public IDictionary GetUpdateCount() { - return GetValue>( IscCodes.isc_info_update_count ); + return GetValue>(IscCodes.isc_info_update_count); } - public Task> GetUpdateCountAsync( CancellationToken cancellationToken = default ) + /// + /// Returns the number of database updates of the affected tables since the database was last attached. + /// + /// Dictionary with the number of updates, with table id (field RDB$RELATION_ID of the system table RDB$RELATIONS) as key. + public Task> GetUpdateCountAsync(CancellationToken cancellationToken = default) { - return GetValueAsync>( IscCodes.isc_info_update_count, cancellationToken ); + return GetValueAsync>(IscCodes.isc_info_update_count, cancellationToken); } public int GetDatabaseSizeInPages() From 124e5f3583867edf27e43ce711aa1784ffb1052d Mon Sep 17 00:00:00 2001 From: DevM900 <173990884+DevM900@users.noreply.github.com> Date: Thu, 4 Jul 2024 07:54:34 +0200 Subject: [PATCH 05/13] Type of the key of the result collection changed from "uint" to "short". --- src/FirebirdSql.Data.FirebirdClient/Common/Extensions.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/FirebirdSql.Data.FirebirdClient/Common/Extensions.cs b/src/FirebirdSql.Data.FirebirdClient/Common/Extensions.cs index 48c625c0..38bbf40c 100644 --- a/src/FirebirdSql.Data.FirebirdClient/Common/Extensions.cs +++ b/src/FirebirdSql.Data.FirebirdClient/Common/Extensions.cs @@ -53,15 +53,15 @@ public static string ToHexString(this byte[] b) return BitConverter.ToString(b).Replace("-", string.Empty); } - public static IDictionary GetTableStatistic(this byte[] b, int aLength) + public static IDictionary GetTableStatistic(this byte[] b, int aLength) { int capacity = aLength > 3 ? (aLength - 3) / 6 + 1 : 0; - var tableStatistic = new Dictionary(capacity); + var tableStatistic = new Dictionary(capacity); for (var i = 3; i < aLength; i += 6) { - var tableId = (uint)IscHelper.VaxInteger(b, i, 2); + var tableId = (short)IscHelper.VaxInteger(b, i, 2); var count = (ulong)IscHelper.VaxInteger(b, i + 2, 4); tableStatistic.Add(tableId, count); } From c43a1bfe68077cff84cef502b96434c23189e2da Mon Sep 17 00:00:00 2001 From: DevM900 <173990884+DevM900@users.noreply.github.com> Date: Thu, 4 Jul 2024 07:55:04 +0200 Subject: [PATCH 06/13] Type of the key of the result collection changed from "uint" to "short". --- .../FirebirdClient/FbDatabaseInfo.cs | 64 +++++++++---------- 1 file changed, 32 insertions(+), 32 deletions(-) diff --git a/src/FirebirdSql.Data.FirebirdClient/FirebirdClient/FbDatabaseInfo.cs b/src/FirebirdSql.Data.FirebirdClient/FirebirdClient/FbDatabaseInfo.cs index e370a2ca..18ee51d2 100644 --- a/src/FirebirdSql.Data.FirebirdClient/FirebirdClient/FbDatabaseInfo.cs +++ b/src/FirebirdSql.Data.FirebirdClient/FirebirdClient/FbDatabaseInfo.cs @@ -228,137 +228,137 @@ public Task GetWritesAsync(CancellationToken cancellationToken = default) /// Returns the number of removals of a version of a record of the affected tables. /// /// Dictionary with the number of removals, with table id (field RDB$RELATION_ID of the system table RDB$RELATIONS) as key. - public IDictionary GetBackoutCount() + public IDictionary GetBackoutCount() { - return GetValue>(IscCodes.isc_info_backout_count); + return GetValue>(IscCodes.isc_info_backout_count); } /// /// Returns the number of removals of a version of a record of the affected tables. /// /// Dictionary with the number of removals, with table id (field RDB$RELATION_ID of the system table RDB$RELATIONS) as key. - public Task> GetBackoutCountAsync(CancellationToken cancellationToken = default) + public Task> GetBackoutCountAsync(CancellationToken cancellationToken = default) { - return GetValueAsync>(IscCodes.isc_info_backout_count, cancellationToken); + return GetValueAsync>(IscCodes.isc_info_backout_count, cancellationToken); } /// /// Returns the number of database deletes of the affected tables since the database was last attached. /// /// Dictionary with the number of deletes, with table id (field RDB$RELATION_ID of the system table RDB$RELATIONS) as key. - public IDictionary GetDeleteCount() + public IDictionary GetDeleteCount() { - return GetValue>(IscCodes.isc_info_delete_count); + return GetValue>(IscCodes.isc_info_delete_count); } /// /// Returns the number of database deletes of the affected tables since the database was last attached. /// /// Dictionary with the number of deletes, with table id (field RDB$RELATION_ID of the system table RDB$RELATIONS) as key. - public Task> GetDeleteCountAsync(CancellationToken cancellationToken = default) + public Task> GetDeleteCountAsync(CancellationToken cancellationToken = default) { - return GetValueAsync>(IscCodes.isc_info_delete_count, cancellationToken); + return GetValueAsync>(IscCodes.isc_info_delete_count, cancellationToken); } /// /// Returns the number of removals of a record and all of its ancestors, for records whose deletions have been committed of the affected tables since the database was last attached. /// /// Dictionary with the number of removals, with table id (field RDB$RELATION_ID of the system table RDB$RELATIONS) as key. - public IDictionary GetExpungeCount() + public IDictionary GetExpungeCount() { - return GetValue>(IscCodes.isc_info_expunge_count); + return GetValue>(IscCodes.isc_info_expunge_count); } /// /// Returns the number of removals of a record and all of its ancestors, for records whose deletions have been committed of the affected tables since the database was last attached. /// /// Dictionary with the number of removals, with table id (field RDB$RELATION_ID of the system table RDB$RELATIONS) as key. - public Task> GetExpungeCountAsync(CancellationToken cancellationToken = default) + public Task> GetExpungeCountAsync(CancellationToken cancellationToken = default) { - return GetValueAsync>(IscCodes.isc_info_expunge_count, cancellationToken); + return GetValueAsync>(IscCodes.isc_info_expunge_count, cancellationToken); } /// /// Returns the number of inserts into the database of the affected tables since the database was last attached. /// /// Dictionary with the number of inserts, with table id (field RDB$RELATION_ID of the system table RDB$RELATIONS) as key. - public IDictionary GetInsertCount() + public IDictionary GetInsertCount() { - return GetValue>(IscCodes.isc_info_insert_count); + return GetValue>(IscCodes.isc_info_insert_count); } /// /// Returns the number of inserts into the database of the affected tables since the database was last attached. /// /// Dictionary with the number of inserts, with table id (field RDB$RELATION_ID of the system table RDB$RELATIONS) as key. - public Task> GetInsertCountAsync(CancellationToken cancellationToken = default) + public Task> GetInsertCountAsync(CancellationToken cancellationToken = default) { - return GetValueAsync>(IscCodes.isc_info_insert_count, cancellationToken); + return GetValueAsync>(IscCodes.isc_info_insert_count, cancellationToken); } /// /// Returns the number of removals of old versions of fully mature records (records that are committed, so that older ancestor versions are no longer needed) of the affected tables. /// /// Dictionary with the number of removals, with table id (field RDB$RELATION_ID of the system table RDB$RELATIONS) as key. - public IDictionary GetPurgeCount() + public IDictionary GetPurgeCount() { - return GetValue>(IscCodes.isc_info_purge_count); + return GetValue>(IscCodes.isc_info_purge_count); } /// /// Returns the number of removals of old versions of fully mature records (records that are committed, so that older ancestor versions are no longer needed) of the affected tables. /// /// Dictionary with the number of removals, with table id (field RDB$RELATION_ID of the system table RDB$RELATIONS) as key. - public Task> GetPurgeCountAsync(CancellationToken cancellationToken = default) + public Task> GetPurgeCountAsync(CancellationToken cancellationToken = default) { - return GetValueAsync>(IscCodes.isc_info_purge_count, cancellationToken); + return GetValueAsync>(IscCodes.isc_info_purge_count, cancellationToken); } /// /// Returns the number of reads done via an index of the affected tables since the database was last attached. /// /// Dictionary with the number of reads, with table id (field RDB$RELATION_ID of the system table RDB$RELATIONS) as key. - public IDictionary GetReadIdxCount() + public IDictionary GetReadIdxCount() { - return GetValue>(IscCodes.isc_info_read_idx_count); + return GetValue>(IscCodes.isc_info_read_idx_count); } /// /// Returns the number of reads done via an index of the affected tables since the database was last attached. /// /// Dictionary with the number of reads, with table id (field RDB$RELATION_ID of the system table RDB$RELATIONS) as key. - public Task> GetReadIdxCountAsync(CancellationToken cancellationToken = default) + public Task> GetReadIdxCountAsync(CancellationToken cancellationToken = default) { - return GetValueAsync>(IscCodes.isc_info_read_idx_count, cancellationToken); + return GetValueAsync>(IscCodes.isc_info_read_idx_count, cancellationToken); } /// /// Returns the number of sequential table scans (row reads) of the affected tables since the database was last attached. /// /// Dictionary with the number of reads, with table id (field RDB$RELATION_ID of the system table RDB$RELATIONS) as key. - public IDictionary GetReadSeqCount() + public IDictionary GetReadSeqCount() { - return GetValue>(IscCodes.isc_info_read_seq_count); + return GetValue>(IscCodes.isc_info_read_seq_count); } /// /// Returns the number of sequential table scans (row reads) of the affected tables since the database was last attached. /// /// Dictionary with the number of reads, with table id (field RDB$RELATION_ID of the system table RDB$RELATIONS) as key. - public Task> GetReadSeqCountAsync(CancellationToken cancellationToken = default) + public Task> GetReadSeqCountAsync(CancellationToken cancellationToken = default) { - return GetValueAsync>(IscCodes.isc_info_read_seq_count, cancellationToken); + return GetValueAsync>(IscCodes.isc_info_read_seq_count, cancellationToken); } /// /// Returns the number of database updates of the affected tables since the database was last attached. /// /// Dictionary with the number of updates, with table id (field RDB$RELATION_ID of the system table RDB$RELATIONS) as key. - public IDictionary GetUpdateCount() + public IDictionary GetUpdateCount() { - return GetValue>(IscCodes.isc_info_update_count); + return GetValue>(IscCodes.isc_info_update_count); } /// /// Returns the number of database updates of the affected tables since the database was last attached. /// /// Dictionary with the number of updates, with table id (field RDB$RELATION_ID of the system table RDB$RELATIONS) as key. - public Task> GetUpdateCountAsync(CancellationToken cancellationToken = default) + public Task> GetUpdateCountAsync(CancellationToken cancellationToken = default) { - return GetValueAsync>(IscCodes.isc_info_update_count, cancellationToken); + return GetValueAsync>(IscCodes.isc_info_update_count, cancellationToken); } public int GetDatabaseSizeInPages() From 72ed3187369d14b55d2b7e18f02baa34efa8b4a7 Mon Sep 17 00:00:00 2001 From: DevM900 <173990884+DevM900@users.noreply.github.com> Date: Thu, 4 Jul 2024 08:50:25 +0200 Subject: [PATCH 07/13] Added tests for determination of the number of reads, inserts, deletes etc --- .../FbDatabaseInfoTests.cs | 116 ++++++++++++++++++ 1 file changed, 116 insertions(+) diff --git a/src/FirebirdSql.Data.FirebirdClient.Tests/FbDatabaseInfoTests.cs b/src/FirebirdSql.Data.FirebirdClient.Tests/FbDatabaseInfoTests.cs index d1a34b86..4a77218b 100644 --- a/src/FirebirdSql.Data.FirebirdClient.Tests/FbDatabaseInfoTests.cs +++ b/src/FirebirdSql.Data.FirebirdClient.Tests/FbDatabaseInfoTests.cs @@ -16,6 +16,7 @@ //$Authors = Carlos Guzman Alvarez, Jiri Cincura (jiri@cincura.net) using System; +using System.Collections.Generic; using System.Linq; using System.Reflection; using System.Threading; @@ -61,4 +62,119 @@ public void CompleteDatabaseInfoTest() Assert.DoesNotThrowAsync(() => (Task)m.Invoke(dbInfo, new object[] { CancellationToken.None }), m.Name); } } + + [Test] + public void PerformanceAnalysis_SELECT_Test() + { + IDictionary tableNameList = GetTableNameList(); + short tableIdTest = tableNameList["TEST"]; + + var dbInfo = new FbDatabaseInfo(Connection); + IDictionary insertCount = dbInfo.GetInsertCount(); + IDictionary updateCount = dbInfo.GetUpdateCount(); + IDictionary readSeqCount = dbInfo.GetReadSeqCount(); + IDictionary readIdxCount = dbInfo.GetReadIdxCount(); + + var fbCommand = new FbCommand("SELECT MAX(INT_FIELD) FROM TEST", Connection); + var maxIntField = fbCommand.ExecuteScalar() as int?; + + insertCount = GetAffectedTables(insertCount, dbInfo.GetInsertCount()); + updateCount = GetAffectedTables(updateCount, dbInfo.GetUpdateCount()); + readSeqCount = GetAffectedTables(readSeqCount, dbInfo.GetReadSeqCount()); + readIdxCount = GetAffectedTables(readIdxCount, dbInfo.GetReadIdxCount()); + + Assert.That(insertCount.ContainsKey(tableIdTest), Is.False); + Assert.That(updateCount.ContainsKey(tableIdTest), Is.False); + Assert.That(readSeqCount.ContainsKey(tableIdTest), Is.True); + Assert.That(readSeqCount[tableIdTest], Is.EqualTo(maxIntField + 1)); + Assert.That(readIdxCount.ContainsKey(tableIdTest), Is.False); + } + + [Test] + public void PerformanceAnalysis_INSERT_Test() + { + IDictionary tableNameList = GetTableNameList(); + short tableIdTest = tableNameList["TEST"]; + + var dbInfo = new FbDatabaseInfo(Connection); + IDictionary insertCount = dbInfo.GetInsertCount(); + IDictionary updateCount = dbInfo.GetUpdateCount(); + IDictionary readSeqCount = dbInfo.GetReadSeqCount(); + IDictionary readIdxCount = dbInfo.GetReadIdxCount(); + + var fbCommand = new FbCommand("INSERT INTO TEST (INT_FIELD) VALUES (900)", Connection); + fbCommand.ExecuteNonQuery(); + + insertCount = GetAffectedTables(insertCount, dbInfo.GetInsertCount()); + updateCount = GetAffectedTables(updateCount, dbInfo.GetUpdateCount()); + readSeqCount = GetAffectedTables(readSeqCount, dbInfo.GetReadSeqCount()); + readIdxCount = GetAffectedTables(readIdxCount, dbInfo.GetReadIdxCount()); + + Assert.That(insertCount.ContainsKey(tableIdTest), Is.True); + Assert.That(insertCount[tableIdTest], Is.EqualTo(1)); + Assert.That(updateCount.ContainsKey(tableIdTest), Is.False); + Assert.That(readSeqCount.ContainsKey(tableIdTest), Is.False); + Assert.That(readIdxCount.ContainsKey(tableIdTest), Is.False); + } + + [Test] + public void PerformanceAnalysis_UPDATE_Test() + { + IDictionary tableNameList = GetTableNameList(); + short tableIdTest = tableNameList["TEST"]; + + var fbCommand = new FbCommand("INSERT INTO TEST (INT_FIELD) VALUES (900)", Connection); + fbCommand.ExecuteNonQuery(); + + var dbInfo = new FbDatabaseInfo(Connection); + IDictionary insertCount = dbInfo.GetInsertCount(); + IDictionary updateCount = dbInfo.GetUpdateCount(); + IDictionary readSeqCount = dbInfo.GetReadSeqCount(); + IDictionary readIdxCount = dbInfo.GetReadIdxCount(); + + fbCommand.CommandText = "UPDATE TEST SET SMALLINT_FIELD = 900 WHERE (INT_FIELD = 900)"; + fbCommand.ExecuteNonQuery(); + + insertCount = GetAffectedTables(insertCount, dbInfo.GetInsertCount()); + updateCount = GetAffectedTables(updateCount, dbInfo.GetUpdateCount()); + readSeqCount = GetAffectedTables(readSeqCount, dbInfo.GetReadSeqCount()); + readIdxCount = GetAffectedTables(readIdxCount, dbInfo.GetReadIdxCount()); + + Assert.That(insertCount.ContainsKey(tableIdTest), Is.False); + Assert.That(updateCount.ContainsKey(tableIdTest), Is.True); + Assert.That(updateCount[tableIdTest], Is.EqualTo(1)); + Assert.That(readSeqCount.ContainsKey(tableIdTest), Is.False); + Assert.That(readIdxCount.ContainsKey(tableIdTest), Is.True); + Assert.That(readIdxCount[tableIdTest], Is.EqualTo(1)); + } + + private IDictionary GetAffectedTables(IDictionary aStatisticInfoBefore, IDictionary aStatisticInfoAfter) + { + var result = new Dictionary(); + foreach (KeyValuePair keyValuePair in aStatisticInfoAfter) + { + if (aStatisticInfoBefore.TryGetValue(keyValuePair.Key, out ulong value)) + { + ulong counter = keyValuePair.Value - value; + if (counter > 0) + result.Add(keyValuePair.Key, counter); + } + else + result.Add(keyValuePair.Key, keyValuePair.Value); + } + return result; + } + + private IDictionary GetTableNameList() + { + IDictionary result = new Dictionary(); + + var command = new FbCommand("select R.RDB$RELATION_ID, R.RDB$RELATION_NAME from RDB$RELATIONS R WHERE RDB$SYSTEM_FLAG = 0", Connection); + FbDataReader reader = command.ExecuteReader(); + while (reader.Read()) + { + result.Add(reader.GetString(1).Trim(), reader.GetInt16(0)); + } + return result; + } } From aa0d9f70f7b354ea6dbf4f6a37923a6817104b6e Mon Sep 17 00:00:00 2001 From: DevM900 <173990884+DevM900@users.noreply.github.com> Date: Fri, 13 Sep 2024 07:13:28 +0200 Subject: [PATCH 08/13] using await --- .../FbDatabaseInfoTests.cs | 62 ++++++++++--------- 1 file changed, 32 insertions(+), 30 deletions(-) diff --git a/src/FirebirdSql.Data.FirebirdClient.Tests/FbDatabaseInfoTests.cs b/src/FirebirdSql.Data.FirebirdClient.Tests/FbDatabaseInfoTests.cs index 4a77218b..e45e4ed6 100644 --- a/src/FirebirdSql.Data.FirebirdClient.Tests/FbDatabaseInfoTests.cs +++ b/src/FirebirdSql.Data.FirebirdClient.Tests/FbDatabaseInfoTests.cs @@ -64,24 +64,24 @@ public void CompleteDatabaseInfoTest() } [Test] - public void PerformanceAnalysis_SELECT_Test() + public async Task PerformanceAnalysis_SELECT_Test() { IDictionary tableNameList = GetTableNameList(); short tableIdTest = tableNameList["TEST"]; var dbInfo = new FbDatabaseInfo(Connection); - IDictionary insertCount = dbInfo.GetInsertCount(); - IDictionary updateCount = dbInfo.GetUpdateCount(); - IDictionary readSeqCount = dbInfo.GetReadSeqCount(); - IDictionary readIdxCount = dbInfo.GetReadIdxCount(); + var insertCount = await dbInfo.GetInsertCountAsync(); + var updateCount = await dbInfo.GetUpdateCountAsync(); + var readSeqCount = await dbInfo.GetReadSeqCountAsync(); + var readIdxCount = await dbInfo.GetReadIdxCountAsync(); var fbCommand = new FbCommand("SELECT MAX(INT_FIELD) FROM TEST", Connection); - var maxIntField = fbCommand.ExecuteScalar() as int?; + var maxIntField = await fbCommand.ExecuteScalarAsync() as int?; - insertCount = GetAffectedTables(insertCount, dbInfo.GetInsertCount()); - updateCount = GetAffectedTables(updateCount, dbInfo.GetUpdateCount()); - readSeqCount = GetAffectedTables(readSeqCount, dbInfo.GetReadSeqCount()); - readIdxCount = GetAffectedTables(readIdxCount, dbInfo.GetReadIdxCount()); + insertCount = GetAffectedTables(insertCount, await dbInfo.GetInsertCountAsync()); + updateCount = GetAffectedTables(updateCount, await dbInfo.GetUpdateCountAsync()); + readSeqCount = GetAffectedTables(readSeqCount, await dbInfo.GetReadSeqCountAsync()); + readIdxCount = GetAffectedTables(readIdxCount, await dbInfo.GetReadIdxCountAsync()); Assert.That(insertCount.ContainsKey(tableIdTest), Is.False); Assert.That(updateCount.ContainsKey(tableIdTest), Is.False); @@ -91,24 +91,24 @@ public void PerformanceAnalysis_SELECT_Test() } [Test] - public void PerformanceAnalysis_INSERT_Test() + public async Task PerformanceAnalysis_INSERT_Test() { IDictionary tableNameList = GetTableNameList(); short tableIdTest = tableNameList["TEST"]; var dbInfo = new FbDatabaseInfo(Connection); - IDictionary insertCount = dbInfo.GetInsertCount(); - IDictionary updateCount = dbInfo.GetUpdateCount(); - IDictionary readSeqCount = dbInfo.GetReadSeqCount(); - IDictionary readIdxCount = dbInfo.GetReadIdxCount(); + var insertCount = await dbInfo.GetInsertCountAsync(); + var updateCount = await dbInfo.GetUpdateCountAsync(); + var readSeqCount = await dbInfo.GetReadSeqCountAsync(); + var readIdxCount = await dbInfo.GetReadIdxCountAsync(); var fbCommand = new FbCommand("INSERT INTO TEST (INT_FIELD) VALUES (900)", Connection); - fbCommand.ExecuteNonQuery(); + await fbCommand.ExecuteNonQueryAsync(); - insertCount = GetAffectedTables(insertCount, dbInfo.GetInsertCount()); - updateCount = GetAffectedTables(updateCount, dbInfo.GetUpdateCount()); - readSeqCount = GetAffectedTables(readSeqCount, dbInfo.GetReadSeqCount()); - readIdxCount = GetAffectedTables(readIdxCount, dbInfo.GetReadIdxCount()); + insertCount = GetAffectedTables(insertCount, await dbInfo.GetInsertCountAsync()); + updateCount = GetAffectedTables(updateCount, await dbInfo.GetUpdateCountAsync()); + readSeqCount = GetAffectedTables(readSeqCount, await dbInfo.GetReadSeqCountAsync()); + readIdxCount = GetAffectedTables(readIdxCount, await dbInfo.GetReadIdxCountAsync()); Assert.That(insertCount.ContainsKey(tableIdTest), Is.True); Assert.That(insertCount[tableIdTest], Is.EqualTo(1)); @@ -118,7 +118,7 @@ public void PerformanceAnalysis_INSERT_Test() } [Test] - public void PerformanceAnalysis_UPDATE_Test() + public async Task PerformanceAnalysis_UPDATE_Test() { IDictionary tableNameList = GetTableNameList(); short tableIdTest = tableNameList["TEST"]; @@ -127,18 +127,18 @@ public void PerformanceAnalysis_UPDATE_Test() fbCommand.ExecuteNonQuery(); var dbInfo = new FbDatabaseInfo(Connection); - IDictionary insertCount = dbInfo.GetInsertCount(); - IDictionary updateCount = dbInfo.GetUpdateCount(); - IDictionary readSeqCount = dbInfo.GetReadSeqCount(); - IDictionary readIdxCount = dbInfo.GetReadIdxCount(); + var insertCount = await dbInfo.GetInsertCountAsync(); + var updateCount = await dbInfo.GetUpdateCountAsync(); + var readSeqCount = await dbInfo.GetReadSeqCountAsync(); + var readIdxCount = await dbInfo.GetReadIdxCountAsync(); fbCommand.CommandText = "UPDATE TEST SET SMALLINT_FIELD = 900 WHERE (INT_FIELD = 900)"; - fbCommand.ExecuteNonQuery(); + await fbCommand.ExecuteNonQueryAsync(); - insertCount = GetAffectedTables(insertCount, dbInfo.GetInsertCount()); - updateCount = GetAffectedTables(updateCount, dbInfo.GetUpdateCount()); - readSeqCount = GetAffectedTables(readSeqCount, dbInfo.GetReadSeqCount()); - readIdxCount = GetAffectedTables(readIdxCount, dbInfo.GetReadIdxCount()); + insertCount = GetAffectedTables(insertCount, await dbInfo.GetInsertCountAsync()); + updateCount = GetAffectedTables(updateCount, await dbInfo.GetUpdateCountAsync()); + readSeqCount = GetAffectedTables(readSeqCount, await dbInfo.GetReadSeqCountAsync()); + readIdxCount = GetAffectedTables(readIdxCount, await dbInfo.GetReadIdxCountAsync()); Assert.That(insertCount.ContainsKey(tableIdTest), Is.False); Assert.That(updateCount.ContainsKey(tableIdTest), Is.True); @@ -157,7 +157,9 @@ private IDictionary GetAffectedTables(IDictionary aS { ulong counter = keyValuePair.Value - value; if (counter > 0) + { result.Add(keyValuePair.Key, counter); + } } else result.Add(keyValuePair.Key, keyValuePair.Value); From 2acda4a3ba411a8bbcf041b55e5a5ea40eacf9be Mon Sep 17 00:00:00 2001 From: DevM900 <173990884+DevM900@users.noreply.github.com> Date: Fri, 13 Sep 2024 07:16:41 +0200 Subject: [PATCH 09/13] changed to var --- .../FbDatabaseInfoTests.cs | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/FirebirdSql.Data.FirebirdClient.Tests/FbDatabaseInfoTests.cs b/src/FirebirdSql.Data.FirebirdClient.Tests/FbDatabaseInfoTests.cs index e45e4ed6..973f3b8f 100644 --- a/src/FirebirdSql.Data.FirebirdClient.Tests/FbDatabaseInfoTests.cs +++ b/src/FirebirdSql.Data.FirebirdClient.Tests/FbDatabaseInfoTests.cs @@ -66,8 +66,8 @@ public void CompleteDatabaseInfoTest() [Test] public async Task PerformanceAnalysis_SELECT_Test() { - IDictionary tableNameList = GetTableNameList(); - short tableIdTest = tableNameList["TEST"]; + var tableNameList = GetTableNameList(); + var tableIdTest = tableNameList["TEST"]; var dbInfo = new FbDatabaseInfo(Connection); var insertCount = await dbInfo.GetInsertCountAsync(); @@ -93,8 +93,8 @@ public async Task PerformanceAnalysis_SELECT_Test() [Test] public async Task PerformanceAnalysis_INSERT_Test() { - IDictionary tableNameList = GetTableNameList(); - short tableIdTest = tableNameList["TEST"]; + var tableNameList = GetTableNameList(); + var tableIdTest = tableNameList["TEST"]; var dbInfo = new FbDatabaseInfo(Connection); var insertCount = await dbInfo.GetInsertCountAsync(); @@ -120,8 +120,8 @@ public async Task PerformanceAnalysis_INSERT_Test() [Test] public async Task PerformanceAnalysis_UPDATE_Test() { - IDictionary tableNameList = GetTableNameList(); - short tableIdTest = tableNameList["TEST"]; + var tableNameList = GetTableNameList(); + var tableIdTest = tableNameList["TEST"]; var fbCommand = new FbCommand("INSERT INTO TEST (INT_FIELD) VALUES (900)", Connection); fbCommand.ExecuteNonQuery(); @@ -151,11 +151,11 @@ public async Task PerformanceAnalysis_UPDATE_Test() private IDictionary GetAffectedTables(IDictionary aStatisticInfoBefore, IDictionary aStatisticInfoAfter) { var result = new Dictionary(); - foreach (KeyValuePair keyValuePair in aStatisticInfoAfter) + foreach (var keyValuePair in aStatisticInfoAfter) { - if (aStatisticInfoBefore.TryGetValue(keyValuePair.Key, out ulong value)) + if (aStatisticInfoBefore.TryGetValue(keyValuePair.Key, out var value)) { - ulong counter = keyValuePair.Value - value; + var counter = keyValuePair.Value - value; if (counter > 0) { result.Add(keyValuePair.Key, counter); @@ -172,7 +172,7 @@ private IDictionary GetTableNameList() IDictionary result = new Dictionary(); var command = new FbCommand("select R.RDB$RELATION_ID, R.RDB$RELATION_NAME from RDB$RELATIONS R WHERE RDB$SYSTEM_FLAG = 0", Connection); - FbDataReader reader = command.ExecuteReader(); + var reader = command.ExecuteReader(); while (reader.Read()) { result.Add(reader.GetString(1).Trim(), reader.GetInt16(0)); From 7edc7ee3a8b96383bf722ed0ee4d9f0154511f0b Mon Sep 17 00:00:00 2001 From: DevM900 <173990884+DevM900@users.noreply.github.com> Date: Fri, 13 Sep 2024 07:18:28 +0200 Subject: [PATCH 10/13] prefix on argument removed, --- src/FirebirdSql.Data.FirebirdClient/Common/Extensions.cs | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/FirebirdSql.Data.FirebirdClient/Common/Extensions.cs b/src/FirebirdSql.Data.FirebirdClient/Common/Extensions.cs index 38bbf40c..58ca9052 100644 --- a/src/FirebirdSql.Data.FirebirdClient/Common/Extensions.cs +++ b/src/FirebirdSql.Data.FirebirdClient/Common/Extensions.cs @@ -53,13 +53,12 @@ public static string ToHexString(this byte[] b) return BitConverter.ToString(b).Replace("-", string.Empty); } - public static IDictionary GetTableStatistic(this byte[] b, int aLength) + public static IDictionary GetTableStatistic(this byte[] b, int length) { - int capacity = aLength > 3 ? - (aLength - 3) / 6 + 1 : - 0; + int capacity = length > 3 ? (length - 3) / 6 + 1 : 0; + var tableStatistic = new Dictionary(capacity); - for (var i = 3; i < aLength; i += 6) + for (var i = 3; i < length; i += 6) { var tableId = (short)IscHelper.VaxInteger(b, i, 2); var count = (ulong)IscHelper.VaxInteger(b, i + 2, 4); From 367af062493278903a3937e7cdcede5de14a0006 Mon Sep 17 00:00:00 2001 From: DevM900 <173990884+DevM900@users.noreply.github.com> Date: Fri, 13 Sep 2024 07:19:08 +0200 Subject: [PATCH 11/13] extra spaces removed --- src/FirebirdSql.Data.FirebirdClient/Common/IscHelper.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/FirebirdSql.Data.FirebirdClient/Common/IscHelper.cs b/src/FirebirdSql.Data.FirebirdClient/Common/IscHelper.cs index 0b47db5e..fb21bc81 100644 --- a/src/FirebirdSql.Data.FirebirdClient/Common/IscHelper.cs +++ b/src/FirebirdSql.Data.FirebirdClient/Common/IscHelper.cs @@ -77,7 +77,7 @@ public static List ParseDatabaseInfo(byte[] buffer, Charset charset) case IscCodes.isc_info_update_count: case IscCodes.isc_info_read_seq_count: case IscCodes.isc_info_read_idx_count: - info.Add( buffer.GetTableStatistic( length ) ); + info.Add(buffer.GetTableStatistic(length)); break; case IscCodes.isc_info_no_reserve: From 600fb37c28fa8cb9acf07ae3422dc50f192af74b Mon Sep 17 00:00:00 2001 From: DevM900 <173990884+DevM900@users.noreply.github.com> Date: Fri, 13 Sep 2024 07:28:48 +0200 Subject: [PATCH 12/13] 'private' modifier removed --- .../FbDatabaseInfoTests.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/FirebirdSql.Data.FirebirdClient.Tests/FbDatabaseInfoTests.cs b/src/FirebirdSql.Data.FirebirdClient.Tests/FbDatabaseInfoTests.cs index 973f3b8f..1f18d7c9 100644 --- a/src/FirebirdSql.Data.FirebirdClient.Tests/FbDatabaseInfoTests.cs +++ b/src/FirebirdSql.Data.FirebirdClient.Tests/FbDatabaseInfoTests.cs @@ -148,7 +148,7 @@ public async Task PerformanceAnalysis_UPDATE_Test() Assert.That(readIdxCount[tableIdTest], Is.EqualTo(1)); } - private IDictionary GetAffectedTables(IDictionary aStatisticInfoBefore, IDictionary aStatisticInfoAfter) + IDictionary GetAffectedTables(IDictionary aStatisticInfoBefore, IDictionary aStatisticInfoAfter) { var result = new Dictionary(); foreach (var keyValuePair in aStatisticInfoAfter) @@ -167,7 +167,7 @@ private IDictionary GetAffectedTables(IDictionary aS return result; } - private IDictionary GetTableNameList() + IDictionary GetTableNameList() { IDictionary result = new Dictionary(); From 3f1e72c7e9ac8fe819ce719fc4f6a59dc65a6dc9 Mon Sep 17 00:00:00 2001 From: DevM900 <173990884+DevM900@users.noreply.github.com> Date: Fri, 13 Sep 2024 07:30:34 +0200 Subject: [PATCH 13/13] prefix 'a' on arguments removed --- .../FbDatabaseInfoTests.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/FirebirdSql.Data.FirebirdClient.Tests/FbDatabaseInfoTests.cs b/src/FirebirdSql.Data.FirebirdClient.Tests/FbDatabaseInfoTests.cs index 1f18d7c9..250fa131 100644 --- a/src/FirebirdSql.Data.FirebirdClient.Tests/FbDatabaseInfoTests.cs +++ b/src/FirebirdSql.Data.FirebirdClient.Tests/FbDatabaseInfoTests.cs @@ -148,12 +148,12 @@ public async Task PerformanceAnalysis_UPDATE_Test() Assert.That(readIdxCount[tableIdTest], Is.EqualTo(1)); } - IDictionary GetAffectedTables(IDictionary aStatisticInfoBefore, IDictionary aStatisticInfoAfter) + IDictionary GetAffectedTables(IDictionary statisticInfoBefore, IDictionary statisticInfoAfter) { var result = new Dictionary(); - foreach (var keyValuePair in aStatisticInfoAfter) + foreach (var keyValuePair in statisticInfoAfter) { - if (aStatisticInfoBefore.TryGetValue(keyValuePair.Key, out var value)) + if (statisticInfoBefore.TryGetValue(keyValuePair.Key, out var value)) { var counter = keyValuePair.Value - value; if (counter > 0)