Skip to content

Update or delete a maintained object

Updates or deletes an existing maintenance object, verifying that exactly one row was affected by the write and reporting a contention error otherwise. This pattern is repeated identically across all seven maintenance objects in this library.

Field Value
Operation ID OP-MENU-07
Trigger Caller calls Save() on a dirty existing object, or Delete()
Inputs Object properties (update) or key (delete), DataPortalInfo.UserID
Outputs Updated or deleted row; the object returns to a "new" state after a successful delete
Primary components Common BOF pattern, representative example clsMenuItem; mirrored by clsMenuPage, clsMenuSecurity, clsMenuSecurityUser, clsMenuFavorite, clsApplicationCode, clsMenuCategoryCode
Entry point SAIF.Business.Menu/clsMenuItem.vb

Steps

  1. BeforeUpdate issues a NonQuery with UpdateSQL (SQL-034), passing every mutable column plus the key, and stamping UPDATE_USER = :UserId / UPDATE_DATE = SYSDATE where those columns exist. (BR-MENU-016)
  2. AfterUpdate checks RowsAffected <> 1; if so it adds error UpdateError = BOC.Messages.DBContentionError, otherwise MarkOld. (BR-MENU-020, BR-MENU-022)
  3. On failure (rows affected ≠ 1): the object records the UpdateError message; the caller's changes remain applied in memory only.
  4. BeforeDelete issues a NonQuery with DeleteSQL (SQL-041) parameterized by the key only.
  5. AfterDelete applies the same single-row check with error key DeleteError, and on success calls MarkNew (returning the object to a transient state). (BR-MENU-020, BR-MENU-022)
  6. On failure (rows affected ≠ 1): the object records the DeleteError message and remains in its prior (old) state.

Process flow

flowchart TD
    Start([Save or Delete called]) --> Action{Update or Delete?}
    Action -->|Update| Upd[BeforeUpdate: UPDATE row, stamp UPDATE_USER/UPDATE_DATE]
    Upd --> UChk{Exactly one row affected?}
    UChk -->|No| UFail([AfterUpdate: add UpdateError])
    UChk -->|Yes| UOk([AfterUpdate: MarkOld])
    Action -->|Delete| Del[BeforeDelete: DELETE row by key]
    Del --> DChk{Exactly one row affected?}
    DChk -->|No| DFail([AfterDelete: add DeleteError])
    DChk -->|Yes| DOk([AfterDelete: MarkNew])

Failure and edge-case behavior

  • Update affects zero or more than one row: UpdateError = BOC.Messages.DBContentionError is added; no exception is thrown.
  • Delete affects zero or more than one row: DeleteError = BOC.Messages.DBContentionError is added; the object is not marked new.
  • A successful delete returns the object to a "new" state, allowing it to be re-inserted without reconstructing it.

Sources

  • SAIF.Business.Menu/clsMenuItem.vb
  • SAIF.Business.Menu/clsMenuPage.vb
  • SAIF.Business.Menu/clsMenuSecurity.vb
  • SAIF.Business.Menu/clsMenuSecurityUser.vb
  • SAIF.Business.Menu/clsMenuFavorite.vb
  • SAIF.Business.Menu/clsApplicationCode.vb
  • SAIF.Business.Menu/clsMenuCategoryCode.vb