@sasjs/utils 2.48.2 → 2.49.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/fs/generateCompileProgram.d.ts +1 -0
- package/fs/generateCompileProgram.js +154 -0
- package/fs/generateCompileProgram.js.map +1 -0
- package/fs/hash.d.ts +22 -0
- package/fs/hash.js +225 -0
- package/fs/hash.js.map +1 -0
- package/fs/index.d.ts +3 -0
- package/fs/index.js +13 -0
- package/fs/index.js.map +1 -0
- package/fs/internal/helper.d.ts +4 -0
- package/fs/internal/helper.js +125 -0
- package/fs/internal/helper.js.map +1 -0
- package/fs/sync.d.ts +6 -0
- package/fs/sync.js +208 -0
- package/fs/sync.js.map +1 -0
- package/index.d.ts +1 -0
- package/index.js +1 -0
- package/index.js.map +1 -1
- package/macros/mf_abort.sas +27 -0
- package/macros/mf_dedup.sas +53 -0
- package/macros/mf_deletefile.sas +31 -0
- package/macros/mf_existds.sas +30 -0
- package/macros/mf_existfeature.sas +59 -0
- package/macros/mf_existfileref.sas +33 -0
- package/macros/mf_existfunction.sas +37 -0
- package/macros/mf_existvar.sas +39 -0
- package/macros/mf_existvarlist.sas +56 -0
- package/macros/mf_fmtdttm.sas +42 -0
- package/macros/mf_getapploc.sas +78 -0
- package/macros/mf_getattrc.sas +34 -0
- package/macros/mf_getattrn.sas +34 -0
- package/macros/mf_getengine.sas +54 -0
- package/macros/mf_getfilesize.sas +64 -0
- package/macros/mf_getfmtlist.sas +61 -0
- package/macros/mf_getfmtname.sas +44 -0
- package/macros/mf_getkeyvalue.sas +32 -0
- package/macros/mf_getplatform.sas +75 -0
- package/macros/mf_getquotedstr.sas +57 -0
- package/macros/mf_getschema.sas +43 -0
- package/macros/mf_getuniquefileref.sas +60 -0
- package/macros/mf_getuniquelibref.sas +57 -0
- package/macros/mf_getuniquename.sas +22 -0
- package/macros/mf_getuser.sas +44 -0
- package/macros/mf_getvalue.sas +36 -0
- package/macros/mf_getvarcount.sas +49 -0
- package/macros/mf_getvarformat.sas +72 -0
- package/macros/mf_getvarlen.sas +56 -0
- package/macros/mf_getvarlist.sas +74 -0
- package/macros/mf_getvarnum.sas +58 -0
- package/macros/mf_getvartype.sas +52 -0
- package/macros/mf_getxengine.sas +43 -0
- package/macros/mf_increment.sas +29 -0
- package/macros/mf_isblank.sas +27 -0
- package/macros/mf_isdir.sas +34 -0
- package/macros/mf_isint.sas +36 -0
- package/macros/mf_islibds.sas +40 -0
- package/macros/mf_loc.sas +29 -0
- package/macros/mf_mkdir.sas +67 -0
- package/macros/mf_mval.sas +19 -0
- package/macros/mf_nobs.sas +26 -0
- package/macros/mf_trimstr.sas +50 -0
- package/macros/mf_uid.sas +21 -0
- package/macros/mf_verifymacvars.sas +72 -0
- package/macros/mf_wordsinstr1andstr2.sas +53 -0
- package/macros/mf_wordsinstr1butnotstr2.sas +54 -0
- package/macros/mf_writefile.sas +67 -0
- package/macros/mp_abort.sas +301 -0
- package/macros/mp_appendfile.sas +57 -0
- package/macros/mp_applyformats.sas +181 -0
- package/macros/mp_assert.sas +56 -0
- package/macros/mp_assertcols.sas +145 -0
- package/macros/mp_assertcolvals.sas +168 -0
- package/macros/mp_assertdsobs.sas +121 -0
- package/macros/mp_assertscope.sas +147 -0
- package/macros/mp_base64copy.sas +117 -0
- package/macros/mp_binarycopy.sas +79 -0
- package/macros/mp_chop.sas +194 -0
- package/macros/mp_cleancsv.sas +78 -0
- package/macros/mp_cntlout.sas +85 -0
- package/macros/mp_copyfolder.sas +84 -0
- package/macros/mp_coretable.sas +73 -0
- package/macros/mp_createconstraints.sas +70 -0
- package/macros/mp_createwebservice.sas +32 -0
- package/macros/mp_csv2ds.sas +140 -0
- package/macros/mp_deleteconstraints.sas +52 -0
- package/macros/mp_deletefolder.sas +70 -0
- package/macros/mp_dictionary.sas +52 -0
- package/macros/mp_dirlist.sas +263 -0
- package/macros/mp_distinctfmtvalues.sas +50 -0
- package/macros/mp_dropmembers.sas +46 -0
- package/macros/mp_ds2cards.sas +291 -0
- package/macros/mp_ds2csv.sas +212 -0
- package/macros/mp_ds2ddl.sas +30 -0
- package/macros/mp_ds2fmtds.sas +105 -0
- package/macros/mp_ds2inserts.sas +180 -0
- package/macros/mp_ds2md.sas +103 -0
- package/macros/mp_ds2squeeze.sas +120 -0
- package/macros/mp_dsmeta.sas +110 -0
- package/macros/mp_filtercheck.sas +251 -0
- package/macros/mp_filtergenerate.sas +105 -0
- package/macros/mp_filterstore.sas +254 -0
- package/macros/mp_filtervalidate.sas +105 -0
- package/macros/mp_getcols.sas +67 -0
- package/macros/mp_getconstraints.sas +115 -0
- package/macros/mp_getdbml.sas +335 -0
- package/macros/mp_getddl.sas +400 -0
- package/macros/mp_getformats.sas +124 -0
- package/macros/mp_getmaxvarlengths.sas +130 -0
- package/macros/mp_getpk.sas +281 -0
- package/macros/mp_gsubfile.sas +58 -0
- package/macros/mp_guesspk.sas +332 -0
- package/macros/mp_hashdataset.sas +91 -0
- package/macros/mp_hashdirectory.sas +162 -0
- package/macros/mp_include.sas +106 -0
- package/macros/mp_init.sas +76 -0
- package/macros/mp_jsonout.sas +406 -0
- package/macros/mp_lib2cards.sas +78 -0
- package/macros/mp_lib2inserts.sas +77 -0
- package/macros/mp_loadformat.sas +303 -0
- package/macros/mp_lockanytable.sas +243 -0
- package/macros/mp_lockfilecheck.sas +103 -0
- package/macros/mp_makedata.sas +107 -0
- package/macros/mp_md5.sas +58 -0
- package/macros/mp_perflog.sas +43 -0
- package/macros/mp_prevobs.sas +88 -0
- package/macros/mp_recursivejoin.sas +90 -0
- package/macros/mp_replace.sas +151 -0
- package/macros/mp_reseterror.sas +27 -0
- package/macros/mp_resetoption.sas +39 -0
- package/macros/mp_retainedkey.sas +247 -0
- package/macros/mp_runddl.sas +49 -0
- package/macros/mp_searchcols.sas +103 -0
- package/macros/mp_searchdata.sas +131 -0
- package/macros/mp_setkeyvalue.sas +55 -0
- package/macros/mp_sortinplace.sas +122 -0
- package/macros/mp_stackdiffs.sas +592 -0
- package/macros/mp_storediffs.sas +230 -0
- package/macros/mp_stprequests.sas +74 -0
- package/macros/mp_streamfile.sas +212 -0
- package/macros/mp_testjob.sas +92 -0
- package/macros/mp_testservice.sas +39 -0
- package/macros/mp_testwritespeedlibrary.sas +59 -0
- package/macros/mp_tree.sas +71 -0
- package/macros/mp_unzip.sas +90 -0
- package/macros/mp_updatevarlength.sas +93 -0
- package/macros/mp_validatecol.sas +97 -0
- package/macros/mp_wait4file.sas +35 -0
- package/macros/mp_webin.sas +59 -0
- package/macros/mp_zip.sas +85 -0
- package/package.json +5 -2
- package/scripts/copySASjsCore.ts +36 -0
- package/types/hash.d.ts +9 -0
- package/types/hash.js +3 -0
- package/types/hash.js.map +1 -0
- package/types/index.d.ts +1 -0
- package/types/index.js +1 -0
- package/types/index.js.map +1 -1
- package/utils/index.d.ts +1 -1
- package/utils/index.js +2 -1
- package/utils/index.js.map +1 -1
- package/utils/utils.d.ts +1 -0
- package/utils/utils.js +7 -1
- package/utils/utils.js.map +1 -1
package/fs/sync.js
ADDED
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
12
|
+
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
|
|
13
|
+
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
|
14
|
+
function verb(n) { return function (v) { return step([n, v]); }; }
|
|
15
|
+
function step(op) {
|
|
16
|
+
if (f) throw new TypeError("Generator is already executing.");
|
|
17
|
+
while (_) try {
|
|
18
|
+
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
|
19
|
+
if (y = 0, t) op = [op[0] & 2, t.value];
|
|
20
|
+
switch (op[0]) {
|
|
21
|
+
case 0: case 1: t = op; break;
|
|
22
|
+
case 4: _.label++; return { value: op[1], done: false };
|
|
23
|
+
case 5: _.label++; y = op[1]; op = [0]; continue;
|
|
24
|
+
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
|
25
|
+
default:
|
|
26
|
+
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
|
27
|
+
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
|
28
|
+
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
|
29
|
+
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
|
30
|
+
if (t[2]) _.ops.pop();
|
|
31
|
+
_.trys.pop(); continue;
|
|
32
|
+
}
|
|
33
|
+
op = body.call(thisArg, _);
|
|
34
|
+
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
|
35
|
+
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
|
36
|
+
}
|
|
37
|
+
};
|
|
38
|
+
var __values = (this && this.__values) || function(o) {
|
|
39
|
+
var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0;
|
|
40
|
+
if (m) return m.call(o);
|
|
41
|
+
if (o && typeof o.length === "number") return {
|
|
42
|
+
next: function () {
|
|
43
|
+
if (o && i >= o.length) o = void 0;
|
|
44
|
+
return { value: o && o[i++], done: !o };
|
|
45
|
+
}
|
|
46
|
+
};
|
|
47
|
+
throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined.");
|
|
48
|
+
};
|
|
49
|
+
var __read = (this && this.__read) || function (o, n) {
|
|
50
|
+
var m = typeof Symbol === "function" && o[Symbol.iterator];
|
|
51
|
+
if (!m) return o;
|
|
52
|
+
var i = m.call(o), r, ar = [], e;
|
|
53
|
+
try {
|
|
54
|
+
while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
|
|
55
|
+
}
|
|
56
|
+
catch (error) { e = { error: error }; }
|
|
57
|
+
finally {
|
|
58
|
+
try {
|
|
59
|
+
if (r && !r.done && (m = i["return"])) m.call(i);
|
|
60
|
+
}
|
|
61
|
+
finally { if (e) throw e.error; }
|
|
62
|
+
}
|
|
63
|
+
return ar;
|
|
64
|
+
};
|
|
65
|
+
var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
|
|
66
|
+
if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
|
|
67
|
+
if (ar || !(i in from)) {
|
|
68
|
+
if (!ar) ar = Array.prototype.slice.call(from, 0, i);
|
|
69
|
+
ar[i] = from[i];
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
return to.concat(ar || Array.prototype.slice.call(from));
|
|
73
|
+
};
|
|
74
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
75
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
76
|
+
};
|
|
77
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
78
|
+
exports.findResourcesNotPresentLocally = exports.generateProgramToSyncHashDiff = exports.generateProgramToGetRemoteHash = void 0;
|
|
79
|
+
var path_1 = __importDefault(require("path"));
|
|
80
|
+
var helper_1 = require("./internal/helper");
|
|
81
|
+
var generateProgramToGetRemoteHash = function (remotePath) { return __awaiter(void 0, void 0, void 0, function () {
|
|
82
|
+
var compiledMacrosCode, codeForHashCreation, code;
|
|
83
|
+
return __generator(this, function (_a) {
|
|
84
|
+
switch (_a.label) {
|
|
85
|
+
case 0: return [4 /*yield*/, (0, helper_1.getCompiledMacrosCode)([
|
|
86
|
+
'mp_hashdirectory.sas',
|
|
87
|
+
'mp_jsonout.sas'
|
|
88
|
+
])];
|
|
89
|
+
case 1:
|
|
90
|
+
compiledMacrosCode = _a.sent();
|
|
91
|
+
codeForHashCreation = getCodeForHashCreation();
|
|
92
|
+
code = compiledMacrosCode + codeForHashCreation;
|
|
93
|
+
return [2 /*return*/, setTargetAtStart(code, remotePath)];
|
|
94
|
+
}
|
|
95
|
+
});
|
|
96
|
+
}); };
|
|
97
|
+
exports.generateProgramToGetRemoteHash = generateProgramToGetRemoteHash;
|
|
98
|
+
var generateProgramToSyncHashDiff = function (hashedFolder, remotePath) { return __awaiter(void 0, void 0, void 0, function () {
|
|
99
|
+
var compiledMacrosCode, initialProgramContent, pathRelativeTo, folderCreationCode, codeForHashCreation, code;
|
|
100
|
+
return __generator(this, function (_a) {
|
|
101
|
+
switch (_a.label) {
|
|
102
|
+
case 0: return [4 /*yield*/, (0, helper_1.getCompiledMacrosCode)([
|
|
103
|
+
'mp_hashdirectory.sas',
|
|
104
|
+
'mp_jsonout.sas',
|
|
105
|
+
'mf_mkdir.sas'
|
|
106
|
+
])];
|
|
107
|
+
case 1:
|
|
108
|
+
compiledMacrosCode = _a.sent();
|
|
109
|
+
initialProgramContent = (0, helper_1.getInitialCode)();
|
|
110
|
+
pathRelativeTo = hashedFolder.absolutePath.endsWith(path_1.default.sep)
|
|
111
|
+
? hashedFolder.absolutePath.slice(0, -1)
|
|
112
|
+
: hashedFolder.absolutePath;
|
|
113
|
+
return [4 /*yield*/, generateCodeForFolderCreation(hashedFolder, pathRelativeTo)];
|
|
114
|
+
case 2:
|
|
115
|
+
folderCreationCode = _a.sent();
|
|
116
|
+
codeForHashCreation = getCodeForHashCreation();
|
|
117
|
+
code = compiledMacrosCode +
|
|
118
|
+
initialProgramContent +
|
|
119
|
+
folderCreationCode +
|
|
120
|
+
codeForHashCreation;
|
|
121
|
+
return [2 /*return*/, setTargetAtStart(code, remotePath)];
|
|
122
|
+
}
|
|
123
|
+
});
|
|
124
|
+
}); };
|
|
125
|
+
exports.generateProgramToSyncHashDiff = generateProgramToSyncHashDiff;
|
|
126
|
+
var findResourcesNotPresentLocally = function (localHash, remoteHashMap) {
|
|
127
|
+
var localHashedArray = convertHashFolderTreeToArray(localHash);
|
|
128
|
+
var remoteHashedArray = Object.keys(remoteHashMap);
|
|
129
|
+
return remoteHashedArray.filter(function (item) { return !localHashedArray.includes(item); });
|
|
130
|
+
};
|
|
131
|
+
exports.findResourcesNotPresentLocally = findResourcesNotPresentLocally;
|
|
132
|
+
var generateCodeForFolderCreation = function (hashedFolder, pathRelativeTo, resultCode) {
|
|
133
|
+
if (resultCode === void 0) { resultCode = ''; }
|
|
134
|
+
return __awaiter(void 0, void 0, void 0, function () {
|
|
135
|
+
var _a, _b, member, _c, e_1_1;
|
|
136
|
+
var e_1, _d;
|
|
137
|
+
return __generator(this, function (_e) {
|
|
138
|
+
switch (_e.label) {
|
|
139
|
+
case 0:
|
|
140
|
+
_e.trys.push([0, 7, 8, 9]);
|
|
141
|
+
_a = __values(hashedFolder.members), _b = _a.next();
|
|
142
|
+
_e.label = 1;
|
|
143
|
+
case 1:
|
|
144
|
+
if (!!_b.done) return [3 /*break*/, 6];
|
|
145
|
+
member = _b.value;
|
|
146
|
+
if (!member.isFile) return [3 /*break*/, 3];
|
|
147
|
+
_c = resultCode;
|
|
148
|
+
return [4 /*yield*/, (0, helper_1.generateCodeForFileCreation)(member.absolutePath, pathRelativeTo)];
|
|
149
|
+
case 2:
|
|
150
|
+
resultCode = _c + _e.sent();
|
|
151
|
+
return [3 /*break*/, 5];
|
|
152
|
+
case 3:
|
|
153
|
+
resultCode += "%mf_mkdir(&fsTarget".concat(member.absolutePath.replace(pathRelativeTo, ''), ")\n");
|
|
154
|
+
return [4 /*yield*/, generateCodeForFolderCreation(member, pathRelativeTo, resultCode)];
|
|
155
|
+
case 4:
|
|
156
|
+
resultCode = _e.sent();
|
|
157
|
+
_e.label = 5;
|
|
158
|
+
case 5:
|
|
159
|
+
_b = _a.next();
|
|
160
|
+
return [3 /*break*/, 1];
|
|
161
|
+
case 6: return [3 /*break*/, 9];
|
|
162
|
+
case 7:
|
|
163
|
+
e_1_1 = _e.sent();
|
|
164
|
+
e_1 = { error: e_1_1 };
|
|
165
|
+
return [3 /*break*/, 9];
|
|
166
|
+
case 8:
|
|
167
|
+
try {
|
|
168
|
+
if (_b && !_b.done && (_d = _a.return)) _d.call(_a);
|
|
169
|
+
}
|
|
170
|
+
finally { if (e_1) throw e_1.error; }
|
|
171
|
+
return [7 /*endfinally*/];
|
|
172
|
+
case 9: return [2 /*return*/, resultCode];
|
|
173
|
+
}
|
|
174
|
+
});
|
|
175
|
+
});
|
|
176
|
+
};
|
|
177
|
+
var getCodeForHashCreation = function () {
|
|
178
|
+
return "/* Get Hashes */\n%mp_hashdirectory(&fsTarget,maxDepth=MAX,outds=work.hashes)\n\n/* Prepare Response JSON */\nfilename tmp temp;\n%mp_jsonout(OPEN,jref=tmp)\n%mp_jsonout(OBJ,hashes,fmt=N,jref=tmp)\n%mp_jsonout(CLOSE,jref=tmp)\n\n/* Print to Log */\ndata _null_;\n retain eof;\n infile tmp end=eof lrecl=10000;\n if _n_=1 then putlog '>>weboutBEGIN<<';\n input;\n putlog _infile_;\n if eof then putlog '>>weboutEND<<';\nrun;\n";
|
|
179
|
+
};
|
|
180
|
+
var setTargetAtStart = function (code, target) {
|
|
181
|
+
return "%let fsTarget=".concat(target, ";\n").concat(code);
|
|
182
|
+
};
|
|
183
|
+
/**
|
|
184
|
+
* convert hash folder tree to an array of relative paths,
|
|
185
|
+
* the returned array will be used to check the resources that are present on remote but not local
|
|
186
|
+
*/
|
|
187
|
+
var convertHashFolderTreeToArray = function (hashedFolder, array) {
|
|
188
|
+
var e_2, _a;
|
|
189
|
+
if (array === void 0) { array = []; }
|
|
190
|
+
if (hashedFolder.isFile)
|
|
191
|
+
return __spreadArray(__spreadArray([], __read(array), false), [hashedFolder.relativePath], false);
|
|
192
|
+
try {
|
|
193
|
+
for (var _b = __values(hashedFolder.members), _c = _b.next(); !_c.done; _c = _b.next()) {
|
|
194
|
+
var member = _c.value;
|
|
195
|
+
array = convertHashFolderTreeToArray(member, array);
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
catch (e_2_1) { e_2 = { error: e_2_1 }; }
|
|
199
|
+
finally {
|
|
200
|
+
try {
|
|
201
|
+
if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
|
|
202
|
+
}
|
|
203
|
+
finally { if (e_2) throw e_2.error; }
|
|
204
|
+
}
|
|
205
|
+
array.push(hashedFolder.relativePath);
|
|
206
|
+
return array;
|
|
207
|
+
};
|
|
208
|
+
//# sourceMappingURL=sync.js.map
|
package/fs/sync.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sync.js","sourceRoot":"","sources":["../../src/fs/sync.ts"],"names":[],"mappings":"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"}
|
package/index.d.ts
CHANGED
package/index.js
CHANGED
package/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,yCAAsB;AACtB,yCAAsB;AACtB,8CAA2B;AAC3B,0CAAuB;AACvB,2CAAwB;AACxB,6CAA0B;AAC1B,yCAAsB;AACtB,0CAAuB;AACvB,0CAAuB;AACvB,gDAA6B"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,yCAAsB;AACtB,yCAAsB;AACtB,8CAA2B;AAC3B,0CAAuB;AACvB,2CAAwB;AACxB,6CAA0B;AAC1B,yCAAsB;AACtB,0CAAuB;AACvB,0CAAuB;AACvB,gDAA6B;AAC7B,uCAAoB"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
@file
|
|
3
|
+
@brief Abort, ungracefully
|
|
4
|
+
@details Will abort with a straightforward %abort if the condition is true.
|
|
5
|
+
|
|
6
|
+
<h4> Related Macros </h4>
|
|
7
|
+
@li mp_abort.sas
|
|
8
|
+
|
|
9
|
+
@version 9.2
|
|
10
|
+
@author Allan Bowe
|
|
11
|
+
@cond
|
|
12
|
+
**/
|
|
13
|
+
|
|
14
|
+
%macro mf_abort(mac=mf_abort.sas, msg=, iftrue=%str(1=1)
|
|
15
|
+
)/*/STORE SOURCE*/;
|
|
16
|
+
|
|
17
|
+
%if not(%eval(%unquote(&iftrue))) %then %return;
|
|
18
|
+
|
|
19
|
+
%put NOTE: /// mf_abort macro executing //;
|
|
20
|
+
%if %length(&mac)>0 %then %put NOTE- called by &mac;
|
|
21
|
+
%put NOTE - &msg;
|
|
22
|
+
|
|
23
|
+
%abort;
|
|
24
|
+
|
|
25
|
+
%mend mf_abort;
|
|
26
|
+
|
|
27
|
+
/** @endcond */
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
@file
|
|
3
|
+
@brief de-duplicates a macro string
|
|
4
|
+
@details Removes all duplicates from a string of words. A delimeter can be
|
|
5
|
+
chosen. Is inspired heavily by this excellent [macro](
|
|
6
|
+
https://github.com/scottbass/SAS/blob/master/Macro/dedup_mstring.sas) from
|
|
7
|
+
[Scott Base](https://www.linkedin.com/in/scottbass). Case sensitive.
|
|
8
|
+
|
|
9
|
+
Usage:
|
|
10
|
+
|
|
11
|
+
%let str=One two one two and through and through;
|
|
12
|
+
%put %mf_dedup(&str);
|
|
13
|
+
%put %mf_dedup(&str,outdlm=%str(,));
|
|
14
|
+
|
|
15
|
+
Which returns:
|
|
16
|
+
|
|
17
|
+
> One two one and through
|
|
18
|
+
> One,two,one,and,through
|
|
19
|
+
|
|
20
|
+
@param [in] str String to be deduplicated
|
|
21
|
+
@param [in] indlm= ( ) Delimeter of the input string
|
|
22
|
+
@param [out] outdlm= ( ) Delimiter of the output string
|
|
23
|
+
|
|
24
|
+
<h4> Related Macros </h4>
|
|
25
|
+
@li mf_trimstr.sas
|
|
26
|
+
|
|
27
|
+
@version 9.2
|
|
28
|
+
@author Allan Bowe
|
|
29
|
+
**/
|
|
30
|
+
|
|
31
|
+
%macro mf_dedup(str
|
|
32
|
+
,indlm=%str( )
|
|
33
|
+
,outdlm=%str( )
|
|
34
|
+
)/*/STORE SOURCE*/;
|
|
35
|
+
|
|
36
|
+
%local num word i pos out;
|
|
37
|
+
|
|
38
|
+
%* loop over each token, searching the target for that token ;
|
|
39
|
+
%let num=%sysfunc(countc(%superq(str),%str(&indlm)));
|
|
40
|
+
%do i=1 %to %eval(&num+1);
|
|
41
|
+
%let word=%scan(%superq(str),&i,%str(&indlm));
|
|
42
|
+
%let pos=%sysfunc(indexw(&out,&word,%str(&outdlm)));
|
|
43
|
+
%if (&pos eq 0) %then %do;
|
|
44
|
+
%if (&i gt 1) %then %let out=&out%str(&outdlm);
|
|
45
|
+
%let out=&out&word;
|
|
46
|
+
%end;
|
|
47
|
+
%end;
|
|
48
|
+
|
|
49
|
+
%unquote(&out)
|
|
50
|
+
|
|
51
|
+
%mend mf_dedup;
|
|
52
|
+
|
|
53
|
+
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
@file
|
|
3
|
+
@brief Deletes a physical file, if it exists
|
|
4
|
+
@details Usage:
|
|
5
|
+
|
|
6
|
+
%mf_writefile(&sasjswork/myfile.txt,l1=some content)
|
|
7
|
+
|
|
8
|
+
%mf_deletefile(&sasjswork/myfile.txt)
|
|
9
|
+
|
|
10
|
+
%mf_deletefile(&sasjswork/myfile.txt)
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
@param filepath Full path to the target file
|
|
14
|
+
|
|
15
|
+
@returns The return code from the fdelete() invocation
|
|
16
|
+
|
|
17
|
+
<h4> Related Macros </h4>
|
|
18
|
+
@li mf_deletefile.test.sas
|
|
19
|
+
@li mf_writefile.sas
|
|
20
|
+
|
|
21
|
+
@version 9.2
|
|
22
|
+
@author Allan Bowe
|
|
23
|
+
**/
|
|
24
|
+
|
|
25
|
+
%macro mf_deletefile(file
|
|
26
|
+
)/*/STORE SOURCE*/;
|
|
27
|
+
%local rc fref;
|
|
28
|
+
%let rc= %sysfunc(filename(fref,&file));
|
|
29
|
+
%if %sysfunc(fdelete(&fref)) ne 0 %then %put %sysfunc(sysmsg());
|
|
30
|
+
%let rc= %sysfunc(filename(fref));
|
|
31
|
+
%mend mf_deletefile;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
@file mf_existds.sas
|
|
3
|
+
@brief Checks whether a dataset OR a view exists.
|
|
4
|
+
@details Can be used in open code, eg as follows:
|
|
5
|
+
|
|
6
|
+
%if %mf_existds(libds=work.someview) %then %put yes it does!;
|
|
7
|
+
|
|
8
|
+
NOTE - some databases have case sensitive tables, for instance POSTGRES
|
|
9
|
+
with the preserve_tab_names=yes libname setting. This may impact
|
|
10
|
+
expected results (depending on whether you 'expect' the result to be
|
|
11
|
+
case insensitive in this context!)
|
|
12
|
+
|
|
13
|
+
@param libds library.dataset
|
|
14
|
+
@return output returns 1 or 0
|
|
15
|
+
|
|
16
|
+
<h4> Related Macros </h4>
|
|
17
|
+
@li mf_existds.test.sas
|
|
18
|
+
|
|
19
|
+
@warning Untested on tables registered in metadata but not physically present
|
|
20
|
+
@version 9.2
|
|
21
|
+
@author Allan Bowe
|
|
22
|
+
**/
|
|
23
|
+
|
|
24
|
+
%macro mf_existds(libds
|
|
25
|
+
)/*/STORE SOURCE*/;
|
|
26
|
+
|
|
27
|
+
%if %sysfunc(exist(&libds)) ne 1 & %sysfunc(exist(&libds,VIEW)) ne 1 %then 0;
|
|
28
|
+
%else 1;
|
|
29
|
+
|
|
30
|
+
%mend mf_existds;
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
@file
|
|
3
|
+
@brief Checks whether a feature exists
|
|
4
|
+
@details Check to see if a feature is supported in your environment.
|
|
5
|
+
Run without arguments to see a list of detectable features.
|
|
6
|
+
Note - this list is based on known versions of SAS rather than
|
|
7
|
+
actual feature detection, as that is tricky / impossible to do
|
|
8
|
+
without generating errs in most cases.
|
|
9
|
+
|
|
10
|
+
%put %mf_existfeature(PROCLUA);
|
|
11
|
+
|
|
12
|
+
@param [in] feature The feature to detect.
|
|
13
|
+
|
|
14
|
+
@return output returns 1 or 0 (or -1 if not found)
|
|
15
|
+
|
|
16
|
+
<h4> SAS Macros </h4>
|
|
17
|
+
@li mf_getplatform.sas
|
|
18
|
+
|
|
19
|
+
@version 8
|
|
20
|
+
@author Allan Bowe
|
|
21
|
+
**/
|
|
22
|
+
/** @cond */
|
|
23
|
+
%macro mf_existfeature(feature
|
|
24
|
+
)/*/STORE SOURCE*/;
|
|
25
|
+
%let feature=%upcase(&feature);
|
|
26
|
+
%local platform;
|
|
27
|
+
%let platform=%mf_getplatform();
|
|
28
|
+
|
|
29
|
+
%if &feature= %then %do;
|
|
30
|
+
%put No feature was requested for detection;
|
|
31
|
+
%end;
|
|
32
|
+
%else %if &feature=COLCONSTRAINTS %then %do;
|
|
33
|
+
%if "%substr(&sysver,1,1)"="4" or "%substr(&sysver,1,1)"="5" %then 0;
|
|
34
|
+
%else 1;
|
|
35
|
+
%end;
|
|
36
|
+
%else %if &feature=PROCLUA %then %do;
|
|
37
|
+
/* https://blogs.sas.com/content/sasdummy/2015/08/03/using-lua-within-your-sas-programs */
|
|
38
|
+
%if &platform=SASVIYA %then 1;
|
|
39
|
+
%else %if "&sysver"="9.2" or "&sysver"="9.3" %then 0;
|
|
40
|
+
%else %if "&SYSVLONG" < "9.04.01M3" %then 0;
|
|
41
|
+
%else 1;
|
|
42
|
+
%end;
|
|
43
|
+
%else %if &feature=DBMS_MEMTYPE %then %do;
|
|
44
|
+
/* does dbms_memtype exist in dictionary.tables? */
|
|
45
|
+
%if "%substr(&sysver,1,1)"="4" or "%substr(&sysver,1,1)"="5" %then 0;
|
|
46
|
+
%else 1;
|
|
47
|
+
%end;
|
|
48
|
+
%else %if &feature=EXPORTXLS %then %do;
|
|
49
|
+
/* is it possible to PROC EXPORT an excel file? */
|
|
50
|
+
%if "%substr(&sysver,1,1)"="4" or "%substr(&sysver,1,1)"="5" %then 1;
|
|
51
|
+
%else %if %sysfunc(sysprod(SAS/ACCESS Interface to PC Files)) = 1 %then 1;
|
|
52
|
+
%else 0;
|
|
53
|
+
%end;
|
|
54
|
+
%else %do;
|
|
55
|
+
-1
|
|
56
|
+
%put &sysmacroname: &feature not found;
|
|
57
|
+
%end;
|
|
58
|
+
%mend mf_existfeature;
|
|
59
|
+
/** @endcond */
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
@file
|
|
3
|
+
@brief Checks whether a fileref exists
|
|
4
|
+
@details You can probably do without this macro as it is just a one liner.
|
|
5
|
+
Mainly it is here as a convenient way to remember the syntax!
|
|
6
|
+
|
|
7
|
+
@param fref the fileref to detect
|
|
8
|
+
|
|
9
|
+
@return output Returns 1 if found and 0 if not found. Note - it is possible
|
|
10
|
+
that the fileref is found, but the file does not (yet) exist. If you need
|
|
11
|
+
to test for this, you may as well use the fileref function directly.
|
|
12
|
+
|
|
13
|
+
@version 8
|
|
14
|
+
@author [Allan Bowe](https://www.linkedin.com/in/allanbowe/)
|
|
15
|
+
**/
|
|
16
|
+
|
|
17
|
+
%macro mf_existfileref(fref
|
|
18
|
+
)/*/STORE SOURCE*/;
|
|
19
|
+
|
|
20
|
+
%local rc;
|
|
21
|
+
%let rc=%sysfunc(fileref(&fref));
|
|
22
|
+
%if &rc=0 %then %do;
|
|
23
|
+
1
|
|
24
|
+
%end;
|
|
25
|
+
%else %if &rc<0 %then %do;
|
|
26
|
+
%put &sysmacroname: Fileref &fref exists but the underlying file does not;
|
|
27
|
+
1
|
|
28
|
+
%end;
|
|
29
|
+
%else %do;
|
|
30
|
+
0
|
|
31
|
+
%end;
|
|
32
|
+
|
|
33
|
+
%mend mf_existfileref;
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
@file
|
|
3
|
+
@brief Checks if a function exists
|
|
4
|
+
@details Returns 1 if the function exists, else 0. Note that this function
|
|
5
|
+
can be slow as it needs to open the sashelp.vfuncs table.
|
|
6
|
+
|
|
7
|
+
Usage:
|
|
8
|
+
|
|
9
|
+
%put %mf_existfunction(CAT);
|
|
10
|
+
%put %mf_existfunction(DOG);
|
|
11
|
+
|
|
12
|
+
Full credit to [Bart](https://sasensei.com/user/305) for the vfunc pointer
|
|
13
|
+
and the tidy approach for pure macro data set filtering.
|
|
14
|
+
Check out his [SAS Packages](https://github.com/yabwon/SAS_PACKAGES)
|
|
15
|
+
framework! Where you can find the same [function](
|
|
16
|
+
https://github.com/yabwon/SAS_PACKAGES/blob/main/packages/baseplus.md#functionexists-macro
|
|
17
|
+
).
|
|
18
|
+
|
|
19
|
+
@param [in] name (positional) - function name
|
|
20
|
+
|
|
21
|
+
@author Allan Bowe
|
|
22
|
+
**/
|
|
23
|
+
/** @cond */
|
|
24
|
+
%macro mf_existfunction(name
|
|
25
|
+
)/*/STORE SOURCE*/;
|
|
26
|
+
|
|
27
|
+
%local dsid rc exist;
|
|
28
|
+
%let dsid=%sysfunc(open(sashelp.vfunc(where=(fncname="%upcase(&name)"))));
|
|
29
|
+
%let exist=1;
|
|
30
|
+
%let exist=%sysfunc(fetch(&dsid, NOSET));
|
|
31
|
+
%let rc=%sysfunc(close(&dsid));
|
|
32
|
+
|
|
33
|
+
%sysevalf(0 = &exist)
|
|
34
|
+
|
|
35
|
+
%mend mf_existfunction;
|
|
36
|
+
|
|
37
|
+
/** @endcond */
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
@file
|
|
3
|
+
@brief Checks if a variable exists in a data set.
|
|
4
|
+
@details Returns 0 if the variable does NOT exist, and the position of the var
|
|
5
|
+
if it does.
|
|
6
|
+
Usage:
|
|
7
|
+
|
|
8
|
+
%put %mf_existvar(work.someds, somevar)
|
|
9
|
+
|
|
10
|
+
@param [in] libds 2 part dataset or view reference
|
|
11
|
+
@param [in] var variable name
|
|
12
|
+
|
|
13
|
+
<h4> Related Macros </h4>
|
|
14
|
+
@li mf_existvar.test.sas
|
|
15
|
+
|
|
16
|
+
@version 9.2
|
|
17
|
+
@author Allan Bowe
|
|
18
|
+
**/
|
|
19
|
+
/** @cond */
|
|
20
|
+
|
|
21
|
+
%macro mf_existvar(libds /* 2 part dataset name */
|
|
22
|
+
, var /* variable name */
|
|
23
|
+
)/*/STORE SOURCE*/;
|
|
24
|
+
|
|
25
|
+
%local dsid rc;
|
|
26
|
+
%let dsid=%sysfunc(open(&libds,is));
|
|
27
|
+
|
|
28
|
+
%if &dsid=0 or %length(&var)=0 %then %do;
|
|
29
|
+
%put %sysfunc(sysmsg());
|
|
30
|
+
0
|
|
31
|
+
%end;
|
|
32
|
+
%else %do;
|
|
33
|
+
%sysfunc(varnum(&dsid,&var))
|
|
34
|
+
%let rc=%sysfunc(close(&dsid));
|
|
35
|
+
%end;
|
|
36
|
+
|
|
37
|
+
%mend mf_existvar;
|
|
38
|
+
|
|
39
|
+
/** @endcond */
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
@file
|
|
3
|
+
@brief Checks if a set of variables ALL exist in a data set.
|
|
4
|
+
@details Returns 0 if ANY of the variables do not exist, or 1 if they ALL do.
|
|
5
|
+
Usage:
|
|
6
|
+
|
|
7
|
+
%put %mf_existVarList(sashelp.class, age sex name dummyvar);
|
|
8
|
+
|
|
9
|
+
@param libds 2 part dataset or view reference
|
|
10
|
+
@param varlist space separated variable names
|
|
11
|
+
|
|
12
|
+
@version 9.2
|
|
13
|
+
@author Allan Bowe
|
|
14
|
+
@cond
|
|
15
|
+
**/
|
|
16
|
+
|
|
17
|
+
%macro mf_existvarlist(libds, varlist
|
|
18
|
+
)/*/STORE SOURCE*/;
|
|
19
|
+
|
|
20
|
+
%if %str(&libds)=%str() or %str(&varlist)=%str() %then %do;
|
|
21
|
+
%mf_abort(msg=No value provided to libds(&libds) or varlist (&varlist)!
|
|
22
|
+
,mac=mf_existvarlist.sas)
|
|
23
|
+
%end;
|
|
24
|
+
|
|
25
|
+
%local dsid rc i var found;
|
|
26
|
+
%let dsid=%sysfunc(open(&libds,is));
|
|
27
|
+
|
|
28
|
+
%if &dsid=0 %then %do;
|
|
29
|
+
%put %str(WARN)ING: unable to open &libds in mf_existvarlist (&dsid);
|
|
30
|
+
%end;
|
|
31
|
+
|
|
32
|
+
%if %sysfunc(attrn(&dsid,NVARS))=0 %then %do;
|
|
33
|
+
%put MF_EXISTVARLIST: No variables in &libds ;
|
|
34
|
+
0
|
|
35
|
+
%return;
|
|
36
|
+
%end;
|
|
37
|
+
|
|
38
|
+
%else %do i=1 %to %sysfunc(countw(&varlist));
|
|
39
|
+
%let var=%scan(&varlist,&i);
|
|
40
|
+
|
|
41
|
+
%if %sysfunc(varnum(&dsid,&var))=0 %then %do;
|
|
42
|
+
%let found=&found &var;
|
|
43
|
+
%end;
|
|
44
|
+
%end;
|
|
45
|
+
|
|
46
|
+
%let rc=%sysfunc(close(&dsid));
|
|
47
|
+
%if %str(&found)=%str() %then %do;
|
|
48
|
+
1
|
|
49
|
+
%end;
|
|
50
|
+
%else %do;
|
|
51
|
+
0
|
|
52
|
+
%put Vars not found: &found;
|
|
53
|
+
%end;
|
|
54
|
+
%mend mf_existvarlist;
|
|
55
|
+
|
|
56
|
+
/** @endcond */
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
@file
|
|
3
|
+
@brief Returns E8601DT26.6 if compatible else DATETIME19.3
|
|
4
|
+
@details From our experience in [Data Controller for SAS]
|
|
5
|
+
(https://datacontroller.io) deployments, the E8601DT26.6 datetime format has
|
|
6
|
+
the widest support when it comes to pass-through SQL queries.
|
|
7
|
+
|
|
8
|
+
However, it is not supported in WPS or early versions of SAS 9 (M3 and below)
|
|
9
|
+
when used as a datetime literal, eg:
|
|
10
|
+
|
|
11
|
+
data _null_;
|
|
12
|
+
demo="%sysfunc(datetime(),E8601DT26.6)"dt;
|
|
13
|
+
demo=;
|
|
14
|
+
run;
|
|
15
|
+
|
|
16
|
+
This macro will therefore return DATEITME19.3 as an alternative format
|
|
17
|
+
based on the runtime environment so that it can be used in such cases, eg:
|
|
18
|
+
|
|
19
|
+
data _null_;
|
|
20
|
+
demo="%sysfunc(datetime(),%mf_fmtdttm())"dt;
|
|
21
|
+
demo=;
|
|
22
|
+
run;
|
|
23
|
+
|
|
24
|
+
<h4> Related Macros </h4>
|
|
25
|
+
@li mf_fmtdttm.test.sas
|
|
26
|
+
|
|
27
|
+
@author Allan Bowe
|
|
28
|
+
**/
|
|
29
|
+
|
|
30
|
+
%macro mf_fmtdttm(
|
|
31
|
+
)/*/STORE SOURCE*/;
|
|
32
|
+
|
|
33
|
+
%if "&sysver"="9.2" or "&sysver"="9.3"
|
|
34
|
+
or ("&sysver"="9.4" and "%substr(&SYSVLONG,9,1)" le "3")
|
|
35
|
+
or "%substr(&sysver,1,1)"="4"
|
|
36
|
+
or "%substr(&sysver,1,1)"="5"
|
|
37
|
+
%then %do;DATETIME19.3%end;
|
|
38
|
+
%else %do;E8601DT26.6%end;
|
|
39
|
+
|
|
40
|
+
%mend mf_fmtdttm;
|
|
41
|
+
|
|
42
|
+
|