Skip to content

Commit

Permalink
Introduce the "Table Key" module (#506)
Browse files Browse the repository at this point in the history
<!-- Thank you for submitting a Pull Request. If you're new to
contributing to BCApps please read our pull request guideline below
* https://github.com/microsoft/BCApps/Contributing.md
-->
#### Summary <!-- Provide a general summary of your changes -->
It has been shown that disabling keys (indexes) allows for faster mass
deletion of records.
Introducing a new module that would allow AL code to disable indexes
before mass deletion / insertion / modification of records in a table.

#### Work Item(s) <!-- Add the issue number here after the #. The issue
needs to be open and approved. Submitting PRs with no linked issues or
unapproved issues is highly discouraged. -->
Fixes
[AB#494937](https://dynamicssmb2.visualstudio.com/1fcb79e7-ab07-432a-a3c6-6cf5a88ba4a5/_workitems/edit/494937)
  • Loading branch information
IhorHandziuk committed Jan 23, 2024
1 parent c122a9a commit 040679f
Show file tree
Hide file tree
Showing 5 changed files with 149 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ using System.Device;
using System.Security.Encryption;
using System.Visualization;
using System.Privacy;
using System.Reflection;
using System.Integration;
using System.Integration.Excel;
using System.Email;
Expand Down Expand Up @@ -52,6 +53,7 @@ permissionset 219 "System Application - Objects"
"Security Groups - Objects",
"SharePoint API - Objects",
"Table Information - Objects",
"Table Key - Objects",
"Translation - Objects",
"User Permissions - Objects",
"User Selection - Objects",
Expand Down
24 changes: 24 additions & 0 deletions src/System Application/App/Table Keys/app.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
{
"id": "1d643d12-c0df-4c82-af68-8e8fd80b32f9",
"name": "Table Keys",
"publisher": "Microsoft",
"brief": "Provides functionality for working with table keys.",
"description": "Provides functionality for disabling and re-enabling table keys.",
"version": "24.0.0.0",
"privacyStatement": "https://go.microsoft.com/fwlink/?linkid=724009",
"EULA": "https://go.microsoft.com/fwlink/?linkid=2009120",
"help": "https://go.microsoft.com/fwlink/?linkid=2103698",
"url": "https://go.microsoft.com/fwlink/?linkid=724011",
"logo": "",
"dependencies": [],
"screenshots": [],
"platform": "24.0.0.0",
"idRanges": [
{
"from": 9557,
"to": 9558
}
],
"target": "OnPrem",
"contextSensitiveHelpUrl": "https://learn.microsoft.com/dynamics365/business-central/"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// ------------------------------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
// ------------------------------------------------------------------------------------------------

namespace System.Reflection;

permissionset 9557 "Table Key - Objects"
{
Access = Internal;
Assignable = false;

Permissions = codeunit "Table Key" = X;
}
44 changes: 44 additions & 0 deletions src/System Application/App/Table Keys/src/TableKey.Codeunit.al
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
// ------------------------------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
// ------------------------------------------------------------------------------------------------

namespace System.Reflection;

/// <summary>
/// Provides functionality for disabling and re-enabling table indexes.
/// </summary>
codeunit 9557 "Table Key"
{
/// <summary>
/// Disables all keys on the provided table. Disabling keys before bulk table write operations can significantly improve performance.
/// </summary>
/// <param name="TableNo">The table to disable all of the keys for.</param>
/// <returns>True, if the keys were disabled successfully, false otherwise.</returns>
/// <remarks>
/// System tables and non-sql based tables are not supported for this operation.
/// Clustered keys, unique keys, SIFT keys, Nonclustered Columnstore Indexes are not affected by this operation.
/// The keys are automatically re-enabled when a Commit() is called, or at the end of AL code execution.
/// </remarks>
[Scope('OnPrem')]
procedure DisableAll(TableNo: Integer): Boolean
var
TableKeyImpl: Codeunit "Table Key Impl.";
begin
exit(TableKeyImpl.DisableAll(TableNo));
end;

/// <summary>
/// Re-enables all keys that have been disabled on the provided table.
/// </summary>
/// <param name="TableNo">The table to re-enable all of the keys for.</param>
/// <returns>True, if the keys were re-enabled successfully, false otherwise.</returns>
/// <remarks>This method can be used when keys need to be re-enabled (for example, for searching) before a Commit() is called.</remarks>
[Scope('OnPrem')]
procedure EnableAll(TableNo: Integer): Boolean
var
TableKeyImpl: Codeunit "Table Key Impl.";
begin
exit(TableKeyImpl.EnableAll(TableNo));
end;
}
65 changes: 65 additions & 0 deletions src/System Application/App/Table Keys/src/TableKeyImpl.Codeunit.al
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
// ------------------------------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
// ------------------------------------------------------------------------------------------------

namespace System.Reflection;

codeunit 9558 "Table Key Impl."
{
Access = Internal;
InherentEntitlements = X;
InherentPermissions = X;

procedure DisableAll(TableNo: Integer): Boolean
begin
exit(AlterAll(TableNo, false));
end;

procedure EnableAll(TableNo: Integer): Boolean
begin
exit(AlterAll(TableNo, true));
end;

local procedure AlterAll(TableNo: Integer; Enable: Boolean): Boolean
var
TableMetadata: Record "Table Metadata";
TableKey: Record "Key";
RecordRef: RecordRef;
KeyToDisable: KeyRef;
begin
// Disabling indexes for system tables is not supported
if TableNo > 2000000000 then
exit(false);

if not TableMetadata.Get(TableNo) then
exit(false);

// Disabling indexes is only supported for Normal tables
if TableMetadata.TableType <> TableMetadata.TableType::Normal then
exit(false);

RecordRef.Open(TableNo);

TableKey.SetRange(TableNo, TableNo);
TableKey.SetRange(TableKey.Enabled, true);
TableKey.SetRange(Clustered, false);
TableKey.SetRange(Unique, false);
TableKey.SetRange(MaintainSIFTIndex, false);
TableKey.SetRange(SumIndexFields, '');
TableKey.SetFilter(TableKey.ObsoleteState, '%1|%2', TableKey.ObsoleteState::No, TableKey.ObsoleteState::Pending);

if TableKey.FindSet() then
repeat
KeyToDisable := RecordRef.KeyIndex(TableKey."No.");
Database.AlterKey(KeyToDisable, Enable);
until TableKey.Next() = 0;

// Disable SystemId index
KeyToDisable := RecordRef.KeyIndex(RecordRef.KeyCount());
Database.AlterKey(KeyToDisable, Enable);
RecordRef.Close();

exit(true);
end;
}

0 comments on commit 040679f

Please sign in to comment.