1
0
mirror of https://github.com/sasjs/core.git synced 2025-12-24 19:51:19 +00:00

Compare commits

..

1 Commits

Author SHA1 Message Date
github-actions
73f8cd8894 chore: updating all.sas 2023-10-17 15:39:42 +00:00
50 changed files with 2000 additions and 3343 deletions

View File

@@ -153,15 +153,6 @@
"contributions": [
"code"
]
},
{
"login": "andyjessen",
"name": "andyjessen",
"avatar_url": "https://avatars.githubusercontent.com/u/62343929?v=4",
"profile": "https://github.com/andyjessen",
"contributions": [
"doc"
]
}
],
"contributorsPerLine": 7,

View File

@@ -15,4 +15,4 @@ What code changes have been made to achieve the intent.
- [ ] Code is formatted correctly (`sasjs lint`).
- [ ] Any new functionality has been unit tested.
- [ ] All unit tests are passing (`sasjs test`).
- [ ] The PR desc or underlying commits follow the [Conventional Commit](https://www.conventionalcommits.org) standard
- [ ] `all.sas` has been regenerated (`python3 build.py`)

View File

@@ -3,12 +3,10 @@ client
tls-client
dev tun
# this will connect with whatever proto DNS tells us (https://community.openvpn.net/openvpn/ticket/934)
proto udp
remote vpn.4gl.io 7194
proto tcp
remote vpn.4gl.io 7494
resolv-retry infinite
# this will fallback from udp6 to udp4 as well
connect-timeout 5
data-ciphers AES-256-CBC:AES-256-GCM
cipher AES-256-CBC
auth SHA256
script-security 2
keepalive 10 120

View File

@@ -8,7 +8,7 @@ on:
jobs:
test:
runs-on: ubuntu-22.04
runs-on: ubuntu-latest
strategy:
matrix:
@@ -34,10 +34,6 @@ jobs:
USER_KEY: ${{ secrets.USER_KEY }}
TLS_KEY: ${{ secrets.TLS_KEY }}
- name: Chmod VPN files
run: |
chmod 600 .github/vpn/ca.crt .github/vpn/user.crt .github/vpn/user.key .github/vpn/tls.key
- name: Install Open VPN
run: |
sudo apt install apt-transport-https
@@ -46,13 +42,8 @@ jobs:
sudo wget -O /etc/apt/sources.list.d/openvpn3.list https://swupdate.openvpn.net/community/openvpn3/repos/openvpn3-jammy.list
sudo apt update
sudo apt install openvpn3=17~betaUb22042+jammy
- name: Start Open VPN 3
run: openvpn3 session-start --config .github/vpn/config.ovpn
- name: Fetch SASJS server
run: curl ${{ secrets.SASJS_SERVER_URL }}/SASjsApi/info
- name: Install Doxygen
run: sudo apt-get install doxygen

View File

@@ -237,7 +237,6 @@ If you find this library useful, please leave a [star](https://github.com/sasjs/
The following repositories are also worth checking out:
* [chris-swenson/sasmacros](https://github.com/chris-swenson/sasmacros)
* [Criptic/sas_snippets](https://github.com/Criptic/sas_snippets)
* [greg-wotton/sas-programs](https://github.com/greg-wootton/sas-programs)
* [KatjaGlassConsulting/SMILE-SmartSASMacros](https://github.com/KatjaGlassConsulting/SMILE-SmartSASMacros)
* [paul-canals/toolbox](https://github.com/paul-canals/toolbox)
@@ -249,7 +248,7 @@ The following repositories are also worth checking out:
## Contributors ✨
<!-- ALL-CONTRIBUTORS-BADGE:START - Do not remove or modify this section -->
[![All Contributors](https://img.shields.io/badge/all_contributors-15-orange.svg?style=flat-square)](#contributors-)
[![All Contributors](https://img.shields.io/badge/all_contributors-14-orange.svg?style=flat-square)](#contributors-)
<!-- ALL-CONTRIBUTORS-BADGE:END -->
Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/docs/en/emoji-key)):
@@ -276,9 +275,6 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d
<td align="center" valign="top" width="14.28%"><a href="https://github.com/henrik-forsell"><img src="https://avatars.githubusercontent.com/u/109935936?v=4?s=100" width="100px;" alt="Henrik Forsell"/><br /><sub><b>Henrik Forsell</b></sub></a><br /><a href="https://github.com/sasjs/core/commits?author=henrik-forsell" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="http://rudvfaden.github.io/"><img src="https://avatars.githubusercontent.com/u/2445577?v=4?s=100" width="100px;" alt="Rud Faden"/><br /><sub><b>Rud Faden</b></sub></a><br /><a href="https://github.com/sasjs/core/commits?author=rudvfaden" title="Code">💻</a></td>
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/andyjessen"><img src="https://avatars.githubusercontent.com/u/62343929?v=4?s=100" width="100px;" alt="andyjessen"/><br /><sub><b>andyjessen</b></sub></a><br /><a href="https://github.com/sasjs/core/commits?author=andyjessen" title="Documentation">📖</a></td>
</tr>
</tbody>
</table>

1534
all.sas

File diff suppressed because it is too large Load Diff

View File

@@ -7,7 +7,7 @@
Usage:
%put %mf_isblank(&var);
%put mf_isblank(&var);
inspiration:
https://support.sas.com/resources/papers/proceedings09/022-2009.pdf

View File

@@ -1,436 +0,0 @@
/**
@file
@brief Returns a mime type from a file extension
@details Provide a file extension and get a mime type.
The mappings were derived from this source:
https://svn.apache.org/repos/asf/httpd/httpd/trunk/docs/conf/mime.types
@param [in] ext The file extension (unquoted)
@return output The mime type
@version 9.2
@author Allan Bowe
**/
%macro mf_mimetype(
ext
)/*/STORE SOURCE*/ /minoperator mindelimiter=' ';
%let ext=%lowcase(&ext);
%if &ext in (sas txt text conf def list log)
%then %do;%str(text/plain)%end;
%else %if &ext=xlsx %then %do;
%str(application/vnd.openxmlformats-officedocument.spreadsheetml.sheet)%end;
%else %if &ext in (xls xlm xla xlc xlt xlw)
%then %do;%str(application/vnd.ms-excel)%end;
%else %if &ext=xlsm
%then %do;%str(application/vnd.ms-excel.sheet.macroenabled.12)%end;
%else %if &ext=xlsb
%then %do;%str(application/vnd.ms-excel.sheet.binary.macroenabled.12)%end;
%else %if &ext in (css csv html n3 sgml vcard)
%then %do;%str(text/&ext)%end;
%else %if &ext in (avif bmp cgm gif ief jxl ktx png sgi tiff webp)
%then %do;%str(image/&ext)%end;
%else %if &ext in (exi gxf ipfix json mbox mp21 mxf oda oxps pdf rtf sdp wasm
xml yang zip)
%then %do;%str(application/&ext)%end;
%else %if &ext in (jpeg jpg jpe) %then %do;%str(image/jpeg)%end;
%else %if &ext in (mp4 mp4v mpg4) %then %do;%str(video/mp4)%end;
%else %if &ext in (otf ttf woff woff2) %then %do;%str(font/&ext)%end;
%else %if &ext in (mpeg mpg mpe m1v m2v)
%then %do;%str(video/mpeg)%end;
%else %if &ext in (h261 h263 h264 jpm mj2 webm)
%then %do;%str(video/&ext)%end;
%else %if &ext in (f4v fli flv m4v mng smv)
%then %do;%str(video/x-&ext)%end;
%else %if &ext in (3ds cmx pcx rgb tga)
%then %do;%str(image/x-&ext)%end;
%else %if &ext in (asm nfo opml sfv)
%then %do;%str(text/x-&ext)%end;
%else %if &ext in (aac caf flac wav)
%then %do;%str(audio/x-&ext)%end;
%else %if &ext in (ts m2t m2ts mts)
%then %do;%str(video/mp2t)%end;
%else %if &ext in (pfa pfb pfm afm)
%then %do;%str(application/x-font-type1)%end;
%else %if &ext in (oga ogg spx opus)
%then %do;%str(audio/ogg)%end;
%else %if &ext in (mid midi kar rmi)
%then %do;%str(audio/midi)%end;
%else %if &ext in (onetoc onetoc2 onetmp onepkg)
%then %do;%str(application/onenote)%end;
%else %if &ext in (mxml xhvml xvml xvm)
%then %do;%str(application/xv+xml)%end;
%else %if &ext in (f for f77 f90)
%then %do;%str(text/x-fortran)%end;
%else %if &ext in (wmf wmz emf emz)
%then %do;%str(application/x-msmetafile)%end;
%else %if &ext in (exe dll com bat msi)
%then %do;%str(application/x-msdownload)%end;
%else %if &ext in (bin dms lrf mar so dist distz pkg bpk dump elc deploy)
%then %do;%str(application/octet-stream)%end;
%else %if &ext in (atom atomcat atomsvc ccxml davmount emma gml gpx inkml mads
mathml metalink mets mods omdoc pls rdf rsd rss sbml shf smil sru ssdl ssml
tei wsdl wspolicy xaml xenc xhtml xop xslt xspf yin)
%then %do;%str(application/&ext+xml)%end;
%else %if &ext in (dir dcr dxr cst cct cxt w3d fgd swa)
%then %do;%str(application/x-director)%end;
%else %if &ext in (z1 z2 z3 z4 z5 z6 z7 z8)
%then %do;%str(application/x-zmachine)%end;
%else %if &ext in (c cc cxx cpp h hh dic)
%then %do;%str(text/x-c)%end;
%else %if &ext in (mpga mp2 mp2a mp3 m2a m3a)
%then %do;%str(audio/mpeg)%end;
%else %if &ext in (t tr roff man me ms)
%then %do;%str(text/troff)%end;
%else %if &ext in (cbr cba cbt cbz cb7)
%then %do;%str(application/x-cbr)%end;
%else %if &ext in (fh fhc fh4 fh5 fh7)
%then %do;%str(image/x-freehand)%end;
%else %if &ext in (aab x32 u32 vox)
%then %do;%str(application/x-authorware-bin)%end;
%else %if &ext in (uvi uvvi uvg uvvg)
%then %do;%str(image/vnd.dece.graphic)%end;
%else %if &ext in (cdx cif cmdf cml csml xyz)
%then %do;%str(chemical/x-&ext)%end;
%else %if &ext in (aif aiff aifc) %then %do;%str(audio/x-aiff)%end;
%else %if &ext in (ma nb mb) %then %do;%str(application/mathematica)%end;
%else %if &ext in (mvb m13 m14) %then %do;%str(application/x-msmediaview)%end;
%else %if &ext in (msh mesh silo) %then %do;%str(model/mesh)%end;
%else %if &ext in (uri uris urls) %then %do;%str(text/uri-list)%end;
%else %if &ext in (mkv mk3d mks) %then %do;%str(video/x-matroska)%end;
%else %if &ext=ez %then %do;%str(application/andrew-inset)%end;
%else %if &ext=aw %then %do;%str(application/applixware)%end;
%else %if &ext=cdmia %then %do;%str(application/cdmi-capability)%end;
%else %if &ext=cdmic %then %do;%str(application/cdmi-container)%end;
%else %if &ext=cdmid %then %do;%str(application/cdmi-domain)%end;
%else %if &ext=cdmio %then %do;%str(application/cdmi-object)%end;
%else %if &ext=cdmiq %then %do;%str(application/cdmi-queue)%end;
%else %if &ext=cu %then %do;%str(application/cu-seeme)%end;
%else %if &ext=dssc %then %do;%str(application/dssc+der)%end;
%else %if &ext=xdssc %then %do;%str(application/dssc+xml)%end;
%else %if &ext=ecma %then %do;%str(application/ecmascript)%end;
%else %if &ext=epub %then %do;%str(application/epub+zip)%end;
%else %if &ext=pfr %then %do;%str(application/font-tdpfr)%end;
%else %if &ext=stk %then %do;%str(application/hyperstudio)%end;
%else %if &ext=ink %then %do;%str(application/inkml+xml)%end;
%else %if &ext=jar %then %do;%str(application/java-archive)%end;
%else %if &ext=ser %then %do;%str(application/java-serialized-object)%end;
%else %if &ext=class %then %do;%str(application/java-vm)%end;
%else %if &ext=jsonml %then %do;%str(application/jsonml+json)%end;
%else %if &ext=lostxml %then %do;%str(application/lost+xml)%end;
%else %if &ext=hqx %then %do;%str(application/mac-binhex40)%end;
%else %if &ext=cpt %then %do;%str(application/mac-compactpro)%end;
%else %if &ext=mrc %then %do;%str(application/marc)%end;
%else %if &ext=mrcx %then %do;%str(application/marcxml+xml)%end;
%else %if &ext=mscml %then %do;%str(application/mediaservercontrol+xml)%end;
%else %if &ext=meta4 %then %do;%str(application/metalink4+xml)%end;
%else %if &ext=m21 %then %do;%str(application/mp21)%end;
%else %if &ext=mp4s %then %do;%str(application/mp4)%end;
%else %if &ext=doc %then %do;%str(application/msword)%end;
%else %if &ext=dot %then %do;%str(application/msword)%end;
%else %if &ext=opf %then %do;%str(application/oebps-package+xml)%end;
%else %if &ext=ogx %then %do;%str(application/ogg)%end;
%else %if &ext=xer %then %do;%str(application/patch-ops-error+xml)%end;
%else %if &ext=pgp %then %do;%str(application/pgp-encrypted)%end;
%else %if &ext=asc %then %do;%str(application/pgp-signature)%end;
%else %if &ext=sig %then %do;%str(application/pgp-signature)%end;
%else %if &ext=prf %then %do;%str(application/pics-rules)%end;
%else %if &ext=p10 %then %do;%str(application/pkcs10)%end;
%else %if &ext=p7m %then %do;%str(application/pkcs7-mime)%end;
%else %if &ext=p7c %then %do;%str(application/pkcs7-mime)%end;
%else %if &ext=p7s %then %do;%str(application/pkcs7-signature)%end;
%else %if &ext=p8 %then %do;%str(application/pkcs8)%end;
%else %if &ext=ac %then %do;%str(application/pkix-attr-cert)%end;
%else %if &ext=cer %then %do;%str(application/pkix-cert)%end;
%else %if &ext=crl %then %do;%str(application/pkix-crl)%end;
%else %if &ext=pkipath %then %do;%str(application/pkix-pkipath)%end;
%else %if &ext=pki %then %do;%str(application/pkixcmp)%end;
%else %if &ext=cww %then %do;%str(application/prs.cww)%end;
%else %if &ext=pskcxml %then %do;%str(application/pskc+xml)%end;
%else %if &ext=rif %then %do;%str(application/reginfo+xml)%end;
%else %if &ext=rnc %then %do;%str(application/relax-ng-compact-syntax)%end;
%else %if &ext=rld %then %do;%str(application/resource-lists-diff+xml)%end;
%else %if &ext=rl %then %do;%str(application/resource-lists+xml)%end;
%else %if &ext=gbr %then %do;%str(application/rpki-ghostbusters)%end;
%else %if &ext=mft %then %do;%str(application/rpki-manifest)%end;
%else %if &ext=roa %then %do;%str(application/rpki-roa)%end;
%else %if &ext=scq %then %do;%str(application/scvp-cv-request)%end;
%else %if &ext=scs %then %do;%str(application/scvp-cv-response)%end;
%else %if &ext=spq %then %do;%str(application/scvp-vp-request)%end;
%else %if &ext=spp %then %do;%str(application/scvp-vp-response)%end;
%else %if &ext=setpay %then %do;%str(application/set-payment-initiation)%end;
%else %if &ext=setreg %then %do;%str(application/set-registration-initiation)%end;
%else %if &ext=smi %then %do;%str(application/smil+xml)%end;
%else %if &ext=rq %then %do;%str(application/sparql-query)%end;
%else %if &ext=srx %then %do;%str(application/sparql-results+xml)%end;
%else %if &ext=gram %then %do;%str(application/srgs)%end;
%else %if &ext=grxml %then %do;%str(application/srgs+xml)%end;
%else %if &ext=teicorpus %then %do;%str(application/tei+xml)%end;
%else %if &ext=tfi %then %do;%str(application/thraud+xml)%end;
%else %if &ext=tsd %then %do;%str(application/timestamped-data)%end;
%else %if &ext=vxml %then %do;%str(application/voicexml+xml)%end;
%else %if &ext=wgt %then %do;%str(application/widget)%end;
%else %if &ext=hlp %then %do;%str(application/winhlp)%end;
%else %if &ext=7z %then %do;%str(application/x-7z-compressed)%end;
%else %if &ext=abw %then %do;%str(application/x-abiword)%end;
%else %if &ext=ace %then %do;%str(application/x-ace-compressed)%end;
%else %if &ext=dmg %then %do;%str(application/x-apple-diskimage)%end;
%else %if &ext=aam %then %do;%str(application/x-authorware-map)%end;
%else %if &ext=aas %then %do;%str(application/x-authorware-seg)%end;
%else %if &ext=bcpio %then %do;%str(application/x-bcpio)%end;
%else %if &ext=torrent %then %do;%str(application/x-bittorrent)%end;
%else %if &ext=blb %then %do;%str(application/x-blorb)%end;
%else %if &ext=blorb %then %do;%str(application/x-blorb)%end;
%else %if &ext=bz %then %do;%str(application/x-bzip)%end;
%else %if &ext=bz2 %then %do;%str(application/x-bzip2)%end;
%else %if &ext=boz %then %do;%str(application/x-bzip2)%end;
%else %if &ext=vcd %then %do;%str(application/x-cdlink)%end;
%else %if &ext=cfs %then %do;%str(application/x-cfs-compressed)%end;
%else %if &ext=chat %then %do;%str(application/x-chat)%end;
%else %if &ext=pgn %then %do;%str(application/x-chess-pgn)%end;
%else %if &ext=nsc %then %do;%str(application/x-conference)%end;
%else %if &ext=cpio %then %do;%str(application/x-cpio)%end;
%else %if &ext=csh %then %do;%str(application/x-csh)%end;
%else %if &ext=deb %then %do;%str(application/x-debian-package)%end;
%else %if &ext=udeb %then %do;%str(application/x-debian-package)%end;
%else %if &ext=dgc %then %do;%str(application/x-dgc-compressed)%end;
%else %if &ext=wad %then %do;%str(application/x-doom)%end;
%else %if &ext=ncx %then %do;%str(application/x-dtbncx+xml)%end;
%else %if &ext=dtb %then %do;%str(application/x-dtbook+xml)%end;
%else %if &ext=res %then %do;%str(application/x-dtbresource+xml)%end;
%else %if &ext=dvi %then %do;%str(application/x-dvi)%end;
%else %if &ext=evy %then %do;%str(application/x-envoy)%end;
%else %if &ext=eva %then %do;%str(application/x-eva)%end;
%else %if &ext=bdf %then %do;%str(application/x-font-bdf)%end;
%else %if &ext=gsf %then %do;%str(application/x-font-ghostscript)%end;
%else %if &ext=psf %then %do;%str(application/x-font-linux-psf)%end;
%else %if &ext=pcf %then %do;%str(application/x-font-pcf)%end;
%else %if &ext=snf %then %do;%str(application/x-font-snf)%end;
%else %if &ext=arc %then %do;%str(application/x-freearc)%end;
%else %if &ext=spl %then %do;%str(application/x-futuresplash)%end;
%else %if &ext=gca %then %do;%str(application/x-gca-compressed)%end;
%else %if &ext=ulx %then %do;%str(application/x-glulx)%end;
%else %if &ext=gnumeric %then %do;%str(application/x-gnumeric)%end;
%else %if &ext=gramps %then %do;%str(application/x-gramps-xml)%end;
%else %if &ext=gtar %then %do;%str(application/x-gtar)%end;
%else %if &ext=hdf %then %do;%str(application/x-hdf)%end;
%else %if &ext=install %then %do;%str(application/x-install-instructions)%end;
%else %if &ext=iso %then %do;%str(application/x-iso9660-image)%end;
%else %if &ext=jnlp %then %do;%str(application/x-java-jnlp-file)%end;
%else %if &ext=latex %then %do;%str(application/x-latex)%end;
%else %if &ext=lzh %then %do;%str(application/x-lzh-compressed)%end;
%else %if &ext=lha %then %do;%str(application/x-lzh-compressed)%end;
%else %if &ext=mie %then %do;%str(application/x-mie)%end;
%else %if &ext=prc %then %do;%str(application/x-mobipocket-ebook)%end;
%else %if &ext=mobi %then %do;%str(application/x-mobipocket-ebook)%end;
%else %if &ext=application %then %do;%str(application/x-ms-application)%end;
%else %if &ext=lnk %then %do;%str(application/x-ms-shortcut)%end;
%else %if &ext=wmd %then %do;%str(application/x-ms-wmd)%end;
%else %if &ext=wmz %then %do;%str(application/x-ms-wmz)%end;
%else %if &ext=xbap %then %do;%str(application/x-ms-xbap)%end;
%else %if &ext=mdb %then %do;%str(application/x-msaccess)%end;
%else %if &ext=obd %then %do;%str(application/x-msbinder)%end;
%else %if &ext=crd %then %do;%str(application/x-mscardfile)%end;
%else %if &ext=clp %then %do;%str(application/x-msclip)%end;
%else %if &ext=mny %then %do;%str(application/x-msmoney)%end;
%else %if &ext=pub %then %do;%str(application/x-mspublisher)%end;
%else %if &ext=scd %then %do;%str(application/x-msschedule)%end;
%else %if &ext=trm %then %do;%str(application/x-msterminal)%end;
%else %if &ext=wri %then %do;%str(application/x-mswrite)%end;
%else %if &ext=nc %then %do;%str(application/x-netcdf)%end;
%else %if &ext=cdf %then %do;%str(application/x-netcdf)%end;
%else %if &ext=nzb %then %do;%str(application/x-nzb)%end;
%else %if &ext=p12 %then %do;%str(application/x-pkcs12)%end;
%else %if &ext=pfx %then %do;%str(application/x-pkcs12)%end;
%else %if &ext=p7b %then %do;%str(application/x-pkcs7-certificates)%end;
%else %if &ext=spc %then %do;%str(application/x-pkcs7-certificates)%end;
%else %if &ext=p7r %then %do;%str(application/x-pkcs7-certreqresp)%end;
%else %if &ext=rar %then %do;%str(application/x-rar-compressed)%end;
%else %if &ext=ris %then %do;%str(application/x-research-info-systems)%end;
%else %if &ext=sh %then %do;%str(application/x-sh)%end;
%else %if &ext=shar %then %do;%str(application/x-shar)%end;
%else %if &ext=swf %then %do;%str(application/x-shockwave-flash)%end;
%else %if &ext=xap %then %do;%str(application/x-silverlight-app)%end;
%else %if &ext=sql %then %do;%str(application/x-sql)%end;
%else %if &ext=sit %then %do;%str(application/x-stuffit)%end;
%else %if &ext=sitx %then %do;%str(application/x-stuffitx)%end;
%else %if &ext=srt %then %do;%str(application/x-subrip)%end;
%else %if &ext=sv4cpio %then %do;%str(application/x-sv4cpio)%end;
%else %if &ext=sv4crc %then %do;%str(application/x-sv4crc)%end;
%else %if &ext=t3 %then %do;%str(application/x-t3vm-image)%end;
%else %if &ext=gam %then %do;%str(application/x-tads)%end;
%else %if &ext=tar %then %do;%str(application/x-tar)%end;
%else %if &ext=tcl %then %do;%str(application/x-tcl)%end;
%else %if &ext=tex %then %do;%str(application/x-tex)%end;
%else %if &ext=tfm %then %do;%str(application/x-tex-tfm)%end;
%else %if &ext=texinfo %then %do;%str(application/x-texinfo)%end;
%else %if &ext=texi %then %do;%str(application/x-texinfo)%end;
%else %if &ext=obj %then %do;%str(application/x-tgif)%end;
%else %if &ext=ustar %then %do;%str(application/x-ustar)%end;
%else %if &ext=src %then %do;%str(application/x-wais-source)%end;
%else %if &ext=der %then %do;%str(application/x-x509-ca-cert)%end;
%else %if &ext=crt %then %do;%str(application/x-x509-ca-cert)%end;
%else %if &ext=fig %then %do;%str(application/x-xfig)%end;
%else %if &ext=xlf %then %do;%str(application/x-xliff+xml)%end;
%else %if &ext=xpi %then %do;%str(application/x-xpinstall)%end;
%else %if &ext=xz %then %do;%str(application/x-xz)%end;
%else %if &ext=xdf %then %do;%str(application/xcap-diff+xml)%end;
%else %if &ext=xht %then %do;%str(application/xhtml+xml)%end;
%else %if &ext=xsl %then %do;%str(application/xml)%end;
%else %if &ext=dtd %then %do;%str(application/xml-dtd)%end;
%else %if &ext=xpl %then %do;%str(application/xproc+xml)%end;
%else %if &ext=adp %then %do;%str(audio/adpcm)%end;
%else %if &ext=au %then %do;%str(audio/basic)%end;
%else %if &ext=snd %then %do;%str(audio/basic)%end;
%else %if &ext=m4a %then %do;%str(audio/mp4)%end;
%else %if &ext=mp4a %then %do;%str(audio/mp4)%end;
%else %if &ext=s3m %then %do;%str(audio/s3m)%end;
%else %if &ext=sil %then %do;%str(audio/silk)%end;
%else %if &ext=uva %then %do;%str(audio/vnd.dece.audio)%end;
%else %if &ext=uvva %then %do;%str(audio/vnd.dece.audio)%end;
%else %if &ext=eol %then %do;%str(audio/vnd.digital-winds)%end;
%else %if &ext=dra %then %do;%str(audio/vnd.dra)%end;
%else %if &ext=dts %then %do;%str(audio/vnd.dts)%end;
%else %if &ext=dtshd %then %do;%str(audio/vnd.dts.hd)%end;
%else %if &ext=lvp %then %do;%str(audio/vnd.lucent.voice)%end;
%else %if &ext=pya %then %do;%str(audio/vnd.ms-playready.media.pya)%end;
%else %if &ext=ecelp4800 %then %do;%str(audio/vnd.nuera.ecelp4800)%end;
%else %if &ext=ecelp7470 %then %do;%str(audio/vnd.nuera.ecelp7470)%end;
%else %if &ext=ecelp9600 %then %do;%str(audio/vnd.nuera.ecelp9600)%end;
%else %if &ext=rip %then %do;%str(audio/vnd.rip)%end;
%else %if &ext=weba %then %do;%str(audio/webm)%end;
%else %if &ext=mka %then %do;%str(audio/x-matroska)%end;
%else %if &ext=m3u %then %do;%str(audio/x-mpegurl)%end;
%else %if &ext=wax %then %do;%str(audio/x-ms-wax)%end;
%else %if &ext=wma %then %do;%str(audio/x-ms-wma)%end;
%else %if &ext=ra %then %do;%str(audio/x-pn-realaudio)%end;
%else %if &ext=ram %then %do;%str(audio/x-pn-realaudio)%end;
%else %if &ext=rmp %then %do;%str(audio/x-pn-realaudio-plugin)%end;
%else %if &ext=xm %then %do;%str(audio/xm)%end;
%else %if &ext=ttc %then %do;%str(font/collection)%end;
%else %if &ext=g3 %then %do;%str(image/g3fax)%end;
%else %if &ext=btif %then %do;%str(image/prs.btif)%end;
%else %if &ext=svg %then %do;%str(image/svg+xml)%end;
%else %if &ext=svgz %then %do;%str(image/svg+xml)%end;
%else %if &ext=tif %then %do;%str(image/tiff)%end;
%else %if &ext=psd %then %do;%str(image/vnd.adobe.photoshop)%end;
%else %if &ext=djv %then %do;%str(image/vnd.djvu)%end;
%else %if &ext=djvu %then %do;%str(image/vnd.djvu)%end;
%else %if &ext=sub %then %do;%str(image/vnd.dvb.subtitle)%end;
%else %if &ext=dwg %then %do;%str(image/vnd.dwg)%end;
%else %if &ext=dxf %then %do;%str(image/vnd.dxf)%end;
%else %if &ext=fbs %then %do;%str(image/vnd.fastbidsheet)%end;
%else %if &ext=fpx %then %do;%str(image/vnd.fpx)%end;
%else %if &ext=fst %then %do;%str(image/vnd.fst)%end;
%else %if &ext=mmr %then %do;%str(image/vnd.fujixerox.edmics-mmr)%end;
%else %if &ext=rlc %then %do;%str(image/vnd.fujixerox.edmics-rlc)%end;
%else %if &ext=mdi %then %do;%str(image/vnd.ms-modi)%end;
%else %if &ext=wdp %then %do;%str(image/vnd.ms-photo)%end;
%else %if &ext=npx %then %do;%str(image/vnd.net-fpx)%end;
%else %if &ext=wbmp %then %do;%str(image/vnd.wap.wbmp)%end;
%else %if &ext=xif %then %do;%str(image/vnd.xiff)%end;
%else %if &ext=ras %then %do;%str(image/x-cmu-raster)%end;
%else %if &ext=ico %then %do;%str(image/x-icon)%end;
%else %if &ext=sid %then %do;%str(image/x-mrsid-image)%end;
%else %if &ext=pct %then %do;%str(image/x-pict)%end;
%else %if &ext=pic %then %do;%str(image/x-pict)%end;
%else %if &ext=pnm %then %do;%str(image/x-portable-anymap)%end;
%else %if &ext=pbm %then %do;%str(image/x-portable-bitmap)%end;
%else %if &ext=pgm %then %do;%str(image/x-portable-graymap)%end;
%else %if &ext=ppm %then %do;%str(image/x-portable-pixmap)%end;
%else %if &ext=xbm %then %do;%str(image/x-xbitmap)%end;
%else %if &ext=xpm %then %do;%str(image/x-xpixmap)%end;
%else %if &ext=xwd %then %do;%str(image/x-xwindowdump)%end;
%else %if &ext=eml %then %do;%str(message/rfc822)%end;
%else %if &ext=mime %then %do;%str(message/rfc822)%end;
%else %if &ext=iges %then %do;%str(model/iges)%end;
%else %if &ext=igs %then %do;%str(model/iges)%end;
%else %if &ext=dae %then %do;%str(model/vnd.collada+xml)%end;
%else %if &ext=dwf %then %do;%str(model/vnd.dwf)%end;
%else %if &ext=gdl %then %do;%str(model/vnd.gdl)%end;
%else %if &ext=gtw %then %do;%str(model/vnd.gtw)%end;
%else %if &ext=vtu %then %do;%str(model/vnd.vtu)%end;
%else %if &ext=vrml %then %do;%str(model/vrml)%end;
%else %if &ext=wrl %then %do;%str(model/vrml)%end;
%else %if &ext=x3db %then %do;%str(model/x3d+binary)%end;
%else %if &ext=x3dbz %then %do;%str(model/x3d+binary)%end;
%else %if &ext=x3dv %then %do;%str(model/x3d+vrml)%end;
%else %if &ext=x3dvz %then %do;%str(model/x3d+vrml)%end;
%else %if &ext=x3d %then %do;%str(model/x3d+xml)%end;
%else %if &ext=x3dz %then %do;%str(model/x3d+xml)%end;
%else %if &ext=appcache %then %do;%str(text/cache-manifest)%end;
%else %if &ext=ics %then %do;%str(text/calendar)%end;
%else %if &ext=ifb %then %do;%str(text/calendar)%end;
%else %if &ext=htm %then %do;%str(text/html)%end;
%else %if &ext=js %then %do;%str(text/javascript)%end;
%else %if &ext=mjs %then %do;%str(text/javascript)%end;
%else %if &ext=dsc %then %do;%str(text/prs.lines.tag)%end;
%else %if &ext=rtx %then %do;%str(text/richtext)%end;
%else %if &ext=sgm %then %do;%str(text/sgml)%end;
%else %if &ext=tsv %then %do;%str(text/tab-separated-values)%end;
%else %if &ext=ttl %then %do;%str(text/turtle)%end;
%else %if &ext=curl %then %do;%str(text/vnd.curl)%end;
%else %if &ext=dcurl %then %do;%str(text/vnd.curl.dcurl)%end;
%else %if &ext=mcurl %then %do;%str(text/vnd.curl.mcurl)%end;
%else %if &ext=scurl %then %do;%str(text/vnd.curl.scurl)%end;
%else %if &ext=sub %then %do;%str(text/vnd.dvb.subtitle)%end;
%else %if &ext=fly %then %do;%str(text/vnd.fly)%end;
%else %if &ext=flx %then %do;%str(text/vnd.fmi.flexstor)%end;
%else %if &ext=gv %then %do;%str(text/vnd.graphviz)%end;
%else %if &ext=3dml %then %do;%str(text/vnd.in3d.3dml)%end;
%else %if &ext=spot %then %do;%str(text/vnd.in3d.spot)%end;
%else %if &ext=jad %then %do;%str(text/vnd.sun.j2me.app-descriptor)%end;
%else %if &ext=wml %then %do;%str(text/vnd.wap.wml)%end;
%else %if &ext=wmls %then %do;%str(text/vnd.wap.wmlscript)%end;
%else %if &ext=s %then %do;%str(text/x-asm)%end;
%else %if &ext=java %then %do;%str(text/x-java-source)%end;
%else %if &ext=p %then %do;%str(text/x-pascal)%end;
%else %if &ext=pas %then %do;%str(text/x-pascal)%end;
%else %if &ext=etx %then %do;%str(text/x-setext)%end;
%else %if &ext=uu %then %do;%str(text/x-uuencode)%end;
%else %if &ext=vcs %then %do;%str(text/x-vcalendar)%end;
%else %if &ext=vcf %then %do;%str(text/x-vcard)%end;
%else %if &ext=3gp %then %do;%str(video/3gpp)%end;
%else %if &ext=3g2 %then %do;%str(video/3gpp2)%end;
%else %if &ext=jpgv %then %do;%str(video/jpeg)%end;
%else %if &ext=jpgm %then %do;%str(video/jpm)%end;
%else %if &ext=mjp2 %then %do;%str(video/mj2)%end;
%else %if &ext=ogv %then %do;%str(video/ogg)%end;
%else %if &ext=mov %then %do;%str(video/quicktime)%end;
%else %if &ext=qt %then %do;%str(video/quicktime)%end;
%else %if &ext=uvh %then %do;%str(video/vnd.dece.hd)%end;
%else %if &ext=uvvh %then %do;%str(video/vnd.dece.hd)%end;
%else %if &ext=uvm %then %do;%str(video/vnd.dece.mobile)%end;
%else %if &ext=uvvm %then %do;%str(video/vnd.dece.mobile)%end;
%else %if &ext=uvp %then %do;%str(video/vnd.dece.pd)%end;
%else %if &ext=uvvp %then %do;%str(video/vnd.dece.pd)%end;
%else %if &ext=uvs %then %do;%str(video/vnd.dece.sd)%end;
%else %if &ext=uvvs %then %do;%str(video/vnd.dece.sd)%end;
%else %if &ext=uvv %then %do;%str(video/vnd.dece.video)%end;
%else %if &ext=uvvv %then %do;%str(video/vnd.dece.video)%end;
%else %if &ext=dvb %then %do;%str(video/vnd.dvb.file)%end;
%else %if &ext=fvt %then %do;%str(video/vnd.fvt)%end;
%else %if &ext=m4u %then %do;%str(video/vnd.mpegurl)%end;
%else %if &ext=mxu %then %do;%str(video/vnd.mpegurl)%end;
%else %if &ext=pyv %then %do;%str(video/vnd.ms-playready.media.pyv)%end;
%else %if &ext=uvu %then %do;%str(video/vnd.uvvu.mp4)%end;
%else %if &ext=uvvu %then %do;%str(video/vnd.uvvu.mp4)%end;
%else %if &ext=viv %then %do;%str(video/vnd.vivo)%end;
%else %if &ext=asf %then %do;%str(video/x-ms-asf)%end;
%else %if &ext=asx %then %do;%str(video/x-ms-asf)%end;
%else %if &ext=vob %then %do;%str(video/x-ms-vob)%end;
%else %if &ext=wm %then %do;%str(video/x-ms-wm)%end;
%else %if &ext=wmv %then %do;%str(video/x-ms-wmv)%end;
%else %if &ext=wmx %then %do;%str(video/x-ms-wmx)%end;
%else %if &ext=wvx %then %do;%str(video/x-ms-wvx)%end;
%else %if &ext=avi %then %do;%str(video/x-msvideo)%end;
%else %if &ext=movie %then %do;%str(video/x-sgi-movie)%end;
%else %if &ext=ice %then %do;%str(x-conference/x-cooltalk)%end;
%else %if "&ext"="in" %then %do;%str(text/plain)%end;
%else %do;%str(application/octet-stream)%end;
%mend mf_mimetype;

View File

@@ -79,8 +79,8 @@ data &cntlout/nonote2err;
end;
/* create row marker. Data cannot be sorted without it! */
if first.fmtname then fmtrow=1;
else fmtrow+1;
if first.fmtname then fmtrow=0;
fmtrow+1;
run;
proc sort;

View File

@@ -85,7 +85,7 @@ data;run;
data &out_ds(compress=no
keep=file_or_folder filepath filename ext msg directory level
);
length directory filepath $2000 fref fref2 $8 file_or_folder $6 filename $255
length directory filepath $500 fref fref2 $8 file_or_folder $6 filename $80
ext $20 msg $200 foption $16;
if _n_=1 then call missing(of _all_);
retain level &level;

View File

@@ -118,21 +118,13 @@ data _null_;
header = cats(coalescec(varlabel(dsid,i),varnm),dlm);
%end;
%else %if &headerformat=SASJS %then %do;
vlen=varlen(dsid,i);
if vartype(dsid,i)='C' then header=cats(varnm,':$char',vlen,'.');
if vartype(dsid,i)='C' then header=cats(varnm,':$char',varlen(dsid,i),'.');
else do;
vfmt=coalescec(varfmt(dsid,i),'0');
fmttype=mcf_getfmttype(vfmt);
if fmttype='DATE' then header=cats(varnm,':date9.');
else if fmttype='DATETIME' then header=cats(varnm,':E8601DT26.6');
else if fmttype='TIME' then header=cats(varnm,':TIME12.');
/**
* there is not much point importing a short length numeric like this,
* eg with best4., as the resulting variable will still be stored as
* length 8. We need a length or format statement to ensure variable
* is creatd with the smaller length...
**/
else if vlen<8 then header=cats(varnm,':best',vlen,'.');
else header=cats(varnm,':best.');
end;
%end;
@@ -159,7 +151,6 @@ data _null_;
set &ds end=last;
%do i=1 %to &vcnt;
%let var=%scan(&varlist,&i);
%local vlen&i;
%if %mf_getvartype(&ds,&var)=C %then %do;
%let dsv1=%mf_getuniquename(prefix=csvcol1_);
%let dsv2=%mf_getuniquename(prefix=csvcol2_);

View File

@@ -86,14 +86,15 @@
/**
* Sanitise the values based on valid value lists, then strip out
* quotes, commas, periods and spaces.
* Only numeric values should remain
*/
%local reason_cd nobs;
%let nobs=0;
data &outds;
/*length GROUP_LOGIC SUBGROUP_LOGIC $3 SUBGROUP_ID 8 VARIABLE_NM $32
OPERATOR_NM $10 RAW_VALUE $4000;*/
set &inds end=last;
length reason_cd $4032 vtype vtype2 $1 vnum dsid 8 tmp $4000;
set &inds;
length reason_cd $4032 vtype $1 vnum dsid 8 tmp $4000;
drop tmp;
/* quick check to ensure column exists */
@@ -109,8 +110,7 @@ data &outds;
end;
/* need to open the dataset to get the column type */
retain dsid;
if _n_=1 then dsid=open("&targetds","i");
dsid=open("&targetds","i");
if dsid>0 then do;
vnum=varnum(dsid,VARIABLE_NM);
if vnum<1 then do;
@@ -120,19 +120,11 @@ data &outds;
call symputx('reason_cd',reason_cd,'l');
call symputx('nobs',_n_,'l');
output;
goto endstep;
return;
end;
/* now we can get the type */
else vtype=vartype(dsid,vnum);
end;
else do;
REASON_CD=cats("Could not open &targetds");
putlog REASON_CD= dsid=;
call symputx('reason_cd',reason_cd,'l');
call symputx('nobs',_n_,'l');
output;
stop;
end;
/* closed list checks */
if GROUP_LOGIC not in ('AND','OR') then do;
@@ -167,40 +159,15 @@ data &outds;
end;
/* special missing logic */
if vtype='N' & OPERATOR_NM in ('=','>','<','<=','>=','NE','GE','LE') then do;
if cats(upcase(raw_value)) in (
if vtype='N'
and OPERATOR_NM in ('=','>','<','<=','>=','NE','GE','LE')
and cats(upcase(raw_value)) in (
'.','.A','.B','.C','.D','.E','.F','.G','.H','.I','.J','.K','.L','.M','.N'
'.N','.O','.P','.Q','.R','.S','.T','.U','.V','.W','.X','.Y','.Z','._'
)
then do;
/* valid numeric - exit data step loop */
return;
end;
else if subpad(upcase(raw_value),1,1) in (
'A','B','C','D','E','F','G','H','I','J','K','L','M','N'
'N','O','P','Q','R','S','T','U','V','W','X','Y','Z','_'
)
then do;
/* check if the raw_value contains a valid variable NAME */
vnum=varnum(dsid,subpad(raw_value,1,32));
if vnum>0 then do;
/* now we can get the type */
vtype2=vartype(dsid,vnum);
/* check type matches */
if vtype2=vtype then do;
/* valid target var - exit loop */
return;
end;
else do;
REASON_CD=cats("Compared Type (",vtype2,") is not (",vtype,")");
putlog REASON_CD= dsid=;
call symputx('reason_cd',reason_cd,'l');
call symputx('nobs',_n_,'l');
output;
goto endstep;
end;
end;
end;
then do;
/* valid numeric - exit data step loop */
return;
end;
/* special logic */
@@ -222,32 +189,6 @@ data &outds;
if vtype='N' then do i=1 to countc(raw_value1, ',')+1;
tmp=scan(raw_value1,i,',');
if cats(tmp) ne '.' and input(tmp, ?? 8.) eq . then do;
if OPERATOR_NM ='BETWEEN' and subpad(upcase(tmp),1,1) in (
'A','B','C','D','E','F','G','H','I','J','K','L','M','N'
'N','O','P','Q','R','S','T','U','V','W','X','Y','Z','_'
)
then do;
/* check if the raw_value contains a valid variable NAME */
/* is not valid syntax for IN or NOT IN */
vnum=varnum(dsid,subpad(tmp,1,32));
if vnum>0 then do;
/* now we can get the type */
vtype2=vartype(dsid,vnum);
/* check type matches */
if vtype2=vtype then do;
/* valid target var - exit loop */
return;
end;
else do;
REASON_CD=cats("Compared Type (",vtype2,") is not (",vtype,")");
putlog REASON_CD= dsid=;
call symputx('reason_cd',reason_cd,'l');
call symputx('nobs',_n_,'l');
output;
goto endstep;
end;
end;
end;
REASON_CD='Non Numeric value provided';
putlog REASON_CD= OPERATOR_NM= raw_value= raw_value1= ;
call symputx('reason_cd',reason_cd,'l');
@@ -272,42 +213,14 @@ data &outds;
/* output records that contain values other than digits and spaces */
if notdigit(compress(raw_value3,' '))>0 then do;
if vtype='C' and subpad(upcase(raw_value),1,1) in (
'A','B','C','D','E','F','G','H','I','J','K','L','M','N'
'N','O','P','Q','R','S','T','U','V','W','X','Y','Z','_'
)
then do;
/* check if the raw_value contains a valid variable NAME */
vnum=varnum(dsid,subpad(raw_value,1,32));
if vnum>0 then do;
/* now we can get the type */
vtype2=vartype(dsid,vnum);
/* check type matches */
if vtype2=vtype then do;
/* valid target var - exit loop */
return;
end;
else do;
REASON_CD=cats("Compared Char Type (",vtype2,") is not (",vtype,")");
putlog REASON_CD= dsid=;
call symputx('reason_cd',reason_cd,'l');
call symputx('nobs',_n_,'l');
output;
goto endstep;
end;
end;
end;
putlog raw_value3= $hex32.;
REASON_CD=cats('Invalid RAW_VALUE:',raw_value);
putlog (_all_)(=);
putlog REASON_CD= raw_value= raw_value1= raw_value2= raw_value3=;
call symputx('reason_cd',reason_cd,'l');
call symputx('nobs',_n_,'l');
output;
end;
endstep:
if last then rc=close(dsid);
run;

View File

@@ -53,11 +53,10 @@ data &outds(keep=name type length varnum format label ddtype fmtname);
else if formatd=0 then format=cats(fmtname,formatl,'.');
else format=cats(fmtname,formatl,'.',formatd);
type='N';
if format=:'DATETIME' or format=:'E8601DT' or format=:'NLDATM'
then ddtype='DATETIME';
if format=:'DATETIME' or format=:'E8601DT' then ddtype='DATETIME';
else if format=:'DATE' or format=:'DDMMYY' or format=:'MMDDYY'
or format=:'YYMMDD' or format=:'E8601DA' or format=:'B8601DA'
or format=:'MONYY' or format=:'NLDATE'
or format=:'MONYY'
then ddtype='DATE';
else if format=:'TIME' then ddtype='TIME';
else ddtype='NUMERIC';

View File

@@ -70,7 +70,6 @@ options
%if "%substr(&sysver,1,1)" ne "4" and "%substr(&sysver,1,1)" ne "5" %then %do;
noautocorrect /* disallow misspelled procedure names */
dsoptions=note2err /* undocumented - convert bad NOTEs to ERRs */
/* turn off with dsoptions=nonote2err */
%end;
;

View File

@@ -9,9 +9,6 @@
format, to prevent loss of data - UNLESS the input dataset contains a marker
column, specifying that a particular row needs to be deleted (`delete_col=`).
Positions of formats are made using the FMTROW variable - this must be present
and unique (on TYPE / FMTNAME / FMTROW).
This macro can also be used to identify which records would be (or were)
considered new, modified or deleted (`loadtarget=`) by creating the following
tables:
@@ -20,7 +17,7 @@
@li work.outds_del
@li work.outds_mod
For example usage, see test (under Related Macros)
For example usage, see mp_loadformat.test.sas
@param [in] libcat The format catalog to be loaded
@param [in] libds The staging table to load
@@ -37,15 +34,12 @@
@param [in] mdebug= (0) Set to 1 to enable DEBUG messages and preserve outputs
<h4> SAS Macros </h4>
@li mf_existds.sas
@li mf_existvar.sas
@li mf_getuniquename.sas
@li mf_nobs.sas
@li mp_abort.sas
@li mp_aligndecimal.sas
@li mp_cntlout.sas
@li mp_lockanytable.sas
@li mp_md5.sas
@li mp_storediffs.sas
<h4> Related Macros </h4>
@@ -89,16 +83,6 @@
%let libcat=%scan(&libcat,1,-);
/* perform input validations */
%mp_abort(
iftrue=(%mf_existds(&libds)=0)
,mac=&sysmacroname
,msg=%str(&libds could not be found)
)
%mp_abort(
iftrue=(%mf_existvar(&libds,FMTROW)=0)
,mac=&sysmacroname
,msg=%str(FMTROW not found in &libds)
)
%let err=0;
%let msg=0;
data _null_;
@@ -119,6 +103,13 @@ data _null_;
stop;
end;
end;
else if name='LIBDS' then do;
if exist(value) le 0 then do;
call symputx('msg',"Unable to open staging table: "!!value);
call symputx('err',1);
stop;
end;
end;
else if (name=:'OUTDS' or name in ('DELETE_COL','LOCKLIBDS','AUDITLIBDS'))
and missing(value) then do;
call symputx('msg',"missing value in var: "!!name);
@@ -126,14 +117,6 @@ data _null_;
stop;
end;
run;
data _null_;
set &libds;
if missing(fmtrow) then do;
call symputx('msg',"missing fmtrow in format: "!!FMTNAME);
call symputx('err',1);
stop;
end;
run;
%mp_abort(
iftrue=(&err ne 0)
@@ -141,15 +124,6 @@ run;
,msg=%str(&msg)
)
%local cnt;
proc sql noprint;
select count(distinct catx('|',type,fmtname,fmtrow)) into: cnt from &libds;
%mp_abort(
iftrue=(&cnt ne %mf_nobs(&libds))
,mac=&sysmacroname
,msg=%str(Non-unique primary key on &libds)
)
/**
* First, extract only relevant formats from the catalog
*/
@@ -203,6 +177,12 @@ data &inlibds/nonote2err;
%mp_aligndecimal(end,width=16)
end;
/* update row marker - retain new var as fmtrow may already be in libds */
if first.fmtname then row=1;
else row+1;
drop row;
fmtrow=row;
fmthash=%mp_md5(cvars=&cvars, nvars=&nvars);
run;

View File

@@ -197,7 +197,6 @@
@li mp_coretable.sas
@li mp_stackdiffs.test.sas
@li mp_storediffs.sas
@li mp_stripdiffs.sas
@todo The current approach assumes that a variable called KEY_HASH is not on
the base table. This part will need to be refactored (eg using

View File

@@ -64,7 +64,6 @@
<h4> Related Macros </h4>
@li mp_stackdiffs.sas
@li mp_storediffs.test.sas
@li mp_stripdiffs.sas
@version 9.2
@author Allan Bowe
@@ -184,7 +183,7 @@ data &ds4;
run;
%if "&loadref"="0" %then %let loadref=%sysfunc(uuidgen());
%if &processed_dttm=0 %then %let processed_dttm=%sysfunc(datetime(),8.6);
%if &processed_dttm=0 %then %let processed_dttm=%sysfunc(datetime());
%let libds=%upcase(&libds);
/* join orig vals for modified & deleted */

View File

@@ -1,255 +0,0 @@
/**
@file
@brief Generates a stage dataset to revert diffs tracked in an audit table
@details A big benefit of tracking data changes in an audit table is that
those changes can be subsequently reverted if necessary!
This macro prepares a staging dataset containing those differences - eg for:
@li deleted rows - these are re-inserted
@li changed rows - differences are reverted
@li added rows - marked with `_____DELETE__THIS__RECORD_____="YES"`
These changes are NOT applied to the base table - a staging dataset is
simply prepared for an ETL process to action. In Data Controller, this
dataset is used directly as an input to the APPROVE process (so that the
reversion diffs can be reviewed prior to being applied).
@param [in] libds Base library.dataset (will not be modified). The library
must be assigned.
@param [in] loadref Unique identifier for the version to be reverted. This
change, plus ALL SUBSEQUENT CHANGES, will be reverted in the output table.
@param [in] difftable The dataset containing the diffs. Definition available
in mddl_dc_difftable.sas
@param [in] filtervar= (0) If provided, the contents of this macro variable
will be applied as an additional filter against &libds
@param [out] outds= (work.mp_stripdiffs) Output table containing the diffs.
Has the same format as the base datset, plus a
`_____DELETE__THIS__RECORD_____` variable.
@param [in] mdebug= set to 1 to enable DEBUG messages and preserve outputs
<h4> SAS Macros </h4>
@li mf_getuniquefileref.sas
@li mf_getuniquename.sas
@li mf_getvarlist.sas
@li mf_islibds.sas
@li mf_wordsinstr1butnotstr2.sas
@li mp_abort.sas
<h4> Related Macros </h4>
@li mddl_dc_difftable.sas
@li mp_stackdiffs.sas
@li mp_storediffs.sas
@li mp_stripdiffs.test.sas
@version 9.2
@author Allan Bowe
**/
/** @cond */
%macro mp_stripdiffs(libds
,loadref
,difftable
,filtervar=0
,outds=work.mp_stripdiffs
,mdebug=0
)/*/STORE SOURCE*/;
%local dbg;
%if &mdebug=1 %then %do;
%put &sysmacroname entry vars:;
%put _local_;
%end;
%else %let dbg=*;
%let libds=%upcase(&libds);
/* safety checks */
%mp_abort(iftrue= (&syscc ne 0)
,mac=&sysmacroname
,msg=%str(SYSCC=&syscc on entry. Clean session required!)
)
%let libds=%upcase(&libds);
%mp_abort(iftrue= (%mf_islibds(&libds)=0)
,mac=&sysmacroname
,msg=%str(Invalid library.dataset reference - %superq(libds))
)
/* set up unique and temporary vars */
%local ds1 ds2 ds3 ds4 ds5 fref1 filterstr;
%let fref1=%mf_getuniquefileref();
%if &filtervar ne 0 %then %let filterstr=%superq(&filtervar);
%else %let filterstr=%str(1=1);
/* get timestamp of the diff to be reverted */
%local ts;
proc sql noprint;
select put(processed_dttm,datetime19.6) into: ts
from &difftable where load_ref="&loadref";
%mp_abort(iftrue= (&sqlobs=0)
,mac=&sysmacroname
,msg=%str(Load ref %superq(loadref) not found!)
)
/* extract diffs for this base table from this timestamp onwards */
%let ds1=%upcase(work.%mf_getuniquename(prefix=mpsd_diffs));
create table &ds1 (drop=libref dsn) as
select * from &difftable
where upcase(cats(libref))="%scan(&libds,1,.)"
and upcase(cats(dsn))="%scan(&libds,2,.)"
and processed_dttm ge "&ts"dt
order by processed_dttm desc, key_hash, is_pk;
/* extract key values only */
%let ds2=%upcase(work.%mf_getuniquename(prefix=mpsd_pks));
%local keyhash processed;
%let keyhash=%upcase(%mf_getuniquename(prefix=mpsdvar_keyhash));
%let processed=%upcase(%mf_getuniquename(prefix=mpsdvar_processed));
create table &ds2 as
select key_hash as &keyhash,
tgtvar_nm,
tgtvar_type,
coalescec(oldval_char,newval_char) as charval,
coalesce(oldval_num, newval_num) as numval,
processed_dttm as &processed
from &ds1
where is_pk=1
order by &keyhash, &processed;
/* grab pk values */
%local pk;
select distinct upcase(tgtvar_nm) into: pk separated by ' ' from &ds2;
%let ds3=%upcase(work.%mf_getuniquename(prefix=mpsd_keychar));
proc transpose data=&ds2(where=(tgtvar_type='C'))
out=&ds3(drop=_name_);
by &keyhash &processed;
id TGTVAR_NM;
var charval;
run;
%let ds4=%upcase(work.%mf_getuniquename(prefix=mpsd_keynum));
proc transpose data=&ds2(where=(tgtvar_type='N'))
out=&ds4(drop=_name_);
by &keyhash &processed;
id TGTVAR_NM;
var numval;
run;
/* shorten the lengths */
%mp_ds2squeeze(&ds3,outds=&ds3)
%mp_ds2squeeze(&ds4,outds=&ds4)
/* now merge to get all key values and de-dup */
%let ds5=%upcase(work.%mf_getuniquename(prefix=mpsd_merged));
data &ds5;
length &keyhash $32 &processed 8;
merge &ds3 &ds4;
by &keyhash &processed;
if not missing(&keyhash);
run;
proc sort data=&ds5 nodupkey;
by &pk;
run;
/* join to base table for preliminary stage DS */
proc sql;
create table &outds as select "No " as _____DELETE__THIS__RECORD_____
%do x=1 %to %sysfunc(countw(&pk,%str( )));
,a.%scan(&pk,&x,%str( ))
%end;
%local notpkcols;
%let notpkcols=%upcase(%mf_getvarlist(&libds));
%let notpkcols=%mf_wordsinstr1butnotstr2(str1=&notpkcols,str2=&pk);
%do x=1 %to %sysfunc(countw(&notpkcols,%str( )));
,b.%scan(&notpkcols,&x,%str( ))
%end;
from &ds5 a
left join &libds (where=(&filterstr)) b
on 1=1
%do x=1 %to %sysfunc(countw(&pk,%str( )));
and a.%scan(&pk,&x,%str( ))=b.%scan(&pk,&x,%str( ))
%end;
;
/* create SAS code to apply to stage_ds */
data _null_;
set &ds1;
file &fref1 lrecl=33000;
length charval $32767;
if _n_=1 then put 'proc sql noprint;';
by descending processed_dttm key_hash is_pk;
if move_type='M' then do;
if first.key_hash then do;
put "update &outds set " @@;
end;
if IS_PK=0 then do;
put " " tgtvar_nm '=' @@;
cnt=count(oldval_char,'"');
charval=quote(trim(substr(oldval_char,1,32765-cnt)));
if tgtvar_type='C' then put charval @@;
else put oldval_num @@;
if not last.is_pk then put ',';
end;
else do;
if first.is_pk then put " where 1=1 " @@;
put " and " tgtvar_nm '=' @@;
cnt=count(oldval_char,'"');
charval=quote(trim(substr(oldval_char,1,32765-cnt)));
if tgtvar_type='C' then put charval @@;
else put oldval_num @@;
end;
end;
else if move_type='A' then do;
if first.key_hash then do;
put "update &outds set _____DELETE__THIS__RECORD_____='Yes' where 1=1 "@@;
end;
/* gating if - as only need PK now */
if is_pk=1;
put ' AND ' tgtvar_nm '=' @@;
cnt=count(newval_char,'"');
charval=quote(trim(substr(newval_char,1,32765-cnt)));
if tgtvar_type='C' then put charval @@;
else put newval_num @@;
end;
else if move_type='D' then do;
if first.key_hash then do;
put "update &outds set _____DELETE__THIS__RECORD_____='No' " @@;
end;
if IS_PK=0 then do;
put " ," tgtvar_nm '=' @@;
cnt=count(oldval_char,'"');
charval=quote(trim(substr(oldval_char,1,32765-cnt)));
if tgtvar_type='C' then put charval @@;
else put oldval_num @@;
end;
else do;
if first.is_pk then put " where 1=1 " @@;
put " and " tgtvar_nm '=' @@;
cnt=count(oldval_char,'"');
charval=quote(trim(substr(oldval_char,1,32765-cnt)));
if tgtvar_type='C' then put charval @@;
else put oldval_num @@;
end;
end;
if last.key_hash then put ';';
run;
/* apply the modification statements */
%inc &fref1/source2 lrecl=33000;
%if &mdebug=0 %then %do;
proc sql;
drop table &ds1, &ds2, &ds3, &ds4, &ds5;
file &fref1 clear;
%end;
%else %do;
data _null_;
infile &fref1;
input;
if _n_=1 then putlog "Contents of SQL adjustments";
putlog _infile_;
run;
%end;
%mend mp_stripdiffs;
/** @endcond */

View File

@@ -6,22 +6,6 @@
(given various practical restrictions) are described here to enable
consistency when dealing with format data.
The HLO variable may have a number of values, documented here due to the
256 char label description length limit:
F=Standard format/informat.
H=Range ending value is HIGH.
I=Numeric informat.
J=Justification for an informat.
L=Range starting value is LOW.
M=MultiLabel.
N=Format or informat has no ranges, including no OTHER= range.
O=Range is OTHER.
R=ROUND option is in effect.
S=Specifies that NOTSORTED is in effect.
U=Specifies that the UPCASE option for an informat be used.
**/
@@ -29,11 +13,9 @@
proc sql;
create table &libds(
TYPE char(1) label=
'Format Type: either N (num fmt), C (char fmt), I (num infmt) or J (char infmt)'
TYPE char(1) label='Type of format - either N (num fmt), C (char fmt), I (num infmt) or J (char infmt)'
,FMTNAME char(32) label='Format name'
,FMTROW num label=
'CALCULATED Position of record by FMTNAME (reqd for multilabel formats)'
,FMTROW num label='CALCULATED Position of record by FMTNAME (reqd for multilabel formats)'
,START char(32767) label='Starting value for format'
/*
Keep lengths of START and END the same to avoid this err:
@@ -53,8 +35,18 @@
,NOEDIT num length=3 label='Is picture string noedit?'
,SEXCL char(1) label='Start exclusion'
,EEXCL char(1) label='End exclusion'
,HLO char(13) label=
'More info: https://core.sasjs.io/mddl__sas__cntlout_8sas_source.html'
,HLO char(13) label='Additional information.
F=Standard format/informat.
H=Range ending value is HIGH.
I=Numeric informat.
J=Justification for an informat.
L=Range starting value is LOW.
M=MultiLabel.
N=Format or informat has no ranges, including no OTHER= range.
O=Range is OTHER.
R=ROUND option is in effect.
S=Specifies that NOTSORTED is in effect.
U=Specifies that the UPCASE option for an informat be used.'
,DECSEP char(1) label='Decimal separator'
,DIG3SEP char(1) label='Three-digit separator'
,DATATYPE char(8) label='Date/time/datetime?'

View File

@@ -80,8 +80,8 @@ function mcf_getfmttype(fmtnm $) $8;
/* apply lookups */
if cats(fmt) in ('DATETIME','B8601DN','B8601DN','B8601DT','B8601DT'
,'B8601DZ','B8601DZ','DATEAMPM','DTDATE','DTMONYY','DTWKDATX','DTYEAR'
,'DTYYQC','E8601DN','E8601DN','E8601DT','E8601DT','E8601DZ','E8601DZ'
,'NLDATM') then return('DATETIME');
,'DTYYQC','E8601DN','E8601DN','E8601DT','E8601DT','E8601DZ','E8601DZ')
then return('DATETIME');
else if fmt in ('DATE','YYMMDD','B8601DA','B8601DA','DAY','DDMMYY'
,'DDMMYYB','DDMMYYC','DDMMYYD','DDMMYYN','DDMMYYP','DDMMYYS','DDMMYYx'
,'DOWNAME','E8601DA','E8601DA','JULDAY','JULIAN','MMDDYY','MMDDYYB'
@@ -92,7 +92,7 @@ function mcf_getfmttype(fmtnm $) $8;
,'YYMMD','YYMMDDB','YYMMDDC','YYMMDDD','YYMMDDN','YYMMDDP','YYMMDDS'
,'YYMMDDx','YYMMN','YYMMP','YYMMS','YYMMx','YYMON','YYQ','YYQC','YYQD'
,'YYQN','YYQP','YYQR','YYQRC','YYQRD','YYQRN','YYQRP','YYQRS','YYQRx'
,'YYQS','YYQx','YYQZ','NLDATE') then return('DATE');
,'YYQS','YYQx','YYQZ') then return('DATE');
else if fmt in ('TIME','B8601LZ','B8601LZ','B8601TM','B8601TM','B8601TZ'
,'B8601TZ','E8601LZ','E8601LZ','E8601TM','E8601TM','E8601TZ','E8601TZ'
,'HHMM','HOUR','MMSS','TIMEAMPM','TOD') then return('TIME');

View File

@@ -54,8 +54,7 @@
%local cur_engine;
%let cur_engine=%mf_getengine(&libref);
%if &cur_engine ne META and &cur_engine ne and %length(&open_passthrough)=0
%then %do;
%if &cur_engine ne META and &cur_engine ne %then %do;
%put NOTE: &libref already has a direct (&cur_engine) libname connection;
%return;
%end;
@@ -211,7 +210,7 @@ run;
%end;
%end;
%else %if &engine=ODBC %then %do;
%&mD.put NOTE: Retrieving ODBC connection details;
&mD.%put NOTE: Retrieving ODBC connection details;
data _null_;
length connx_uri conprop_uri value datasource up_uri schema domprop_uri authdomain $256.;
call missing (of _all_);

View File

@@ -1,25 +1,22 @@
/**
@file mm_getdetails.sas
@brief extracts metadata attributes and associations for a particular uri
@param [in] uri the metadata object for which to return
attributes / associations
@param [in] sortoptions= Enables sorting of the output datasets, for example,
`SORTSEQ=LINGUISTIC`
@param [out] outattrs= (work.attributes)
The dataset to create that contains the list of attributes
@param [out] outassocs= (work.associations)
The dataset to contain the list of associations
<h4> Related Files </h4>
@li mm_getobjects.sas
@li mm_gettypes.sas
@version 9.2
@author Allan Bowe
**/
%macro mm_getdetails(uri
,outattrs=work.attributes
,outassocs=work.associations
,sortoptions=
)/*/STORE SOURCE*/;
data &outassocs;
@@ -44,7 +41,7 @@ data &outassocs;
n1+1;
end;
run;
proc sort &sortoptions;
proc sort;
by assoc name;
run;
@@ -64,7 +61,7 @@ data &outattrs;
n1+1;
end;
run;
proc sort &sortoptions;
proc sort;
by type name;
run;

View File

@@ -11,11 +11,10 @@
@param [in] user= the metadata user to return groups for. Leave blank for all
groups.
@param [in] repo= (foundation) the metadata repository that contains the
user/group information
@param [in] mDebug= (0) set to 1 to show debug messages in the log
@param [out] outds= (work.mm_getgroups) The dataset to create that contains
the list of groups
@param [in] repo= the metadata repository that contains the user/group
information
@param [in] mDebug= set to 1 to show debug messages in the log
@param [out] outds= the dataset to create that contains the list of groups
@returns outds dataset containing all groups in a column named "metagroup"
- groupuri

1724
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -7,7 +7,7 @@
"Viya",
"SASjs"
],
"author": "Allan Bowe",
"author": "Allan Bowe <support@macropeople.com>",
"repository": {
"type": "git",
"url": "git+https://github.com/sasjs/core.git"
@@ -26,10 +26,13 @@
"homepage": "https://core.sasjs.io",
"main": "index.js",
"scripts": {
"build": "npx @sasjs/cli cbd -t server",
"docs": "npx @sasjs/cli doc -t docsonly && ./sasjs/utils/build.sh",
"test": "npx @sasjs/cli test -t server",
"lint": "npx @sasjs/cli lint",
"build": "sasjs cbd -t server",
"docs": "sasjs doc -t docsonly && ./sasjs/utils/build.sh",
"test": "sasjs test -t server",
"lint": "sasjs lint",
"prepare": "git rev-parse --git-dir && git config core.hooksPath ./.git-hooks || true"
},
"devDependencies": {
"@sasjs/cli": "^4.4.1"
}
}
}

View File

@@ -37,10 +37,6 @@
"allowInsecureRequests": false
},
"appLoc": "/Public/app/macrocore",
"deployConfig": {
"deployServicePack": true,
"deployScripts": []
},
"macroFolders": [
"viya",
"tests/viyaonly"
@@ -71,7 +67,7 @@
},
{
"name": "server",
"serverUrl": "https://sas.4gl.io",
"serverUrl": "https://sas9.4gl.io",
"serverType": "SASJS",
"httpsAgentOptions": {
"allowInsecureRequests": false

View File

@@ -1,27 +1,22 @@
#!/bin/bash
####################################################################
# PROJECT: SASjs Core Docs Build
# To execute, use the npm command (npm run docs)
# Target repo will have github action to create sitemap
# https://github.com/marketplace/actions/generate-sitemap
# PROJECT: Macro Core Docs Build #
# To execute, use the npm command (npm run docs) #
####################################################################
# refresh github pages site
rm -rf sasjsbuild/docsite
git clone git@github.com:sasjs/core.github.io.git sasjsbuild/docsite
rm -rf sasjsbuild/docsite/*.html
rm -rf sasjsbuild/docsite/*.js
rm -rf sasjsbuild/docsite/*.png
rm -rf sasjsbuild/docsite/*.dot
rm -rf sasjsbuild/docsite/*.css
rm -rf sasjsbuild/docsite/*.svg
rm -rf search
cp -R sasjsbuild/docs/* sasjsbuild/docsite/
rm -rf sasjsbuild/docsite/*
mv sasjsbuild/docs/* sasjsbuild/docsite/
cd sasjsbuild/docsite/
git config user.name sasjs
echo 'core.sasjs.io' > CNAME
git add .
git commit -m "build.sh build on $(date +%F:%H:%M:%S)"
git push
npx sitemap-generator-cli https://core.sasjs.io
git add .
git commit -m "adding sitemap"
git push
echo "check it out: https://sasjs.github.io/core.github.io/files.html"

View File

@@ -8,12 +8,6 @@
Requires the server to have SSH keys.
<h4> SAS Macros </h4>
@li mf_mkdir.sas
@li mp_gitadd.sas
@li mp_gitreleaseinfo.sas
@li mp_gitstatus.sas
<h4> SAS Macros </h4>
@li mp_gitadd.sas
@li mp_gitreleaseinfo.sas
@@ -130,15 +124,11 @@ data members(compress=char);
keep name name2 path;
run;
proc sort data=members;
by name name2;
run;
%let temp_options = %sysfunc(getoption(source)) %sysfunc(getoption(notes));
options nosource nonotes;
data _null_;
set members;
by name;
by name notsorted;
ord + first.name;

View File

@@ -1,231 +0,0 @@
/**
@file
@brief Triggers a SASjs Server STP using the /SASjsApi/stp/trigger endpoint
@details Triggers the STP and returns the sessionId
Example:
%ms_triggerstp(/some/stored/program
,debug=131
,outds=work.myresults
)
@param [in] pgm The full path to the Stored Program in SASjs Drive (_program
parameter)
@param [in] debug= (131) The value to supply to the _debug URL parameter
@param [in] mdebug= (0) Set to 1 to enable DEBUG messages
@param [in] inputparams=(_null_) A dataset containing name/value pairs in the
following format:
|name:$32|value:$10000|
|---|---|
|stpmacname|some value|
|mustbevalidname|can be anything, oops, %abort!!|
@param [in] inputfiles= (_null_) A dataset containing fileref/name/filename in
the following format:
|fileref:$8|name:$32|filename:$256|
|---|---|--|
|someref|some_name|some_filename.xls|
|fref2|another_file|zyx_v2.csv|
@param [in] expiresaftermins= (15) The number of minutes to retain the session
folder after the session ends.
@param [out] outds= (work.ms_triggerstp) Set to the name of a dataset to
contain the sessionId. If this dataset already exists, and contains the
sessionId, it will be appended to.
Format:
|sessionId:$36|
|---|
|20241028074744-54132-1730101664824|
<h4> SAS Macros </h4>
@li mf_getuniquefileref.sas
@li mf_getuniquelibref.sas
@li mf_getuniquename.sas
@li mp_abort.sas
@li mp_dropmembers.sas
@li mf_nobs.sas
**/
%macro ms_triggerstp(pgm
,debug=131
,inputparams=_null_
,inputfiles=_null_
,expiresAfterMins=15
,outds=work.ms_triggerstp
,mdebug=0
);
%local dbg mainref authref boundary libref triggered_sid;
%let mainref=%mf_getuniquefileref();
%let authref=%mf_getuniquefileref();
%let boundary=%mf_getuniquename();
%if &inputparams=0 %then %let inputparams=_null_;
%if &mdebug=1 %then %do;
%put &sysmacroname entry vars:;
%put _local_;
%end;
%else %let dbg=*;
%mp_abort(iftrue=("&pgm"="")
,mac=&sysmacroname
,msg=%str(Program not provided)
)
%mp_abort(iftrue=("&outds"="")
,mac=&sysmacroname
,msg=%str(Output dataset not provided)
)
/* avoid sending bom marker to API */
%local optval;
%let optval=%sysfunc(getoption(bomfile));
options nobomfile;
/* Add params to the content */
data _null_;
file &mainref termstr=crlf lrecl=32767 mod;
length line $1000 name $32 value $32767;
if _n_=1 then call missing(of _all_);
set &inputparams;
put "--&boundary";
line=cats('Content-Disposition: form-data; name="',name,'"');
put line;
put ;
put value;
run;
/* parse input file list */
%local webcount;
%let webcount=0;
data _null_;
set &inputfiles end=last;
length fileref $8 name $32 filename $256;
call symputx(cats('webref',_n_),fileref,'l');
call symputx(cats('webname',_n_),name,'l');
call symputx(cats('webfilename',_n_),filename,'l');
if last then do;
call symputx('webcount',_n_);
call missing(of _all_);
end;
run;
/* write out the input files to the content */
%local i;
%do i=1 %to &webcount;
data _null_;
file &mainref termstr=crlf lrecl=32767 mod;
infile &&webref&i lrecl=32767;
if _n_ = 1 then do;
length line $32767;
line=cats(
'Content-Disposition: form-data; name="'
,"&&webname&i"
,'"; filename="'
,"&&webfilename&i"
,'"'
);
put "--&boundary";
put line;
put "Content-Type: text/plain";
put ;
end;
input;
put _infile_; /* add the actual file to be sent */
run;
%end;
/* Add footer to the content */
data _null_;
file &mainref termstr=crlf mod;
put / "--&boundary--";
run;
data _null_;
file &authref lrecl=1000;
infile "&_sasjs_tokenfile" lrecl=1000;
input;
if _n_=1 then put "Content-Type: multipart/form-data; boundary=&boundary";
put _infile_;
run;
%if &mdebug=1 %then %do;
data _null_;
if _n_ eq 1 then putlog "NOTE: ***** authref=&authref content *****";
infile &authref;
input;
put _infile_;
data _null_;
if _n_ eq 1 then putlog "NOTE: ***** mainref=&mainref content *****";
infile &mainref;
input;
put _infile_;
run;
%end;
%local resp_path outref;
%let resp_path=%sysfunc(pathname(work))/%mf_getuniquename();
%let outref=%mf_getuniquefileref();
filename &outref "&resp_path" lrecl=32767;
/* prepare request*/
proc http method='POST' headerin=&authref in=&mainref out=&outref
url="&_sasjs_apiserverurl/SASjsApi/stp/trigger?%trim(
)_program=&pgm%str(&)_debug=131%str(&)expiresAfterMins=&expiresaftermins";
%if &mdebug=1 %then %do;
debug level=2;
%end;
run;
%if (&SYS_PROCHTTP_STATUS_CODE ne 200 and &SYS_PROCHTTP_STATUS_CODE ne 201)
or &mdebug=1
%then %do;
data _null_;
if _n_ eq 1 then putlog "NOTE: ***** outref=&outref content *****";
infile &outref;
input;
putlog _infile_;
run;
%end;
%mp_abort(
iftrue=(&SYS_PROCHTTP_STATUS_CODE ne 200
and &SYS_PROCHTTP_STATUS_CODE ne 201)
,mac=&sysmacroname
,msg=%str(&SYS_PROCHTTP_STATUS_CODE &SYS_PROCHTTP_STATUS_PHRASE)
)
/* reset options */
options &optval;
%let libref=%mf_getuniquelibref();
libname &libref JSON fileref=&outref;
%let triggered_sid=%mf_getuniquename(prefix=triggered_sid_);
data work.&triggered_sid (keep=sessionid);
set &libref..root;
%if &mdebug=1 %then %do;
putlog (_all_)(=);
%end;
run;
%if %mf_nobs(work.&triggered_sid)>0 %then %do;
proc append base=&outds data=work.&triggered_sid;
run;
%end;
%if &mdebug=1 %then %do;
%put &sysmacroname exit vars:;
%put _local_;
%end;
%else %do;
/* clear refs */
filename &authref;
filename &mainref;
filename &outref;
libname &libref clear;
/* and remove temp dataset */
%mp_dropmembers(&triggered_sid,libref=work);
%end;
%mend ms_triggerstp;

View File

@@ -1,16 +0,0 @@
/**
@file
@brief Testing mf_mimetype macro
<h4> SAS Macros </h4>
@li mf_mimetype.sas
@li mp_assert.sas
**/
%mp_assert(
iftrue=("%mf_mimetype(XLS)"="application/vnd.ms-excel",
desc=Checking correct value
)

View File

@@ -1,43 +0,0 @@
/**
@file
@brief Testing mp_ds2csv.sas macro
<h4> SAS Macros </h4>
@li mp_ds2csv.sas
@li mp_assert.sas
@li mp_assertscope.sas
**/
data work.shortnum;
length a 3 b 4 c 8;
a=1;b=2;c=3;
output;
stop;
run;
/**
* Test 1 - default CSV
*/
%mp_ds2csv(work.shortnum,outfile="&sasjswork/test1.csv",headerformat=SASJS)
%let test1b=FAIL;
data _null_;
infile "&sasjswork/test1.csv";
input;
list;
if _n_=1 then call symputx('test1a',_infile_);
else if _infile_=:'1,2,3' then call symputx('test1b','PASS');
run;
%mp_assert(
iftrue=("&test1a"="A:best3. B:best4. C:best."),
desc=Checking header row Test 1,
outds=work.test_results
)
%mp_assert(
iftrue=("&test1b"="PASS"),
desc=Checking data row Test 1,
outds=work.test_results
)

View File

@@ -53,10 +53,7 @@ AND,AND,1,age,=,.A
AND,AND,1,height,<,.B
AND,AND,1,age,IN,"(.a,.b,.)"
AND,AND,1,age,IN,"(.A)"
AND,AND,1,AGE,=,AGE
AND,AND,1,AGE,<,Weight
AND,AND,1,AGE,BETWEEN,"HEIGHT AND WEIGHT"
AND,OR,2,Name,=,name
;;;;
run;
@@ -207,26 +204,3 @@ run;
outds=work.test_results
)
%let syscc=0;
/* invalid IN value (cannot use var names) */
data work.inds;
infile datalines4 dsd;
input GROUP_LOGIC:$3. SUBGROUP_LOGIC:$3. SUBGROUP_ID:8. VARIABLE_NM:$32.
OPERATOR_NM:$10. RAW_VALUE:$4000.;
datalines4;
AND,AND,1,AGE,NOT IN,"(height, age)"
;;;;
run;
%mp_filtercheck(work.inds,
targetds=work.class,
outds=work.badrecords,
abort=NO
)
%let syscc=0;
%mp_assertdsobs(work.badrecords,
desc=Invalid IN syntax,
test=HASOBS,
outds=work.test_results
)

View File

@@ -189,10 +189,8 @@ data work.stagedata3;
if last.fmtname then do;
output; /* 6 new records */
x=_n_;
x+1;start=cats("mod",x);end=start;label='newlabel1';fmtrow=fmtrow+1;
output;
x+1;start=cats("mod",x);end=start;label='newlabel2';fmtrow=fmtrow+2;
output;
x+1;start=cats("mod",x);end=start;label='newlabel1';output;
x+1;start=cats("mod",x);end=start;label='newlabel2';output;
end;
else if fmtrow le 3 then do; /* 9 more changed values */
start= cats("mod",_n_);

View File

@@ -58,9 +58,6 @@ proc format library=&cat1;
value agemlb (multilabel)
19-120='Adults'
1-18='Children'
0-1='Preschool'
1-2='Preschool'
2-3='Preschool'
1-4='Preschool';
value agemlc (multilabel notsorted)
19-120='Adults'
@@ -70,19 +67,16 @@ run;
%mp_cntlout(libcat=&cat1,cntlout=work.cntlout1)
%mp_assertdsobs(work.cntlout1,
desc=Has 19 records,
test=EQUALS 19
desc=Has 16 records,
test=EQUALS 16
)
data work.stagedata3;
set work.cntlout1;
if fmtname='AGEMLA' and label ne 'Preschool' then deleteme='Yes';
if fmtname='AGEMLB' and label = 'Preschool' then label='Kids';
if fmtname='GENDERML' and label='Farmale' then do;
output;
fmtrow=101; output;
end;
else output;
if fmtname='GENDERML' and label='Farmale' then output;
output;
run;
@@ -119,17 +113,14 @@ run;
%let check1=0;
%let check2=0;
%let check3=0;
data test;
set work.cntlout2;
where fmtname='GENDERML';
putlog fmtrow= label=;
if _n_=4 and label='Farmale' then call symputx('check1',1);
if _n_=5 and label ne 'Farmale' then call symputx('check2',1);
if _n_=8 and label = 'Farmale' then call symputx('check3',1);
if _n_=5 and label='Farmale' then call symputx('check2',1);
run;
%mp_assert(
iftrue=(&check1=1 and &check2=1 and &check3=1),
iftrue=(&check1=1 and &check2=1),
desc=Ensuring Farmale values retain their order,
outds=work.test_results
)

View File

@@ -1,106 +0,0 @@
/**
@file
@brief Testing mp_stripdiffs.sas macro
@details
<h4> SAS Macros </h4>
@li mp_assert.sas
@li mp_assertscope.sas
@li mp_ds2md.sas
@li mp_stripdiffs.sas
**/
/* make an adjustable base dataset */
/* use a composite key also (name weight) */
libname libby (work);
data libby.class;
set sashelp.class;
run;
/* first, store some diffs */
data work.orig work.deleted work.changed work.appended;
set libby.class;
if _n_=1 then do;
call symputx('delname',name);
output work.orig work.deleted;
end;
else if _n_=2 then do;
output work.orig;
call symputx('modname',name);
call symputx('modval',age);
age=99;
output work.changed;
end;
else do;
name='Newbie';
output work.appended;
stop;
end;
run;
%mp_storediffs(libby.class,work.orig,NAME WEIGHT
,delds=work.deleted
,modds=work.changed
,appds=work.appended
,outds=work.audit
,loadref=UPLOAD1
,mdebug=0
)
%mp_ds2md(work.audit)
%mp_assert(
iftrue=(&syscc=0),
desc=Checking preparation case,
outds=work.test_results
)
/* apply the changes */
proc sql;
delete from libby.class where name in ("&delname","&modname");
proc append base=libby.class data=work.appended;
proc append base=libby.class data=work.changed;
run;
/* now, prepare the revert dataset */
%mp_assertscope(SNAPSHOT)
%mp_stripdiffs(libby.class
,UPLOAD1
,work.audit
,outds=work.mp_stripdiffs
,mdebug=1
)
%mp_ds2md(work.mp_stripdiffs)
%mp_assertscope(COMPARE)
%mp_assert(
iftrue=(&syscc=0),
desc=Checking error condition,
outds=work.test_results
)
%let delpass=0;
%let modpass=0;
%let addpass=0;
data _null_;
set work.mp_stripdiffs;
if upcase(_____DELETE__THIS__RECORD_____)='NO' and name="&delname"
then call symputx('delpass',1);
if name="&modname" and age=&modval then call symputx('modpass',1);
if upcase(_____DELETE__THIS__RECORD_____)='YES' and name="Newbie"
then call symputx('addpass',1);
run;
%mp_assert(
iftrue=(&delpass=1),
desc=Ensuring deleted record is back in the dataset,
outds=work.test_results
)
%mp_assert(
iftrue=(&modpass=1),
desc=Ensuring modified record now has old value,
outds=work.test_results
)
%mp_assert(
iftrue=(&addpass=1),
desc=Ensuring added record is now marked for deletion,
outds=work.test_results
)

View File

@@ -1,90 +0,0 @@
/**
@file
@brief Testing ms_triggerstp.sas macro
<h4> SAS Macros </h4>
@li mf_getuniquename.sas
@li mp_assert.sas
@li mp_assertscope.sas
@li ms_createfile.sas
@li ms_triggerstp.sas
@li mf_existds.sas
@li mp_assertdsobs.sas
@li mp_assertcols.sas
@li mf_getvartype.sas
@li ms_deletefile.sas
**/
/* first, create multiple STPs to run */
filename stpcode1 temp;
data _null_;
file stpcode1;
put '%put hello world;';
put '%put _all_;';
put 'data _null_; file _webout1; put "triggerstp test 1";run;';
run;
filename stpcode2 temp;
data _null_;
file stpcode2;
put '%put Lorem Ipsum;';
put '%put _all_;';
put 'data _null_; file _webout2; put "triggerstp test 2";run;';
run;
options mprint;
%let fname1=%mf_getuniquename();
%let fname2=%mf_getuniquename();
%ms_createfile(/sasjs/tests/&fname1..sas
,inref=stpcode1
,mdebug=1
)
%ms_createfile(/sasjs/tests/&fname2..sas
,inref=stpcode2
)
%mp_assertscope(SNAPSHOT)
%ms_triggerstp(/sasjs/tests/&fname1
,debug=131
,outds=work.mySessions
)
%ms_triggerstp(/sasjs/tests/&fname2
,outds=work.mySessions
)
%mp_assertscope(COMPARE
,ignorelist=MCLIB0_JADP1LEN MCLIB0_JADPNUM MCLIB0_JADVLEN)
%mp_assert(iftrue=%str(%mf_existds(work.mySessions)=1)
,desc=Testing output exists
,outds=work.test_results
)
%mp_assertdsobs(work.mySessions,
test=EQUALS 2,
desc=Testing observations,
outds=work.test_results
)
%mp_assertcols(work.mySessions,
cols=sessionid,
test=ALL,
desc=Testing column exists,
outds=work.test_results
)
data _null_;
retain contentCheck 1;
set work.mySessions end=last;
if missing(sessionID) then contentCheck = 0;
if last then do;
call symputx("contentCheck",contentCheck,"l");
end;
run;
%let typeCheck = %mf_getvartype(work.mySessions,sessionid);
%mp_assert(iftrue=%str(&typeCheck = C and &contentCheck = 1)
,desc=Testing type and content of output
,outds=work.test_results
)
%ms_deletefile(/sasjs/tests/&fname1..sas)
%ms_deletefile(/sasjs/tests/&fname2..sas)

View File

@@ -10,7 +10,7 @@
**/
/* location in metadata or SAS Drive for temporary files */
%let mcTestAppLoc=/Public/testresults/sasjs_core/%mf_uid();
%let mcTestAppLoc=/tmp/tests/sasjs/core/%mf_uid();
/* set defaults */
%mp_init()

View File

@@ -1,35 +0,0 @@
/**
@file
@brief Testing mfv_getpathuri macro function
<h4> SAS Macros </h4>
@li mf_uid.sas
@li mfv_getpathuri.sas
@li mp_assert.sas
@li mv_createfile.sas
**/
options mprint sgen;
%let file=%mf_uid();
/* create a folder */
filename somefile temp;
data _null_;
file somefile;
put 'hello testings';
run;
%let path=&mcTestAppLoc/temp;
%mv_createfile(path=&path, name=&file..txt,inref=somefile)
%mp_assert(
iftrue=(%mfv_existfile(&path/&file..txt)=1),
desc=Check if created file exists
)
%mp_assert(
iftrue=(%length(%mfv_getpathuri(&path/&file..txt))>0),
desc=Check that a URI was returned
)

View File

@@ -6,7 +6,6 @@
@li mf_uid.sas
@li mfv_existfile.sas
@li mp_assert.sas
@li mp_assertscope.sas
@li mv_createfile.sas
@@ -22,65 +21,22 @@ data _null_;
file somefile;
put 'hello testings';
run;
%mp_assertscope(SNAPSHOT)
%mv_createfile(path=&mcTestAppLoc/temp, name=&file..txt,inref=somefile,mdebug=1)
%mp_assertscope(COMPARE
,ignorelist=MCLIB0_JADP1LEN MCLIB0_JADP2LEN MCLIB0_JADPNUM
MCLIB0_JADVLEN MCLIB2_JADP1LEN
SASJSPROCESSMODE SASJS_STPSRV_HEADER_LOC
MCLIB2_JADP2LEN MCLIB2_JADPNUM MCLIB2_JADVLEN
)
%mv_createfile(path=&mcTestAppLoc/temp, name=&file..txt,inref=somefile)
%mp_assert(
iftrue=(%mfv_existfile(&mcTestAppLoc/temp/&file..txt)=1),
desc=Check if created file exists
)
%put TEST 2 - html file;
filename f2 temp;
data _null_;
file f2;
put '<html><body><p>Hello world</p></body></html>';
run;
%mv_createfile(path=&mcTestAppLoc/temp, name=test.html,inref=f2,mdebug=1)
%mp_assert(
iftrue=(%mfv_existfile(&mcTestAppLoc/temp/test.html)=1),
desc=Check if created file exists
)
%put TEST 3 - dataset upload ;
%put TEST 2 - dataset upload ;
data temp;
x=1;
run;
filename ds "%sysfunc(pathname(work))/temp.sas7bdat";
%mv_createfile(path=&mcTestAppLoc/temp, name=&file..sas7bdat,inref=ds,mdebug=1)
%mv_createfile(path=&mcTestAppLoc/temp, name=&file..sas7bdat,inref=ds)
%mp_assert(
iftrue=(%mfv_existfile(&mcTestAppLoc/temp/&file..sas7bdat)=1),
desc=Check if created dataset exists
)
%put TEST 4 - create a .sas file;
filename f4 temp;
data _null_;
file f4;
put '%put hello FromSASStudioBailey; ';
run;
%mv_createfile(path=&mcTestAppLoc/temp, name=test4.sas,inref=f4,mdebug=1)
%mp_assert(
iftrue=(%mfv_existfile(&mcTestAppLoc/temp/test4.sas)=1),
desc=Check if created sas program exists
)
%put TEST 5 - reading from files service and writing back;
filename sendfrom filesrvc folderpath="&mcTestAppLoc/temp" filename='test4.sas';
OPTIONS MERROR SYMBOLGEN MLOGIC MPRINT;
%mv_createfile(path=&mcTestAppLoc/temp,name=test5.sas,inref=sendfrom,mdebug=1) ;
)

View File

@@ -29,20 +29,4 @@ run;
%mp_assert(
iftrue=(&test=1),
desc=Check if temp folder can be successfully created
)
/* create a folder without output dataset as part of the original macro */
%mv_createfolder(path=&mcTestAppLoc/temp/&folder/folder2,outds=folders2)
%let test=0;
data _null_;
set work.folders2;
putlog (_all_)(=);
if not missing(self_uri) and not missing(parent_uri)
then call symputx('test2',1);
run;
%mp_assert(
iftrue=(&test2=1),
desc=Check if outds param works
)

View File

@@ -1,41 +0,0 @@
/**
@file
@brief Testing mx_getgroups.test.sas macro
Be sure to run <code>%let mcTestAppLoc=/Public/temp/macrocore;</code> when
running in Studio
<h4> SAS Macros </h4>
@li mf_nobs.sas
@li mf_getuser.sas
@li mp_assert.sas
@li mx_getgroups.sas
**/
%mx_getgroups(outds=work.test1)
%mp_assert(
iftrue=(%mf_nobs(work.test1)>0),
desc=groups were found,
outds=work.test_results
)
%mp_assertcols(work.test1,
cols=groupuri groupname groupdesc,
test=ALL,
desc=check all columns exist
)
%mx_getgroups(outds=work.test2,user=%mf_getuser())
%mp_assert(
iftrue=(%mf_nobs(work.test2)>0),
desc=groups for current user were found,
outds=work.test_results
)
%mp_assertcols(work.test2,
cols=groupuri groupname groupdesc,
test=ALL,
desc=check all columns exist
)

View File

@@ -1,52 +0,0 @@
/**
@file
@brief Returns the uri of a file or folder
@details The automatic variable `_FILESRVC_[fref]_URI` is used after assigning
a fileref using the filesrvc engine.
Usage:
%put %mfv_getpathuri(/Public/folder/file.txt);
%put %mfv_getpathuri(/Public/folder);
@param [in] filepath The full path to the file on SAS drive
(eg /Public/myfile.txt)
<h4> SAS Macros </h4>
@li mf_abort.sas
@li mf_getuniquefileref.sas
<h4> Related Macros </h4>
@li mfv_existfile.sas
@li mfv_existfolder.sas
@version 3.5
@author [Allan Bowe](https://www.linkedin.com/in/allanbowe/)
**/
%macro mfv_getpathuri(filepath
)/*/STORE SOURCE*/;
%mf_abort(
iftrue=(&syscc ne 0),
msg=Cannot enter &sysmacroname with syscc=&syscc
)
%local fref rc path name var /* var is used to avoid delete timing issue */;
%let fref=%mf_getuniquefileref();
%let name=%scan(&filepath,-1,/);
%let path=%substr(&filepath,1,%length(&filepath)-%length(&name)-1);
%if %sysfunc(filename(fref,,filesrvc,folderPath="&path" filename="&name"))=0
%then %do;
%let var=_FILESRVC_&fref._URI;
%str(&&&var)
%let rc=%sysfunc(filename(fref));
%symdel &var;
%end;
%else %do;
%put &sysmacroname: did not find &filepath;
%let syscc=0;
%end;
%mend mfv_getpathuri;

View File

@@ -1,12 +1,8 @@
/**
@file
@brief Creates a file in SAS Drive using the API method
@details Creates a file in SAS Drive using the API interface.
@brief Creates a file in SAS Drive
@details Creates a file in SAS Drive and adds the appropriate content type.
If the parent folder does not exist, it is created.
The API approach is more flexible than using the filesrvc engine of the
filename statement, as it provides more options.
SAS docs: https://developer.sas.com/rest-apis/files/createNewFile
Usage:
@@ -18,57 +14,49 @@
%mv_createfile(path=/Public/temp,name=newfile.txt,inref=myfile)
@param [in] path= The parent (SAS Drive) folder in which to create the file
@param [in] path= The parent folder in which to create the file
@param [in] name= The name of the file to be created
@param [in] inref= The fileref pointing to the file to be uploaded
@param [in] intype= (BINARY) The type of the input data. Valid values:
@li BINARY File is copied byte for byte using the mp_binarycopy.sas macro.
@li BASE64 File will be first decoded using the mp_base64.sas macro, then
loaded byte by byte to SAS Drive.
@param [in] contentdisp= (attchment) Content Disposition. Example values:
@param [in] contentdisp= (inline) Content Disposition. Example values:
@li inline
@li attachment
@param [in] ctype= (0) The actual MIME type of the file (if blank will be
determined based on file extension))
@param [in] ctype= (0) Set a default HTTP Content-Type header to be returned
with the file when the content is retrieved from the Files service.
@param [in] access_token_var= The global macro variable to contain the access
token, if using authorization_code grant type.
@param [in] grant_type= (sas_services) Valid values are:
@li password
@li authorization_code
@li sas_services
@param [in] force= (YES) Will overwrite (delete / recreate) files by default.
Set to NO to abort if a file already exists in that location.
@param [out] outds= (_null_) Output dataset with the uri of the new file
@param [in] mdebug= (0) Set to 1 to enable DEBUG messages
@version VIYA V.03.05
@author Allan Bowe, source: https://github.com/sasjs/core
<h4> SAS Macros </h4>
@li mf_getplatform.sas
@li mf_getuniquefileref.sas
@li mf_getuniquename.sas
@li mf_isblank.sas
@li mf_mimetype.sas
@li mfv_getpathuri.sas
@li mp_abort.sas
@li mp_base64copy.sas
@li mp_binarycopy.sas
@li mv_createfolder.sas
<h4> Related Macros</h4>
@li mv_createfile.sas
**/
%macro mv_createfile(path=
,name=
,inref=
,intype=BINARY
,contentdisp=attachment
,contentdisp=inline
,ctype=0
,access_token_var=ACCESS_TOKEN
,grant_type=sas_services
,mdebug=0
,outds=_null_
,force=YES
);
%local dbg;
%if &mdebug=1 %then %do;
@@ -90,125 +78,51 @@
%mp_abort(iftrue=(&grant_type ne authorization_code and &grant_type ne password
and &grant_type ne sas_services
)
,mac=MV_CREATEFILE
,mac=&sysmacroname
,msg=%str(Invalid value for grant_type: &grant_type)
)
%mp_abort(iftrue=(%mf_isblank(&path)=1 or %length(&path)=1)
,mac=MV_CREATEFILE
,mac=&sysmacroname
,msg=%str(path value must be provided)
)
%mp_abort(iftrue=(%mf_isblank(&name)=1 or %length(&name)=1)
,mac=MV_CREATEFILE
,mac=&sysmacroname
,msg=%str(name value with length >1 must be provided)
)
/* prep the source file */
%local fref;
%let fref=%mf_getuniquefileref();
%if %upcase(&intype)=BINARY %then %let fref=&inref;
%else %if %upcase(&intype)=BASE64 %then %do;
%mp_base64copy(inref=&inref, outref=&fref, action=DECODE)
%end;
%else %put %str(ERR)OR: invalid value for intype: &intype;
%if &mdebug=1 %then %do;
data _null_;
infile &fref lrecl=32767;
input;
put _infile_;
run;
%end;
options noquotelenmax;
%local base_uri; /* location of rest apis */
%let base_uri=%mf_getplatform(VIYARESTAPI);
/* create folder if it does not already exist */
%local folderds self_uri;
%let folderds=%mf_getuniquename(prefix=folderds);
%mv_createfolder(path=&path
,access_token_var=&access_token_var
,grant_type=&grant_type
,mdebug=&mdebug
,outds=&folderds
)
data _null_;
set &folderds;
call symputx('self_uri',self_uri,'l');
run;
/* abort or delete if file already exists */
%let force=%upcase(&force);
%local fileuri ;
%let fileuri=%mfv_getpathuri(&path/&name);
%mp_abort(iftrue=(%mf_isblank(&fileuri)=0 and &force ne YES)
,mac=MV_CREATEFILE
,msg=%str(File &path/&name already exists and force=&force)
)
%if %mf_isblank(&fileuri)=0 and &force=YES %then %do;
proc http method="DELETE" url="&base_uri&fileuri" &oauth_bearer;
headers
%if &grant_type=authorization_code %then %do;
"Authorization"="Bearer &&&access_token_var"
%end;
"Accept"="*/*";
run;
%put &sysmacroname DELETE &base_uri&fileuri
&=SYS_PROCHTTP_STATUS_CODE &=SYS_PROCHTTP_STATUS_PHRASE;
/* create file with relevant options */
%local fref;
%let fref=%mf_getuniquefileref();
filename &fref filesrvc
folderPath="&path"
filename="&name"
cdisp="&contentdisp"
%if "&ctype" ne "0" %then %do;
ctype="&ctype"
%end;
lrecl=1048544;
%if &intype=BINARY %then %do;
%mp_binarycopy(inref=&inref, outref=&fref)
%end;
%else %if &intype=BASE64 %then %do;
%mp_base64copy(inref=&inref, outref=&fref, action=DECODE)
%end;
%local url mimetype ext;
%let url=&base_uri/files/files?parentFolderUri=&self_uri;
%let ext=%upcase(%scan(&name,-1,.));
filename &fref clear;
/* fetch job info */
%local fname1;
%let fname1=%mf_getuniquefileref();
proc http method='POST' out=&fname1 &oauth_bearer in=&fref
%if "&ctype" = "0" %then %do;
%let mimetype=%mf_mimetype(&ext);
ct="&mimetype"
%end;
%else %do;
ct="&ctype"
%end;
%if "&ext"="HTML" or "&ext"="CSS" or "&ext"="JS" or "&ext"="SVG" %then %do;
url="&url%str(&)typeDefName=file";
%end;
%else %do;
url="&url";
%end;
%local base_uri; /* location of rest apis */
%let base_uri=%mf_getplatform(VIYARESTAPI);
headers "Accept"="application/json"
%if &grant_type=authorization_code %then %do;
"Authorization"="Bearer &&&access_token_var"
%end;
"Content-Disposition"= "&contentdisp filename=""&name""; name=""&name"";";
run;
%if &mdebug=1 %then %put &sysmacroname POST &=url
&=SYS_PROCHTTP_STATUS_CODE &=SYS_PROCHTTP_STATUS_PHRASE;
%mp_abort(iftrue=(&SYS_PROCHTTP_STATUS_CODE ne 201)
,mac=MV_CREATEFILE
,msg=%str(&SYS_PROCHTTP_STATUS_CODE &SYS_PROCHTTP_STATUS_PHRASE)
)
%local libref2;
%let libref2=%mf_getuniquelibref();
libname &libref2 JSON fileref=&fname1;
%put Grabbing the follow on link ;
data &outds;
set &libref2..links end=last;
if rel='createChild' then do;
call symputx('href',quote(cats("&base_uri",href)),'l');
&dbg put (_all_)(=);
end;
run;
%put &sysmacroname: File &name successfully created:;%put;
%put &base_uri%mfv_getpathuri(&path/&name);%put;
%put &sysmacroname: File &name successfully created in &path;
%put &sysmacroname:;%put;
%put &base_uri/SASJobExecution?_file=&path/&name;%put;
%put &sysmacroname:;

View File

@@ -17,16 +17,15 @@
@li sas_services
@param [in] mdebug=(0) set to 1 to enable DEBUG messages
@param [out] outds=(_null_) Optionally create an output dataset which will
contain the uri (self_uri) of the created (and parent) folder.
@version VIYA V.03.04
@author Allan Bowe, source: https://github.com/sasjs/core
<h4> SAS Macros </h4>
@li mp_abort.sas
@li mf_getuniquefileref.sas
@li mf_getuniquelibref.sas
@li mf_isblank.sas
@li mfv_getpathuri.sas
@li mf_getplatform.sas
@li mfv_existfolder.sas
@@ -37,7 +36,6 @@
,access_token_var=ACCESS_TOKEN
,grant_type=sas_services
,mdebug=0
,outds=_null_
);
%local dbg;
%if &mdebug=1 %then %do;
@@ -48,11 +46,6 @@
%if %mfv_existfolder(&path)=1 %then %do;
%put &sysmacroname: &path already exists;
data &outds;
self_uri="%mfv_getpathuri(&path)";
output;
stop;
run;
%return;
%end;
@@ -87,12 +80,12 @@ options noquotelenmax;
%local subfolder_cnt; /* determine the number of subfolders */
%let subfolder_cnt=%sysfunc(countw(&path,/));
%local href; /* resource address (none for root) */
%let href="/folders/folders?parentFolderUri=/folders/folders/none";
%local base_uri; /* location of rest apis */
%let base_uri=%mf_getplatform(VIYARESTAPI);
%local href; /* resource address (none for root) */
%let href="&base_uri/folders/folders?parentFolderUri=/folders/folders/none";
%local x newpath subfolder;
%do x=1 %to &subfolder_cnt;
%let subfolder=%scan(&path,&x,%str(/));
@@ -122,7 +115,7 @@ options noquotelenmax;
%put &sysmacroname following check to see if &newpath exists:;
%put _local_;
data _null_;
infile &fname1;
set &fname1;
input;
putlog _infile_;
run;
@@ -164,9 +157,8 @@ options noquotelenmax;
'Content-Type'='application/vnd.sas.content.folder+json'
'Accept'='application/vnd.sas.content.folder+json';
run;
%if &SYS_PROCHTTP_STATUS_CODE ne 200 %then %do;
%put &=SYS_PROCHTTP_STATUS_CODE &=SYS_PROCHTTP_STATUS_PHRASE;
%end;
%put &=SYS_PROCHTTP_STATUS_CODE;
%put &=SYS_PROCHTTP_STATUS_PHRASE;
%mp_abort(iftrue=(&SYS_PROCHTTP_STATUS_CODE ne 201)
,mac=&sysmacroname
,msg=%str(&SYS_PROCHTTP_STATUS_CODE &SYS_PROCHTTP_STATUS_PHRASE)
@@ -175,17 +167,12 @@ options noquotelenmax;
%let libref2=%mf_getuniquelibref();
libname &libref2 JSON fileref=&fname2;
%put &sysmacroname &newpath now created. Grabbing the follow on link ;
data &outds;
data _null_;
set &libref2..links;
if rel='createChild' then do;
call symputx('href',quote(cats("&base_uri",href)),'l');
&dbg put (_all_)(=);
end;
if method='GET' and rel='self' then do;
self_uri=uri;
output;
end;
keep self_uri ;
run;
libname &libref2 clear;

View File

@@ -955,7 +955,12 @@ run;
libname &libref1 clear;
%end;
%put NOTE: &sysmacroname: Job &name successfully created! Check it out:;
%put NOTE-;%put NOTE- &url/SASJobExecution?_PROGRAM=&path/&name;%put NOTE-;
%put &sysmacroname: Job &name successfully created in &path;
%put &sysmacroname:;
%put &sysmacroname: Check it out here:;
%put &sysmacroname:;%put;
%put &url/SASJobExecution?_PROGRAM=&path/&name;%put;
%put &sysmacroname:;
%put &sysmacroname:;
%mend mv_createwebservice;

View File

@@ -111,15 +111,13 @@ proc http method='GET' out=&fname1a &oauth_bearer
headers "Authorization"="Bearer &&&access_token_var";
%end;
run;
%if &SYS_PROCHTTP_STATUS_CODE ne 200 %then %do;
%put &=sysmacroname &=SYS_PROCHTTP_STATUS_CODE &=SYS_PROCHTTP_STATUS_PHRASE;
%end;
%put &=SYS_PROCHTTP_STATUS_CODE;
%local libref1a;
%let libref1a=%mf_getuniquelibref();
libname &libref1a JSON fileref=&fname1a;
%local uri found;
%let found=0;
/* %put Getting object uri from &libref1a..items; */
%put Getting object uri from &libref1a..items;
data _null_;
length contenttype name $1000;
set &libref1a..items;

View File

@@ -90,7 +90,7 @@ run;
)
%end;
/* grab the follow on link */
%put &sysmacroname: grab the follow on link ;
%local libref1;
%let libref1=%mf_getuniquelibref();
libname &libref1 JSON fileref=&fname1;
@@ -114,7 +114,7 @@ run;
libname &libref1a JSON fileref=&fname1a;
%local uri found;
%let found=0;
/* %put Getting object uri from &libref1a..items; */
%put Getting object uri from &libref1a..items;
data _null_;
length contenttype name $1000;
set &libref1a..items;

View File

@@ -1,6 +1,6 @@
/**
@file
@brief Deletes a viya folder
@file mv_deleteviyafolder.sas
@brief Creates a viya folder if that folder does not already exist
@details If not running in Studo 5 +, will expect an oauth token in a global
macro variable (default ACCESS_TOKEN).

View File

@@ -1,98 +0,0 @@
/**
@file
@brief Fetches all groups or the groups for a particular member
@details When building applications that run on multiple flavours of SAS, it
is convenient to use a single macro (like this one) to fetch the groups
regardless of the flavour of SAS being used
The alternative would be to compile a generic macro in target-specific
folders (SASVIYA, SAS9 and SASJS). This avoids compiling unnecessary macros
at the expense of a more complex sasjsconfig.json setup.
@param [in] mdebug= (0) Set to 1 to enable DEBUG messages
@param [in] user= (0) Provide the username on which to filter
@param [in] uid= (0) Provide the userid on which to filter
@param [in] repo= (foundation) SAS9 only, choose the metadata repo to query
@param [in] access_token_var= (ACCESS_TOKEN) VIYA only.
The global macro variable to contain the access token
@param [in] grant_type= (sas_services) VIYA only.
Valid values are "password" or "authorization_code" (unquoted).
@param [out] outds= (work.mx_getgroups) This output dataset will contain the
list of groups. Format:
|GROUPNAME:$32.|GROUPDESC:$256.|GROUPURI:best.|
|---|---|---|
|`SomeGroup `|`A group `|`1`|
|`Another Group`|`this is a different group`|`2`|
|`admin`|`Administrators `|`3`|
<h4> SAS Macros </h4>
@li mf_getplatform.sas
@li mm_getgroups.sas
@li ms_getgroups.sas
@li mv_getgroups.sas
@li mv_getusergroups.sas
**/
%macro mx_getgroups(
mdebug=0,
user=0,
uid=0,
repo=foundation,
access_token_var=ACCESS_TOKEN,
grant_type=sas_services,
outds=work.mx_getgroups
)/*/STORE SOURCE*/;
%local platform name shortloc;
%let platform=%mf_getplatform();
%if &platform=SASJS %then %do;
%ms_getgroups(
user=&user,
uid=&uid,
outds=&outds,
mdebug=&mdebug
)
data &outds;
length groupuri groupname $32 groupdesc $128 ;
set &outds;
keep groupuri groupname groupdesc;
groupuri=cats(groupid);
groupname=name;
groupdesc=description;
run;
proc sort; by groupname; run;
%end;
%else %if &platform=SAS9 or &platform=SASMETA %then %do;
%if &user=0 %then %let user=;
%mm_getGroups(
user=&user
,outds=&outds
,repo=&repo
,mDebug=&mdebug
)
proc sort data=&outds; by groupname; run;
%end;
%else %if &platform=SASVIYA %then %do;
%if &user=0 %then %do;
%mv_getgroups(access_token_var=&access_token_var
,grant_type=&grant_type
,outds=&outds
)
%end;
%else %do;
%mv_getusergroups(&user
,outds=&outds
,access_token_var=&access_token_var
,grant_type=&grant_type
)
%end;
proc sort
data=&outds(rename=(id=groupuri name=groupname description=groupdesc))
out=&outds (keep=groupuri groupname groupdesc);
by groupname;
run;
%end;
%mend mx_getgroups;