59 Commits

Author SHA1 Message Date
8c60473c15 chore(release): 7.0.0 [skip ci]
# [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](e874143a95))
* commit git hooks checking lint ([69f687a](69f687a85f))
* ensuring apploc is not case sensitive. Closes [#171](#171) ([24545f2](24545f2acd))
* export unregistered formats ([f6d7d6f](f6d7d6f90c)), closes [#158](#158)
* reload startupservice after user approves the MPE_TABLES page ([e5f8e50](e5f8e500c1))
* showing catalog_cnt in libinfo ([e44a25d](e44a25dcc3)), closes [#160](#160)

### Features

* adding 4 new tables for catalogs ([e4dbab8](e4dbab8b16))
* capturing catalog specific information, closes [#159](#159) ([b4c586a](b4c586a859))
* viewer added catalog_cnt ([2aa19d1](2aa19d1dca))

### 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)
2025-06-11 13:46:10 +00:00
bb126eba5b Merge pull request 'Reload startupservice after user approves the MPE_TABLES changes' (#170) from issue157 into main
All checks were successful
Release / Build-production-and-ng-test (push) Successful in 4m8s
Release / Build-and-test-development (push) Successful in 8m47s
Release / release (push) Successful in 8m50s
Reviewed-on: #170
2025-06-11 13:16:22 +00:00
d1998422d2 chore: fix for mpe_datastatus_libs
All checks were successful
Build / Build-and-ng-test (pull_request) Successful in 4m19s
Build / Build-and-test-development (pull_request) Successful in 8m45s
2025-06-11 14:15:50 +01:00
69f687a85f fix: commit git hooks checking lint
All checks were successful
Build / Build-and-ng-test (pull_request) Successful in 4m11s
Build / Build-and-test-development (pull_request) Successful in 8m34s
2025-06-11 13:11:30 +02:00
2aa19d1dca feat: viewer added catalog_cnt
Some checks failed
Build / Build-and-ng-test (pull_request) Failing after 48s
Build / Build-and-test-development (pull_request) Successful in 8m49s
2025-06-11 12:57:10 +02:00
e44a25dcc3 fix: showing catalog_cnt in libinfo
All checks were successful
Build / Build-and-ng-test (pull_request) Successful in 4m19s
Build / Build-and-test-development (pull_request) Successful in 8m53s
Closes #160
2025-06-11 10:06:52 +01:00
efb5ffa906 chore: reverting accidental change
All checks were successful
Build / Build-and-ng-test (pull_request) Successful in 4m4s
Build / Build-and-test-development (pull_request) Successful in 8m33s
2025-06-10 22:45:39 +01:00
b4c586a859 feat: capturing catalog specific information, closes #159
All checks were successful
Build / Build-and-ng-test (pull_request) Successful in 4m12s
Build / Build-and-test-development (pull_request) Successful in 8m35s
BREAKING CHANGE:  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)
2025-06-10 22:40:09 +01:00
e874143a95 fix: bumping adapter to re-enable JES API method 2025-06-10 16:18:56 +01:00
e4dbab8b16 feat: adding 4 new tables for catalogs 2025-06-10 16:18:30 +01:00
f6d7d6f90c fix: export unregistered formats
All checks were successful
Build / Build-and-ng-test (pull_request) Successful in 4m14s
Build / Build-and-test-development (pull_request) Successful in 9m0s
Closes #158
2025-06-10 09:41:18 +01:00
063c90caf4 chore(docs): readme fix
All checks were successful
Build / Build-and-ng-test (pull_request) Successful in 4m3s
Build / Build-and-test-development (pull_request) Successful in 8m38s
2025-06-06 23:24:35 +01:00
2011c2eee7 chore(docs): updating README with viya deploy details
All checks were successful
Build / Build-and-ng-test (pull_request) Successful in 4m0s
Build / Build-and-test-development (pull_request) Successful in 8m28s
2025-06-06 23:23:47 +01:00
24545f2acd fix: ensuring apploc is not case sensitive. Closes #171
All checks were successful
Build / Build-and-ng-test (pull_request) Successful in 4m6s
Build / Build-and-test-development (pull_request) Successful in 8m38s
2025-06-06 21:05:08 +01:00
a7c81245ff Merge branch 'main' into issue157
All checks were successful
Build / Build-and-ng-test (pull_request) Successful in 4m6s
Build / Build-and-test-development (pull_request) Successful in 8m45s
2025-06-06 13:17:17 +00:00
4f2c993b2d style: lint
All checks were successful
Build / Build-and-ng-test (pull_request) Successful in 4m3s
Build / Build-and-test-development (pull_request) Successful in 8m35s
2025-06-06 15:03:51 +02:00
e5f8e500c1 fix: reload startupservice after user approves the MPE_TABLES page 2025-06-06 15:03:36 +02:00
a61e2de140 chore(release): 6.16.2 [skip ci]
## [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](4830c6d219))
2025-06-06 11:36:00 +00:00
881d2b060e Merge pull request 'fix: streaming viya deploy isStreaming function stability fix' (#169) from viya-deploy into main
All checks were successful
Release / Build-production-and-ng-test (push) Successful in 3m53s
Release / Build-and-test-development (push) Successful in 8m36s
Release / release (push) Successful in 8m18s
Reviewed-on: #169
2025-06-06 11:08:03 +00:00
4830c6d219 fix: streaming viya deploy isStreaming function stability fix
All checks were successful
Build / Build-and-ng-test (pull_request) Successful in 3m59s
Build / Build-and-test-development (pull_request) Successful in 8m30s
2025-06-06 13:06:55 +02:00
4c3c9ac88c chore(release): 6.16.1 [skip ci]
## [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](86134f478a))
* viya streamed app deploy page flow fix ([89ab296](89ab296151))
2025-06-06 10:35:30 +00:00
7e1c610a4d Merge pull request 'Viya deploy, updating the compute context in index.html file, found based on URL' (#168) from viya-deploy into main
All checks were successful
Release / Build-production-and-ng-test (push) Successful in 3m54s
Release / Build-and-test-development (push) Successful in 8m30s
Release / release (push) Successful in 8m19s
Reviewed-on: #168
2025-06-06 10:19:20 +00:00
8139f495ce style: lint
All checks were successful
Build / Build-and-ng-test (pull_request) Successful in 4m4s
Build / Build-and-test-development (pull_request) Successful in 8m33s
2025-06-06 12:06:10 +02:00
89ab296151 fix: viya streamed app deploy page flow fix 2025-06-06 12:05:52 +02:00
a0dc92c403 style: lint
All checks were successful
Build / Build-and-ng-test (pull_request) Successful in 4m15s
Build / Build-and-test-development (pull_request) Successful in 8m34s
2025-06-06 10:58:01 +02:00
86134f478a fix: viya deploy updating index html based on URL 2025-06-06 10:57:41 +02:00
9a2addc18e chore(release): 6.16.0 [skip ci]
# [6.16.0](https://git.datacontroller.io/dc/dc/compare/v6.15.2...v6.16.0) (2025-06-05)

### Bug Fixes

* adapter bump ([ca7caa2](ca7caa25b6))
* automatic viya deploy timing issue ([037a97b](037a97b6ff))
* bump core to ensure ff works on viya streaming deploy ([cbd69df](cbd69df708)), closes [#156](#156)
* viya deploy load data timing ([abdbb67](abdbb67471))

### Features

* viya deploy, update the index.html contextname ([7223955](72239558af))
2025-06-05 13:53:03 +00:00
9264ce2a60 Merge pull request 'Adapter bump, including getFileContent and updateFileContent' (#167) from adapter-bump into main
All checks were successful
Release / Build-production-and-ng-test (push) Successful in 4m4s
Release / Build-and-test-development (push) Successful in 9m9s
Release / release (push) Successful in 8m19s
Reviewed-on: #167
2025-06-05 13:17:06 +00:00
cbd69df708 fix: bump core to ensure ff works on viya streaming deploy
All checks were successful
Build / Build-and-ng-test (pull_request) Successful in 4m3s
Build / Build-and-test-development (pull_request) Successful in 8m39s
closes #156 (along with previous releases)
2025-06-05 14:16:44 +01:00
ca7caa25b6 fix: adapter bump
All checks were successful
Build / Build-and-ng-test (pull_request) Successful in 4m9s
Build / Build-and-test-development (pull_request) Successful in 8m45s
2025-06-05 14:49:21 +02:00
c10330627f Merge pull request 'Viya smooth deploy' (#166) from deploy-context into main
Some checks failed
Release / Build-production-and-ng-test (push) Has been cancelled
Release / Build-and-test-development (push) Has been cancelled
Release / release (push) Has been cancelled
Reviewed-on: #166
2025-06-05 12:30:29 +00:00
d80c59afce Merge branch 'main' into deploy-context
Some checks failed
Build / Build-and-ng-test (pull_request) Has been cancelled
Build / Build-and-test-development (pull_request) Has been cancelled
2025-06-05 12:30:19 +00:00
abdbb67471 fix: viya deploy load data timing
Some checks failed
Build / Build-and-ng-test (pull_request) Failing after 4m0s
Build / Build-and-test-development (pull_request) Failing after 2h56m12s
2025-06-05 12:07:26 +02:00
037a97b6ff fix: automatic viya deploy timing issue 2025-06-04 17:37:44 +02:00
a0a529ad38 style: lint 2025-06-04 17:36:13 +02:00
72239558af feat: viya deploy, update the index.html contextname 2025-06-04 17:35:15 +02:00
d2097ad6dd chore(release): 6.15.2 [skip ci]
## [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](624a7a8f37))
2025-06-04 14:26:44 +00:00
1bd542cddb Merge pull request 'fix: pipeline updates for DC.html' (#165) from issue156b into main
All checks were successful
Release / Build-production-and-ng-test (push) Successful in 4m29s
Release / Build-and-test-development (push) Successful in 8m37s
Release / release (push) Successful in 8m17s
Reviewed-on: #165
2025-06-04 13:53:24 +00:00
fb1c1ee874 Merge branch 'main' into issue156b
All checks were successful
Build / Build-and-ng-test (pull_request) Successful in 4m1s
Build / Build-and-test-development (pull_request) Successful in 8m34s
2025-06-04 13:48:58 +00:00
624a7a8f37 fix: pipeline updates for DC.html
All checks were successful
Build / Build-and-ng-test (pull_request) Successful in 4m5s
Build / Build-and-test-development (pull_request) Successful in 8m42s
2025-06-04 14:41:36 +01:00
381378f532 chore(release): 6.15.1 [skip ci]
## [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](4b558948d9))
2025-06-04 12:57:08 +00:00
af05486c0e Merge pull request 'fix: updating pipeline to default to streaming on viya' (#164) from issue156b into main
Some checks failed
Release / Build-production-and-ng-test (push) Successful in 3m57s
Release / Build-and-test-development (push) Successful in 8m41s
Release / release (push) Failing after 7m35s
Reviewed-on: #164
2025-06-04 12:28:12 +00:00
4b558948d9 fix: updating pipeline to default to streaming on viya
All checks were successful
Build / Build-and-ng-test (pull_request) Successful in 4m4s
Build / Build-and-test-development (pull_request) Successful in 8m33s
Also added error captures on makedata
2025-06-04 13:27:28 +01:00
d9cff42f5c chore(release): 6.15.0 [skip ci]
# [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](da4d0b28c7))

### Features

* viya deploy context ([6c96ef7](6c96ef7fb0))
2025-06-04 09:26:02 +00:00
2a3d2b8d0d Merge pull request 'feat: viya deploy context' (#163) from deploy-context into main
All checks were successful
Release / Build-production-and-ng-test (push) Successful in 4m3s
Release / Build-and-test-development (push) Successful in 8m39s
Release / release (push) Successful in 8m30s
Reviewed-on: #163
2025-06-04 09:09:28 +00:00
d0f453d291 chore: typo
All checks were successful
Build / Build-and-ng-test (pull_request) Successful in 3m59s
Build / Build-and-test-development (pull_request) Successful in 8m31s
2025-06-04 09:41:06 +02:00
8e65dd0eae style: lint
All checks were successful
Build / Build-and-ng-test (pull_request) Successful in 3m59s
Build / Build-and-test-development (pull_request) Successful in 8m25s
2025-06-03 21:06:48 +02:00
da4d0b28c7 fix: makedata with context name
Some checks failed
Build / Build-and-ng-test (pull_request) Failing after 49s
Build / Build-and-test-development (pull_request) Successful in 8m32s
2025-06-03 21:00:54 +02:00
6c96ef7fb0 feat: viya deploy context
Some checks failed
Build / Build-and-ng-test (pull_request) Failing after 47s
Build / Build-and-test-development (pull_request) Successful in 8m35s
2025-06-03 20:22:39 +02:00
997f09adde chore(release): 6.14.10 [skip ci]
## [6.14.10](https://git.datacontroller.io/dc/dc/compare/v6.14.9...v6.14.10) (2025-06-02)

### Bug Fixes

* bump core ([0e8503e](0e8503ed2b))
* default to home directory for SAS Drive in Viya ([9682b54](9682b548e6))
2025-06-02 17:51:20 +00:00
0e8503ed2b fix: bump core
All checks were successful
Release / Build-production-and-ng-test (push) Successful in 4m31s
Release / Build-and-test-development (push) Successful in 8m40s
Release / release (push) Successful in 8m20s
2025-06-02 18:32:33 +01:00
97dfcd79b1 Merge pull request 'issue156' (#161) from issue156 into main
Some checks failed
Release / Build-and-test-development (push) Has been cancelled
Release / release (push) Has been cancelled
Release / Build-production-and-ng-test (push) Has been cancelled
Reviewed-on: #161
2025-06-02 17:29:18 +00:00
9a12a2e41f Merge branch 'main' into issue156
Some checks failed
Build / Build-and-ng-test (pull_request) Successful in 4m9s
Build / Build-and-test-development (pull_request) Has been cancelled
2025-06-02 17:27:14 +00:00
5c114e562b chore(release): 6.14.9 [skip ci]
## [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](f3125ff464))
2025-06-02 10:36:05 +00:00
ae696a0be0 Merge pull request 'Viya default DC Path by user name' (#162) from viya-smooth-deploy into main
All checks were successful
Release / Build-production-and-ng-test (push) Successful in 3m56s
Release / Build-and-test-development (push) Successful in 8m33s
Release / release (push) Successful in 8m22s
Reviewed-on: #162
2025-06-02 10:19:51 +00:00
22d46a5dcc style: lint
All checks were successful
Build / Build-and-ng-test (pull_request) Successful in 4m8s
Build / Build-and-test-development (pull_request) Successful in 8m34s
2025-06-02 11:24:30 +02:00
f3125ff464 fix: default DC path for viya 2025-06-02 11:24:18 +02:00
9682b548e6 fix: default to home directory for SAS Drive in Viya
All checks were successful
Build / Build-and-ng-test (pull_request) Successful in 4m10s
Build / Build-and-test-development (pull_request) Successful in 8m35s
2025-05-29 15:05:18 +01:00
2e0c60cc0d chore: fix package-lock 2025-05-28 18:57:43 +02:00
54 changed files with 1421 additions and 294 deletions

View File

@ -1,11 +1,12 @@
#!/bin/sh
# Avoid commits to the master branch
BRANCH=`git rev-parse --abbrev-ref HEAD`
REGEX="^(master|development)$"
# Using `--silent` helps for showing any errs in the first line of the response
# The first line is picked up by the VS Code GIT UI popup when rc is not 0
if [[ "$BRANCH" =~ $REGEX ]]; then
echo "You are on branch $BRANCH. Are you sure you want to commit to this branch?"
echo "If so, commit with -n to bypass the pre-commit hook."
if npm run --silent lint:silent ; then
exit 0
else
npm run --silent lint:fix
echo "❌ Prettier check failed! We ran lint:fix for you. Please add & commit again."
exit 1
fi

View File

@ -237,20 +237,20 @@ jobs:
cd sas
sasjs c -t viya
rm -rf sasjsbuild/tests
sed -i -e 's/servertype="SASJS"/servertype="SASVIYA"/g' sasjsbuild/services/clickme.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
sed -i -e 's/servertype="SASJS"/servertype="SASVIYA"/g' sasjsbuild/services/DC.html
sasjs b -t viya
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)
run: |
cd sas
cp sasjsbuild/viya.json ../client/dist
cp sasjsbuild/viya.json ../client/dist/viya.json
cd ..
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 }}"
curl -k $URL -F attachment=@frontend.zip
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/sas9.sas
curl -k $URL -F attachment=@sas/viya.sas
curl -k $URL -F attachment=@sas/viya.json
curl -k $URL -F attachment=@sas/viya_noweb.sas
curl -k $URL -F attachment=@sas/viya_noweb.json

View File

@ -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)

View File

@ -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).
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
* Docs: https://docs.datacontroller.io

View File

@ -21,7 +21,7 @@
"@clr/icons": "^13.0.2",
"@clr/ui": "file:libraries/clr-ui-17.9.0.tgz",
"@handsontable/angular": "^15.3.0",
"@sasjs/adapter": "^4.11.0",
"@sasjs/adapter": "^4.12.1",
"@sasjs/utils": "^3.4.0",
"@sheet/crypto": "file:libraries/sheet-crypto.tgz",
"@types/d3-graphviz": "^2.6.7",
@ -5912,9 +5912,9 @@
]
},
"node_modules/@sasjs/adapter": {
"version": "4.11.3",
"resolved": "https://registry.npmjs.org/@sasjs/adapter/-/adapter-4.11.3.tgz",
"integrity": "sha512-KF6G4vzs4l4efjpCD02og3kB44uFfJ1u2UWu749VdHtLKNN9l+PO26/moR+YAmRmmz2I9sC3X09fZE1nlN6zgw==",
"version": "4.12.1",
"resolved": "https://registry.npmjs.org/@sasjs/adapter/-/adapter-4.12.1.tgz",
"integrity": "sha512-0217oZIkrecOyQygRe6Azgc1C4TIcjB5noi15fU4Rd5GsfDpleKVfQQdzYZ7im/vesWlLIVl/yUT67MMaQe0ew==",
"hasInstallScript": true,
"license": "ISC",
"dependencies": {

View File

@ -49,7 +49,7 @@
"@clr/icons": "^13.0.2",
"@clr/ui": "file:libraries/clr-ui-17.9.0.tgz",
"@handsontable/angular": "^15.3.0",
"@sasjs/adapter": "^4.11.0",
"@sasjs/adapter": "^4.12.1",
"@sasjs/utils": "^3.4.0",
"@sheet/crypto": "file:libraries/sheet-crypto.tgz",
"@types/d3-graphviz": "^2.6.7",

View File

@ -98,14 +98,14 @@
<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="clr-input-wrapper">
<div class="clr-input-wrapper small-mt">
<input clrInput name="dcloc" [(ngModel)]="dcPath" />
</div>
</div>
<label for="dcloc" class="mt-20 clr-control-label">SAS Admin group</label>
<div class="mb-10 clr-control-container">
<div class="clr-input-wrapper">
<div class="clr-input-wrapper small-mt">
<select
*ngIf="!adminGroupsLoading"
clrSelect
@ -124,6 +124,42 @@
</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) -->
<!-- <clr-checkbox-wrapper>

View File

@ -8,15 +8,22 @@ import {
} from '@angular/core'
import SASjs, { SASjsConfig } from '@sasjs/adapter'
import { DcAdapterSettings } from 'src/app/models/DcAdapterSettings'
import { HelperService } from 'src/app/services'
import { DeployService } from 'src/app/services/deploy.service'
import { EventService } from 'src/app/services/event.service'
import { LoggerService } from 'src/app/services/logger.service'
import { SasViyaService } from 'src/app/services/sas-viya.service'
import { SasService } from 'src/app/services/sas.service'
import { ViyaApiCurrentUser } from 'src/app/viya-api-explorer/models/viya-api-current-user.model'
import {
Item,
ViyaApiIdentities
} 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({
selector: 'app-automatic-deploy',
@ -34,6 +41,7 @@ export class AutomaticComponent implements OnInit {
@Output() onNavigateToHome: EventEmitter<any> = new EventEmitter<any>()
public selectedComputeContext: string = ''
public makeDataResponse: string = ''
public jsonFile: any = null
public autodeploying: boolean = false
@ -48,7 +56,12 @@ export class AutomaticComponent implements OnInit {
public recreateDatabase: boolean = true
public createDatabaseLoading: boolean = false
public adminGroupsLoading: boolean = false
public currentUserInfoLoading: boolean = false
public computeContextsLoading: boolean = false
public adminGroups: { id: string; name: string }[] = []
public runningAsUser: string | undefined
public currentUserInfo: ViyaApiCurrentUser | null = null
public computeContexts: ComputeContextItem[] = []
/** autoDeployStatus
* This object presents the status for two steps that we have for deploy.
@ -70,17 +83,83 @@ export class AutomaticComponent implements OnInit {
private deployService: DeployService,
private sasService: SasService,
private sasViyaService: SasViyaService,
private loggerService: LoggerService
private loggerService: LoggerService,
private helperService: HelperService
) {}
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() {
return new Promise<void>((resolve, reject) => {
this.adminGroupsLoading = true
this.sasViyaService.getAdminGroups().subscribe((res: ViyaApiIdentities) => {
this.sasViyaService
.getAdminGroups()
.subscribe((res: ViyaApiIdentities) => {
this.adminGroupsLoading = false
// Map admin groups with only needed fields
this.adminGroups = res.items.map((item: Item) => {
@ -89,12 +168,37 @@ export class AutomaticComponent implements OnInit {
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'
}
})
}
public getComputeContextName(id: string): string | undefined {
return (
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.
* Here we want to run this request using original WEB method.
@ -175,7 +292,7 @@ export class AutomaticComponent implements OnInit {
*/
let overrideConfig = {
useComputeApi: null,
contextName: this.sasJsConfig.contextName,
contextName: selectedComputeContextName,
debug: true
}
@ -209,6 +326,9 @@ export class AutomaticComponent implements OnInit {
MAC: macMsg
})
}
if (this.helperService.isStreamingViya())
this.updateIndexHtmlComputeContext()
})
.catch((err: any) => {
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(
content: any,
filename: string,

View File

@ -8,4 +8,5 @@ export interface Libinfo {
LIBID: string
LIBSIZE: number
TABLE_CNT: number
CATALOG_CNT: number
}

View File

@ -1,30 +1,14 @@
import { BaseSASResponse } from './common/BaseSASResponse'
export interface EditorsStageDataSASResponse extends BaseSASResponse {
SYSDATE: string
SYSTIME: string
sasparams: Sasparam[]
_DEBUG: string
_PROGRAM: string
AUTOEXEC: string
MF_GETUSER: string
SYSCC: string
SYSENCODING: string
SYSERRORTEXT: string
SYSHOSTINFOLONG: string
SYSHOSTNAME: string
SYSPROCESSID: string
SYSPROCESSMODE: string
SYSPROCESSNAME: string
SYSJOBID: string
SYSSCPL: string
SYSSITE: string
SYSTCPIPHOSTNAME: string
SYSUSERID: string
SYSVLONG: string
SYSWARNINGTEXT: string
END_DTTM: string
MEMSIZE: string
}
export interface Sasparam {

View 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
}

View File

@ -13,6 +13,8 @@ import {
AuditorsPostdataSASResponse,
Param
} from '../../models/sas/auditors-postdata.model'
import { PublicGetChangeinfo } from 'src/app/models/sas/public-getchangeinfo.model'
import { SasService } from 'src/app/services'
interface ChangesObj {
ind: any
@ -76,9 +78,11 @@ export class ApproveDetailsComponent implements AfterViewInit, OnDestroy {
public diffsLimit: boolean = false
public recordsLimit: number = 100
public refreshStartupserviceAfterApprove: boolean = false
constructor(
private sasStoreService: SasStoreService,
private sasService: SasService,
private eventService: EventService,
private router: ActivatedRoute,
private route: Router
@ -162,6 +166,9 @@ export class ApproveDetailsComponent implements AfterViewInit, OnDestroy {
await this.sasStoreService
.approveTable(approveParams, 'SASControlTable', 'auditors/postdata')
.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')
})
.catch((err: any) => {
@ -176,7 +183,7 @@ export class ApproveDetailsComponent implements AfterViewInit, OnDestroy {
public async callChangesInfo(tableId: any) {
await this.sasStoreService
.getChangeInfo(tableId)
.then((res: any) => {
.then((res: PublicGetChangeinfo) => {
this.tableDetails = res.jsparams[0]
this.jsParams = res.jsparams[0]
@ -189,6 +196,11 @@ export class ApproveDetailsComponent implements AfterViewInit, OnDestroy {
}
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) => {
this.acceptLoading = false

View File

@ -1,6 +1,7 @@
import { Injectable } from '@angular/core'
import cloneDeep from 'lodash-es/cloneDeep'
import * as CryptoMD5 from 'crypto-js/md5'
import { SasService } from './sas.service'
const librariesToShow = 50
@ -12,7 +13,7 @@ export class HelperService {
public loadMoreCount: number = librariesToShow
public isMicrosoft: boolean = false
constructor() {
constructor(private sasService: SasService) {
this.isMicrosoft = this.isIEorEDGE()
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
// But NodeJS is not available in browser so we have to go with any
private debounceTimeout: any

View File

@ -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 { Observable } from 'rxjs'
import { catchError, Observable, throwError } from 'rxjs'
import { Collection } from '../viya-api-explorer/models/collection.model'
import { AppStoreService } from './app-store.service'
import { ViyaApis } from '../viya-api-explorer/models/viya-apis.models'
import { ViyaApiFolderMembers } from '../viya-api-explorer/models/viya-api-folder-content.model'
import { ViyaApiFolder } from '../viya-api-explorer/models/viya-api-folder.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({
providedIn: 'root'
@ -74,7 +83,7 @@ export class SasViyaService {
this.serverUrl = adapterConfig?.serverUrl || ''
//example collection request
// example collection request
// this.getByCollection('jobs').subscribe((res) => {
// console.log('res', res)
// })
@ -94,7 +103,7 @@ export class SasViyaService {
* @returns
*/
getByUrl(url: string): Observable<Collection> {
return this.http.get<Collection>(`${this.serverUrl}${url}`, {
return this.get<Collection>(`${this.serverUrl}${url}`, {
withCredentials: true
})
}
@ -105,23 +114,32 @@ export class SasViyaService {
* @returns
*/
getByCollection(apiCollection: string): Observable<Collection> {
return this.http.get<Collection>(`${this.serverUrl}${apiCollection}`, {
return this.get<Collection>(`${this.serverUrl}${apiCollection}`, {
withCredentials: true
})
}
getComputeContexts(): Observable<any> {
return this.http.get<any>(`${this.serverUrl}/compute/contexts`, {
getComputeContexts(): Observable<ViyaComputeContexts> {
return this.get<ViyaComputeContexts>(`${this.serverUrl}/compute/contexts`, {
withCredentials: true
})
}
getComputeContextById(id: string): Observable<ComputeContextDetails> {
return this.get<ComputeContextDetails>(
`${this.serverUrl}/compute/contexts/${id}`,
{
withCredentials: true
}
)
}
/**
* @param path Path to the folder
* @returns The folder info object
*/
getFolderByPath(path: string): Observable<ViyaApiFolder> {
return this.http.get<any>(
return this.get<ViyaApiFolder>(
`${this.serverUrl}/folders/folders/@item?path=${path}`,
{
withCredentials: true
@ -130,7 +148,7 @@ export class SasViyaService {
}
getFolderMembers(folderId: string): Observable<ViyaApiFolderMembers> {
return this.http.get<any>(
return this.get<ViyaApiFolderMembers>(
`${this.serverUrl}/folders/folders/${folderId}/members`,
{
withCredentials: true
@ -139,11 +157,63 @@ export class SasViyaService {
}
getAdminGroups(limit: number = 5000): Observable<ViyaApiIdentities> {
return this.http.get<any>(
return this.get<ViyaApiIdentities>(
`${this.serverUrl}/identities/groups?sortBy=name&limit=${limit}`,
{
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)
})
)
}
}

View File

@ -333,6 +333,10 @@ export class SasService {
})
}
public reloadStartupData() {
this.loadStartupServiceEmitter.emit()
}
public getLicenseSiteId(): string[] {
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)
}
}

View File

@ -598,6 +598,12 @@
{{ libinfo[0] ? libinfo[0].TABLE_CNT : '' }}
</td>
</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>
</ng-container>
</div>

View File

@ -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
}

View File

@ -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
}

View File

@ -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
}

View File

@ -3884,6 +3884,12 @@ app-header-actions {
// END OF CSP WORKAROUND
.clr-input-wrapper.small-mt {
.clr-form-control {
margin-top: 5px !important;
}
}
body[cds-theme="dark"] {
scrollbar-width: thin;
scrollbar-color: $trackColor $thumbColor;

View File

@ -1,6 +1,6 @@
{
"name": "dcfrontend",
"version": "6.14.8",
"version": "7.0.0",
"description": "Data Controller",
"devDependencies": {
"@saithodev/semantic-release-gitea": "^2.1.0",
@ -19,7 +19,9 @@
"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: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": {
"type": "git",

26
sas/package-lock.json generated
View File

@ -6,8 +6,8 @@
"": {
"name": "dc-sas",
"dependencies": {
"@sasjs/cli": "^4.12.5",
"@sasjs/core": "^4.57.0"
"@sasjs/cli": "^4.12.8",
"@sasjs/core": "^4.59.1"
}
},
"node_modules/@coolaj86/urequest": {
@ -30,9 +30,9 @@
}
},
"node_modules/@sasjs/adapter": {
"version": "4.11.3",
"resolved": "https://registry.npmjs.org/@sasjs/adapter/-/adapter-4.11.3.tgz",
"integrity": "sha512-KF6G4vzs4l4efjpCD02og3kB44uFfJ1u2UWu749VdHtLKNN9l+PO26/moR+YAmRmmz2I9sC3X09fZE1nlN6zgw==",
"version": "4.12.1",
"resolved": "https://registry.npmjs.org/@sasjs/adapter/-/adapter-4.12.1.tgz",
"integrity": "sha512-0217oZIkrecOyQygRe6Azgc1C4TIcjB5noi15fU4Rd5GsfDpleKVfQQdzYZ7im/vesWlLIVl/yUT67MMaQe0ew==",
"hasInstallScript": true,
"license": "ISC",
"dependencies": {
@ -45,14 +45,14 @@
}
},
"node_modules/@sasjs/cli": {
"version": "4.12.5",
"resolved": "https://registry.npmjs.org/@sasjs/cli/-/cli-4.12.5.tgz",
"integrity": "sha512-y6JFATKlTyTl0gRPpDBPL1rwZsyeuyp5uEz7HMA7raSzQuNa6QZ1oO1Er91I7+cLUg0Ndh5aSNGKYOdBRStQ2g==",
"version": "4.12.8",
"resolved": "https://registry.npmjs.org/@sasjs/cli/-/cli-4.12.8.tgz",
"integrity": "sha512-20WiywlcLV22T1XfkAumV66mM3PfQ1N9ihJfpxoOVCFs2wF/ZertqnP4BZ5CE1dc30M1C2oDOzzSSVZqePPQnw==",
"hasInstallScript": true,
"license": "ISC",
"dependencies": {
"@sasjs/adapter": "4.11.3",
"@sasjs/core": "4.57.0",
"@sasjs/adapter": "4.12.1",
"@sasjs/core": "4.59.1",
"@sasjs/lint": "2.4.3",
"@sasjs/utils": "3.5.2",
"adm-zip": "0.5.10",
@ -77,9 +77,9 @@
}
},
"node_modules/@sasjs/core": {
"version": "4.57.0",
"resolved": "https://registry.npmjs.org/@sasjs/core/-/core-4.57.0.tgz",
"integrity": "sha512-iJiLnW4oY15InGerXXWtrjc1YpJ9UDz72+r7Odfr/yYR7RxIhtXGjYQIqyQu6US+cS/0b2pi12LZB6VnfMS/pA==",
"version": "4.59.1",
"resolved": "https://registry.npmjs.org/@sasjs/core/-/core-4.59.1.tgz",
"integrity": "sha512-52GNI4nIll5YivI8uobWrucE6TkHcTjcbKTr/YPC9eTauC4sh0V0MptebfAJ5E6vE5P2WevNZGr42KdDpckLpg==",
"license": "MIT"
},
"node_modules/@sasjs/lint": {

View File

@ -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",
"viya": "npm run viyacbd && sasjs test",
"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",
"sasdocs": "sasjs doc && ./sasjs/utils/deploydocs.sh"
},
"private": true,
"dependencies": {
"@sasjs/cli": "^4.12.5",
"@sasjs/core": "^4.57.0"
"@sasjs/cli": "^4.12.8",
"@sasjs/core": "^4.59.1"
}
}

View 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));

View 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));

View 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));

View File

@ -14,5 +14,6 @@ create table &curlib..mpe_datastatus_libs(
libref char(8) label='Library Name',
libsize num format=SIZEKMG. label='Size of file',
table_cnt num label='Number of Tables',
catalog_cnt num label='Number of Catalogs',
constraint pk_mpe_datastatus_libs
primary key(libref,tx_to));

View 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));

View File

@ -14,8 +14,8 @@ create table &curlib..mpe_datastatus_tabs(
libref char(8) label='Library Name',
dsn char(64) label='Member Name',
filesize num format=SIZEKMG. label='Size of file',
crdate num format=DATETIME. informat=DATETIME. label='Date Created',
modate num format=DATETIME. informat=DATETIME. label='Date Modified',
crdate num format=DATETIME. label='Date Created',
modate num format=DATETIME. label='Date Modified',
nobs num label='Number of Physical (Actual, inc. deleted) Observations',
constraint pk_mpe_datastatus_tabs
primary key(libref,dsn,tx_to));

View File

@ -29,7 +29,7 @@ create table dc.mpe_datacatalog_TABS(
nvar num label='Number of Variables',
compress char(8) label='Compression Routine',
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
primary key(libref,dsn,tx_to));
@ -67,8 +67,8 @@ create table dc.mpe_datacatalog_vars(
libref char(8) label='Library Name',
dsn char(64) label='Member Name',
filesize num format=SIZEKMG. label='Size of file',
crdate num format=DATETIME. informat=DATETIME. label='Date Created',
modate num format=DATETIME. informat=DATETIME. label='Date Modified',
crdate num format=DATETIME. label='Date Created',
modate num format=DATETIME. label='Date Modified',
nobs num label='Number of Physical (Actual, inc. deleted) Observations',
constraint pk
primary key(libref,dsn,tx_to));

View 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));

View File

@ -14,14 +14,31 @@
**/
%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 libds=%upcase(&libds);
%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_;
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('ddld',dd_longdesc,'l');
run;

View File

@ -34,4 +34,15 @@ run;
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
)

View File

@ -106,6 +106,19 @@ proc datasets lib=&lib noprint;
/nomiss unique;
quit;
proc sql;
create table &lib..mpe_datacatalog_CATS(
TX_FROM float &notnull 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(
TX_FROM num &notnull format=datetime19.3,
TX_TO num &notnull format=datetime19.3,
@ -125,6 +138,23 @@ proc datasets lib=&lib noprint;
/nomiss unique;
quit;
proc sql;
create table &lib..mpe_datacatalog_OBJS(
TX_FROM num &notnull format=datetime19.,
TX_TO num &notnull format=datetime19.,
libref char(8) &notnull label='Library Name',
memname char(64) &notnull label='Member Name',
objname char(32) &notnull label='Object Name',
objtype char(8) &notnull 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(
TX_FROM num &notnull format=datetime19.3,
TX_TO num &notnull format=datetime19.3,
@ -137,7 +167,7 @@ create table &lib..mpe_datacatalog_TABS(
nvar num label='Number of Variables',
compress char(8) label='Compression Routine',
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;
proc datasets lib=&lib noprint;
modify mpe_datacatalog_TABS;
@ -169,12 +199,29 @@ proc datasets lib=&lib noprint;
/nomiss unique;
quit;
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 &notnull label='Number of objects',
created num &notnull 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(
TX_FROM num &notnull format=datetime19.3,
TX_TO num &notnull format=datetime19.3,
libref char(8) label='Library Name',
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;
proc datasets lib=&lib noprint;
modify mpe_datastatus_libs;
@ -183,14 +230,32 @@ proc datasets lib=&lib noprint;
/nomiss unique;
quit;
proc sql;
create table &lib..mpe_datastatus_OBJS(
TX_FROM float &notnull format=datetime19.,
TX_TO float &notnull 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 &notnull 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(
TX_FROM num &notnull format=datetime19.3,
TX_TO num &notnull format=datetime19.3,
libref char(8) label='Library Name',
dsn char(64) label='Member Name',
filesize num format=SIZEKMG. label='Size of file',
crdate num format=DATETIME. informat=DATETIME. label='Date Created',
modate num format=DATETIME. informat=DATETIME. label='Date Modified',
crdate num format=DATETIME. label='Date Created',
modate num format=DATETIME. label='Date Modified',
nobs num label='Number of Physical (Actual, inc. deleted) Observations'
);quit;
proc datasets lib=&lib noprint;

View 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
)

View 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;

View 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)

View File

@ -48,11 +48,6 @@ create table cols as
,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;
proc sql;
connect using &lib;
@ -175,6 +170,11 @@ create table cols as
%end;
%mp_abort(iftrue= (&syscc ne 0)
,mac=&_program
,msg=%str(syscc=&syscc afer &lib indexes extraction)
)
/* load columns */
%bitemporal_dataloader(base_lib=&mpelib
,base_dsn=mpe_datacatalog_vars
@ -314,12 +314,26 @@ proc sql;
%if &ds = #ALL %then %do;
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
,sum(filesize) as libsize
,count(*) as table_cnt
from statustabs
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
,base_dsn=mpe_datastatus_libs

View 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
)

View File

@ -94,51 +94,18 @@
},
{
"name": "viya",
"serverUrl": "https://sas.4gl.io",
"serverUrl": "https://viya-f0g8ht62vq.engage.sas.com",
"serverType": "SASVIYA",
"httpsAgentOptions": {
"allowInsecureRequests": false
},
"appLoc": "/Public/app/dc",
"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"
]
},
"appLoc": "/Public/app/dcplaceholder",
"deployConfig": {
"deployServicePack": true,
"deployScripts": [
"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": [
"sasjs/targets/viya/macros_viya"
],
@ -147,36 +114,31 @@
],
"buildConfig": {
"initProgram": "sasjs/utils/buildinitviya.sas",
"termProgram": "sasjs/utils/buildtermviya.sas",
"macroVars": {
"dcpath": "/opt/sas/viya/config/var/tmp/dc",
"adminGroup": "DataBuilders"
},
"buildResultsFolder": "sasjsresults",
"buildOutputFolder": "sasjsbuild",
"buildOutputFileName": "viya.sas"
"buildOutputFileName": "viya.sas",
"termProgram": "",
"macroVars": {}
},
"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"
],
"initProgram": "sasjs/utils/serviceinitviya.sas",
"termProgram": "",
"macroVars": {}
},
"streamConfig": {
"streamWeb": true,
"streamWebFolder": "webv",
"streamWebFolder": "web",
"webSourcePath": "../client/dist",
"streamServiceName": "clickme",
"streamServiceName": "DC",
"streamLogo": "favicon.ico",
"assetPaths": []
},
"deployConfig": {
"deployServicePack": true
},
"contextName": "Datacontroller compute context"
"contextName": "SAS Job Execution compute context"
},
{
"name": "vtest",
@ -312,38 +274,6 @@
"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",
"serverUrl": "https://sas.4gl.io",

View 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)

View File

@ -675,7 +675,7 @@ data xl_rules;
keep xl_column xl_rule;
run;
%mpe_dsmeta(&libds, outds=dsmeta)
%mpe_dsmeta(&orig_libds, outds=dsmeta)
%mpe_getversions(&mpelib,
%scan(&orig_libds,1,.),

View File

@ -54,7 +54,10 @@ data _null_;
/* if a TXTEMPORAL table then filter as such */
call symputx('txfrom',var_txfrom);
call symputx('txto',var_txto);
run;
/* if a format, extract relevant info */
data _null_;
ds=symget('ds');
is_fmt=0;
if subpad(cats(reverse(ds)),1,3)=:'CF-' then do;

View File

@ -76,3 +76,37 @@ run;
test=EQUALS 3,
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
)

View File

@ -74,7 +74,8 @@ create table work.libinfo as
a.schemas,
a.libid,
b.libsize,
b.table_cnt
b.table_cnt,
b.catalog_cnt
from &mpelib..mpe_datacatalog_libs(where=(&dc_dttmtfmt. lt tx_to)) a
inner join &mpelib..mpe_datastatus_libs(where=(&dc_dttmtfmt. lt tx_to)) b
on a.libref=b.libref

View File

@ -355,7 +355,7 @@ run;
%mp_getcols(&libds, outds=cols)
%mpe_dsmeta(&libds, outds=dsmeta)
%mpe_dsmeta(&orig_libds, outds=dsmeta)
%mpe_getversions(&mpelib,
%scan(&orig_libds,1,.),

View File

@ -167,7 +167,8 @@ create table work.libinfo as
a.schemas,
a.libid,
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
left join &mpelib..mpe_datastatus_libs(where=(&dc_dttmtfmt. lt tx_to)) b
on a.libref=b.libref

View File

@ -9,6 +9,7 @@
<h4> SAS Macros </h4>
@li mpe_refreshlibs.sas
@li dc_assignlib.sas
@li mpe_refreshcatalogs.sas
@li mpe_refreshtables.sas
@li mm_getrepos.sas
@ -44,6 +45,7 @@ run;
%dc_assignlib(WRITE,&libref) /* write just in order to assign direct lib */
%mpe_refreshlibs(lib=&libref)
%mpe_refreshtables(&libref)
%mpe_refreshcatalogs(&libref)
%end;
%else %do xx=1 %to &repocnt;
options metarepository=&&repo&xx;
@ -73,6 +75,7 @@ run;
%do i=1 %to &libcnt;
%dc_assignlib(WRITE,&&lib&i)
%mpe_refreshtables(&&lib&i)
%mpe_refreshcatalogs(&&lib&i)
%end;
%end;

View File

@ -9,6 +9,7 @@
<h4> SAS Macros </h4>
@li mpe_refreshlibs.sas
@li dc_assignlib.sas
@li mpe_refreshcatalogs.sas
@li mpe_refreshtables.sas
@ -34,6 +35,8 @@ data libraries;
str=cats('%mpe_refreshtables(',libref,')');
put str;
putlog str;
str=cats('%mpe_refreshcatalogs(',libref,')');
put str;
run;
%inc executor/source2;

View File

@ -10,6 +10,7 @@
@li mpe_refreshlibs.sas
@li dc_assignlib.sas
@li mpe_refreshtables.sas
@li mpe_refreshcatalogs.sas
@version 3.4
@ -19,19 +20,29 @@
4GL Apps Ltd.
**/
%macro dc_refreshcatalog();
%macro dc_refreshcatalog(libref);
%mpe_refreshlibs()
filename executor catalog 'work.code.code.source';
data libraries;
%if #&libref# ne ## %then %do;
%put &sysmacroname: assigning specific libref, &libref;
%dc_assignlib(WRITE,&libref) /* write just in order to assign direct lib */
%mpe_refreshlibs(lib=&libref)
%mpe_refreshtables(&libref)
%mpe_refreshcatalogs(&libref)
%end;
%else %do;
%mpe_refreshlibs()
filename executor catalog 'work.code.code.source';
data libraries;
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;
run;
%inc executor;
%end;
%mend dc_refreshcatalog;

View File

@ -7,6 +7,7 @@
@li mf_getapploc.sas
@li mf_mkdir.sas
@li mf_trimstr.sas
@li mp_abort.sas
@li mpe_getvars.sas
@li mpe_makedata.sas
@li mpe_makedatamodel.sas
@ -50,9 +51,33 @@ options noquotelenmax;
%put &=admin;
%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/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";
%global admin;
@ -60,11 +85,23 @@ libname &dclib "&dcpath";
%mpe_makedatamodel(lib=&dclib)
%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 */
%mf_mkdir(&dcpath/dc_demo)
libname dcdemo "&dcpath/dc_demo";
%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 */
%let root=%mf_getapploc(&_program)/services;
%put &=root;
@ -167,7 +204,7 @@ run;
*/
%mp_abort(iftrue=(&syscc ne 0)
,mac=&sysmacroname
,msg=%str(Err during DB build)
,msg=%str(Err during settings job creation)
)

View File

@ -21,7 +21,7 @@ REMOVE THAT LAST MACRO
%let syscc=0;
%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;
options mprint mprintnest nobomfile lrecl=32767;

View File

@ -28,7 +28,7 @@
%global apploc _program;
%let defaultcontext=Datacontroller compute context;
%let defaultcontext=SAS Job Execution compute context;
data _null_;
length _pgm $1000;
@ -60,6 +60,9 @@ run;
%let testloc=%sysfunc(pathname(&DC_LIBREF))/fmt%mf_getuniquefileref();
%mf_mkdir(&testloc)
libname dctest "&testloc";
/* test library with only one format catalog */
%mf_mkdir(&testloc/fmtonly)
libname fmtonly "&testloc/fmtonly";
/* add formats */
PROC FORMAT library=dctest.dcfmts;
@ -99,6 +102,10 @@ run;
proc append base=&dc_libref..mpe_tables data=work.append;
run;
/* lone format catalog */
proc format cntlin=work.fmts library=fmtonly.dcfmts;
run;
/* add some other tables */
%mp_coretable(LOCKTABLE,libds=dctest.locktable)
%mp_coretable(DIFFTABLE,libds=dctest.difftable)
@ -130,6 +137,7 @@ options mprint;
put _infile_;
if last then do;
put "libname dctest '&testloc';";
put "libname fmtonly '&testloc/fmtonly';";
end;
run;
data _null_;
@ -151,6 +159,7 @@ options mprint;
put _infile_;
if last then do;
put "libname dctest '&testloc';";
put "libname fmtonly '&testloc/fmtonly';";
end;
run;
%ms_deletefile(&root/services/public/settings.sas)
@ -182,6 +191,7 @@ options mprint;
put _infile_;
if last then do;
put "libname dctest '&testloc';";
put "libname fmtonly '&testloc/fmtonly';";
end;
run;
%mm_deletestp(target=&root/services/public/Data_Controller_Settings)

View File

@ -2,6 +2,20 @@
@file buildinitviya.sas
@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;
/* 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));