Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Correction of the return values of the DatabaseInfo methods for determining the insert, read and delete operations #1183

Open
wants to merge 14 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 8 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
116 changes: 116 additions & 0 deletions src/FirebirdSql.Data.FirebirdClient.Tests/FbDatabaseInfoTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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<string, short> tableNameList = GetTableNameList();
short tableIdTest = tableNameList["TEST"];
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use var.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done


var dbInfo = new FbDatabaseInfo(Connection);
IDictionary<short, ulong> insertCount = dbInfo.GetInsertCount();
IDictionary<short, ulong> updateCount = dbInfo.GetUpdateCount();
IDictionary<short, ulong> readSeqCount = dbInfo.GetReadSeqCount();
IDictionary<short, ulong> readIdxCount = dbInfo.GetReadIdxCount();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use var.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done


var fbCommand = new FbCommand("SELECT MAX(INT_FIELD) FROM TEST", Connection);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

await using

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

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<string, short> tableNameList = GetTableNameList();
short tableIdTest = tableNameList["TEST"];
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use var.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done


var dbInfo = new FbDatabaseInfo(Connection);
IDictionary<short, ulong> insertCount = dbInfo.GetInsertCount();
IDictionary<short, ulong> updateCount = dbInfo.GetUpdateCount();
IDictionary<short, ulong> readSeqCount = dbInfo.GetReadSeqCount();
IDictionary<short, ulong> readIdxCount = dbInfo.GetReadIdxCount();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use var.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done


var fbCommand = new FbCommand("INSERT INTO TEST (INT_FIELD) VALUES (900)", Connection);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

await using

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

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<string, short> tableNameList = GetTableNameList();
short tableIdTest = tableNameList["TEST"];
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use var.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done


var fbCommand = new FbCommand("INSERT INTO TEST (INT_FIELD) VALUES (900)", Connection);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

await using

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

fbCommand.ExecuteNonQuery();

var dbInfo = new FbDatabaseInfo(Connection);
IDictionary<short, ulong> insertCount = dbInfo.GetInsertCount();
IDictionary<short, ulong> updateCount = dbInfo.GetUpdateCount();
IDictionary<short, ulong> readSeqCount = dbInfo.GetReadSeqCount();
IDictionary<short, ulong> readIdxCount = dbInfo.GetReadIdxCount();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use var.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done


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<short, ulong> GetAffectedTables(IDictionary<short, ulong> aStatisticInfoBefore, IDictionary<short, ulong> aStatisticInfoAfter)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove private.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove the a prefix on arguments.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

{
var result = new Dictionary<short, ulong>();
foreach (KeyValuePair<short, ulong> keyValuePair in aStatisticInfoAfter)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use var.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

{
if (aStatisticInfoBefore.TryGetValue(keyValuePair.Key, out ulong value))
{
ulong counter = keyValuePair.Value - value;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use var.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

if (counter > 0)
result.Add(keyValuePair.Key, counter);
}
else
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add }/{ for consistency sake.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

result.Add(keyValuePair.Key, keyValuePair.Value);
}
return result;
}

private IDictionary<string, short> GetTableNameList()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it would be better to use FbSchema here (unless something prevents using it).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As far as I can see, we would have to extend FbTables to get the relation id

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove private.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

{
IDictionary<string, short> result = new Dictionary<string, short>();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use var.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done


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();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use var.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

while (reader.Read())
{
result.Add(reader.GetString(1).Trim(), reader.GetInt16(0));
}
return result;
}
}
18 changes: 18 additions & 0 deletions src/FirebirdSql.Data.FirebirdClient/Common/Extensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -51,6 +53,22 @@ public static string ToHexString(this byte[] b)
return BitConverter.ToString(b).Replace("-", string.Empty);
}

public static IDictionary<short, ulong> GetTableStatistic(this byte[] b, int aLength)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove a prefix on argument.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

{
int capacity = aLength > 3 ?
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Put it on single line.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

(aLength - 3) / 6 + 1 :
0;
var tableStatistic = new Dictionary<short, ulong>(capacity);
for (var i = 3; i < aLength; i += 6)
{
var tableId = (short)IscHelper.VaxInteger(b, i, 2);
var count = (ulong)IscHelper.VaxInteger(b, i + 2, 4);
tableStatistic.Add(tableId, count);
}

return tableStatistic;
}

public static IEnumerable<IEnumerable<T>> Split<T>(this T[] array, int size)
{
for (var i = 0; i < (float)array.Length / size; i++)
Expand Down
19 changes: 11 additions & 8 deletions src/FirebirdSql.Data.FirebirdClient/Common/IscHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -54,14 +54,6 @@ public static List<object> 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:
Expand All @@ -77,6 +69,17 @@ public static List<object> 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 ) );
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove extra spaces around (/).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

break;

