mirror of
https://github.com/microsoft/BCQuality.git
synced 2026-10-05 14:46:55 +01:00
Merge pull request #67 from Curabis/rule/upgrade-codeunit-subtype-full-six-triggers
[BCQuality] Fix: document all 6 upgrade triggers, not just 2
This commit is contained in:
commit
37eac65805
1 changed files with 39 additions and 26 deletions
|
|
@ -1,26 +1,39 @@
|
||||||
---
|
---
|
||||||
bc-version: [all]
|
bc-version: [all]
|
||||||
domain: upgrade
|
domain: upgrade
|
||||||
keywords: [upgrade-codeunit, subtype, on-upgrade-per-company, on-upgrade-per-database, trigger]
|
keywords: [upgrade-codeunit, subtype, on-upgrade-per-company, on-upgrade-per-database, trigger]
|
||||||
technologies: [al]
|
technologies: [al]
|
||||||
countries: [w1]
|
countries: [w1]
|
||||||
application-area: [all]
|
application-area: [all]
|
||||||
---
|
---
|
||||||
|
|
||||||
# Upgrade logic must live in a codeunit with `Subtype = Upgrade`
|
# Upgrade logic must live in a codeunit with `Subtype = Upgrade`
|
||||||
|
|
||||||
## Description
|
## Description
|
||||||
|
|
||||||
A codeunit only participates in the upgrade pipeline when it sets `Subtype = Upgrade`. The platform then dispatches the `OnUpgradePerCompany` and `OnUpgradePerDatabase` triggers on that codeunit during upgrade. A codeunit without `Subtype = Upgrade` — even one that declares an `OnUpgradePerCompany` trigger — is not an upgrade codeunit, and reviewers ignore it for upgrade concerns. Conversely, any procedure invoked transitively from an `OnUpgrade...` trigger of an upgrade codeunit IS upgrade code regardless of where it lives, and the upgrade rules apply to it.
|
A codeunit only participates in the upgrade pipeline when it sets `Subtype = Upgrade`. The platform then dispatches up to six system triggers on that codeunit during upgrade, run in this order:
|
||||||
|
|
||||||
## Best Practice
|
| Trigger | Runs | Fails the upgrade on error |
|
||||||
|
|---|---|---|
|
||||||
Place every piece of upgrade logic in a codeunit declared with `Subtype = Upgrade;` and expose entry points via the two triggers `OnUpgradePerCompany` and `OnUpgradePerDatabase`. Helper procedures may live in normal codeunits, but they inherit the upgrade-context rules (guarded reads, no external calls, upgrade tags, etc.) when called from an upgrade trigger.
|
| `OnCheckPreconditionsPerCompany` | once per company | Yes |
|
||||||
|
| `OnCheckPreconditionsPerDatabase` | once, no company open | Yes |
|
||||||
See sample: `upgrade-codeunit-subtype.good.al`.
|
| `OnUpgradePerCompany` | once per company | Yes |
|
||||||
|
| `OnUpgradePerDatabase` | once, no company open | Yes |
|
||||||
## Anti Pattern
|
| `OnValidateUpgradePerCompany` | once per company | Yes |
|
||||||
|
| `OnValidateUpgradePerDatabase` | once, no company open | Yes |
|
||||||
Putting upgrade-style logic in a regular codeunit that the platform never invokes during upgrade — for example a normal codeunit with a manually invented "RunUpgrade" procedure that nothing wires to the upgrade pipeline. The migration code will simply not run.
|
|
||||||
|
A codeunit without `Subtype = Upgrade` — even one that declares an `OnUpgradePerCompany` trigger — is not an upgrade codeunit, and reviewers ignore it for upgrade concerns. Conversely, any procedure invoked transitively from any of these six triggers on an upgrade codeunit IS upgrade code regardless of where it lives, and the upgrade rules apply to it.
|
||||||
See sample: `upgrade-codeunit-subtype.bad.al`.
|
|
||||||
|
Only `OnUpgradePerCompany`/`OnUpgradePerDatabase` do the actual data migration. `OnCheckPreconditions...` runs first and aborts the upgrade if a precondition isn't met; `OnValidateUpgrade...` runs last and aborts if the result can't be confirmed correct. See [[minimize-onvalidate-upgrade-triggers]] for CURABIS's own guidance on when to use the CheckPreconditions/ValidateUpgrade pair versus keeping upgrade logic in `OnUpgrade...` alone.
|
||||||
|
|
||||||
|
## Best Practice
|
||||||
|
|
||||||
|
Place every piece of upgrade logic in a codeunit declared with `Subtype = Upgrade;` and expose entry points via whichever of the six triggers the scenario needs — at minimum `OnUpgradePerCompany`/`OnUpgradePerDatabase`, optionally paired with `OnCheckPreconditions...`/`OnValidateUpgrade...`. Helper procedures may live in normal codeunits, but they inherit the upgrade-context rules (guarded reads, no external calls, upgrade tags, etc.) when called from any of these six triggers.
|
||||||
|
|
||||||
|
See sample: `upgrade-codeunit-subtype.good.al`.
|
||||||
|
|
||||||
|
## Anti Pattern
|
||||||
|
|
||||||
|
Putting upgrade-style logic in a regular codeunit that the platform never invokes during upgrade — for example a normal codeunit with a manually invented "RunUpgrade" procedure that nothing wires to the upgrade pipeline. The migration code will simply not run.
|
||||||
|
|
||||||
|
See sample: `upgrade-codeunit-subtype.bad.al`.
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue