Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e995626ff4 | ||
|
|
c800145ead | ||
|
|
504a3136b7 | ||
|
|
2e269341df | ||
|
|
6d09a8e1d8 | ||
|
|
19e50fdf6a | ||
|
|
6f4166dad3 | ||
|
|
aff6806bb9 | ||
|
|
13042876b8 | ||
|
|
7f2a76986a | ||
|
|
90b374a52e | ||
|
|
4316f519c4 | ||
|
|
be8d92f439 | ||
|
|
7770737963 | ||
|
|
fdb39a78a5 | ||
|
|
2a65664a51 | ||
|
|
c21f413f06 | ||
|
|
10448de15b | ||
|
|
83641a204f | ||
|
|
66c48a4cc7 | ||
|
|
1a5cea9ebe | ||
|
|
abf01d6375 | ||
|
|
e7fdb3ab52 | ||
|
|
4d53ced89c | ||
|
|
7d0e349247 | ||
|
|
99b2a7454e | ||
|
|
046f24d0b7 | ||
|
|
bd30a059ed | ||
|
|
206d88c6a9 | ||
|
|
cd47d0e442 | ||
|
|
85f200c724 | ||
|
|
4a53499055 | ||
|
|
d95f440c4f | ||
|
|
94b27628aa | ||
|
|
5236b74fee | ||
|
|
06df7e6e23 | ||
|
|
7e49033aae | ||
|
|
76bdc90ed8 | ||
|
|
6782b77e69 | ||
|
|
6d9d29b786 | ||
|
|
6f176b35e1 | ||
|
|
d342e51241 | ||
|
|
57e8a6e975 | ||
|
|
9666ca3300 | ||
|
|
6fa1b4f6ba | ||
|
|
1d0cfd6681 | ||
|
|
021db986e0 | ||
|
|
11f298ee2a | ||
|
|
034700a33e | ||
|
|
c875ce04b7 | ||
|
|
2f30680e84 | ||
|
|
9b68c55754 | ||
|
|
0590191ff4 | ||
|
|
964434af0a | ||
|
|
dec5f239de | ||
|
|
80cabc7312 | ||
|
|
ddd5866484 | ||
|
|
a0bb0c1e20 | ||
|
|
1b590a6ee7 | ||
|
|
874e045dff | ||
|
|
1ca32b4b71 | ||
|
|
b880988887 | ||
|
|
55ad7424fd | ||
|
|
f3954fa046 | ||
|
|
05a16acabb | ||
|
|
ae6620b3db | ||
|
|
447397236b | ||
|
|
3bfd96f431 | ||
|
|
ffdbdb869c | ||
|
|
535937b586 | ||
|
|
ad5a566001 | ||
|
|
15c617f48e | ||
|
|
6a950ea839 | ||
|
|
5dfbc2526e | ||
|
|
ca8499de90 | ||
|
|
102f59d2e8 | ||
|
|
71af1df610 | ||
|
|
f9daa7dfbb | ||
|
|
965efacf70 | ||
|
|
bd3addd619 | ||
|
|
81ec07117d | ||
|
|
45a46d6a0a | ||
|
|
52c3101807 | ||
|
|
6a66f8439d | ||
|
|
38045f9ba6 | ||
|
|
6309e91272 | ||
|
|
807dd55bac | ||
|
|
2ec7d35342 | ||
|
|
4c45779312 | ||
|
|
92f2f4f6d2 | ||
|
|
5ec342cbc4 | ||
|
|
f090dc18ba | ||
|
|
7c2cc2628b | ||
|
|
c6ef23d54b | ||
|
|
5715d17312 |
No files matched your search
@@ -12,20 +12,17 @@ jobs:
|
|||||||
- uses: actions/setup-node@v3
|
- uses: actions/setup-node@v3
|
||||||
with:
|
with:
|
||||||
node-version: 18
|
node-version: 18
|
||||||
|
|
||||||
- name: Checkout master
|
- name: Checkout master
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v4 # Updated to latest version
|
||||||
|
|
||||||
- name: Setup Python
|
- name: Setup Python
|
||||||
uses: actions/setup-python@v4
|
uses: actions/setup-python@v4
|
||||||
|
with:
|
||||||
|
python-version: '3.12' # Specify your desired version (e.g., 3.10 or 3.12)
|
||||||
env:
|
env:
|
||||||
AGENT_TOOLSDIRECTORY: /opt/hostedtoolcache
|
AGENT_TOOLSDIRECTORY: /opt/hostedtoolcache
|
||||||
RUNNER_TOOL_CACHE: /opt/hostedtoolcache
|
RUNNER_TOOL_CACHE: /opt/hostedtoolcache
|
||||||
|
|
||||||
- name: Install pip3
|
|
||||||
run: |
|
|
||||||
apt-get update
|
|
||||||
apt-get install python3-pip -y
|
|
||||||
|
|
||||||
- name: Install Chrome
|
- name: Install Chrome
|
||||||
run: |
|
run: |
|
||||||
@@ -40,14 +37,13 @@ jobs:
|
|||||||
|
|
||||||
- name: build site
|
- name: build site
|
||||||
run: |
|
run: |
|
||||||
pip3 install mkdocs
|
pip install mkdocs
|
||||||
pip3 install mkdocs-material
|
pip install mkdocs-material
|
||||||
pip3 install fontawesome_markdown
|
pip install fontawesome_markdown
|
||||||
pip3 install mkdocs-redirects
|
pip install mkdocs-redirects
|
||||||
python3 -m mkdocs build --clean
|
mkdocs build --clean
|
||||||
mkdir site/slides
|
mkdir site/slides
|
||||||
npx @marp-team/marp-cli slides/innovation/innovation.md -o ./site/slides/innovation/index.html
|
npx @marp-team/marp-cli slides/innovation/innovation.md -o ./site/slides/innovation/index.html
|
||||||
npx @marp-team/marp-cli slides/if/if.md -o site/if.pdf --allow-local-files --html=true
|
npx @marp-team/marp-cli slides/if/if.md -o site/if.pdf --allow-local-files --html=true
|
||||||
|
|
||||||
- name: Deploy docs
|
- name: Deploy docs
|
||||||
run: surfer put --token ${{ secrets.SURFERKEY }} --server docs.datacontroller.io site/* /
|
run: surfer put --token ${{ secrets.SURFERKEY }} --server docs.datacontroller.io site/* /
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
# This configuration file was automatically generated by Gitpod.
|
|
||||||
# Please adjust to your needs (see https://www.gitpod.io/docs/config-gitpod-file)
|
|
||||||
# and commit this file to your remote git repository to share the goodness with others.
|
|
||||||
|
|
||||||
tasks:
|
|
||||||
- init: npm install
|
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,51 @@
|
|||||||
|
# Agent Instructions
|
||||||
|
|
||||||
|
This repository is the **user-facing documentation** for Data Controller for SAS®, published at [docs.datacontroller.io](https://docs.datacontroller.io). It is a [MkDocs](https://www.mkdocs.org/) site using the Material theme.
|
||||||
|
|
||||||
|
## Related repositories
|
||||||
|
|
||||||
|
Data Controller spans three sibling repositories (usually checked out side by side under the same parent directory):
|
||||||
|
|
||||||
|
- **`dc`** - the product source (Angular client + SAS backend). The behaviour documented here is implemented there. Deep technical notes live in `dc/.agent/docs/`.
|
||||||
|
- **`docs.datacontroller.io`** (this repo) - the user-facing product documentation.
|
||||||
|
- **`datacontroller.io`** - the marketing site, blog and feed (Gatsby).
|
||||||
|
|
||||||
|
When documenting a feature, the source of truth for behaviour is `dc`. When a doc page describes internals, prefer linking to the user-facing concept rather than duplicating implementation detail.
|
||||||
|
|
||||||
|
## Structure
|
||||||
|
|
||||||
|
- Pages are Markdown files in `docs/`.
|
||||||
|
- The navigation tree, site config, theme, plugins and redirects are all defined in `mkdocs.yml`. **A new page is not published until it is added to the `nav:` tree in `mkdocs.yml`.**
|
||||||
|
- `docs/tables/` documents the `MPE_*` control tables (see naming conventions below).
|
||||||
|
- `docs/img/` holds images; `docs/video/` holds video assets; `docs/marketing/` holds flyers/PDFs.
|
||||||
|
- `theme/` is the custom Material theme override; `slides/` and `slides.md` are the presentation deck.
|
||||||
|
|
||||||
|
## Page conventions
|
||||||
|
|
||||||
|
- Each page starts with YAML front matter: `layout: article`, `title`, `description`, and usually `og_image`. Match the style of existing pages.
|
||||||
|
- `description` is used for SEO and social cards - write a single, complete sentence.
|
||||||
|
- Reference images with root-relative paths (e.g. `/img/foo.png`) or relative paths consistent with neighbouring pages.
|
||||||
|
- This site uses these `markdown_extensions`: `admonition`, `pymdownx.superfences`, `codehilite`, `meta`, and `toc` (with permalinks). Use fenced code blocks with language hints (`sas`, `js`, `bash` are highlighted); use admonitions (`!!! note`) for callouts.
|
||||||
|
- Internal links use the page slug with a trailing slash (e.g. `/dcc-validations/`), matching existing cross-references.
|
||||||
|
|
||||||
|
## MPE table docs (`docs/tables/`)
|
||||||
|
|
||||||
|
Control tables are documented one file per table, named `mpe_<name>.md`, and registered under the "Table Guide" section of `nav:` in `mkdocs.yml`. Follow the existing pattern:
|
||||||
|
|
||||||
|
- Front matter with a `description` explaining what the table configures.
|
||||||
|
- A short intro paragraph, then a link to the relevant configuration guide.
|
||||||
|
- A `## Columns` list. Prefix primary-key / business-key columns with the 🔑 emoji, and give each column as `` `NAME type` ``: description. SCD2 tables carry `TX_FROM`/`TX_TO` as the first two columns.
|
||||||
|
|
||||||
|
## Writing style
|
||||||
|
|
||||||
|
Use regular dashes (`-`) in content, not em-dashes. Do not hard-wrap Markdown: each paragraph, list item and heading is a single logical line, regardless of length - let the renderer soft-wrap. This keeps diffs clean.
|
||||||
|
|
||||||
|
## Building
|
||||||
|
|
||||||
|
- `pip install mkdocs mkdocs-material mkdocs-redirects` (see `build.sh` / `mkdocs.yml` for the exact plugin list).
|
||||||
|
- `mkdocs serve` for a live-reloading local preview; `mkdocs build` (or `./build.sh`) to produce the static site.
|
||||||
|
- After adding or renaming a page, confirm it appears in the `nav:` tree and that `mkdocs build` reports no warnings about missing/orphaned files.
|
||||||
|
|
||||||
|
## Git
|
||||||
|
|
||||||
|
Do NOT auto-commit or push. Leave changes in the working tree for the user to review and commit.
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
# Context: docs.datacontroller.io (product documentation)
|
||||||
|
|
||||||
|
The user-facing documentation for Data Controller for SAS®, published at [docs.datacontroller.io](https://docs.datacontroller.io) as a **MkDocs** (Material theme) static site.
|
||||||
|
|
||||||
|
## What the product is
|
||||||
|
|
||||||
|
Data Controller for SAS® is a web application that lets users safely add, modify and delete data in SAS datasets and databases. Every change is **staged** and **approved** before being applied to the **target table**, and the change history is retained. It runs on SAS Viya, SAS 9 EBI and SASjs Server. The product source lives in the sibling `dc` repo (see its `CONTEXT.md` for the full domain glossary); the marketing site is `datacontroller.io`.
|
||||||
|
|
||||||
|
## Domain vocabulary (used throughout the docs)
|
||||||
|
|
||||||
|
- **Roles**: Viewer, Editor, Approver, Auditor, Administrator.
|
||||||
|
- **Target table**: the physical SAS/database table a user changes; configured by an admin in `MPE_TABLES`.
|
||||||
|
- **Submission / staging / approval**: changes are staged and require approval before being applied.
|
||||||
|
- **Load types** (`MPE_TABLES.LOADTYPE`): `UPDATE`, `REPLACE`, `TXTEMPORAL`, `BITEMPORAL`, `FORMAT_CAT` - determine history behaviour (SCD2 / bitemporal / none).
|
||||||
|
- **MPE control tables** (`MPE_*`): configuration and state tables, each documented under `docs/tables/mpe_<name>.md`.
|
||||||
|
- **Validations** (`MPE_VALIDATIONS`): point-of-entry data-quality rules.
|
||||||
|
- **Row / Column Level Security** (RLS / CLS): server-side access control.
|
||||||
|
|
||||||
|
Use these terms consistently; match the casing used in the existing docs.
|
||||||
|
|
||||||
|
## Structure
|
||||||
|
|
||||||
|
- Pages are Markdown in `docs/`. **A page is not published until it is added to the `nav:` tree in `mkdocs.yml`.**
|
||||||
|
- `docs/tables/` documents the `MPE_*` control tables (one file per table, following the shared column-list pattern with 🔑 for key columns).
|
||||||
|
- `mkdocs.yml` defines nav, theme, plugins (search, redirects) and markdown extensions (`admonition`, `pymdownx.superfences`, `codehilite`, `meta`, `toc`).
|
||||||
|
|
||||||
|
## Conventions
|
||||||
|
|
||||||
|
- Front matter per page: `layout: article`, `title`, `description`, usually `og_image`.
|
||||||
|
- Use regular dashes, not em-dashes. Do not hard-wrap Markdown.
|
||||||
|
- Preview with `mkdocs serve`; build with `mkdocs build` (or `./build.sh`) and confirm no warnings.
|
||||||
|
|
||||||
|
See `AGENTS.md` for full page/table conventions and build instructions.
|
||||||
@@ -1,98 +1,24 @@
|
|||||||
---
|
---
|
||||||
layout: article
|
layout: article
|
||||||
title: Admin Services
|
title: Admin Services
|
||||||
description: Data Controller contains a number of admin-only web services, such as DB Export, Lineage Generation, and Data Catalog refresh.
|
description: The Administrator Screen provides useful system information and buttons for various administrator actions
|
||||||
|
og_title: Administrator Screen
|
||||||
|
og_image: /img/admininfo.png
|
||||||
---
|
---
|
||||||
|
|
||||||
# Admin Services
|
## Administrator Screen
|
||||||
|
|
||||||
Several web services have been defined to provide additional functionality outside of the user interface. These somewhat-hidden services must be called directly, using a web browser.
|
The admin screen (under user profile / System) displays a number of useful system parameters as well as several buttons for executing administrator specific actions
|
||||||
|
|
||||||
In a future version, these features will be made available from an Admin screen (so, no need to manually modify URLs).
|

|
||||||
|
|
||||||
The URL is made up of several components:
|
Button info as follows:
|
||||||
|
|
||||||
* `SERVERURL` -> the domain (and port) on which your SAS server resides
|
|Button|Description|
|
||||||
* `EXECUTOR` -> Either `SASStoredProcess` for SAS 9, else `SASJobExecution` for Viya
|
|---|---|
|
||||||
* `APPLOC` -> The root folder location in which the Data Controller backend services were deployed
|
|Refresh Data Lineage|This is only displayed for SAS9 installs. Will refresh all TABLE level data lineage (impact analysis) using an efficient batch approach (proc metadata).|
|
||||||
* `SERVICE` -> The actual Data Controller service being described. May include additional parameters.
|
|Refresh Data Catalog|Update Data Catalog for ALL libraries. More info [here](/dcu-datacatalog).|
|
||||||
|
|Download Configuration|This downloads a zip file containing the current database configuration - useful for migrating to a different data controller database instance.|
|
||||||
|
|Update Licence Key| Link to the screen for providing a new Data Controller licence key|
|
||||||
|
|Export DC Library DDL|COMING SOON!! <br>Exports the data controller control library in DB specific DDL (eg SAS, PGSQL, TSQL) and allows an optional schema name to be included|
|
||||||
|
|
||||||
To illustrate the above, consider the following URL:
|
|
||||||
|
|
||||||
[https://viya.4gl.io/SASJobExecution/?_program=/Public/app/viya/services/admin/exportdb&flavour=PGSQL](https://viya.4gl.io/SASJobExecution/?_program=/Public/app/viya/services/admin/exportdb&flavour=PGSQL
|
|
||||||
)
|
|
||||||
|
|
||||||
This is broken down into:
|
|
||||||
|
|
||||||
* `$SERVERURL` = `https://sas.analytium.co.uk`
|
|
||||||
* `$EXECUTOR` = `SASJobExecution`
|
|
||||||
* `$APPLOC` = `/Public/app/dc`
|
|
||||||
* `$SERVICE` = `services/admin/exportdb&flavour=PGSQL`
|
|
||||||
|
|
||||||
The below sections will only describe the `$SERVICE` component - you may construct this into a URL as follows:
|
|
||||||
|
|
||||||
* `$SERVERURL/$EXECUTOR?_program=$APPLOC/$SERVICE`
|
|
||||||
|
|
||||||
## Export Config
|
|
||||||
|
|
||||||
This service will provide a zip file containing the current database configuration. This is useful for migrating to a different data controller database instance.
|
|
||||||
|
|
||||||
EXAMPLE:
|
|
||||||
|
|
||||||
* `services/admin/exportconfig`
|
|
||||||
|
|
||||||
## Export Database
|
|
||||||
Exports the data controller control library in DB specific DDL. The following URL parameters may be added:
|
|
||||||
|
|
||||||
* `&flavour=` (only PGSQL supported at this time)
|
|
||||||
* `&schema=` (optional, if target schema is needed)
|
|
||||||
|
|
||||||
EXAMPLES:
|
|
||||||
|
|
||||||
* `services/admin/exportdb&flavour=PGSQL&schema=DC`
|
|
||||||
* `services/admin/exportdb&flavour=PGSQL`
|
|
||||||
|
|
||||||
## Refresh Data Catalog
|
|
||||||
|
|
||||||
In any SAS estate, it's unlikely the size & shape of data will remain static. By running a regular Catalog Scan, you can track changes such as:
|
|
||||||
|
|
||||||
- Library Properties (size, schema, path, number of tables)
|
|
||||||
- Table Properties (size, number of columns, primary keys)
|
|
||||||
- Variable Properties (presence in a primary key, constraints, position in the dataset)
|
|
||||||
|
|
||||||
The data is stored with SCD2 so you can actually **track changes to your model over time**! Curious when that new column appeared? Just check the history in [MPE_DATACATALOG_TABS](/tables/mpe_datacatalog_tabs).
|
|
||||||
|
|
||||||
To run the refresh process, just trigger the stored process, eg below:
|
|
||||||
|
|
||||||
* `services/admin/refreshcatalog`
|
|
||||||
* `services/admin/refreshcatalog&libref=MYLIB`
|
|
||||||
|
|
||||||
The optional `&libref=` parameter allows you to run the process for a single library. Just provide the libref.
|
|
||||||
|
|
||||||
When doing a full scan, the following LIBREFS are ignored:
|
|
||||||
|
|
||||||
* 'CASUSER'
|
|
||||||
* 'MAPSGFK'
|
|
||||||
* 'SASUSER'
|
|
||||||
* 'SASWORK
|
|
||||||
* 'STPSAMP'
|
|
||||||
* 'TEMP'
|
|
||||||
* `WORK'
|
|
||||||
|
|
||||||
Additional LIBREFs can be excluded by adding them to the `DCXXXX.MPE_CONFIG` table (where `var_scope='DC_CATALOG' and var_name='DC_IGNORELIBS'`). Use a pipe (`|`) symbol to seperate them. This can be useful where there are connection issues for a particular library.
|
|
||||||
|
|
||||||
Be aware that the scan process can take a long time if you have a lot of tables!
|
|
||||||
|
|
||||||
Output tables (all SCD2):
|
|
||||||
|
|
||||||
* [MPE_DATACATALOG_LIBS](/tables/mpe_datacatalog_libs) - Library attributes
|
|
||||||
* [MPE_DATACATALOG_TABS](/tables/mpe_datacatalog_tabs) - Table attributes
|
|
||||||
* [MPE_DATACATALOG_VARS](/tables/mpe_datacatalog_vars) - Column attributes
|
|
||||||
* [MPE_DATASTATUS_LIBS](/tables/mpe_datastatus_libs) - Frequently changing library attributes (such as size & number of tables)
|
|
||||||
* [MPE_DATASTATUS_TABS](/tables/mpe_datastatus_tabs) - Frequently changing table attributes (such as size & number of rows)
|
|
||||||
|
|
||||||
## Update Licence Key
|
|
||||||
|
|
||||||
Whenever navigating Data Controller, there is always a hash (`#`) in the URL. To access the licence key screen, remove all content to the RIGHT of the hash and add the following string: `/licensing/update`.
|
|
||||||
|
|
||||||
If you are using https protocol, you will have 2 keys (licence key / activation key). In http mode, there is just one key (licence key) for both boxes.
|
|
||||||
@@ -0,0 +1,56 @@
|
|||||||
|
---
|
||||||
|
layout: article
|
||||||
|
title: CAS Tables
|
||||||
|
description: Dealing with CAS (in-memory) Tables in Data Controller
|
||||||
|
og_image: /img/SAS-Viya-and-CAS-300x249.png
|
||||||
|
---
|
||||||
|
|
||||||
|
!!! warning
|
||||||
|
Work in Progress!
|
||||||
|
|
||||||
|
# CAS Tables
|
||||||
|
|
||||||
|
CAS Tables require special consideration in Data Controller with regards to the following topics:
|
||||||
|
|
||||||
|
- System Account
|
||||||
|
- Loading
|
||||||
|
- Unloading
|
||||||
|
- Special Variables
|
||||||
|
|
||||||
|
## System Account
|
||||||
|
|
||||||
|
Despite having a shared SYSUSERID, the SPRE session will (by default) authenticate using the logged-in user credentials. To get around this, it is necessary to set up the CAS connection in the autoexec - ie, before the user takes over the session. The code snippet will be:
|
||||||
|
|
||||||
|
```sas
|
||||||
|
%let _CASHOST_ = <your-host>;
|
||||||
|
|
||||||
|
%let _CASPORT_ = 5570;
|
||||||
|
|
||||||
|
cas dcsession authdomain="<your-domain>" sessopts=(caslib=casuser);
|
||||||
|
```
|
||||||
|
|
||||||
|
The credentials need to be first placed in the viya credentials service as described [here](https://go.documentation.sas.com/doc/en/pgmsascdc/v_073/casref/n0z3r80fjqpobvn1lvegno9gefni.htm#p11ynzjbz96oq1n17rgt2utv6swj).
|
||||||
|
|
||||||
|
Another approach can be to use the `AUTHINFO="authentication-file" option, as described [here](https://go.documentation.sas.com/doc/en/pgmsascdc/v_073/casref/n0z3r80fjqpobvn1lvegno9gefni.htm#n174yddgn85756n1v5q4yb881xa0).
|
||||||
|
|
||||||
|
Note that since the CAS connection is using a shared account, the CASUSER library is never shown in the DC interface.
|
||||||
|
|
||||||
|
## Loading
|
||||||
|
|
||||||
|
It can happen that a CAS table is configured in Data Controller but not loaded into memory. In this case, when a user selects the table, it will be automatically loaded.
|
||||||
|
|
||||||
|
## Unloading
|
||||||
|
|
||||||
|
After an approval, the in-memory version of the CAS Table will be updated. To apply this to the underlying file on disk, the following code must be executed (eg in a POST APPROVE HOOK):
|
||||||
|
|
||||||
|
```sas
|
||||||
|
proc casutil;
|
||||||
|
save casdata="mytable" incaslib="mycaslib"
|
||||||
|
casout="mytable" outcaslib="mycaslib"
|
||||||
|
replace;
|
||||||
|
quit;
|
||||||
|
```
|
||||||
|
|
||||||
|
## Special Variables
|
||||||
|
|
||||||
|
Processing of data in Data Controller is performed in SPRE with SAS datasets - and as such, it is not possible to process character variables longer than 32k or other CAS specific data types.
|
||||||
@@ -0,0 +1,45 @@
|
|||||||
|
/*
|
||||||
|
* Data Controller brand overrides for the Material theme.
|
||||||
|
*
|
||||||
|
* The values below mirror the marketing site (https://datacontroller.io): the
|
||||||
|
* slate used for its navbar and hero, and the green used for its logo accent.
|
||||||
|
* They are wired up through the `custom` palette in mkdocs.yml, which leaves
|
||||||
|
* these CSS variables for us to define.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Primary - the brand slate, used for the header, the mobile drawer title and body links. */
|
||||||
|
:root,
|
||||||
|
[data-md-color-primary='custom'] {
|
||||||
|
--md-primary-fg-color: #314351;
|
||||||
|
--md-primary-fg-color--light: #3d5468;
|
||||||
|
--md-primary-fg-color--dark: #263542;
|
||||||
|
--md-primary-bg-color: #fff;
|
||||||
|
--md-primary-bg-color--light: #ffffffb3;
|
||||||
|
--md-typeset-a-color: #314351;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Accent - the brand green, used for link hover, focus rings and the active search hit. */
|
||||||
|
[data-md-color-accent='custom'] {
|
||||||
|
--md-accent-fg-color: #79a843;
|
||||||
|
--md-accent-fg-color--transparent: #79a8431a;
|
||||||
|
--md-accent-bg-color: #fff;
|
||||||
|
--md-accent-bg-color--light: #ffffffb3;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Dark scheme. Material derives its dark greys from a hue variable, so pointing
|
||||||
|
* that at the brand slate (206deg) gives the whole scheme the same cast as the
|
||||||
|
* header instead of Material's neutral default.
|
||||||
|
*/
|
||||||
|
[data-md-color-scheme='slate'] {
|
||||||
|
--md-hue: 206deg;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The brand slate is only readable on a light background, so the dark scheme
|
||||||
|
* uses a light tint of it for body links. Green stays the accent, which keeps
|
||||||
|
* link hover visible in both schemes.
|
||||||
|
*/
|
||||||
|
[data-md-color-scheme='slate'][data-md-color-primary='custom'] {
|
||||||
|
--md-typeset-a-color: #9fb5c6;
|
||||||
|
}
|
||||||
@@ -48,6 +48,18 @@ After this, remaining columns are shown. Dates / datetime fields have appropria
|
|||||||
|
|
||||||
New rows can be added using the right click context menu, or the 'Add Row' button. The data can also be sorted by clicking on the column headers.
|
New rows can be added using the right click context menu, or the 'Add Row' button. The data can also be sorted by clicking on the column headers.
|
||||||
|
|
||||||
|
#### Native Date and Time Pickers
|
||||||
|
|
||||||
|
Date, time, and datetime columns use native browser pickers when editing a cell. This provides a familiar calendar and time selector, and respects your browser's locale settings for date and time formats.
|
||||||
|
|
||||||
|
#### Paste Validation Overlay
|
||||||
|
|
||||||
|
When you paste data into the editor (or drag to autofill cells), a confirmation overlay appears so you can review the changes before they are applied. All pasted values are checked against your configured [validation rules](/dcc-validations/). For large pastes, a progress indicator shows how many cells have been validated.
|
||||||
|
|
||||||
|
#### Row Status Indicators
|
||||||
|
|
||||||
|
Each row's header cell is colour-coded to show its current status - modified, added, deleted, or unchanged. The "modified" indicator uses a `±` symbol so you can quickly spot which rows have changed.
|
||||||
|
|
||||||
When ready to submit, hit the SUBMIT button and enter a reason for the change. The owners of the data are now alerted (so long as their email addresses are in metadata) with a link to the approve screen.
|
When ready to submit, hit the SUBMIT button and enter a reason for the change. The owners of the data are now alerted (so long as their email addresses are in metadata) with a link to the approve screen.
|
||||||
If you are also an approver you can approve this change yourself.
|
If you are also an approver you can approve this change yourself.
|
||||||
|
|
||||||
@@ -60,7 +72,7 @@ Data Controller supports special missing numerics, ie - a single letter or under
|
|||||||
The Data Controller only permits BiTemporal data uploads at a single point in time - so for convenience, when viewing data in the edit screen, only the most recent records are displayed. To edit earlier records, either use file upload, or apply a filter.
|
The Data Controller only permits BiTemporal data uploads at a single point in time - so for convenience, when viewing data in the edit screen, only the most recent records are displayed. To edit earlier records, either use file upload, or apply a filter.
|
||||||
|
|
||||||
### Submitted
|
### Submitted
|
||||||
This page shows a list of the changes you have submitted (that are not yet approved).
|
This page shows a list of the changes you have submitted (that are not yet approved). When you open a submitted change for review, you can toggle between viewing the data with SAS formats applied (eg formatted dates and currency) or as raw underlying values. This is useful when you need to verify the exact value being submitted rather than its display representation.
|
||||||
|
|
||||||
### Approvals
|
### Approvals
|
||||||
This shows the list of changes that have been submitted to you (or your groups) for approval.
|
This shows the list of changes that have been submitted to you (or your groups) for approval.
|
||||||
|
|||||||
@@ -39,6 +39,14 @@ run;
|
|||||||
|
|
||||||
!!! note
|
!!! note
|
||||||
Data Controller does not support decimals when EDITING. For datetimes, this means that values must be rounded to 1 second (milliseconds are not supported).
|
Data Controller does not support decimals when EDITING. For datetimes, this means that values must be rounded to 1 second (milliseconds are not supported).
|
||||||
|
|
||||||
|
In the LOAD screen these dates display as **ISO 8601** (`YYYY-MM-DD`, `HH:mm:ss`, `YYYY-MM-DDTHH:mm:ss`) regardless of the user's locale. This guarantees:
|
||||||
|
|
||||||
|
- Consistent CSV / Excel exports across geographies
|
||||||
|
- Predictable copy / paste between cells and into external tools
|
||||||
|
- No more `1/2/2026` vs `2/1/2026` ambiguity at edit time
|
||||||
|
|
||||||
|
If you need a locale-specific *display* (eg `DD/MM/YYYY`) on a per-column basis, use the new [`NUMBER_FORMAT`](/dcc-validations/) rule with an `Intl.DateTimeFormat`-compatible JSON value.
|
||||||
|
|
||||||
If you have other dates / datetimes / times you would like us to support, do [get in touch](https://datacontroller.io/contact)!
|
If you have other dates / datetimes / times you would like us to support, do [get in touch](https://datacontroller.io/contact)!
|
||||||
|
|
||||||
|
|||||||
@@ -1,41 +1,52 @@
|
|||||||
---
|
---
|
||||||
layout: article
|
layout: article
|
||||||
title: DC Options
|
title: DC Configuration Options
|
||||||
description: Options in Data Controller are set in the MPE_CONFIG table and apply to all users.
|
description: Configuration Options in Data Controller are set in the MPE_CONFIG table and apply to all users.
|
||||||
og_title: Data Controller for SAS® Options
|
og_title: Data Controller for SAS® Options
|
||||||
og_image: /img/mpe_config.png
|
og_image: /img/mpe_config.png
|
||||||
---
|
---
|
||||||
# Data Controller for SAS® - Options
|
# Configuration Options
|
||||||
|
|
||||||
The [MPE_CONFIG](/tables/mpe_config/) table provides a number of system options, which apply to all users. The table may be re-purposed for other applications, so long as scopes beginning with "DC_" are avoided.
|
The [MPE_CONFIG](/tables/mpe_config/) table provides a number of system configuration options, which apply to all users. The table may be re-purposed for other applications, so long as scopes beginning with "DC_" are avoided.
|
||||||
|
|
||||||
Currently used scopes include:
|
Currently used scopes include:
|
||||||
|
|
||||||
* DC
|
* [DC](/dcc-options/#dc-scope)
|
||||||
* DC_CATALOG
|
* [DC_CATALOG](/dcc-options/#dc_catalog-scope)
|
||||||
|
* [DC_EMAIL](/dcc-options/#dc_email-scope)
|
||||||
|
|
||||||
## DC Scope
|
## DC Scope
|
||||||
|
|
||||||
### DC_EMAIL_ALERTS
|
### DC_EMAIL_ALERTS
|
||||||
Set to YES or NO to enable email alerts. This requires email options to be preconfigured (mail server etc).
|
Set to YES or NO to enable email alerts. This requires email options to be preconfigured (mail server etc).
|
||||||
|
|
||||||
|
### DC_MAXCELLS_WEBEDIT
|
||||||
|
By default, a maximum of 200,000 cells (observations multiplied by variables) can be edited in the browser at one time. This limit is applied together with [DC_MAXOBS_WEBEDIT](#dc_maxobs_webedit) - whichever is reached first.
|
||||||
|
|
||||||
|
The cell count matters because the cost of an EDIT screen load tracks the number of cells, not the number of rows. A 10 column table is comfortable at 250 rows, but 250 rows of a 1000 column table is 250,000 cells.
|
||||||
|
|
||||||
### DC_MAXOBS_WEBEDIT
|
### DC_MAXOBS_WEBEDIT
|
||||||
By default, a maximum of 100 observations can be edited in the browser at one time. This number can be increased, but note that the following factors will impact performance:
|
By default, a maximum of 250 observations can be edited in the browser at one time. This number can be increased, but note that the following factors will impact performance:
|
||||||
|
|
||||||
* Number of configured [Validations](/dcc-validations)
|
* Number of configured [Validations](/dcc-validations)
|
||||||
* Browser type and version (works best in Chrome)
|
* Browser type and version (works best in Chrome)
|
||||||
* Number (and size) of columns
|
* Number (and size) of columns
|
||||||
* Speed of client machine (laptop/desktop)
|
* Speed of client machine (laptop/desktop)
|
||||||
|
|
||||||
|
A wide table can reach the [DC_MAXCELLS_WEBEDIT](#dc_maxcells_webedit) limit well before this one, so increase both together.
|
||||||
|
|
||||||
|
### DC_MAXOBS_WEBVIEW
|
||||||
|
By default, a maximum of 2000 observations can be viewed in the browser at one time. Please see previous section for items to consider if increasing this value.
|
||||||
|
|
||||||
### DC_REQUEST_LOGS
|
### DC_REQUEST_LOGS
|
||||||
On SASjs Server and SAS9 Server types, at the end of each DC SAS request, a record is added to the [MPE_REQUESTS](/tables/mpe_requests) table. In some situations this can cause table locks. To prevent this issue from occuring, the `DC_REQUEST_LOGS` option can be set to `NO` (Default is `YES`).
|
On SASjs Server and SAS9 Server types, at the end of each DC SAS request, a record is added to the [MPE_REQUESTS](/tables/mpe_requests) table. In some situations this can cause table locks. To prevent this issue from occuring, the `DC_REQUEST_LOGS` option can be set to `NO` (Default is `YES`).
|
||||||
|
|
||||||
### DC_RESTRICT_EDITRECORD
|
### DC_RESTRICT_EDITRECORD
|
||||||
Setting YES will prevent the EDIT RECORD dialog appearing in the EDIT screen by removing the "Edit Row" option in the right click menu, and the "ADD RECORD" button in the bottom left.
|
Setting YES will prevent the EDIT RECORD dialog appearing in the EDIT screen by removing the "Edit Row" option in the right click menu, and the "ADD RECORD" button in the bottom left.
|
||||||
|
|
||||||
Anything other than YES will mean that the modal _is_ available.
|
Anything other than YES will mean that the modal _is_ available.
|
||||||
|
|
||||||
Default=NO
|
Default=NO
|
||||||
|
|
||||||
### DC_RESTRICT_VIEWER
|
### DC_RESTRICT_VIEWER
|
||||||
Set to YES to restrict the list of libraries and tables in VIEWER to only those explicitly set to VIEW in the MPE_SECURITY table. The default is NO (users can see all tables they already have permission to see).
|
Set to YES to restrict the list of libraries and tables in VIEWER to only those explicitly set to VIEW in the MPE_SECURITY table. The default is NO (users can see all tables they already have permission to see).
|
||||||
@@ -53,7 +64,7 @@ Default=SYSTEM.
|
|||||||
|
|
||||||
!!! note
|
!!! note
|
||||||
If you have clients in different geographies loading excel in local formats, you can also address this issue by ensuring the locale of the windows _user_ profile is not set to the default (eg `English (United States)`). When leaving the DC_LOCALE as SYSTEM, the locale settings in SAS are not added or modified.
|
If you have clients in different geographies loading excel in local formats, you can also address this issue by ensuring the locale of the windows _user_ profile is not set to the default (eg `English (United States)`). When leaving the DC_LOCALE as SYSTEM, the locale settings in SAS are not added or modified.
|
||||||
|
|
||||||
## DC_CATALOG Scope
|
## DC_CATALOG Scope
|
||||||
|
|
||||||
### DC_IGNORELIBS
|
### DC_IGNORELIBS
|
||||||
@@ -66,4 +77,36 @@ When running the [Refresh Data Catalog](/admin-services/#refresh-data-catalog) s
|
|||||||
|
|
||||||
Number of rows to return for each HISTORY page. Default - 100. Increasing this will increase for all users. Using very large numbers here can result in a sluggish page load time. If you need large amounts of HISTORY data, it is generally better to extract it directly from the [MPE_REVIEW](/tables/mpe_review/) table.
|
Number of rows to return for each HISTORY page. Default - 100. Increasing this will increase for all users. Using very large numbers here can result in a sluggish page load time. If you need large amounts of HISTORY data, it is generally better to extract it directly from the [MPE_REVIEW](/tables/mpe_review/) table.
|
||||||
|
|
||||||
|
## DC_EMAIL Scope
|
||||||
|
|
||||||
|
This section allows more fine grained control over the email configuration. Be sure that `DC_EMAIL_ALERTS` is set to `YES` (above) for these to activate.
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
Embedded macro variables are resolved at runtime.
|
||||||
|
|
||||||
|
### APPROVED_TEMPLATE
|
||||||
|
|
||||||
|
Sent when a change is approved. Available variables:
|
||||||
|
|
||||||
|
- ALERT_LIB: Library of table being edited
|
||||||
|
- ALERT_DS: table being edited
|
||||||
|
- FROM_USER: the user who made the approval
|
||||||
|
|
||||||
|
### REJECTED_TEMPLATE
|
||||||
|
|
||||||
|
Sent when a change is rejected. Available variables:
|
||||||
|
|
||||||
|
- ALERT_LIB: Library of table being edited
|
||||||
|
- ALERT_DS: table being edited
|
||||||
|
- FROM_USER: the user who made the rejection
|
||||||
|
- REVIEW_REASON_TXT: The text provided by the user who made the rejection
|
||||||
|
|
||||||
|
### SUBMITTED_TEMPLATE
|
||||||
|
|
||||||
|
Sent when a change is submitted. Available variables:
|
||||||
|
|
||||||
|
- ALERT_LIB: Library of table being edited
|
||||||
|
- ALERT_DS: table being edited
|
||||||
|
- FROM_USER: the user who made the submission
|
||||||
|
- SUBMITTED_TXT: The text provided by the user who made the submission.
|
||||||
@@ -212,7 +212,6 @@ The code is simply `%include`'d at the relevant point during backend execution.
|
|||||||
* Physical, ie the full path to a `.sas` program on the physical server directory
|
* Physical, ie the full path to a `.sas` program on the physical server directory
|
||||||
* Logical, ie a Viya Job (SAS Drive), SAS 9 Stored Process (Metadata Folder) or SASJS Stored Program (SASjs Drive).
|
* Logical, ie a Viya Job (SAS Drive), SAS 9 Stored Process (Metadata Folder) or SASJS Stored Program (SASjs Drive).
|
||||||
|
|
||||||
|
|
||||||
If the entry ends in `".sas"` it is assumed to be a physical, filesystem file. Otherwise, the source code is extracted from SAS Drive or Metadata.
|
If the entry ends in `".sas"` it is assumed to be a physical, filesystem file. Otherwise, the source code is extracted from SAS Drive or Metadata.
|
||||||
|
|
||||||
To illustrate:
|
To illustrate:
|
||||||
@@ -220,5 +219,7 @@ To illustrate:
|
|||||||
* Physical filesystem (ends in .sas): `/opt/sas/code/myprogram.sas`
|
* Physical filesystem (ends in .sas): `/opt/sas/code/myprogram.sas`
|
||||||
* Logical filesystem: `/Shared Data/stored_processes/mydatavalidator`
|
* Logical filesystem: `/Shared Data/stored_processes/mydatavalidator`
|
||||||
|
|
||||||
|
You can access the path to hook script at runtime (ie, in the HOOK script SAS code) using the `PGMLOC` macro variable.
|
||||||
|
|
||||||
!!! warning
|
!!! warning
|
||||||
Do not place your hook scripts inside the Data Controller (logical) application folder, as they may be inadvertently lost during a deployment (eg in the case of a backup-and-deploy-new-instance approach).
|
Do not place your hook scripts inside the Data Controller (logical) application folder, as they may be inadvertently lost during a deployment (eg in the case of a backup-and-deploy-new-instance approach).
|
||||||
@@ -23,20 +23,114 @@ It is possible to configure a number of other rules by updating the MPE_VALIDATI
|
|||||||
|
|
||||||
## Configurable Checks
|
## Configurable Checks
|
||||||
|
|
||||||
Check back frequently as we plan to keep growing this list of checks.
|
Check back frequently as we keep growing this list of checks. For how each rule treats a special missing value (`.A`-`.Z`, `._`), see [Special Missing Values](#special-missing-values).
|
||||||
|
|
||||||
|Rule Type|Example Value |Description|
|
|Rule Type|Example Value |Description|
|
||||||
|---|---|---|
|
|---|---|---|
|
||||||
|CASE|UPCASE|Will enforce the case of cell values. Valid values: UPCASE, LOWCASE, PROPCASE|
|
|CASE|UPCASE|Will enforce the case of cell values. Valid values: UPCASE, LOWCASE, PROPCASE|
|
||||||
|NOTNULL|(defaultval)|Will prevent submission if null values are present. Optional - provide a default value.|
|
|NOTNULL|(defaultval)|Will prevent submission if null values are present - a special missing counts as null. Optional - provide a default value.|
|
||||||
|MINVAL|1|Defines a minimum value for a numeric cell|
|
|MINVAL|1|Defines a minimum value for a numeric cell. A special missing value sorts below every number, so it fails a numeric floor, and the floor itself may be a special missing - see [Special Missing Values](#special-missing-values).|
|
||||||
|MAXVAL|1000000|Defines a maximum value for a numeric cell|
|
|MAXVAL|1000000|Defines a maximum value for a numeric cell. A special missing value sorts below every number, so it passes a numeric ceiling, and the ceiling itself may be a special missing - see [Special Missing Values](#special-missing-values).|
|
||||||
|
|READONLY|(defaultval) |Renders the column read-only in the editor. The defaultval is used when rows are added. |
|
||||||
|
|HIDDEN|(defaultval) |Hides the column from the editor grid while still submitting its data. The defaultval is used when rows are added. |
|
||||||
|
|ROUND|2 |Rounds numeric input on paste/edit. Positive digits round to number of decimal places (eg 2 rounds to 0.01) Negative digits round to the nearest ten/hundred etc. Half-away-from-zero rounding is applied so `-0.5 -> -1` and `2.5 -> 3`. |
|
||||||
|
|NUMBER_FORMAT|`{"style":"currency","currency":"GBP"}` |Display-only [`Intl.NumberFormat` renderer](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/NumberFormat). RULE_VALUE is the JSON options object passed straight to `Intl.NumberFormat`. Does not change the stored value. |
|
||||||
|
|HARDFORMULA|`= PRICE * VOLUME`|The cell displays a value computed from a formula, using other columns in the same row. The column is read-only - the user cannot override the result. See [Formula Rules](#formula-rules) below.|
|
||||||
|
|SOFTFORMULA|`= if( DC.ROW_STATUS != 'U', DC.USER_NAME, DC.ORIG_VALUE )`|Like HARDFORMULA, but the user can override the computed value and type their own. See [Formula Rules](#formula-rules) below.|
|
||||||
|
|HARDREGEX|`^[A-Z]{3}$`|The cell value **must** match the regex pattern, otherwise submission is blocked and the cell is highlighted red. See [Regex Rules](#regex-rules) below.|
|
||||||
|
|SOFTREGEX|`^[A-Z]{3}$`|A cell value that does not match the regex pattern is highlighted yellow as a warning, but submission is **not** blocked. See [Regex Rules](#regex-rules) below.|
|
||||||
|HARDSELECT|sashelp.class.name|A distinct list of values (max 1000) are taken from this library.member.column reference, and the value **must** be in this list. This list may be supplemented by entries in the MPE_SELECTBOX table.|
|
|HARDSELECT|sashelp.class.name|A distinct list of values (max 1000) are taken from this library.member.column reference, and the value **must** be in this list. This list may be supplemented by entries in the MPE_SELECTBOX table.|
|
||||||
|SOFTSELECT|dcdemo.mpe_tables.libref|A distinct list of values (max 1000) are taken from this library.member.column reference, and the user-provided value may (or may not) be in this list. This list may be supplemented by entries in the MPE_SELECTBOX table.|
|
|SOFTSELECT|dcdemo.mpe_tables.libref|A distinct list of values (max 1000) are taken from this library.member.column reference, and the user-provided value may (or may not) be in this list. This list may be supplemented by entries in the MPE_SELECTBOX table.|
|
||||||
|[HARDSELECT_HOOK](/dynamic-cell-dropdown)|/logical/folder/stpname|A SAS service (STP or Viya Job) or a path to a SAS program on the filesystem. User provided values **must** be in this list. Cannot be used alongside a SOFTSELECT_HOOK.|
|
|[HARDSELECT_HOOK](/dynamic-cell-dropdown)|/logical/folder/stpname|A SAS service (STP or Viya Job) or a path to a SAS program on the filesystem. User provided values **must** be in this list. Cannot be used alongside a SOFTSELECT_HOOK.|
|
||||||
|[SOFTSELECT_HOOK](/dynamic-cell-dropdown)|/physical/path/program.sas|A SAS service (STP or Viya Job) or a path to a SAS program on the filesystem. User-provided values may (or may not) be in this list. Cannot be used alongside a HARDSELECT_HOOK.|
|
|[SOFTSELECT_HOOK](/dynamic-cell-dropdown)|/physical/path/program.sas|A SAS service (STP or Viya Job) or a path to a SAS program on the filesystem. User-provided values may (or may not) be in this list. Cannot be used alongside a HARDSELECT_HOOK.|
|
||||||
|
|
||||||
|
|
||||||
|
## Special Missing Values
|
||||||
|
|
||||||
|
A SAS numeric variable has 28 missing values: the regular `.` and 27 special ones (`.A`-`.Z` and `._`). Data Controller accepts them in a numeric cell as a letter - `a` to `z` - or an underscore, with or without a leading period (`a`, `.a`, `_`, `._`), and stores the matching special missing in SAS. The period is optional, and a plain `.` stores the regular missing.
|
||||||
|
|
||||||
|
A numeric column that carries a date, datetime or time format is the exception. Those cells are edited through a date picker rather than the numeric editor, and the picker accepts only a date - so a special missing cannot be typed into one of them.
|
||||||
|
|
||||||
|
The rules treat a special missing as a value for some checks and as a missing value for others - and the range rules compare it in the order SAS gives it, below every number but ordered among the other missing values:
|
||||||
|
|
||||||
|
|Rule|What happens to a special missing|
|
||||||
|
|---|---|
|
||||||
|
|NOTNULL|Fails. A special missing is a missing value, so a NOT NULL (or primary key) constraint rejects it, and a real SAS NOT NULL constraint on the target table rejects it too.|
|
||||||
|
|MINVAL|Fails if the minimum is a number - a missing sorts below every number, so it is below any numeric floor. A minimum that is itself a special missing is compared in the order the missing values have among themselves, and can accept one.|
|
||||||
|
|MAXVAL|Passes - a missing sorts below every number, so it is below any numeric ceiling. A ceiling that is itself a special missing is compared in the missing values' own order, and can reject one.|
|
||||||
|
|CASE|Not applicable - it is a character rule.|
|
||||||
|
|ROUND|Ignored - ROUND only rounds values that are numbers, so a special missing is left as typed.|
|
||||||
|
|HARDREGEX / SOFTREGEX|Checked against the pattern like any other value. Unlike blanks and the plain `.`, special missings are **not** exempt. See [Regex Rules](#regex-rules).|
|
||||||
|
|SOFTSELECT|Supports special missings - a soft dropdown never blocks a value.|
|
||||||
|
|HARDSELECT|Supports special missings - the value is matched against the dropdown list like any other value.|
|
||||||
|
|HARDFORMULA / SOFTFORMULA|The formula returns `#VALUE!` for that row instead of a number, and that is what gets submitted.|
|
||||||
|
|
||||||
|
In short, a special missing is rejected by NOTNULL, by a primary key column, and by a MINVAL whose floor is a number; a formula returns `#VALUE!` for it. It is fine in a column that carries a MAXVAL, a regex, a dropdown, or ROUND - and it can satisfy a MINVAL when the floor is expressed as a special missing.
|
||||||
|
|
||||||
|
A range rule compares in the order SAS itself uses, so a range written in special missings means what SAS would mean by it. That order puts every missing below every non-missing value, and orders the missing values as `._`, then the regular missing, then `.A` through `.Z`. So `MINVAL .A` with `MAXVAL .C` accepts `.B` and rejects `.D`, and a blank - the regular missing - fails a floor of `.A` because it sorts below it. A number sorts above every missing, so it passes a floor of `.A` and fails a ceiling of `.C`.
|
||||||
|
|
||||||
|
A primary key column is treated as NOT NULL whether or not the target table carries a physical constraint, and whether or not MPE_VALIDATIONS has a NOTNULL rule for it - a key identifies the row, so a blank and a special missing are both rejected there.
|
||||||
|
|
||||||
|
A range rule's own value is read as a number when it looks like one and as a missing value when it is a special missing. A value that is neither - a typo such as `..` or `AB` - satisfies nothing, so every cell in the column fails until the rule is corrected.
|
||||||
|
|
||||||
|
## Formula Rules
|
||||||
|
|
||||||
|
HARDFORMULA and SOFTFORMULA let you configure a column so that its value is automatically calculated from other columns in the same row - just like a spreadsheet formula. When a user opens the editor, the formula is evaluated live and the result is shown in each cell.
|
||||||
|
|
||||||
|
### Writing a formula
|
||||||
|
|
||||||
|
Formulas use column names, not cell references, so there is no need to know the grid layout. For example, if you have PRICE and VOLUME columns, a REVENUE column formula would be:
|
||||||
|
|
||||||
|
```
|
||||||
|
= PRICE * VOLUME
|
||||||
|
```
|
||||||
|
|
||||||
|
Each row calculates its own result - the PRICE in row 1 is multiplied by the VOLUME in row 1, the PRICE in row 2 by the VOLUME in row 2, and so on.
|
||||||
|
|
||||||
|
!!! note
|
||||||
|
Each column name in the formula must be surrounded by spaces (eg ` PRICE ` not `PRICE`) so it is recognised as a column reference rather than part of a function name. For example, `=MATCH( PRICE )` resolves the column reference, but `=MATCH(PRICE)` does not - PRICE is left unrecognised and the formula will error rather than using the column's value. Text inside quotes is left as-is.
|
||||||
|
|
||||||
|
### HARDFORMULA vs SOFTFORMULA
|
||||||
|
|
||||||
|
* **HARDFORMULA** - the column is read-only. The formula result is always shown and submitted. The user cannot change it.
|
||||||
|
* **SOFTFORMULA** - the cell shows the formula result but the user can type a different value if needed. If they do, their value is submitted instead.
|
||||||
|
|
||||||
|
### Editor behaviour
|
||||||
|
|
||||||
|
* When you paste a formula into the grid, column names are automatically translated so the formula works in its new position.
|
||||||
|
* A cell that is overwritten by a formula is flagged so you can revert it.
|
||||||
|
* Formula-looking values pasted from Excel are treated as plain data (not evaluated), unless you explicitly choose "Apply as formula".
|
||||||
|
|
||||||
|
### Special values
|
||||||
|
|
||||||
|
Formulas can reference three special values that are resolved at runtime:
|
||||||
|
|
||||||
|
* `DC.ROW_STATUS` - the current state of the row: `M` (Modified), `A` (Added), `D` (Deleted), or `U` (Unchanged). A newly-added row is `A` from the moment it is created - there is no transient state before that.
|
||||||
|
* `DC.USER_NAME` - the logged-in user id.
|
||||||
|
* `DC.ORIG_VALUE` - the original cell value before the current edit.
|
||||||
|
|
||||||
|
Example - show the current user id if the row is changed, otherwise keep the original value:
|
||||||
|
|
||||||
|
```
|
||||||
|
= if( DC.ROW_STATUS != 'U', DC.USER_NAME, DC.ORIG_VALUE )
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
## Regex Rules
|
||||||
|
|
||||||
|
HARDREGEX and SOFTREGEX validate cell values against a SAS (Perl-style) regular expression provided in `RULE_VALUE` - the same syntax accepted by [PRXPARSE](https://documentation.sas.com/doc/en/pgmsascdc/9.4_3.5/lefunctionsref/p0s9ilagexmjl8n1u7e1t1jfnzlk.htm).
|
||||||
|
|
||||||
|
Things to be aware of:
|
||||||
|
|
||||||
|
* Patterns are validated with `PRXPARSE` when the rule is saved - a post-edit check on MPE_VALIDATIONS itself will reject invalid patterns and list the offending columns.
|
||||||
|
* The pattern is evaluated in the browser using the JavaScript regex engine, which shares the same core syntax (character classes, quantifiers, groups, alternation, `^`/`$` anchors, `\d \w \s` etc). Stick to that common subset: Perl-only constructs such as inline modifiers `(?i)`, `\A` / `\z` anchors, possessive quantifiers (`a++`) and atomic groups (`(?>...)`) will pass the SAS-side PRXPARSE check but fail (and be silently ignored) in the frontend.
|
||||||
|
* The pattern is used **as authored** - it is not auto-anchored. If you want to match the entire cell value, include `^` and `$` yourself (eg `^[A-Z]{3}$`).
|
||||||
|
* Blank values are exempt from pattern matching on any column type - use the NOTNULL rule if you also need to enforce populated values. On numeric columns the plain SAS missing (`.`) is also exempt. Special missings (`.A`-`.Z`, `._`) are **not** exempt - being deliberately-set values, they are validated against the pattern like any other value, so on numeric columns make sure your pattern accommodates them (or avoid special missings). On character columns there is no missing-value concept: even `.` is treated as real text.
|
||||||
|
* Only one regex rule is ever applied per column. If a column has both a HARDREGEX and a SOFTREGEX rule, the SOFTREGEX rule is ignored entirely - even for values that pass the HARDREGEX - so a dual-rule column behaves exactly like a HARDREGEX-only column. For the same reason, the column-header info dropdown shows only the rule that is applied (the HARDREGEX pattern when both exist).
|
||||||
|
* Cells in rows that are marked for deletion are not validated / warned (except primary key columns, which still validate).
|
||||||
|
* In the unlikely event a pattern that fails in the browser slips through (see above), the frontend treats it as always-valid (no blocking, no warning) rather than breaking the editor.
|
||||||
|
* `RULE_VALUE` is limited to 128 characters, which constrains very long patterns.
|
||||||
|
|
||||||
## Dropdowns
|
## Dropdowns
|
||||||
|
|
||||||
There are now actually FIVE places where you can configure dropdowns!
|
There are now actually FIVE places where you can configure dropdowns!
|
||||||
|
|||||||
@@ -14,6 +14,8 @@ There are two ways to deploy Data Controller on SAS 9:
|
|||||||
* Full Deployment (preferred)
|
* Full Deployment (preferred)
|
||||||
* Streaming (for quick demos)
|
* Streaming (for quick demos)
|
||||||
|
|
||||||
|
Both fetch a deployment program from the [releases page](https://git.datacontroller.io/dc/dc/releases) - see the [downloads page](/downloads) for what each asset contains and how to verify it.
|
||||||
|
|
||||||
### Full Deployment
|
### Full Deployment
|
||||||
|
|
||||||
#### 1 - Deploy Stored Processes
|
#### 1 - Deploy Stored Processes
|
||||||
@@ -27,27 +29,27 @@ filename dc url "https://git.datacontroller.io/dc/dc/releases/download/latest/sa
|
|||||||
%inc dc;
|
%inc dc;
|
||||||
```
|
```
|
||||||
|
|
||||||
If you don't have internet access from SAS, download `sas9.sas` from [here](https://git.datacontroller.io/dc/dc/releases), and change the initial `compiled_apploc` and `compiled_serverName` macro variable assignments as necessary.
|
If you don't have internet access from SAS, download `sas9.sas` from [here](https://git.datacontroller.io/dc/dc/releases), verify it against the release `SHA256SUMS` file ([downloads page](/downloads/#verifying-a-download)), and change the initial `compiled_apploc` and `compiled_serverName` macro variable assignments as necessary.
|
||||||
|
|
||||||
#### 2 - Deploy the Frontend
|
#### 2 - Deploy the Frontend
|
||||||
|
|
||||||
The Data Controller frontend comes pre-built, and ready to deploy to the root of the SAS Web Server (mid-tier).
|
The Data Controller frontend comes pre-built, and ready to deploy to the SAS Web Server (mid-tier).
|
||||||
|
|
||||||
Deploy as follows:
|
Deploy as follows:
|
||||||
|
|
||||||
1. Download the `frontend.zip` file from: [https://git.datacontroller.io/dc/dc/releases](https://git.datacontroller.io/dc/dc/releases)
|
1. Download the `frontend.zip` file from: [https://git.datacontroller.io/dc/dc/releases](https://git.datacontroller.io/dc/dc/releases) (verify it against the release `SHA256SUMS` file - see the [downloads page](/downloads/#verifying-a-download))
|
||||||
2. Unzip and place in the [htdocs folder of your SAS Web Server](https://sasjs.io/frontend-deployment/#sas9-deploy) - typically a subdirectory of: `!SASCONFIG/LevX/Web/WebServer/htdocs`.
|
2. Create a folder for Data Controller in the [htdocs folder of your SAS Web Server](https://sasjs.io/frontend-deployment/#sas9-deploy) - typically a subdirectory of: `!SASCONFIG/LevX/Web/WebServer/htdocs` - and unzip the archive **into** that folder. The archive holds the frontend files at its root, so `index.html` sits directly inside your folder (alongside the `images` folder and the compiled asset files) - for example `htdocs/dc/index.html`.
|
||||||
3. Open the `index.html` file and update the values in the `<sasjs>` tag as follows:
|
3. Open the `index.html` file and update the values in the `<sasjs>` tag as follows:
|
||||||
|
|
||||||
* `appLoc` - same as per SAS code in the section above
|
* `appLoc` - same as per SAS code in the section above
|
||||||
* `serverType` - change this to`SAS9`
|
* `serverType` - change this to`SAS9`
|
||||||
* `serverUrl` - Provide only if your SAS Mid Tier is on a different domain than the web server (protocol://SASMIDTIERSERVER:port)
|
* `serverUrl` - Provide only if your SAS Mid Tier is on a different domain than the web server (protocol://SASMIDTIERSERVER:port)
|
||||||
* `loginMechanism` - set to `Redirected` if using SSO or 2FA
|
* `loginMechanism` - set to `Redirected` if using SSO or 2FA
|
||||||
* `debug` - set to `true` to debug issues on startup (otherwise it's faster to leave it off and turn on in the application itself when needed)
|
* `debug` - set to `true` to debug issues on startup (otherwise it's faster to leave it off and turn on in the application itself when needed)
|
||||||
|
|
||||||
The remaining properties are not relevant for a SAS 9 deployment and can be **safely ignored**.
|
The remaining properties are not relevant for a SAS 9 deployment and can be **safely ignored**.
|
||||||
|
|
||||||
You can now open the app at `https://YOURWEBSERVER/unzippedfoldername` (step 2 above) and follow the configuration steps (DC Physical Location and Admin Group) to complete deployment.
|
You can now open the app at `https://YOURWEBSERVER/<yourfoldername>` (the folder created in step 2 above) and follow the configuration steps (DC Physical Location and Admin Group) to complete deployment.
|
||||||
|
|
||||||
#### 3 - Run the Configurator
|
#### 3 - Run the Configurator
|
||||||
|
|
||||||
@@ -93,7 +95,7 @@ filename dc url "https://git.datacontroller.io/dc/dc/releases/download/vX.X.X/de
|
|||||||
%inc dc;
|
%inc dc;
|
||||||
```
|
```
|
||||||
|
|
||||||
If you don't have internet access from your SAS environment, just download `demostream_sas9.sas` from [https://git.datacontroller.io/dc/dc/releases](https://git.datacontroller.io/dc/dc/releases) and modify the `appLoc` on line 2, as follows:
|
If you don't have internet access from SAS, download `demostream_sas9.sas` from [https://git.datacontroller.io/dc/dc/releases](https://git.datacontroller.io/dc/dc/releases) (verify it against the release `SHA256SUMS` file - see the [downloads page](/downloads/#verifying-a-download)) and modify the `appLoc` on line 2, as follows:
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
@@ -169,14 +171,15 @@ The full redeployment process is as follows:
|
|||||||
- To a new metadata folder
|
- To a new metadata folder
|
||||||
- To a new frontend folder (if full deploy)
|
- To a new frontend folder (if full deploy)
|
||||||
* _Delete_ the **new** DC library (metadata + physical tables)
|
* _Delete_ the **new** DC library (metadata + physical tables)
|
||||||
* _Move_ the **old** DC library (metadata only) to the new DC metadata folder
|
* _Move_ the **old** DC library (metadata only) to the new DC metadata folder. You will need to use DI Studio to do this (as you can't _move_ objects using SAS Management Console)
|
||||||
* Copy the _content_ of the old `services/public/Data_Controller_Settings` STP to the new one
|
* Copy the _content_ of the old `services/public/Data_Controller_Settings` STP to the new one
|
||||||
- This will link the new DC instance to the old DC library / logs directory
|
- This will link the new DC instance to the old DC library / logs directory
|
||||||
- It will also re-apply any site-specific DC mods
|
- It will also re-apply any site-specific DC mods
|
||||||
* Run any/all DB migrations between the old and new DC version
|
* Run any/all DB migrations between the old and new DC version
|
||||||
- See [migrations](https://git.datacontroller.io/dc/dc/src/branch/main/sas/sasjs/db/migrations) folder
|
- See [migrations](https://git.datacontroller.io/dc/dc/src/branch/main/sas/sasjs/db/migrations) folder
|
||||||
|
- Update the metadata of the SAS Library, using DI Studio, to capture the model changes
|
||||||
* Test and make sure the new instance works as expected
|
* Test and make sure the new instance works as expected
|
||||||
* Delete (or rename) the **old** instance
|
* Delete (or rename) the **old** instance
|
||||||
- Metadata + frontend, NOT the underlying DC library data
|
- Metadata + frontend, NOT the underlying DC library data
|
||||||
* Rename the new instance so it is the same as the old
|
* Rename the new instance so it is the same as the old
|
||||||
- Both frontend and metadata
|
- Both frontend and metadata
|
||||||
|
|||||||
@@ -1,185 +0,0 @@
|
|||||||
---
|
|
||||||
layout: article
|
|
||||||
title: DC SAS Viya Deployment
|
|
||||||
description: How to deploy Data Controller in a production SAS Viya environment
|
|
||||||
og_image: https://docs.datacontroller.io/img/dci_deploymentdiagramviya.png
|
|
||||||
---
|
|
||||||
|
|
||||||
# SAS Viya Deployment
|
|
||||||
|
|
||||||
## Overview
|
|
||||||
Data Controller for SAS Viya consists of a frontend, a set of Job Execution Services, a staging area, a Compute Context, and a database library. The library can be a SAS Base engine if desired, however this can cause contention (eg table locks) if end users are able to connect to the datasets directly, eg via Enterprise Guide or Base SAS.
|
|
||||||
A database that supports concurrent access is highly recommended.
|
|
||||||
|
|
||||||
## Prerequisites
|
|
||||||
|
|
||||||
### System Account
|
|
||||||
|
|
||||||
Data Controller makes use of a system account for performing backend data updates and writing to the staging area. This needs to be provisioned in advance using the Viya admin-cli. The process is well described here: [https://communities.sas.com/t5/SAS-Communities-Library/SAS-Viya-3-5-Compute-Server-Service-Accounts/ta-p/620992](https://communities.sas.com/t5/SAS-Communities-Library/SAS-Viya-3-5-Compute-Server-Service-Accounts/ta-p/620992)
|
|
||||||
|
|
||||||
### Database
|
|
||||||
Whilst we do recommend that Data Controller configuration tables are stored in a database for concurrency reasons, it is also possible to use a BASE engine library, which is adequate if you only have a few users.
|
|
||||||
|
|
||||||
To migrate the control library to a database, first perform a regular deployment, and afterwards you can generate the DDL and update the settings file..
|
|
||||||
|
|
||||||
Make sure the system account (see above) has full read / write access.
|
|
||||||
|
|
||||||
!!! note
|
|
||||||
"Modify schema" privileges are not required.
|
|
||||||
|
|
||||||
### Staging Directory
|
|
||||||
All deployments of Data Controller make use of a physical staging directory. This is used to store logs, as well as CSV and Excel files uploaded by end users. This directory should NOT be accessible by end users - only the SAS system account requires access to this directory.
|
|
||||||
A typical small deployment will grow by a 5-10 mb each month. A very large enterprise customer, with 100 or more editors, might generate up to 0.5 GB or so per month, depending on the size and frequency of the Excel EUCs and CSVs being uploaded. Web modifications are restricted only to modified rows, so are typically just a few kb in size.
|
|
||||||
|
|
||||||
## Deployment Diagram
|
|
||||||
|
|
||||||
The below areas of the SAS Viya platform are modified when deploying Data Controller:
|
|
||||||
|
|
||||||
<img src="/img/dci_deploymentdiagramviya.svg" height="350" style="border:3px solid black" >
|
|
||||||
|
|
||||||
|
|
||||||
## Deployment
|
|
||||||
Data Controller deployment is split between 3 deployment types:
|
|
||||||
|
|
||||||
* Demo version
|
|
||||||
* Full Version (manual deploy)
|
|
||||||
* Full Version (automated deploy)
|
|
||||||
|
|
||||||
<!--
|
|
||||||
## Full Version - Manual Deploy
|
|
||||||
-->
|
|
||||||
|
|
||||||
There are several parts to this proces:
|
|
||||||
|
|
||||||
1. Create the Compute Context
|
|
||||||
2. Deploy Frontend
|
|
||||||
4. Prepare the database and update settings (optional)
|
|
||||||
5. Update the Compute Context autoexec
|
|
||||||
|
|
||||||
|
|
||||||
### Create Compute Context
|
|
||||||
|
|
||||||
The Viya Compute context is used to spawn the Job Execution Services - such that those services may run under the specified system account, with a particular autoexec.
|
|
||||||
|
|
||||||
We strongly recommend a dedicated compute context for running Data Controller. The setup requires an Administrator account.
|
|
||||||
|
|
||||||
* Log onto SASEnvironment Manager, select Contexts, View Compute Contexts, and click the Create icon.
|
|
||||||
* In the New Compute Context dialog, enter the following attributes:
|
|
||||||
* Context Name
|
|
||||||
* Launcher Context
|
|
||||||
* Attribute pairs:
|
|
||||||
* reuseServerProcesses: true
|
|
||||||
* runServerAs: {{the account set up [earlier](#system-account)}}
|
|
||||||
* Save and exit
|
|
||||||
|
|
||||||
!!! note
|
|
||||||
XCMD is NOT required to use Data Controller.
|
|
||||||
### Deploy frontend
|
|
||||||
|
|
||||||
Unzip the frontend into your chosen directory (eg `/var/www/html/DataController`) on the SAS Web Server. Open `index.html` and update the following inside `dcAdapterSettings`:
|
|
||||||
|
|
||||||
- `appLoc` - this should point to the root folder on SAS Drive where you would like the Job Execution services to be created. This folder should initially, NOT exist (if it is found, the backend will not be deployed)
|
|
||||||
- `contextName` - here you should put the name of the compute context you created in the previous step.
|
|
||||||
- `dcPath` - the physical location on the filesystem to be used for staged data. This is only used at deployment time, it can be configured later in `$(appLoc)/services/settings.sas` or in the autoexec if used.
|
|
||||||
- `adminGroup` - the name of an existing group, which should have unrestricted access to Data Controller. This is only used at deployment time, it can be configured later in `$(appLoc)/services/settings.sas` or in the autoexec if used.
|
|
||||||
- `servertype` - should be SASVIYA
|
|
||||||
- `debug` - can stay as `false` for performance, but could be switched to `true` for debugging startup issues
|
|
||||||
- `useComputeApi` - use `true` for best performance.
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
Now, open https://YOURSERVER/DataController (using whichever subfolder you deployed to above) using an account that has the SAS privileges to write to the `appLoc` location.
|
|
||||||
|
|
||||||
You will be presented with a deployment screen like the one below. Be sure to check the "Recreate Database" option and then click the "Deploy" button.
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
Your services are deployed! And the app is operational, albeit still a little sluggish, as every single request is using the APIs to fetch the content of the `$(appLoc)/services/settings.sas` file.
|
|
||||||
|
|
||||||
To improve responsiveness by another 700ms we recommend you follow the steps in [Update Compute Context Autoexec](/dci-deploysasviya/#update-compute-context-autoexec) below.
|
|
||||||
|
|
||||||
### Deploy Database
|
|
||||||
If you have a lot of users, such that concurrency (locked datasets) becomes an issue, you might consider migrating the control library to a database.
|
|
||||||
|
|
||||||
The first part to this is generating the DDL (and inserts). For this, use the DDL exporter as described [here](/admin-services/#export-database). If you need a flavour of DDL that is not yet supported, [contact us](https://datacontroller.io/contact/).
|
|
||||||
|
|
||||||
Step 2 is simply to run this DDL in your preferred database.
|
|
||||||
|
|
||||||
Step 3 is to update the library definition in the `$(appLoc)/services/settings.sas` file using SAS Studio.
|
|
||||||
|
|
||||||
### Update Compute Context Autoexec
|
|
||||||
|
|
||||||
First, open the `$(appLoc)/services/settings.sas` file in SAS Studio, and copy the code.
|
|
||||||
|
|
||||||
Then, open SASEnvironment Manager, select Contexts, View Compute Contexts, and open the context we created earlier.
|
|
||||||
|
|
||||||
Switch to the Advanced tab and paste in the SAS code copied from SAS Studio above.
|
|
||||||
|
|
||||||
It will look similar to:
|
|
||||||
|
|
||||||
```
|
|
||||||
%let DC_LIBREF=DCDBVIYA;
|
|
||||||
%let DC_ADMIN_GROUP={{YOUR DC ADMIN GROUP}};
|
|
||||||
%let DC_STAGING_AREA={{YOUR DEDICATED FILE SYSTEM DRIVE}};
|
|
||||||
libname &dc_libref {{YOUR DC DATABASE}};
|
|
||||||
```
|
|
||||||
|
|
||||||
To explain each of these lines:
|
|
||||||
|
|
||||||
* `DC_LIBREF` can be any valid 8 character libref.
|
|
||||||
* `DC_ADMIN_GROUP` is the name of the group which will have unrestricted access to Data Controller
|
|
||||||
* `DC_STAGING_AREA` should point to the location on the filesystem where the staging files and logs are be stored
|
|
||||||
* The final libname statement can also be configured to point at a database instead of a BASE engine directory (contact us for DDL)
|
|
||||||
|
|
||||||
If you have additional libraries that you would like to use in Data Controller, they should also be defined here.
|
|
||||||
<!--
|
|
||||||
## Full Version - Automated Deploy
|
|
||||||
|
|
||||||
The automated deploy makes use of the SASjs CLI to create the dependent context and job execution services. In addition to the standard prerequisites (a registered viya system account and a prepared database) you will also need:
|
|
||||||
|
|
||||||
* a local copy of the [SASjs CLI](https://sasjs.io/sasjs-cli/#installation)
|
|
||||||
* a Client / Secret - with an administrator group in SCOPE, and an authorization_code GRANT_TYPE. The SASjs [Viya Token Generator](https://github.com/sasjs/viyatoken) may help with this.
|
|
||||||
|
|
||||||
### Prepare the Target and Token
|
|
||||||
|
|
||||||
To configure this part (one time, manual step), we need to run a single command:
|
|
||||||
```
|
|
||||||
sasjs add
|
|
||||||
```
|
|
||||||
A sequence of command line prompts will follow for defining the target. These prompts are described [here](https://sasjs.io/sasjs-cli-add/). Note that `appLoc` is the SAS Drive location in which the Data Controller jobs will be deployed.
|
|
||||||
|
|
||||||
### Prepare the Context JSON
|
|
||||||
This file describes the context that the CI/CD process will generate. Save this file, eg as `myContext.json`.
|
|
||||||
|
|
||||||
```
|
|
||||||
{
|
|
||||||
"name": "DataControllerContext",
|
|
||||||
"attributes": {
|
|
||||||
"reuseServerProcesses": true,
|
|
||||||
"runServerAs": "mycasaccount"
|
|
||||||
},
|
|
||||||
"environment": {
|
|
||||||
"autoExecLines": [
|
|
||||||
"%let DC_LIBREF=DCDBVIYA;",
|
|
||||||
"%let DC_ADMIN_GROUP={{YOUR DC ADMIN GROUP}};",
|
|
||||||
"%let DC_STAGING_AREA={{YOUR DEDICATED FILE SYSTEM DRIVE}};",
|
|
||||||
"libname &dc_libref {{YOUR DC DATABASE}};",
|
|
||||||
],
|
|
||||||
"options": []
|
|
||||||
},
|
|
||||||
"launchContext": {
|
|
||||||
"contextName": "SAS Job Execution launcher context"
|
|
||||||
},
|
|
||||||
"launchType": "service",
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### Prepare Deployment Script
|
|
||||||
|
|
||||||
The deployment script will run on a build server (or local desktop) and execute as follows:
|
|
||||||
|
|
||||||
```
|
|
||||||
# Create the SAS Viya Target
|
|
||||||
sasjs context create --source myContext.json --target myTarget
|
|
||||||
```
|
|
||||||
-->
|
|
||||||
@@ -10,6 +10,16 @@ og_image: https://docs.datacontroller.io/img/cannotimport.png
|
|||||||
## Overview
|
## Overview
|
||||||
[Let us know](https://datacontroller.io/contact/) if you experience an installation problem that is not described here!
|
[Let us know](https://datacontroller.io/contact/) if you experience an installation problem that is not described here!
|
||||||
|
|
||||||
|
## max number of active processes has been reached for the user
|
||||||
|
|
||||||
|
On Viya versions 2025 or later you may get the following message in the network response:
|
||||||
|
|
||||||
|
`Unable to create compute server session. Unable to complete the launch request, max number of active processes has been reached for the user: user=USERNAME limit=10`
|
||||||
|
|
||||||
|
This limit should be set to at least 20 or 30 due to the way the [sasjs/adapter](https://github.com/sasjs/adapter) works (by prelaunching sessions to improve responsiveness).
|
||||||
|
|
||||||
|
A guide for making the configuration change is available [here](https://communities.sas.com/t5/SAS-Communities-Library/Limit-a-user-s-simultaneous-compute-server-processes-in-SAS-Viya/ta-p/761820).
|
||||||
|
|
||||||
## Internet Explorer - blank screen
|
## Internet Explorer - blank screen
|
||||||
If you have an older, or 'locked down' version of Internet Explorer you may get a blank / white screen when navigating to the Data Controller url. To fix this, click settings (cog icon in top right), *Compatibility View settings*, and **uncheck** *Display intranet sites in Compatibility view* as follows:
|
If you have an older, or 'locked down' version of Internet Explorer you may get a blank / white screen when navigating to the Data Controller url. To fix this, click settings (cog icon in top right), *Compatibility View settings*, and **uncheck** *Display intranet sites in Compatibility view* as follows:
|
||||||

|

|
||||||
@@ -98,8 +108,131 @@ This can happen if you enter the wrong `serverName` when deploying the SAS progr
|
|||||||
|
|
||||||
The error may also be thrown due to an encoding issue - changing to a UTF-8 server has helped at least one customer.
|
The error may also be thrown due to an encoding issue - changing to a UTF-8 server has helped at least one customer.
|
||||||
|
|
||||||
|
## Displayed timestamps are in UTC (or the wrong timezone)
|
||||||
|
|
||||||
|
Data Controller records timestamps (such as the SUBMITTED column on the Submitted screen, and the audit history) using the SAS session clock, via the `datetime()` function. That function returns the time of the operating system, adjusted by the [TIMEZONE= system option](https://documentation.sas.com/doc/en/pgmsascdc/default/lesysoptsref/p15siqs0s00e50n1wuuvygzkr14r.htm) if it is set. The value is then displayed in the frontend exactly as stored, without conversion.
|
||||||
|
|
||||||
|
On Viya, the SAS compute sessions that run Data Controller jobs are started inside Kubernetes containers whose clock is UTC by default, and which inherit no timezone from the host machine. If the TIMEZONE= option is not set for the compute context used by Data Controller, every timestamp DC records and displays is UTC. Other SAS products can appear unaffected because clients such as SAS Studio create their own compute sessions and pass the browser timezone / locale, whereas Data Controller submits jobs to its own shared compute context, which gets the raw container clock.
|
||||||
|
|
||||||
|
To confirm the current state, run the following in a SAS session under the Data Controller compute context (or check the DC job log, where `_DEBUG` output shows the same values):
|
||||||
|
|
||||||
|
```sas
|
||||||
|
proc options option=timezone;
|
||||||
|
run;
|
||||||
|
%put &=SYSTIMEZONEIDENT &=SYSTIMEZONEOFFSET;
|
||||||
|
```
|
||||||
|
|
||||||
|
If TIMEZONE is blank (and SYSTIMEZONEOFFSET is 0), the session is on UTC. To fix it, ask your Viya administrator to set the timezone for the compute context used by Data Controller (in SAS Environment Manager, edit the context's Autoexec, or set the context's SAS options):
|
||||||
|
|
||||||
|
```sas
|
||||||
|
options timezone='Europe/Berlin';
|
||||||
|
```
|
||||||
|
|
||||||
|
Then recycle any existing compute sessions - hot sessions keep the old setting until they terminate.
|
||||||
|
|
||||||
|
!!! note
|
||||||
|
Use a region/area time zone ID such as `Europe/Berlin` rather than a fixed offset such as `GMT+2`. Fixed offsets do not follow daylight saving time, so the display would be 1 hour off in winter (CET = UTC+1).
|
||||||
|
|
||||||
|
!!! note
|
||||||
|
Changing the timezone affects new timestamps only. Previously recorded submissions keep the UTC values that were stored when they were created.
|
||||||
|
|
||||||
## Determining Application Version
|
## Determining Application Version
|
||||||
|
|
||||||
The app version is bundled into the frontend during the release, and is visible by clicking your username in the top right.
|
The app version is bundled into the frontend during the release, and is visible by clicking your username in the top right.
|
||||||
|
|
||||||
You can also determine the app version (and SASjs Version, and build time) by opening browser Development Tools and running `appinfo()` in the console.
|
You can also determine the app version (and SASjs Version, and build time) by opening browser Development Tools and running `appinfo()` in the console.
|
||||||
|
|
||||||
|
## Support Diagnostics
|
||||||
|
|
||||||
|
The frontend sends two input tables with the startup service and with the services that execute customer-provided code - the [hook scripts](macros.md) (pre/post edit and approve hooks) and the dynamic cell dropdown programs. They are available in those services as `work.browser_info` and `work.browser_url_vars`, so a support ticket can be diagnosed from the job log without asking the user follow-up questions, and a hook can adapt to its context. Other services do not receive them.
|
||||||
|
|
||||||
|
The services that receive the tables are: `public/startupservice`, `editors/getdata`, `editors/getdynamiccolvals`, `editors/stagedata`, `editors/loadfile`, `editors/restore` and `auditors/postdata`.
|
||||||
|
|
||||||
|
`editors/loadfile` is the exception in practice: the app reaches it through the adapter's file-upload call (multipart), which carries no input tables, so the service - and the post edit hook it runs - does not receive them in normal use. It is on the list for completeness, and would receive them if the service were ever invoked through the ordinary request path.
|
||||||
|
|
||||||
|
### browser_info
|
||||||
|
|
||||||
|
A single-row table with these columns:
|
||||||
|
|
||||||
|
| Column | Description |
|
||||||
|
|---|---|
|
||||||
|
| `url` | The URL of the Data Controller page itself (the iframe), not the document embedding it. When the editor is embedded in a report, the embedding URL is visible here. |
|
||||||
|
| `referrer` | The embedding document, from `document.referrer`. For an embedded report this is the report URL, so the embedding report can be told apart from the editor URL. |
|
||||||
|
| `timezone` | The browser's IANA timezone name, e.g. `Europe/Berlin`. |
|
||||||
|
| `tz_offset` | The browser's UTC offset in minutes, as `Date.getTimezoneOffset()` returns it (positive west of UTC, so `Europe/Berlin` in summer is -120). |
|
||||||
|
| `locale` | The browser locale, e.g. `en-GB`. |
|
||||||
|
| `dc_version` | The Data Controller build, as shown by `appinfo()`. |
|
||||||
|
| `adapter_version` | The `@sasjs/adapter` version the client was built with. |
|
||||||
|
| `browser` | The browser family, parsed from the user agent. |
|
||||||
|
| `browser_version` | The browser version. |
|
||||||
|
| `platform` | The operating system, parsed from the user agent. |
|
||||||
|
| `user_agent` | The raw `navigator.userAgent` string. |
|
||||||
|
|
||||||
|
### browser_url_vars
|
||||||
|
|
||||||
|
The page URL parameters as one row per parameter, so a SAS program can read a parameter by name rather than parse the `url` string:
|
||||||
|
|
||||||
|
| Column | Description |
|
||||||
|
|---|---|
|
||||||
|
| `name` | The URL parameter name. |
|
||||||
|
| `value` | The URL parameter value. |
|
||||||
|
|
||||||
|
Parameters from both the search string and the hash query string (Angular routes carry them after the `#`) are included; on a name collision the search string value wins. The table is sent only when the page URL has at least one parameter.
|
||||||
|
|
||||||
|
On SAS 9 and Viya the app is reached through the platform's own job URL, so the platform's parameters (`_FILE`, `_program`, `_debug`, `_webout` and friends) are in the table alongside DC's. Read a parameter by name rather than assuming every row belongs to Data Controller - `embed` and `labels` are DC's, `_FILE` and `_program` are the platform's.
|
||||||
|
|
||||||
|
The values in both tables are supplied by the client, so treat them as diagnostics hints rather than a security boundary.
|
||||||
|
|
||||||
|
To see the tables, run any of the services above with debug on. The debug value depends on the path: `&_debug=131` on the Compute API and SAS 9, or `&_debug=128` on the Viya web (JES) path with `runAsTask` enabled - which is what the frontend sends there, so turning debug on in the app is enough. Either value makes the session initialisation write the tables to the job log:
|
||||||
|
|
||||||
|
```
|
||||||
|
NOTE: MPEINIT: work.browser_url_vars:
|
||||||
|
name=embed value=va
|
||||||
|
NOTE: MPEINIT: work.browser_info:
|
||||||
|
url=... referrer=... timezone=Europe/Berlin tz_offset=-120 locale=en-GB
|
||||||
|
dc_version=7.15.0 adapter_version=4.19.0 browser=Chrome browser_version=120.0
|
||||||
|
platform=Linux user_agent=...
|
||||||
|
```
|
||||||
|
|
||||||
|
A service called directly (for instance from a URL, or by a script), or by an older frontend, has no `work.browser_info` - the log then records that fact instead.
|
||||||
|
|
||||||
|
### Reading the tables from a hook
|
||||||
|
|
||||||
|
A [hook script](macros.md) is `%include`d into the running service, so it shares the service's WORK library and can read the tables directly. Take an embedded editor opened at:
|
||||||
|
|
||||||
|
```
|
||||||
|
https://datacontroller.io/#/editor/SASHELP.CLASS?labels=true&embed=va
|
||||||
|
```
|
||||||
|
|
||||||
|
`browser_url_vars` then holds a row per parameter - `labels=true` and `embed=va` - so a hook can pick up either by name:
|
||||||
|
|
||||||
|
```sas
|
||||||
|
%let labels=N;
|
||||||
|
%let embed=N;
|
||||||
|
|
||||||
|
%if %sysfunc(exist(work.browser_url_vars)) %then %do;
|
||||||
|
proc sql noprint;
|
||||||
|
select value into :labels
|
||||||
|
from work.browser_url_vars
|
||||||
|
where name = 'labels';
|
||||||
|
select value into :embed
|
||||||
|
from work.browser_url_vars
|
||||||
|
where name = 'embed';
|
||||||
|
quit;
|
||||||
|
%end;
|
||||||
|
```
|
||||||
|
|
||||||
|
To branch on what the client reports:
|
||||||
|
|
||||||
|
```sas
|
||||||
|
%if %sysfunc(exist(work.browser_info)) %then %do;
|
||||||
|
data _null_;
|
||||||
|
set work.browser_info;
|
||||||
|
call symputx('dc_timezone', timezone);
|
||||||
|
call symputx('dc_locale', locale);
|
||||||
|
run;
|
||||||
|
%end;
|
||||||
|
```
|
||||||
|
|
||||||
|
!!! warning
|
||||||
|
Guard with `%sysfunc(exist())` before reading. A service called directly, or by a frontend older than this feature, has no `work.browser_info` at all, so an unguarded `set` or `select` fails the job.
|
||||||
@@ -1,7 +1,25 @@
|
|||||||
# Data Controller for SAS: Data Catalog
|
---
|
||||||
Data Controller collects information about the size and shape of the tables and columns. The Catalog does not contain information about the data content (values).
|
layout: article
|
||||||
|
title: DC Data Catalog
|
||||||
|
description: Catalog the Libraries, Tables, Columns, SAS Catalogs, and associated Objects in your SAS estate
|
||||||
|
og_title: DC Data Catalog Documentation
|
||||||
|
og_image: /img/catalog.png
|
||||||
|
---
|
||||||
|
|
||||||
The catalog is based primarily on the existing SAS dictionary tables, augmented with attributes such as primary key fields, filesize / libsize, and number of observations (eg for database tables).
|
# DC Data Catalog
|
||||||
|
|
||||||
|
In any SAS estate, it's unlikely the size & shape of data will remain static. By running a regular Catalog Scan, you can track changes such as:
|
||||||
|
|
||||||
|
- Library Properties (size, schema, path, number of tables)
|
||||||
|
- Table Properties (size, number of columns, primary keys)
|
||||||
|
- Variable Properties (presence in a primary key, constraints, position in the dataset)
|
||||||
|
- SAS Catalog Properties (number of entries, created / modified datetimes)
|
||||||
|
- SAS Catalog Object properties (entry name, type, description, created / modified datetimes)
|
||||||
|
|
||||||
|
The data is stored with SCD2 so you can actually **track changes to your model over time**! Curious when that new column appeared? Just check the history in [MPE_DATACATALOG_TABS](/tables/mpe_datacatalog_tabs).
|
||||||
|
|
||||||
|
|
||||||
|
The Catalog does **not** contain information about the data content (values). It is based primarily on the existing SAS dictionary tables, augmented with attributes such as primary key fields, filesize / libsize, and number of observations (eg for database tables).
|
||||||
|
|
||||||
Frequently changing data (such as nobs, size) are stored on the MPE_DATASTATUS_XXX tables. The rest is stored on the MPE_DATACATALOG_XXX tables.
|
Frequently changing data (such as nobs, size) are stored on the MPE_DATASTATUS_XXX tables. The rest is stored on the MPE_DATACATALOG_XXX tables.
|
||||||
|
|
||||||
@@ -20,14 +38,60 @@ Table attributes are split between those that change infrequently (eg PK_FIELDS)
|
|||||||
|
|
||||||
Variable attributes come from dictionary tables with an extra PK indicator. A PK is identified by the fact the variable is within an index that is both UNIQUE and NOTNULL. Variable names are always uppercase.
|
Variable attributes come from dictionary tables with an extra PK indicator. A PK is identified by the fact the variable is within an index that is both UNIQUE and NOTNULL. Variable names are always uppercase.
|
||||||
|
|
||||||
|
### Catalogs & Objects
|
||||||
|
|
||||||
|
This info comes from the dictionary.catalogs table. The catalog created / modified time is considered to be the earliest created time / latest modified time of the underlying objects.
|
||||||
|
|
||||||
## Assumptions
|
## Assumptions
|
||||||
|
|
||||||
The following assumptions are made:
|
The following assumptions are made:
|
||||||
|
|
||||||
* Data _Models_ (eg attributes) are not sensitive. If so the catalog tables should be disabled.
|
* Data _Models_ (eg attributes) are not sensitive. If so the catalog tables should be disabled.
|
||||||
* Users can see all tables in the libraries they can access. The refresh process will close out any tables that are not found, if the user can see at least one table in a library.
|
* Users can see all tables in the libraries they can access. The refresh process will close out any tables that are not found, if the user can see at least one table in a library.
|
||||||
* For a particular site, libraries are unique on LIBREF.
|
* For a particular site, libraries are unique on LIBREF.
|
||||||
|
|
||||||
If you have duplicate librefs, specific table security setups, or sensitive models - contact us.
|
If you have duplicate librefs, specific table security setups, or sensitive models - contact us.
|
||||||
|
|
||||||
|
|
||||||
|
## Refreshing the Data Catalog
|
||||||
|
|
||||||
|
The update process for INDIVIDUAL libraries can be run by any user, and is performed in the VIEW menu by expanding a library definition and clicking the refresh icon next to the library name.
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
Members of the admin group may run the refresh process for ALL libraries by clicking the REFRESH button on the System page.
|
||||||
|
|
||||||
|
Under the hood, the refresh is executed by three SAS macros:
|
||||||
|
|
||||||
|
- `mpe_refreshlibs` - library attributes (engine, paths, permissions, owners, schemas, metadata name / id) into [MPE_DATACATALOG_LIBS](/tables/mpe_datacatalog_libs)
|
||||||
|
- `mpe_refreshtables` - table and column attributes (including primary key detection from constraints and unique not-null indexes) into the DATACATALOG_TABS / VARS tables, and sizes / row counts into the DATASTATUS tables
|
||||||
|
- `mpe_refreshcatalogs` - SAS Catalog and object attributes
|
||||||
|
|
||||||
|
These run inside the `refreshlibinfo` service (single library, any user) and the `refreshlibs` / `refreshcatalog` services (all libraries, admins only).
|
||||||
|
|
||||||
|
When doing a full scan, the following LIBREFS are ignored:
|
||||||
|
|
||||||
|
* 'CASUSER'
|
||||||
|
* 'MAPSGFK'
|
||||||
|
* 'SASUSER'
|
||||||
|
* 'SASWORK
|
||||||
|
* 'STPSAMP'
|
||||||
|
* 'TEMP'
|
||||||
|
* `WORK'
|
||||||
|
|
||||||
|
Additional LIBREFs can be excluded by adding them to the `DCXXXX.MPE_CONFIG` table (where `var_scope='DC_CATALOG' and var_name='DC_IGNORELIBS'`). Use a pipe (`|`) symbol to seperate them. This can be useful where there are connection issues for a particular library.
|
||||||
|
|
||||||
|
Be aware that the scan process can take a long time if you have a lot of tables!
|
||||||
|
|
||||||
|
|
||||||
|
Output tables (all SCD2):
|
||||||
|
|
||||||
|
* [MPE_DATACATALOG_CATS](/tables/mpe_datacatalog_cats) - SAS Catalog list
|
||||||
|
* [MPE_DATACATALOG_LIBS](/tables/mpe_datacatalog_libs) - Library attributes
|
||||||
|
* [MPE_DATACATALOG_OBJS](/tables/mpe_datacatalog_objs) - SAS Catalog object attributes
|
||||||
|
* [MPE_DATACATALOG_TABS](/tables/mpe_datacatalog_tabs) - Table attributes
|
||||||
|
* [MPE_DATACATALOG_VARS](/tables/mpe_datacatalog_vars) - Column attributes
|
||||||
|
* [MPE_DATASTATUS_CATS](/tables/mpe_datastatus_cats) - Frequently changing catalog attributes (such as created / modified datetimes and number of entries)
|
||||||
|
* [MPE_DATASTATUS_LIBS](/tables/mpe_datastatus_libs) - Frequently changing library attributes (such as size & number of tables)
|
||||||
|
* [MPE_DATASTATUS_OBJS](/tables/mpe_datastatus_objs) - Frequently changing catalog object attributes (such as created / modified datetimes and library concatenation level)
|
||||||
|
* [MPE_DATASTATUS_TABS](/tables/mpe_datastatus_tabs) - Frequently changing table attributes (such as size & number of rows)
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
# Data Controller for SAS: Viewer
|
# Data Controller for SAS: Viewer
|
||||||
|
|
||||||
The viewer screen provides a raw view of the underlying table.
|
The viewer screen provides a raw view of the underlying table.
|
||||||
Choose a library, then a table, and click view to see the first 5000 rows.
|
Choose a library, then a table, and click view to see the first 500 rows.
|
||||||
A filter option is provided should you wish to view a different section of rows.
|
A filter option is provided should you wish to view a different section of rows.
|
||||||
|
|
||||||
The following libraries will be visible:
|
The following libraries will be visible:
|
||||||
@@ -16,6 +16,18 @@ Row and Column level security can also be applied in VIEW mode, as can additiona
|
|||||||
|
|
||||||
A single search box can be used to make a full table search on any character or numeric value, using this [macro](https://core.sasjs.io/mp__searchdata_8sas.html).
|
A single search box can be used to make a full table search on any character or numeric value, using this [macro](https://core.sasjs.io/mp__searchdata_8sas.html).
|
||||||
|
|
||||||
|
The search covers **every** column of the table at once, so you do not need to know which column holds the value you are looking for:
|
||||||
|
|
||||||
|
- **Character search** (the default) is a case sensitive CONTAINS match against every character column, so `Smith` finds `Smithson` and `smith` finds `Goldsmith`, but `smith` will not find `Smithson`.
|
||||||
|
- **Numeric search** (tick the Numeric box) is an exact match against every numeric column, so `42` will not find `420` or `4210`.
|
||||||
|
- If a filter is applied, the search runs within the filtered rows rather than the whole table.
|
||||||
|
- The grid is capped by the [`DC_MAXOBS_WEBVIEW`](/dcc-options/#dc_maxobs_webview) option (500 rows by default).
|
||||||
|
- For a search, the cap applies to the row count as well: a search that matches more rows than the cap returns 500 of them, and the count shown next to the table name is the number of rows returned, not the total number of matches.
|
||||||
|
- Without a search, the count shown next to the table name is the full number of rows in the filtered view, so it can be higher than the number of rows displayed - a table of 1,200 rows reports `1,200 rows` above a grid holding the first 500.
|
||||||
|
- A search that matches nothing shows a "No data found with given conditions" panel rather than an empty grid.
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
<iframe width="560" height="315" src="https://www.youtube.com/embed/i27w-xq85WQ" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
|
<iframe width="560" height="315" src="https://www.youtube.com/embed/i27w-xq85WQ" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
|
||||||
|
|
||||||
## Options
|
## Options
|
||||||
@@ -37,6 +49,8 @@ The Download button gives several options for obtaining the current view of data
|
|||||||
|
|
||||||
Note - if the table is registered in Data Controller as being TXTEMPORAL (SCD2) then the download option will prefilter for the _current_ records and removes the valid from / valid to variables. This makes the CSV suitable for DC file upload, if desired.
|
Note - if the table is registered in Data Controller as being TXTEMPORAL (SCD2) then the download option will prefilter for the _current_ records and removes the valid from / valid to variables. This makes the CSV suitable for DC file upload, if desired.
|
||||||
|
|
||||||
|
Note that all the above items are exported from backend. There is also a _frontend_ context menu that can be used in the VIEW screen (right click menu) for quick export into CSV or Excel formats.
|
||||||
|
|
||||||
### Web Query URL
|
### Web Query URL
|
||||||
|
|
||||||
This option gives you a URL that can be used to import data directly into third party tools such as Power BI or Microsoft Excel (as a "web query"). You can set up a filter, eg for a particular month, and refresh the query on demand using client tooling such as VBA.
|
This option gives you a URL that can be used to import data directly into third party tools such as Power BI or Microsoft Excel (as a "web query"). You can set up a filter, eg for a particular month, and refresh the query on demand using client tooling such as VBA.
|
||||||
@@ -0,0 +1,178 @@
|
|||||||
|
---
|
||||||
|
layout: article
|
||||||
|
title: DC SAS Viya Deployment
|
||||||
|
description: How to deploy Data Controller in a production SAS Viya environment
|
||||||
|
og_image: https://docs.datacontroller.io/img/dci_deploymentdiagramviya.png
|
||||||
|
---
|
||||||
|
|
||||||
|
# SAS Viya Deployment
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
Data Controller for SAS Viya consists of a static web frontend, a set of Viya Jobs, a staging area (physical directory), a Compute Context, and a Library.
|
||||||
|
|
||||||
|
## Prerequisites
|
||||||
|
|
||||||
|
### System Account
|
||||||
|
|
||||||
|
Data Controller makes use of a system account for performing backend data updates and writing to the staging area. This needs to be provisioned in advance using the Viya admin-cli. The process is well described here: [https://communities.sas.com/t5/SAS-Communities-Library/SAS-Viya-3-5-Compute-Server-Service-Accounts/ta-p/620992](https://communities.sas.com/t5/SAS-Communities-Library/SAS-Viya-3-5-Compute-Server-Service-Accounts/ta-p/620992)
|
||||||
|
|
||||||
|
### Library
|
||||||
|
Currently, all of our customers are using the standard BASE engine library for the control tables. However it is possible to use a database instead. To migrate the control library to a database, first perform a regular deployment, and afterwards you can generate the DDL. For this, use the DDL exporter as described [here](/admin-services/#export-database). If you need a flavour of DDL that is not yet supported, [contact us](https://datacontroller.io/contact/).
|
||||||
|
|
||||||
|
Make sure the system account (see above) has full read / write access.
|
||||||
|
|
||||||
|
!!! note
|
||||||
|
"Modify schema" privileges are not required.
|
||||||
|
|
||||||
|
### Staging Directory
|
||||||
|
All deployments of Data Controller make use of a physical staging directory. This is used to store logs, as well as CSV and Excel files uploaded by end users. This directory should NOT be accessible by end users - only the SAS system account requires access to this directory.
|
||||||
|
A typical small deployment will grow by a 5-10 mb each month. A very large enterprise customer, with 100 or more editors, might generate up to 0.5 GB or so per month, depending on the size and frequency of the Excel EUCs and CSVs being uploaded. Web modifications are restricted only to modified rows, so are typically just a few kb in size.
|
||||||
|
|
||||||
|
## Deployment Diagram
|
||||||
|
|
||||||
|
The below areas of the SAS Viya platform are modified when deploying Data Controller:
|
||||||
|
|
||||||
|
<img src="/img/dci_deploymentdiagramviya.svg" height="350" style="border:3px solid black" >
|
||||||
|
|
||||||
|
!!! note
|
||||||
|
The "streaming" version of Viya uses the files API for web content, so there is no need for the web server component.
|
||||||
|
|
||||||
|
|
||||||
|
## Deployment
|
||||||
|
Data Controller deployment is split between 2 deployment types:
|
||||||
|
|
||||||
|
* Streaming (web content served from SAS Drive)
|
||||||
|
* Separated (web content served from dedicated web server)
|
||||||
|
|
||||||
|
For most customers, the streaming approach is preferred, as it makes the deployment much simpler.
|
||||||
|
|
||||||
|
|
||||||
|
There are several parts to this proces:
|
||||||
|
|
||||||
|
1. Create the Compute Context
|
||||||
|
2. Deploy Services
|
||||||
|
3. Configure Frontend
|
||||||
|
4. First Launch
|
||||||
|
5. Optmisation
|
||||||
|
|
||||||
|
|
||||||
|
### Create Shared Compute Context
|
||||||
|
|
||||||
|
We strongly recommend a dedicated compute context for running Data Controller. The setup requires an Administrator account.
|
||||||
|
|
||||||
|
* Log onto SASEnvironment Manager, select Contexts, View Compute Contexts, and click the Create icon.
|
||||||
|
* In the New Compute Context dialog, enter the following attributes:
|
||||||
|
* Context Name
|
||||||
|
* Launcher Context
|
||||||
|
* Attribute pairs:
|
||||||
|
* reuseServerProcesses: true
|
||||||
|
* runServerAs: {{the account set up [earlier](#system-account)}}
|
||||||
|
* Save and exit
|
||||||
|
|
||||||
|
!!! note
|
||||||
|
XCMD is NOT required to use Data Controller.
|
||||||
|
|
||||||
|
A group should be defined in Environment Manager that has the "create session" permission on this context.
|
||||||
|
|
||||||
|
To avoid giving users the ability to run code on that context (and shared system account) in SAS Studio and other apps, this permission should have the following condition attached: `clientId() == 'sas.jobExecution'`
|
||||||
|
|
||||||
|
### Deploy Services
|
||||||
|
|
||||||
|
Services are deployed by running a SAS program.
|
||||||
|
|
||||||
|
**Streaming Deploy (BACKEND + FRONTEND):**
|
||||||
|
|
||||||
|
Run the following in SAS Studio:
|
||||||
|
|
||||||
|
```sas
|
||||||
|
%let apploc=/Public/DataController; /* desired SAS Drive location */
|
||||||
|
filename dc url "https://git.datacontroller.io/dc/dc/releases/download/latest/viya.sas";
|
||||||
|
%inc dc;
|
||||||
|
```
|
||||||
|
|
||||||
|
**Separated Deploy (BACKEND ONLY):**
|
||||||
|
|
||||||
|
Run the following in SAS Studio:
|
||||||
|
|
||||||
|
```sas
|
||||||
|
%let apploc=/Public/DataController; /* desired SAS Drive location */
|
||||||
|
filename dc url "https://git.datacontroller.io/dc/dc/releases/download/latest/viya_noweb.sas";
|
||||||
|
%inc dc;
|
||||||
|
```
|
||||||
|
|
||||||
|
### Configure Frontend
|
||||||
|
|
||||||
|
**Streaming Deploy:**
|
||||||
|
|
||||||
|
At the end of the SAS log from Step 2, there will be a link (`YOURSAS.SERVER/SASJobExecution?_file=/YOUR/APPLOC/services/DC.html`). Open this in **SASJobExecution** (not SAS Studio) to perform the configuration (below).
|
||||||
|
|
||||||
|
**Separated Deploy:**
|
||||||
|
|
||||||
|
Unzip the frontend into your chosen directory (eg `/var/www/html/DataController`) on the SAS Web Server. Edit `index.html` to perform the configuration (below).
|
||||||
|
|
||||||
|
**index.html**
|
||||||
|
|
||||||
|
The following attributes may be updated in the index.html file. For streaming deploy, be sure to use the JobExecution app (not SAS Studio) for correct file type handling.
|
||||||
|
|
||||||
|
- `appLoc` - the root folder where the Jobs were deployed in step 2
|
||||||
|
- `contextName` - here you should put the name of the compute context you created in step 1
|
||||||
|
- `servertype` - should be SASVIYA
|
||||||
|
- `debug` - can stay as `false` for performance, but could be switched to `true` for debugging startup issues
|
||||||
|
- `useComputeApi` - Setting `true` will give the best performance due to the use of [hot sessions](https://github.com/sasjs/adapter#using-the-compute-api) created client-side by the SASjs adapter. This is great for demo purposes, or when running a single user DC instance, however for typical enterprise use we recommend `false` or `null` so that the compute context usage can be restricted as described [above](/deploy-viya/#create-shared-compute-context)
|
||||||
|
- `runAsTask` - setting `true` will trigger jobs as Viya Compute Tasks. Be sure to increase the default expiry to 30 seconds (it is 5 by default) and set `useComputeApi` to `null`. For scaling options, see [SAS docs](https://documentation.sas.com/doc/en/sasadmincdc/v_074/calsrvpgm/p059rp0q82tvpzn1hk9x26486do5.htm#p1ktrn1coq0rx1n1ux8bjqh8jx4h).
|
||||||
|
|
||||||
|
|
||||||
|
### First Launch
|
||||||
|
|
||||||
|
Now the services are deployed (including the service which creates the staging area) we can open the Data Controller web interface and make the necessary configurations:
|
||||||
|
|
||||||
|
* dcpath - physical path for deployment (will contain SAS datasets and a subfolder for staged content)
|
||||||
|
* Admin Group - the members of this group will have full access to Data Controller
|
||||||
|
* Compute Context - the context configured in Step 1
|
||||||
|
|
||||||
|
### Optimisation
|
||||||
|
|
||||||
|
At this point, every DC request will read the `services/public/settings.sas` file to get the DC library (and other) settings. To avoid these API calls (which will speed up the app) we can simply move this code to the autoexec. Steps as follows:
|
||||||
|
|
||||||
|
First, open the `$(appLoc)/services/settings.sas` file in SAS Studio, and copy the code.
|
||||||
|
|
||||||
|
Then, open SASEnvironment Manager, select Contexts, View Compute Contexts, and open the context we created earlier.
|
||||||
|
|
||||||
|
Switch to the Advanced tab and paste in the SAS code copied from SAS Studio above.
|
||||||
|
|
||||||
|
It will look similar to:
|
||||||
|
|
||||||
|
```
|
||||||
|
%let DC_LIBREF=DCDBVIYA;
|
||||||
|
%let DC_ADMIN_GROUP={{YOUR DC ADMIN GROUP}};
|
||||||
|
%let DC_STAGING_AREA={{YOUR DEDICATED FILE SYSTEM DRIVE}};
|
||||||
|
libname &dc_libref {{YOUR DC DATABASE}};
|
||||||
|
```
|
||||||
|
|
||||||
|
To explain each of these lines:
|
||||||
|
|
||||||
|
* `DC_LIBREF` can be any valid 8 character libref.
|
||||||
|
* `DC_ADMIN_GROUP` is the name of the group which will have unrestricted access to Data Controller
|
||||||
|
* `DC_STAGING_AREA` should point to the location on the filesystem where the staging files and logs are be stored
|
||||||
|
* The final libname statement can also be configured to point at a database instead of a BASE engine directory (contact us for DDL)
|
||||||
|
|
||||||
|
If you have additional libraries that you would like to use in Data Controller, they should also be defined here.
|
||||||
|
|
||||||
|
## Redeployment
|
||||||
|
|
||||||
|
To update DC, just deploy it as a fresh instance, then move the new config across, as follows:
|
||||||
|
|
||||||
|
1. Do a full deploy to a completely new location
|
||||||
|
2. Copy the contents of the old `$(appLoc)/services/settings.sas` file to the new SAS Folder location
|
||||||
|
3. Delete the new physical directory (just created) as it is now replaced with the old one (per step 2)
|
||||||
|
4. Either delete or rename the old SAS Folder location (appLoc), and rename the new SAS Folder location to equal the old one
|
||||||
|
5. If using a dedicated web frontend, backup/rename so that the new web server location matches the old one
|
||||||
|
6. Run any migrations relevant to the release, as defined [here](https://git.datacontroller.io/dc/dc/src/branch/main/sas/sasjs/db/migrations)
|
||||||
|
|
||||||
|
## Visual Analytics
|
||||||
|
|
||||||
|
It is possible to embed a Data Controller table within SAS Visual Analytics by simply pasting the URL.
|
||||||
|
|
||||||
|
To make the portlet more visually appealing, the Data Controller title bar can be removed by adding `?embed=true` to the URL. When opening in a new window, the title bar will be gone.
|
||||||
|
|
||||||
|
For a deeper VA integration - where report row selections drive filters and column visibility in the Data Controller editor - append `?embed=va` instead. See the [SAS Visual Analytics Embed](/embed-va/) page for details on filter modes, configuration, and debugging.
|
||||||
@@ -0,0 +1,52 @@
|
|||||||
|
---
|
||||||
|
layout: article
|
||||||
|
title: DC Downloads
|
||||||
|
description: Data Controller release assets and how to verify them
|
||||||
|
---
|
||||||
|
|
||||||
|
# Downloads
|
||||||
|
|
||||||
|
Data Controller releases are published on the [releases page](https://git.datacontroller.io/dc/dc/releases) of the source repository. Every release carries the same set of assets:
|
||||||
|
|
||||||
|
| Asset | Use |
|
||||||
|
|---|---|
|
||||||
|
| `frontend.zip` | The pre-built web frontend, for deployments that serve the frontend from a web server (SAS 9 full deploy, Viya separated deploy) |
|
||||||
|
| `sas9.sas` | SAS 9 full deployment program (stored processes + frontend registration) |
|
||||||
|
| `demostream_sas9.sas` | SAS 9 streaming deployment program (demos and evaluations) |
|
||||||
|
| `viya.sas` | Viya streaming deployment program (backend + frontend) |
|
||||||
|
| `viya_noweb.sas` | Viya separated deployment program (backend only) |
|
||||||
|
| `viya_noweb.json` | The Viya backend services as a SASjs Drive JSON deployment bundle |
|
||||||
|
| `sasjs_server.json.zip` | SASjs Server deployment bundle (all services, for [SASjs Server](https://server.sasjs.io) deployments) |
|
||||||
|
| `SHA256SUMS` | SHA-256 checksums for every asset above |
|
||||||
|
|
||||||
|
Which asset you need depends on the deployment route - see [SAS 9 Deployment](/dci-deploysas9) or [SAS Viya Deployment](/deploy-viya).
|
||||||
|
|
||||||
|
## Verifying a download
|
||||||
|
|
||||||
|
Every asset is covered by the `SHA256SUMS` file, which the release pipeline generates over the exact files it uploads. To verify a download:
|
||||||
|
|
||||||
|
1. Download the asset (for example `frontend.zip`) from the [releases page](https://git.datacontroller.io/dc/dc/releases).
|
||||||
|
2. Download `SHA256SUMS` from the same release into the same folder.
|
||||||
|
3. Run the check:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sha256sum --check SHA256SUMS --ignore-missing
|
||||||
|
```
|
||||||
|
|
||||||
|
Each asset that matches reports `OK`. The `--ignore-missing` flag means you only need the files you actually downloaded - the check skips assets you did not fetch.
|
||||||
|
|
||||||
|
On Windows, `certutil` can compute the hash of a single file for comparison against the value listed in `SHA256SUMS`:
|
||||||
|
|
||||||
|
```
|
||||||
|
certutil -hashfile frontend.zip SHA256
|
||||||
|
```
|
||||||
|
|
||||||
|
### What the checksum proves
|
||||||
|
|
||||||
|
A matching checksum confirms the asset is byte-for-byte the file the release pipeline uploaded. It catches corrupted and tampered downloads - interrupted transfers, proxies or mirrors that altered the file in transit.
|
||||||
|
|
||||||
|
It is not a cryptographic signature. The hashes travel in the same release as the files they cover, so they protect the download path, not the release itself: a compromise of the forge would allow both the asset and its checksum to be altered together. For download integrity - the typical concern when fetching deployment artifacts over the internet - it is the standard check.
|
||||||
|
|
||||||
|
## Integrity inside SAS
|
||||||
|
|
||||||
|
The SAS deployment programs embed the frontend and services as generated SAS code. Once `%inc`'d, their integrity is established by the check above at download time. They deploy the stored processes or jobs into the SAS Folder you nominate (`appLoc`) - a metadata location, not physical disk - and the only physical location they write to is the Data Controller location (`dcLoc`) you configure. The programs can be [reviewed in full](https://code.datacontroller.io) (or in the [source repository](https://git.datacontroller.io/dc/dc)) before you run them.
|
||||||
@@ -49,15 +49,14 @@ The following tables should be created in the WORK library as outputs:
|
|||||||
This output table can contain up to three columns:
|
This output table can contain up to three columns:
|
||||||
|
|
||||||
* `display_index` (optional, mandatory if using `dynamic_extended_values`). Is a numeric key used to join the two tables.
|
* `display_index` (optional, mandatory if using `dynamic_extended_values`). Is a numeric key used to join the two tables.
|
||||||
* `display_value` - always character
|
|
||||||
* `raw_value` - unformatted character or numeric according to source data type
|
* `raw_value` - unformatted character or numeric according to source data type
|
||||||
|
|
||||||
Example values:
|
Example values:
|
||||||
|
|
||||||
|DISPLAY_INDEX:best.|DISPLAY_VALUE:$|RAW_VALUE|
|
|DISPLAY_INDEX:best.|RAW_VALUE|
|
||||||
|---|---|---|
|
|---|---|
|
||||||
|1|$77.43|77.43|
|
|1|77.43|
|
||||||
|2|$88.43|88.43|
|
|2|88.43|
|
||||||
|
|
||||||
### `WORK.DYNAMIC_EXTENDED_VALUES`
|
### `WORK.DYNAMIC_EXTENDED_VALUES`
|
||||||
This output table is optional. If provided, it will map the DISPLAY_INDEX from the DYNAMIC_VALUES table to additional column/value pairs, that will be used to populate dropdowns for _other_ cells in the _same_ row.
|
This output table is optional. If provided, it will map the DISPLAY_INDEX from the DYNAMIC_VALUES table to additional column/value pairs, that will be used to populate dropdowns for _other_ cells in the _same_ row.
|
||||||
@@ -66,7 +65,6 @@ The following columns should be provided:
|
|||||||
|
|
||||||
* `display_index` - a numeric key joining each value to the `dynamic_values` table
|
* `display_index` - a numeric key joining each value to the `dynamic_values` table
|
||||||
* `extra_col_name` - the name of the additional variable(s) to contain the extra dropdown(s)
|
* `extra_col_name` - the name of the additional variable(s) to contain the extra dropdown(s)
|
||||||
* `display_value` - the value to display in the dropdown. Always character.
|
|
||||||
* `display_type` - Either C or N depending on the raw value type
|
* `display_type` - Either C or N depending on the raw value type
|
||||||
* `raw_value_num` - The unformatted value if numeric
|
* `raw_value_num` - The unformatted value if numeric
|
||||||
* `raw_value_char` - The unformatted value if character
|
* `raw_value_char` - The unformatted value if character
|
||||||
@@ -74,17 +72,17 @@ The following columns should be provided:
|
|||||||
|
|
||||||
Example Values:
|
Example Values:
|
||||||
|
|
||||||
|DISPLAY_INDEX:best.|EXTRA_COL_NAME:$32|DISPLAY_VALUE:$|DISPLAY_TYPE:$1.|RAW_VALUE_NUM|RAW_VALUE_CHAR:$5000|FORCED_VALUE|
|
|DISPLAY_INDEX:best.|EXTRA_COL_NAME:$32|DISPLAY_TYPE:$1.|RAW_VALUE_NUM|RAW_VALUE_CHAR:$5000|FORCED_VALUE|
|
||||||
|---|---|---|---|---|---|---|
|
|---|---|---|---|---|---|
|
||||||
|1|DISCOUNT_RT|"50%"|N|0.5||.|
|
|1|DISCOUNT_RT|N|0.5||.|
|
||||||
|1|DISCOUNT_RT|"40%"|N|0.4||0|
|
|1|DISCOUNT_RT|N|0.4||0|
|
||||||
|1|DISCOUNT_RT|"30%"|N|0.3||1|
|
|1|DISCOUNT_RT|N|0.3||1|
|
||||||
|1|CURRENCY_SYMBOL|"GBP"|C||"GBP"|.|
|
|1|CURRENCY_SYMBOL|C||"GBP"|.|
|
||||||
|1|CURRENCY_SYMBOL|"RSD"|C||"RSD"|.|
|
|1|CURRENCY_SYMBOL|C||"RSD"|.|
|
||||||
|2|DISCOUNT_RT|"50%"|N|0.5||.|
|
|2|DISCOUNT_RT|N|0.5||.|
|
||||||
|2|DISCOUNT_RT|"40%"|N|0.4||1|
|
|2|DISCOUNT_RT|N|0.4||1|
|
||||||
|2|CURRENCY_SYMBOL|"EUR"|C||"EUR"|.|
|
|2|CURRENCY_SYMBOL|C||"EUR"|.|
|
||||||
|2|CURRENCY_SYMBOL|"HKD"|C||"HKD"|1|
|
|2|CURRENCY_SYMBOL|C||"HKD"|1|
|
||||||
|
|
||||||
|
|
||||||
### Code Examples
|
### Code Examples
|
||||||
@@ -107,9 +105,9 @@ Simple dropdown
|
|||||||
Output should be a single table called
|
Output should be a single table called
|
||||||
"work.dynamic_values" in the format below.
|
"work.dynamic_values" in the format below.
|
||||||
|
|
||||||
|DISPLAY_VALUE:$|RAW_VALUE:??|
|
|RAW_VALUE:??|
|
||||||
|---|---|
|
|---|
|
||||||
|$44.00|44|
|
|44|
|
||||||
|
|
||||||
**/
|
**/
|
||||||
|
|
||||||
@@ -133,37 +131,33 @@ create table work.source as
|
|||||||
where tx_to > "%sysfunc(datetime(),E8601DT26.6)"dt
|
where tx_to > "%sysfunc(datetime(),E8601DT26.6)"dt
|
||||||
order by 1,2;
|
order by 1,2;
|
||||||
|
|
||||||
data work.DYNAMIC_VALUES (keep=display_index raw_value display_value);
|
data work.DYNAMIC_VALUES (keep=display_index raw_value);
|
||||||
set work.source end=last;
|
set work.source end=last;
|
||||||
by libref;
|
by libref;
|
||||||
if last.libref then do;
|
if last.libref then do;
|
||||||
display_index+1;
|
display_index+1;
|
||||||
raw_value=libref;
|
raw_value=libref;
|
||||||
display_value=libref;
|
|
||||||
output;
|
output;
|
||||||
end;
|
end;
|
||||||
if last then do;
|
if last then do;
|
||||||
display_index+1;
|
display_index+1;
|
||||||
raw_value='*ALL*';
|
raw_value='*ALL*';
|
||||||
display_value='*ALL*';
|
|
||||||
output;
|
output;
|
||||||
end;
|
end;
|
||||||
run;
|
run;
|
||||||
|
|
||||||
data work.dynamic_extended_values(keep=display_index extra_col_name display_type
|
data work.dynamic_extended_values(keep=display_index extra_col_name display_type
|
||||||
display_value RAW_VALUE_CHAR raw_value_num forced_value);
|
RAW_VALUE_CHAR raw_value_num forced_value);
|
||||||
set work.source end=last;
|
set work.source end=last;
|
||||||
by libref dsn;
|
by libref dsn;
|
||||||
retain extra_col_name 'ALERT_DS';
|
retain extra_col_name 'ALERT_DS';
|
||||||
retain display_type 'C';
|
retain display_type 'C';
|
||||||
retain raw_value_num .;
|
retain raw_value_num .;
|
||||||
raw_value_char=dsn;
|
raw_value_char=dsn;
|
||||||
display_value=dsn;
|
|
||||||
forced_value=0;
|
forced_value=0;
|
||||||
|
|
||||||
if first.libref then display_index+1;
|
if first.libref then display_index+1;
|
||||||
if last.libref then do;
|
if last.libref then do;
|
||||||
display_value='*ALL*';
|
|
||||||
raw_value_char='*ALL*';
|
raw_value_char='*ALL*';
|
||||||
forced_value=1;
|
forced_value=1;
|
||||||
output;
|
output;
|
||||||
@@ -171,7 +165,6 @@ data work.dynamic_extended_values(keep=display_index extra_col_name display_type
|
|||||||
else output;
|
else output;
|
||||||
|
|
||||||
if last then do;
|
if last then do;
|
||||||
display_value='*ALL*';
|
|
||||||
raw_value_char='*ALL*';
|
raw_value_char='*ALL*';
|
||||||
forced_value=1;
|
forced_value=1;
|
||||||
output;
|
output;
|
||||||
|
|||||||
@@ -1,5 +1,13 @@
|
|||||||
Data Controller for SAS® - Emails
|
---
|
||||||
====================
|
layout: article
|
||||||
|
title: Data Controller Emails
|
||||||
|
description: Set up email alerts in Data Controller
|
||||||
|
og_title: Data Controller for SAS® emails
|
||||||
|
og_image: /img/mpe_config_dc_email.png
|
||||||
|
---
|
||||||
|
|
||||||
|
# Data Controller for SAS® - Emails
|
||||||
|
|
||||||
|
|
||||||
## Overview
|
## Overview
|
||||||
Data Controller enables email alerts for users when tables are:
|
Data Controller enables email alerts for users when tables are:
|
||||||
@@ -21,7 +29,7 @@ To switch it on, navigate to `DCXXXXXX.MPE_CONFIG` and set the value for `DC_EMA
|
|||||||

|

|
||||||
|
|
||||||
!!! tip
|
!!! tip
|
||||||
If your Stored Process session does not have the email options configured, then the appropriate options statement must be invoked. These options may need to be done at startup, or in the configuration file. See [documentation](https://documentation.sas.com/?cdcId=pgmsascdc&cdcVersion=9.4_3.4&docsetId=lrcon&docsetTarget=n05iwqtqxzvtvun1eyw11nrd9i9r.htm&locale=en)
|
If your SAS 9 Stored Process or Viya Compute session does not have the email options configured, then the appropriate options statement must be invoked. These options may need to be done at startup, or in the configuration file. See [documentation](https://documentation.sas.com/?cdcId=pgmsascdc&cdcVersion=9.4_3.4&docsetId=lrcon&docsetTarget=n05iwqtqxzvtvun1eyw11nrd9i9r.htm&locale=en)
|
||||||
|
|
||||||
## Configuration
|
## Configuration
|
||||||
The `DCXXXXXX.MPE_ALERTS` table must be updated with the following attributes:
|
The `DCXXXXXX.MPE_ALERTS` table must be updated with the following attributes:
|
||||||
@@ -31,4 +39,10 @@ The `DCXXXXXX.MPE_ALERTS` table must be updated with the following attributes:
|
|||||||
* ALERT_DS - either `*ALL*` or the dataset name to be alerted on
|
* ALERT_DS - either `*ALL*` or the dataset name to be alerted on
|
||||||
* ALERT_USER - the metadata name (not displayname) of the user to be alerted
|
* ALERT_USER - the metadata name (not displayname) of the user to be alerted
|
||||||
|
|
||||||
If your site does not put emails in metadata, then the user emails must instead be entered in `DCXXXXXX.MPE_EMAILS`.
|
If your site does not put emails in metadata (or have them available in the Viya identities service), then the user emails must instead be entered in `DCXXXXXX.MPE_EMAILS`.
|
||||||
|
|
||||||
|
## Templates
|
||||||
|
|
||||||
|
The wording of the emails can be easily modified by updating the template in the [MPE_CONFIG](/tables/mpe_config) table.
|
||||||
|
|
||||||
|
More information can be found in the [options configuration](https://docs.datacontroller.io/dcc-options/#dc_email-scope) page.
|
||||||
@@ -0,0 +1,60 @@
|
|||||||
|
---
|
||||||
|
layout: article
|
||||||
|
title: SAS Visual Analytics Embed
|
||||||
|
description: Embed the Data Controller editor inside a SAS VA report as a data-driven content object. Row selections in the VA report drive filters and column visibility in the editor.
|
||||||
|
---
|
||||||
|
|
||||||
|
# Embedding inside SAS Visual Analytics
|
||||||
|
|
||||||
|
Data Controller can be embedded inside a SAS Visual Analytics report as a **data-driven content** (DDC) object. This unlocks scenarios where a user can safely modify the values in an underlying SAS table, and have the visualisation updated- all from inside the same report.
|
||||||
|
|
||||||
|
## URL
|
||||||
|
|
||||||
|
Open the editor as a DDC by appending `?embed=va` to the editor route:
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
`https://yourserver/DC/#/editor/<library>/<table>?embed=va`
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
The `?embed=` parameter accepts three values:
|
||||||
|
|
||||||
|
| Value | Behaviour |
|
||||||
|
|---|---|
|
||||||
|
| `true` | Chrome (header, back button, sub-nav) is hidden. Editor functions normally. |
|
||||||
|
| `va` | Same chrome-hiding as `true`, **plus** editor becomes "VA-aware" - any report filters are captured, and columns can be displayed / hidden using the Edit Report interface. Filter button is disabled (use VA filters instead)|
|
||||||
|
| `false` (or omitted) | Standard interactive UI. |
|
||||||
|
|
||||||
|
## How VA drives the editor
|
||||||
|
|
||||||
|
VA pushes a JSON payload to the iframe via `window.postMessage` whenever the selected rows change. Data Controller listens for these messages and:
|
||||||
|
|
||||||
|
1. Resolves each VA `parameter` to a DC column by matching on column label.
|
||||||
|
2. Builds a filter (using existing [Filter](/filter/) machinery) over the selected values.
|
||||||
|
3. Hides any VA columns marked as `brush` so the grid stays focused on the user-editable columns (except primary key cols which are always shown)
|
||||||
|
|
||||||
|
If VA sends an empty / unmatched message the editor falls back to the unfiltered view but stays in VA mode.
|
||||||
|
|
||||||
|
More logic available in [`va-messaging.service.ts'](https://git.datacontroller.io/dc/dc/src/branch/main/client/src/app/services/va-messaging.service.ts).
|
||||||
|
|
||||||
|
## Filter Modes
|
||||||
|
|
||||||
|
When running in `embed=va` mode, the editor provides two filter modes, controlled by the **Auto-apply** checkbox:
|
||||||
|
|
||||||
|
* **Live (default)** - the editor updates automatically as you select rows in the VA report, so the data you see always matches your current selection.
|
||||||
|
* **Confirm** - filter changes are held until you click the **Apply** button. This is useful when editing, where an automatic reload would discard unsaved changes.
|
||||||
|
|
||||||
|
A status indicator shows whether a filter change is pending, loading, or idle. In edit mode, a pending filter is held until you leave edit mode, so your unsaved edits are never lost.
|
||||||
|
|
||||||
|
## Configuration in VA
|
||||||
|
|
||||||
|
In the VA Report Designer, add a **Data-Driven Content** object and set the URL to the editor route shown above. Be sure that any report level filters have their corresponding parameters added to the DDC object itself.
|
||||||
|
|
||||||
|
## Debugging
|
||||||
|
|
||||||
|
The following snippet can be used in console to dump the values being provided to DC from VA:
|
||||||
|
|
||||||
|
```
|
||||||
|
console.log(JSON.stringify(window.__vaLastMessage?.data, null, 2))
|
||||||
|
```
|
||||||
@@ -7,7 +7,7 @@ og_image: https://docs.datacontroller.io/img/filter_dynamic_on.png
|
|||||||
|
|
||||||
# Filtering
|
# Filtering
|
||||||
|
|
||||||
Data Controller for SAS® enables you to create complex table filters. The "dynamic" setting enables the dropdown values to be pre-filtered by previous filter clauses. Filtered views are shareable!
|
Data Controller for SAS® enables you to create complex table filters. The "dynamic" setting enables the dropdown values to be pre-filtered by previous filter clauses. Filtered views are shareable! They are also used when [embedded in VA.](/embed-va)
|
||||||
|
|
||||||
## Shared Filters
|
## Shared Filters
|
||||||
|
|
||||||
|
|||||||
|
After Width: | Height: | Size: 150 KiB |
|
Before Width: | Height: | Size: 43 KiB After Width: | Height: | Size: 46 KiB |
|
After Width: | Height: | Size: 138 KiB |
|
After Width: | Height: | Size: 56 KiB |
|
After Width: | Height: | Size: 126 KiB |
|
After Width: | Height: | Size: 178 KiB |
|
After Width: | Height: | Size: 181 KiB |
|
After Width: | Height: | Size: 195 KiB |
@@ -0,0 +1,15 @@
|
|||||||
|
<svg width="70" height="70" viewBox="0 0 70 70" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<g clip-path="url(#clip0_101_8)">
|
||||||
|
<path d="M37.5993 16.6212C38.5916 16.7415 39.5538 16.8317 40.5461 16.9519C42.9216 17.2827 45.237 17.7337 47.402 18.8463C48.0334 19.1771 48.6348 19.5379 49.0859 20.1092C49.8075 20.9512 49.7774 21.8533 49.0558 22.6952C48.304 23.5371 47.3418 24.0183 46.3195 24.4092C43.944 25.3413 41.4482 25.7623 38.9224 25.9728C34.8029 26.3035 30.7435 26.1532 26.7142 25.191C25.3911 24.8903 24.0981 24.4693 22.9254 23.8078C22.4744 23.5672 22.0534 23.2665 21.6625 22.9057C20.58 21.8533 20.58 20.7407 21.6926 19.7484C22.8954 18.6659 24.3688 18.1547 25.8722 17.7337C27.9771 17.1324 30.112 16.8317 32.277 16.6813C32.4575 16.6813 32.6679 16.7415 32.8183 16.5911C34.3819 16.6212 36.0056 16.6212 37.5993 16.6212Z" fill="#E0E0E0"/>
|
||||||
|
<path d="M20.8507 41.3082C22.7751 43.7738 25.5115 44.6759 28.338 45.2773C33.9309 46.4801 39.5238 46.3297 44.9663 44.4053C46.6502 43.8039 48.2138 42.992 49.3264 41.4886C49.5068 41.248 49.597 41.3683 49.6872 41.5487C49.8677 41.9396 49.9579 42.3305 49.9579 42.7515C49.9579 44.2249 49.9579 45.7284 49.9579 47.2018C49.9579 48.164 49.5068 48.9157 48.8453 49.5772C47.4621 50.9604 45.7181 51.7122 43.8838 52.2835C40.1853 53.4261 36.3966 53.6667 32.5777 53.3961C29.7212 53.1856 26.9548 52.6443 24.3387 51.4716C23.2261 50.9604 22.2038 50.3591 21.3919 49.4269C20.7605 48.7052 20.4297 47.8934 20.4297 46.9311C20.4598 45.578 20.4297 44.2249 20.4297 42.8718C20.4297 42.3305 20.5199 41.8193 20.8507 41.3082Z" fill="#8EC63F"/>
|
||||||
|
<path d="M20.8807 32.0167C22.4744 34.1516 24.6996 35.0537 27.075 35.6852C32.7582 37.1886 38.4413 37.1586 44.0643 35.4747C45.9286 34.9334 47.6726 34.1216 49.0258 32.6482C49.2062 32.4677 49.3265 32.0468 49.5369 32.1069C49.8376 32.1971 49.8376 32.6181 49.9278 32.9488C50.0481 33.46 49.988 33.9712 49.988 34.4824C49.988 35.5047 49.9579 36.497 49.988 37.5194C50.0481 38.7823 49.5369 39.7746 48.6048 40.5865C47.1915 41.8494 45.4776 42.6011 43.6433 43.0822C37.4791 44.7361 31.3449 44.706 25.3009 42.6011C23.8275 42.09 22.4744 41.3683 21.3919 40.1956C20.7304 39.4739 20.3997 38.632 20.3997 37.6397C20.4297 36.3166 20.3997 34.9635 20.3997 33.6404C20.4297 33.0992 20.5199 32.5579 20.8807 32.0167Z" fill="#E0E0E0"/>
|
||||||
|
<path d="M20.8207 23.0861C21.2717 24.4091 22.3542 25.0105 23.4969 25.5517C25.5416 26.514 27.7366 26.965 29.9317 27.2357C34.2918 27.7769 38.6519 27.7168 42.9518 26.8147C44.6958 26.4539 46.3797 25.9727 47.9132 25.0105C48.7853 24.4693 49.2363 23.9581 49.537 23.1161C49.8377 23.5371 49.9279 23.9882 49.9279 24.4392C49.9279 25.9427 49.958 27.4161 49.9279 28.9195C49.8978 30.1825 49.1762 31.0845 48.244 31.8363C46.5 33.2195 44.4553 33.9411 42.3203 34.4223C36.6673 35.6551 31.0744 35.5649 25.5717 33.7006C24.1283 33.2195 22.7451 32.5279 21.6326 31.4454C20.7906 30.6335 20.3396 29.7014 20.3696 28.4986C20.3997 27.2056 20.3696 25.9126 20.3696 24.6196C20.4298 24.0483 20.52 23.5672 20.8207 23.0861Z" fill="#8EC63F"/>
|
||||||
|
<path d="M55.3403 63.4393C60.2417 63.7099 62.8577 57.696 59.3095 54.2981C55.5809 50.7199 49.4467 54.0576 50.409 59.1093C28.2478 73.2419 -0.258034 52.1031 7.86071 26.4238L2.38808 22.7553C-9.91033 55.4408 27.9471 83.0746 55.3403 63.4393ZM53.7767 56.3729C56.062 53.9974 59.7004 57.3051 57.5655 59.8009C55.3103 62.4169 51.3411 58.8988 53.7767 56.3729Z" fill="#E0E0E0"/>
|
||||||
|
<path d="M10.6272 15.2681C14.1453 18.6358 19.9487 15.8694 19.6179 11.0583C41.749 -3.19461 70.4052 17.9142 62.2865 43.6836L67.7591 47.3521C79.6967 15.5988 43.463 -12.9972 15.4383 6.21715C10.1761 5.13465 6.77827 11.5695 10.6272 15.2681ZM16.1599 13.1933C13.8145 15.6289 10.116 12.0807 12.4614 9.64507C14.8068 7.20944 18.5054 10.7576 16.1599 13.1933Z" fill="#8EC63F"/>
|
||||||
|
</g>
|
||||||
|
<defs>
|
||||||
|
<clipPath id="clip0_101_8">
|
||||||
|
<rect width="70" height="70" fill="white"/>
|
||||||
|
</clipPath>
|
||||||
|
</defs>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 3.7 KiB |
|
After Width: | Height: | Size: 157 KiB |
|
After Width: | Height: | Size: 131 KiB |
|
After Width: | Height: | Size: 56 KiB |
|
After Width: | Height: | Size: 280 KiB |
|
After Width: | Height: | Size: 55 KiB |
|
Before Width: | Height: | Size: 98 KiB |
@@ -23,7 +23,7 @@ The following resources contain additional information on the Data Controller:
|
|||||||
- Data Controller flyer ([front](/marketing/flyer-front.pdf) / [back](/marketing/flyer-back.pdf))
|
- Data Controller flyer ([front](/marketing/flyer-front.pdf) / [back](/marketing/flyer-back.pdf))
|
||||||
- Data Controller [videos](/videos)
|
- Data Controller [videos](/videos)
|
||||||
- Data Controller [SAS Code](https://code.datacontroller.io)
|
- Data Controller [SAS Code](https://code.datacontroller.io)
|
||||||
- Data Controller [Download](https://4gl.uk/dcdeploy)
|
- Data Controller [Download](https://git.datacontroller.io/dc/dc/releases)
|
||||||
|
|
||||||
## Product Features
|
## Product Features
|
||||||
|
|
||||||
@@ -31,7 +31,7 @@ Data Controller is regularly updated with new features. If you see something th
|
|||||||
|
|
||||||
* [Excel uploads](/excel) - drag & drop directly into SAS. All versions of excel supported.
|
* [Excel uploads](/excel) - drag & drop directly into SAS. All versions of excel supported.
|
||||||
* Data Lineage - at both table and column level, export as image or CSV
|
* Data Lineage - at both table and column level, export as image or CSV
|
||||||
* Data Validation Rules - both automatic and user defined
|
* Data Validation Rules - both automatic and user defined, including [live formulas](/dcc-validations/#formula-rules)
|
||||||
* Data Dictionary - map data definitions and ownership
|
* Data Dictionary - map data definitions and ownership
|
||||||
* Data Catalog - including primary key extraction
|
* Data Catalog - including primary key extraction
|
||||||
* DDL generator - in SAS, TSQL and PGSQL flavours
|
* DDL generator - in SAS, TSQL and PGSQL flavours
|
||||||
@@ -42,7 +42,8 @@ Data Controller is regularly updated with new features. If you see something th
|
|||||||
* [Row Level Security](/row-level-security)
|
* [Row Level Security](/row-level-security)
|
||||||
* Excel [formula support](excel)
|
* Excel [formula support](excel)
|
||||||
* Dynamic [cell dropdown](/dynamic-cell-dropdown)
|
* Dynamic [cell dropdown](/dynamic-cell-dropdown)
|
||||||
* Works on ALL flavours of SAS (Foundation, EBI, Viya)
|
* [SAS Visual Analytics embed](/embed-va/) - drive the editor from VA report selections
|
||||||
|
* Works on ALL flavours of SAS (Base, EBI, Viya)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -26,6 +26,9 @@ Library definitions should be added in the `autoexec.sas` of the designated Comp
|
|||||||
|
|
||||||
If the above is not feasible, it is possible to insert code in the `[DC Drive Path]/services/settings.sas` file however - this will have a performance impact due to the additional API calls.
|
If the above is not feasible, it is possible to insert code in the `[DC Drive Path]/services/settings.sas` file however - this will have a performance impact due to the additional API calls.
|
||||||
|
|
||||||
|
!!! note
|
||||||
|
The CASUSER library must be assigned, as it is used to store temporary in-memory tables during CAS data updates.
|
||||||
|
|
||||||
## SAS 9 EBI Libraries
|
## SAS 9 EBI Libraries
|
||||||
|
|
||||||
In most cases, libname statements are NOT required so long as they are accessible in metadata.
|
In most cases, libname statements are NOT required so long as they are accessible in metadata.
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ Native pass through is also available for optimised data loads in the following
|
|||||||
* Microsoft SQL SERVER
|
* Microsoft SQL SERVER
|
||||||
* Amazon REDSHIFT
|
* Amazon REDSHIFT
|
||||||
* PostgreSQL
|
* PostgreSQL
|
||||||
|
* Snowflake
|
||||||
|
|
||||||
The macros work dynamically, taking data types / lengths etc from the table metadata at runtime. Data Controller macros are available for unlimited (internal) use by licenced customers. They are currently in use, in production, in dozens of SAS environments globally and have been battle tested on large data volumes as well as some more esoteric gotchas such as:
|
The macros work dynamically, taking data types / lengths etc from the table metadata at runtime. Data Controller macros are available for unlimited (internal) use by licenced customers. They are currently in use, in production, in dozens of SAS environments globally and have been battle tested on large data volumes as well as some more esoteric gotchas such as:
|
||||||
|
|
||||||
|
|||||||
@@ -7,26 +7,68 @@ og_image: https://docs.datacontroller.io/img/restore.png
|
|||||||
|
|
||||||
# Data Restore
|
# Data Restore
|
||||||
|
|
||||||
For those tables which have [Audit Tracking](/dcc-tables/#audit_libds) enabled, it is possible to restore the data to an earlier state!
|
For tables that have [Audit Tracking](/dcc-tables/#audit_libds) enabled, it is possible to restore the data to an earlier state.
|
||||||
|
|
||||||
Simply open the submit to be reverted (via HISTORY or the table INFO/VERSIONS screen), and click the red **REVERT** button. This will generate a NEW submission, containing the necessary reversal entries. This new submission **must then be approved** in the usual fashion.
|
## How to restore data
|
||||||
|
|
||||||
|
Open the submit to be reverted (via the **History** tab, or the **Info / Versions** screen on the table viewer), and click the red **REVERT** button.
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
This approach means that the audit history remains intact - there is simply a new entry, which reverts all the previous entries.
|
This will generate a **new submission** containing all the reversal entries needed to bring the table back to its previous state. This new submission **must then be approved** in the usual fashion - it goes through the same edit-stage-approve workflow as any other change.
|
||||||
|
|
||||||
## Caveats
|
This approach means that the audit history remains intact. There is simply a new entry in the audit trail which reverts all the previous entries.
|
||||||
|
|
||||||
Note that there are some caveats to this feature:
|
## How it works
|
||||||
|
|
||||||
- User must have EDIT permission
|
Behind the scenes, rollback is not a silent undo. It is a **first-class approval workflow** just like any other edit. When you choose to restore a previous version, the backend reads the audit table and computes every difference between the current state and the version you want to go back to.
|
||||||
- Table must have TXTEMPORAL or UPDATE Load Type
|
|
||||||
- Changes **outside** of Data Controller cannot be reversed
|
|
||||||
- If there are COLUMN or ROW level security rules, the restore will abort
|
|
||||||
- If the model has changed (new / deleted) columns the restore will abort
|
|
||||||
|
|
||||||
## Technical Information
|
The process is driven by the open-source [`%mp_stripdiffs`](https://core.sasjs.io/mp__stripdiffs_8sas.html) macro. It extracts all changes recorded in the audit table (the default is [`MPE_AUDIT`](/tables/mpe_audit/), or a custom table configured in `AUDIT_LIBDS`) from the selected version onwards, and left-joins them to the base table to build a staging dataset. Changes are then applied in **reverse chronological order**:
|
||||||
|
|
||||||
The restore works by undoing all the changes listed in the [MPE_AUDIT](/tables/mpe_audit/) table. The keys from this table (since and including the version to be restored) are left joined to the base table (to get current values) to create a staging dataset, and then the changes applied in reverse chronological order using [this macro](https://core.sasjs.io/mp__stripdiffs_8sas.html). This staging dataset is then submitted for approval, providing a final sense check before the new / reverted state is applied.
|
- **Deleted rows** are re-inserted with their original values.
|
||||||
|
- **Modified rows** are reverted to their previous values.
|
||||||
|
- **Added rows** are marked for deletion with the `_____DELETE__THIS__RECORD_____` flag.
|
||||||
|
|
||||||
Source code for the restore process is available [here](https://git.datacontroller.io/dc/dc/src/branch/main/sas/sasjs/services/editors/restore.sas).
|
The computed differences are written to a new staging package in the approvals directory, complete with a CSV and a `macvars.sas` snapshot of the session context. A new `LOAD_REF` is generated, and the package is submitted via the standard [`mpe_loader`](https://git.datacontroller.io/dc/dc/src/branch/main/sas/sasjs/macros/mpe_loader.sas) service. This means the rollback itself is **reviewable and approvable** - nothing is applied silently.
|
||||||
|
|
||||||
|
Because the rollback creates a new approved changeset rather than silently rewinding history, the full audit trail is maintained: the reversion appears as a new load reference in `MPE_SUBMIT`, `MPE_REVIEW`, `MPE_DATALOADS`, and `MPE_AUDIT`, just like any other submission.
|
||||||
|
|
||||||
|
## Security and access
|
||||||
|
|
||||||
|
Not everyone can restore everything. The [`mpe_checkrestore`](https://git.datacontroller.io/dc/dc/src/branch/main/sas/sasjs/macros/mpe_checkrestore.sas) macro enforces a strict access check before the restore service will run.
|
||||||
|
|
||||||
|
### Who can restore
|
||||||
|
|
||||||
|
- **Admins** - members of the admin group (configured in `MPE_CONFIG`) can restore any table that has audit tracking enabled.
|
||||||
|
- **Editors** - non-admin users must have `EDIT` access to the target table, and must **not** be subject to Column Level Security or Row Level Security restrictions.
|
||||||
|
|
||||||
|
### What is checked
|
||||||
|
|
||||||
|
1. **The load must exist in the audit table.** Loads that were never applied, or tables without an audit table configured, cannot be restored.
|
||||||
|
2. **The user must have `EDIT` access.** This is checked via `MPE_SECURITY`.
|
||||||
|
3. **CLS and RLS restrictions block non-admin users.** If the user belongs to a group with active Column Level Security (`MPE_COLUMN_LEVEL_SECURITY`) or Row Level Security (`MPE_ROW_LEVEL_SECURITY`) rules scoped to `EDIT` or `ALL`, restore is denied. Admins bypass this check.
|
||||||
|
|
||||||
|
!!! note
|
||||||
|
The presence of CLS or RLS rules on a table does **not** prevent the table itself from being restorable. It only prevents non-admin users who are subject to those restrictions from initiating the restore. After a successful restore, the same CLS and RLS filters continue to apply when users view or edit the data.
|
||||||
|
|
||||||
|
If access is denied, the service aborts immediately with a clear reason - no opaque errors.
|
||||||
|
|
||||||
|
## Limitations
|
||||||
|
|
||||||
|
!!! warning
|
||||||
|
Be aware of the following caveats before attempting a restore:
|
||||||
|
|
||||||
|
- **Audit table required.** The table must have `AUDIT_LIBDS` configured in `MPE_TABLES` (it defaults to `MPE_AUDIT`). Without this, there is no change history to roll back from.
|
||||||
|
- **Only Data Controller changes can be reversed.** Changes made directly to the target table outside of Data Controller are not tracked in the audit table and cannot be reverted.
|
||||||
|
- **Supported load types.** Restore is supported for `UPDATE` and `TXTEMPORAL` load types. `REPLACE` loads do not maintain row-level audit history and cannot be restored. `BITEMPORAL` loads maintain audit history but restore behaviour may be constrained by validity windows.
|
||||||
|
- **Model consistency.** If the table structure has changed since the version being restored (for example, columns were added or removed), the restore will abort because the audit diffs no longer match the current schema.
|
||||||
|
- **SCD2 validity windows.** For `TXTEMPORAL` tables, the restore works on the current snapshot only. Historical validity windows are respected by the underlying [`%mp_stripdiffs`](https://core.sasjs.io/mp__stripdiffs_8sas.html) macro, but ensure your approvers understand that the reversion applies to the current state of the data.
|
||||||
|
- **No partial restore.** Rolling back a version reverts **all** changes from that version onwards, not just selected records. There is no way to cherry-pick individual rows from a previous version.
|
||||||
|
|
||||||
|
## Technical background
|
||||||
|
|
||||||
|
The restore process is implemented in the [`restore.sas`](https://git.datacontroller.io/dc/dc/src/branch/main/sas/sasjs/services/editors/restore.sas) service. It delegates access control to [`mpe_checkrestore.sas`](https://git.datacontroller.io/dc/dc/src/branch/main/sas/sasjs/macros/mpe_checkrestore.sas), diff computation to [`%mp_stripdiffs`](https://core.sasjs.io/mp__stripdiffs_8sas.html), and approval workflow submission to [`%mpe_loader`](https://git.datacontroller.io/dc/dc/src/branch/main/sas/sasjs/macros/mpe_loader.sas).
|
||||||
|
|
||||||
|
Audit records are written by the open-source [`%mp_storediffs`](https://core.sasjs.io/mp__storediffs_8sas.html) macro during the normal approval workflow, which compares the pre-load snapshot with the applied changes and appends row-level entries to the audit table. This is why restore is only possible for tables that were loaded through Data Controller's tracked loaders.
|
||||||
|
|
||||||
|
For a lighter overview of this feature, see the [feed post on datacontroller.io](https://datacontroller.io/rollback-data-changes/).
|
||||||
@@ -21,10 +21,8 @@ When features are requested, we will describe the work to be performed in the se
|
|||||||
The following features are currently requested:
|
The following features are currently requested:
|
||||||
|
|
||||||
* Ability to set 'number of approvals' to zero, enabling instant updates (4 days)
|
* Ability to set 'number of approvals' to zero, enabling instant updates (4 days)
|
||||||
* Ability to restore previous versions
|
|
||||||
* Ability to make automated submissions using an API
|
* Ability to make automated submissions using an API
|
||||||
|
|
||||||
|
|
||||||
### Set Approvals to Zero
|
### Set Approvals to Zero
|
||||||
|
|
||||||
The following changes are necessary to implement this feature:
|
The following changes are necessary to implement this feature:
|
||||||
@@ -160,4 +158,23 @@ Our customer was ingesting Basel III reports into SAS and needed an easy to use
|
|||||||
|
|
||||||
We built an approach that allowed end users to define a series of rules for importing cells and ranges from anywhere within a workbook - based on absolute / relative positioning, or using search strings.
|
We built an approach that allowed end users to define a series of rules for importing cells and ranges from anywhere within a workbook - based on absolute / relative positioning, or using search strings.
|
||||||
|
|
||||||
The changes we made to deliver this feature are described [here](https://git.datacontroller.io/dc/dc/issues/69) and the final documentation is [here](/excel).
|
The changes we made to deliver this feature are described [here](https://git.datacontroller.io/dc/dc/issues/69) and the final documentation is [here](/excel).
|
||||||
|
|
||||||
|
|
||||||
|
### Restore Previous Versions
|
||||||
|
|
||||||
|
It is now possible to restore any change by heading to the particular staged data screen and hitting the red REVERT button
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
This will submit a NEW change (which must first be approved) that will revert the table to state it was in just prior to the selected upload.
|
||||||
|
|
||||||
|
Note that Data Controller can only track (and revert) changes that are made using the Data Controller tool itself! It does not / cannot track changes made externally to a table, by other tools.
|
||||||
|
|
||||||
|
### Frontend Formulae
|
||||||
|
|
||||||
|
Delivered in v7.13.0. Formula columns (HARDFORMULA / SOFTFORMULA) are computed live in the editor using HyperFormula, with variable-name references resolved to row-relative cell references. See [Formula Rules](/dcc-validations/#formula-rules).
|
||||||
|
|
||||||
|
### Regex Rules
|
||||||
|
|
||||||
|
Delivered. HARDREGEX (blocking) and SOFTREGEX (warning) rules validate cell values against a Perl-style regular expression. See [Regex Rules](/dcc-validations/#regex-rules).
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
---
|
||||||
|
layout: article
|
||||||
|
title: MPE_DATACATALOG_CATS
|
||||||
|
description: The MPE_DATACATALOG_CATS table contains all the catalogs available in each library
|
||||||
|
og_title: MPE_DATACATALOG_CATS Table Documentation
|
||||||
|
og_image: /img/datacatalog_cats.png
|
||||||
|
---
|
||||||
|
|
||||||
|
# MPE_DATACATALOG_CATS
|
||||||
|
|
||||||
|
The `MPE_DATACATALOG_CATS` table contains the catalogs available in each library.
|
||||||
|
|
||||||
|
More frequently changing attributes are stored in [MPE_DATASTATUS_CATS](/tables/mpe_datastatus_cats).
|
||||||
|
|
||||||
|
To trigger a scan, see the Refresh Data Catalog [instructions](/dcu-datacatalog/#refreshing-the-data-catalog).
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
## Columns
|
||||||
|
|
||||||
|
- `TX_FROM num`: SCD2 open datetime
|
||||||
|
- 🔑 `TX_TO num`: SCD2 close datetime
|
||||||
|
- 🔑 `LIBREF char(8)`: SAS Libref (8 chars)
|
||||||
|
- 🔑 `MEMNAME char(64)`: The catalog member name
|
||||||
@@ -10,11 +10,11 @@ The `MPE_DATACATALOG_LIBS` table catalogs library attributes such as engine, pat
|
|||||||
|
|
||||||
More frequently changing attributes (such as size and number of tables) are stored in [MPE_DATASTATUS_LIBS](/mpe_datastatus_libs).
|
More frequently changing attributes (such as size and number of tables) are stored in [MPE_DATASTATUS_LIBS](/mpe_datastatus_libs).
|
||||||
|
|
||||||
To ignore additional librefs, or to trigger a scan, see the Refresh Data Catalog [instructions](https://docs.datacontroller.io/admin-services/#refresh-data-catalog).
|
To ignore additional librefs, or to trigger a scan, see the Refresh Data Catalog [instructions](/dcu-datacatalog/#refreshing-the-data-catalog).
|
||||||
|
|
||||||
## Columns
|
## Columns
|
||||||
|
|
||||||
- `TX_FROM num`: SCD2 open datetime
|
- `TX_FROM num`: SCD2 open datetime
|
||||||
- 🔑 `TX_TO num`: SCD2 close datetime
|
- 🔑 `TX_TO num`: SCD2 close datetime
|
||||||
- 🔑 `LIBREF char(8)`: SAS Libref (8 chars)
|
- 🔑 `LIBREF char(8)`: SAS Libref (8 chars)
|
||||||
- `ENGINE char(32)`: The engine used to connect to the library
|
- `ENGINE char(32)`: The engine used to connect to the library
|
||||||
@@ -25,5 +25,22 @@ To ignore additional librefs, or to trigger a scan, see the Refresh Data Catalog
|
|||||||
- `SCHEMAS char(500)`: The library schema (DB engines)
|
- `SCHEMAS char(500)`: The library schema (DB engines)
|
||||||
- `LIBID char(17)`: The Library Id (from metadata if SAS 9)
|
- `LIBID char(17)`: The Library Id (from metadata if SAS 9)
|
||||||
|
|
||||||
|
## Refresh Process
|
||||||
|
|
||||||
|
The table is refreshed by the `mpe_refreshlibs` macro, which runs:
|
||||||
|
|
||||||
|
- When a user clicks the refresh icon next to a library in the VIEW menu (via the `refreshlibinfo` service)
|
||||||
|
- For ALL libraries when an administrator clicks REFRESH on the System page (via the `refreshlibs` service)
|
||||||
|
|
||||||
|
The refresh is driven primarily from `dictionary.libnames`, augmented with library name / id from metadata (SAS 9 only). Noteworthy behaviours:
|
||||||
|
|
||||||
|
- The `V9` engine is normalised to `BASE`
|
||||||
|
- Concatenated libraries produce multiple quoted entries in `PATHS`, with one comma-separated `PERMS` / `OWNERS` value per path
|
||||||
|
- `SCHEMAS` is populated for database engines
|
||||||
|
- On SAS 9 (metadata) deployments, invalid libraries are validated by attempting a META libname assignment and skipped on failure. If your environment has invalid libraries that cause exception errors, set the `DC_VIEWLIB_CHECK` config variable to `NO` in Data Controller Settings
|
||||||
|
- The following librefs are always excluded: `SASWORK`, `WORK`, `SASUSER`, `CASUSER`, `TEMP`, `STPSAMP`, `MAPSGFK`. Additional librefs can be ignored via `DC_IGNORELIBS` (see [Refreshing the Data Catalog](/dcu-datacatalog/#refreshing-the-data-catalog))
|
||||||
|
|
||||||
|
The load is TXTEMPORAL on the `LIBREF` key, so records are closed out (not deleted) when a library disappears.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
---
|
||||||
|
layout: article
|
||||||
|
title: MPE_DATACATALOG_OBJS
|
||||||
|
description: The MPE_DATACATALOG_OBJS table contains the objects inside every SAS Catalog
|
||||||
|
og_title: MPE_DATACATALOG_OBJS Table Documentation
|
||||||
|
og_image: /img/datacatalog_objs.png
|
||||||
|
---
|
||||||
|
|
||||||
|
# MPE_DATACATALOG_OBJS
|
||||||
|
|
||||||
|
The `MPE_DATACATALOG_OBJS` table contains a listing of all the objects available in each SAS Catalog.
|
||||||
|
|
||||||
|
More frequently changing attributes are stored in [MPE_DATASTATUS_OBJS](/mpe_datastatus_objs).
|
||||||
|
|
||||||
|
To trigger a scan, see the Refresh Data Catalog [instructions](/dcu-datacatalog/#refreshing-the-data-catalog).
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
## Columns
|
||||||
|
|
||||||
|
- `TX_FROM num`: SCD2 open datetime
|
||||||
|
- 🔑 `TX_TO num`: SCD2 close datetime
|
||||||
|
- 🔑 `LIBREF char(8)`: SAS Libref (8 chars)
|
||||||
|
- 🔑 `MEMNAME char(64)`: The catalog member name
|
||||||
|
- 🔑 `OBJNAME char(32)`: The object name
|
||||||
|
- 🔑 `OBJTYPE char(8)`: The object type
|
||||||
|
- `OBJDESC char(256)`: The object description
|
||||||
|
- `ALIAS char(32)`: The object alias
|
||||||
@@ -10,11 +10,11 @@ The `MPE_DATACATALOG_TABS` table catalogs attributes such as number of variables
|
|||||||
|
|
||||||
More frequently changing attributes (such as size modification date and number of observations) are stored in [MPE_DATASTATUS_TABS](/mpe_datastatus_tabs).
|
More frequently changing attributes (such as size modification date and number of observations) are stored in [MPE_DATASTATUS_TABS](/mpe_datastatus_tabs).
|
||||||
|
|
||||||
To trigger a scan, see the Refresh Data Catalog [instructions](https://docs.datacontroller.io/admin-services/#refresh-data-catalog).
|
To trigger a scan, see the Refresh Data Catalog [instructions](/dcu-datacatalog/#refreshing-the-data-catalog).
|
||||||
|
|
||||||
## Columns
|
## Columns
|
||||||
|
|
||||||
- `TX_FROM num`: SCD2 open datetime
|
- `TX_FROM num`: SCD2 open datetime
|
||||||
- 🔑 `TX_TO num`: SCD2 close datetime
|
- 🔑 `TX_TO num`: SCD2 close datetime
|
||||||
- 🔑 `LIBREF char(8)`: SAS Libref (8 chars)
|
- 🔑 `LIBREF char(8)`: SAS Libref (8 chars)
|
||||||
- 🔑 `DSN char(64)`: The library member name
|
- 🔑 `DSN char(64)`: The library member name
|
||||||
|
|||||||
@@ -8,11 +8,11 @@ description: The MPE_DATACATALOG_VARS table catalogs variable attributes such as
|
|||||||
|
|
||||||
The `MPE_DATACATALOG_VARS` table catalogs variable attributes such as primary key status, not null constraints and index usage.
|
The `MPE_DATACATALOG_VARS` table catalogs variable attributes such as primary key status, not null constraints and index usage.
|
||||||
|
|
||||||
To trigger a scan, see the Refresh Data Catalog [instructions](https://docs.datacontroller.io/admin-services/#refresh-data-catalog).
|
To trigger a scan, see the Refresh Data Catalog [instructions](/dcu-datacatalog/#refreshing-the-data-catalog).
|
||||||
|
|
||||||
## Columns
|
## Columns
|
||||||
|
|
||||||
- `TX_FROM num`: SCD2 open datetime
|
- `TX_FROM num`: SCD2 open datetime
|
||||||
- 🔑 `TX_TO num`: SCD2 close datetime
|
- 🔑 `TX_TO num`: SCD2 close datetime
|
||||||
- 🔑 `LIBREF char(8)`: SAS Libref (8 chars)
|
- 🔑 `LIBREF char(8)`: SAS Libref (8 chars)
|
||||||
- 🔑 `DSN char(64)`: The library member name
|
- 🔑 `DSN char(64)`: The library member name
|
||||||
|
|||||||
@@ -0,0 +1,21 @@
|
|||||||
|
---
|
||||||
|
layout: article
|
||||||
|
title: MPE_DATADICTIONARY
|
||||||
|
description: The MPE_DATADICTIONARY table documents libraries, tables, columns and directories with descriptions, ownership and sensitivity information.
|
||||||
|
---
|
||||||
|
|
||||||
|
# MPE_DATADICTIONARY
|
||||||
|
|
||||||
|
The `MPE_DATADICTIONARY` table stores user-maintained documentation for libraries, tables, columns and directories. This content is surfaced in the Data Dictionary view of Data Controller.
|
||||||
|
|
||||||
|
## Columns
|
||||||
|
|
||||||
|
- `TX_FROM num`: SCD2 open datetime
|
||||||
|
- 🔑 `DD_TYPE char(16)`: The type of item being documented (e.g. LIBRARY, TABLE, COLUMN, DIRECTORY)
|
||||||
|
- 🔑 `DD_SOURCE char(1024)`: The item being documented (e.g. `libref`, `libref.table`, `libref.table.column` or a directory path)
|
||||||
|
- `DD_SHORTDESC char(256)`: Short description
|
||||||
|
- `DD_LONGDESC char(32767)`: Long description (Markdown supported)
|
||||||
|
- `DD_OWNER char(128)`: Owner of the item
|
||||||
|
- `DD_RESPONSIBLE char(128)`: Responsible party for the item
|
||||||
|
- `DD_SENSITIVITY char(64)`: Sensitivity classification (e.g. Low)
|
||||||
|
- 🔑 `TX_TO num`: SCD2 close datetime
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
---
|
||||||
|
layout: article
|
||||||
|
title: MPE_DATALOADS
|
||||||
|
description: The MPE_DATALOADS table is an audit trail of every load performed through Data Controller for SAS®, including record counts and duration.
|
||||||
|
---
|
||||||
|
|
||||||
|
# MPE_DATALOADS
|
||||||
|
|
||||||
|
The `MPE_DATALOADS` table records an audit entry for every load performed (via the frontend, or via the [bitemporal dataloader macros](/macros/)).
|
||||||
|
|
||||||
|
## Columns
|
||||||
|
|
||||||
|
- 🔑 `PROCESSED_DTTM num`: Datetime the load completed
|
||||||
|
- 🔑 `LIBREF char(8)`: SAS Libref of the target table
|
||||||
|
- 🔑 `DSN char(32)`: Target table name
|
||||||
|
- 🔑 `ETLSOURCE char(100)`: Source of the load (e.g. the submitting user / service)
|
||||||
|
- `LOADTYPE char(20)`: The load type applied (UPDATE, REPLACE, TXTEMPORAL, BITEMPORAL, FORMAT_CAT)
|
||||||
|
- `CHANGED_RECORDS num`: Number of records changed
|
||||||
|
- `NEW_RECORDS num`: Number of records added
|
||||||
|
- `DELETED_RECORDS num`: Number of records deleted
|
||||||
|
- `DURATION num`: Duration of the load (seconds)
|
||||||
|
- `USER_NM char(50)`: The user who performed the load
|
||||||
|
- `MAC_VER char(5)`: The version of the Data Controller macros used
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
---
|
||||||
|
layout: article
|
||||||
|
title: MPE_DATASTATUS_CATS
|
||||||
|
description: The MPE_DATASTATUS_CATS table captures frequently changing SAS catalog attributes such as created / modified datetimes and number of entries.
|
||||||
|
og_title: MPE_DATASTATUS_CATS Table Documentation
|
||||||
|
og_image: /img/datastatus_cats.png
|
||||||
|
---
|
||||||
|
|
||||||
|
# MPE_DATASTATUS_CATS
|
||||||
|
|
||||||
|
The `MPE_DATASTATUS_CATS` table captures frequently changing SAS table attributes such as created / modified datetimes and number of entries.
|
||||||
|
|
||||||
|
To trigger a scan, see the Refresh Data Catalog [instructions](/dcu-datacatalog/#refreshing-the-data-catalog).
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
## Columns
|
||||||
|
|
||||||
|
- `TX_FROM num`: SCD2 open datetime
|
||||||
|
- 🔑 `TX_TO num`: SCD2 close datetime
|
||||||
|
- 🔑 `LIBREF char(8)`: SAS Libref (8 chars)
|
||||||
|
- 🔑 `MEMNAME char(64)`: The catalog member name
|
||||||
|
- `NOBS num`: The number of catalog entries
|
||||||
|
- `CREATED num`: Creation datetime (based on earliest created object)
|
||||||
|
- `MODIFIED num`: Modified datetime (based on last modified object)
|
||||||
|
|
||||||
|
|
||||||
@@ -8,13 +8,23 @@ description: The MPE_DATASTATUS_LIBS table captures frequently changing SAS libr
|
|||||||
|
|
||||||
The `MPE_DATASTATUS_LIBS` table captures frequently changing SAS library attributes such as size (if filesystem based) and the number of tables.
|
The `MPE_DATASTATUS_LIBS` table captures frequently changing SAS library attributes such as size (if filesystem based) and the number of tables.
|
||||||
|
|
||||||
To trigger a scan, see the Refresh Data Catalog [instructions](https://docs.datacontroller.io/admin-services/#refresh-data-catalog).
|
To trigger a scan, see the Refresh Data Catalog [instructions](/dcu-datacatalog/#refreshing-the-data-catalog).
|
||||||
|
|
||||||
## Columns
|
## Columns
|
||||||
|
|
||||||
- `TX_FROM num`: SCD2 open datetime
|
- `TX_FROM num`: SCD2 open datetime
|
||||||
- 🔑 `TX_TO num`: SCD2 close datetime
|
- 🔑 `TX_TO num`: SCD2 close datetime
|
||||||
- 🔑 `LIBREF char(8)`: SAS Libref (8 chars)
|
- 🔑 `LIBREF char(8)`: SAS Libref (8 chars)
|
||||||
- `LIBSIZE num`: The size of the library (in bytes), displayed with the SIZEKMG. format. Only applicable to BASE engine libraries.
|
- `LIBSIZE num`: The size of the library (in bytes), displayed with the SIZEKMG. format. Only applicable to BASE engine libraries.
|
||||||
- `TABLE_CNT num`: The number of tables in the library.
|
- `TABLE_CNT num`: The number of tables in the library.
|
||||||
|
- `CATALOG_CNT num`: The number of SAS Catalogs in the library (from `dictionary.catalogs`).
|
||||||
|
|
||||||
|
## Refresh Process
|
||||||
|
|
||||||
|
This table is populated by the `mpe_refreshtables` macro when a FULL library refresh is performed (all tables). It does not change when a single table is refreshed.
|
||||||
|
|
||||||
|
- `LIBSIZE` is the sum of `filesize` across the library members in `dictionary.tables` - hence it is only applicable to BASE (filesystem) engines. For SQL Server libraries, filesize is not available and row counts are instead taken from `sys.partitions` via pass-through
|
||||||
|
- `TABLE_CNT` is the count of tables in the library
|
||||||
|
|
||||||
|
To trigger a scan, see the Refresh Data Catalog [instructions](/dcu-datacatalog/#refreshing-the-data-catalog).
|
||||||
|
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
---
|
||||||
|
layout: article
|
||||||
|
title: MPE_DATASTATUS_OBJS
|
||||||
|
description: The MPE_DATASTATUS_OBJS table captures frequently changing SAS catalog object attributes such as created / modified datetimes and library concatenation level
|
||||||
|
og_title: MPE_DATASTATUS_OBJS Table Documentation
|
||||||
|
og_image: /img/datastatus_objs.png
|
||||||
|
---
|
||||||
|
|
||||||
|
# MPE_DATASTATUS_OBJS
|
||||||
|
|
||||||
|
The `MPE_DATASTATUS_OBJS` table captures frequently changing SAS catalog object attributes such as created / modified datetimes and library concatenation level
|
||||||
|
|
||||||
|
To trigger a scan, see the Refresh Data Catalog [instructions](/dcu-datacatalog/#refreshing-the-data-catalog).
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
## Columns
|
||||||
|
|
||||||
|
- `TX_FROM num`: SCD2 open datetime
|
||||||
|
- 🔑 `TX_TO num`: SCD2 close datetime
|
||||||
|
- 🔑 `LIBREF char(8)`: SAS Libref (8 chars)
|
||||||
|
- 🔑 `MEMNAME char(64)`: The catalog member name
|
||||||
|
- 🔑 `OBJNAME char(32)`: The object name
|
||||||
|
- 🔑 `OBJTYPE char(8)`: The object type
|
||||||
|
- `CREATED num`: Creation datetime (based on earliest created object)
|
||||||
|
- `MODIFIED num`: Modified datetime (based on last modified object)
|
||||||
|
- `LEVEL num`: Library concatenation level
|
||||||
|
|
||||||
@@ -8,11 +8,11 @@ description: The MPE_DATASTATUS_TABS table captures frequently changing SAS tabl
|
|||||||
|
|
||||||
The `MPE_DATASTATUS_TABS` table captures frequently changing SAS table attributes such as size (if filesystem based), modification date, and the number of observations.
|
The `MPE_DATASTATUS_TABS` table captures frequently changing SAS table attributes such as size (if filesystem based), modification date, and the number of observations.
|
||||||
|
|
||||||
To trigger a scan, see the Refresh Data Catalog [instructions](https://docs.datacontroller.io/admin-services/#refresh-data-catalog).
|
To trigger a scan, see the Refresh Data Catalog [instructions](/dcu-datacatalog/#refreshing-the-data-catalog).
|
||||||
|
|
||||||
## Columns
|
## Columns
|
||||||
|
|
||||||
- `TX_FROM num`: SCD2 open datetime
|
- `TX_FROM num`: SCD2 open datetime
|
||||||
- 🔑 `TX_TO num`: SCD2 close datetime
|
- 🔑 `TX_TO num`: SCD2 close datetime
|
||||||
- 🔑 `LIBREF char(8)`: SAS Libref (8 chars)
|
- 🔑 `LIBREF char(8)`: SAS Libref (8 chars)
|
||||||
- 🔑 `DSN char(64)`: The library member name
|
- 🔑 `DSN char(64)`: The library member name
|
||||||
|
|||||||
@@ -0,0 +1,25 @@
|
|||||||
|
---
|
||||||
|
layout: article
|
||||||
|
title: MPE_EMAILS
|
||||||
|
description: The MPE_EMAILS table is used to map email addresses to individual users
|
||||||
|
og_title: MPE_EMAILS Table Documentation
|
||||||
|
og_image: /img/mpe_emails.png
|
||||||
|
---
|
||||||
|
|
||||||
|
# MPE_EMAILS
|
||||||
|
|
||||||
|
The MPE_EMAILS table maps emails to user ids. This is helpful in situations where the email address is not automatically available (eg in SAS metadata or the Viya identities service)
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
The table is SCD2 controlled for ease of rollback and version management.
|
||||||
|
|
||||||
|
For more information, see the [email config](/emails) page.
|
||||||
|
|
||||||
|
## Columns
|
||||||
|
|
||||||
|
- 🔑 `TX_FROM num`: SCD2 open datetime
|
||||||
|
- 🔑 `USER_NAME char(50)`: The system name of the user
|
||||||
|
- `USER_DISPLAYNAME char(100)`: The name by which the user should be addressed
|
||||||
|
- `USER_EMAIL char(100)`: The email address of the user
|
||||||
|
- `TX_TO num`: SCD2 close datetime
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
---
|
||||||
|
layout: article
|
||||||
|
title: MPE_EXCEL_CONFIG
|
||||||
|
description: The MPE_EXCEL_CONFIG table configures column-level rules applied during Excel uploads in Data Controller for SAS®.
|
||||||
|
---
|
||||||
|
|
||||||
|
# MPE_EXCEL_CONFIG
|
||||||
|
|
||||||
|
The `MPE_EXCEL_CONFIG` table configures column-level rules that are applied when uploading data via Excel. See the [Excel](/excel/) guide for more details.
|
||||||
|
|
||||||
|
## Columns
|
||||||
|
|
||||||
|
- `TX_FROM num`: SCD2 open datetime
|
||||||
|
- 🔑 `XL_LIBREF char(8)`: SAS Libref of the target table
|
||||||
|
- 🔑 `XL_TABLE char(32)`: Target table name
|
||||||
|
- 🔑 `XL_COLUMN char(32)`: Column to which the rule applies
|
||||||
|
- `XL_RULE char(32)`: The rule to apply. Currently the only supported rule is `FORMULA` - this extracts the underlying cell _formula_ (eg `=VLOOKUP(...)`) rather than the raw cell value during an Excel upload. The target column must be character, and wide enough to hold the longest formula.
|
||||||
|
- `XL_ACTIVE num`: Flag indicating whether the rule is active (1 = active)
|
||||||
|
- `TX_TO num`: SCD2 close datetime
|
||||||
|
|
||||||
|
## Example
|
||||||
|
|
||||||
|
The following entry (from the Data Controller sample data) causes the `DD_LONGDESC` column of `MPE_DATADICTIONARY` to be loaded as a formula rather than a raw value when uploading via Excel:
|
||||||
|
|
||||||
|
```sas
|
||||||
|
insert into &lib..MPE_EXCEL_CONFIG set
|
||||||
|
tx_from=0
|
||||||
|
,xl_libref="&lib"
|
||||||
|
,xl_table="MPE_DATADICTIONARY"
|
||||||
|
,xl_column="DD_LONGDESC"
|
||||||
|
,xl_rule="FORMULA"
|
||||||
|
,xl_active=1
|
||||||
|
,tx_to='31DEC5999:23:59:59'dt;
|
||||||
|
```
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
---
|
||||||
|
layout: article
|
||||||
|
title: MPE_FILTERANYTABLE
|
||||||
|
description: The MPE_FILTERANYTABLE table stores a record for each unique filter clause created in Data Controller for SAS®.
|
||||||
|
---
|
||||||
|
|
||||||
|
# MPE_FILTERANYTABLE
|
||||||
|
|
||||||
|
The `MPE_FILTERANYTABLE` table stores a record for each unique filter created via the FILTER menu. When a user submits a filter, the entire clause is hashed - if that hash already exists for the table, the existing `FILTER_RK` is reused, otherwise a new record is added. This means identical filters are only ever stored once, and the `FILTER_RK` can be safely embedded in the shareable URLs described in the [filter](/filter/) guide.
|
||||||
|
|
||||||
|
The individual lines of the filter clause itself are stored in [MPE_FILTERSOURCE](/tables/mpe_filtersource/).
|
||||||
|
|
||||||
|
## Columns
|
||||||
|
|
||||||
|
- 🔑 `FILTER_RK num`: Unique retained key for the filter, used to recall the filter (eg in shareable URLs)
|
||||||
|
- `FILTER_HASH char(32)`: Hash of the entire filter clause, used to detect duplicate filters and to join to [MPE_FILTERSOURCE](/tables/mpe_filtersource/)
|
||||||
|
- `FILTER_TABLE char(41)`: The table being filtered (in `libref.dataset` format)
|
||||||
|
- `PROCESSED_DTTM num`: Datetime the filter was first created
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
---
|
||||||
|
layout: article
|
||||||
|
title: MPE_FILTERSOURCE
|
||||||
|
description: The MPE_FILTERSOURCE table stores the individual lines of each filter clause created in Data Controller for SAS®.
|
||||||
|
---
|
||||||
|
|
||||||
|
# MPE_FILTERSOURCE
|
||||||
|
|
||||||
|
The `MPE_FILTERSOURCE` table stores the individual query lines of each filter created via the FILTER menu, keyed by the hash stored in [MPE_FILTERANYTABLE](/tables/mpe_filteranytable/). See the [filter](/filter/) guide for more details.
|
||||||
|
|
||||||
|
## Columns
|
||||||
|
|
||||||
|
- 🔑 `FILTER_HASH char(32)`: Hash of the filter clause, joining to [MPE_FILTERANYTABLE](/tables/mpe_filteranytable/)
|
||||||
|
- 🔑 `FILTER_LINE num`: Line number within the filter clause
|
||||||
|
- `GROUP_LOGIC char(3)`: AND / OR logic applied between groups
|
||||||
|
- `SUBGROUP_LOGIC char(3)`: AND / OR logic applied within the subgroup
|
||||||
|
- `SUBGROUP_ID num`: Identifier of the subgroup to which this line belongs
|
||||||
|
- `VARIABLE_NM char(32)`: The variable being filtered
|
||||||
|
- `OPERATOR_NM char(12)`: The filter operator (e.g. `=`, `>`, `IN`)
|
||||||
|
- `RAW_VALUE char(4000)`: The filter value
|
||||||
|
- `PROCESSED_DTTM num`: Datetime the filter line was created
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
---
|
||||||
|
layout: article
|
||||||
|
title: MPE_GROUPS
|
||||||
|
description: The MPE_GROUPS table defines optional groups and group membership used to secure access to tables in Data Controller for SAS®.
|
||||||
|
---
|
||||||
|
|
||||||
|
# MPE_GROUPS
|
||||||
|
|
||||||
|
The `MPE_GROUPS` table defines optional groups, and the members of those groups, used to secure access in Data Controller.
|
||||||
|
|
||||||
|
A more detailed breakdown is available in the [configuration](/dcc-groups/) section.
|
||||||
|
|
||||||
|
## Columns
|
||||||
|
|
||||||
|
- `TX_FROM num`: SCD2 open datetime
|
||||||
|
- 🔑 `GROUP_NAME char(100)`: The name of the group
|
||||||
|
- `GROUP_DESC char(256)`: A description of the group
|
||||||
|
- 🔑 `USER_NAME char(50)`: The user (SAS identity name) who is a member of the group
|
||||||
|
- `TX_TO num`: SCD2 close datetime
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
---
|
||||||
|
layout: article
|
||||||
|
title: MPE_LINEAGE_COLS
|
||||||
|
description: The MPE_LINEAGE_COLS table stores column-level lineage (forward and reverse) extracted by Data Controller for SAS®.
|
||||||
|
---
|
||||||
|
|
||||||
|
# MPE_LINEAGE_COLS
|
||||||
|
|
||||||
|
The `MPE_LINEAGE_COLS` table stores column-level lineage - the column mappings derived from jobs registered in SAS DI Studio. See the [lineage](/dcu-lineage/) guide for more details.
|
||||||
|
|
||||||
|
## Columns
|
||||||
|
|
||||||
|
- 🔑 `COL_ID char(32)`: Unique identifier of the lineage record
|
||||||
|
- 🔑 `DIRECTION char(1)`: Lineage direction (e.g. F for forward, R for reverse)
|
||||||
|
- `JOBNAME char(256)`: Name of the job in which the mapping was found
|
||||||
|
- `SOURCETABLENAME char(256)`: Name of the source table
|
||||||
|
- `SOURCECOLNAME char(256)`: Name of the source column
|
||||||
|
- 🔑 `SOURCECOLURI char(256)`: URI of the source column
|
||||||
|
- 🔑 `MAP_TYPE char(256)`: The type of mapping
|
||||||
|
- 🔑 `MAP_TRANSFORM char(256)`: The transformation applied in the mapping
|
||||||
|
- `TARGETTABLENAME char(256)`: Name of the target table
|
||||||
|
- `TARGETCOLNAME char(256)`: Name of the target column
|
||||||
|
- 🔑 `TARGETCOLURI char(256)`: URI of the target column
|
||||||
|
- `DERIVED_RULE char(500)`: The derivation rule applied
|
||||||
|
- `LEVEL num`: The depth of the mapping within the lineage tree
|
||||||
|
- `MODIFIED_DTTM num`: Datetime the record was last modified
|
||||||
|
- `MODIFIED_BY char(64)`: The user who last modified the record
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
---
|
||||||
|
layout: article
|
||||||
|
title: MPE_LINEAGE_TABS
|
||||||
|
description: The MPE_LINEAGE_TABS table stores table-level lineage (forward and reverse) extracted by Data Controller for SAS®.
|
||||||
|
---
|
||||||
|
|
||||||
|
# MPE_LINEAGE_TABS
|
||||||
|
|
||||||
|
The `MPE_LINEAGE_TABS` table stores table-level lineage - the table-to-table relationships derived from jobs registered in SAS DI Studio. See the [lineage](/dcu-lineage/) guide for more details.
|
||||||
|
|
||||||
|
## Columns
|
||||||
|
|
||||||
|
- `TX_FROM num`: SCD2 open datetime
|
||||||
|
- 🔑 `TX_TO num`: SCD2 close datetime
|
||||||
|
- 🔑 `JOBID char(17)`: Identifier of the job in which the relationship was found
|
||||||
|
- `JOBNAME char(128)`: Name of the job
|
||||||
|
- 🔑 `SRCTABLEID char(17)`: Identifier of the source table
|
||||||
|
- `SRCTABLETYPE char(16)`: Type of the source table
|
||||||
|
- `SRCTABLENAME char(64)`: Name of the source table
|
||||||
|
- `SRCLIBREF char(8)`: Libref of the source table
|
||||||
|
- 🔑 `TGTTABLEID char(17)`: Identifier of the target table
|
||||||
|
- `TGTTABLETYPE char(16)`: Type of the target table
|
||||||
|
- `TGTTABLENAME char(64)`: Name of the target table
|
||||||
|
- `TGTLIBREF char(8)`: Libref of the target table
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
---
|
||||||
|
layout: article
|
||||||
|
title: MPE_LOADS
|
||||||
|
description: The MPE_LOADS table records the status of CSV file loads performed by the Data Controller for SAS® target loader.
|
||||||
|
---
|
||||||
|
|
||||||
|
# MPE_LOADS
|
||||||
|
|
||||||
|
The `MPE_LOADS` table tracks the status of CSV file loads processed by the target loader ([mpe_targetloader](/macros/) macro), including failures and their reasons.
|
||||||
|
|
||||||
|
## Columns
|
||||||
|
|
||||||
|
- 🔑 `CSV_DIR char(255)`: The staged folder reference (mperef) containing the CSV files being loaded
|
||||||
|
- `USER_NM char(50)`: The user who submitted the load
|
||||||
|
- `STATUS char(15)`: The status of the load (e.g. IN PROGRESS, SUCCESS, FAILED)
|
||||||
|
- `DURATION num`: Duration of the load (seconds)
|
||||||
|
- `PROCESSED_DTTM num`: Datetime the load was processed
|
||||||
|
- `REASON_TXT char(2048)`: The reason for failure (where applicable)
|
||||||
|
- `APPROVALS char(64)`: Approval information for the load
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
---
|
||||||
|
layout: article
|
||||||
|
title: MPE_MAXKEYVALUES
|
||||||
|
description: The MPE_MAXKEYVALUES table stores the current maximum surrogate / retained key value for each keyed table in Data Controller for SAS®.
|
||||||
|
---
|
||||||
|
|
||||||
|
# MPE_MAXKEYVALUES
|
||||||
|
|
||||||
|
The `MPE_MAXKEYVALUES` table stores the current maximum surrogate / retained key value for each table configured with a retained key (see [RK_UNDERLYING](/dcc-tables/#rk_underlying)). It is used to generate new key values during loads.
|
||||||
|
|
||||||
|
## Columns
|
||||||
|
|
||||||
|
- 🔑 `KEYTABLE char(41)`: Base table in `libref.dataset` format
|
||||||
|
- `KEYCOLUMN char(32)`: The surrogate / retained key field containing the key values
|
||||||
|
- `MAX_KEY num`: Integer value representing the current max RK or SK value in the KEYTABLE
|
||||||
|
- `PROCESSED_DTTM num`: Datetime this value was last updated
|
||||||
@@ -22,4 +22,4 @@ Edits to this table are covered by a (backend) post edit hook, which will automa
|
|||||||
- 🔑 `DSN char(32)`: The name of the target dataset (or format catalog)
|
- 🔑 `DSN char(32)`: The name of the target dataset (or format catalog)
|
||||||
- 🔑 `ACCESS_LEVEL char(100)`: Either VIEW, EDIT or APPROVE
|
- 🔑 `ACCESS_LEVEL char(100)`: Either VIEW, EDIT or APPROVE
|
||||||
- 🔑 `SAS_GROUP char(100)`: The SAS Group to which to provide access
|
- 🔑 `SAS_GROUP char(100)`: The SAS Group to which to provide access
|
||||||
- `TX_TO num`: SCD2 close datetime
|
- `TX_TO num`: SCD2 close datetime
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
---
|
||||||
|
layout: article
|
||||||
|
title: MPE_SELECTBOX
|
||||||
|
description: The MPE_SELECTBOX table configures the dropdown values available for columns of control tables in Data Controller for SAS®.
|
||||||
|
---
|
||||||
|
|
||||||
|
# MPE_SELECTBOX
|
||||||
|
|
||||||
|
The `MPE_SELECTBOX` table configures the values that appear in dropdowns when editing control tables (eg `LOADTYPE` in [MPE_TABLES](/tables/mpe_tables/) or `ACCESS_LEVEL` in [MPE_SECURITY](/tables/mpe_security/)).
|
||||||
|
|
||||||
|
A more detailed breakdown is available in the [configuration](/dcc-selectbox/) section.
|
||||||
|
|
||||||
|
## Columns
|
||||||
|
|
||||||
|
- `VER_FROM_DTTM num`: SCD2 open datetime
|
||||||
|
- 🔑 `SELECTBOX_RK num`: Surrogate key for the selectbox value
|
||||||
|
- `SELECT_LIB char(17)`: Libref of the table to which the dropdown applies
|
||||||
|
- `SELECT_DS char(32)`: Name of the table to which the dropdown applies
|
||||||
|
- `BASE_COLUMN char(36)`: The column against which the dropdown is applied
|
||||||
|
- `SELECTBOX_VALUE char(500)`: The dropdown value
|
||||||
|
- `SELECTBOX_ORDER num`: Optional ordering of the dropdown values (1 comes before 2)
|
||||||
|
- `SELECTBOX_TYPE char(32)`: Column type (blank for default, else `sas` or `js` to indicate relevant system functions)
|
||||||
|
- `VER_TO_DTTM num`: SCD2 close datetime
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
---
|
||||||
|
layout: article
|
||||||
|
title: MPE_SIGNOFFS
|
||||||
|
description: The MPE_SIGNOFFS table records signoffs made against loaded data in Data Controller for SAS®.
|
||||||
|
---
|
||||||
|
|
||||||
|
# MPE_SIGNOFFS
|
||||||
|
|
||||||
|
The `MPE_SIGNOFFS` table is designed to record signoffs - the final approval step associated with SIGNOFF access (see [MPE_SECURITY](/tables/mpe_security/) and [SIGNOFF_COLS](/dcc-tables/#signoff_cols)).
|
||||||
|
|
||||||
|
!!! note
|
||||||
|
This table is created as part of the Data Controller data model but is not currently populated by any Data Controller service. It is reserved for custom signoff implementations.
|
||||||
|
|
||||||
|
## Columns
|
||||||
|
|
||||||
|
- 🔑 `TECH_FROM_DTTM num`: SCD2 open datetime
|
||||||
|
- 🔑 `SIGNOFF_TABLE char(50)`: The table being signed off
|
||||||
|
- 🔑 `SIGNOFF_SECTION_RK num`: The retained key of the section being signed off
|
||||||
|
- `SIGNOFF_VERSION_RK num`: The retained key of the version being signed off
|
||||||
|
- `SIGNOFF_NAME char(100)`: The name of the user performing the signoff
|
||||||
|
- `TECH_TO_DTTM num`: SCD2 close datetime
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
---
|
||||||
|
layout: article
|
||||||
|
title: MPE_USERS
|
||||||
|
description: The MPE_USERS table captures the users of Data Controller for SAS® and when they were last seen.
|
||||||
|
---
|
||||||
|
|
||||||
|
# MPE_USERS
|
||||||
|
|
||||||
|
The `MPE_USERS` table captures the actual users of the app - each user is registered on first login, and their last seen date is updated on subsequent activity.
|
||||||
|
|
||||||
|
## Columns
|
||||||
|
|
||||||
|
- 🔑 `USER_ID char(50)`: The user id
|
||||||
|
- `LAST_SEEN_DT num`: Date the user was last active
|
||||||
|
- `REGISTERED_DT num`: Date the user first registered
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
---
|
||||||
|
layout: article
|
||||||
|
title: MPE_VALIDATIONS
|
||||||
|
description: The `MPE_VALIDATIONS` table enables a number of validations to be applied to the data at the point of entry - such as casing, min/max values, nullability, and the ability to generate dropdown values directly from source tables or dynamically from SAS programs.
|
||||||
|
og_image: /img/mpe_validations.png
|
||||||
|
---
|
||||||
|
|
||||||
|
# MPE_VALIDATIONS
|
||||||
|
|
||||||
|
The `MPE_VALIDATIONS` table enables a number of validations to be applied to the data at the point of entry - such as casing, min/max values, nullability, and the ability to generate dropdown values directly from source tables or dynamically from SAS programs.
|
||||||
|
|
||||||
|
A detailed breakdown is available in the [validations](/dcc-validations/) section.
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
## Columns
|
||||||
|
|
||||||
|
- 🔑`TX_FROM num`: SCD2 open datetime
|
||||||
|
- `TX_TO num`: SCD2 close datetime
|
||||||
|
- 🔑 `BASE_LIB char(8)`: SAS Libref (8 chars)
|
||||||
|
- 🔑 `BASE_DS char(32)`: The library member name
|
||||||
|
- 🔑 `BASE_COL char(32)`: The column name
|
||||||
|
- 🔑 `RULE_TYPE char(32)`: The name of the rule to apply. Valid values include `CASE`, `NOTNULL`, `MINVAL`, `MAXVAL`, `READONLY`, `HIDDEN`, `ROUND`, `NUMBER_FORMAT`, `HARDFORMULA`, `SOFTFORMULA`, `HARDREGEX`, `SOFTREGEX`, `HARDSELECT`, `SOFTSELECT`, `HARDSELECT_HOOK` and `SOFTSELECT_HOOK`.
|
||||||
|
- `RULE_VALUE char(128)`: The value of the rule.
|
||||||
|
- `RULE_ACTIVE num`: Set to 1 for an active rule, or 0 to disable the rule.
|
||||||
@@ -12,7 +12,7 @@ Often when editing (or examining) raw data, it is helpful to see it alongside re
|
|||||||
Each individual viewbox has the following features:
|
Each individual viewbox has the following features:
|
||||||
|
|
||||||
* Choose the columns to display (and which order)
|
* Choose the columns to display (and which order)
|
||||||
* Resize individual boxes (or reset to original)
|
* Resize individual boxes by dragging any of the four edges or corners (or reset to original)
|
||||||
* Full filtering capability (complex clauses)
|
* Full filtering capability (complex clauses)
|
||||||
* Minimise / Restore all, or individually
|
* Minimise / Restore all, or individually
|
||||||
* Reposition - manually, or snap to grid
|
* Reposition - manually, or snap to grid
|
||||||
|
|||||||
@@ -18,21 +18,41 @@ nav:
|
|||||||
- MPE_AUDIT: tables/mpe_audit.md
|
- MPE_AUDIT: tables/mpe_audit.md
|
||||||
- MPE_COLUMN_LEVEL_SECURITY: tables/mpe_column_level_security.md
|
- MPE_COLUMN_LEVEL_SECURITY: tables/mpe_column_level_security.md
|
||||||
- MPE_CONFIG: tables/mpe_config.md
|
- MPE_CONFIG: tables/mpe_config.md
|
||||||
|
- MPE_DATACATALOG_CATS: tables/mpe_datacatalog_cats.md
|
||||||
- MPE_DATACATALOG_LIBS: tables/mpe_datacatalog_libs.md
|
- MPE_DATACATALOG_LIBS: tables/mpe_datacatalog_libs.md
|
||||||
|
- MPE_DATACATALOG_OBJS: tables/mpe_datacatalog_objs.md
|
||||||
- MPE_DATACATALOG_TABS: tables/mpe_datacatalog_tabs.md
|
- MPE_DATACATALOG_TABS: tables/mpe_datacatalog_tabs.md
|
||||||
- MPE_DATACATALOG_VARS: tables/mpe_datacatalog_vars.md
|
- MPE_DATACATALOG_VARS: tables/mpe_datacatalog_vars.md
|
||||||
|
- MPE_DATASTATUS_CATS: tables/mpe_datastatus_cats.md
|
||||||
- MPE_DATASTATUS_LIBS: tables/mpe_datastatus_libs.md
|
- MPE_DATASTATUS_LIBS: tables/mpe_datastatus_libs.md
|
||||||
|
- MPE_DATASTATUS_OBJ: tables/mpe_datastatus_objs.md
|
||||||
- MPE_DATASTATUS_TABS: tables/mpe_datastatus_tabs.md
|
- MPE_DATASTATUS_TABS: tables/mpe_datastatus_tabs.md
|
||||||
|
- MPE_DATADICTIONARY: tables/mpe_datadictionary.md
|
||||||
|
- MPE_DATALOADS: tables/mpe_dataloads.md
|
||||||
|
- MPE_EMAILS: tables/mpe_emails.md
|
||||||
|
- MPE_EXCEL_CONFIG: tables/mpe_excel_config.md
|
||||||
|
- MPE_FILTERANYTABLE: tables/mpe_filteranytable.md
|
||||||
|
- MPE_FILTERSOURCE: tables/mpe_filtersource.md
|
||||||
|
- MPE_GROUPS: tables/mpe_groups.md
|
||||||
|
- MPE_LINEAGE_COLS: tables/mpe_lineage_cols.md
|
||||||
|
- MPE_LINEAGE_TABS: tables/mpe_lineage_tabs.md
|
||||||
|
- MPE_LOADS: tables/mpe_loads.md
|
||||||
- MPE_LOCKANYTABLE: tables/mpe_lockanytable.md
|
- MPE_LOCKANYTABLE: tables/mpe_lockanytable.md
|
||||||
|
- MPE_MAXKEYVALUES: tables/mpe_maxkeyvalues.md
|
||||||
- MPE_REQUESTS: tables/mpe_requests.md
|
- MPE_REQUESTS: tables/mpe_requests.md
|
||||||
- MPE_REVIEW: tables/mpe_review.md
|
- MPE_REVIEW: tables/mpe_review.md
|
||||||
- MPE_SUBMIT: tables/mpe_submit.md
|
- MPE_SUBMIT: tables/mpe_submit.md
|
||||||
- MPE_SECURITY: tables/mpe_security.md
|
- MPE_SECURITY: tables/mpe_security.md
|
||||||
|
- MPE_SELECTBOX: tables/mpe_selectbox.md
|
||||||
|
- MPE_SIGNOFFS: tables/mpe_signoffs.md
|
||||||
- MPE_TABLES: tables/mpe_tables.md
|
- MPE_TABLES: tables/mpe_tables.md
|
||||||
|
- MPE_USERS: tables/mpe_users.md
|
||||||
|
- MPE_VALIDATIONS: tables/mpe_validations.md
|
||||||
- MPE_XLMAP_DATA: tables/mpe_xlmap_data.md
|
- MPE_XLMAP_DATA: tables/mpe_xlmap_data.md
|
||||||
- MPE_XLMAP_INFO: tables/mpe_xlmap_info.md
|
- MPE_XLMAP_INFO: tables/mpe_xlmap_info.md
|
||||||
- MPE_XLMAP_RULES: tables/mpe_xlmap_rules.md
|
- MPE_XLMAP_RULES: tables/mpe_xlmap_rules.md
|
||||||
- Configuration:
|
- Configuration:
|
||||||
|
- CAS Tables: cas-tables.md
|
||||||
- Column Level Security: column-level-security.md
|
- Column Level Security: column-level-security.md
|
||||||
- Dates / Datetimes: dcc-dates.md
|
- Dates / Datetimes: dcc-dates.md
|
||||||
- Dynamic Cell Dropdown: dynamic-cell-dropdown.md
|
- Dynamic Cell Dropdown: dynamic-cell-dropdown.md
|
||||||
@@ -47,10 +67,12 @@ nav:
|
|||||||
- Selectboxes: dcc-selectbox.md
|
- Selectboxes: dcc-selectbox.md
|
||||||
- Tables: dcc-tables.md
|
- Tables: dcc-tables.md
|
||||||
- Validations: dcc-validations.md
|
- Validations: dcc-validations.md
|
||||||
|
- Visual Analytics: embed-va.md
|
||||||
- Macros: macros.md
|
- Macros: macros.md
|
||||||
- Installation:
|
- Installation:
|
||||||
- System Requirements: dci-requirements.md
|
- System Requirements: dci-requirements.md
|
||||||
- SAS Viya: dci-deploysasviya.md
|
- Downloads: downloads.md
|
||||||
|
- SAS Viya: deploy-viya.md
|
||||||
- SAS 9 EBI: dci-deploysas9.md
|
- SAS 9 EBI: dci-deploysas9.md
|
||||||
- SAS 9 STP Hardening: dci-stpinstance.md
|
- SAS 9 STP Hardening: dci-stpinstance.md
|
||||||
- Troubleshooting: dci-troubleshooting.md
|
- Troubleshooting: dci-troubleshooting.md
|
||||||
@@ -74,7 +96,9 @@ markdown_extensions:
|
|||||||
extra:
|
extra:
|
||||||
manifest: manifest.webmanifest
|
manifest: manifest.webmanifest
|
||||||
|
|
||||||
extra_css: ['font-awesome.css']
|
extra_css:
|
||||||
|
- font-awesome.css
|
||||||
|
- dc-brand.css
|
||||||
|
|
||||||
plugins:
|
plugins:
|
||||||
- search:
|
- search:
|
||||||
@@ -90,12 +114,22 @@ repo_url: 'https://git.datacontroller.io/dc/docs.datacontroller.io'
|
|||||||
|
|
||||||
theme:
|
theme:
|
||||||
name: material
|
name: material
|
||||||
logo: 'img/favicon.ico'
|
logo: 'img/dc-logo.svg'
|
||||||
palette:
|
palette:
|
||||||
primary: 'White'
|
- scheme: slate
|
||||||
accent: 'Amber'
|
primary: custom
|
||||||
|
accent: custom
|
||||||
|
toggle:
|
||||||
|
icon: material/weather-sunny
|
||||||
|
name: Switch to light mode
|
||||||
|
- scheme: default
|
||||||
|
primary: custom
|
||||||
|
accent: custom
|
||||||
|
toggle:
|
||||||
|
icon: material/weather-night
|
||||||
|
name: Switch to dark mode
|
||||||
font:
|
font:
|
||||||
text: 'Open Sans'
|
text: 'Montserrat'
|
||||||
code: 'Ubuntu Mono'
|
code: 'Ubuntu Mono'
|
||||||
favicon: img/favicon.ico
|
favicon: img/favicon.ico
|
||||||
custom_dir: 'theme'
|
custom_dir: 'theme'
|
||||||
@@ -105,4 +139,4 @@ theme:
|
|||||||
- JavaScript
|
- JavaScript
|
||||||
- Bash
|
- Bash
|
||||||
|
|
||||||
copyright: All rights reserved ©2023 Bowe IO Ltd.
|
copyright: All rights reserved ©2026 Bowe IO Ltd.
|
||||||