case IscCodes.isc_info_no_reserve:
case IscCodes.isc_info_forced_writes:
case IscCodes.isc_info_db_read_only:
Expand Down
130 changes: 97 additions & 33 deletions src/FirebirdSql.Data.FirebirdClient/FirebirdClient/FbDatabaseInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@

using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
Expand Down Expand Up @@ -225,76 +224,141 @@ public Task<int> GetWritesAsync(CancellationToken cancellationToken = default)
return GetValueAsync<int>(IscCodes.isc_info_writes, cancellationToken);
}

public int GetBackoutCount()
/// <summary>
/// Returns the number of removals of a version of a record of the affected tables.
/// </summary>
/// <returns>Dictionary with the number of removals, with table id (field RDB$RELATION_ID of the system table RDB$RELATIONS) as key.</returns>
public IDictionary<short, ulong> GetBackoutCount()
{
return GetValue<int>(IscCodes.isc_info_backout_count);
return GetValue<IDictionary<short, ulong>>(IscCodes.isc_info_backout_count);
}
public Task<int> GetBackoutCountAsync(CancellationToken cancellationToken = default)
/// <summary>
/// Returns the number of removals of a version of a record of the affected tables.
/// </summary>
/// <returns>Dictionary with the number of removals, with table id (field RDB$RELATION_ID of the system table RDB$RELATIONS) as key.</returns>
public Task<IDictionary<short, ulong>> GetBackoutCountAsync(CancellationToken cancellationToken = default)
{
return GetValueAsync<int>(IscCodes.isc_info_backout_count, cancellationToken);
return GetValueAsync<IDictionary<short, ulong>>(IscCodes.isc_info_backout_count, cancellationToken);
}

public int GetDeleteCount()
/// <summary>
/// Returns the number of database deletes of the affected tables since the database was last attached.
/// </summary>
/// <returns>Dictionary with the number of deletes, with table id (field RDB$RELATION_ID of the system table RDB$RELATIONS) as key.</returns>
public IDictionary<short, ulong> GetDeleteCount()
{
return GetValue<int>(IscCodes.isc_info_delete_count);
return GetValue<IDictionary<short, ulong>>(IscCodes.isc_info_delete_count);
}
public Task<int> GetDeleteCountAsync(CancellationToken cancellationToken = default)
/// <summary>
/// Returns the number of database deletes of the affected tables since the database was last attached.
/// </summary>
/// <returns>Dictionary with the number of deletes, with table id (field RDB$RELATION_ID of the system table RDB$RELATIONS) as key.</returns>
public Task<IDictionary<short, ulong>> GetDeleteCountAsync(CancellationToken cancellationToken = default)
{
return GetValueAsync<int>(IscCodes.isc_info_delete_count, cancellationToken);
return GetValueAsync<IDictionary<short, ulong>>(IscCodes.isc_info_delete_count, cancellationToken);
}

public int GetExpungeCount()
/// <summary>
/// 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.
/// </summary>
/// <returns>Dictionary with the number of removals, with table id (field RDB$RELATION_ID of the system table RDB$RELATIONS) as key.</returns>
public IDictionary<short, ulong> GetExpungeCount()
{
return GetValue<int>(IscCodes.isc_info_expunge_count);
return GetValue<IDictionary<short, ulong>>(IscCodes.isc_info_expunge_count);
}
public Task<int> GetExpungeCountAsync(CancellationToken cancellationToken = default)

/// <summary>
/// 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.
/// </summary>
/// <returns>Dictionary with the number of removals, with table id (field RDB$RELATION_ID of the system table RDB$RELATIONS) as key.</returns>
public Task<IDictionary<short, ulong>> GetExpungeCountAsync(CancellationToken cancellationToken = default)
{
return GetValueAsync<int>(IscCodes.isc_info_expunge_count, cancellationToken);
return GetValueAsync<IDictionary<short, ulong>>(IscCodes.isc_info_expunge_count, cancellationToken);
}

public int GetInsertCount()
/// <summary>
/// Returns the number of inserts into the database of the affected tables since the database was last attached.
/// </summary>
/// <returns>Dictionary with the number of inserts, with table id (field RDB$RELATION_ID of the system table RDB$RELATIONS) as key.</returns>
public IDictionary<short, ulong> GetInsertCount()
{
return GetValue<int>(IscCodes.isc_info_insert_count);
return GetValue<IDictionary<short, ulong>>(IscCodes.isc_info_insert_count);
}
public Task<int> GetInsertCountAsync(CancellationToken cancellationToken = default)
/// <summary>
/// Returns the number of inserts into the database of the affected tables since the database was last attached.
/// </summary>
/// <returns>Dictionary with the number of inserts, with table id (field RDB$RELATION_ID of the system table RDB$RELATIONS) as key.</returns>
public Task<IDictionary<short, ulong>> GetInsertCountAsync(CancellationToken cancellationToken = default)
{
return GetValueAsync<int>(IscCodes.isc_info_insert_count, cancellationToken);
return GetValueAsync<IDictionary<short, ulong>>(IscCodes.isc_info_insert_count, cancellationToken);
}

