Compare commits
59 Commits
Author | SHA1 | Date | |
---|---|---|---|
8c60473c15 | |||
bb126eba5b | |||
d1998422d2 | |||
69f687a85f | |||
2aa19d1dca | |||
e44a25dcc3 | |||
efb5ffa906 | |||
b4c586a859 | |||
e874143a95 | |||
e4dbab8b16 | |||
f6d7d6f90c | |||
063c90caf4 | |||
2011c2eee7 | |||
24545f2acd | |||
a7c81245ff | |||
4f2c993b2d | |||
e5f8e500c1 | |||
a61e2de140 | |||
881d2b060e | |||
4830c6d219 | |||
4c3c9ac88c | |||
7e1c610a4d | |||
8139f495ce | |||
89ab296151 | |||
a0dc92c403 | |||
86134f478a | |||
9a2addc18e | |||
9264ce2a60 | |||
cbd69df708 | |||
ca7caa25b6 | |||
c10330627f | |||
d80c59afce | |||
abdbb67471 | |||
037a97b6ff | |||
a0a529ad38 | |||
72239558af | |||
d2097ad6dd | |||
1bd542cddb | |||
fb1c1ee874 | |||
624a7a8f37 | |||
381378f532 | |||
af05486c0e | |||
4b558948d9 | |||
d9cff42f5c | |||
2a3d2b8d0d | |||
d0f453d291 | |||
8e65dd0eae | |||
da4d0b28c7 | |||
6c96ef7fb0 | |||
997f09adde | |||
0e8503ed2b | |||
97dfcd79b1 | |||
9a12a2e41f | |||
5c114e562b | |||
ae696a0be0 | |||
22d46a5dcc | |||
f3125ff464 | |||
9682b548e6 | |||
2e0c60cc0d |
@ -1,11 +1,12 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
|
||||||
# Avoid commits to the master branch
|
# Using `--silent` helps for showing any errs in the first line of the response
|
||||||
BRANCH=`git rev-parse --abbrev-ref HEAD`
|
# The first line is picked up by the VS Code GIT UI popup when rc is not 0
|
||||||
REGEX="^(master|development)$"
|
|
||||||
|
|
||||||
if [[ "$BRANCH" =~ $REGEX ]]; then
|
if npm run --silent lint:silent ; then
|
||||||
echo "You are on branch $BRANCH. Are you sure you want to commit to this branch?"
|
exit 0
|
||||||
echo "If so, commit with -n to bypass the pre-commit hook."
|
else
|
||||||
exit 1
|
npm run --silent lint:fix
|
||||||
|
echo "❌ Prettier check failed! We ran lint:fix for you. Please add & commit again."
|
||||||
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
@ -237,20 +237,20 @@ jobs:
|
|||||||
cd sas
|
cd sas
|
||||||
sasjs c -t viya
|
sasjs c -t viya
|
||||||
rm -rf sasjsbuild/tests
|
rm -rf sasjsbuild/tests
|
||||||
sed -i -e 's/servertype="SASJS"/servertype="SASVIYA"/g' sasjsbuild/services/clickme.html
|
sed -i -e 's/servertype="SASJS"/servertype="SASVIYA"/g' sasjsbuild/services/DC.html
|
||||||
sasjs b -t viya
|
|
||||||
cp sasjsbuild/viya.sas ./demostream_viya.sas
|
|
||||||
# compile Viya Full deploy (without web)
|
|
||||||
rm -rf sasjsbuild/services/web
|
|
||||||
rm sasjsbuild/services/clickme.html
|
|
||||||
sasjs b -t viya
|
sasjs b -t viya
|
||||||
cp sasjsbuild/viya.sas ./viya.sas
|
cp sasjsbuild/viya.sas ./viya.sas
|
||||||
cp sasjsbuild/viya.json ./viya.json
|
# compile Viya Full deploy (without web)
|
||||||
|
rm -rf sasjsbuild/services/web
|
||||||
|
rm sasjsbuild/services/DC.html
|
||||||
|
sasjs b -t viya
|
||||||
|
cp sasjsbuild/viya.sas ./viya_noweb.sas
|
||||||
|
cp sasjsbuild/viya.json ./viya_noweb.json
|
||||||
|
|
||||||
- name: Zip Frontend (including viya.json for full viya deploy)
|
- name: Zip Frontend (including viya.json for full viya deploy)
|
||||||
run: |
|
run: |
|
||||||
cd sas
|
cd sas
|
||||||
cp sasjsbuild/viya.json ../client/dist
|
cp sasjsbuild/viya.json ../client/dist/viya.json
|
||||||
cd ..
|
cd ..
|
||||||
zip -r frontend.zip ./client/dist
|
zip -r frontend.zip ./client/dist
|
||||||
|
|
||||||
@ -277,8 +277,8 @@ jobs:
|
|||||||
URL="https://git.datacontroller.io/api/v1/repos/dc/dc/releases/$RELEASE_ID/assets?access_token=${{ secrets.RELEASE_TOKEN }}"
|
URL="https://git.datacontroller.io/api/v1/repos/dc/dc/releases/$RELEASE_ID/assets?access_token=${{ secrets.RELEASE_TOKEN }}"
|
||||||
curl -k $URL -F attachment=@frontend.zip
|
curl -k $URL -F attachment=@frontend.zip
|
||||||
curl -k $URL -F attachment=@sas/demostream_sas9.sas
|
curl -k $URL -F attachment=@sas/demostream_sas9.sas
|
||||||
curl -k $URL -F attachment=@sas/demostream_viya.sas
|
curl -k $URL -F attachment=@sas/viya.sas
|
||||||
curl -k $URL -F attachment=@sas/sasjs_server.json.zip
|
curl -k $URL -F attachment=@sas/sasjs_server.json.zip
|
||||||
curl -k $URL -F attachment=@sas/sas9.sas
|
curl -k $URL -F attachment=@sas/sas9.sas
|
||||||
curl -k $URL -F attachment=@sas/viya.sas
|
curl -k $URL -F attachment=@sas/viya_noweb.sas
|
||||||
curl -k $URL -F attachment=@sas/viya.json
|
curl -k $URL -F attachment=@sas/viya_noweb.json
|
||||||
|
95
CHANGELOG.md
95
CHANGELOG.md
@ -1,3 +1,98 @@
|
|||||||
|
# [7.0.0](https://git.datacontroller.io/dc/dc/compare/v6.16.2...v7.0.0) (2025-06-11)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* bumping adapter to re-enable JES API method ([e874143](https://git.datacontroller.io/dc/dc/commit/e874143a95d0ac2e56c0793e04b979c27f96d74b))
|
||||||
|
* commit git hooks checking lint ([69f687a](https://git.datacontroller.io/dc/dc/commit/69f687a85f1cc562346b6167813d617cb9bd3404))
|
||||||
|
* ensuring apploc is not case sensitive. Closes [#171](https://git.datacontroller.io/dc/dc/issues/171) ([24545f2](https://git.datacontroller.io/dc/dc/commit/24545f2acdd5bd73cbe062526f2bd043269cc6a3))
|
||||||
|
* export unregistered formats ([f6d7d6f](https://git.datacontroller.io/dc/dc/commit/f6d7d6f90c978ac8c071471dfb67a60834424de5)), closes [#158](https://git.datacontroller.io/dc/dc/issues/158)
|
||||||
|
* reload startupservice after user approves the MPE_TABLES page ([e5f8e50](https://git.datacontroller.io/dc/dc/commit/e5f8e500c125ee233c6f7af5ad0077c0ed6abfcb))
|
||||||
|
* showing catalog_cnt in libinfo ([e44a25d](https://git.datacontroller.io/dc/dc/commit/e44a25dcc39ba4b9714257c60da84c2dfa613a85)), closes [#160](https://git.datacontroller.io/dc/dc/issues/160)
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* adding 4 new tables for catalogs ([e4dbab8](https://git.datacontroller.io/dc/dc/commit/e4dbab8b1654b24e610e4b0603d1cf2b02a451e2))
|
||||||
|
* capturing catalog specific information, closes [#159](https://git.datacontroller.io/dc/dc/issues/159) ([b4c586a](https://git.datacontroller.io/dc/dc/commit/b4c586a859929e0122cd46449e43d4ca597b8b2b))
|
||||||
|
* viewer added catalog_cnt ([2aa19d1](https://git.datacontroller.io/dc/dc/commit/2aa19d1dca747f41274a032cde78d8ba73d66224))
|
||||||
|
|
||||||
|
|
||||||
|
### BREAKING CHANGES
|
||||||
|
|
||||||
|
* Introduction of 4 new tables for capturing information related to catalogs and their objects. Migration script prepared and available in the DB folder (usual place)
|
||||||
|
|
||||||
|
## [6.16.2](https://git.datacontroller.io/dc/dc/compare/v6.16.1...v6.16.2) (2025-06-06)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* streaming viya deploy `isStreaming` function stability fix ([4830c6d](https://git.datacontroller.io/dc/dc/commit/4830c6d2191cb47abcc7919bc1d49e55595e6121))
|
||||||
|
|
||||||
|
## [6.16.1](https://git.datacontroller.io/dc/dc/compare/v6.16.0...v6.16.1) (2025-06-06)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* viya deploy updating index html based on URL ([86134f4](https://git.datacontroller.io/dc/dc/commit/86134f478ae0b9426e01bfcc9ca4ee597ca733f7))
|
||||||
|
* viya streamed app deploy page flow fix ([89ab296](https://git.datacontroller.io/dc/dc/commit/89ab2961513b245eeea48d1867c6496d3261761e))
|
||||||
|
|
||||||
|
# [6.16.0](https://git.datacontroller.io/dc/dc/compare/v6.15.2...v6.16.0) (2025-06-05)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* adapter bump ([ca7caa2](https://git.datacontroller.io/dc/dc/commit/ca7caa25b6eea1bd4579fb8b67ec9b211a893079))
|
||||||
|
* automatic viya deploy timing issue ([037a97b](https://git.datacontroller.io/dc/dc/commit/037a97b6ffa27b40891531ae6812ebe5b5e71e34))
|
||||||
|
* bump core to ensure ff works on viya streaming deploy ([cbd69df](https://git.datacontroller.io/dc/dc/commit/cbd69df708edf3a8446115ca7315fac3557dcf97)), closes [#156](https://git.datacontroller.io/dc/dc/issues/156)
|
||||||
|
* viya deploy load data timing ([abdbb67](https://git.datacontroller.io/dc/dc/commit/abdbb674713796e5308eb4272197a5c253868a85))
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* viya deploy, update the index.html contextname ([7223955](https://git.datacontroller.io/dc/dc/commit/72239558af2ee50cdfc71b7e185e6661ab568ba1))
|
||||||
|
|
||||||
|
## [6.15.2](https://git.datacontroller.io/dc/dc/compare/v6.15.1...v6.15.2) (2025-06-04)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* pipeline updates for DC.html ([624a7a8](https://git.datacontroller.io/dc/dc/commit/624a7a8f37f0265cf576da310ac330c75aa417cf))
|
||||||
|
|
||||||
|
## [6.15.1](https://git.datacontroller.io/dc/dc/compare/v6.15.0...v6.15.1) (2025-06-04)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* updating pipeline to default to streaming on viya ([4b55894](https://git.datacontroller.io/dc/dc/commit/4b558948d997f456ff25a12a58827fe0d2075493))
|
||||||
|
|
||||||
|
# [6.15.0](https://git.datacontroller.io/dc/dc/compare/v6.14.10...v6.15.0) (2025-06-04)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* makedata with context name ([da4d0b2](https://git.datacontroller.io/dc/dc/commit/da4d0b28c7109afd6f96455e1e0e80a40d25a942))
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* viya deploy context ([6c96ef7](https://git.datacontroller.io/dc/dc/commit/6c96ef7fb0a55754a84ff0a8bbab838b78c1acaf))
|
||||||
|
|
||||||
|
## [6.14.10](https://git.datacontroller.io/dc/dc/compare/v6.14.9...v6.14.10) (2025-06-02)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* bump core ([0e8503e](https://git.datacontroller.io/dc/dc/commit/0e8503ed2bb22a0fc3924ac929e7f19626772e0a))
|
||||||
|
* default to home directory for SAS Drive in Viya ([9682b54](https://git.datacontroller.io/dc/dc/commit/9682b548e6106d99d97dcc023a35d93addfd5170))
|
||||||
|
|
||||||
|
## [6.14.9](https://git.datacontroller.io/dc/dc/compare/v6.14.8...v6.14.9) (2025-06-02)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* default DC path for viya ([f3125ff](https://git.datacontroller.io/dc/dc/commit/f3125ff4641e47e33cb203228f5b1014ea3343bc))
|
||||||
|
|
||||||
## [6.14.8](https://git.datacontroller.io/dc/dc/compare/v6.14.7...v6.14.8) (2025-05-28)
|
## [6.14.8](https://git.datacontroller.io/dc/dc/compare/v6.14.7...v6.14.8) (2025-05-28)
|
||||||
|
|
||||||
|
|
||||||
|
11
README.md
11
README.md
@ -23,7 +23,16 @@ _Problems with the above include:_
|
|||||||
|
|
||||||
Data Controller for SAS® solves all these issues in a simple-to-install, user-friendly, secure, documented, battle-tested web application. Available on Viya, SAS 9 EBI, and [SASjs Server](https://server.sasjs.io).
|
Data Controller for SAS® solves all these issues in a simple-to-install, user-friendly, secure, documented, battle-tested web application. Available on Viya, SAS 9 EBI, and [SASjs Server](https://server.sasjs.io).
|
||||||
|
|
||||||
For more information:
|
An individual Viya deploy can be done in just 2 lines of #SAS code!
|
||||||
|
|
||||||
|
```sas
|
||||||
|
filename dc url "https://git.datacontroller.io/dc/dc/releases/download/latest/viya.sas";
|
||||||
|
%inc dc;
|
||||||
|
```
|
||||||
|
|
||||||
|
For a multi-user deploy, using a shared system account, please see [deploy docs](https://docs.datacontroller.io/deploy-viya/).
|
||||||
|
|
||||||
|
For further information:
|
||||||
|
|
||||||
* Main site: https://datacontroller.io
|
* Main site: https://datacontroller.io
|
||||||
* Docs: https://docs.datacontroller.io
|
* Docs: https://docs.datacontroller.io
|
||||||
|
8
client/package-lock.json
generated
8
client/package-lock.json
generated
@ -21,7 +21,7 @@
|
|||||||
"@clr/icons": "^13.0.2",
|
"@clr/icons": "^13.0.2",
|
||||||
"@clr/ui": "file:libraries/clr-ui-17.9.0.tgz",
|
"@clr/ui": "file:libraries/clr-ui-17.9.0.tgz",
|
||||||
"@handsontable/angular": "^15.3.0",
|
"@handsontable/angular": "^15.3.0",
|
||||||
"@sasjs/adapter": "^4.11.0",
|
"@sasjs/adapter": "^4.12.1",
|
||||||
"@sasjs/utils": "^3.4.0",
|
"@sasjs/utils": "^3.4.0",
|
||||||
"@sheet/crypto": "file:libraries/sheet-crypto.tgz",
|
"@sheet/crypto": "file:libraries/sheet-crypto.tgz",
|
||||||
"@types/d3-graphviz": "^2.6.7",
|
"@types/d3-graphviz": "^2.6.7",
|
||||||
@ -5912,9 +5912,9 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"node_modules/@sasjs/adapter": {
|
"node_modules/@sasjs/adapter": {
|
||||||
"version": "4.11.3",
|
"version": "4.12.1",
|
||||||
"resolved": "https://registry.npmjs.org/@sasjs/adapter/-/adapter-4.11.3.tgz",
|
"resolved": "https://registry.npmjs.org/@sasjs/adapter/-/adapter-4.12.1.tgz",
|
||||||
"integrity": "sha512-KF6G4vzs4l4efjpCD02og3kB44uFfJ1u2UWu749VdHtLKNN9l+PO26/moR+YAmRmmz2I9sC3X09fZE1nlN6zgw==",
|
"integrity": "sha512-0217oZIkrecOyQygRe6Azgc1C4TIcjB5noi15fU4Rd5GsfDpleKVfQQdzYZ7im/vesWlLIVl/yUT67MMaQe0ew==",
|
||||||
"hasInstallScript": true,
|
"hasInstallScript": true,
|
||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
@ -49,7 +49,7 @@
|
|||||||
"@clr/icons": "^13.0.2",
|
"@clr/icons": "^13.0.2",
|
||||||
"@clr/ui": "file:libraries/clr-ui-17.9.0.tgz",
|
"@clr/ui": "file:libraries/clr-ui-17.9.0.tgz",
|
||||||
"@handsontable/angular": "^15.3.0",
|
"@handsontable/angular": "^15.3.0",
|
||||||
"@sasjs/adapter": "^4.11.0",
|
"@sasjs/adapter": "^4.12.1",
|
||||||
"@sasjs/utils": "^3.4.0",
|
"@sasjs/utils": "^3.4.0",
|
||||||
"@sheet/crypto": "file:libraries/sheet-crypto.tgz",
|
"@sheet/crypto": "file:libraries/sheet-crypto.tgz",
|
||||||
"@types/d3-graphviz": "^2.6.7",
|
"@types/d3-graphviz": "^2.6.7",
|
||||||
|
@ -98,14 +98,14 @@
|
|||||||
|
|
||||||
<label for="dcloc" class="mt-20 clr-control-label">DC Loc</label>
|
<label for="dcloc" class="mt-20 clr-control-label">DC Loc</label>
|
||||||
<div class="mb-10 clr-control-container dc-loc-input-wrapper">
|
<div class="mb-10 clr-control-container dc-loc-input-wrapper">
|
||||||
<div class="clr-input-wrapper">
|
<div class="clr-input-wrapper small-mt">
|
||||||
<input clrInput name="dcloc" [(ngModel)]="dcPath" />
|
<input clrInput name="dcloc" [(ngModel)]="dcPath" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<label for="dcloc" class="mt-20 clr-control-label">SAS Admin group</label>
|
<label for="dcloc" class="mt-20 clr-control-label">SAS Admin group</label>
|
||||||
<div class="mb-10 clr-control-container">
|
<div class="mb-10 clr-control-container">
|
||||||
<div class="clr-input-wrapper">
|
<div class="clr-input-wrapper small-mt">
|
||||||
<select
|
<select
|
||||||
*ngIf="!adminGroupsLoading"
|
*ngIf="!adminGroupsLoading"
|
||||||
clrSelect
|
clrSelect
|
||||||
@ -124,6 +124,42 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<label for="computeContext" class="mt-20 clr-control-label"
|
||||||
|
>Compute Context</label
|
||||||
|
>
|
||||||
|
<div class="mb-10 clr-control-container">
|
||||||
|
<div class="clr-input-wrapper small-mt">
|
||||||
|
<select
|
||||||
|
*ngIf="!computeContextsLoading"
|
||||||
|
clrSelect
|
||||||
|
name="options"
|
||||||
|
(ngModelChange)="onComputeContextChange($event)"
|
||||||
|
[(ngModel)]="selectedComputeContext"
|
||||||
|
>
|
||||||
|
<option
|
||||||
|
*ngFor="let computeContext of computeContexts"
|
||||||
|
[value]="computeContext.id"
|
||||||
|
>
|
||||||
|
{{ computeContext.name }}
|
||||||
|
</option>
|
||||||
|
</select>
|
||||||
|
<clr-spinner
|
||||||
|
clrInline
|
||||||
|
class="spinner-sm"
|
||||||
|
*ngIf="computeContextsLoading"
|
||||||
|
></clr-spinner>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<ng-container *ngIf="runningAsUser">
|
||||||
|
<label for="dcloc" class="mt-20 clr-control-label">Running as user:</label>
|
||||||
|
<div class="mb-10 clr-control-container">
|
||||||
|
<div class="clr-input-wrapper">
|
||||||
|
<p class="mt-0">{{ runningAsUser }}</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</ng-container>
|
||||||
|
|
||||||
<!-- Keeping this for a reference in case future VIYA changes and starts allowing separate backend and frontend) -->
|
<!-- Keeping this for a reference in case future VIYA changes and starts allowing separate backend and frontend) -->
|
||||||
|
|
||||||
<!-- <clr-checkbox-wrapper>
|
<!-- <clr-checkbox-wrapper>
|
||||||
|
@ -8,15 +8,22 @@ import {
|
|||||||
} from '@angular/core'
|
} from '@angular/core'
|
||||||
import SASjs, { SASjsConfig } from '@sasjs/adapter'
|
import SASjs, { SASjsConfig } from '@sasjs/adapter'
|
||||||
import { DcAdapterSettings } from 'src/app/models/DcAdapterSettings'
|
import { DcAdapterSettings } from 'src/app/models/DcAdapterSettings'
|
||||||
|
import { HelperService } from 'src/app/services'
|
||||||
import { DeployService } from 'src/app/services/deploy.service'
|
import { DeployService } from 'src/app/services/deploy.service'
|
||||||
import { EventService } from 'src/app/services/event.service'
|
import { EventService } from 'src/app/services/event.service'
|
||||||
import { LoggerService } from 'src/app/services/logger.service'
|
import { LoggerService } from 'src/app/services/logger.service'
|
||||||
import { SasViyaService } from 'src/app/services/sas-viya.service'
|
import { SasViyaService } from 'src/app/services/sas-viya.service'
|
||||||
import { SasService } from 'src/app/services/sas.service'
|
import { SasService } from 'src/app/services/sas.service'
|
||||||
|
import { ViyaApiCurrentUser } from 'src/app/viya-api-explorer/models/viya-api-current-user.model'
|
||||||
import {
|
import {
|
||||||
Item,
|
Item,
|
||||||
ViyaApiIdentities
|
ViyaApiIdentities
|
||||||
} from 'src/app/viya-api-explorer/models/viya-api-identities.model'
|
} from 'src/app/viya-api-explorer/models/viya-api-identities.model'
|
||||||
|
import { ComputeContextDetails } from 'src/app/viya-api-explorer/models/viya-compute-context-details.model'
|
||||||
|
import {
|
||||||
|
ViyaComputeContexts,
|
||||||
|
Item as ComputeContextItem
|
||||||
|
} from 'src/app/viya-api-explorer/models/viya-compute-contexts.model'
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-automatic-deploy',
|
selector: 'app-automatic-deploy',
|
||||||
@ -34,6 +41,7 @@ export class AutomaticComponent implements OnInit {
|
|||||||
|
|
||||||
@Output() onNavigateToHome: EventEmitter<any> = new EventEmitter<any>()
|
@Output() onNavigateToHome: EventEmitter<any> = new EventEmitter<any>()
|
||||||
|
|
||||||
|
public selectedComputeContext: string = ''
|
||||||
public makeDataResponse: string = ''
|
public makeDataResponse: string = ''
|
||||||
public jsonFile: any = null
|
public jsonFile: any = null
|
||||||
public autodeploying: boolean = false
|
public autodeploying: boolean = false
|
||||||
@ -48,7 +56,12 @@ export class AutomaticComponent implements OnInit {
|
|||||||
public recreateDatabase: boolean = true
|
public recreateDatabase: boolean = true
|
||||||
public createDatabaseLoading: boolean = false
|
public createDatabaseLoading: boolean = false
|
||||||
public adminGroupsLoading: boolean = false
|
public adminGroupsLoading: boolean = false
|
||||||
|
public currentUserInfoLoading: boolean = false
|
||||||
|
public computeContextsLoading: boolean = false
|
||||||
public adminGroups: { id: string; name: string }[] = []
|
public adminGroups: { id: string; name: string }[] = []
|
||||||
|
public runningAsUser: string | undefined
|
||||||
|
public currentUserInfo: ViyaApiCurrentUser | null = null
|
||||||
|
public computeContexts: ComputeContextItem[] = []
|
||||||
|
|
||||||
/** autoDeployStatus
|
/** autoDeployStatus
|
||||||
* This object presents the status for two steps that we have for deploy.
|
* This object presents the status for two steps that we have for deploy.
|
||||||
@ -70,31 +83,122 @@ export class AutomaticComponent implements OnInit {
|
|||||||
private deployService: DeployService,
|
private deployService: DeployService,
|
||||||
private sasService: SasService,
|
private sasService: SasService,
|
||||||
private sasViyaService: SasViyaService,
|
private sasViyaService: SasViyaService,
|
||||||
private loggerService: LoggerService
|
private loggerService: LoggerService,
|
||||||
|
private helperService: HelperService
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
this.getAdminGroups()
|
this.loadData()
|
||||||
|
}
|
||||||
|
|
||||||
|
public async loadData() {
|
||||||
|
await this.getAdminGroups()
|
||||||
|
await this.getComputeContexts()
|
||||||
|
await this.getCurrentUser()
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
if (this.selectedComputeContext) {
|
||||||
|
this.onComputeContextChange(this.selectedComputeContext)
|
||||||
|
}
|
||||||
|
}, 500)
|
||||||
|
}
|
||||||
|
|
||||||
|
public async getComputeContexts() {
|
||||||
|
return new Promise<void>((resolve, reject) => {
|
||||||
|
this.computeContextsLoading = true
|
||||||
|
|
||||||
|
this.sasViyaService.getComputeContexts().subscribe(
|
||||||
|
(res: ViyaComputeContexts) => {
|
||||||
|
this.computeContextsLoading = false
|
||||||
|
|
||||||
|
const defaultContext = res.items.find(
|
||||||
|
(item: ComputeContextItem) =>
|
||||||
|
item.name === 'SAS Job Execution compute context'
|
||||||
|
)
|
||||||
|
|
||||||
|
if (defaultContext) {
|
||||||
|
this.selectedComputeContext = defaultContext.id
|
||||||
|
}
|
||||||
|
|
||||||
|
this.computeContexts = res.items
|
||||||
|
|
||||||
|
resolve()
|
||||||
|
},
|
||||||
|
(err) => {
|
||||||
|
reject(err)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
public async getCurrentUser() {
|
||||||
|
return new Promise<void>((resolve, reject) => {
|
||||||
|
this.currentUserInfoLoading = true
|
||||||
|
|
||||||
|
this.sasViyaService.getCurrentUser().subscribe(
|
||||||
|
(res: ViyaApiCurrentUser) => {
|
||||||
|
this.currentUserInfoLoading = false
|
||||||
|
|
||||||
|
this.currentUserInfo = res
|
||||||
|
|
||||||
|
this.dcPath = `/export/viya/homes/${res.id}`
|
||||||
|
|
||||||
|
resolve()
|
||||||
|
},
|
||||||
|
(err) => {
|
||||||
|
console.error('Error while getting current user', err)
|
||||||
|
reject(err)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
public async getAdminGroups() {
|
public async getAdminGroups() {
|
||||||
this.adminGroupsLoading = true
|
return new Promise<void>((resolve, reject) => {
|
||||||
|
this.adminGroupsLoading = true
|
||||||
|
|
||||||
this.sasViyaService.getAdminGroups().subscribe((res: ViyaApiIdentities) => {
|
this.sasViyaService
|
||||||
this.adminGroupsLoading = false
|
.getAdminGroups()
|
||||||
// Map admin groups with only needed fields
|
.subscribe((res: ViyaApiIdentities) => {
|
||||||
this.adminGroups = res.items.map((item: Item) => {
|
this.adminGroupsLoading = false
|
||||||
return {
|
// Map admin groups with only needed fields
|
||||||
id: item.id,
|
this.adminGroups = res.items.map((item: Item) => {
|
||||||
name: item.name
|
return {
|
||||||
|
id: item.id,
|
||||||
|
name: item.name
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
resolve()
|
||||||
|
}),
|
||||||
|
(err: any) => {
|
||||||
|
this.adminGroupsLoading = false
|
||||||
|
this.loggerService.error('Error while getting admin groups', err)
|
||||||
|
this.eventService.showAbortModal('admin groups', err)
|
||||||
|
|
||||||
|
reject(err)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
public async onComputeContextChange(computeContextId: string) {
|
||||||
|
this.sasViyaService
|
||||||
|
.getComputeContextById(computeContextId)
|
||||||
|
.subscribe((res: ComputeContextDetails) => {
|
||||||
|
if (res.attributes && res.attributes.runServerAs) {
|
||||||
|
this.runningAsUser = res.attributes.runServerAs
|
||||||
|
} else {
|
||||||
|
this.runningAsUser = this.currentUserInfo?.id || 'unknown'
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}),
|
}
|
||||||
(err: any) => {
|
|
||||||
this.adminGroupsLoading = false
|
public getComputeContextName(id: string): string | undefined {
|
||||||
this.loggerService.error('Error while getting admin groups', err)
|
return (
|
||||||
this.eventService.showAbortModal('admin groups', err)
|
this.computeContexts.find(
|
||||||
}
|
(context: ComputeContextItem) => context.id === id
|
||||||
|
)?.name || undefined
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -168,6 +272,19 @@ export class AutomaticComponent implements OnInit {
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Get and run service using the selected context name
|
||||||
|
let selectedComputeContextName = this.sasJsConfig.contextName
|
||||||
|
|
||||||
|
if (this.selectedComputeContext.length && this.computeContexts.length) {
|
||||||
|
const computeContextName = this.getComputeContextName(
|
||||||
|
this.selectedComputeContext
|
||||||
|
)
|
||||||
|
|
||||||
|
if (computeContextName) {
|
||||||
|
selectedComputeContextName = computeContextName
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* We are overriding default `sasjsConfig` object fields with this object fields.
|
* We are overriding default `sasjsConfig` object fields with this object fields.
|
||||||
* Here we want to run this request using original WEB method.
|
* Here we want to run this request using original WEB method.
|
||||||
@ -175,7 +292,7 @@ export class AutomaticComponent implements OnInit {
|
|||||||
*/
|
*/
|
||||||
let overrideConfig = {
|
let overrideConfig = {
|
||||||
useComputeApi: null,
|
useComputeApi: null,
|
||||||
contextName: this.sasJsConfig.contextName,
|
contextName: selectedComputeContextName,
|
||||||
debug: true
|
debug: true
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -209,6 +326,9 @@ export class AutomaticComponent implements OnInit {
|
|||||||
MAC: macMsg
|
MAC: macMsg
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (this.helperService.isStreamingViya())
|
||||||
|
this.updateIndexHtmlComputeContext()
|
||||||
})
|
})
|
||||||
.catch((err: any) => {
|
.catch((err: any) => {
|
||||||
this.eventService.showAbortModal('makedata', JSON.stringify(err))
|
this.eventService.showAbortModal('makedata', JSON.stringify(err))
|
||||||
@ -223,6 +343,57 @@ export class AutomaticComponent implements OnInit {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Only when on Viya streamed app, this method will update the `contextname` in the `index.html` on the SAS drive
|
||||||
|
* This is needed to ensure that the DC will use the same compute context `makedata` service used to run against.
|
||||||
|
*/
|
||||||
|
public async updateIndexHtmlComputeContext() {
|
||||||
|
const filenamePath = location.search.split('/').pop()
|
||||||
|
const filename = filenamePath?.includes('.') ? filenamePath : undefined
|
||||||
|
|
||||||
|
if (!filename) {
|
||||||
|
this.eventService.showAbortModal(
|
||||||
|
null,
|
||||||
|
'We could not figure out the file name of `index.html` based on the url.'
|
||||||
|
)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
const indexHtmlContent = await this.sasService.getFileContent(
|
||||||
|
`${this.appLoc}/services`,
|
||||||
|
filename
|
||||||
|
)
|
||||||
|
|
||||||
|
if (!indexHtmlContent) {
|
||||||
|
this.loggerService.error(
|
||||||
|
`Failed to get ${filename} at ${this.appLoc}/services`
|
||||||
|
)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
const computeContextName = this.getComputeContextName(
|
||||||
|
this.selectedComputeContext
|
||||||
|
)
|
||||||
|
|
||||||
|
if (!computeContextName) {
|
||||||
|
this.loggerService.error(
|
||||||
|
`Compute context name not found for ID: ${this.selectedComputeContext} | List: ${JSON.stringify(this.computeContexts)}`
|
||||||
|
)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
const updatedContent = indexHtmlContent.replace(
|
||||||
|
/contextname="[^"]*"/g,
|
||||||
|
`contextname="${computeContextName}"`
|
||||||
|
)
|
||||||
|
|
||||||
|
await this.sasService
|
||||||
|
.updateFileContent(`${this.appLoc}/services`, filename, updatedContent)
|
||||||
|
.catch((err: any) => {
|
||||||
|
this.loggerService.error(`Failed to update DataController.html: ${err}`)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
public downloadFile(
|
public downloadFile(
|
||||||
content: any,
|
content: any,
|
||||||
filename: string,
|
filename: string,
|
||||||
|
@ -8,4 +8,5 @@ export interface Libinfo {
|
|||||||
LIBID: string
|
LIBID: string
|
||||||
LIBSIZE: number
|
LIBSIZE: number
|
||||||
TABLE_CNT: number
|
TABLE_CNT: number
|
||||||
|
CATALOG_CNT: number
|
||||||
}
|
}
|
||||||
|
@ -1,30 +1,14 @@
|
|||||||
import { BaseSASResponse } from './common/BaseSASResponse'
|
import { BaseSASResponse } from './common/BaseSASResponse'
|
||||||
|
|
||||||
export interface EditorsStageDataSASResponse extends BaseSASResponse {
|
export interface EditorsStageDataSASResponse extends BaseSASResponse {
|
||||||
SYSDATE: string
|
|
||||||
SYSTIME: string
|
|
||||||
sasparams: Sasparam[]
|
sasparams: Sasparam[]
|
||||||
_DEBUG: string
|
|
||||||
_PROGRAM: string
|
|
||||||
AUTOEXEC: string
|
AUTOEXEC: string
|
||||||
MF_GETUSER: string
|
|
||||||
SYSCC: string
|
|
||||||
SYSENCODING: string
|
SYSENCODING: string
|
||||||
SYSERRORTEXT: string
|
|
||||||
SYSHOSTINFOLONG: string
|
SYSHOSTINFOLONG: string
|
||||||
SYSHOSTNAME: string
|
|
||||||
SYSPROCESSID: string
|
SYSPROCESSID: string
|
||||||
SYSPROCESSMODE: string
|
SYSPROCESSMODE: string
|
||||||
SYSPROCESSNAME: string
|
SYSPROCESSNAME: string
|
||||||
SYSJOBID: string
|
|
||||||
SYSSCPL: string
|
|
||||||
SYSSITE: string
|
|
||||||
SYSTCPIPHOSTNAME: string
|
SYSTCPIPHOSTNAME: string
|
||||||
SYSUSERID: string
|
|
||||||
SYSVLONG: string
|
|
||||||
SYSWARNINGTEXT: string
|
|
||||||
END_DTTM: string
|
|
||||||
MEMSIZE: string
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface Sasparam {
|
export interface Sasparam {
|
||||||
|
28
client/src/app/models/sas/public-getchangeinfo.model.ts
Normal file
28
client/src/app/models/sas/public-getchangeinfo.model.ts
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
import { BaseSASResponse } from './common/BaseSASResponse'
|
||||||
|
|
||||||
|
export interface PublicGetChangeinfo extends BaseSASResponse {
|
||||||
|
jsparams: Jsparam[]
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface Jsparam {
|
||||||
|
TABLE_ID: string
|
||||||
|
SUBMIT_STATUS_CD: string
|
||||||
|
BASE_LIB: string
|
||||||
|
BASE_DS: string
|
||||||
|
SUBMITTED_BY_NM: string
|
||||||
|
SUBMITTED_ON: number
|
||||||
|
SUBMITTED_REASON_TXT: string
|
||||||
|
INPUT_OBS: number
|
||||||
|
INPUT_VARS: number
|
||||||
|
NUM_OF_APPROVALS_REQUIRED: number
|
||||||
|
NUM_OF_APPROVALS_REMAINING: number
|
||||||
|
REVIEWED_BY_NM: string
|
||||||
|
REVIEWED_ON?: any
|
||||||
|
TABLE_NM: string
|
||||||
|
BASE_TABLE: string
|
||||||
|
REVIEWED_ON_DTTM: string
|
||||||
|
SUBMITTED_ON_DTTM: string
|
||||||
|
LIB_ENGINE: string
|
||||||
|
ALLOW_RESTORE: string
|
||||||
|
REASON: string
|
||||||
|
}
|
@ -13,6 +13,8 @@ import {
|
|||||||
AuditorsPostdataSASResponse,
|
AuditorsPostdataSASResponse,
|
||||||
Param
|
Param
|
||||||
} from '../../models/sas/auditors-postdata.model'
|
} from '../../models/sas/auditors-postdata.model'
|
||||||
|
import { PublicGetChangeinfo } from 'src/app/models/sas/public-getchangeinfo.model'
|
||||||
|
import { SasService } from 'src/app/services'
|
||||||
|
|
||||||
interface ChangesObj {
|
interface ChangesObj {
|
||||||
ind: any
|
ind: any
|
||||||
@ -76,9 +78,11 @@ export class ApproveDetailsComponent implements AfterViewInit, OnDestroy {
|
|||||||
|
|
||||||
public diffsLimit: boolean = false
|
public diffsLimit: boolean = false
|
||||||
public recordsLimit: number = 100
|
public recordsLimit: number = 100
|
||||||
|
public refreshStartupserviceAfterApprove: boolean = false
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private sasStoreService: SasStoreService,
|
private sasStoreService: SasStoreService,
|
||||||
|
private sasService: SasService,
|
||||||
private eventService: EventService,
|
private eventService: EventService,
|
||||||
private router: ActivatedRoute,
|
private router: ActivatedRoute,
|
||||||
private route: Router
|
private route: Router
|
||||||
@ -162,6 +166,9 @@ export class ApproveDetailsComponent implements AfterViewInit, OnDestroy {
|
|||||||
await this.sasStoreService
|
await this.sasStoreService
|
||||||
.approveTable(approveParams, 'SASControlTable', 'auditors/postdata')
|
.approveTable(approveParams, 'SASControlTable', 'auditors/postdata')
|
||||||
.then((res: any) => {
|
.then((res: any) => {
|
||||||
|
// If we are approving MPE_TABLES we will arm the trigger for the reload of startup data to se the updated tables
|
||||||
|
if (this.refreshStartupserviceAfterApprove)
|
||||||
|
this.sasService.reloadStartupData()
|
||||||
this.route.navigateByUrl('/review/history')
|
this.route.navigateByUrl('/review/history')
|
||||||
})
|
})
|
||||||
.catch((err: any) => {
|
.catch((err: any) => {
|
||||||
@ -176,7 +183,7 @@ export class ApproveDetailsComponent implements AfterViewInit, OnDestroy {
|
|||||||
public async callChangesInfo(tableId: any) {
|
public async callChangesInfo(tableId: any) {
|
||||||
await this.sasStoreService
|
await this.sasStoreService
|
||||||
.getChangeInfo(tableId)
|
.getChangeInfo(tableId)
|
||||||
.then((res: any) => {
|
.then((res: PublicGetChangeinfo) => {
|
||||||
this.tableDetails = res.jsparams[0]
|
this.tableDetails = res.jsparams[0]
|
||||||
this.jsParams = res.jsparams[0]
|
this.jsParams = res.jsparams[0]
|
||||||
|
|
||||||
@ -189,6 +196,11 @@ export class ApproveDetailsComponent implements AfterViewInit, OnDestroy {
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.keysArray = keysArray
|
this.keysArray = keysArray
|
||||||
|
|
||||||
|
// If we are approving MPE_TABLES we will arm the trigger for the reload of startup data to se the updated tables
|
||||||
|
// After user approved if armed, reload will be triggered
|
||||||
|
if (res.jsparams[0].BASE_DS === 'MPE_TABLES')
|
||||||
|
this.refreshStartupserviceAfterApprove = true
|
||||||
})
|
})
|
||||||
.catch((err: any) => {
|
.catch((err: any) => {
|
||||||
this.acceptLoading = false
|
this.acceptLoading = false
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import { Injectable } from '@angular/core'
|
import { Injectable } from '@angular/core'
|
||||||
import cloneDeep from 'lodash-es/cloneDeep'
|
import cloneDeep from 'lodash-es/cloneDeep'
|
||||||
import * as CryptoMD5 from 'crypto-js/md5'
|
import * as CryptoMD5 from 'crypto-js/md5'
|
||||||
|
import { SasService } from './sas.service'
|
||||||
|
|
||||||
const librariesToShow = 50
|
const librariesToShow = 50
|
||||||
|
|
||||||
@ -12,7 +13,7 @@ export class HelperService {
|
|||||||
public loadMoreCount: number = librariesToShow
|
public loadMoreCount: number = librariesToShow
|
||||||
public isMicrosoft: boolean = false
|
public isMicrosoft: boolean = false
|
||||||
|
|
||||||
constructor() {
|
constructor(private sasService: SasService) {
|
||||||
this.isMicrosoft = this.isIEorEDGE()
|
this.isMicrosoft = this.isIEorEDGE()
|
||||||
console.log('Is IE or Edge?', this.isMicrosoft)
|
console.log('Is IE or Edge?', this.isMicrosoft)
|
||||||
}
|
}
|
||||||
@ -314,6 +315,20 @@ export class HelperService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public isStreamingViya(): boolean {
|
||||||
|
const serverType = this.sasService.getServerType()
|
||||||
|
|
||||||
|
if (serverType !== 'SASVIYA') return false
|
||||||
|
|
||||||
|
if (
|
||||||
|
location.search.toLowerCase().includes('?_file=') &&
|
||||||
|
location.pathname.toLowerCase().includes('/sasjobexecution')
|
||||||
|
)
|
||||||
|
return true
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
// Required type is NodeJS.Timeout
|
// Required type is NodeJS.Timeout
|
||||||
// But NodeJS is not available in browser so we have to go with any
|
// But NodeJS is not available in browser so we have to go with any
|
||||||
private debounceTimeout: any
|
private debounceTimeout: any
|
||||||
|
@ -1,12 +1,21 @@
|
|||||||
import { HttpClient } from '@angular/common/http'
|
import {
|
||||||
|
HttpClient,
|
||||||
|
HttpContext,
|
||||||
|
HttpErrorResponse,
|
||||||
|
HttpHeaders,
|
||||||
|
HttpParams
|
||||||
|
} from '@angular/common/http'
|
||||||
import { Injectable } from '@angular/core'
|
import { Injectable } from '@angular/core'
|
||||||
import { Observable } from 'rxjs'
|
import { catchError, Observable, throwError } from 'rxjs'
|
||||||
import { Collection } from '../viya-api-explorer/models/collection.model'
|
import { Collection } from '../viya-api-explorer/models/collection.model'
|
||||||
import { AppStoreService } from './app-store.service'
|
import { AppStoreService } from './app-store.service'
|
||||||
import { ViyaApis } from '../viya-api-explorer/models/viya-apis.models'
|
import { ViyaApis } from '../viya-api-explorer/models/viya-apis.models'
|
||||||
import { ViyaApiFolderMembers } from '../viya-api-explorer/models/viya-api-folder-content.model'
|
import { ViyaApiFolderMembers } from '../viya-api-explorer/models/viya-api-folder-content.model'
|
||||||
import { ViyaApiFolder } from '../viya-api-explorer/models/viya-api-folder.model'
|
import { ViyaApiFolder } from '../viya-api-explorer/models/viya-api-folder.model'
|
||||||
import { ViyaApiIdentities } from '../viya-api-explorer/models/viya-api-identities.model'
|
import { ViyaApiIdentities } from '../viya-api-explorer/models/viya-api-identities.model'
|
||||||
|
import { ViyaApiCurrentUser } from '../viya-api-explorer/models/viya-api-current-user.model'
|
||||||
|
import { ViyaComputeContexts } from '../viya-api-explorer/models/viya-compute-contexts.model'
|
||||||
|
import { ComputeContextDetails } from '../viya-api-explorer/models/viya-compute-context-details.model'
|
||||||
|
|
||||||
@Injectable({
|
@Injectable({
|
||||||
providedIn: 'root'
|
providedIn: 'root'
|
||||||
@ -74,7 +83,7 @@ export class SasViyaService {
|
|||||||
|
|
||||||
this.serverUrl = adapterConfig?.serverUrl || ''
|
this.serverUrl = adapterConfig?.serverUrl || ''
|
||||||
|
|
||||||
//example collection request
|
// example collection request
|
||||||
// this.getByCollection('jobs').subscribe((res) => {
|
// this.getByCollection('jobs').subscribe((res) => {
|
||||||
// console.log('res', res)
|
// console.log('res', res)
|
||||||
// })
|
// })
|
||||||
@ -94,7 +103,7 @@ export class SasViyaService {
|
|||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
getByUrl(url: string): Observable<Collection> {
|
getByUrl(url: string): Observable<Collection> {
|
||||||
return this.http.get<Collection>(`${this.serverUrl}${url}`, {
|
return this.get<Collection>(`${this.serverUrl}${url}`, {
|
||||||
withCredentials: true
|
withCredentials: true
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -105,23 +114,32 @@ export class SasViyaService {
|
|||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
getByCollection(apiCollection: string): Observable<Collection> {
|
getByCollection(apiCollection: string): Observable<Collection> {
|
||||||
return this.http.get<Collection>(`${this.serverUrl}${apiCollection}`, {
|
return this.get<Collection>(`${this.serverUrl}${apiCollection}`, {
|
||||||
withCredentials: true
|
withCredentials: true
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
getComputeContexts(): Observable<any> {
|
getComputeContexts(): Observable<ViyaComputeContexts> {
|
||||||
return this.http.get<any>(`${this.serverUrl}/compute/contexts`, {
|
return this.get<ViyaComputeContexts>(`${this.serverUrl}/compute/contexts`, {
|
||||||
withCredentials: true
|
withCredentials: true
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getComputeContextById(id: string): Observable<ComputeContextDetails> {
|
||||||
|
return this.get<ComputeContextDetails>(
|
||||||
|
`${this.serverUrl}/compute/contexts/${id}`,
|
||||||
|
{
|
||||||
|
withCredentials: true
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param path Path to the folder
|
* @param path Path to the folder
|
||||||
* @returns The folder info object
|
* @returns The folder info object
|
||||||
*/
|
*/
|
||||||
getFolderByPath(path: string): Observable<ViyaApiFolder> {
|
getFolderByPath(path: string): Observable<ViyaApiFolder> {
|
||||||
return this.http.get<any>(
|
return this.get<ViyaApiFolder>(
|
||||||
`${this.serverUrl}/folders/folders/@item?path=${path}`,
|
`${this.serverUrl}/folders/folders/@item?path=${path}`,
|
||||||
{
|
{
|
||||||
withCredentials: true
|
withCredentials: true
|
||||||
@ -130,7 +148,7 @@ export class SasViyaService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
getFolderMembers(folderId: string): Observable<ViyaApiFolderMembers> {
|
getFolderMembers(folderId: string): Observable<ViyaApiFolderMembers> {
|
||||||
return this.http.get<any>(
|
return this.get<ViyaApiFolderMembers>(
|
||||||
`${this.serverUrl}/folders/folders/${folderId}/members`,
|
`${this.serverUrl}/folders/folders/${folderId}/members`,
|
||||||
{
|
{
|
||||||
withCredentials: true
|
withCredentials: true
|
||||||
@ -139,11 +157,63 @@ export class SasViyaService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
getAdminGroups(limit: number = 5000): Observable<ViyaApiIdentities> {
|
getAdminGroups(limit: number = 5000): Observable<ViyaApiIdentities> {
|
||||||
return this.http.get<any>(
|
return this.get<ViyaApiIdentities>(
|
||||||
`${this.serverUrl}/identities/groups?sortBy=name&limit=${limit}`,
|
`${this.serverUrl}/identities/groups?sortBy=name&limit=${limit}`,
|
||||||
{
|
{
|
||||||
withCredentials: true
|
withCredentials: true
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getCurrentUser(): Observable<ViyaApiCurrentUser> {
|
||||||
|
return this.get<ViyaApiCurrentUser>(
|
||||||
|
`${this.serverUrl}/identities/users/@currentUser`,
|
||||||
|
{
|
||||||
|
withCredentials: true
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
get<T>(
|
||||||
|
url: string,
|
||||||
|
options?: {
|
||||||
|
headers?:
|
||||||
|
| HttpHeaders
|
||||||
|
| {
|
||||||
|
[header: string]: string | string[]
|
||||||
|
}
|
||||||
|
context?: HttpContext
|
||||||
|
observe?: 'body'
|
||||||
|
params?:
|
||||||
|
| HttpParams
|
||||||
|
| {
|
||||||
|
[param: string]:
|
||||||
|
| string
|
||||||
|
| number
|
||||||
|
| boolean
|
||||||
|
| ReadonlyArray<string | number | boolean>
|
||||||
|
}
|
||||||
|
reportProgress?: boolean
|
||||||
|
responseType?: 'json'
|
||||||
|
withCredentials?: boolean
|
||||||
|
transferCache?:
|
||||||
|
| {
|
||||||
|
includeHeaders?: string[]
|
||||||
|
}
|
||||||
|
| boolean
|
||||||
|
}
|
||||||
|
): Observable<T> {
|
||||||
|
return this.http.get<T>(url, options).pipe(
|
||||||
|
catchError((err: HttpErrorResponse) => {
|
||||||
|
console.log('url', url)
|
||||||
|
console.log('err.status', err.status)
|
||||||
|
if (err.status === 449 || err.status === 401) {
|
||||||
|
// Retry once if we got a 449
|
||||||
|
return this.http.get<T>(url, options)
|
||||||
|
}
|
||||||
|
// Otherwise propagate the error
|
||||||
|
return throwError(() => err)
|
||||||
|
})
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -333,6 +333,10 @@ export class SasService {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public reloadStartupData() {
|
||||||
|
this.loadStartupServiceEmitter.emit()
|
||||||
|
}
|
||||||
|
|
||||||
public getLicenseSiteId(): string[] {
|
public getLicenseSiteId(): string[] {
|
||||||
return this.license_site_id.value || []
|
return this.license_site_id.value || []
|
||||||
}
|
}
|
||||||
@ -657,4 +661,17 @@ export class SasService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Viya specific functions
|
||||||
|
public getFileContent(folderPath: string, fileName: string) {
|
||||||
|
return this.sasjsAdapter.getFileContent(folderPath, fileName)
|
||||||
|
}
|
||||||
|
|
||||||
|
public updateFileContent(
|
||||||
|
folderPath: string,
|
||||||
|
fileName: string,
|
||||||
|
content: string
|
||||||
|
) {
|
||||||
|
return this.sasjsAdapter.updateFileContent(folderPath, fileName, content)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -598,6 +598,12 @@
|
|||||||
{{ libinfo[0] ? libinfo[0].TABLE_CNT : '' }}
|
{{ libinfo[0] ? libinfo[0].TABLE_CNT : '' }}
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
<tr *ngIf="libinfo[0].CATALOG_CNT !== null">
|
||||||
|
<td class="m-0">CATALOG_CNT:</td>
|
||||||
|
<td class="m-0 font-bold">
|
||||||
|
{{ libinfo[0] ? libinfo[0].CATALOG_CNT : '' }}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
</div>
|
</div>
|
||||||
|
@ -0,0 +1,17 @@
|
|||||||
|
export interface ViyaApiCurrentUser {
|
||||||
|
creationTimeStamp: string
|
||||||
|
modifiedTimeStamp: string
|
||||||
|
id: string
|
||||||
|
type: string
|
||||||
|
name: string
|
||||||
|
links: Link[]
|
||||||
|
version: number
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface Link {
|
||||||
|
method: string
|
||||||
|
rel: string
|
||||||
|
href: string
|
||||||
|
uri: string
|
||||||
|
type: string
|
||||||
|
}
|
@ -0,0 +1,34 @@
|
|||||||
|
export interface ComputeContextDetails {
|
||||||
|
attributes?: Attributes
|
||||||
|
createdBy: string
|
||||||
|
creationTimeStamp: string
|
||||||
|
description: string
|
||||||
|
id: string
|
||||||
|
launchContext: LaunchContext
|
||||||
|
launchType: string
|
||||||
|
links: Link[]
|
||||||
|
modifiedBy: string
|
||||||
|
modifiedTimeStamp: string
|
||||||
|
name: string
|
||||||
|
version: number
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface Link {
|
||||||
|
method: string
|
||||||
|
rel: string
|
||||||
|
href: string
|
||||||
|
uri: string
|
||||||
|
type?: string
|
||||||
|
responseType?: string
|
||||||
|
itemType?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface LaunchContext {
|
||||||
|
contextId: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface Attributes {
|
||||||
|
reuseServerProcesses: string
|
||||||
|
runServerAs: string
|
||||||
|
serverMinAvailable: string
|
||||||
|
}
|
@ -0,0 +1,36 @@
|
|||||||
|
export interface ViyaComputeContexts {
|
||||||
|
accept: string
|
||||||
|
count: number
|
||||||
|
items: Item[]
|
||||||
|
limit: number
|
||||||
|
links: Link2[]
|
||||||
|
name: string
|
||||||
|
start: number
|
||||||
|
version: number
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface Link2 {
|
||||||
|
method: string
|
||||||
|
rel: string
|
||||||
|
href: string
|
||||||
|
uri: string
|
||||||
|
type: string
|
||||||
|
itemType: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface Item {
|
||||||
|
createdBy: string
|
||||||
|
id: string
|
||||||
|
links: Link[]
|
||||||
|
name: string
|
||||||
|
version: number
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface Link {
|
||||||
|
method: string
|
||||||
|
rel: string
|
||||||
|
href: string
|
||||||
|
uri: string
|
||||||
|
type?: string
|
||||||
|
responseType?: string
|
||||||
|
}
|
@ -3884,6 +3884,12 @@ app-header-actions {
|
|||||||
|
|
||||||
// END OF CSP WORKAROUND
|
// END OF CSP WORKAROUND
|
||||||
|
|
||||||
|
.clr-input-wrapper.small-mt {
|
||||||
|
.clr-form-control {
|
||||||
|
margin-top: 5px !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
body[cds-theme="dark"] {
|
body[cds-theme="dark"] {
|
||||||
scrollbar-width: thin;
|
scrollbar-width: thin;
|
||||||
scrollbar-color: $trackColor $thumbColor;
|
scrollbar-color: $trackColor $thumbColor;
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "dcfrontend",
|
"name": "dcfrontend",
|
||||||
"version": "6.14.8",
|
"version": "7.0.0",
|
||||||
"description": "Data Controller",
|
"description": "Data Controller",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@saithodev/semantic-release-gitea": "^2.1.0",
|
"@saithodev/semantic-release-gitea": "^2.1.0",
|
||||||
@ -19,7 +19,9 @@
|
|||||||
"lint": "npm run lint:fix",
|
"lint": "npm run lint:fix",
|
||||||
"lint:fix": "npx prettier --write \"client/{src,test}/**/*.{ts,tsx,js,jsx,html,css,sass,less,yml,md,graphql}\" \"client/cypress/integration/*.tests.ts\"",
|
"lint:fix": "npx prettier --write \"client/{src,test}/**/*.{ts,tsx,js,jsx,html,css,sass,less,yml,md,graphql}\" \"client/cypress/integration/*.tests.ts\"",
|
||||||
"lint:check": "npx prettier --check \"client/{src,test}/**/*.{ts,tsx,js,jsx,html,css,sass,less,yml,md,graphql}\" \"client/cypress/integration/*.tests.ts\"",
|
"lint:check": "npx prettier --check \"client/{src,test}/**/*.{ts,tsx,js,jsx,html,css,sass,less,yml,md,graphql}\" \"client/cypress/integration/*.tests.ts\"",
|
||||||
"jo": "echo"
|
"lint:silent": "npx prettier --loglevel silent --check \"client/{src,test}/**/*.{ts,tsx,js,jsx,html,css,sass,less,yml,md,graphql}\" \"client/cypress/integration/*.tests.ts\"",
|
||||||
|
"jo": "echo",
|
||||||
|
"prepare": "git rev-parse --git-dir && git config core.hooksPath ./.git-hooks && git config core.autocrlf false || true"
|
||||||
},
|
},
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
|
26
sas/package-lock.json
generated
26
sas/package-lock.json
generated
@ -6,8 +6,8 @@
|
|||||||
"": {
|
"": {
|
||||||
"name": "dc-sas",
|
"name": "dc-sas",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@sasjs/cli": "^4.12.5",
|
"@sasjs/cli": "^4.12.8",
|
||||||
"@sasjs/core": "^4.57.0"
|
"@sasjs/core": "^4.59.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@coolaj86/urequest": {
|
"node_modules/@coolaj86/urequest": {
|
||||||
@ -30,9 +30,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@sasjs/adapter": {
|
"node_modules/@sasjs/adapter": {
|
||||||
"version": "4.11.3",
|
"version": "4.12.1",
|
||||||
"resolved": "https://registry.npmjs.org/@sasjs/adapter/-/adapter-4.11.3.tgz",
|
"resolved": "https://registry.npmjs.org/@sasjs/adapter/-/adapter-4.12.1.tgz",
|
||||||
"integrity": "sha512-KF6G4vzs4l4efjpCD02og3kB44uFfJ1u2UWu749VdHtLKNN9l+PO26/moR+YAmRmmz2I9sC3X09fZE1nlN6zgw==",
|
"integrity": "sha512-0217oZIkrecOyQygRe6Azgc1C4TIcjB5noi15fU4Rd5GsfDpleKVfQQdzYZ7im/vesWlLIVl/yUT67MMaQe0ew==",
|
||||||
"hasInstallScript": true,
|
"hasInstallScript": true,
|
||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
@ -45,14 +45,14 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@sasjs/cli": {
|
"node_modules/@sasjs/cli": {
|
||||||
"version": "4.12.5",
|
"version": "4.12.8",
|
||||||
"resolved": "https://registry.npmjs.org/@sasjs/cli/-/cli-4.12.5.tgz",
|
"resolved": "https://registry.npmjs.org/@sasjs/cli/-/cli-4.12.8.tgz",
|
||||||
"integrity": "sha512-y6JFATKlTyTl0gRPpDBPL1rwZsyeuyp5uEz7HMA7raSzQuNa6QZ1oO1Er91I7+cLUg0Ndh5aSNGKYOdBRStQ2g==",
|
"integrity": "sha512-20WiywlcLV22T1XfkAumV66mM3PfQ1N9ihJfpxoOVCFs2wF/ZertqnP4BZ5CE1dc30M1C2oDOzzSSVZqePPQnw==",
|
||||||
"hasInstallScript": true,
|
"hasInstallScript": true,
|
||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@sasjs/adapter": "4.11.3",
|
"@sasjs/adapter": "4.12.1",
|
||||||
"@sasjs/core": "4.57.0",
|
"@sasjs/core": "4.59.1",
|
||||||
"@sasjs/lint": "2.4.3",
|
"@sasjs/lint": "2.4.3",
|
||||||
"@sasjs/utils": "3.5.2",
|
"@sasjs/utils": "3.5.2",
|
||||||
"adm-zip": "0.5.10",
|
"adm-zip": "0.5.10",
|
||||||
@ -77,9 +77,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@sasjs/core": {
|
"node_modules/@sasjs/core": {
|
||||||
"version": "4.57.0",
|
"version": "4.59.1",
|
||||||
"resolved": "https://registry.npmjs.org/@sasjs/core/-/core-4.57.0.tgz",
|
"resolved": "https://registry.npmjs.org/@sasjs/core/-/core-4.59.1.tgz",
|
||||||
"integrity": "sha512-iJiLnW4oY15InGerXXWtrjc1YpJ9UDz72+r7Odfr/yYR7RxIhtXGjYQIqyQu6US+cS/0b2pi12LZB6VnfMS/pA==",
|
"integrity": "sha512-52GNI4nIll5YivI8uobWrucE6TkHcTjcbKTr/YPC9eTauC4sh0V0MptebfAJ5E6vE5P2WevNZGr42KdDpckLpg==",
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/@sasjs/lint": {
|
"node_modules/@sasjs/lint": {
|
||||||
|
@ -22,13 +22,13 @@
|
|||||||
"serverdata": "sasjs request services/admin/makedata -d deploy/makeDataServer.json -l sasjsresults/makedata_server.log -o sasjsresults/makedata_server.json -t server",
|
"serverdata": "sasjs request services/admin/makedata -d deploy/makeDataServer.json -l sasjsresults/makedata_server.log -o sasjsresults/makedata_server.json -t server",
|
||||||
"viya": "npm run viyacbd && sasjs test",
|
"viya": "npm run viyacbd && sasjs test",
|
||||||
"viyacbd": "sasjs folder delete /Public/app/viya && sasjs cbd -t viya && npm run viyadata",
|
"viyacbd": "sasjs folder delete /Public/app/viya && sasjs cbd -t viya && npm run viyadata",
|
||||||
"viyadata": "sasjs request services/admin/makedata -d deploy/makeDataViya.json -l sasjsresults/makedata.log -o sasjsresults/output.json",
|
"viyadata": "sasjs request services/admin/makedata -d deploy/makeDataViya.json -l sasjsresults/makedata.log -o sasjsresults/output.json -t viya",
|
||||||
"v4data": "sasjs request services/admin/makedata -d deploy/makeDataV4.json -l sasjsresults/makedatav4.log -o sasjsresults/outputv4.json -t v4",
|
"v4data": "sasjs request services/admin/makedata -d deploy/makeDataV4.json -l sasjsresults/makedatav4.log -o sasjsresults/outputv4.json -t v4",
|
||||||
"sasdocs": "sasjs doc && ./sasjs/utils/deploydocs.sh"
|
"sasdocs": "sasjs doc && ./sasjs/utils/deploydocs.sh"
|
||||||
},
|
},
|
||||||
"private": true,
|
"private": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@sasjs/cli": "^4.12.5",
|
"@sasjs/cli": "^4.12.8",
|
||||||
"@sasjs/core": "^4.57.0"
|
"@sasjs/core": "^4.59.1"
|
||||||
}
|
}
|
||||||
}
|
}
|
17
sas/sasjs/db/datactrl/mpe_datacatalog_cats.ddl
Normal file
17
sas/sasjs/db/datactrl/mpe_datacatalog_cats.ddl
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
/**
|
||||||
|
@file mpe_datacatalog_CATS.ddl
|
||||||
|
@brief ddl file
|
||||||
|
@details
|
||||||
|
|
||||||
|
@version 9.3
|
||||||
|
@author 4GL Apps Ltd
|
||||||
|
@copyright 4GL Apps Ltd
|
||||||
|
**/
|
||||||
|
|
||||||
|
create table &curlib..mpe_datacatalog_CATS(
|
||||||
|
TX_FROM float format=datetime19.,
|
||||||
|
TX_TO float format=datetime19.,
|
||||||
|
libref char(8) label='Library Name',
|
||||||
|
memname char(64) label='Member Name',
|
||||||
|
constraint pk_mpe_datacatalog_CATS
|
||||||
|
primary key(libref,memname,tx_to));
|
21
sas/sasjs/db/datactrl/mpe_datacatalog_objs.ddl
Normal file
21
sas/sasjs/db/datactrl/mpe_datacatalog_objs.ddl
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
/**
|
||||||
|
@file mpe_datacatalog_CATS.ddl
|
||||||
|
@brief ddl file
|
||||||
|
@details
|
||||||
|
|
||||||
|
@version 9.3
|
||||||
|
@author 4GL Apps Ltd
|
||||||
|
@copyright 4GL Apps Ltd
|
||||||
|
**/
|
||||||
|
|
||||||
|
create table &curlib..mpe_datacatalog_OBJS(
|
||||||
|
TX_FROM float format=datetime19.,
|
||||||
|
TX_TO float format=datetime19.,
|
||||||
|
libref char(8) label='Library Name',
|
||||||
|
memname char(64) label='Member Name',
|
||||||
|
objname char(32) label='Object Name',
|
||||||
|
objtype char(8) label='Object Type',
|
||||||
|
objdesc char(256) label='Object Description',
|
||||||
|
alias char(32) label='Object Alias',
|
||||||
|
constraint pk_mpe_datacatalog_OBJS
|
||||||
|
primary key(libref,memname,objname,objtype,tx_to));
|
20
sas/sasjs/db/datactrl/mpe_datastatus_cats.ddl
Normal file
20
sas/sasjs/db/datactrl/mpe_datastatus_cats.ddl
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
/**
|
||||||
|
@file mpe_datacatalog_CATS.ddl
|
||||||
|
@brief ddl file
|
||||||
|
@details
|
||||||
|
|
||||||
|
@version 9.3
|
||||||
|
@author 4GL Apps Ltd
|
||||||
|
@copyright 4GL Apps Ltd
|
||||||
|
**/
|
||||||
|
|
||||||
|
create table &curlib..mpe_datastatus_CATS(
|
||||||
|
TX_FROM float format=datetime19.,
|
||||||
|
TX_TO float format=datetime19.,
|
||||||
|
libref char(8) label='Library Name',
|
||||||
|
memname char(64) label='Member Name',
|
||||||
|
nobjs num label='Number of objects',
|
||||||
|
created num format=DATETIME. label='Date Created',
|
||||||
|
modified num format=DATETIME. label='Date Modified',
|
||||||
|
constraint pk_mpe_datastatus_CATS
|
||||||
|
primary key(libref,memname,tx_to));
|
@ -14,5 +14,6 @@ create table &curlib..mpe_datastatus_libs(
|
|||||||
libref char(8) label='Library Name',
|
libref char(8) label='Library Name',
|
||||||
libsize num format=SIZEKMG. label='Size of file',
|
libsize num format=SIZEKMG. label='Size of file',
|
||||||
table_cnt num label='Number of Tables',
|
table_cnt num label='Number of Tables',
|
||||||
|
catalog_cnt num label='Number of Catalogs',
|
||||||
constraint pk_mpe_datastatus_libs
|
constraint pk_mpe_datastatus_libs
|
||||||
primary key(libref,tx_to));
|
primary key(libref,tx_to));
|
||||||
|
22
sas/sasjs/db/datactrl/mpe_datastatus_objs.ddl
Normal file
22
sas/sasjs/db/datactrl/mpe_datastatus_objs.ddl
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
/**
|
||||||
|
@file mpe_datacatalog_CATS.ddl
|
||||||
|
@brief ddl file
|
||||||
|
@details
|
||||||
|
|
||||||
|
@version 9.3
|
||||||
|
@author 4GL Apps Ltd
|
||||||
|
@copyright 4GL Apps Ltd
|
||||||
|
**/
|
||||||
|
|
||||||
|
create table &curlib..mpe_datastatus_OBJS(
|
||||||
|
TX_FROM float format=datetime19.,
|
||||||
|
TX_TO float format=datetime19.,
|
||||||
|
libref char(8) label='Library Name',
|
||||||
|
memname char(64) label='Member Name',
|
||||||
|
objname char(32) label='Object Name',
|
||||||
|
objtype char(8) label='Object Type',
|
||||||
|
created num format=DATETIME. label='Date Created',
|
||||||
|
modified num format=DATETIME. label='Date Modified',
|
||||||
|
level num label='Library Concatenation Level',
|
||||||
|
constraint pk_mpe_datastatus_OBJS
|
||||||
|
primary key(libref,memname,objname,objtype,tx_to));
|
@ -14,8 +14,8 @@ create table &curlib..mpe_datastatus_tabs(
|
|||||||
libref char(8) label='Library Name',
|
libref char(8) label='Library Name',
|
||||||
dsn char(64) label='Member Name',
|
dsn char(64) label='Member Name',
|
||||||
filesize num format=SIZEKMG. label='Size of file',
|
filesize num format=SIZEKMG. label='Size of file',
|
||||||
crdate num format=DATETIME. informat=DATETIME. label='Date Created',
|
crdate num format=DATETIME. label='Date Created',
|
||||||
modate num format=DATETIME. informat=DATETIME. label='Date Modified',
|
modate num format=DATETIME. label='Date Modified',
|
||||||
nobs num label='Number of Physical (Actual, inc. deleted) Observations',
|
nobs num label='Number of Physical (Actual, inc. deleted) Observations',
|
||||||
constraint pk_mpe_datastatus_tabs
|
constraint pk_mpe_datastatus_tabs
|
||||||
primary key(libref,dsn,tx_to));
|
primary key(libref,dsn,tx_to));
|
||||||
|
@ -29,7 +29,7 @@ create table dc.mpe_datacatalog_TABS(
|
|||||||
nvar num label='Number of Variables',
|
nvar num label='Number of Variables',
|
||||||
compress char(8) label='Compression Routine',
|
compress char(8) label='Compression Routine',
|
||||||
pk_fields char(512)
|
pk_fields char(512)
|
||||||
label='Primary Key Fields (identified by being in a constraint that is both Unique and Not Null)',
|
label='Primary Key Fields (in a constraint that is both Unique and Not Null)',
|
||||||
constraint pk
|
constraint pk
|
||||||
primary key(libref,dsn,tx_to));
|
primary key(libref,dsn,tx_to));
|
||||||
|
|
||||||
@ -67,8 +67,8 @@ create table dc.mpe_datacatalog_vars(
|
|||||||
libref char(8) label='Library Name',
|
libref char(8) label='Library Name',
|
||||||
dsn char(64) label='Member Name',
|
dsn char(64) label='Member Name',
|
||||||
filesize num format=SIZEKMG. label='Size of file',
|
filesize num format=SIZEKMG. label='Size of file',
|
||||||
crdate num format=DATETIME. informat=DATETIME. label='Date Created',
|
crdate num format=DATETIME. label='Date Created',
|
||||||
modate num format=DATETIME. informat=DATETIME. label='Date Modified',
|
modate num format=DATETIME. label='Date Modified',
|
||||||
nobs num label='Number of Physical (Actual, inc. deleted) Observations',
|
nobs num label='Number of Physical (Actual, inc. deleted) Observations',
|
||||||
constraint pk
|
constraint pk
|
||||||
primary key(libref,dsn,tx_to));
|
primary key(libref,dsn,tx_to));
|
71
sas/sasjs/db/migrations/20250611_v7.0_release.sas
Normal file
71
sas/sasjs/db/migrations/20250611_v7.0_release.sas
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
/**
|
||||||
|
@file
|
||||||
|
@brief migration script to move from v6.8.2 to v7.0 of data controller
|
||||||
|
|
||||||
|
BREAKING CHANGE - 1 new column and 4 additional tables for capturing catalogs
|
||||||
|
|
||||||
|
Be sure to run this using the correct system account
|
||||||
|
(eg the regular DC account)
|
||||||
|
|
||||||
|
On SAS 9 you may wish to run proc metalib or refresh in DI Studio afterwards
|
||||||
|
to see the new tables in the VIEW page
|
||||||
|
|
||||||
|
proc metalib;
|
||||||
|
omr (library="&DC_LIBNAME");
|
||||||
|
folder="&root/data";
|
||||||
|
update_rule=(delete);
|
||||||
|
run;
|
||||||
|
|
||||||
|
**/
|
||||||
|
|
||||||
|
%let dclib=YOURDCLIB;
|
||||||
|
|
||||||
|
libname &dclib "/YOUR/DATACONTROLLER/LIBRARY/PATH";
|
||||||
|
|
||||||
|
proc sql;
|
||||||
|
create table work.BACKUP as select * from &dclib..mpe_datastatus_libs;
|
||||||
|
alter table &dclib..mpe_datastatus_libs add catalog_cnt num;
|
||||||
|
|
||||||
|
create table &dclib..mpe_datacatalog_CATS(
|
||||||
|
TX_FROM float format=datetime19.,
|
||||||
|
TX_TO float format=datetime19.,
|
||||||
|
libref char(8) label='Library Name',
|
||||||
|
memname char(64) label='Member Name',
|
||||||
|
constraint pk_mpe_datacatalog_CATS
|
||||||
|
primary key(libref,memname,tx_to));
|
||||||
|
|
||||||
|
create table &dclib..mpe_datacatalog_OBJS(
|
||||||
|
TX_FROM float format=datetime19.,
|
||||||
|
TX_TO float format=datetime19.,
|
||||||
|
libref char(8) label='Library Name',
|
||||||
|
memname char(64) label='Member Name',
|
||||||
|
objname char(32) label='Object Name',
|
||||||
|
objtype char(8) label='Object Type',
|
||||||
|
objdesc char(256) label='Object Description',
|
||||||
|
alias char(32) label='Object Alias',
|
||||||
|
constraint pk_mpe_datacatalog_OBJS
|
||||||
|
primary key(libref,memname,objname,objtype,tx_to));
|
||||||
|
|
||||||
|
create table &dclib..mpe_datastatus_CATS(
|
||||||
|
TX_FROM float format=datetime19.,
|
||||||
|
TX_TO float format=datetime19.,
|
||||||
|
libref char(8) label='Library Name',
|
||||||
|
memname char(64) label='Member Name',
|
||||||
|
nobjs num label='Number of objects',
|
||||||
|
created num format=DATETIME. label='Date Created',
|
||||||
|
modified num format=DATETIME. label='Date Modified',
|
||||||
|
constraint pk_mpe_datastatus_CATS
|
||||||
|
primary key(libref,memname,tx_to));
|
||||||
|
|
||||||
|
create table &dclib..mpe_datastatus_OBJS(
|
||||||
|
TX_FROM float format=datetime19.,
|
||||||
|
TX_TO float format=datetime19.,
|
||||||
|
libref char(8) label='Library Name',
|
||||||
|
memname char(64) label='Member Name',
|
||||||
|
objname char(32) label='Object Name',
|
||||||
|
objtype char(8) label='Object Type',
|
||||||
|
created num format=DATETIME. label='Date Created',
|
||||||
|
modified num format=DATETIME. label='Date Modified',
|
||||||
|
level num label='Library Concatenation Level',
|
||||||
|
constraint pk_mpe_datastatus_OBJS
|
||||||
|
primary key(libref,memname,objname,objtype,tx_to));
|
@ -14,14 +14,31 @@
|
|||||||
**/
|
**/
|
||||||
|
|
||||||
%macro mpe_dsmeta(libds, outds=dsmeta);
|
%macro mpe_dsmeta(libds, outds=dsmeta);
|
||||||
%local ddsd ddld notes lenstmt;
|
%local ddsd ddld notes lenstmt memname;
|
||||||
%let lenstmt=length ods_table $18 name $100 value $1000;
|
%let lenstmt=length ods_table $18 name $100 value $1000;
|
||||||
%let libds=%upcase(&libds);
|
%let libds=%upcase(&libds);
|
||||||
%mp_dsmeta(&libds, outds=&outds)
|
|
||||||
|
%if "%scan(&libds,2,-)" ne "FC" %then %do;
|
||||||
|
%let memname=%scan(&libds,2,.);
|
||||||
|
%mp_dsmeta(&libds, outds=&outds)
|
||||||
|
%end;
|
||||||
|
%else %do;
|
||||||
|
%let memname=%scan(&libds,2,.-);
|
||||||
|
data &outds;
|
||||||
|
&lenstmt;
|
||||||
|
set sashelp.vcatalg;
|
||||||
|
ods_table=cats(objtype);
|
||||||
|
name=cats(objname);
|
||||||
|
value=catx(' ',objdesc,'(modified:',put(modified,datetime19.),')');
|
||||||
|
where libname="%scan(&libds,1,.)" and memname="&memname";
|
||||||
|
keep ods_table name value;
|
||||||
|
run;
|
||||||
|
proc sort; by ods_table name;run;
|
||||||
|
%end;
|
||||||
|
|
||||||
data _null_;
|
data _null_;
|
||||||
set &mpelib..mpe_datadictionary;
|
set &mpelib..mpe_datadictionary;
|
||||||
where &dc_dttmtfmt < tx_to & dd_source=%upcase("&libds") & dd_type='TABLE';
|
where &dc_dttmtfmt < tx_to & dd_source="&memname" & dd_type='TABLE';
|
||||||
call symputx('ddsd',dd_shortdesc,'l');
|
call symputx('ddsd',dd_shortdesc,'l');
|
||||||
call symputx('ddld',dd_longdesc,'l');
|
call symputx('ddld',dd_longdesc,'l');
|
||||||
run;
|
run;
|
||||||
|
@ -34,4 +34,15 @@ run;
|
|||||||
outds=work.test_results
|
outds=work.test_results
|
||||||
)
|
)
|
||||||
|
|
||||||
|
%mpe_dsmeta(FMTONLY.DCFMTS-FC,outds=test2)
|
||||||
|
data work.test2;
|
||||||
|
set work.test2;
|
||||||
|
putlog (_all_)(=);
|
||||||
|
run;
|
||||||
|
|
||||||
|
%mp_assertdsobs(work.test2,
|
||||||
|
desc=Test 2 - records returned,
|
||||||
|
test=EQUALS 5,
|
||||||
|
outds=work.test_results
|
||||||
|
)
|
||||||
|
|
||||||
|
@ -106,6 +106,19 @@ proc datasets lib=&lib noprint;
|
|||||||
/nomiss unique;
|
/nomiss unique;
|
||||||
quit;
|
quit;
|
||||||
proc sql;
|
proc sql;
|
||||||
|
create table &lib..mpe_datacatalog_CATS(
|
||||||
|
TX_FROM float ¬null format=datetime19.,
|
||||||
|
TX_TO float format=datetime19.,
|
||||||
|
libref char(8) label='Library Name',
|
||||||
|
memname char(64) label='Member Name'
|
||||||
|
);quit;
|
||||||
|
proc datasets lib=&lib noprint;
|
||||||
|
modify mpe_datacatalog_CATS;
|
||||||
|
index create
|
||||||
|
pk_mpe_datacatalog_CATS=(tx_to libref memname)
|
||||||
|
/nomiss unique;
|
||||||
|
quit;
|
||||||
|
proc sql;
|
||||||
create table &lib..mpe_datacatalog_libs(
|
create table &lib..mpe_datacatalog_libs(
|
||||||
TX_FROM num ¬null format=datetime19.3,
|
TX_FROM num ¬null format=datetime19.3,
|
||||||
TX_TO num ¬null format=datetime19.3,
|
TX_TO num ¬null format=datetime19.3,
|
||||||
@ -125,6 +138,23 @@ proc datasets lib=&lib noprint;
|
|||||||
/nomiss unique;
|
/nomiss unique;
|
||||||
quit;
|
quit;
|
||||||
proc sql;
|
proc sql;
|
||||||
|
create table &lib..mpe_datacatalog_OBJS(
|
||||||
|
TX_FROM num ¬null format=datetime19.,
|
||||||
|
TX_TO num ¬null format=datetime19.,
|
||||||
|
libref char(8) ¬null label='Library Name',
|
||||||
|
memname char(64) ¬null label='Member Name',
|
||||||
|
objname char(32) ¬null label='Object Name',
|
||||||
|
objtype char(8) ¬null label='Object Type',
|
||||||
|
objdesc char(256) label='Object Description',
|
||||||
|
alias char(32) label='Object Alias'
|
||||||
|
);quit;
|
||||||
|
proc datasets lib=&lib noprint;
|
||||||
|
modify mpe_datacatalog_OBJS;
|
||||||
|
index create
|
||||||
|
pk_mpe_datacatalog_OBJS=(libref memname objname objtype tx_to)
|
||||||
|
/nomiss unique;
|
||||||
|
quit;
|
||||||
|
proc sql;
|
||||||
create table &lib..mpe_datacatalog_TABS(
|
create table &lib..mpe_datacatalog_TABS(
|
||||||
TX_FROM num ¬null format=datetime19.3,
|
TX_FROM num ¬null format=datetime19.3,
|
||||||
TX_TO num ¬null format=datetime19.3,
|
TX_TO num ¬null format=datetime19.3,
|
||||||
@ -137,7 +167,7 @@ create table &lib..mpe_datacatalog_TABS(
|
|||||||
nvar num label='Number of Variables',
|
nvar num label='Number of Variables',
|
||||||
compress char(8) label='Compression Routine',
|
compress char(8) label='Compression Routine',
|
||||||
pk_fields char(512)
|
pk_fields char(512)
|
||||||
label='Primary Key Fields (identified by being in a constraint that is both Unique and Not Null)'
|
label='Primary Key Fields - in a constraint being both Unique and Not Null'
|
||||||
);quit;
|
);quit;
|
||||||
proc datasets lib=&lib noprint;
|
proc datasets lib=&lib noprint;
|
||||||
modify mpe_datacatalog_TABS;
|
modify mpe_datacatalog_TABS;
|
||||||
@ -169,12 +199,29 @@ proc datasets lib=&lib noprint;
|
|||||||
/nomiss unique;
|
/nomiss unique;
|
||||||
quit;
|
quit;
|
||||||
proc sql;
|
proc sql;
|
||||||
|
create table &lib..mpe_datastatus_CATS(
|
||||||
|
TX_FROM float format=datetime19.,
|
||||||
|
TX_TO float format=datetime19.,
|
||||||
|
libref char(8) label='Library Name',
|
||||||
|
memname char(64) label='Member Name',
|
||||||
|
nobjs num ¬null label='Number of objects',
|
||||||
|
created num ¬null format=DATETIME. label='Date Created',
|
||||||
|
modified num format=DATETIME. label='Date Modified'
|
||||||
|
);quit;
|
||||||
|
proc datasets lib=&lib noprint;
|
||||||
|
modify mpe_datastatus_CATS;
|
||||||
|
index create
|
||||||
|
pk_mpe_datastatus_cats=(libref memname tx_to)
|
||||||
|
/nomiss unique;
|
||||||
|
quit;
|
||||||
|
proc sql;
|
||||||
create table &lib..mpe_datastatus_libs(
|
create table &lib..mpe_datastatus_libs(
|
||||||
TX_FROM num ¬null format=datetime19.3,
|
TX_FROM num ¬null format=datetime19.3,
|
||||||
TX_TO num ¬null format=datetime19.3,
|
TX_TO num ¬null format=datetime19.3,
|
||||||
libref char(8) label='Library Name',
|
libref char(8) label='Library Name',
|
||||||
libsize num format=SIZEKMG. label='Size of library',
|
libsize num format=SIZEKMG. label='Size of library',
|
||||||
table_cnt num label='Number of Tables'
|
table_cnt num label='Number of Tables',
|
||||||
|
catalog_cnt num label='Number of Catalogs'
|
||||||
);quit;
|
);quit;
|
||||||
proc datasets lib=&lib noprint;
|
proc datasets lib=&lib noprint;
|
||||||
modify mpe_datastatus_libs;
|
modify mpe_datastatus_libs;
|
||||||
@ -183,14 +230,32 @@ proc datasets lib=&lib noprint;
|
|||||||
/nomiss unique;
|
/nomiss unique;
|
||||||
quit;
|
quit;
|
||||||
proc sql;
|
proc sql;
|
||||||
|
create table &lib..mpe_datastatus_OBJS(
|
||||||
|
TX_FROM float ¬null format=datetime19.,
|
||||||
|
TX_TO float ¬null format=datetime19.,
|
||||||
|
libref char(8) label='Library Name',
|
||||||
|
memname char(64) label='Member Name',
|
||||||
|
objname char(32) label='Object Name',
|
||||||
|
objtype char(8) label='Object Type',
|
||||||
|
created num ¬null format=DATETIME. label='Date Created',
|
||||||
|
modified num format=DATETIME. label='Date Modified',
|
||||||
|
level num label='Library Concatenation Level'
|
||||||
|
);quit;
|
||||||
|
proc datasets lib=&lib noprint;
|
||||||
|
modify mpe_datastatus_OBJS;
|
||||||
|
index create
|
||||||
|
pk_mpe_datastatus_OBJS=(libref memname objname objtype tx_to)
|
||||||
|
/nomiss unique;
|
||||||
|
quit;
|
||||||
|
proc sql;
|
||||||
create table &lib..mpe_datastatus_tabs(
|
create table &lib..mpe_datastatus_tabs(
|
||||||
TX_FROM num ¬null format=datetime19.3,
|
TX_FROM num ¬null format=datetime19.3,
|
||||||
TX_TO num ¬null format=datetime19.3,
|
TX_TO num ¬null format=datetime19.3,
|
||||||
libref char(8) label='Library Name',
|
libref char(8) label='Library Name',
|
||||||
dsn char(64) label='Member Name',
|
dsn char(64) label='Member Name',
|
||||||
filesize num format=SIZEKMG. label='Size of file',
|
filesize num format=SIZEKMG. label='Size of file',
|
||||||
crdate num format=DATETIME. informat=DATETIME. label='Date Created',
|
crdate num format=DATETIME. label='Date Created',
|
||||||
modate num format=DATETIME. informat=DATETIME. label='Date Modified',
|
modate num format=DATETIME. label='Date Modified',
|
||||||
nobs num label='Number of Physical (Actual, inc. deleted) Observations'
|
nobs num label='Number of Physical (Actual, inc. deleted) Observations'
|
||||||
);quit;
|
);quit;
|
||||||
proc datasets lib=&lib noprint;
|
proc datasets lib=&lib noprint;
|
||||||
|
26
sas/sasjs/macros/mpe_makedatamodel.test.sas
Normal file
26
sas/sasjs/macros/mpe_makedatamodel.test.sas
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
/**
|
||||||
|
@file
|
||||||
|
@brief Testing mpe_refreshtables macro
|
||||||
|
|
||||||
|
<h4> SAS Macros </h4>
|
||||||
|
@li mpe_makedatamodel.sas
|
||||||
|
@li mp_assert.sas
|
||||||
|
@li mp_assertscope.sas
|
||||||
|
|
||||||
|
@author 4GL Apps Ltd
|
||||||
|
@copyright 4GL Apps Ltd. This code may only be used within Data Controller
|
||||||
|
and may not be re-distributed or re-sold without the express permission of
|
||||||
|
4GL Apps Ltd.
|
||||||
|
|
||||||
|
**/
|
||||||
|
|
||||||
|
%mp_assertscope(SNAPSHOT)
|
||||||
|
%mpe_makedatamodel(lib=WORK)
|
||||||
|
%mp_assertscope(COMPARE,
|
||||||
|
desc=Checking macro variables against previous snapshot
|
||||||
|
)
|
||||||
|
|
||||||
|
%mp_assert(
|
||||||
|
iftrue=(&syscc = 0),
|
||||||
|
desc=Checking error condition
|
||||||
|
)
|
140
sas/sasjs/macros/mpe_refreshcatalogs.sas
Normal file
140
sas/sasjs/macros/mpe_refreshcatalogs.sas
Normal file
@ -0,0 +1,140 @@
|
|||||||
|
/**
|
||||||
|
@file mpe_refreshtables.sas
|
||||||
|
@brief Refreshes the data catalog
|
||||||
|
@details Assumes library is already assigned.
|
||||||
|
Usage:
|
||||||
|
|
||||||
|
%mpe_refreshcatalogs(sashelp)
|
||||||
|
|
||||||
|
<h4> SAS Macros </h4>
|
||||||
|
@li bitemporal_dataloader.sas
|
||||||
|
|
||||||
|
@version 9.3
|
||||||
|
@author 4GL Apps Ltd
|
||||||
|
**/
|
||||||
|
|
||||||
|
%macro mpe_refreshcatalogs(lib,cat=#all);
|
||||||
|
%let lib=%upcase(&lib);
|
||||||
|
%let cat=%upcase(&cat);
|
||||||
|
|
||||||
|
%put running &sysmacroname &lib for &cat;
|
||||||
|
proc sql;
|
||||||
|
create table work.catdata as
|
||||||
|
select libname as libref,
|
||||||
|
memname,
|
||||||
|
objname,
|
||||||
|
objtype,
|
||||||
|
objdesc,
|
||||||
|
created,
|
||||||
|
modified,
|
||||||
|
alias,
|
||||||
|
level
|
||||||
|
from dictionary.catalogs
|
||||||
|
where upcase(libname)="&lib"
|
||||||
|
%if &cat ne #ALL %then %do;
|
||||||
|
and upcase(memname)="&cat"
|
||||||
|
%end;
|
||||||
|
;
|
||||||
|
|
||||||
|
%mp_abort(iftrue= (&syscc ne 0)
|
||||||
|
,mac=&_program
|
||||||
|
,msg=%str(syscc=&syscc afer &lib objects extraction)
|
||||||
|
)
|
||||||
|
|
||||||
|
/* load mpe_datacatalog_CATS */
|
||||||
|
proc sql;
|
||||||
|
create table datacats as select distinct libref,memname from catdata;
|
||||||
|
|
||||||
|
%bitemporal_dataloader(base_lib=&mpelib
|
||||||
|
,base_dsn=mpe_datacatalog_CATS
|
||||||
|
,append_dsn=datacats
|
||||||
|
,PK=LIBREF MEMNAME
|
||||||
|
,etlsource=&sysmacroname
|
||||||
|
,loadtype=TXTEMPORAL
|
||||||
|
,tech_from=TX_FROM
|
||||||
|
,tech_to=TX_TO
|
||||||
|
%if &cat = #ALL %then %do;
|
||||||
|
,close_vars=LIBREF
|
||||||
|
%end;
|
||||||
|
,dclib=&mpelib
|
||||||
|
)
|
||||||
|
|
||||||
|
/* load mpe_datacatalog_objsS */
|
||||||
|
proc sql;
|
||||||
|
create table dataobjs as
|
||||||
|
select distinct libref,
|
||||||
|
memname,
|
||||||
|
objname,
|
||||||
|
objtype,
|
||||||
|
objdesc,
|
||||||
|
alias
|
||||||
|
from catdata;
|
||||||
|
quit;
|
||||||
|
|
||||||
|
%bitemporal_dataloader(base_lib=&mpelib
|
||||||
|
,base_dsn=mpe_datacatalog_OBJS
|
||||||
|
,append_dsn=dataobjs
|
||||||
|
,PK=LIBREF MEMNAME OBJNAME OBJTYPE
|
||||||
|
,etlsource=&sysmacroname
|
||||||
|
,loadtype=TXTEMPORAL
|
||||||
|
,tech_from=TX_FROM
|
||||||
|
,tech_to=TX_TO
|
||||||
|
%if &cat = #ALL %then %do;
|
||||||
|
,close_vars=LIBREF MEMNAME
|
||||||
|
%end;
|
||||||
|
,dclib=&mpelib
|
||||||
|
)
|
||||||
|
|
||||||
|
%put load mpe_datastatus_OBJS;
|
||||||
|
proc sql;
|
||||||
|
create table statusobjs as
|
||||||
|
select distinct libref,
|
||||||
|
memname,
|
||||||
|
objname,
|
||||||
|
objtype,
|
||||||
|
created,
|
||||||
|
modified,
|
||||||
|
level
|
||||||
|
from catdata;
|
||||||
|
|
||||||
|
%bitemporal_dataloader(base_lib=&mpelib
|
||||||
|
,base_dsn=mpe_datastatus_OBJS
|
||||||
|
,append_dsn=statusobjs
|
||||||
|
,PK=LIBREF MEMNAME OBJNAME OBJTYPE
|
||||||
|
,etlsource=&sysmacroname
|
||||||
|
,loadtype=TXTEMPORAL
|
||||||
|
,tech_from=TX_FROM
|
||||||
|
,tech_to=TX_TO
|
||||||
|
%if &cat = #ALL %then %do;
|
||||||
|
,close_vars=LIBREF MEMNAME
|
||||||
|
%end;
|
||||||
|
,dclib=&mpelib
|
||||||
|
)
|
||||||
|
|
||||||
|
%put load mpe_datastatus_cats;
|
||||||
|
proc sql;
|
||||||
|
create table statuscats as
|
||||||
|
select libref,
|
||||||
|
memname,
|
||||||
|
count(*) as nobjs,
|
||||||
|
min(created) as created,
|
||||||
|
max(modified) as modified
|
||||||
|
from catdata
|
||||||
|
group by 1,2;
|
||||||
|
|
||||||
|
%bitemporal_dataloader(base_lib=&mpelib
|
||||||
|
,base_dsn=mpe_datastatus_cats
|
||||||
|
,append_dsn=statuscats
|
||||||
|
,PK=LIBREF MEMNAME
|
||||||
|
,etlsource=&sysmacroname
|
||||||
|
,loadtype=TXTEMPORAL
|
||||||
|
,tech_from=TX_FROM
|
||||||
|
,tech_to=TX_TO
|
||||||
|
%if &cat = #ALL %then %do;
|
||||||
|
,close_vars=LIBREF
|
||||||
|
%end;
|
||||||
|
,dclib=&mpelib
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
%mend mpe_refreshcatalogs;
|
38
sas/sasjs/macros/mpe_refreshcatalogs.test.sas
Normal file
38
sas/sasjs/macros/mpe_refreshcatalogs.test.sas
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
/**
|
||||||
|
@file
|
||||||
|
@brief Testing mpe_refreshcatalogs macro
|
||||||
|
|
||||||
|
<h4> SAS Macros </h4>
|
||||||
|
@li mpe_refreshcatalogs.sas
|
||||||
|
@li mp_assert.sas
|
||||||
|
@li mp_assertscope.sas
|
||||||
|
@li mp_ds2md.sas
|
||||||
|
|
||||||
|
@author 4GL Apps Ltd
|
||||||
|
@copyright 4GL Apps Ltd. This code may only be used within Data Controller
|
||||||
|
and may not be re-distributed or re-sold without the express permission of
|
||||||
|
4GL Apps Ltd.
|
||||||
|
|
||||||
|
**/
|
||||||
|
|
||||||
|
%mp_assertscope(SNAPSHOT)
|
||||||
|
%mpe_refreshcatalogs(FMTONLY)
|
||||||
|
%mp_assertscope(COMPARE,
|
||||||
|
desc=Checking macro variables against previous snapshot
|
||||||
|
)
|
||||||
|
|
||||||
|
/* make sure that the process picks up the catalog */
|
||||||
|
proc sql noprint;
|
||||||
|
create table work.test1 as
|
||||||
|
select *
|
||||||
|
from &mpelib..mpe_datacatalog_cats(where=(&dc_dttmtfmt. lt tx_to))
|
||||||
|
where libref="FMTONLY";
|
||||||
|
%let test1=0;
|
||||||
|
select count(*) into: test1 from work.test1;
|
||||||
|
|
||||||
|
%mp_assert(
|
||||||
|
iftrue=(&test1>0),
|
||||||
|
desc=Checking fmtonly.dcfmts was picked up
|
||||||
|
)
|
||||||
|
|
||||||
|
%mp_ds2md(work.test1)
|
@ -48,11 +48,6 @@ create table cols as
|
|||||||
,msg=%str(syscc=&syscc afer &lib cols extraction)
|
,msg=%str(syscc=&syscc afer &lib cols extraction)
|
||||||
)
|
)
|
||||||
|
|
||||||
%mp_abort(iftrue= (&syscc ne 0)
|
|
||||||
,mac=&_program
|
|
||||||
,msg=%str(syscc=&syscc afer &lib indexes extraction)
|
|
||||||
)
|
|
||||||
|
|
||||||
%if &engine=SQLSVR %then %do;
|
%if &engine=SQLSVR %then %do;
|
||||||
proc sql;
|
proc sql;
|
||||||
connect using &lib;
|
connect using &lib;
|
||||||
@ -175,6 +170,11 @@ create table cols as
|
|||||||
|
|
||||||
%end;
|
%end;
|
||||||
|
|
||||||
|
%mp_abort(iftrue= (&syscc ne 0)
|
||||||
|
,mac=&_program
|
||||||
|
,msg=%str(syscc=&syscc afer &lib indexes extraction)
|
||||||
|
)
|
||||||
|
|
||||||
/* load columns */
|
/* load columns */
|
||||||
%bitemporal_dataloader(base_lib=&mpelib
|
%bitemporal_dataloader(base_lib=&mpelib
|
||||||
,base_dsn=mpe_datacatalog_vars
|
,base_dsn=mpe_datacatalog_vars
|
||||||
@ -295,7 +295,7 @@ proc sql;
|
|||||||
%if &ds ne #ALL %then %do;
|
%if &ds ne #ALL %then %do;
|
||||||
and upcase(memname)="&ds"
|
and upcase(memname)="&ds"
|
||||||
%end;
|
%end;
|
||||||
;
|
;
|
||||||
%end;
|
%end;
|
||||||
|
|
||||||
%bitemporal_dataloader(base_lib=&mpelib
|
%bitemporal_dataloader(base_lib=&mpelib
|
||||||
@ -314,12 +314,26 @@ proc sql;
|
|||||||
|
|
||||||
%if &ds = #ALL %then %do;
|
%if &ds = #ALL %then %do;
|
||||||
proc sql;
|
proc sql;
|
||||||
create table statuslibs as select
|
create table work.sumcat as
|
||||||
|
select libname as libref,
|
||||||
|
count(distinct memname) as catalog_cnt
|
||||||
|
from dictionary.catalogs
|
||||||
|
where upcase(libname)="&lib"
|
||||||
|
group by 1;
|
||||||
|
create table work.sumdsn as select
|
||||||
libref
|
libref
|
||||||
,sum(filesize) as libsize
|
,sum(filesize) as libsize
|
||||||
,count(*) as table_cnt
|
,count(*) as table_cnt
|
||||||
from statustabs
|
from statustabs
|
||||||
group by 1;
|
group by 1;
|
||||||
|
create table work.statuslibs as
|
||||||
|
select coalesce(a.libref,b.libref) as libref,
|
||||||
|
a.libsize,
|
||||||
|
a.table_cnt,
|
||||||
|
b.catalog_cnt
|
||||||
|
from work.sumdsn a
|
||||||
|
full join work.sumcat b
|
||||||
|
on a.libref=b.libref;
|
||||||
|
|
||||||
%bitemporal_dataloader(base_lib=&mpelib
|
%bitemporal_dataloader(base_lib=&mpelib
|
||||||
,base_dsn=mpe_datastatus_libs
|
,base_dsn=mpe_datastatus_libs
|
||||||
|
50
sas/sasjs/macros/mpe_refreshtables.test.sas
Normal file
50
sas/sasjs/macros/mpe_refreshtables.test.sas
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
/**
|
||||||
|
@file
|
||||||
|
@brief Testing mpe_refreshtables macro
|
||||||
|
|
||||||
|
<h4> SAS Macros </h4>
|
||||||
|
@li mpe_refreshtables.sas
|
||||||
|
@li mp_assert.sas
|
||||||
|
@li mp_assertscope.sas
|
||||||
|
|
||||||
|
@author 4GL Apps Ltd
|
||||||
|
@copyright 4GL Apps Ltd. This code may only be used within Data Controller
|
||||||
|
and may not be re-distributed or re-sold without the express permission of
|
||||||
|
4GL Apps Ltd.
|
||||||
|
|
||||||
|
**/
|
||||||
|
|
||||||
|
%mp_assertscope(SNAPSHOT)
|
||||||
|
%mpe_refreshtables(FMTONLY)
|
||||||
|
%mp_assertscope(COMPARE,
|
||||||
|
desc=Checking macro variables against previous snapshot
|
||||||
|
)
|
||||||
|
|
||||||
|
/* make sure that the process picks up a library that contains only a single
|
||||||
|
catalog */
|
||||||
|
proc sql;
|
||||||
|
create table work.libinfo as
|
||||||
|
select a.engine,
|
||||||
|
a.libname,
|
||||||
|
a.paths,
|
||||||
|
a.perms,
|
||||||
|
a.owners,
|
||||||
|
a.schemas,
|
||||||
|
a.libid,
|
||||||
|
b.libsize,
|
||||||
|
b.table_cnt,
|
||||||
|
b.catalog_cnt
|
||||||
|
from &mpelib..mpe_datacatalog_libs(where=(&dc_dttmtfmt. lt tx_to)) a
|
||||||
|
left join &mpelib..mpe_datastatus_libs(where=(&dc_dttmtfmt. lt tx_to)) b
|
||||||
|
on a.libref=b.libref
|
||||||
|
where a.libref="&libref";
|
||||||
|
|
||||||
|
%let test1=0;
|
||||||
|
data _null_;
|
||||||
|
set work.libinfo;
|
||||||
|
call symputx('test1',table_cnt);
|
||||||
|
run;
|
||||||
|
%mp_assert(
|
||||||
|
iftrue=(&test1>0),
|
||||||
|
desc=Checking fmtonly.dcfmts was picked up
|
||||||
|
)
|
@ -94,51 +94,18 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "viya",
|
"name": "viya",
|
||||||
"serverUrl": "https://sas.4gl.io",
|
"serverUrl": "https://viya-f0g8ht62vq.engage.sas.com",
|
||||||
"serverType": "SASVIYA",
|
"serverType": "SASVIYA",
|
||||||
"httpsAgentOptions": {
|
"httpsAgentOptions": {
|
||||||
"allowInsecureRequests": false
|
"allowInsecureRequests": false
|
||||||
},
|
},
|
||||||
"appLoc": "/Public/app/dc",
|
"appLoc": "/Public/app/dcplaceholder",
|
||||||
"macroFolders": [
|
|
||||||
"sasjs/targets/viya/macros_viya"
|
|
||||||
],
|
|
||||||
"programFolders": [
|
|
||||||
"sasjs/db/datactrl"
|
|
||||||
],
|
|
||||||
"binaryFolders": [],
|
|
||||||
"buildConfig": {
|
|
||||||
"initProgram": "sasjs/utils/buildinitviya.sas",
|
|
||||||
"termProgram": "sasjs/utils/buildtermviya.sas",
|
|
||||||
"buildResultsFolder": "sasjsresults",
|
|
||||||
"buildOutputFolder": "sasjsbuild",
|
|
||||||
"buildOutputFileName": "viya.sas"
|
|
||||||
},
|
|
||||||
"serviceConfig": {
|
|
||||||
"initProgram": "sasjs/utils/serviceinitviya.sas",
|
|
||||||
"serviceFolders": [
|
|
||||||
"sasjs/targets/viya/services_viya/viya_users",
|
|
||||||
"sasjs/targets/viya/services_viya/admin",
|
|
||||||
"sasjs/targets/viya/services_viya/public"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"deployConfig": {
|
"deployConfig": {
|
||||||
"deployServicePack": true,
|
"deployServicePack": true,
|
||||||
"deployScripts": [
|
"deployScripts": [
|
||||||
"sasjs/utils/viyadeploy.sh"
|
"sasjs/utils/viyadeploy.sh"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"contextName": "Datacontroller compute context"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "viyacloud",
|
|
||||||
"serverUrl": "https://4gl.viyacloud.sas.com",
|
|
||||||
"serverType": "SASVIYA",
|
|
||||||
"httpsAgentOptions": {
|
|
||||||
"rejectUnauthorized": false,
|
|
||||||
"allowInsecureRequests": true
|
|
||||||
},
|
|
||||||
"appLoc": "/30.SASApps/app/dc",
|
|
||||||
"macroFolders": [
|
"macroFolders": [
|
||||||
"sasjs/targets/viya/macros_viya"
|
"sasjs/targets/viya/macros_viya"
|
||||||
],
|
],
|
||||||
@ -147,36 +114,31 @@
|
|||||||
],
|
],
|
||||||
"buildConfig": {
|
"buildConfig": {
|
||||||
"initProgram": "sasjs/utils/buildinitviya.sas",
|
"initProgram": "sasjs/utils/buildinitviya.sas",
|
||||||
"termProgram": "sasjs/utils/buildtermviya.sas",
|
|
||||||
"macroVars": {
|
|
||||||
"dcpath": "/opt/sas/viya/config/var/tmp/dc",
|
|
||||||
"adminGroup": "DataBuilders"
|
|
||||||
},
|
|
||||||
"buildResultsFolder": "sasjsresults",
|
"buildResultsFolder": "sasjsresults",
|
||||||
"buildOutputFolder": "sasjsbuild",
|
"buildOutputFolder": "sasjsbuild",
|
||||||
"buildOutputFileName": "viya.sas"
|
"buildOutputFileName": "viya.sas",
|
||||||
|
"termProgram": "",
|
||||||
|
"macroVars": {}
|
||||||
},
|
},
|
||||||
"serviceConfig": {
|
"serviceConfig": {
|
||||||
"initProgram": "sasjs/utils/serviceinitviya.sas",
|
|
||||||
"serviceFolders": [
|
"serviceFolders": [
|
||||||
"sasjs/targets/viya/services_viya/viya_users",
|
"sasjs/targets/viya/services_viya/viya_users",
|
||||||
"sasjs/targets/viya/services_viya/admin",
|
"sasjs/targets/viya/services_viya/admin",
|
||||||
"sasjs/targets/viya/services_viya/public"
|
"sasjs/targets/viya/services_viya/public"
|
||||||
],
|
],
|
||||||
|
"initProgram": "sasjs/utils/serviceinitviya.sas",
|
||||||
"termProgram": "",
|
"termProgram": "",
|
||||||
"macroVars": {}
|
"macroVars": {}
|
||||||
},
|
},
|
||||||
"streamConfig": {
|
"streamConfig": {
|
||||||
"streamWeb": true,
|
"streamWeb": true,
|
||||||
"streamWebFolder": "webv",
|
"streamWebFolder": "web",
|
||||||
"webSourcePath": "../client/dist",
|
"webSourcePath": "../client/dist",
|
||||||
"streamServiceName": "clickme",
|
"streamServiceName": "DC",
|
||||||
|
"streamLogo": "favicon.ico",
|
||||||
"assetPaths": []
|
"assetPaths": []
|
||||||
},
|
},
|
||||||
"deployConfig": {
|
"contextName": "SAS Job Execution compute context"
|
||||||
"deployServicePack": true
|
|
||||||
},
|
|
||||||
"contextName": "Datacontroller compute context"
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "vtest",
|
"name": "vtest",
|
||||||
@ -312,38 +274,6 @@
|
|||||||
"assetPaths": []
|
"assetPaths": []
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"name": "server-vlad",
|
|
||||||
"serverUrl": "https://sas.4gl.io:5000",
|
|
||||||
"serverType": "SASJS",
|
|
||||||
"httpsAgentOptions": {
|
|
||||||
"allowInsecureRequests": false
|
|
||||||
},
|
|
||||||
"appLoc": "/30.SASApps/app/dc",
|
|
||||||
"macroFolders": [
|
|
||||||
"sasjs/targets/server/macros_server"
|
|
||||||
],
|
|
||||||
"programFolders": [
|
|
||||||
"sasjs/db/datactrl"
|
|
||||||
],
|
|
||||||
"serviceConfig": {
|
|
||||||
"serviceFolders": [
|
|
||||||
"sasjs/targets/server/services_server/admin",
|
|
||||||
"sasjs/targets/server/services_server/usernav"
|
|
||||||
],
|
|
||||||
"initProgram": "sasjs/utils/serviceinitserver.sas",
|
|
||||||
"termProgram": "",
|
|
||||||
"macroVars": {}
|
|
||||||
},
|
|
||||||
"streamConfig": {
|
|
||||||
"streamWeb": true,
|
|
||||||
"streamWebFolder": "webv",
|
|
||||||
"streamServiceName": "DataController",
|
|
||||||
"webSourcePath": "../client/dist",
|
|
||||||
"streamLogo": "favicon.ico",
|
|
||||||
"assetPaths": []
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"name": "mihajlo",
|
"name": "mihajlo",
|
||||||
"serverUrl": "https://sas.4gl.io",
|
"serverUrl": "https://sas.4gl.io",
|
||||||
|
27
sas/sasjs/services/admin/dirlist.sas
Normal file
27
sas/sasjs/services/admin/dirlist.sas
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
/**
|
||||||
|
@file
|
||||||
|
@brief Fetches directories to facilitate configuration
|
||||||
|
@details The service can also be invoked using the following URL param:
|
||||||
|
|
||||||
|
@li &parent= (parent path)
|
||||||
|
|
||||||
|
<h4> SAS Macros </h4>
|
||||||
|
@li mp_dirlist.sas
|
||||||
|
|
||||||
|
@version 9.2
|
||||||
|
@author 4GL Apps Ltd
|
||||||
|
@copyright 4GL Apps Ltd. This code may only be used within Data Controller
|
||||||
|
and may not be re-distributed or re-sold without the express permission of
|
||||||
|
4GL Apps Ltd.
|
||||||
|
|
||||||
|
**/
|
||||||
|
|
||||||
|
%global parent;
|
||||||
|
/* if no flavour is specified, default to root */
|
||||||
|
%let parent=%sysfunc(coalescec(&parent,/));
|
||||||
|
|
||||||
|
%mp_dirlist(path=&parent,outds=dirlist, maxdepth=2)
|
||||||
|
|
||||||
|
%webout(OPEN)
|
||||||
|
%webout(OBJ,dirlist)
|
||||||
|
%webout(CLOSE)
|
@ -675,7 +675,7 @@ data xl_rules;
|
|||||||
keep xl_column xl_rule;
|
keep xl_column xl_rule;
|
||||||
run;
|
run;
|
||||||
|
|
||||||
%mpe_dsmeta(&libds, outds=dsmeta)
|
%mpe_dsmeta(&orig_libds, outds=dsmeta)
|
||||||
|
|
||||||
%mpe_getversions(&mpelib,
|
%mpe_getversions(&mpelib,
|
||||||
%scan(&orig_libds,1,.),
|
%scan(&orig_libds,1,.),
|
||||||
|
@ -54,7 +54,10 @@ data _null_;
|
|||||||
/* if a TXTEMPORAL table then filter as such */
|
/* if a TXTEMPORAL table then filter as such */
|
||||||
call symputx('txfrom',var_txfrom);
|
call symputx('txfrom',var_txfrom);
|
||||||
call symputx('txto',var_txto);
|
call symputx('txto',var_txto);
|
||||||
|
run;
|
||||||
|
|
||||||
|
/* if a format, extract relevant info */
|
||||||
|
data _null_;
|
||||||
ds=symget('ds');
|
ds=symget('ds');
|
||||||
is_fmt=0;
|
is_fmt=0;
|
||||||
if subpad(cats(reverse(ds)),1,3)=:'CF-' then do;
|
if subpad(cats(reverse(ds)),1,3)=:'CF-' then do;
|
||||||
|
@ -76,3 +76,37 @@ run;
|
|||||||
test=EQUALS 3,
|
test=EQUALS 3,
|
||||||
outds=work.test_results
|
outds=work.test_results
|
||||||
)
|
)
|
||||||
|
|
||||||
|
/* test 3 - when there is a format catalog / nothing else in the library */
|
||||||
|
data work.params3;
|
||||||
|
length name $32 value $1000;
|
||||||
|
name='type';value='SAS';output;
|
||||||
|
name='table';value="FMTONLY.DCFMTS-FC";output;
|
||||||
|
name='filter';value='0';output;
|
||||||
|
run;
|
||||||
|
|
||||||
|
%mx_testservice(&_program,
|
||||||
|
viyacontext=&defaultcontext,
|
||||||
|
inputparams=work.params3,
|
||||||
|
outref=web3,
|
||||||
|
viyaresult=WEBOUT_TXT
|
||||||
|
)
|
||||||
|
|
||||||
|
data work.results3;
|
||||||
|
infile web3;
|
||||||
|
input;
|
||||||
|
putlog _infile_;
|
||||||
|
if _infile_=:'datalines4;' then do;
|
||||||
|
output;
|
||||||
|
output;
|
||||||
|
output;
|
||||||
|
stop;
|
||||||
|
end;
|
||||||
|
if _n_>100 then stop;
|
||||||
|
run;
|
||||||
|
|
||||||
|
%mp_assertdsobs(work.results3,
|
||||||
|
desc=datalines file is successfully returned for LONE format catalog,
|
||||||
|
test=EQUALS 3,
|
||||||
|
outds=work.test_results
|
||||||
|
)
|
||||||
|
@ -1,85 +1,86 @@
|
|||||||
/**
|
/**
|
||||||
@file refreshlibinfo.sas
|
@file refreshlibinfo.sas
|
||||||
@brief Refresh the Data Catalog for a particular library
|
@brief Refresh the Data Catalog for a particular library
|
||||||
@details When showing library info in the VIEW menu, the data is taken from
|
@details When showing library info in the VIEW menu, the data is taken from
|
||||||
the Data Catalog tables. These may be empty or outdated, and so this service
|
the Data Catalog tables. These may be empty or outdated, and so this service
|
||||||
allows end users to run a refresh of the data.
|
allows end users to run a refresh of the data.
|
||||||
|
|
||||||
<h4> Service Inputs </h4>
|
<h4> Service Inputs </h4>
|
||||||
<h5> lib2refresh </h5>
|
<h5> lib2refresh </h5>
|
||||||
Should contain the libref to be refreshed.
|
Should contain the libref to be refreshed.
|
||||||
|libref:$8.|
|
|libref:$8.|
|
||||||
|---|
|
|---|
|
||||||
|SOMELIB|
|
|SOMELIB|
|
||||||
|
|
||||||
<h4> Service Outputs </h4>
|
<h4> Service Outputs </h4>
|
||||||
|
|
||||||
<h5> libinfo </h5>
|
<h5> libinfo </h5>
|
||||||
|
|
||||||
|engine $|libname $|paths $|perms $|owners $|schemas $ |libid $|libsize $|table_cnt |
|
|engine $|libname $|paths $|perms $|owners $|schemas $ |libid $|libsize $|table_cnt |
|
||||||
|---|---|---|---|---|---|---|---|---|
|
|---|---|---|---|---|---|---|---|---|
|
||||||
|V9|SOMELIB|"some/path"|rwxrwxr-x|sassrv|` `|` `|636MB|33|
|
|V9|SOMELIB|"some/path"|rwxrwxr-x|sassrv|` `|` `|636MB|33|
|
||||||
|
|
||||||
<h4> SAS Macros </h4>
|
<h4> SAS Macros </h4>
|
||||||
@li dc_assignlib.sas
|
@li dc_assignlib.sas
|
||||||
@li dc_refreshcatalog.sas
|
@li dc_refreshcatalog.sas
|
||||||
@li mp_abort.sas
|
@li mp_abort.sas
|
||||||
|
|
||||||
@version 9.3
|
@version 9.3
|
||||||
@author 4GL Apps Ltd
|
@author 4GL Apps Ltd
|
||||||
@copyright 4GL Apps Ltd. This code may only be used within Data Controller
|
@copyright 4GL Apps Ltd. This code may only be used within Data Controller
|
||||||
and may not be re-distributed or re-sold without the express permission of
|
and may not be re-distributed or re-sold without the express permission of
|
||||||
4GL Apps Ltd.
|
4GL Apps Ltd.
|
||||||
**/
|
**/
|
||||||
|
|
||||||
|
|
||||||
%mpeinit()
|
%mpeinit()
|
||||||
|
|
||||||
%webout(FETCH)
|
%webout(FETCH)
|
||||||
|
|
||||||
%mp_abort(iftrue= (&syscc ne 0)
|
%mp_abort(iftrue= (&syscc ne 0)
|
||||||
,msg=%str(syscc=&syscc Problem on startup)
|
,msg=%str(syscc=&syscc Problem on startup)
|
||||||
)
|
)
|
||||||
|
|
||||||
%let libref=;
|
%let libref=;
|
||||||
data _null_;
|
data _null_;
|
||||||
set work.lib2refresh;
|
set work.lib2refresh;
|
||||||
call symputx('libref',libref);
|
call symputx('libref',libref);
|
||||||
run;
|
run;
|
||||||
|
|
||||||
%mp_abort(iftrue= (&syscc ne 0)
|
%mp_abort(iftrue= (&syscc ne 0)
|
||||||
,msg=%str(syscc=&syscc Problem with inputs - was lib2refresh object sent?)
|
,msg=%str(syscc=&syscc Problem with inputs - was lib2refresh object sent?)
|
||||||
)
|
)
|
||||||
|
|
||||||
%dc_assignlib(WRITE,&libref)
|
%dc_assignlib(WRITE,&libref)
|
||||||
|
|
||||||
%mp_abort(iftrue= (&syscc ne 0)
|
%mp_abort(iftrue= (&syscc ne 0)
|
||||||
,msg=%str(syscc=&syscc after lib assignment)
|
,msg=%str(syscc=&syscc after lib assignment)
|
||||||
)
|
)
|
||||||
|
|
||||||
%dc_refreshcatalog(&libref)
|
%dc_refreshcatalog(&libref)
|
||||||
|
|
||||||
%mp_abort(iftrue= (&syscc ne 0)
|
%mp_abort(iftrue= (&syscc ne 0)
|
||||||
,msg=%str(syscc=&syscc Problem when running the catalog refresh)
|
,msg=%str(syscc=&syscc Problem when running the catalog refresh)
|
||||||
)
|
)
|
||||||
|
|
||||||
/* get libinfo */
|
/* get libinfo */
|
||||||
proc sql;
|
proc sql;
|
||||||
create table work.libinfo as
|
create table work.libinfo as
|
||||||
select a.engine,
|
select a.engine,
|
||||||
a.libname,
|
a.libname,
|
||||||
a.paths,
|
a.paths,
|
||||||
a.perms,
|
a.perms,
|
||||||
a.owners,
|
a.owners,
|
||||||
a.schemas,
|
a.schemas,
|
||||||
a.libid,
|
a.libid,
|
||||||
b.libsize,
|
b.libsize,
|
||||||
b.table_cnt
|
b.table_cnt,
|
||||||
from &mpelib..mpe_datacatalog_libs(where=(&dc_dttmtfmt. lt tx_to)) a
|
b.catalog_cnt
|
||||||
inner join &mpelib..mpe_datastatus_libs(where=(&dc_dttmtfmt. lt tx_to)) b
|
from &mpelib..mpe_datacatalog_libs(where=(&dc_dttmtfmt. lt tx_to)) a
|
||||||
on a.libref=b.libref
|
inner join &mpelib..mpe_datastatus_libs(where=(&dc_dttmtfmt. lt tx_to)) b
|
||||||
where a.libref="&libref";
|
on a.libref=b.libref
|
||||||
|
where a.libref="&libref";
|
||||||
%webout(OPEN)
|
|
||||||
%webout(OBJ,libinfo)
|
%webout(OPEN)
|
||||||
%webout(CLOSE)
|
%webout(OBJ,libinfo)
|
||||||
|
%webout(CLOSE)
|
||||||
|
@ -355,7 +355,7 @@ run;
|
|||||||
|
|
||||||
%mp_getcols(&libds, outds=cols)
|
%mp_getcols(&libds, outds=cols)
|
||||||
|
|
||||||
%mpe_dsmeta(&libds, outds=dsmeta)
|
%mpe_dsmeta(&orig_libds, outds=dsmeta)
|
||||||
|
|
||||||
%mpe_getversions(&mpelib,
|
%mpe_getversions(&mpelib,
|
||||||
%scan(&orig_libds,1,.),
|
%scan(&orig_libds,1,.),
|
||||||
|
@ -167,7 +167,8 @@ create table work.libinfo as
|
|||||||
a.schemas,
|
a.schemas,
|
||||||
a.libid,
|
a.libid,
|
||||||
coalesce(b.libsize,0) as libsize,
|
coalesce(b.libsize,0) as libsize,
|
||||||
coalesce(b.table_cnt,0) as table_cnt
|
coalesce(b.table_cnt,0) as table_cnt,
|
||||||
|
coalesce(b.catalog_cnt,0) as catalog_cnt
|
||||||
from &mpelib..mpe_datacatalog_libs(where=(&dc_dttmtfmt. lt tx_to)) a
|
from &mpelib..mpe_datacatalog_libs(where=(&dc_dttmtfmt. lt tx_to)) a
|
||||||
left join &mpelib..mpe_datastatus_libs(where=(&dc_dttmtfmt. lt tx_to)) b
|
left join &mpelib..mpe_datastatus_libs(where=(&dc_dttmtfmt. lt tx_to)) b
|
||||||
on a.libref=b.libref
|
on a.libref=b.libref
|
||||||
|
@ -9,6 +9,7 @@
|
|||||||
<h4> SAS Macros </h4>
|
<h4> SAS Macros </h4>
|
||||||
@li mpe_refreshlibs.sas
|
@li mpe_refreshlibs.sas
|
||||||
@li dc_assignlib.sas
|
@li dc_assignlib.sas
|
||||||
|
@li mpe_refreshcatalogs.sas
|
||||||
@li mpe_refreshtables.sas
|
@li mpe_refreshtables.sas
|
||||||
@li mm_getrepos.sas
|
@li mm_getrepos.sas
|
||||||
|
|
||||||
@ -44,6 +45,7 @@ run;
|
|||||||
%dc_assignlib(WRITE,&libref) /* write just in order to assign direct lib */
|
%dc_assignlib(WRITE,&libref) /* write just in order to assign direct lib */
|
||||||
%mpe_refreshlibs(lib=&libref)
|
%mpe_refreshlibs(lib=&libref)
|
||||||
%mpe_refreshtables(&libref)
|
%mpe_refreshtables(&libref)
|
||||||
|
%mpe_refreshcatalogs(&libref)
|
||||||
%end;
|
%end;
|
||||||
%else %do xx=1 %to &repocnt;
|
%else %do xx=1 %to &repocnt;
|
||||||
options metarepository=&&repo&xx;
|
options metarepository=&&repo&xx;
|
||||||
@ -73,6 +75,7 @@ run;
|
|||||||
%do i=1 %to &libcnt;
|
%do i=1 %to &libcnt;
|
||||||
%dc_assignlib(WRITE,&&lib&i)
|
%dc_assignlib(WRITE,&&lib&i)
|
||||||
%mpe_refreshtables(&&lib&i)
|
%mpe_refreshtables(&&lib&i)
|
||||||
|
%mpe_refreshcatalogs(&&lib&i)
|
||||||
%end;
|
%end;
|
||||||
%end;
|
%end;
|
||||||
|
|
||||||
|
@ -9,6 +9,7 @@
|
|||||||
<h4> SAS Macros </h4>
|
<h4> SAS Macros </h4>
|
||||||
@li mpe_refreshlibs.sas
|
@li mpe_refreshlibs.sas
|
||||||
@li dc_assignlib.sas
|
@li dc_assignlib.sas
|
||||||
|
@li mpe_refreshcatalogs.sas
|
||||||
@li mpe_refreshtables.sas
|
@li mpe_refreshtables.sas
|
||||||
|
|
||||||
|
|
||||||
@ -34,6 +35,8 @@ data libraries;
|
|||||||
str=cats('%mpe_refreshtables(',libref,')');
|
str=cats('%mpe_refreshtables(',libref,')');
|
||||||
put str;
|
put str;
|
||||||
putlog str;
|
putlog str;
|
||||||
|
str=cats('%mpe_refreshcatalogs(',libref,')');
|
||||||
|
put str;
|
||||||
run;
|
run;
|
||||||
%inc executor/source2;
|
%inc executor/source2;
|
||||||
|
|
||||||
|
@ -10,6 +10,7 @@
|
|||||||
@li mpe_refreshlibs.sas
|
@li mpe_refreshlibs.sas
|
||||||
@li dc_assignlib.sas
|
@li dc_assignlib.sas
|
||||||
@li mpe_refreshtables.sas
|
@li mpe_refreshtables.sas
|
||||||
|
@li mpe_refreshcatalogs.sas
|
||||||
|
|
||||||
|
|
||||||
@version 3.4
|
@version 3.4
|
||||||
@ -19,19 +20,29 @@
|
|||||||
4GL Apps Ltd.
|
4GL Apps Ltd.
|
||||||
**/
|
**/
|
||||||
|
|
||||||
%macro dc_refreshcatalog();
|
%macro dc_refreshcatalog(libref);
|
||||||
|
|
||||||
%mpe_refreshlibs()
|
%if #&libref# ne ## %then %do;
|
||||||
|
%put &sysmacroname: assigning specific libref, &libref;
|
||||||
filename executor catalog 'work.code.code.source';
|
%dc_assignlib(WRITE,&libref) /* write just in order to assign direct lib */
|
||||||
data libraries;
|
%mpe_refreshlibs(lib=&libref)
|
||||||
set &mpelib..mpe_datacatalog_libs;
|
%mpe_refreshtables(&libref)
|
||||||
where &dc_dttmtfmt. le TX_TO;
|
%mpe_refreshcatalogs(&libref)
|
||||||
file executor;
|
%end;
|
||||||
str=cats('%mpe_refreshtables(',libref,')');
|
%else %do;
|
||||||
put str;
|
%mpe_refreshlibs()
|
||||||
putlog str;
|
filename executor catalog 'work.code.code.source';
|
||||||
run;
|
data libraries;
|
||||||
%inc executor;
|
set &mpelib..mpe_datacatalog_libs;
|
||||||
|
where &dc_dttmtfmt. le TX_TO;
|
||||||
|
file executor;
|
||||||
|
str=cats('%mpe_refreshtables(',libref,')');
|
||||||
|
put str;
|
||||||
|
str=cats('%mpe_refreshcatalogs(',libref,')');
|
||||||
|
put str;
|
||||||
|
putlog str;
|
||||||
|
run;
|
||||||
|
%inc executor;
|
||||||
|
%end;
|
||||||
|
|
||||||
%mend dc_refreshcatalog;
|
%mend dc_refreshcatalog;
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
@li mf_getapploc.sas
|
@li mf_getapploc.sas
|
||||||
@li mf_mkdir.sas
|
@li mf_mkdir.sas
|
||||||
@li mf_trimstr.sas
|
@li mf_trimstr.sas
|
||||||
|
@li mp_abort.sas
|
||||||
@li mpe_getvars.sas
|
@li mpe_getvars.sas
|
||||||
@li mpe_makedata.sas
|
@li mpe_makedata.sas
|
||||||
@li mpe_makedatamodel.sas
|
@li mpe_makedatamodel.sas
|
||||||
@ -50,9 +51,33 @@ options noquotelenmax;
|
|||||||
%put &=admin;
|
%put &=admin;
|
||||||
|
|
||||||
%mf_mkdir(&dcpath)
|
%mf_mkdir(&dcpath)
|
||||||
|
%mp_abort(iftrue= (&syscc ne 0)
|
||||||
|
,mac=&_program
|
||||||
|
,msg=%str(Unable to create &dcpath using &sysuserid)
|
||||||
|
)
|
||||||
%mf_mkdir(&dcpath/secret)
|
%mf_mkdir(&dcpath/secret)
|
||||||
%mf_mkdir(&dcpath/dc_staging)
|
%mf_mkdir(&dcpath/dc_staging)
|
||||||
|
|
||||||
|
/* check we have physical permissions to the DCLIB folder */
|
||||||
|
data _null_;
|
||||||
|
putlog "dcpath=&dcpath/permTest.txt";
|
||||||
|
putlog "sysuserid=&sysuserid";
|
||||||
|
data _null_;
|
||||||
|
file "&dcpath/permTest.txt";
|
||||||
|
run;
|
||||||
|
%mp_abort(iftrue= (&syscc ne 0)
|
||||||
|
,mac=&_program
|
||||||
|
,msg=%str(User &sysuserid does not have WRITE permissions to: &dcpath )
|
||||||
|
)
|
||||||
|
filename delfile "&dcpath/permTest.txt";
|
||||||
|
data _null_;
|
||||||
|
rc=fdelete('delfile');
|
||||||
|
run;
|
||||||
|
%mp_abort(iftrue= (&syscc ne 0)
|
||||||
|
,mac=&_program..sas
|
||||||
|
,msg=%str(User &sysuserid could create (but not delete) &dcpath/permTest.txt )
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
libname &dclib "&dcpath";
|
libname &dclib "&dcpath";
|
||||||
%global admin;
|
%global admin;
|
||||||
@ -60,11 +85,23 @@ libname &dclib "&dcpath";
|
|||||||
%mpe_makedatamodel(lib=&dclib)
|
%mpe_makedatamodel(lib=&dclib)
|
||||||
%mpe_makedata(lib=&dclib,mpeadmins=&admin,path=%str(&dcpath))
|
%mpe_makedata(lib=&dclib,mpeadmins=&admin,path=%str(&dcpath))
|
||||||
|
|
||||||
|
%mp_abort(iftrue=(&syscc ne 0)
|
||||||
|
,mac=&sysmacroname
|
||||||
|
,msg=%str(Err during &dclib build)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
/* sample data library */
|
/* sample data library */
|
||||||
%mf_mkdir(&dcpath/dc_demo)
|
%mf_mkdir(&dcpath/dc_demo)
|
||||||
libname dcdemo "&dcpath/dc_demo";
|
libname dcdemo "&dcpath/dc_demo";
|
||||||
%mpe_makesampledata(outlib=DCDEMO)
|
%mpe_makesampledata(outlib=DCDEMO)
|
||||||
|
|
||||||
|
%mp_abort(iftrue=(&syscc ne 0)
|
||||||
|
,mac=&sysmacroname
|
||||||
|
,msg=%str(Err during demo data build)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
/* the DC precode is stored in the root of the project */
|
/* the DC precode is stored in the root of the project */
|
||||||
%let root=%mf_getapploc(&_program)/services;
|
%let root=%mf_getapploc(&_program)/services;
|
||||||
%put &=root;
|
%put &=root;
|
||||||
@ -167,7 +204,7 @@ run;
|
|||||||
*/
|
*/
|
||||||
%mp_abort(iftrue=(&syscc ne 0)
|
%mp_abort(iftrue=(&syscc ne 0)
|
||||||
,mac=&sysmacroname
|
,mac=&sysmacroname
|
||||||
,msg=%str(Err during DB build)
|
,msg=%str(Err during settings job creation)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@ -21,7 +21,7 @@ REMOVE THAT LAST MACRO
|
|||||||
%let syscc=0;
|
%let syscc=0;
|
||||||
%global apploc _program dclib defaultcontext _debug sasjs_mdebug dc_dttmtfmt;
|
%global apploc _program dclib defaultcontext _debug sasjs_mdebug dc_dttmtfmt;
|
||||||
|
|
||||||
%let defaultcontext=Datacontroller compute context;
|
%let defaultcontext=SAS Job Execution compute context;
|
||||||
%let sasjs_mdebug=0;
|
%let sasjs_mdebug=0;
|
||||||
|
|
||||||
options mprint mprintnest nobomfile lrecl=32767;
|
options mprint mprintnest nobomfile lrecl=32767;
|
||||||
|
@ -28,7 +28,7 @@
|
|||||||
|
|
||||||
%global apploc _program;
|
%global apploc _program;
|
||||||
|
|
||||||
%let defaultcontext=Datacontroller compute context;
|
%let defaultcontext=SAS Job Execution compute context;
|
||||||
|
|
||||||
data _null_;
|
data _null_;
|
||||||
length _pgm $1000;
|
length _pgm $1000;
|
||||||
@ -60,6 +60,9 @@ run;
|
|||||||
%let testloc=%sysfunc(pathname(&DC_LIBREF))/fmt%mf_getuniquefileref();
|
%let testloc=%sysfunc(pathname(&DC_LIBREF))/fmt%mf_getuniquefileref();
|
||||||
%mf_mkdir(&testloc)
|
%mf_mkdir(&testloc)
|
||||||
libname dctest "&testloc";
|
libname dctest "&testloc";
|
||||||
|
/* test library with only one format catalog */
|
||||||
|
%mf_mkdir(&testloc/fmtonly)
|
||||||
|
libname fmtonly "&testloc/fmtonly";
|
||||||
|
|
||||||
/* add formats */
|
/* add formats */
|
||||||
PROC FORMAT library=dctest.dcfmts;
|
PROC FORMAT library=dctest.dcfmts;
|
||||||
@ -99,6 +102,10 @@ run;
|
|||||||
proc append base=&dc_libref..mpe_tables data=work.append;
|
proc append base=&dc_libref..mpe_tables data=work.append;
|
||||||
run;
|
run;
|
||||||
|
|
||||||
|
/* lone format catalog */
|
||||||
|
proc format cntlin=work.fmts library=fmtonly.dcfmts;
|
||||||
|
run;
|
||||||
|
|
||||||
/* add some other tables */
|
/* add some other tables */
|
||||||
%mp_coretable(LOCKTABLE,libds=dctest.locktable)
|
%mp_coretable(LOCKTABLE,libds=dctest.locktable)
|
||||||
%mp_coretable(DIFFTABLE,libds=dctest.difftable)
|
%mp_coretable(DIFFTABLE,libds=dctest.difftable)
|
||||||
@ -130,6 +137,7 @@ options mprint;
|
|||||||
put _infile_;
|
put _infile_;
|
||||||
if last then do;
|
if last then do;
|
||||||
put "libname dctest '&testloc';";
|
put "libname dctest '&testloc';";
|
||||||
|
put "libname fmtonly '&testloc/fmtonly';";
|
||||||
end;
|
end;
|
||||||
run;
|
run;
|
||||||
data _null_;
|
data _null_;
|
||||||
@ -151,6 +159,7 @@ options mprint;
|
|||||||
put _infile_;
|
put _infile_;
|
||||||
if last then do;
|
if last then do;
|
||||||
put "libname dctest '&testloc';";
|
put "libname dctest '&testloc';";
|
||||||
|
put "libname fmtonly '&testloc/fmtonly';";
|
||||||
end;
|
end;
|
||||||
run;
|
run;
|
||||||
%ms_deletefile(&root/services/public/settings.sas)
|
%ms_deletefile(&root/services/public/settings.sas)
|
||||||
@ -182,6 +191,7 @@ options mprint;
|
|||||||
put _infile_;
|
put _infile_;
|
||||||
if last then do;
|
if last then do;
|
||||||
put "libname dctest '&testloc';";
|
put "libname dctest '&testloc';";
|
||||||
|
put "libname fmtonly '&testloc/fmtonly';";
|
||||||
end;
|
end;
|
||||||
run;
|
run;
|
||||||
%mm_deletestp(target=&root/services/public/Data_Controller_Settings)
|
%mm_deletestp(target=&root/services/public/Data_Controller_Settings)
|
||||||
|
@ -2,6 +2,20 @@
|
|||||||
@file buildinitviya.sas
|
@file buildinitviya.sas
|
||||||
@brief initialisation for viya build program
|
@brief initialisation for viya build program
|
||||||
|
|
||||||
|
<h4> SAS Macros </h4>
|
||||||
|
@li mfv_getfolderpath.sas
|
||||||
|
@li mfv_getpathuri.sas
|
||||||
|
@li mv_createfolder.sas
|
||||||
|
|
||||||
**/
|
**/
|
||||||
|
|
||||||
options nonotes nomprint;
|
options nonotes nomprint;
|
||||||
|
|
||||||
|
/* update apploc to default to user home area if not set */
|
||||||
|
%let apploc=%sysfunc(ifc("&apploc"="/Public/app/dcplaceholder"
|
||||||
|
,/Users/&sysuserid/My Folder/Data Controller
|
||||||
|
,&apploc));
|
||||||
|
|
||||||
|
/* ensure the correct casing of appLoc */
|
||||||
|
%mv_createfolder(path=&apploc)
|
||||||
|
%let apploc=%mfv_getfolderpath(%mfv_getpathuri(&apploc));
|
Reference in New Issue
Block a user