Merge pull request 'docs(developer-guide): the delete-record column is client-owned' (#19) from docs/delete-record-column-client-side into main
Publish to docs.datacontroller.io / Deploy docs (push) Successful in 1m27s

Reviewed-on: #19
This commit was merged in pull request #19.
This commit is contained in:
allan committed 2026-10-18 09:53:47 +00:00
commit 2b60c7443b
3 files changed
+5 -3

No files matched your search

+1 -1
View File
@@ -42,7 +42,7 @@ The Editor screen lets users who have been pre-authorised (via the `DATACTRL.MPE
2 - *Upload*. If you have a lot of data, you can [upload it directly](files). The changes are then approved in the usual way. 2 - *Upload*. If you have a lot of data, you can [upload it directly](files). The changes are then approved in the usual way.
3 - *Edit*. This is the main interface, data is displayed in tabular format. The first column is always "Delete?", as this allows you to mark rows for deletion. Note that removing a row from display does not mark it for deletion! It simply means that this row is not part of the changeset being submitted. 3 - *Edit*. This is the main interface, data is displayed in tabular format. The first column is always "Delete?", as this allows you to mark rows for deletion. This column is created by Data Controller and is not part of your table. Note that removing a row from display does not mark it for deletion! It simply means that this row is not part of the changeset being submitted.
The next set of columns are the Primary Key, and are shaded grey. If the table has a surrogate / retained key, then it is the Business Key that is shown here (the RK field is calculated / updated at the backend). For SCD2 type tables, the 'validity' fields are not shown. It is assumed that the user is always working with the current version of the data, and the view is filtered as such. The next set of columns are the Primary Key, and are shaded grey. If the table has a surrogate / retained key, then it is the Business Key that is shown here (the RK field is calculated / updated at the backend). For SCD2 type tables, the 'validity' fields are not shown. It is assumed that the user is always working with the current version of the data, and the view is filtered as such.
After this, remaining columns are shown. Dates / datetime fields have appropriate datepickers. Other fields may also have dropdowns to ensure entry of standard values, these can be configured in the `DATACTRL.MPE_SELECTBOX` table. After this, remaining columns are shown. Dates / datetime fields have appropriate datepickers. Other fields may also have dropdowns to ensure entry of standard values, these can be configured in the `DATACTRL.MPE_SELECTBOX` table.
+3
View File
@@ -16,6 +16,9 @@ Adding tables to the Data Controller is a matter of configuration, specifically
![screenshot](img/configtable.png) ![screenshot](img/configtable.png)
!!! note
`_____DELETE__THIS__RECORD_____` is a reserved name. The editor creates that column itself - it is the **Delete?** column - and never reads it from the table, so a target table must not contain a column of that name. The editor refuses to open a table that does, rather than let the two collide.
## MPE_TABLES Configuration Details ## MPE_TABLES Configuration Details
Each table to be edited in the Data Controller is represented by one record in `DATACTRL.MPE_TABLES`. The fields should be populated as follows: Each table to be edited in the Data Controller is represented by one record in `DATACTRL.MPE_TABLES`. The fields should be populated as follows:
+1 -2
View File
@@ -101,7 +101,6 @@ The hook below is registered in `MPE_TABLES.PRE_EDIT_HOOK` for a table with a da
/* re-read the table, so the grid shows both quarters */ /* re-read the table, so the grid shows both quarters */
data work.out (drop=&var_txfrom &var_txto &var_processed &drop_rk); data work.out (drop=&var_txfrom &var_txto &var_processed &drop_rk);
_____DELETE__THIS__RECORD_____="No";
set &orig_libds; set &orig_libds;
where %inc newfilt; where %inc newfilt;
run; run;
@@ -130,7 +129,7 @@ The hook below is registered in `MPE_TABLES.PRE_EDIT_HOOK` for a table with a da
- **The user's clause.** `work.QUERY` is the filter's clauses as structured rows, and `%mp_filtergenerate` turns them back into a WHERE clause. This is the user's filter on its own, with no Row Level Security or validity clause mixed in. - **The user's clause.** `work.QUERY` is the filter's clauses as structured rows, and `%mp_filtergenerate` turns them back into a WHERE clause. This is the user's filter on its own, with no Row Level Security or validity clause mixed in.
- **Data Controller's clause.** Calling `%mpe_filtermaster` with `filter_rk=-1` produces the part of the filter that is not the user's: the current-record validity clause and any Row Level Security, or `1=1` when there is neither. - **Data Controller's clause.** Calling `%mpe_filtermaster` with `filter_rk=-1` produces the part of the filter that is not the user's: the current-record validity clause and any Row Level Security, or `1=1` when there is neither.
- **The combined filter.** The two clauses are combined as `( user OR previous-quarter ) AND ( validity + RLS )`, so the previous quarter is added to the user's selection without widening anything the user is not entitled to see. - **The combined filter.** The two clauses are combined as `( user OR previous-quarter ) AND ( validity + RLS )`, so the previous quarter is added to the user's selection without widening anything the user is not entitled to see.
- **The rows.** `work.OUT` is rebuilt with the combined filter, using the same drop list as the data step `getdata` runs itself - the transaction and processing columns, plus `&drop_rk`, the surrogate key that `getdata` hides when a table is registered with `RK_UNDERLYING` - and sorted on `&sortpk`, because `getdata` sorts before the hook runs and does not sort again afterwards. On a bitemporal table `getdata` also deduplicates to the latest record per primary key (`by &pk &var_busfrom`); add that step too, or the re-read returns every temporal version rather than the current one. - **The rows.** `work.OUT` is rebuilt with the combined filter, using the same drop list as the data step `getdata` runs itself - the transaction and processing columns, plus `&drop_rk`, the surrogate key that `getdata` hides when a table is registered with `RK_UNDERLYING` - and sorted on `&sortpk`, because `getdata` sorts before the hook runs and does not sort again afterwards. On a bitemporal table `getdata` also deduplicates to the latest record per primary key (`by &pk &var_busfrom`); add that step too, or the re-read returns every temporal version rather than the current one. The delete column is **not** re-added: `_____DELETE__THIS__RECORD_____` is created by the editor itself and is never a column of the dataset, so a hook must not introduce it (a response that carries that name is refused by the editor).
- **The returned text.** `filtref` is overwritten with the combined filter, so the clause the editor shows is the one that was actually applied. - **The returned text.** `filtref` is overwritten with the combined filter, so the clause the editor shows is the one that was actually applied.
### What it looks like ### What it looks like