public int GetPurgeCount()
/// <summary>
/// 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.
/// </summary>
/// <returns>Dictionary with the number of removals, with table id (field RDB$RELATION_ID of the system table RDB$RELATIONS) as key.</returns>
public IDictionary<short, ulong> GetPurgeCount()
{
return GetValue<int>(IscCodes.isc_info_purge_count);
return GetValue<IDictionary<short, ulong>>(IscCodes.isc_info_purge_count);
}
public Task<int> GetPurgeCountAsync(CancellationToken cancellationToken = default)
/// <summary>
/// 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.
/// </summary>
/// <returns>Dictionary with the number of removals, with table id (field RDB$RELATION_ID of the system table RDB$RELATIONS) as key.</returns>
public Task<IDictionary<short, ulong>> GetPurgeCountAsync(CancellationToken cancellationToken = default)
{
return GetValueAsync<int>(IscCodes.isc_info_purge_count, cancellationToken);
return GetValueAsync<IDictionary<short, ulong>>(IscCodes.isc_info_purge_count, cancellationToken);
}

public long GetReadIdxCount()
/// <summary>
/// Returns the number of reads done via an index of the affected tables since the database was last attached.
/// </summary>
/// <returns>Dictionary with the number of reads, with table id (field RDB$RELATION_ID of the system table RDB$RELATIONS) as key.</returns>
public IDictionary<short, ulong> GetReadIdxCount()
{
return GetValue<long>(IscCodes.isc_info_read_idx_count);
return GetValue<IDictionary<short, ulong>>(IscCodes.isc_info_read_idx_count);
}
public Task<long> GetReadIdxCountAsync(CancellationToken cancellationToken = default)
/// <summary>
/// Returns the number of reads done via an index of the affected tables since the database was last attached.
/// </summary>
/// <returns>Dictionary with the number of reads, with table id (field RDB$RELATION_ID of the system table RDB$RELATIONS) as key.</returns>
public Task<IDictionary<short, ulong>> GetReadIdxCountAsync(CancellationToken cancellationToken = default)
{
return GetValueAsync<long>(IscCodes.isc_info_read_idx_count, cancellationToken);
return GetValueAsync<IDictionary<short, ulong>>(IscCodes.isc_info_read_idx_count, cancellationToken);
}

public long GetReadSeqCount()
/// <summary>
/// Returns the number of sequential table scans (row reads) of the affected tables since the database was last attached.
/// </summary>
/// <returns>Dictionary with the number of reads, with table id (field RDB$RELATION_ID of the system table RDB$RELATIONS) as key.</returns>
public IDictionary<short, ulong> GetReadSeqCount()
{
return GetValue<long>(IscCodes.isc_info_read_seq_count);
return GetValue<IDictionary<short, ulong>>(IscCodes.isc_info_read_seq_count);
}
public Task<long> GetReadSeqCountAsync(CancellationToken cancellationToken = default)
/// <summary>
/// Returns the number of sequential table scans (row reads) of the affected tables since the database was last attached.
/// </summary>
/// <returns>Dictionary with the number of reads, with table id (field RDB$RELATION_ID of the system table RDB$RELATIONS) as key.</returns>
public Task<IDictionary<short, ulong>> GetReadSeqCountAsync(CancellationToken cancellationToken = default)
{
return GetValueAsync<long>(IscCodes.isc_info_read_seq_count, cancellationToken);
return GetValueAsync<IDictionary<short, ulong>>(IscCodes.isc_info_read_seq_count, cancellationToken);
}

public long GetUpdateCount()
/// <summary>
/// Returns the number of database updates of the affected tables since the database was last attached.
/// </summary>
/// <returns>Dictionary with the number of updates, with table id (field RDB$RELATION_ID of the system table RDB$RELATIONS) as key.</returns>
public IDictionary<short, ulong> GetUpdateCount()
{
return GetValue<long>(IscCodes.isc_info_update_count);
return GetValue<IDictionary<short, ulong>>(IscCodes.isc_info_update_count);
}
public Task<long> GetUpdateCountAsync(CancellationToken cancellationToken = default)
/// <summary>
/// Returns the number of database updates of the affected tables since the database was last attached.
/// </summary>
/// <returns>Dictionary with the number of updates, with table id (field RDB$RELATION_ID of the system table RDB$RELATIONS) as key.</returns>
public Task<IDictionary<short, ulong>> GetUpdateCountAsync(CancellationToken cancellationToken = default)
{
return GetValueAsync<long>(IscCodes.isc_info_update_count, cancellationToken);
return GetValueAsync<IDictionary<short, ulong>>(IscCodes.isc_info_update_count, cancellationToken);
}

public int GetDatabaseSizeInPages()
Expand Down
Loading