├── CognosScripts
├── HolidayCalendar.js
├── HolidayCalendarControl.js
├── ObjectMethods.js
├── OrderOfMethodsCustomControl.js
├── OrderOfMethodsPageModule.js
├── ParamDisplay.js
├── ParameterCapture.js
├── ParameterDisplay.js
├── ParameterToText.js
├── PromptAutoFinish.js
├── PromptButton.js
├── PromptDateDefault.js
├── PromptFinish.js
├── PromptIncrementAndRun.js
├── PromptLoadValuesFromQuery.js
├── Prompts.js
├── README.md
├── cleanParams.js
├── json.js
├── json2xml.js
├── mapOpenLayers.js
└── xml2json.js
├── ContentStore
├── ADSI.sql
├── BrokenShortcuts.sql
├── Capabilities.ps1
├── CognosScheduleEmailRecients.sql
├── ContentStoreCMIDSearch.sql
├── ContentStoreDoc.txt
├── LocateSchedules.sql
├── ModuleAndModelSpecs.sql
├── ModulesAndPackages.ps1
├── ObjectCapabilities.ps1
├── ObjectPermissions.ps1
├── OutputSpecs.sql
├── OwnedObjects.sql
├── PackageReference.sql
├── PermissionsPerUser.sql
├── README.md
├── RoleGroupMembership.ps1
├── SpecBackup
│ ├── README.md
│ ├── ReportBackup.ps1
│ ├── export.ps1
│ └── push.ps1
├── capabilities.sql
├── udf_CognosPermissions.sql
└── udf_ConvertFromBase10.sql
├── LICENSE
├── Maintenance
├── MaintenanceWindow
│ ├── CognosMaintenance.ps1
│ ├── CognosStart.ps1
│ ├── CognosStop.ps1
│ └── README.md
└── SSL
│ ├── README.md
│ ├── RequestCognosServerCert.ps1
│ ├── SSLCertExpiration.csv
│ └── SSLExpiration.ps1
├── README.md
├── RESTAPI
├── ModuleBusinessNames.ps1
├── README.md
├── REST API Example.ps1
├── fn.ps1
└── getCSV.ps1
├── ReportSpecifications
├── Bursting.txt
├── CommaDelimitedList.txt
├── ComplexLineChart.txt
├── CrosstabWithRowLabelHeaders.txt
├── Date Calculations.txt
├── Parameter Reporter.txt
├── Parameter Value Automation.txt
├── Prompt Scripts.txt
├── README.md
├── Scriptable Reports - Order of Methods.txt
├── ToolTips.txt
└── VariableOperator.txt
└── SDK
└── README.md
/CognosScripts/HolidayCalendar.js:
--------------------------------------------------------------------------------
1 | define(function () {
2 | // HoldayCalendar.js
3 | // Holiday Calendar
4 | // contains dates that are holidays
5 | // provides a function to determin if
6 |
7 | function HolidayCalendar() {
8 | };
9 |
10 | HolidayCalendar.Holidays = [];
11 | HolidayCalendar.Holidays.push(new Date(2016,0,1));
12 | HolidayCalendar.Holidays.push(new Date(2016,0,18));
13 | HolidayCalendar.Holidays.push(new Date(2016,1,15));
14 | HolidayCalendar.Holidays.push(new Date(2016,4,30));
15 | HolidayCalendar.Holidays.push(new Date(2016,6,4));
16 | HolidayCalendar.Holidays.push(new Date(2016,8,5));
17 | HolidayCalendar.Holidays.push(new Date(2016,10,11));
18 | HolidayCalendar.Holidays.push(new Date(2016,10,24));
19 | HolidayCalendar.Holidays.push(new Date(2016,10,25));
20 | HolidayCalendar.Holidays.push(new Date(2016,11,26));
21 | HolidayCalendar.Holidays.push(new Date(2017,0,2));
22 | HolidayCalendar.Holidays.push(new Date(2017,0,16));
23 | HolidayCalendar.Holidays.push(new Date(2017,1,20));
24 | HolidayCalendar.Holidays.push(new Date(2017,4,29));
25 | HolidayCalendar.Holidays.push(new Date(2017,6,4));
26 | HolidayCalendar.Holidays.push(new Date(2017,8,4));
27 | HolidayCalendar.Holidays.push(new Date(2017,10,10));
28 | HolidayCalendar.Holidays.push(new Date(2017,10,23));
29 | HolidayCalendar.Holidays.push(new Date(2017,10,24));
30 | HolidayCalendar.Holidays.push(new Date(2017,11,25));
31 | HolidayCalendar.Holidays.push(new Date(2018,0,1));
32 | HolidayCalendar.Holidays.push(new Date(2018,0,15));
33 | HolidayCalendar.Holidays.push(new Date(2018,1,19));
34 | HolidayCalendar.Holidays.push(new Date(2018,4,28));
35 | HolidayCalendar.Holidays.push(new Date(2018,6,4));
36 | HolidayCalendar.Holidays.push(new Date(2018,8,3));
37 | HolidayCalendar.Holidays.push(new Date(2018,10,12));
38 | HolidayCalendar.Holidays.push(new Date(2018,10,22));
39 | HolidayCalendar.Holidays.push(new Date(2018,10,23));
40 | HolidayCalendar.Holidays.push(new Date(2018,11,25));
41 | HolidayCalendar.Holidays.push(new Date(2019,0,1));
42 | HolidayCalendar.Holidays.push(new Date(2019,0,21));
43 | HolidayCalendar.Holidays.push(new Date(2019,1,18));
44 | HolidayCalendar.Holidays.push(new Date(2019,4,27));
45 | HolidayCalendar.Holidays.push(new Date(2019,6,4));
46 | HolidayCalendar.Holidays.push(new Date(2019,8,2));
47 | HolidayCalendar.Holidays.push(new Date(2019,10,11));
48 | HolidayCalendar.Holidays.push(new Date(2019,10,28));
49 | HolidayCalendar.Holidays.push(new Date(2019,10,29));
50 | HolidayCalendar.Holidays.push(new Date(2019,11,25));
51 | HolidayCalendar.Holidays.push(new Date(2020,0,1));
52 | HolidayCalendar.Holidays.push(new Date(2020,0,20));
53 | HolidayCalendar.Holidays.push(new Date(2020,1,17));
54 | HolidayCalendar.Holidays.push(new Date(2020,4,25));
55 | HolidayCalendar.Holidays.push(new Date(2020,6,3));
56 | HolidayCalendar.Holidays.push(new Date(2020,8,7));
57 | HolidayCalendar.Holidays.push(new Date(2020,10,11));
58 | HolidayCalendar.Holidays.push(new Date(2020,10,26));
59 | HolidayCalendar.Holidays.push(new Date(2020,10,27));
60 | HolidayCalendar.Holidays.push(new Date(2020,11,25));
61 | HolidayCalendar.Holidays.push(new Date(2021,0,1));
62 | HolidayCalendar.Holidays.push(new Date(2021,0,18));
63 | HolidayCalendar.Holidays.push(new Date(2021,1,15));
64 | HolidayCalendar.Holidays.push(new Date(2021,4,31));
65 | HolidayCalendar.Holidays.push(new Date(2021,6,5));
66 | HolidayCalendar.Holidays.push(new Date(2021,8,6));
67 | HolidayCalendar.Holidays.push(new Date(2021,10,11));
68 | HolidayCalendar.Holidays.push(new Date(2021,10,25));
69 | HolidayCalendar.Holidays.push(new Date(2021,10,26));
70 | HolidayCalendar.Holidays.push(new Date(2021,11,24));
71 | HolidayCalendar.Holidays.push(new Date(2021,11,31));
72 | HolidayCalendar.Holidays.push(new Date(2022,0,17));
73 | HolidayCalendar.Holidays.push(new Date(2022,1,21));
74 | HolidayCalendar.Holidays.push(new Date(2022,4,30));
75 | HolidayCalendar.Holidays.push(new Date(2022,5,19));
76 | HolidayCalendar.Holidays.push(new Date(2022,6,4));
77 | HolidayCalendar.Holidays.push(new Date(2022,8,5));
78 | HolidayCalendar.Holidays.push(new Date(2022,10,11));
79 | HolidayCalendar.Holidays.push(new Date(2022,10,24));
80 | HolidayCalendar.Holidays.push(new Date(2022,10,25));
81 | HolidayCalendar.Holidays.push(new Date(2022,11,26));
82 | HolidayCalendar.Holidays.push(new Date(2023,0,2));
83 | HolidayCalendar.Holidays.push(new Date(2023,0,16));
84 | HolidayCalendar.Holidays.push(new Date(2023,1,20));
85 | HolidayCalendar.Holidays.push(new Date(2023,4,29));
86 | HolidayCalendar.Holidays.push(new Date(2023,5,19));
87 | HolidayCalendar.Holidays.push(new Date(2023,6,4));
88 | HolidayCalendar.Holidays.push(new Date(2023,8,4));
89 | HolidayCalendar.Holidays.push(new Date(2023,10,10));
90 | HolidayCalendar.Holidays.push(new Date(2023,10,23));
91 | HolidayCalendar.Holidays.push(new Date(2023,10,24));
92 | HolidayCalendar.Holidays.push(new Date(2023,11,25));
93 | HolidayCalendar.Holidays.push(new Date(2024,0,1));
94 | HolidayCalendar.Holidays.push(new Date(2024,0,15));
95 | HolidayCalendar.Holidays.push(new Date(2024,1,19));
96 | HolidayCalendar.Holidays.push(new Date(2024,4,27));
97 | HolidayCalendar.Holidays.push(new Date(2024,5,19));
98 | HolidayCalendar.Holidays.push(new Date(2024,6,4));
99 | HolidayCalendar.Holidays.push(new Date(2024,8,2));
100 | HolidayCalendar.Holidays.push(new Date(2024,10,11));
101 | HolidayCalendar.Holidays.push(new Date(2024,10,28));
102 | HolidayCalendar.Holidays.push(new Date(2024,10,29));
103 | HolidayCalendar.Holidays.push(new Date(2024,11,25));
104 | /*
105 | Use this query against ConformedDimensions:
106 | select 'HolidayCalendar.Holidays.push(new Date('
107 | + cast(datepart(year, d.FullDate) as varchar(4)) + ','
108 | + cast(datepart(month, d.FullDate) - 1 as varchar(2)) + ','
109 | + cast(datepart(day, d.FullDate) as varchar(2)) + '));'
110 | from [Date] d
111 | where d.LegalStateHolidayInd = 'yes'
112 | and year(d.FullDate) >= 2016
113 | order by d.FullDate
114 | */
115 |
116 | HolidayCalendar.isHoliday = function (d) {
117 | var b = false;
118 | d1 = new Date(d);
119 | d1.setHours(0);
120 | d1.setMinutes(0);
121 | d1.setSeconds(0);
122 | d1.setMilliseconds(0);
123 | //console.log(d);
124 | b = this.Holidays.contains(d1);
125 | //console.log(" " + b.toString());
126 | return b;
127 | };
128 |
129 | return HolidayCalendar;
130 | });
--------------------------------------------------------------------------------
/CognosScripts/HolidayCalendarControl.js:
--------------------------------------------------------------------------------
1 | define(function () {
2 | // HolidayCalendar.js
3 | // Holiday Calendar
4 | // Exposes one dataset with one category that contains the
5 | // dates of holidays appropriate to the context of the report.
6 | "use strict";
7 |
8 | var log = function (label, message) {
9 | console.log(" **** " + label + " : " + message);
10 | }
11 |
12 | function HolidayCalendarControl() {};
13 |
14 | HolidayCalendarControl.prototype.initialize = function ( oControlHost, fnDoneInitializing ) {
15 | log("HolidayCalendar", "initialize" );
16 |
17 | var bInit = true;
18 | if (bInit) fnDoneInitializing();
19 | };
20 |
21 | HolidayCalendarControl.prototype.setData = function( oControlHost, oDataStore ){
22 | log("HolidayCalendar", "setData" );
23 | this.m_oDataStore = oDataStore;
24 | };
25 |
26 | HolidayCalendarControl.prototype.draw = function( oControlHost ){
27 | log("HolidayCalendar", "draw" );
28 | };
29 |
30 | return HolidayCalendarControl;
31 | });
--------------------------------------------------------------------------------
/CognosScripts/OrderOfMethodsCustomControl.js:
--------------------------------------------------------------------------------
1 | define( function() {
2 | "use strict";
3 |
4 | //var log = function (message) {
5 | // console.log(" Order Of Methods : " + message);
6 | //}
7 |
8 | function AdvancedControl() {
9 | };
10 |
11 | AdvancedControl.prototype.initialize = function( oControlHost, fnDoneInitializing ) {
12 | this.config = oControlHost.configuration;
13 | this.log = function (message) {
14 | if (!oControlHost.page.ScriptLog) {
15 | var p = document.createElement("pre");
16 | oControlHost.page.ScriptLog = oControlHost.page.getControlByName("ScriptLog").element.appendChild(p);
17 | }
18 | s = " Order Of Methods : custom control " + this.config.ControlNum + " " + message + "\r\n";
19 | oControlHost.page.ScriptLog.textContent += s;
20 | //oControlHost.page.getControlByName("ScriptLog").element.childNode.textContent += " Order Of Methods : custom control " + this.config.ControlNum + " " + message + "\r\n";
21 | console.log(s);
22 | };
23 | this.log("initialize");
24 | fnDoneInitializing();
25 | };
26 |
27 | AdvancedControl.prototype.destroy = function( oControlHost ) {
28 | this.log("destroy");
29 | };
30 |
31 | AdvancedControl.prototype.draw = function( oControlHost ) {
32 | this.log("draw");
33 | };
34 |
35 | AdvancedControl.prototype.show = function( oControlHost ) {
36 | this.log("show");
37 | };
38 |
39 | AdvancedControl.prototype.hide = function( oControlHost ) {
40 | this.log("hide");
41 | };
42 |
43 | AdvancedControl.prototype.isInValidState = function( oControlHost ) {
44 | this.log("isInValidState");
45 | return true;
46 | };
47 |
48 | AdvancedControl.prototype.getParameters = function( oControlHost ) {
49 | this.log("getParameters");
50 | };
51 |
52 | AdvancedControl.prototype.setData = function( oControlHost, oDataStore ) {
53 | this.log("setData");
54 | };
55 |
56 | return AdvancedControl;
57 | });
--------------------------------------------------------------------------------
/CognosScripts/OrderOfMethodsPageModule.js:
--------------------------------------------------------------------------------
1 | define (["/CognosScripts/ObjectMethods.js"], function () {
2 |
3 |
4 | //var log = function (message) {
5 | // console.log(" Order Of Methods : " + message);
6 | //}
7 |
8 | function PageModule() {
9 | };
10 |
11 | PageModule.prototype.load = function( oPage ) {
12 | if (!oPage.ScriptLog) {
13 | var p = document.createElement("pre");
14 | oPage.ScriptLog = oPage.getControlByName("ScriptLog").element.appendChild(p);
15 | }
16 | this.log = function (message) {
17 | s = " Order Of Methods : page module " + message + "\r\n";
18 | oPage.ScriptLog.textContent += s;
19 | //oPage.getControlByName("ScriptLog").element.childNode.textContent += " Order Of Methods : page module " + message + "\r\n";
20 | console.log(s);
21 | };
22 | this.log("load");
23 | };
24 |
25 | PageModule.prototype.show = function( oPage ) {
26 | this.log("show");
27 | };
28 |
29 | PageModule.prototype.hide = function( oPage ) {
30 | this.log("hide");
31 | };
32 |
33 | PageModule.prototype.destroy = function( oPage ) {
34 | this.log("destroy");
35 | };
36 |
37 | return PageModule;
38 | });
--------------------------------------------------------------------------------
/CognosScripts/ParamDisplay.js:
--------------------------------------------------------------------------------
1 | define( function() {
2 | "use strict";
3 |
4 | /*
5 | Module Type: Custom Control Module
6 | Purpose: Reads from sessionStorage and, for each parameter, displays the prompt name and selected values.
7 | */
8 |
9 | var log = function (label, message) {
10 | console.log(" **** " + label + " : " + message);
11 | }
12 |
13 | function ParamDisplay() {};
14 |
15 | ParamDisplay.prototype.initialize = function(oControlHost, fnDoneInitializing) {
16 | log("ParamDisplay", "CustomControlModule.initialize" );
17 |
18 | this.Params = window.Application.GetParameterValues();
19 |
20 | fnDoneInitializing();
21 | };
22 |
23 | ParamDisplay.prototype.destroy = function(oControlHost) {
24 | //log("ParamDisplay", "CustomControlModule.destroy" );
25 | };
26 |
27 | ParamDisplay.prototype.draw = function(oControlHost) {
28 | log("ParamDisplay", "CustomControlModule.draw" );
29 |
30 | var tbl = document.createElement("table");
31 | this.Params.forEach(function(e) {
32 | var tr = document.createElement("tr");
33 | var paramName = document.createElement("td");
34 | paramName.appendChild(document.createTextNode(e.name));
35 | paramName.style.verticalAlign = "top";
36 | tr.appendChild(paramName);
37 | var paramValue = document.createElement("td");
38 | paramValue.style.verticalAlign = "top";
39 | var ParamValue = "";
40 | //var paramDiv = document.createElement("div");
41 | var bRange = false;
42 | e.value.forEach(function(v) {
43 | if (v.type.indexOf("Range") != -1) {
44 | bRange = true;
45 | var paramDiv = document.createElement("div");
46 | ParamValue = ((typeof v.start == "undefined") ? "" : v.start.display) + " to " + ((typeof v.end == "undefined") ? "" : v.end.display);
47 | paramDiv.appendChild(document.createTextNode(ParamValue));
48 | paramValue.appendChild(paramDiv);
49 | }
50 | else {
51 | ParamValue += ", " + ((typeof v.display == "undefined") ? "" : v.display);
52 | }
53 | });
54 | if (!bRange) paramValue.appendChild(document.createTextNode(ParamValue.substring(2)));
55 | tr.appendChild(paramValue);
56 | tbl.appendChild(tr);
57 | });
58 | oControlHost.container.appendChild(tbl);
59 | };
60 |
61 | ParamDisplay.prototype.show = function(oControlHost) {
62 | //log("ParamDisplay", "CustomControlModule.show" );
63 | };
64 |
65 | ParamDisplay.prototype.hide = function(oControlHost) {
66 | //log("ParamDisplay", "CustomControlModule.hide" );
67 | };
68 |
69 | ParamDisplay.prototype.isInValidState = function(oControlHost) {
70 | //log("ParamDisplay", "CustomControlModule.isInValidState" );
71 | };
72 |
73 | ParamDisplay.prototype.getParameters = function(oControlHost) {
74 | //log("ParamDisplay", "CustomControlModule.getParameters" );
75 | };
76 |
77 | ParamDisplay.prototype.setData = function(oControlHost, oDataStore) {
78 | //log("ParamDisplay", "CustomControlModule.setData" );
79 | };
80 |
81 | return ParamDisplay;
82 | });
--------------------------------------------------------------------------------
/CognosScripts/ParameterCapture.js:
--------------------------------------------------------------------------------
1 | define(function () {
2 | "use strict";
3 |
4 | /*
5 | Module Type: Page Module
6 | Purpose: Captures parameter name, prompt name, and selected
7 | parameter values.
8 | Stores data in sessionStorage for retrieval by the
9 | next prompt page using this module or a custom control
10 | using the ParameterDisplay Custom Control Module.
11 | Requirements: The first prompt page must have a layout calculation
12 | named "ReportName" defined as ReportName()
13 | Future: This functionality should probably be incorporated
14 | into Prompts.js.
15 | */
16 |
17 | var log = function (label, message) {
18 | console.log(" **** " + label + " : " + message);
19 | }
20 |
21 | function PageModule() {
22 | };
23 |
24 | PageModule.prototype.load = function(oPage) {
25 | log("page", "PageModule.load" );
26 |
27 | var crObject = oPage.getControlByName("ReportName");
28 | //this.CurrentReport = "";
29 | this.CurrentReport = sessionStorage.getItem("CurrentReport");
30 | if (crObject) {
31 | this.CurrentReport = crObject.text;
32 | sessionStorage.setItem("CurrentReport", this.CurrentReport);
33 | }
34 |
35 | //var apc = oPage.getAllPromptControls();
36 | //
37 | //apc.forEach(function (n) {
38 | // log(" Prompts: ", n.name);
39 | //});
40 | };
41 |
42 | PageModule.prototype.show = function(oPage) {
43 | log("page", "PageModule.show" );
44 | };
45 |
46 | PageModule.prototype.hide = function(oPage) {
47 | log("page", "PageModule.hide" );
48 | };
49 |
50 | PageModule.prototype.destroy = function(oPage) {
51 | log("page", "PageModule.destroy" );
52 |
53 | if (this.CurrentReport) {
54 | if (!sessionStorage.getItem("Parameters" + this.CurrentReport)) {
55 | sessionStorage.setItem("Parameters" + this.CurrentReport, JSON.stringify({}));
56 | }
57 |
58 | var prompts = oPage.getAllPromptControls();
59 | prompts.forEach(function (e) {
60 | var p = JSON.parse(sessionStorage.getItem("Parameters" + this.CurrentReport));
61 | var v1 = e.getValues();
62 | var v2 = JSON.stringify(v1);
63 | var v3 = e.name;
64 | var v4 = [v3, v2];
65 | p[e.parameter] = JSON.stringify(v4);
66 | //p[e.parameter] = JSON.stringify([e.name, JSON.stringify(e.getValues())]);
67 | sessionStorage.setItem("Parameters" + this.CurrentReport, JSON.stringify(p));
68 | }, this);
69 | }
70 | };
71 |
72 | return PageModule;
73 | });
--------------------------------------------------------------------------------
/CognosScripts/ParameterDisplay.js:
--------------------------------------------------------------------------------
1 | define( function() {
2 | "use strict";
3 |
4 | /*
5 | Module Type: Custom Control Module
6 | Purpose: Reads from sessionStorage and, for each parameter, displays the prompt name and selected values.
7 | */
8 |
9 | var log = function (label, message) {
10 | console.log(" **** " + label + " : " + message);
11 | }
12 |
13 | function ParameterDisplay() {};
14 |
15 | ParameterDisplay.prototype.initialize = function(oControlHost, fnDoneInitializing) {
16 | log("ParameterDisplay", "CustomControlModule.initialize" );
17 | this.CurrentReport = sessionStorage.getItem("CurrentReport");
18 | fnDoneInitializing();
19 | };
20 |
21 | ParameterDisplay.prototype.destroy = function(oControlHost) {
22 | log("ParameterDisplay", "CustomControlModule.destroy" );
23 | };
24 |
25 | ParameterDisplay.prototype.draw = function(oControlHost) {
26 | log("ParameterDisplay", "CustomControlModule.draw" );
27 |
28 | if (this.CurrentReport) { // if there is no object named ReportName, don't try to display parameters
29 | var params = JSON.parse(sessionStorage.getItem("Parameters" + this.CurrentReport));
30 |
31 | Object.keys(params).forEach(function(e) {
32 | var ss = JSON.parse(params[e]);
33 | var ne = document.createElement("div");
34 | var ns = "";
35 | JSON.parse(ss[1]).forEach(function(f) {
36 | if (f.start) {
37 | ns += ", start: " + ((typeof f.start.display == "undefined") ? "" : f.start.display) + ", end: " + ((typeof f.end.display == "undefined") ? "" : f.end.display);
38 | }
39 | else {
40 | ns += ", " + ((typeof f.display == "undefined") ? "" : f.display);
41 | }
42 | });
43 | ns = ns.substring(2);
44 | var nc = document.createTextNode(ss[0] + ": " + ns);
45 | ne.appendChild(nc);
46 | oControlHost.container.appendChild(ne);
47 | });
48 | }
49 |
50 | //oControlHost.container.innerHTML = JSON.stringify(apn);
51 | };
52 |
53 | ParameterDisplay.prototype.show = function(oControlHost) {
54 | log("ParameterDisplay", "CustomControlModule.show" );
55 | };
56 |
57 | ParameterDisplay.prototype.hide = function(oControlHost) {
58 | log("ParameterDisplay", "CustomControlModule.hide" );
59 | };
60 |
61 | ParameterDisplay.prototype.isInValidState = function(oControlHost) {
62 | log("ParameterDisplay", "CustomControlModule.isInValidState" );
63 | };
64 |
65 | ParameterDisplay.prototype.getParameters = function(oControlHost) {
66 | log("ParameterDisplay", "CustomControlModule.getParameters" );
67 | };
68 |
69 | ParameterDisplay.prototype.setData = function(oControlHost, oDataStore) {
70 | log("ParameterDisplay", "CustomControlModule.setData" );
71 | };
72 |
73 | return ParameterDisplay;
74 | });
--------------------------------------------------------------------------------
/CognosScripts/ParameterToText.js:
--------------------------------------------------------------------------------
1 | define (["/CognosScripts/json.js", "/CognosScripts/xml2json.js", "/CognosScripts/cleanParams.js"], function () {
2 | /*
3 | author: doug pulse
4 | created: 2016-05-13
5 | license: public domain
6 |
7 | input: object parameter name/value pairs returned by cleanParams
8 |
9 | output: string something more useful for reporting
10 |
11 | purpose: Convert a list of parameter values stored as a javascript
12 | object into a string.
13 |
14 | usage: After converting the parameter data from the original XML in
15 | databaseserver.IBMCognosAudit.COGIPF_PARAMETER.COGIPF_PARAMETER_VALUE_BLOB
16 | to a JSON string, the resulting JSON can be parsed (JSON.parse)
17 | into an object and used as input to these functions.
18 |
19 | This function expects a single value from a single audit record. The
20 | custom control for this script should be in a list column body. The
21 | master-detail relationships property of the data set should be set to
22 | join to the main data set on COGIPF_SUBREQUESTID so that each custom
23 | control receives only one value from the COGIPF_PARAMETER_VALUE_BLOB column.
24 | */
25 |
26 |
27 | var log = function (label, message) {
28 | console.log(" **** " + label + " : " + message);
29 | }
30 |
31 | ParameterDisplayValues = function (o) {
32 | var sOut = "";
33 | var vals = [];
34 | for (var a in o) {
35 | //alert(a);
36 | sOut += a;
37 | vals = [];
38 | if (o[a][0].start) {
39 | sOut += " in range {";
40 | for (var i = 0; i < o[a].length; i++) {
41 | vals.push(o[a][i].start.display + " to " + o[a][i].end.display);
42 | }
43 | }
44 | else {
45 | sOut += " = {";
46 | for (var i = 0; i < o[a].length; i++) {
47 | vals.push(o[a][i].display);
48 | }
49 | }
50 | sOut += vals.toString() + "}\n";
51 | }
52 | return sOut;
53 | }
54 |
55 | //ParameterValues = function (o) {
56 | // var sOut = "";
57 | // var vals = [];
58 | // for (var a in o) {
59 | // //alert(a);
60 | // sOut += a;
61 | // vals = [];
62 | // if (o[a][0].start) {
63 | // sOut += " in range {";
64 | // for (var i = 0; i < o[a].length; i++) {
65 | // vals.push(o[a][i].start.use + " to " + o[a][i].end.use);
66 | // }
67 | // }
68 | // else {
69 | // sOut += " = {";
70 | // for (var i = 0; i < o[a].length; i++) {
71 | // vals.push(o[a][i].use);
72 | // }
73 | // }
74 | // sOut += vals.toString() + "}\n";
75 | // }
76 | // return sOut;
77 | //}
78 |
79 |
80 |
81 |
82 | function ParameterToText() {
83 | };
84 |
85 | ParameterToText.prototype.initialize = function( oControlHost, fnDoneInitializing ) {
86 | log("ParameterToText", "Control.initialize" );
87 | fnDoneInitializing();
88 | };
89 |
90 | ParameterToText.prototype.draw = function( oControlHost ) {
91 | log("ParameterToText", "Control.draw" );
92 | var o = oControlHost.configuration;
93 | this.colName = ( o && o.colName ) ? o.colName : "Parameter XML";
94 |
95 | //log("Parameter XML", this.xml);
96 | var j = xml2json(this.xml); // returns a string
97 | var o = JSON.parse(j); // returns an object
98 | var c = cleanParams(o); // returns
99 | var s = ParameterDisplayValues(c);
100 | //return s.replace(/\n/gi, "<br />");
101 |
102 | var f = document.createElement("span");
103 | f.innerHTML = s.replace(/\n/gi, " ");
104 |
105 | oControlHost.container.appendChild(f);
106 | };
107 |
108 | ParameterToText.prototype.setData = function( oControlHost, oDataStore ) {
109 | log("ParameterToText", "Control.setData" );
110 | log("ParameterToText", "Control.draw" );
111 | var o = oControlHost.configuration;
112 | this.colName = ( o && o.colName ) ? o.colName : "Parameter XML";
113 | var colNum = oDataStore.getColumnIndex(this.colName);
114 | console.log(" subrequest id = " + oDataStore.getCellValue(0, oDataStore.getColumnIndex("Subrequest ID")));
115 | this.xml = oDataStore.getCellValue(0, colNum);
116 | };
117 |
118 | return ParameterToText;
119 | });
120 |
--------------------------------------------------------------------------------
/CognosScripts/PromptAutoFinish.js:
--------------------------------------------------------------------------------
1 | define( function() {
2 | "use strict";
3 |
4 | var log = function (label, message) {
5 | console.log(" **** " + label + " : " + message);
6 | };
7 |
8 | function AutoFinish() {
9 | };
10 |
11 | AutoFinish.prototype.initialize = function( oControlHost, fnDoneInitializing ) {
12 | log("AutoFinish", "Control.initialize" );
13 | if (!oControlHost.page.AutoFinish) {
14 | console.log(" Defining AutoFinish");
15 | oControlHost.page.AutoFinish = function () {
16 | oControlHost.next()
17 | };
18 | }
19 | fnDoneInitializing();
20 | };
21 |
22 | AutoFinish.prototype.draw = function( oControlHost ) {
23 | log("AutoFinish", "Control.draw" );
24 | };
25 |
26 | return AutoFinish;
27 | });
--------------------------------------------------------------------------------
/CognosScripts/PromptButton.js:
--------------------------------------------------------------------------------
1 | define( function() {
2 | "use strict";
3 |
4 | var log = function (label, message) {
5 | console.log(" **** PromptButton : " + label + " : " + message);
6 | };
7 |
8 |
9 | function Button() {
10 | };
11 |
12 |
13 | Button.prototype.initialize = function( oControlHost, fnDoneInitializing ) {
14 | log("Button", "Control.initialize" );
15 |
16 | /*
17 | Configuration:
18 | {
19 | "ButtonType": "Finish",
20 | "ButtonLabel": "Finish",
21 | "RequiredPrompts": // this is [ [a and b] or [a and c] ]
22 | [
23 | ["WorkOrder", "Bien"],
24 | ["WorkOrder", "fy"]
25 | ],
26 | "RequiredPromptCount": 2,
27 | "HiddenPrompt": "MyHiddenPrompt",
28 | "ValidationFailureAlert": "validation failed"
29 | }
30 | */
31 |
32 | /*
33 | Using RequiredPrompts or RequiredPromptCount probably only makes
34 | sense with a ButtonType of Finish or Next.
35 |
36 | Using HiddenPrompt is for when the page may already have all
37 | required prompts set, but you want to allow autosubmit to control
38 | other prompting and not to "finish" prompting.
39 | The prompt used for HiddenPrompt should be a Text Box Prompt.
40 | */
41 |
42 | this.controlHost = oControlHost;
43 | this.oConfig = this.controlHost.configuration;
44 | this.page = this.controlHost.page;
45 | this.Prompts = this.page.getAllPromptControls();
46 | this.ButtonType = ( this.oConfig && this.oConfig.ButtonType ) ? this.oConfig.ButtonType : "Finish";
47 | this.ButtonLabel = ( this.oConfig && this.oConfig.ButtonLabel ) ? this.oConfig.ButtonLabel : this.ButtonType;
48 | this.failureAlert = ( this.oConfig && this.oConfig.ValidationFailureAlert ) ? this.oConfig.ValidationFailureAlert : null;
49 |
50 | this.RequiredPromptsValidator = function (arr) {
51 | //[
52 | // ["WorkOrder", "Bien"],
53 | // ["WorkOrder", "fy"]
54 | //]
55 | var valid = false;
56 | var v; // prompt values
57 |
58 | for (var i = 0; i < arr.length; i++) {
59 | var m = 0;
60 | for (var j = 0; j < arr[i].length; j++) {
61 | if (this.page.getControlByName(arr[i][j])) {
62 | v = this.page.getControlByName(arr[i][j]).getValues();
63 | // A single-select textbox prompt is a special case.
64 | // If it is empty, getValues() returns an array with one element:
65 | // [{"use":null,"display":null}]
66 | if (v.length == 1 && (v[0].use == "" || v[0].use == undefined) && (v[0].display == null || v[0].display == "" || v[0].display == undefined)) {
67 | }
68 | else if (v.length > 0) {
69 | m++;
70 | }
71 | }
72 | }
73 | if (m == j) {
74 | valid = true;
75 | break;
76 | }
77 | }
78 | return valid;
79 | };
80 |
81 | this.RequiredPromptCountValidator = function (n) {
82 | var m = 0; // How many prompts have values?
83 | var v; // prompt values
84 |
85 | if (n < 1) return true; // No prompts are required. Why use this feature?
86 |
87 | for (var i = 0; i < this.Prompts.length && m < n; i++) {
88 | if (this.Prompts[i].name.substr(0, 4) == 'oper') {
89 | // this is an operator selector
90 | // don't count this in fulfilling a minimum number of parameters
91 | }
92 | else {
93 | v = this.Prompts[i].getValues();
94 | // A single-select textbox prompt is a special case.
95 | // If it is empty, getValues() returns an array with one element:
96 | // [{"use":null,"display":null}]
97 | if (v.length == 1 && v[0].use == null && v[0].display == null) {
98 | }
99 | else if (v.length > 0) {
100 | m++;
101 | }
102 | }
103 | }
104 |
105 | return m >= n;
106 | };
107 |
108 | this.CompletePromptInit = function (s) {
109 | var done = false;
110 | var p;
111 |
112 | log("CompletePromptInit", s);
113 |
114 | p = this.page.getControlByName(s)
115 |
116 | if (p) {
117 | p.setValues([{"use": undefined, "display": undefined}]);
118 | done = true;
119 | log("CompletePromptInit", "success");
120 | }
121 | else {
122 | done = false;
123 | log("CompletePromptInit", "failure");
124 | }
125 |
126 | return done;
127 | };
128 |
129 | this.CompletePrompt = function (s) {
130 | var done = false;
131 | var p;
132 |
133 | log("CompletePrompt", s);
134 |
135 | p = this.page.getControlByName(s)
136 |
137 | if (p) {
138 | p.setValues([{"use": "a", "display": "a"}]);
139 | done = true;
140 | log("CompletePrompt", "success");
141 | }
142 | else {
143 | done = false;
144 | log("CompletePrompt", "failure");
145 | }
146 |
147 | return done;
148 | };
149 |
150 | this.TakeAction = function () {
151 | var i = 0;
152 | var msg = "";
153 |
154 | if (this.oConfig && this.oConfig.RequiredPrompts) {
155 | if (this.RequiredPromptsValidator(this.oConfig.RequiredPrompts)) i++;
156 | else msg += "\r\n The required parameters were not specified.";
157 | }
158 | else {
159 | i++;
160 | }
161 |
162 | if (this.oConfig && this.oConfig.RequiredPromptCount) {
163 | if (this.RequiredPromptCountValidator(this.oConfig.RequiredPromptCount)) i++;
164 | else msg += "\r\n Not enough parameters were specified.";
165 | }
166 | else {
167 | i++;
168 | }
169 |
170 | if (this.oConfig && this.oConfig.HiddenPrompt) {
171 | if (this.CompletePrompt(this.oConfig.HiddenPrompt)) i++;
172 | else msg += "\r\n Prompt named " + this.oConfig.HiddenPrompt + " was not found or could not be set.";
173 | }
174 | else {
175 | i++;
176 | }
177 |
178 | if (i == 3) {
179 | // passed validation. take action
180 | switch (this.ButtonType.toLowerCase()) {
181 | case "finish":
182 | this.controlHost.finish()
183 | break;
184 | case "next":
185 | this.controlHost.next()
186 | break;
187 | case "back":
188 | this.controlHost.back()
189 | break;
190 | case "reprompt":
191 | this.controlHost.reprompt()
192 | break;
193 | case "cancel":
194 | this.controlHost.cancel()
195 | break;
196 | default:
197 | // error
198 | }
199 | }
200 | else {
201 | // failed validation. do nothing? alert the user? write to the console?
202 | log("Prompt Validation Failure", "Unable to use the " + this.ButtonType.toUpperCase() + " feature because prompt validation failed." + msg);
203 | if (this.failureAlert) alert(this.failureAlert);
204 | }
205 | };
206 |
207 | if (this.oConfig && this.oConfig.HiddenPrompt) {
208 | if (this.CompletePromptInit(this.oConfig.HiddenPrompt)) {
209 | }
210 | else {
211 | log("Prompt Validation Failure", "Unable to initialize.\r\n Prompt named " + this.oConfig.HiddenPrompt + " was not found or could not be set.");
212 | }
213 | }
214 |
215 | fnDoneInitializing();
216 | };
217 |
218 | Button.prototype.draw = function( oControlHost ) {
219 | log("Button", "Control.draw" );
220 |
221 | //var d = document.createElement("div");
222 | // d.className = "clsPromptComponent";
223 | // d.setAttribute("pt", "btn");
224 | var b = document.createElement("button");
225 | b.className = "bp";
226 | b.type = "button";
227 | b.onmouseover = function () {this.className = 'bp bph'};
228 | b.onmouseout = function () {this.className = 'bp'};
229 | b.onclick = this.TakeAction.bind(this);
230 | b.innerHTML = this.ButtonLabel;
231 | oControlHost.container.appendChild(b);
232 | //d.appendChild(b);
233 | //oControlHost.container.appendChild(d);
234 | };
235 |
236 | return Button;
237 | });
--------------------------------------------------------------------------------
/CognosScripts/PromptDateDefault.js:
--------------------------------------------------------------------------------
1 | define(function() {
2 | "use strict";
3 | /*
4 | Sets a date prompt to the value(s) returned by a query.
5 |
6 | The query may return a list of single dates or a list of start and end dates.
7 |
8 | Sample Configurations:
9 | {
10 | "PromptName": "PromptDate",
11 | "Date": "Date"
12 | }
13 | {
14 | "PromptName": "PromptDate",
15 | "StartDate": "StartDate",
16 | "EndDate": "EndDate"
17 | }
18 |
19 | The data store must contain columns with names that match the values for
20 | either Date or StartDate and EndDate.
21 | The date values must be in the format yyyy-mm-dd.
22 | */
23 |
24 | var log = function (label, message) {
25 | console.log(" **** " + label + " : " + message);
26 | };
27 |
28 | function DateDefault() {};
29 |
30 | DateDefault.prototype.initialize = function( oControlHost, fnDoneInitializing ) {
31 | log("DateDefault", "Control.initialize" );
32 |
33 | var o = oControlHost.configuration;
34 | var sPromptName = o && o["PromptName"] ? o["PromptName"] : null;
35 | var ctrl = oControlHost.page.getControlByName(sPromptName);
36 | var datastores = oControlHost.control.dataStores ? oControlHost.control.dataStores : null;
37 | var sDateColumn = o && o["Date"] ? o["Date"] : null;
38 | var sStartDateColumn = o && o["StartDate"] ? o["StartDate"] : null;
39 | var sEndDateColumn = o && o["EndDate"] ? o["EndDate"] : null;
40 | var bValid = true;
41 | var reDate = /^\d{4}-\d{2}-\d{2}$/;
42 | var iDateCol, iStartDateCol, iEndDateCol;
43 | var sDate, sStartDate, sEndDate;
44 | var sMsg = "";
45 |
46 |
47 | // check configuration
48 | if (!sPromptName) {
49 | bValid = false;
50 | sMsg += "Invalid Configuration: The name of the date prompt was not provided.";
51 | }
52 |
53 | if (!sDateColumn && !(sStartDateColumn || sEndDateColumn)) {
54 | bValid = false;
55 | sMsg += "Invalid Configuration: The name of either the date prompt or the startdate and enddate prompts are required.";
56 | }
57 |
58 | if (!ctrl) {
59 | bValid = false;
60 | sMsg += "Invalid configuration: ";
61 | if (o["PromptName"]) {
62 | sMsg += " There is not a prompt named '" + o["PromptName"] + "'.";
63 | }
64 | else {
65 | sMsg += " There is not a prompt named 'PromptDate' and no prompt name was provided in the configuration.";
66 | }
67 | }
68 |
69 | if (!datastores || datastores.length != 1) {
70 | bValid = false;
71 | sMsg += "Invalid configuration: The DateDefault custom control requires one data store.";
72 | }
73 |
74 | if (!bValid) {
75 | log("DateDefault", sMsg);
76 | return;
77 | }
78 |
79 | // check data store(s)
80 | var ds = datastores[0];
81 | var bDateFound = false;
82 | var bStartDateFound = false;
83 | var bEndDateFound = false;
84 |
85 | for (var i = 0; i < ds.columnNames.length; i++) {
86 | if (sDateColumn) {
87 | if (ds.columnNames[i] == sDateColumn) {
88 | iDateCol = i;
89 | bDateFound = true;
90 | break;
91 | }
92 | }
93 | else {
94 | if (ds.columnNames[i] == sStartDateColumn) {
95 | iStartDateCol = i;
96 | bStartDateFound = true;
97 | }
98 | if (ds.columnNames[i] == sEndDateColumn) {
99 | iEndDateCol = i;
100 | bEndDateFound = true;
101 | }
102 | if (bStartDateFound && bEndDateFound) break;
103 | }
104 | }
105 |
106 | bValid = (sDateColumn && bDateFound) || (!sDateColumn && bStartDateFound && bEndDateFound);
107 |
108 | if (!bValid) {
109 | log("DateDefault", "The date columns defined in the configurations were not found in the data store.");
110 | return;
111 | }
112 |
113 |
114 | // It's all good. Let's get the data and validate it.
115 | var vals = ds.columnValues;
116 | if (sDateColumn) {
117 | for (var i = 0; i < ds.rowCount; i++) {
118 | if (!vals[iDateCol][i].substr(0, 10).match(reDate)) {
119 | sMsg += "Invalid input: " + vals[iDateCol][i] + " is not a valid date.";
120 | bValid = false;
121 | break;
122 | }
123 | }
124 | }
125 | else {
126 | for (var i = 0; i < ds.rowCount; i++) {
127 | if (!vals[iStartDateCol][i].substr(0, 10).match(reDate)) {
128 | sMsg += "Invalid input: " + vals[iStartDateCol][i] + " is not a valid date.";
129 | bValid = false;
130 | break;
131 | }
132 | if (!vals[iEndDateCol][i].substr(0, 10).match(reDate)) {
133 | sMsg += "Invalid input: " + vals[iEndDateCol][i] + " is not a valid date.";
134 | bValid = false;
135 | break;
136 | }
137 | }
138 | }
139 |
140 | if (!bValid) {
141 | log("DateDefault", sMsg);
142 | return;
143 | }
144 |
145 |
146 | // Data's good. Build the array and add it to the control.
147 | var arrDates = [];
148 | if (sDateColumn) {
149 | for (var i = 0; i < ds.rowCount; i++) {
150 | arrDates.push({"use":vals[iDateCol][i].substr(0, 10)});
151 | }
152 | }
153 | else {
154 | for (var i = 0; i < ds.rowCount; i++) {
155 | arrDates.push({"start":{"use":vals[iStartDateCol][i].substr(0, 10)},"end":{"use":vals[iEndDateCol][i].substr(0, 10)}});
156 | }
157 | }
158 | oControlHost.page.getControlByName(sPromptName).setValues(arrDates);
159 |
160 |
161 | fnDoneInitializing();
162 | };
163 |
164 | DateDefault.prototype.draw = function( oControlHost )
165 | {
166 |
167 | };
168 |
169 | return DateDefault;
170 | });
171 |
172 |
173 | /*
174 | Simple values
175 | { 'use': '[a].[b].[c]', 'display': 'Canada' }
176 |
177 | Range values
178 | {
179 | 'start': {'use': '2007-01-01', 'display': 'January 1, 2007'}
180 | 'end': {'use': '2007-12-31', 'display': 'December 31, 2007'}
181 | }
182 |
183 | Multiple values
184 | [
185 | { 'use': '12', 'display': 'Canada' },
186 | { 'use': '41', 'display': 'Germany' },
187 | { 'use': '76', 'display': 'Japan' }
188 | ]
189 | */
--------------------------------------------------------------------------------
/CognosScripts/PromptFinish.js:
--------------------------------------------------------------------------------
1 | define( function() {
2 | "use strict";
3 |
4 | /*
5 | Sample Configuration:
6 | RequiredPrompts and RequiredPromptCount do not need to be used together.
7 | In this example, Country and City are optional prompts (and filters).
8 | Since this does not use prompt validation, requiring year is meaningless.
9 | Even if the Required property is Yes, it must still be specified in the
10 | configuration for the custom control. If it is not, a system-generated
11 | prompt page will appear after the user clicks on the custom prompt button.
12 |
13 | {
14 | "name": "FinnishButton",
15 | "buttonLabel": "Finish",
16 | "RequiredPrompts":
17 | [
18 | ["Country","Year"],
19 | ["City","Year"]
20 | ],
21 | "RequiredPromptCount":2
22 | }
23 | */
24 |
25 | var log = function (label, message) {
26 | console.log(" **** " + label + " : " + message);
27 | }
28 |
29 | function customFinish(){};
30 |
31 | customFinish.prototype.draw = function( oControlHost ) {
32 | //log("draw", "start");
33 | //this.m_sName = oControlHost.configuration.name || "FinishButton";
34 | this.msg = "";
35 |
36 | var o = oControlHost.configuration
37 | , buttonLabel = o["buttonLabel"] ? o["buttonLabel"] : 'Finish'
38 | , el = oControlHost.container;
39 |
40 | el.innerHTML = '' +
41 | '' ;
42 |
43 | document.getElementById("custom_PromptFinish").onmouseover = this.AddClass.bind (this, oControlHost, el.querySelector( "#custom_PromptFinish" ), "bph");
44 | document.getElementById("custom_PromptFinish").onmouseout = this.RemoveClass.bind (this, oControlHost, el.querySelector( "#custom_PromptFinish" ), "bph");
45 |
46 | document.getElementById("custom_PromptFinish").onclick = this.Finish.bind(this, oControlHost);
47 | //log("draw", "complete");
48 | };
49 |
50 | customFinish.prototype.Finish = function (oControlHost) {
51 | //log("Finish", "start");
52 |
53 | if (this.checkPrompts(oControlHost)) {
54 | oControlHost.finish();
55 | }
56 | else {
57 | alert(this.msg);
58 | }
59 | };
60 |
61 | customFinish.prototype.checkPrompts = function(oControlHost) {
62 | //log("checkPrompts", "start");
63 | var o = oControlHost.configuration;
64 |
65 | var blnGood = false;
66 |
67 | if (o.RequiredPrompts && o.RequiredPromptCount) {
68 | blnGood = this.RequiredPrompts(o.RequiredPrompts, oControlHost) && this.RequiredPromptCount(o.RequiredPromptCount, oControlHost);
69 | }
70 | else {
71 | if (o.RequiredPrompts) {
72 | blnGood = this.RequiredPrompts(o.RequiredPrompts, oControlHost);
73 | }
74 | if (o.RequiredPromptCount) {
75 | blnGood = this.RequiredPromptCount(o.RequiredPromptCount, oControlHost);
76 | }
77 | }
78 |
79 | return blnGood;
80 | };
81 |
82 | customFinish.prototype.RequiredPrompts = function (rp, oControlHost) {
83 | //log("RequiredPrompts", "start");
84 | var blnGood = false;
85 | // check the entire set
86 | // if any group is complete, we're done
87 | rp.forEach(function (arr) {
88 | // check each group
89 | if (!blnGood) {
90 | // reset the counter
91 | var rpc = 0;
92 | arr.forEach(function(sPromptName) {
93 | //log(" prompt", sPromptName);
94 | var oPrompt = oControlHost.page.getControlByName(sPromptName);
95 | if (!oPrompt) {
96 | alert(sPromptName + " was not found.");
97 | }
98 | else {
99 | //log(" prompt value", JSON.stringify(oPrompt.getValues()[0].use));
100 | rpc += (oPrompt.getValues()[0].use == undefined || oPrompt.getValues()[0].use == "") ? 0 : 1;
101 | }
102 | });
103 | // if the counter grew to the size of the array, we're good
104 | //log(" array length", arr.length);
105 | //log(" prompt count", rpc);
106 | if (arr.length == rpc) blnGood = true;
107 | }
108 | });
109 | //log("Required Prompts", blnGood);
110 | if (!blnGood) this.msg = "You must enter a valid combination of parameters."
111 | return blnGood;
112 | };
113 |
114 | customFinish.prototype.RequiredPromptCount = function (rpc, oControlHost) {
115 | //log("RequiredPromptCount", "start");
116 | //log(p.name, "");
117 | var blnGood = false;
118 | var i = 0;
119 | var a = oControlHost.page.getAllPromptControls();
120 | a.forEach(function(e) {
121 | //log(" Prompt Validation: Prompt" + e.name, JSON.stringify(e.getValues()));
122 | //log(" Prompt Validation: Prompt" + e.name, e.getValues()[0].use == undefined);
123 | i += e.getValues()[0].use == undefined ? 0 : 1;
124 | //log(" Prompt Validation: Prompt" + e.name, i);
125 | });
126 | //log("PromptCount", i);
127 | //log("RequiredPromptCount", rpc);
128 | blnGood = i >= rpc;
129 | //log("Required Prompt Count", blnGood);
130 | if (!blnGood) this.msg = "You must enter at least " + rpc + " parameters to proceed!";
131 | return blnGood;
132 | };
133 |
134 | customFinish.prototype.AddClass = function (oControlHost, o, c) {
135 | //log("AddClass", "start");
136 | if (this.checkPrompts(oControlHost)) {
137 | o.classList.add(c);
138 | }
139 | };
140 |
141 | customFinish.prototype.RemoveClass = function (oControlHost, o, c) {
142 | //log("RemoveClass", "start");
143 | o.classList.remove(c);
144 | };
145 |
146 | return customFinish;
147 | });
--------------------------------------------------------------------------------
/CognosScripts/PromptIncrementAndRun.js:
--------------------------------------------------------------------------------
1 | define( function() {
2 | "use strict";
3 |
4 | var log = function (label, message) {
5 | console.log(" **** " + label + " : " + message);
6 | };
7 |
8 | function Button() {
9 | };
10 |
11 |
12 | Button.prototype.initialize = function( oControlHost, fnDoneInitializing ) {
13 | /*
14 | Configuration:
15 | {
16 | "ButtonLabel": "Increment Day Number",
17 | "PromptName": "DayNumberPrompt"
18 | }
19 | */
20 |
21 | this.controlHost = oControlHost;
22 | this.oConfig = this.controlHost.configuration;
23 | this.page = this.controlHost.page;
24 | this.PromptName = ( this.oConfig && this.oConfig.PromptName ) ? this.oConfig.PromptName : "Prompt1";
25 | this.ButtonLabel = ( this.oConfig && this.oConfig.ButtonLabel ) ? this.oConfig.ButtonLabel : "Finish";
26 | this.Prompt = this.page.getControlByName(this.PromptName);
27 | this.DayNum = this.Prompt.getValues();
28 | // You may want to verify that DayNum is a number.
29 | // Here I just check to see if it is blank and set a default value if it is.
30 | if (typeof this.DayNum[0].use == "undefined") this.DayNum = [{"use": "1", "display": "1"}];
31 |
32 | this.TakeAction = function () {
33 | this.DayNum[0].use = ((this.DayNum[0].use * 1.0) + 1).toString();
34 | this.DayNum[0].display = ((this.DayNum[0].display * 1.0) + 1).toString();
35 | this.Prompt.setValues(this.DayNum);
36 | this.controlHost.finish();
37 | };
38 |
39 | fnDoneInitializing();
40 | };
41 |
42 | Button.prototype.draw = function( oControlHost ) {
43 | var b = document.createElement("button");
44 | b.className = "bp";
45 | b.type = "button";
46 | b.onmouseover = function () {this.className = 'bp bph'};
47 | b.onmouseout = function () {this.className = 'bp'};
48 | b.onclick = this.TakeAction.bind(this);
49 | b.innerHTML = this.ButtonLabel;
50 | oControlHost.container.appendChild(b);
51 | };
52 |
53 | return Button;
54 | });
55 |
--------------------------------------------------------------------------------
/CognosScripts/PromptLoadValuesFromQuery.js:
--------------------------------------------------------------------------------
1 | define( function() {
2 | "use strict";
3 |
4 | /*
5 | Add data sets to the control.
6 | Add one query item to Categories.
7 | Name the data set the same as the target prompt.
8 | Ensure the custom control appears after the prompt in the layout.
9 | The query output in the data set will appear in the prompt.
10 |
11 | Tested with multi-select textbox prompts.
12 | */
13 |
14 | var log = function (name, label, message) {
15 | console.log(" **** " + name + " : " + label + " : " + message);
16 | };
17 |
18 | var convertValues = function (valArray) {
19 | var a = [];
20 | valArray.forEach(function (n) {
21 | a.push({"use": n, "display": n});
22 | });
23 | return a;
24 | };
25 |
26 | function loadFromQuery(){};
27 |
28 |
29 | loadFromQuery.prototype.initialize = function( oControlHost, fnDoneInitializing ) {
30 | log(oControlHost.control.name, "initialize", "start");
31 |
32 | this.vals = [];
33 |
34 | fnDoneInitializing();
35 | log(oControlHost.control.name, "initialize", "complete");
36 | };
37 |
38 | loadFromQuery.prototype.draw = function( oControlHost ) {
39 | log(oControlHost.control.name, "draw", "start");
40 |
41 | var o = oControlHost.configuration;
42 | var oPage = oControlHost.page;
43 | for (var e in this.vals) {
44 | var oPrompt = oPage.getControlByName(this.vals[e].name);
45 | oPrompt.setValues(convertValues(this.vals[e].values));
46 | }
47 |
48 | log(oControlHost.control.name, "draw", "complete");
49 | };
50 |
51 | loadFromQuery.prototype.setData = function( oControlHost, oDataStore ) {
52 | log(oControlHost.control.name, "setData:" + oDataStore.name, "start");
53 |
54 | this.m_oDataStore = oDataStore;
55 | this.m_aData = [];
56 | var iRowCount = oDataStore.rowCount;
57 | for ( var iRow = 0; iRow < iRowCount; iRow++ ) {
58 | this.m_aData.push(oDataStore.getCellValue( iRow, 0 ));
59 | }
60 |
61 | if (this.m_aData.length) {
62 | this.m_aData.sort();
63 |
64 | var thisPrompt = {}
65 | thisPrompt.name = oDataStore.name;
66 | thisPrompt.values = this.m_aData.slice();
67 | this.vals.push(thisPrompt);
68 | }
69 |
70 | log(oControlHost.control.name, "setData:" + oDataStore.name, "complete");
71 | };
72 |
73 | return loadFromQuery;
74 | });
75 |
76 |
77 |
--------------------------------------------------------------------------------
/CognosScripts/README.md:
--------------------------------------------------------------------------------
1 | # CognosScripts
2 | This is where I put all of the JavaScript modules. On my Cognos server, this lives at wwwroot\CognosScripts.
3 |
4 | ## Prompts.js
5 | A page module that provides various ways to control prompt behaviours.
6 | **See the comments in the code for examples for the *Configuration* object for the Custom Control Module in Cognos.**
7 |
8 | ### PromptValues
9 | Set specific values.
10 | Cognos expects parameter values to be strings.
11 | #### PromptName
12 | The *Name* property of the prompt object.
13 | #### PromptValue
14 | The value(s)
15 | #### PromptRange
16 | The range of values
17 | #### PromptRelative
18 | For dates, choose values relative to today.
19 |
20 | ### PromptIndex
21 | (not yet implemented)
22 | Set values based on their location in the list.
23 | #### PromptName
24 | The *Name* property of the prompt object.
25 | #### PromptIndex
26 | The zero-based index of the item in the list, or a word like "first" or "last".
27 |
28 | ### SelectAll
29 | A list of prompt names for which all of the values in the prompt will be selected.
30 |
31 | ### AutoComplete
32 | Automatically complete this prompt page after automatically setting prompt values.
33 | Works with a Custom Control using *PromptAutoFinish.js*.
34 |
35 |
36 | ## PromptAutoFinish.js
37 | Custom Control module that works with Prompts.js to autofinish (autonext?) a prompt page.
38 |
39 | ## PromptFinish.js
40 | Custom Control module that handles RequiredPrompts and RequiredPromptCount. This is a different take on PromptButton.js, which may work better.
41 |
42 | ## PromptButton.js
43 | Custom Control module to create a prompt button. Includes prompt control method for RequiredPrompts and RequiredPromptCount.
44 |
45 | ## PromptDateDefault.js
46 | A way to use data rather than JavaScript to choose a set of default values for a date prompt. This is an alternative to the some of the features in Prompts.js.
47 |
48 | ## ParameterCapture.js
49 | Captures parameter name, prompt name, and selected parameter values for presentation using ParameterDisplay.js.
50 |
51 | ## ParameterDisplay.js
52 | For each prompt on any prompt page, displays the prompt name and selected values.
53 |
54 | ## ParamDisplay.js
55 | For each parameter, displays the parameter name and selected values.
56 |
57 | ## ObjectMethods.js
58 | A collection of additional object methods to make some scripting tasks simpler. Used by Prompts.js.
59 |
60 | ## HolidayCalendar.js
61 | Provides a HolidayCalendar object used by some methods of the Date object that are defined in ObjectMethods.js. Used by Prompt.js.
62 |
63 | ## HolidayCalendarControl.js
64 | Custom Control module to define the data set for the HolidayCalendar object in Prompts.js. Used as the module for a custom control that has one dataset with one category that contains the dates of holidays appropriate to the context of the report.
65 |
66 | ## mapOpenLayers.js
67 | Provides a means to present points on a map using a base map from OpenStreetMap or ArcGISOnline.
68 |
69 | ## OrderOfMethodsPageModule.js and OrderOfMethodsCustomControl.js
70 | Used to demonstrate when events occur in the Cognos JavaScript API.
71 |
72 | ## ParameterToText.js
73 | Parses the XML stored in the COGIPF_PARAMETER_VALUE_BLOB field for paramValue records and makes them human-readable for reporting.
74 |
75 | ## cleanParams.js
76 | Used by ParameterToText.js to return the human-readable text.
77 |
78 | ## xml2json.js
79 | Used by ParameterToText.js to turn the XML into a JSON string.
80 |
81 | ## json2xml.js
82 | Not used yet. It's the inverse of xml2json.js.
83 |
84 | ## json.js
85 | Used by ParameterToText.js. Creates a JSON object only if one does not already exist. (for old browsers)
86 |
87 |
--------------------------------------------------------------------------------
/CognosScripts/cleanParams.js:
--------------------------------------------------------------------------------
1 | /*
2 | author: doug pulse
3 | created: 2016-05-13
4 | license: public domain
5 |
6 | input: object the results of running xml2json on databaseserver.IBMCognosAudit.COGIPF_PARAMETER.COGIPF_PARAMETER_VALUE_BLOB
7 |
8 | output: object something smaller -- only what we actually need from the original data
9 |
10 | purpose: When a report is run in IBM Cognos BI (10.2.1, 10.2.2, 11.0.2),
11 | the system optionally* stores parameter values in the
12 | COGIPF_PARAMETER_VALUE_BLOB column of the COGIPF_PARAMETER
13 | table in the Cognos Audit database (commonly named IBMCognosAudit).
14 | databaseserver.IBMCognosAudit.COGIPF_PARAMETER.COGIPF_PARAMETER_VALUE_BLOB
15 | All of the report parameters are included in the string,
16 | regardless of whether or not they are used. It is stored as
17 | ntext, but the data is xml. After converting the xml to json
18 | (see xml2json.js), the string can be used as input for this function.
19 | cleanParams() strips the parameter data down to only what was
20 | actually used when the report was run. It also dramatically
21 | simplifies the object, removing all of the Cognos-specific
22 | stuff that no Cognos admininstrator would ever find useful.
23 |
24 | * create a custom property in the advanced properties for the
25 | Report and Batch Report services:
26 | RSVP.PARAMETERS.LOG = true
27 | */
28 |
29 | function cleanParams (params) {
30 | var p = params.parameterValues.item;
31 | var o = new Object();
32 |
33 | // iterate through each of the parameters recorded in the data
34 | if (p.length > 1) {
35 | for (var i = 0; i < p.length; i++) {
36 | console.log(" " + i);
37 | // look for parameters that are actually used
38 | if (p[i]["bus:value"]["@SOAP-ENC:arrayType"] != "bus:parmValueItem[0]") {
39 | // the value should not have a 0
40 | // something like "bus:parmValueItem[1]"
41 | // the number defines the length of the array of values
42 | var name = p[i]["bus:name"]["#text"];
43 | var vals = p[i]["bus:value"]["item"];
44 | o[name] = [];
45 | var n = p[i]["bus:value"]["@SOAP-ENC:arrayType"].replace(/bus:parmValueItem\[/gi, "").replace(/]/gi, "");
46 | console.log(" " + n);
47 |
48 | if (n == 1) {
49 | if (vals["@xsi:type"] == "bus:boundRangeParmValueItem") {
50 | // in_range prompts are special:
51 | o[name].push({start: {display: vals["bus:start"]["bus:display"]["#text"], use: vals["bus:start"]["bus:use"]["#text"]}, "end": {display: vals["bus:end"]["bus:display"]["#text"], use: vals["bus:end"]["bus:use"]["#text"]}});
52 | }
53 | else {
54 | try {
55 | o[name].push({display: vals["bus:display"]["#text"], use: vals["bus:use"]["#text"]});
56 | }
57 | catch (e) {
58 | console.log(e.message);
59 | console.log(JSON.stringify(params));
60 | }
61 | }
62 | }
63 | else {
64 | for (var j = 0; j < n; j++) {
65 | console.log(" " + j);
66 | if (vals[j]["@xsi:type"] == "bus:boundRangeParmValueItem") {
67 | // in_range prompts are special:
68 | o[name].push({start: {display: vals[j]["bus:start"]["bus:display"]["#text"], use: vals[j]["bus:start"]["bus:use"]["#text"]}, end: {display: vals[j]["bus:end"]["bus:display"]["#text"], use: vals[j]["bus:end"]["bus:use"]["#text"]}});
69 | }
70 | else {
71 | try {
72 | o[name].push({display: vals[j]["bus:display"]["#text"], use: vals[j]["bus:use"]["#text"]});
73 | }
74 | catch (e) {
75 | console.log(e.message);
76 | console.log(JSON.stringify(params));
77 | }
78 | }
79 | }
80 | }
81 | }
82 | }
83 | }
84 | else {
85 | // there is only one parameter
86 | // look for parameters that are actually used
87 | if (p["bus:value"]["@SOAP-ENC:arrayType"] != "bus:parmValueItem[0]") {
88 | // the value should not have a 0
89 | // something like "bus:parmValueItem[1]"
90 | // the number defines the length of the array of values
91 | var name = p["bus:name"]["#text"];
92 | var vals = p["bus:value"]["item"];
93 | o[name] = [];
94 | var n = p["bus:value"]["@SOAP-ENC:arrayType"].replace(/bus:parmValueItem\[/gi, "").replace(/]/gi, "");
95 |
96 | if (n == 1) {
97 | if (vals["@xsi:type"] == "bus:boundRangeParmValueItem") {
98 | // in_range prompts are special:
99 | o[name].push({start: {display: vals["bus:start"]["bus:display"]["#text"], use: vals["bus:start"]["bus:use"]["#text"]}, "end": {display: vals["bus:end"]["bus:display"]["#text"], use: vals["bus:end"]["bus:use"]["#text"]}});
100 | }
101 | else {
102 | o[name].push({display: vals["bus:display"]["#text"], use: vals["bus:use"]["#text"]});
103 | }
104 | }
105 | else {
106 | for (var j = 0; j < n; j++) {
107 | if (vals[j]["@xsi:type"] == "bus:boundRangeParmValueItem") {
108 | // in_range prompts are special:
109 | o[name].push({start: {display: vals[j]["bus:start"]["bus:display"]["#text"], use: vals[j]["bus:start"]["bus:use"]["#text"]}, end: {display: vals[j]["bus:end"]["bus:display"]["#text"], use: vals[j]["bus:end"]["bus:use"]["#text"]}});
110 | }
111 | else {
112 | o[name].push({display: vals[j]["bus:display"]["#text"], use: vals[j]["bus:use"]["#text"]});
113 | }
114 | }
115 | }
116 | }
117 | }
118 |
119 | // return the cleaned parameter value data
120 | return o;
121 | }
122 |
--------------------------------------------------------------------------------
/CognosScripts/json2xml.js:
--------------------------------------------------------------------------------
1 | /* This work is licensed under Creative Commons GNU LGPL License.
2 |
3 | License: http://creativecommons.org/licenses/LGPL/2.1/
4 | Version: 0.9
5 | Author: Stefan Goessner/2006
6 | Web: http://goessner.net/
7 | */
8 | function json2xml(o, tab) {
9 | var toXml = function(v, name, ind) {
10 | var xml = "";
11 | if (v instanceof Array) {
12 | for (var i=0, n=v.length; i" : "/>";
25 | if (hasChild) {
26 | for (var m in v) {
27 | if (m == "#text")
28 | xml += v[m];
29 | else if (m == "#cdata")
30 | xml += "";
31 | else if (m.charAt(0) != "@")
32 | xml += toXml(v[m], m, ind+"\t");
33 | }
34 | xml += (xml.charAt(xml.length-1)=="\n"?ind:"") + "" + name + ">";
35 | }
36 | }
37 | else {
38 | xml += ind + "<" + name + ">" + v.toString() + "" + name + ">";
39 | }
40 | return xml;
41 | }, xml="";
42 | for (var m in o)
43 | xml += toXml(o[m], m, "");
44 | return tab ? xml.replace(/\t/g, tab) : xml.replace(/\t|\n/g, "");
45 | }
46 |
--------------------------------------------------------------------------------
/CognosScripts/xml2json.js:
--------------------------------------------------------------------------------
1 | /* This work is licensed under Creative Commons GNU LGPL License.
2 |
3 | License: http://creativecommons.org/licenses/LGPL/2.1/
4 | Version: 0.9
5 | Author: Stefan Goessner/2006
6 | Web: http://goessner.net/
7 |
8 | // 2016-05-13 doug pulse updated to handle xml input as string
9 | */
10 | function xml2json(xml, tab) {
11 | var X = {
12 | toObj: function(xml) {
13 | var o = {};
14 | if (xml.nodeType==1) { // element node ..
15 | if (xml.attributes.length) // element with attributes ..
16 | for (var i=0; i 1)
58 | o = X.escape(X.innerXml(xml));
59 | else
60 | for (var n=xml.firstChild; n; n=n.nextSibling)
61 | o["#cdata"] = X.escape(n.nodeValue);
62 | }
63 | }
64 | if (!xml.attributes.length && !xml.firstChild) o = null;
65 | }
66 | else if (xml.nodeType==9) { // document.node
67 | o = X.toObj(xml.documentElement);
68 | }
69 | else
70 | alert("unhandled node type: " + xml.nodeType);
71 | return o;
72 | },
73 | toJson: function(o, name, ind) {
74 | var json = name ? ("\""+name+"\"") : "";
75 | if (o instanceof Array) {
76 | for (var i=0,n=o.length; i 1 ? ("\n"+ind+"\t"+o.join(",\n"+ind+"\t")+"\n"+ind) : o.join("")) + "]";
79 | }
80 | else if (o == null)
81 | json += (name&&":") + "null";
82 | else if (typeof(o) == "object") {
83 | var arr = [];
84 | for (var m in o)
85 | arr[arr.length] = X.toJson(o[m], m, ind+"\t");
86 | json += (name?":{":"{") + (arr.length > 1 ? ("\n"+ind+"\t"+arr.join(",\n"+ind+"\t")+"\n"+ind) : arr.join("")) + "}";
87 | }
88 | else if (typeof(o) == "string")
89 | json += (name&&":") + "\"" + o.toString() + "\"";
90 | else
91 | json += (name&&":") + o.toString();
92 | return json;
93 | },
94 | innerXml: function(node) {
95 | var s = ""
96 | if ("innerHTML" in node)
97 | s = node.innerHTML;
98 | else {
99 | var asXml = function(n) {
100 | var s = "";
101 | if (n.nodeType == 1) {
102 | s += "<" + n.nodeName;
103 | for (var i=0; i";
107 | for (var c=n.firstChild; c; c=c.nextSibling)
108 | s += asXml(c);
109 | s += ""+n.nodeName+">";
110 | }
111 | else
112 | s += "/>";
113 | }
114 | else if (n.nodeType == 3)
115 | s += n.nodeValue;
116 | else if (n.nodeType == 4)
117 | s += "";
118 | return s;
119 | };
120 | for (var c=node.firstChild; c; c=c.nextSibling)
121 | s += asXml(c);
122 | }
123 | return s;
124 | },
125 | escape: function(txt) {
126 | return txt.replace(/[\\]/g, "\\\\")
127 | .replace(/[\"]/g, '\\"')
128 | .replace(/[\n]/g, '\\n')
129 | .replace(/[\r]/g, '\\r');
130 | },
131 | removeWhite: function(e) {
132 | e.normalize();
133 | for (var n = e.firstChild; n; ) {
134 | if (n.nodeType == 3) { // text node
135 | if (!n.nodeValue.match(/[^ \f\n\r\t\v]/)) { // pure whitespace text node
136 | var nxt = n.nextSibling;
137 | e.removeChild(n);
138 | n = nxt;
139 | }
140 | else
141 | n = n.nextSibling;
142 | }
143 | else if (n.nodeType == 1) { // element node
144 | X.removeWhite(n);
145 | n = n.nextSibling;
146 | }
147 | else // any other node
148 | n = n.nextSibling;
149 | }
150 | return e;
151 | }
152 | };
153 |
154 | if (typeof xml == "string") xml = parseXml(xml);
155 |
156 | if (xml.nodeType == 9) // document node
157 | xml = xml.documentElement;
158 | var json = X.toJson(X.toObj(X.removeWhite(xml)), xml.nodeName, "\t");
159 |
160 | return "{\n" + (tab ? json.replace(/\t/g, tab) : json.replace(/\t|\n/g, "")) + "\n}";
161 | }
162 |
163 | function parseXml(xml) {
164 | // 2016-05-13 doug pulse updated to handle error in IE without an alert
165 |
166 | var dom = null;
167 | if (window.DOMParser) {
168 | try {
169 | dom = (new DOMParser()).parseFromString(xml, "text/xml");
170 | }
171 | catch (e) { dom = null; }
172 | }
173 | else if (window.ActiveXObject) {
174 | try {
175 | dom = new ActiveXObject('Microsoft.XMLDOM');
176 | dom.async = false;
177 |
178 | if (!dom.loadXML(xml)) { // parse error ..
179 | //window.alert(dom.parseError.reason + dom.parseError.srcText);
180 | xml = "" + dom.parseError.reason + dom.parseError.srcText + "";
181 | dom.loadXML(xml);
182 | }
183 | }
184 | catch (e) { dom = null; }
185 | }
186 | else
187 | alert("cannot parse xml string!");
188 |
189 | return dom;
190 | }
191 |
--------------------------------------------------------------------------------
/ContentStore/ADSI.sql:
--------------------------------------------------------------------------------
1 | USE [master]
2 | GO
3 | EXEC master.dbo.sp_addlinkedserver @server = N'ADSI', @srvproduct=N'Active Directory Service Interfaces', @provider=N'ADSDSOObject', @datasrc=N'adsdatasource'
4 | EXEC master.dbo.sp_addlinkedsrvlogin @rmtsrvname=N'ADSI',@useself=N'False',@locallogin=NULL,@rmtuser=N'DOMAIN\USER',@rmtpassword='*********'
5 | GO
6 | EXEC master.dbo.sp_serveroption @server=N'ADSI', @optname=N'collation compatible', @optvalue=N'false'
7 | GO
8 | EXEC master.dbo.sp_serveroption @server=N'ADSI', @optname=N'data access', @optvalue=N'true'
9 | GO
10 | EXEC master.dbo.sp_serveroption @server=N'ADSI', @optname=N'dist', @optvalue=N'false'
11 | GO
12 | EXEC master.dbo.sp_serveroption @server=N'ADSI', @optname=N'pub', @optvalue=N'false'
13 | GO
14 | EXEC master.dbo.sp_serveroption @server=N'ADSI', @optname=N'rpc', @optvalue=N'false'
15 | GO
16 | EXEC master.dbo.sp_serveroption @server=N'ADSI', @optname=N'rpc out', @optvalue=N'false'
17 | GO
18 | EXEC master.dbo.sp_serveroption @server=N'ADSI', @optname=N'sub', @optvalue=N'false'
19 | GO
20 | EXEC master.dbo.sp_serveroption @server=N'ADSI', @optname=N'connect timeout', @optvalue=N'0'
21 | GO
22 | EXEC master.dbo.sp_serveroption @server=N'ADSI', @optname=N'collation name', @optvalue=null
23 | GO
24 | EXEC master.dbo.sp_serveroption @server=N'ADSI', @optname=N'lazy schema validation', @optvalue=N'false'
25 | GO
26 | EXEC master.dbo.sp_serveroption @server=N'ADSI', @optname=N'query timeout', @optvalue=N'0'
27 | GO
28 | EXEC master.dbo.sp_serveroption @server=N'ADSI', @optname=N'use remote collation', @optvalue=N'true'
29 | GO
30 | EXEC master.dbo.sp_serveroption @server=N'ADSI', @optname=N'remote proc transaction promotion', @optvalue=N'true'
31 | GO
--------------------------------------------------------------------------------
/ContentStore/BrokenShortcuts.sql:
--------------------------------------------------------------------------------
1 | ;
2 | with cte(
3 | PCMID,
4 | CMID,
5 | ReportName,
6 | ReportPath,
7 | done,
8 | RootNode
9 | ) as
10 | (
11 | select o.PCMID
12 | , o.CMID
13 | , n.NAME
14 | , cast(n.NAME as varchar(max))
15 | , 0
16 | , cast(n.NAME as varchar(max))
17 |
18 | from CMOBJECTS o
19 | inner join CMOBJNAMES n on n.CMID = o.CMID
20 | inner join CMCLASSES c on c.CLASSID = o.CLASSID
21 | inner join CMREFNOORD1 r on r.CMID = o.CMID
22 | inner join CMOBJECTS b on b.CMID = r.REFCMID
23 | inner join CMOBJECTS do on do.CMID = b.PCMID
24 | inner join CMOBJNAMES dn on dn.CMID = do.CMID
25 |
26 | where n.ISDEFAULT = 1
27 | and c.NAME in ('reportView', 'shortcut')
28 | and dn.NAME = 'Deleted Object Folder'
29 |
30 | union all
31 | select o.PCMID
32 | , o.CMID
33 | , cte.ReportName
34 | , cast(n.NAME + '/' + cte.ReportPath as varchar(max))
35 | , case when left(n.NAME, 8) = 'MyNamespace:' then 1 else 0 end
36 | , cast(n.NAME as varchar(max))
37 |
38 | from CMOBJECTS o
39 | inner join CMOBJNAMES n on n.CMID = o.CMID
40 | inner join cte cte on cte.PCMID = o.CMID
41 |
42 | where n.ISDEFAULT = 1
43 | and n.CMID != 0
44 | and cte.done = 0
45 | )
46 |
47 |
48 | select replace(c.ReportPath, c.RootNode, isnull(u.Name, c.RootNode)) as ReportPath
49 |
50 | from cte c
51 | left outer join (
52 | select a.OBJID
53 | , b.NAME
54 |
55 | from CMOBJPROPS1 a
56 | inner join CMOBJPROPS33 b on b.CMID = a.CMID
57 | ) u on u.OBJID = c.RootNode
58 |
59 | where (c.ReportPath like 'Team Content%'
60 | or c.ReportPath like 'MyNamespace:%')
61 |
62 | order by ReportPath
63 |
--------------------------------------------------------------------------------
/ContentStore/Capabilities.ps1:
--------------------------------------------------------------------------------
1 | $CognosEnvironment = Read-Host "Cognos Environment (P, Q, D):"
2 | switch($CognosEnvironment) {
3 | "P" {
4 | $dbServer = "ProdDBServer"
5 | $dbName = "ProdDBName"
6 | }
7 | "Q" {
8 | $dbServer = "QADBServer"
9 | $dbName = "QADBName"
10 | }
11 | "D" {
12 | $dbServer = "DevDBServer"
13 | $dbName = "DevDBName"
14 | }
15 | }
16 |
17 | $AuthenticationNamespace = "NamespaceName"
18 | $DomainName = "DomainName"
19 |
20 | "
21 |
22 |
23 |
24 | Getting data from the database.
25 | This may take a couple minutes.
26 |
27 |
28 |
29 | "
30 |
31 | $sqlquery = "
32 | declare @DirectoryNamespace varchar(128) = '$DirectoryNamespace'
33 | declare @DomainName varchar(255) = '$DomainName'
34 | ;
35 | with
36 | capabilities as (
37 | select cast(n.NAME as varchar(max)) as CapabilityPath
38 | , n.NAME
39 | , c.NAME as class
40 | , o.CMID
41 | , o.PCMID
42 | , o.DISABLED
43 |
44 | from CMOBJECTS o
45 | inner join CMOBJNAMES n on n.CMID = o.CMID
46 | inner join CMCLASSES c on c.CLASSID = o.CLASSID
47 |
48 | where n.ISDEFAULT = 1
49 | and c.NAME = 'capability'
50 | and n.NAME = 'Capability'
51 |
52 | union all
53 | select cast(cap.CapabilityPath + '/' + n.NAME as varchar(max))
54 | , n.NAME
55 | , c.NAME
56 | , o.CMID
57 | , o.PCMID
58 | , o.DISABLED
59 | from capabilities cap
60 | inner join CMOBJECTS o on o.PCMID = cap.CMID
61 | inner join CMOBJNAMES n on n.CMID = o.CMID
62 | inner join CMCLASSES c on c.CLASSID = o.CLASSID
63 |
64 | where n.ISDEFAULT = 1
65 | )
66 |
67 | select *
68 | into #capabilities
69 | from capabilities
70 | ;
71 | with
72 | capabilitypolicy as (
73 | select c.CapabilityPath
74 | , c.DISABLED
75 | , CONVERT(varchar(max), CONVERT(varbinary(max), p.POLICIES, 1), 2) as pol
76 | from #capabilities c
77 | inner join CMPOLICIES p on p.CMID = c.CMID
78 | ),
79 | cte (
80 | CapabilityPath,
81 | pol,
82 | l,
83 | pos,
84 | curr,
85 | valout
86 | ) as (
87 | -- Loop through the value 2 characters (1 hex value) at a time.
88 | -- Convert each value to ASCII.
89 | -- We'll replace anything small (non-printing characters) with LF to keep it simple.
90 | -- That may not be the best solution.
91 | select CapabilityPath
92 | , pol
93 | , len(pol) as l
94 | , 3 as pos
95 | , substring(pol, 1, 2) as curr
96 | , case
97 | when convert(int, convert(varbinary, '0x' + substring(pol, 1, 2), 1)) < 32 then char(10)
98 | else cast(cast(convert(binary(2), '0x' + substring(pol, 1, 2), 1) as char(1)) as varchar(max))
99 | end as valout
100 | from capabilitypolicy
101 | union all
102 | select CapabilityPath
103 | , pol
104 | , l
105 | , pos + 2 as pos
106 | , substring(pol, pos, 2) as curr
107 | , valout +
108 | case
109 | when convert(int, convert(varbinary, '0x' + substring(pol, pos, 2), 1)) < 32 then char(10)
110 | else cast(cast(convert(binary(2), '0x' + substring(pol, pos, 2), 1) as char(1)) as varchar(max))
111 | end as valout
112 | from cte
113 | where pos < l
114 | ),
115 | cte2 as (
116 | -- Rank to identify the final value.
117 | select *
118 | , rank() over (partition by CapabilityPath order by pos desc) as rnk
119 | from cte
120 | ),
121 | a as (
122 | -- We need only the results of the last step.
123 | select CapabilityPath
124 | , valout
125 | from cte2
126 | where rnk = 1
127 | ),
128 | q as (
129 | --select CapabilityPath
130 | --, ROW_NUMBER() over (partition by CapabilityPath order by CapabilityPath) as rownum -- not reliable because string_split doesn't guarantee order until SQL 2022
131 | ----, ROW_NUMBER() over (partition by CapabilityPath order by ordinal) as rownum -- Use with SQL 2022 or later
132 | --, value as val
133 | ----, substring(value, 11, 32) as val
134 | --from a
135 | -- cross apply string_split(valout, char(10)) -- not reliable because string_split doesn't guarantee order until SQL 2022
136 | -- --cross apply string_split(valout, char(10), 1) -- Use with SQL 2022 or later
137 |
138 | -- SQL Server 2012 does not have string_split()
139 | SELECT CapabilityPath
140 | , ROW_NUMBER() over (partition by CapabilityPath order by CapabilityPath) as rownum
141 | , Split.a.value('.', 'NVARCHAR(MAX)') val
142 | FROM (
143 | SELECT CapabilityPath
144 | , CAST('' +
145 | REPLACE(
146 | replace(
147 | replace(
148 | replace(
149 | replace(
150 | replace(
151 | valout, '`"', char(10)
152 | ), '<', char(10)
153 | ), '>', char(10)
154 | ), '&', char(10)
155 | ), '''', char(10)
156 | ), char(10), ''
157 | ) + '' AS XML
158 | ) AS String
159 | from a
160 | ) AS A
161 | CROSS APPLY String.nodes('/X') AS Split(a)
162 | )
163 |
164 | -- Using a temporary table here reduces run time from 88 seconds to 8 seconds.
165 | select *
166 | into #q
167 | from q
168 | OPTION (MAXRECURSION 0)
169 |
170 | ;
171 |
172 | with
173 | perms as (
174 | select perm
175 | from (
176 | values
177 | ('execute')
178 | , ('read')
179 | , ('setPolicy')
180 | , ('traverse')
181 | , ('write')
182 | ) v (perm)
183 | ),
184 | capabilityPerms as (
185 | -- Cognos roles
186 | select q.CapabilityPath
187 | , q.rownum
188 | , n.NAME
189 | from #q q
190 | inner join CMOBJNAMES n on n.CMID = cast(SUBSTRING(q.val, 3, CHARINDEX(':', q.val, 3) - 3) as int)
191 | inner join CMOBJECTS o on o.CMID = n.CMID
192 | inner join CMCLASSES c on c.CLASSID = o.CLASSID
193 | where q.val like '::%'
194 | and CHARINDEX(':', val, 3) > 0
195 | and n.ISDEFAULT = 1
196 | and c.NAME = 'role'
197 |
198 | -- Cognos groups? Cognos groups and users?
199 | union
200 | select q.CapabilityPath
201 | , q.rownum
202 | , SUBSTRING(val, 3, 400) as 'Name'
203 | from #q q
204 | where q.val like '::%'
205 | and CHARINDEX(':', val, 3) = 0
206 |
207 | -- AD groups and users?
208 | union
209 | select q.CapabilityPath
210 | , q.rownum
211 | , @DomainName + '\' + u.NAME
212 | from #q q
213 | inner join CMOBJNAMES n on n.NAME = q.val
214 | inner join cmobjprops33 u on u.CMID = n.CMID
215 | where n.NAME like @DirectoryNamespace + '%'
216 |
217 | -- permissions (setPolicy, execute, etc.)
218 | union
219 | select q.CapabilityPath
220 | , q.rownum
221 | , p.perm
222 | from #q q
223 | inner join perms p on q.val like '%' + p.perm + '%'
224 | ),
225 | executeStart as (
226 | select cp.CapabilityPath
227 | , cp.rownum
228 | , cp.NAME
229 | from capabilityPerms cp
230 | where cp.NAME = 'execute'
231 | ),
232 | readStart as (
233 | select cp.CapabilityPath
234 | , cp.rownum
235 | , cp.NAME
236 | from capabilityPerms cp
237 | where cp.NAME = 'read'
238 | ),
239 | setPolicyStart as (
240 | select cp.CapabilityPath
241 | , cp.rownum
242 | , cp.NAME
243 | from capabilityPerms cp
244 | where cp.NAME = 'setPolicy'
245 | ),
246 | traverseStart as (
247 | select cp.CapabilityPath
248 | , cp.rownum
249 | , cp.NAME
250 | from capabilityPerms cp
251 | where cp.NAME = 'traverse'
252 | ),
253 | writeStart as (
254 | select cp.CapabilityPath
255 | , cp.rownum
256 | , cp.NAME
257 | from capabilityPerms cp
258 | where cp.NAME = 'write'
259 | ),
260 | permClass as (
261 | select cp.CapabilityPath
262 | , cp.rownum
263 | , cp.NAME
264 | , es.rownum as executeStart
265 | , rs.rownum as readStart
266 | , ss.rownum as setPolicyStart
267 | , ts.rownum as traverseStart
268 | , ws.rownum as writeStart
269 | from capabilityPerms cp
270 | left outer join executeStart es on es.CapabilityPath = cp.CapabilityPath
271 | left outer join readStart rs on rs.CapabilityPath = cp.CapabilityPath
272 | left outer join setPolicyStart ss on ss.CapabilityPath = cp.CapabilityPath
273 | left outer join traverseStart ts on ts.CapabilityPath = cp.CapabilityPath
274 | left outer join writeStart ws on ws.CapabilityPath = cp.CapabilityPath
275 | )
276 |
277 | select c.CapabilityPath
278 | , case
279 | when pc.rownum between coalesce(pc.executeStart, 999) and coalesce(pc.readStart, pc.setPolicyStart, pc.traverseStart, pc.writeStart, 999)
280 | then 'execute'
281 | when pc.rownum between coalesce(pc.readStart, 999) and coalesce(pc.setPolicyStart, pc.traverseStart, pc.writeStart, 999)
282 | then 'read'
283 | when pc.rownum between coalesce(pc.setPolicyStart, 999) and coalesce(pc.traverseStart, pc.writeStart, 999)
284 | then 'setPolicy'
285 | when pc.rownum between coalesce(pc.traverseStart, 999) and coalesce(pc.writeStart, 999)
286 | then 'traverse'
287 | when pc.rownum between coalesce(pc.writeStart, 999) and 999
288 | then 'write'
289 | else 'inherited'
290 | end as permission
291 | , pc.NAME as PrincipalName
292 | from #capabilities c
293 | left outer join permClass pc on pc.CapabilityPath = c.CapabilityPath
294 | and pc.NAME not in (
295 | select perm
296 | from perms
297 | )
298 | --and pc.NAME = 'BI Administrators'
299 | order by 1, 2, 3
300 |
301 | drop table #q
302 | drop table #capabilities
303 | "
304 |
305 | $result = Invoke-Sqlcmd $sqlquery `
306 | -ServerInstance $dbServer `
307 | -Database $dbName `
308 | -MaxCharLength 1000000 `
309 | -ConnectionTimeout 10 `
310 | -QueryTimeout 600 `
311 | -TrustServerCertificate
312 |
313 | $l = $result.length
314 | $Capability = @()
315 | $i = 0
316 | $startTime = Get-Date
317 |
318 | foreach($row in $result) {
319 | $r = [PSCustomObject]@{}
320 | $r | Add-Member -MemberType NoteProperty -Name 'CapabilityPath' -Value $row.CapabilityPath
321 | $r | Add-Member -MemberType NoteProperty -Name 'permission' -Value $row.permission
322 | $r | Add-Member -MemberType NoteProperty -Name 'PrincipalName' -Value $row.PrincipalName
323 |
324 | $Capability += $r
325 |
326 | $i++
327 | $p = [int]($i * 100 / $l)
328 |
329 | $elapsed = ((Get-Date) - $startTime).TotalSeconds
330 | $remainingItems = $l - $i
331 | $averageItemTime = $elapsed / $i
332 |
333 | Write-Progress "Processing $l capabilities" `
334 | -Status "$i capabilities processed" `
335 | -PercentComplete $p `
336 | -SecondsRemaining ($remainingItems * $averageItemTime)
337 | }
338 |
339 |
340 | $f = Join-Path (Join-Path $env:USERPROFILE "Downloads") "Capabilities$CognosEnvironment.csv"
341 |
342 | $Capability | Export-Csv -Path $f -NoTypeInformation
343 | Start-Process -FilePath $f
344 |
--------------------------------------------------------------------------------
/ContentStore/CognosScheduleEmailRecients.sql:
--------------------------------------------------------------------------------
1 |
2 | create table #report (
3 | ReportId int,
4 | ReportName varchar(256),
5 | ReportPath varchar(4000)
6 | )
7 |
8 | create table #schedules (
9 | ScheduleId int,
10 | ObjectName varchar(256),
11 | ObjectPath varchar(4000),
12 | ReportId int
13 | )
14 |
15 | create table #ScheduleDelivery (
16 | CMID int,
17 | DELIVOPTIONS ntext,
18 | CAMID xml,
19 | Email xml
20 | )
21 |
22 | create table #CAMID (
23 | id int identity(1,1),
24 | CMID int,
25 | ReportName varchar(100),
26 | ReportPath varchar(500),
27 | SchedulePath varchar(500),
28 | CAMID xml
29 | )
30 |
31 | create table #Email (
32 | id int identity(1,1),
33 | CMID int,
34 | ReportName varchar(100),
35 | ReportPath varchar(500),
36 | SchedulePath varchar(500),
37 | Email xml
38 | )
39 |
40 | create table #output (
41 | id int identity(1,1),
42 | CMID int,
43 | ReportName varchar(100),
44 | ReportPath varchar(500),
45 | SchedulePath varchar(500),
46 | email varchar(100)
47 | )
48 |
49 | --================================================================================
50 | -- get locations of reports and report views
51 | ;
52 | with cte(PCMID,
53 | CMID,
54 | ReportId,
55 | ReportName,
56 | ReportPath,
57 | done,
58 | RootNode) as
59 |
60 | (
61 | select o.PCMID
62 | , n.CMID
63 | , n.CMID
64 | , n.NAME
65 | , cast(n.NAME as varchar(max))
66 | , 0
67 | , cast(n.NAME as varchar(max))
68 | from CMOBJECTS o
69 | inner join CMOBJNAMES n on n.CMID = o.CMID
70 | inner join CMCLASSES c on c.CLASSID = o.CLASSID
71 | where n.ISDEFAULT = 1
72 | and isdate(n.NAME) = 0
73 | and c.name in ('report')--, 'reportview')
74 |
75 | union all
76 | select o.PCMID
77 | , n.CMID
78 | , cte.ReportId
79 | , cte.ReportName
80 | , cast(n.NAME + '/' + cte.ReportPath as varchar(max))
81 | , case when left(n.NAME, 8) = 'AuthenticationNamespaceName:' then 1 else 0 end
82 | , cast(n.NAME as varchar(max))
83 | from CMOBJECTS o
84 | inner join CMOBJNAMES n on n.CMID = o.CMID
85 | inner join cte cte on cte.PCMID = n.CMID
86 | where n.ISDEFAULT = 1
87 | and n.CMID != 0
88 | and cte.done = 0
89 | )
90 |
91 | insert #report
92 | select c.ReportId
93 | , c.ReportName
94 | , replace(c.ReportPath, c.RootNode, isnull(u.Name, c.RootNode)) as ReportPath
95 | from cte c
96 | left outer join (
97 | select a.OBJID
98 | , b.NAME
99 |
100 | from CMOBJPROPS1 a
101 | inner join CMOBJPROPS33 b on b.CMID = a.CMID
102 | ) u on u.OBJID = c.RootNode
103 | where (c.ReportPath like 'Team Content%'
104 | or c.ReportPath like 'AuthenticationNamespaceName:%') -- "My Content"
105 | order by ReportPath
106 |
107 |
108 |
109 | --================================================================================
110 | -- get locations of schedules
111 | ;
112 | with cte(PCMID,
113 | CMID,
114 | ScheduleId,
115 | ObjectName,
116 | ObjectPath,
117 | done,
118 | RootNode,
119 | ReportId) as
120 |
121 | (
122 | select o.PCMID
123 | , n.CMID
124 | , n.CMID
125 | , n.NAME
126 | , cast(n.NAME as varchar(max))
127 | , 0
128 | , cast(n.NAME as varchar(max))
129 | , 0
130 | from CMOBJECTS o
131 | inner join CMOBJNAMES n on n.CMID = o.CMID
132 | inner join CMCLASSES c on c.CLASSID = o.CLASSID
133 | where n.ISDEFAULT = 1
134 | and c.name = 'schedule'
135 |
136 | union all
137 | select o.PCMID
138 | , n.CMID
139 | , cte.ScheduleId
140 | , cte.ObjectName
141 | , cast(n.NAME + '/' + cte.ObjectPath as varchar(max))
142 | , case when left(n.NAME, 8) = 'AuthenticationNamespaceName:' then 1 else 0 end
143 | , cast(n.NAME as varchar(max))
144 | , case
145 | when c.NAME in ('report', 'reportview') then o.CMID
146 | else cte.ReportId
147 | end
148 | from CMOBJECTS o
149 | inner join CMOBJNAMES n on n.CMID = o.CMID
150 | inner join CMCLASSES c on c.CLASSID = o.CLASSID
151 | inner join cte cte on cte.PCMID = n.CMID
152 | where n.ISDEFAULT = 1
153 | and n.CMID != 0
154 | and cte.done = 0
155 | )
156 |
157 | insert #schedules
158 | select c.ScheduleId
159 | , c.ObjectName
160 | , replace(c.ObjectPath, c.RootNode, isnull(u.Name, c.RootNode)) as ObjectPath
161 | , c.ReportId
162 | from cte c
163 | left outer join (
164 | select a.OBJID
165 | , b.NAME
166 |
167 | from CMOBJPROPS1 a
168 | inner join CMOBJPROPS33 b on b.CMID = a.CMID
169 | ) u on u.OBJID = c.RootNode
170 | where c.ObjectPath like 'Team Content%'
171 | or c.ObjectPath like 'AuthenticationNamespaceName:%'
172 | order by ObjectPath
173 |
174 |
175 |
176 | --================================================================================
177 | -- get delivery info as xml
178 | insert #ScheduleDelivery
179 | select CMID
180 | , DELIVOPTIONS
181 | , cast(case
182 | when cast(DELIVOPTIONS as varchar(max)) like '%to;%'
183 | then replace(replace(SUBSTRING(cast(DELIVOPTIONS as varchar(max)), CHARINDEX('', cast(DELIVOPTIONS as varchar(max)), CHARINDEX('', cast(DELIVOPTIONS as varchar(max)), CHARINDEX('true%'
196 |
197 |
198 |
199 | --================================================================================
200 |
201 | insert #CAMID
202 | select sd.CMID
203 | , r.ReportName
204 | , r.ReportPath
205 | , s.ObjectPath
206 | , sd.CAMID
207 | from #ScheduleDelivery sd
208 | inner join #schedules s on s.ScheduleId = sd.CMID
209 | inner join #report r on r.ReportId = s.ReportId
210 | where cast(sd.CAMID as varchar(max)) <> ''
211 |
212 | insert #Email
213 | select sd.CMID
214 | , r.ReportName
215 | , r.ReportPath
216 | , s.ObjectPath
217 | , sd.Email
218 | from #ScheduleDelivery sd
219 | inner join #schedules s on s.ScheduleId = sd.CMID
220 | inner join #report r on r.ReportId = s.ReportId
221 | where cast(sd.Email as varchar(max)) <> ''
222 |
223 |
224 | declare @maxId int
225 | select @maxId = max(id)
226 | from #CAMID
227 |
228 | declare @i int
229 | set @i = 1
230 |
231 | declare @CMID int
232 | declare @ReportName varchar(100)
233 | declare @ReportPath varchar(500)
234 | declare @SchedulePath varchar(500)
235 | declare @arrlen int
236 |
237 | declare @x xml
238 | declare @xOut varchar(128)
239 |
240 |
241 | while @i <= @maxId
242 | begin
243 | select @CMID = CMID
244 | , @ReportName = ReportName
245 | , @ReportPath = ReportPath
246 | , @SchedulePath = SchedulePath
247 | , @x = CAMID
248 | from #CAMID n
249 | where id = @i
250 |
251 | insert #output
252 | select x.cmid
253 | , rn
254 | , rp
255 | , sp
256 | , b.NAME
257 | from (
258 | select @CMID as cmid
259 | , @ReportName as rn
260 | , @ReportPath as rp
261 | , @SchedulePath as sp
262 | , replace(replace(pd.value('text()[1]', 'varchar(128)'), 'CAMID("', ''), '")', '') as camid
263 | from @x.nodes('//value') as x(Rec)
264 | cross apply @x.nodes('//value/item') as i(pd)
265 | ) x
266 | inner join CMOBJPROPS1 a on a.OBJID = x.camid
267 | inner join CMOBJPROPS33 b on b.CMID = a.CMID
268 |
269 | set @i = @i + 1
270 | end
271 |
272 |
273 |
274 | select @maxId = max(id)
275 | from #Email
276 |
277 | set @i = 1
278 |
279 | while @i <= @maxId
280 | begin
281 | select @CMID = CMID
282 | , @ReportName = ReportName
283 | , @ReportPath = ReportPath
284 | , @SchedulePath = SchedulePath
285 | , @x = Email
286 | from #Email n
287 | where id = @i
288 |
289 | insert #output
290 | select @CMID
291 | , @ReportName
292 | , @ReportPath
293 | , @SchedulePath
294 | , pd.value('text()[1]', 'varchar(128)')
295 | from @x.nodes('//value') as x(Rec)
296 | cross apply @x.nodes('//value/item') as i(pd)
297 |
298 | set @i = @i + 1
299 | end
300 |
301 |
302 | select *
303 | from #output
304 |
305 |
306 | drop table #report
307 | drop table #schedules
308 | drop table #ScheduleDelivery
309 | drop table #CAMID
310 | drop table #Email
311 | drop table #output
312 |
--------------------------------------------------------------------------------
/ContentStore/LocateSchedules.sql:
--------------------------------------------------------------------------------
1 | -- get locations of schedules
2 | ;
3 | with cte(PCMID,
4 | CMID,
5 | ScheduleId,
6 | ObjectName,
7 | ObjectPath,
8 | done,
9 | RootNode,
10 | Modified,
11 | ReportId) as
12 | (
13 | select o.PCMID
14 | , n.CMID
15 | , n.CMID
16 | , n.NAME
17 | , cast(n.NAME as varchar(max))
18 | , 0
19 | , cast(n.NAME as varchar(max))
20 | , o.MODIFIED
21 | , 0
22 | from CMOBJECTS o
23 | inner join CMOBJNAMES n on n.CMID = o.CMID
24 | inner join CMCLASSES c on c.CLASSID = o.CLASSID
25 | where n.ISDEFAULT = 1
26 | and c.name = 'schedule'
27 |
28 | union all
29 | select o.PCMID
30 | , n.CMID
31 | , cte.ScheduleId
32 | , cte.ObjectName
33 | , cast(n.NAME + '/' + cte.ObjectPath as varchar(max))
34 | , case when left(n.NAME, 8) = 'MyNamespace:' then 1 else 0 end
35 | , cast(n.NAME as varchar(max))
36 | , cte.Modified
37 | , case
38 | when c.NAME in ('report', 'reportview', 'dataset2') then o.CMID
39 | else cte.ReportId
40 | end
41 | from CMOBJECTS o
42 | inner join CMOBJNAMES n on n.CMID = o.CMID
43 | inner join CMCLASSES c on c.CLASSID = o.CLASSID
44 | inner join cte cte on cte.PCMID = n.CMID
45 | where n.ISDEFAULT = 1
46 | and n.CMID != 0
47 | and cte.done = 0
48 | )
49 |
50 | select c.ScheduleId
51 | , c.ObjectName
52 | , c.Modified
53 | , c.ObjectPath
54 | , c.ReportId
55 | , c.RootNode
56 | into #schedules
57 | from cte c
58 | where c.ObjectPath like 'Team Content%'
59 | or c.ObjectPath like 'MyNamespace:%'
60 | order by ObjectPath
61 |
62 | select s.ReportId
63 | , replace(reverse(substring(reverse(s.ObjectPath), charindex('/', reverse(s.ObjectPath)) + 1, 4000)), s.RootNode, isnull(u.Name, s.RootNode)) as ObjectPath
64 | , case
65 | when schedtype.interval = 'trigger' then 'on trigger ' + t.SCHEDTRIGNAME
66 | else 'Every ' +
67 | cast(c.EVERYNPERIODS as varchar(5)) + ' ' +
68 | schedtype.interval +
69 | case
70 | when c.EVERYNPERIODS > 1 then 's'
71 | else ''
72 | end +
73 | case
74 | when schedtype.interval = 'hour' then ' between ' +
75 | format(
76 | CONVERT(
77 | datetime,
78 | SWITCHOFFSET(
79 | CONVERT(
80 | datetimeoffset,
81 | c.INTRARECURSTART
82 | ),
83 | DATENAME(
84 | TzOffset,
85 | SYSDATETIMEOFFSET()
86 | )
87 | )
88 | ),
89 | 'HH:mm:ss'
90 | ) +
91 | ' and ' +
92 | format(
93 | CONVERT(
94 | datetime,
95 | SWITCHOFFSET(
96 | CONVERT(
97 | datetimeoffset,
98 | c.INTRARECUREND
99 | ),
100 | DATENAME(
101 | TzOffset,
102 | SYSDATETIMEOFFSET()
103 | )
104 | )
105 | ),
106 | 'HH:mm:ss'
107 | ) + ' '
108 | when schedtype.interval = 'day' then ' '
109 | when schedtype.interval = 'year' then ' on day ' + cast(c.YEARLYABSDAY as varchar(5)) + ' of ' + DATENAME(month, DATEFROMPARTS(2020, c.YEARLYABSMONTH + 1, 1)) /*'month ' + cast(c.YEARLYABSMONTH as varchar(5))*/ + ' '
110 | else ' on ' +
111 | case
112 | when schedtype.interval = 'week' then
113 | case
114 | when c.WEEKLYMONDAY = 1 then 'monday '
115 | else ''
116 | end +
117 | case
118 | when c.WEEKLYTUESDAY = 1 then 'tuesday '
119 | else ''
120 | end +
121 | case
122 | when c.WEEKLYWEDNESDAY = 1 then 'wednesday '
123 | else ''
124 | end +
125 | case
126 | when c.WEEKLYTHURSDAY = 1 then 'thursday '
127 | else ''
128 | end +
129 | case
130 | when c.WEEKLYFRIDAY = 1 then 'friday '
131 | else ''
132 | end +
133 | case
134 | when c.WEEKLYSATURDAY = 1 then 'saturday '
135 | else ''
136 | end +
137 | case
138 | when c.WEEKLYSUNDAY = 1 then 'sunday '
139 | else ''
140 | end
141 | when schedtype.interval = 'month' then
142 | case
143 | when schedtype.typename = 'monthly by day of month' then 'day ' + cast(c.MONTHLYABSDAY as varchar(5)) + ' '
144 | when schedtype.typename = 'monthly by day of week' then daynames.name /*cast(c.MONTHLYRELDAY as varchar(5))*/ + ' of week ' + cast(c.MONTHLYRELWEEK + 1 as varchar(5)) + ' ' -- this isn't right
145 | else ''
146 | end
147 | else ''
148 | end
149 | end +
150 | 'at ' +
151 | format(
152 | CONVERT(
153 | datetime,
154 | SWITCHOFFSET(
155 | CONVERT(
156 | datetimeoffset,
157 | c.STARTDATE
158 | ),
159 | DATENAME(
160 | TzOffset,
161 | SYSDATETIMEOFFSET()
162 | )
163 | )
164 | ),
165 | case
166 | when schedtype.interval = 'hour' then 'mm'
167 | else 'HH:mm:ss'
168 | end
169 | )
170 | end as ScheduleDescription
171 | , format(
172 | CONVERT(
173 | datetime,
174 | SWITCHOFFSET(
175 | CONVERT(
176 | datetimeoffset,
177 | c.STARTDATE
178 | ),
179 | DATENAME(
180 | TzOffset,
181 | SYSDATETIMEOFFSET()
182 | )
183 | )
184 | ),
185 | 'HH:mm:ss'
186 | ) as StartTime
187 | into #reports
188 | from #schedules s
189 | inner join CMOBJPROPS2 c on c.CMID = s.ScheduleId
190 | left outer join CMOBJPROPS51 t on t.CMID = s.ScheduleId
191 | left outer join (values (2, 'monthly by day of week', 'month')
192 | , (1, 'monthly by day of month', 'month')
193 | , (4, 'weekly', 'week')
194 | , (0, 'daily', 'day')
195 | , (9, 'hourly', 'hour')
196 | , (7, 'triggered', 'trigger')
197 | , (5, 'yearly', 'year')
198 | ) schedtype (type, typename, interval) on schedtype.type = c.TYPE
199 | left outer join (
200 | select a.OBJID
201 | , b.NAME
202 |
203 | from CMOBJPROPS1 a
204 | inner join CMOBJPROPS33 b on b.CMID = a.CMID
205 | ) u on u.OBJID = s.RootNode
206 | left outer join (values (0, 'Sunday')
207 | , (1, 'Monday')
208 | , (2, 'Tuesday')
209 | , (3, 'Wednesday')
210 | , (4, 'Thursday')
211 | , (5, 'Friday')
212 | , (6, 'Saturday')
213 | ) daynames (num, name) on daynames.num = c.MONTHLYRELDAY
214 |
215 | order by format(
216 | CONVERT(
217 | datetime,
218 | SWITCHOFFSET(
219 | CONVERT(
220 | datetimeoffset,
221 | c.STARTDATE
222 | ),
223 | DATENAME(
224 | TzOffset,
225 | SYSDATETIMEOFFSET()
226 | )
227 | )
228 | ),
229 | 'HH:mm:ss'
230 | )
231 | , c.type
232 | , s.ObjectPath
233 |
234 |
235 |
236 | select pn.NAME as Package
237 | , r.ObjectPath as ReportPath
238 | , r.ScheduleDescription
239 | , r.StartTime
240 | --, r.ReportId
241 |
242 | from #reports r
243 | inner join CMREFNOORD1 ref on ref.CMID = r.ReportId
244 | inner join CMOBJECTS po on po.CMID = ref.REFCMID
245 | inner join CMOBJNAMES pn on pn.CMID = po.CMID
246 | inner join CMCLASSES pc on pc.CLASSID = po.CLASSID
247 |
248 | where pn.ISDEFAULT = 1
249 | and pc.NAME = 'package'
250 |
251 | order by Package
252 | , StartTime
253 |
254 |
255 |
256 | drop table #schedules
257 | drop table #reports
258 |
--------------------------------------------------------------------------------
/ContentStore/ModuleAndModelSpecs.sql:
--------------------------------------------------------------------------------
1 | use IBMCognos
2 | GO
3 | ;
4 |
5 | declare @DirectoryNamespace varchar(255) = 'MyNamespace'
6 | declare @DirectoryNamespaceLength int = 11
7 |
8 | -- data container full path
9 | -- ...for all packages, modules, uploaded files, and datasets
10 | ;
11 | with
12 | objname as (
13 | select o.CMID
14 | , coalesce(n2.name, n.NAME) as 'NAME'
15 | from CMOBJECTS o
16 | left outer join CMOBJNAMES n on n.CMID = o.CMID
17 | and n.LOCALEID = 92
18 | left outer join CMOBJNAMES n2 on n2.CMID = o.CMID
19 | and n2.LOCALEID = 118
20 | ),
21 | package (
22 | PCMID
23 | , CMID
24 | , ObjectId
25 | , ObjectName
26 | , ObjectPath
27 | , done
28 | , RootNode
29 | , ObjectType
30 | , ParentObjectType
31 | ) as (
32 | select o.PCMID
33 | , n.CMID
34 | , n.CMID
35 | , cast(n.NAME as varchar(550))
36 | , cast(n.NAME as varchar(max))
37 | , 0
38 | , cast(n.NAME as varchar(max))
39 | , c.NAME
40 | , cast(null as varchar(50))
41 | from CMOBJECTS o
42 | inner join objname n on n.CMID = o.CMID
43 | inner join CMCLASSES c on c.CLASSID = o.CLASSID
44 | --where c.name in ('package', 'module', 'uploadedFile', 'dataSet2')
45 | --where c.name in ('module', 'model')
46 | -- and n.NAME in ('! BigBudgetModule', 'May New data module')
47 | --where c.name = 'model'
48 |
49 | union all
50 | select o.PCMID
51 | , n.CMID
52 | , p.ObjectId
53 | , cast(
54 | case
55 | when p.ParentObjectType is null
56 | then
57 | case
58 | when c.NAME = 'folder'
59 | then p.ObjectName
60 | when c.NAME = 'package'
61 | then n.NAME
62 | when c.NAME = 'exploration'
63 | then n.NAME + '--' + p.ObjectName
64 | end
65 | else p.ObjectName
66 | end as varchar(550))
67 | , case
68 | when p.ParentObjectType is null and c.NAME = 'package'
69 | then cast(n.NAME as varchar(max))
70 | else cast(n.NAME + '/' + p.ObjectPath as varchar(max))
71 | end
72 | , case when left(n.NAME, @DirectoryNamespaceLength + 1) = @DirectoryNamespace + ':' then 1 else 0 end
73 | , cast(n.NAME as varchar(max))
74 | , p.ObjectType
75 | , case when p.ParentObjectType is null then c.NAME else p.ParentObjectType end
76 | from CMOBJECTS o
77 | inner join objname n on n.CMID = o.CMID
78 | inner join CMCLASSES c on c.CLASSID = o.CLASSID
79 | inner join package p on p.PCMID = n.CMID
80 | where n.CMID != 0
81 | and p.done = 0
82 | ),
83 | content as (
84 | -- There will be many paths for the same object.
85 | -- Keep only the path for each that starts at the root.
86 | select p.ObjectId
87 | , p.ObjectName
88 | , p.ObjectType
89 | , replace(replace(p.ObjectPath, p.RootNode, isnull(u.Name, p.RootNode)), '/(en) ', '/') as ObjectPath
90 | , p.ParentObjectType
91 |
92 | from package p
93 | left outer join (
94 | select a.OBJID
95 | , b.NAME
96 |
97 | from CMOBJPROPS1 a
98 | inner join CMOBJPROPS33 b on b.CMID = a.CMID
99 | ) u on u.OBJID = p.RootNode
100 | where (p.ObjectPath like 'Team Content%'
101 | or p.ObjectPath like @DirectoryNamespace + ':%')
102 | ),
103 | objprops86 as (
104 | select s.CMID
105 | , cast(s.CBASEDEF as varchar(max)) as CBASEDEF
106 | from CMOBJPROPS86 s
107 | ),
108 | zip as (
109 | select
110 | d.ObjectId
111 | , d.ObjectName
112 | , d.ObjectType
113 | , d.ParentObjectType
114 | , d.ObjectPath
115 | --, module.CBASEDEF AS CBASEDEF_BASE64
116 | , case d.ObjectType
117 | when 'module' then CAST('' AS XML).value('xs:base64Binary(sql:column("module.CBASEDEF"))', 'VARBINARY(MAX)')
118 | when 'model' then cast(model.cmodel as varbinary(max))
119 | end as CBASEDEF_COMPRESSED
120 | from content d
121 | left outer join objprops86 module on module.CMID = d.ObjectId
122 | left outer join CMOBJPROPS7 model on model.CMID = d.ObjectId
123 | )
124 |
125 | select
126 | ObjectId
127 | , ObjectName
128 | , ObjectType
129 | , ParentObjectType
130 | , ObjectPath
131 | --, CBASEDEF_BASE64
132 | , CBASEDEF_COMPRESSED
133 | --, cast(cbasedef_compressed as varchar(max)) as CBASEDEF_COMPRESSED_vc
134 | , CASE CAST(LEFT(CBASEDEF_COMPRESSED, 4) AS VARBINARY(MAX))
135 | WHEN 0x1F8B0800 THEN 'GZIP'
136 | WHEN 0x504B0304 THEN 'ZIP'
137 | END AS FILE_TYPE
138 | , CASE CAST(LEFT(CBASEDEF_COMPRESSED, 2) AS VARBINARY(MAX))
139 | WHEN 0x1F8B
140 | THEN CONVERT(VARCHAR(MAX), DECOMPRESS (CBASEDEF_COMPRESSED))
141 | WHEN 0x504B
142 | THEN 'TODO: UNZIP PKZIP BINARY'
143 | END as CBASEDEF_STRING
144 |
145 | into #outputs
146 |
147 | from zip
148 |
149 | order by ObjectPath
150 |
151 | /*
152 | model CMOBJPROPS7.CMODEL
153 | package (model contains spec)
154 | module CMOBJPROPS86.CBASEDEF
155 |
156 |
157 | TODO:
158 | unzip ZIP binary
159 | extract data source(s) from models (xml)
160 | extract data source(s) from modules (json)
161 |
162 | drop table #zip
163 |
164 | */
165 |
166 |
167 | /* ************************************************************************* */
168 | /* ************************************************************************* */
169 |
170 | /*
171 | Now let's go find all of the models that use specific data sources.
172 | */
173 | select o.ObjectId
174 | , o.ObjectName
175 | , o.ObjectPath
176 | , cast(o.CBASEDEF_STRING as xml) as CBASEDEF_STRING_x
177 | into #models
178 | from #outputs o
179 | where o.FILE_TYPE = 'GZIP'
180 | and o.ObjectType = 'model'
181 |
182 | ;
183 | WITH
184 | --XMLNAMESPACES ('http://www.developer.cognos.com/schemas/bmt/60/12' as ns)
185 | ----('http://www.developer.cognos.com/schemas/bmt/60/7' as ns) -- The version differs per object. Can we somehow ignore the xml namespace and still get results? *: to the rescue!
186 | --,
187 | models as (
188 | select o.ObjectId
189 | , o.ObjectPath
190 | --, model.datasource.value('ns:cmDataSource[1]', 'varchar(255)') as DataSource
191 | , model.datasource.value('*:cmDataSource[1]', 'varchar(255)') as DataSource -- *: namespace-unaware in XPath2.0 "This would not work with elements in the default namespace, though." - Rafael Winterhalter on SO
192 | --, model.datasource.value('*[local-name() = "cmDataSource"][1]', 'varchar(255)') as DataSource -- older xpath
193 | from #models o
194 | --cross apply o.CBASEDEF_STRING_x.nodes('/ns:project/ns:dataSources/ns:dataSource') as model(datasource)
195 | cross apply o.CBASEDEF_STRING_x.nodes('/*:project/*:dataSources/*:dataSource') as model(datasource)
196 | --cross apply o.CBASEDEF_STRING_x.nodes('/*[local-name() = "project"]/*[local-name() = "dataSources"]/*[local-name() = "dataSource"]') as model(datasource)
197 | )
198 | select *
199 | from models
200 | where DataSource in (
201 | 'My Data Source'
202 | , 'My Other Data Source'
203 | )
204 | order by 2, 3
205 |
206 | /* ************************************************************************* */
207 | /* ************************************************************************* */
208 |
209 |
210 | drop table #models
211 | drop table #outputs
212 |
--------------------------------------------------------------------------------
/ContentStore/ModulesAndPackages.ps1:
--------------------------------------------------------------------------------
1 | <#
2 | .SYNOPSIS
3 | Get specs (.xml and .json files) for packages and data modules.
4 |
5 | .DESCRIPTION
6 | Works for a Cognos Analytics content store on SQL Server
7 |
8 | .PARAMETER CSServerName
9 | Name of the database server where the Content Store lives.
10 |
11 | .PARAMETER CSDatabaseName
12 | Name of the Content Store database. Typically IBMCognos.
13 |
14 | .PARAMETER DirectoryNamespace
15 | Name of the external directory namespace. This is used for the paths of
16 | packages and data modules that are in My Content.
17 |
18 | .EXAMPLE
19 | .\ModulesAndPackages.ps1 "DatabaseServer" "IBMCognos" "DirectoryNamespace"
20 | #>
21 | [CmdletBinding()]
22 | param(
23 | [parameter(position=0, mandatory=$true)]
24 | [string]$CSServerName,
25 | [parameter(position=1, mandatory=$true)]
26 | [string]$CSDatabaseName,
27 | [parameter(position=2, mandatory=$true)]
28 | [string]$DirectoryNamespace
29 | )
30 |
31 | # $functions = Join-Path $env:USERPROFILE "repos\CognosAdmin\RESTAPI\fn.ps1"
32 | # . $functions
33 |
34 | $sqlquery = "
35 | declare @DirectoryNamespace varchar(255) = '$DirectoryNamespace'
36 | declare @DirectoryNamespaceLength int = 11
37 | -- data container full path
38 | -- ...for all packages, modules, uploaded files, and datasets
39 | ;
40 | with
41 | objname as (
42 | select o.CMID
43 | , coalesce(n2.name, n.NAME) as 'NAME'
44 | from CMOBJECTS o
45 | left outer join CMOBJNAMES n on n.CMID = o.CMID
46 | and n.LOCALEID = 92
47 | left outer join CMOBJNAMES n2 on n2.CMID = o.CMID
48 | and n2.LOCALEID = 118
49 | ),
50 | package (
51 | PCMID
52 | , CMID
53 | , ObjectId
54 | , ObjectName
55 | , ObjectPath
56 | , done
57 | , RootNode
58 | , ObjectType
59 | , ParentObjectType
60 | ) as (
61 | select o.PCMID
62 | , n.CMID
63 | , n.CMID
64 | , cast(n.NAME as varchar(550))
65 | , cast(n.NAME as varchar(max))
66 | , 0
67 | , cast(n.NAME as varchar(max))
68 | , c.NAME
69 | , cast(null as varchar(50))
70 | from CMOBJECTS o
71 | inner join objname n on n.CMID = o.CMID
72 | inner join CMCLASSES c on c.CLASSID = o.CLASSID
73 | --where c.name in ('package', 'module', 'uploadedFile', 'dataSet2')
74 | where c.name in ('module', 'model')
75 | -- and n.NAME in ('! BigBudgetModule', 'May New data module')
76 | --where c.name = 'model'
77 | -- and n.NAME = 'MS2 Validation'
78 |
79 | union all
80 | select o.PCMID
81 | , n.CMID
82 | , p.ObjectId
83 | , cast(
84 | case
85 | when p.ParentObjectType is null
86 | then
87 | case
88 | when c.NAME = 'folder'
89 | then p.ObjectName
90 | when c.NAME = 'package'
91 | then n.NAME
92 | when c.NAME = 'exploration'
93 | then n.NAME + '--' + p.ObjectName
94 | end
95 | else p.ObjectName
96 | end as varchar(550))
97 | , case
98 | when p.ParentObjectType is null and c.NAME = 'package'
99 | then cast(n.NAME as varchar(max))
100 | else cast(n.NAME + '/' + p.ObjectPath as varchar(max))
101 | end
102 | , case when left(n.NAME, @DirectoryNamespaceLength + 1) = @DirectoryNamespace + ':' then 1 else 0 end
103 | , cast(n.NAME as varchar(max))
104 | , p.ObjectType
105 | , case when p.ParentObjectType is null then c.NAME else p.ParentObjectType end
106 | from CMOBJECTS o
107 | inner join objname n on n.CMID = o.CMID
108 | inner join CMCLASSES c on c.CLASSID = o.CLASSID
109 | inner join package p on p.PCMID = n.CMID
110 | where n.CMID != 0
111 | and p.done = 0
112 | ),
113 | content as (
114 | -- There will be many paths for the same object.
115 | -- Keep only the path for each that starts at the root.
116 | select p.ObjectId
117 | , p.ObjectName
118 | , p.ObjectType
119 | , replace(replace(p.ObjectPath, p.RootNode, isnull(u.Name, p.RootNode)), '/(en) ', '/') as ObjectPath
120 | , p.ParentObjectType
121 |
122 | from package p
123 | left outer join (
124 | select a.OBJID
125 | , b.NAME
126 |
127 | from CMOBJPROPS1 a
128 | inner join CMOBJPROPS33 b on b.CMID = a.CMID
129 | ) u on u.OBJID = p.RootNode
130 | where (p.ObjectPath like 'Team Content%'
131 | or p.ObjectPath like @DirectoryNamespace + ':u:%')
132 | ),
133 | objprops86 as (
134 | select s.CMID
135 | , cast(s.CBASEDEF as varchar(max)) as CBASEDEF
136 | from CMOBJPROPS86 s
137 | ),
138 | zip as (
139 | select
140 | d.ObjectId
141 | , d.ObjectName
142 | , d.ObjectType
143 | , d.ParentObjectType
144 | , d.ObjectPath
145 | --, module.CBASEDEF AS CBASEDEF_BASE64
146 | , case d.ObjectType
147 | when 'module' then CAST('' AS XML).value('xs:base64Binary(sql:column(`"module.CBASEDEF`"))', 'VARBINARY(MAX)')
148 | when 'model' then cast(model.cmodel as varbinary(max))
149 | end as CBASEDEF_COMPRESSED
150 | from content d
151 | left outer join objprops86 module on module.CMID = d.ObjectId
152 | left outer join CMOBJPROPS7 model on model.CMID = d.ObjectId
153 | )
154 |
155 | select
156 | ObjectId
157 | , ObjectName
158 | , ObjectType
159 | , ParentObjectType
160 | , ObjectPath
161 | --, CBASEDEF_BASE64
162 | , CBASEDEF_COMPRESSED
163 | --, cast(cbasedef_compressed as varchar(max)) as CBASEDEF_COMPRESSED_vc
164 | , CASE CAST(LEFT(CBASEDEF_COMPRESSED, 4) AS VARBINARY(MAX))
165 | WHEN 0x1F8B0800 THEN 'GZIP'
166 | WHEN 0x504B0304 THEN 'ZIP'
167 | END AS FILE_TYPE
168 | , CASE CAST(LEFT(CBASEDEF_COMPRESSED, 2) AS VARBINARY(MAX))
169 | WHEN 0x1F8B
170 | THEN CONVERT(VARCHAR(MAX), DECOMPRESS (CBASEDEF_COMPRESSED))
171 | WHEN 0x504B
172 | THEN 'TODO: UNZIP PKZIP BINARY'
173 | END as CBASEDEF_STRING
174 |
175 | --into #outputs
176 |
177 | from zip
178 |
179 | order by ObjectPath"
180 |
181 | Write-Host "
182 |
183 |
184 |
185 | starting
186 | "
187 |
188 | $result = Invoke-Sqlcmd -Query $sqlquery `
189 | -ServerInstance $CSServerName `
190 | -Database $CSDatabaseName `
191 | -MaxCharLength 25000000 `
192 | -ConnectionTimeout 10 `
193 | -QueryTimeout 600 `
194 | -TrustServerCertificate
195 |
196 | Write-Host "got data... continuing"
197 |
198 | $zipPath = Join-Path $env:USERPROFILE "temp.zip"
199 | $zipFolderPath = Join-Path $env:USERPROFILE "temp"
200 | $basePath = Join-Path $env:USERPROFILE "CognosModules"
201 |
202 | $basePath | Get-ChildItem -Recurse | Remove-Item -Recurse
203 |
204 | # $modules = @()
205 | $l = $result.length
206 | $i = 0
207 | $startTime = Get-Date
208 |
209 | $modulesToUnzip = 0
210 | $modulesUnzipped = 0
211 |
212 | # Write-Host "starting loop
213 |
214 | # "
215 |
216 | foreach ($row in $result) {
217 | # Write-Host $row.ObjectName
218 |
219 | # $r = [PSCustomObject]@{}
220 | if ($row.ObjectPath -like "Team Content/*") {
221 | $objPath = $row.ObjectPath
222 | # $r | Add-Member -MemberType NoteProperty -Name 'ObjectPath' -Value $row.ObjectPath
223 | }
224 | else {
225 | $objPath = Join-Path "My Content" $row.ObjectPath
226 | # $r | Add-Member -MemberType NoteProperty -Name 'ObjectPath' -Value $objPath
227 | }
228 | # $r | Add-Member -MemberType NoteProperty -Name 'ObjectType' -Value $row.ObjectType
229 | # $r | Add-Member -MemberType NoteProperty -Name 'FileType' -Value $row.FILE_TYPE
230 | # $r | Add-Member -MemberType NoteProperty -Name 'CBASEDEF_COMPRESSED' -Value $row.CBASEDEF_COMPRESSED
231 |
232 | if ($row.CBASEDEF_STRING -eq "TODO: UNZIP PKZIP BINARY") {
233 | # Write-Host " unzipping"
234 | $modulesToUnzip++
235 | $binary = $row.CBASEDEF_COMPRESSED
236 | $binary | Set-Content -Path $zipPath -AsByteStream
237 | try {
238 | # Write-Host " expanding"
239 | Expand-Archive -Path $zipPath -DestinationPath $zipFolderPath
240 | # Write-Host " expanded"
241 | $files = Get-ChildItem -Path $zipFolderPath
242 | $baseDef = Get-Content $files.FullName
243 | Remove-Item -Path $zipFolderPath -Recurse
244 | $modulesUnzipped++
245 | }
246 | catch {
247 | # Write-Host " failed to expand: $($row.ObjectPath)"
248 | $baseDef = ""
249 | }
250 |
251 | # $r | Add-Member -MemberType NoteProperty -Name 'CBASEDEF_STRING' -Value $baseDef
252 | }
253 | else {
254 | $baseDef = $row.CBASEDEF_STRING
255 | # $r | Add-Member -MemberType NoteProperty -Name 'CBASEDEF_STRING' -Value $row.CBASEDEF_STRING
256 | }
257 |
258 | if ($row.ObjectType -eq "module" -and $row.FILE_TYPE -eq "GZIP") {
259 | # $r | Add-Member -MemberType NoteProperty -Name 'FileExt' -Value ".json"
260 | $fileExt = ".json"
261 | # Depth defaults
262 | # ConvertFrom-Json = 1024
263 | # ConvertTo-Json = 2 (max = 100)
264 | $baseDef = $baseDef | ConvertFrom-Json | ConvertTo-Json -Depth 100
265 | }
266 | else {
267 | # $r | Add-Member -MemberType NoteProperty -Name 'FileExt' -Value ".xml"
268 | $fileExt = ".xml"
269 | $baseDef =$baseDef | Format-XML
270 | }
271 |
272 | # $modules += $r
273 |
274 | $relPath = "$($objPath)$($fileExt)"
275 | $filePath = Join-Path $basePath $relPath
276 | $folderPath = Split-Path $filePath
277 | # Write-Host " writing file"
278 | if (!(Test-Path $folderPath)) {
279 | # Write-Host " $folderPath does not exist"
280 | New-Item -ItemType Directory -Path $folderPath -Force
281 | }
282 | $baseDef | Out-File -FilePath $filePath
283 |
284 | $i++
285 | $p = [int]($i * 100 / $l)
286 |
287 | $elapsed = ((Get-Date) - $startTime).TotalSeconds
288 | $remainingItems = $l - $i
289 | $averageItemTime = $elapsed / $i
290 |
291 | Write-Progress "Processing $l modules" -Status "$i modules processed" -PercentComplete $p -SecondsRemaining ($remainingItems * $averageItemTime)
292 | }
293 |
294 | Write-Host "Total number of modules: $l"
295 | Write-Host "Modules to unzip: $modulesToUnzip"
296 | Write-Host "Modules successfully unzipped: $modulesUnzipped"
297 |
--------------------------------------------------------------------------------
/ContentStore/OutputSpecs.sql:
--------------------------------------------------------------------------------
1 | ;
2 | with cte2(CMID,
3 | ObjectName,
4 | ObjectPath,
5 | ObjectClass,
6 | Modified) as
7 | (
8 | select o.CMID
9 | , n.NAME
10 | , cast(
11 | replace(
12 | replace(
13 | replace(
14 | replace(
15 | replace(
16 | replace(
17 | replace(
18 | replace(
19 | replace(
20 | n.NAME, char(60), '' -- <
21 | ), char(62), '' -- >
22 | ), char(58), '' -- :
23 | ), char(34), '' -- quote
24 | ), char(47), '' -- /
25 | ), char(92), '' -- \
26 | ), char(124), '' -- |
27 | ), char(63), '' -- ?
28 | ), char(42), '' -- *
29 | ) as varchar(max))
30 | , cast(c.NAME as varchar(max))
31 | , o.MODIFIED
32 | from CMOBJECTS o
33 | inner join CMOBJNAMES n on n.CMID = o.CMID
34 | inner join CMCLASSES c on c.CLASSID = o.CLASSID
35 | where n.ISDEFAULT = 1
36 | and isdate(n.NAME) = 0
37 | and o.CMID = 2
38 |
39 | union all
40 | select o.CMID
41 | , n.NAME
42 | , cast(cte2.ObjectPath + '/' +
43 | replace(
44 | replace(
45 | replace(
46 | replace(
47 | replace(
48 | replace(
49 | replace(
50 | replace(
51 | replace(
52 | n.NAME, char(60), ''
53 | ), char(62), ''
54 | ), char(58), ''
55 | ), char(34), ''
56 | ), char(47), ''
57 | ), char(92), ''
58 | ), char(124), ''
59 | ), char(63), ''
60 | ), char(42), ''
61 | ) as varchar(max))
62 | , cast(c.NAME as varchar(max))
63 | , o.MODIFIED
64 | from CMOBJECTS o
65 | inner join CMOBJNAMES n on n.CMID = o.CMID
66 | inner join CMCLASSES c on c.CLASSID = o.CLASSID
67 | inner join cte2 cte2 on cte2.CMID = o.PCMID
68 | where n.ISDEFAULT = 1
69 | and n.CMID != 0
70 | )
71 |
72 | select REPLACE(c.ObjectPath,'/','\') + case when c.ObjectClass = 'exploration' then '.json' else '.xml' end as FilePath
73 | , s.SPEC as SPEC
74 | from cte2 c
75 | left join CMOBJPROPS7 s on s.CMID = c.CMID
76 | where c.ObjectClass in ('report', 'exploration', 'dataSet2')
77 | and c.ObjectPath like 'Team Content/Reports%'
--------------------------------------------------------------------------------
/ContentStore/OwnedObjects.sql:
--------------------------------------------------------------------------------
1 | -- objects owned by the selected user
2 | ;
3 | declare @DirectoryNamespace varchar(255) = '$AuthenticationNamespace'
4 | declare @username nvarchar(256) = N'username'
5 | ;
6 | with
7 | objname as (
8 | select o.CMID
9 | , coalesce(n2.name, n.NAME) as 'NAME'
10 | from CMOBJECTS o
11 | left outer join CMOBJNAMES n on n.CMID = o.CMID
12 | and n.LOCALEID = 92 -- en
13 | left outer join CMOBJNAMES n2 on n2.CMID = o.CMID
14 | and n2.LOCALEID = 118 -- en-us
15 | ),
16 | usr as (
17 | select u.CMID
18 | from CMOBJPROPS33 u
19 | where u.NAME = @username
20 | ),
21 | userobjects as (
22 | select o.CMID
23 | , o.MODIFIED
24 | , o.OWNER
25 | , n.NAME
26 | , c.NAME as Class
27 | , po.CMID as ParentCMID
28 | , po.OWNER as ParentOwner
29 | , pn.NAME as ParentName
30 | , pc.NAME as ParentClass
31 | from CMOBJECTS o
32 | inner join objname n on n.CMID = o.CMID
33 | inner join CMCLASSES c on c.CLASSID = o.CLASSID
34 | inner join CMREFNOORD2 n2 on n2.CMID = o.CMID
35 | inner join CMOBJECTS po on po.CMID = o.PCMID
36 | inner join objname pn on pn.CMID = po.CMID
37 | inner join CMCLASSES pc on pc.CLASSID = po.CLASSID
38 | inner join usr u on u.CMID = n2.REFCMID
39 | ),
40 | cte(
41 | PCMID,
42 | CMID,
43 | ObjectId,
44 | ObjectName,
45 | ObjectPath,
46 | done,
47 | RootNode,
48 | ObjectClass
49 | ) as (
50 | select o.PCMID
51 | , n.CMID
52 | , n.CMID
53 | , n.NAME
54 | , cast(n.NAME as varchar(max))
55 | , 0
56 | , cast(n.NAME as varchar(max))
57 | , c.NAME
58 | from CMOBJECTS o
59 | inner join objname n on n.CMID = o.CMID
60 | inner join CMCLASSES c on c.CLASSID = o.CLASSID
61 | inner join userobjects uo on uo.CMID = o.CMID
62 |
63 | union all
64 | select o.PCMID
65 | , n.CMID
66 | , cte.ObjectId
67 | , cte.ObjectName
68 | , cast(n.NAME + '/' + cte.ObjectPath as varchar(max))
69 | , case when left(n.NAME, 8) = @DirectoryNamespace + ':' then 1 else 0 end
70 | , cast(n.NAME as varchar(max))
71 | , cte.ObjectClass
72 | from CMOBJECTS o
73 | inner join objname n on n.CMID = o.CMID
74 | inner join cte cte on cte.PCMID = n.CMID
75 | where n.CMID != 0
76 | and cte.done = 0
77 | )
78 |
79 | select c.ObjectId
80 | , c.ObjectName
81 | , replace(c.ObjectPath, c.RootNode, isnull(u.Name, c.RootNode)) as ObjectPath
82 | , c.ObjectClass
83 | into #reports
84 | from cte c
85 | left outer join (
86 | select a.OBJID
87 | , b.NAME
88 |
89 | from CMOBJPROPS1 a
90 | inner join CMOBJPROPS33 b on b.CMID = a.CMID
91 | ) u on u.OBJID = c.RootNode
92 | where (c.ObjectPath like 'Team Content%'
93 | or c.ObjectPath like @DirectoryNamespace + ':%')
94 | order by ObjectPath
95 |
96 | select *
97 | from #reports
98 | order by ObjectPath
99 |
100 | drop table #reports
101 |
--------------------------------------------------------------------------------
/ContentStore/PackageReference.sql:
--------------------------------------------------------------------------------
1 | -- find data containers (packages, modules, uploaded files, and datasets) that are not used
2 | use IBMCognos
3 | GO
4 | /*
5 | Package Usage
6 | Are packages used? (by existing presentation outputs)
7 | */
8 | ;
9 | declare @DirectoryNamespace varchar(255) = 'MyNamespace'
10 | declare @DirectoryNamespaceLength int = 11
11 |
12 |
13 | -- output object full path
14 | -- ...for all reports and dashboards
15 | ;
16 | with
17 | objname as (
18 | select o.CMID
19 | , coalesce(n2.name, n.NAME) as 'NAME'
20 | --, n.NAME
21 | --, n2.NAME
22 | from CMOBJECTS o
23 | left outer join CMOBJNAMES n on n.CMID = o.CMID
24 | and n.LOCALEID = 92
25 | left outer join CMOBJNAMES n2 on n2.CMID = o.CMID
26 | and n2.LOCALEID = 118
27 | --order by 2
28 | ),
29 | report (PCMID,
30 | CMID,
31 | ObjectId,
32 | ObjectName,
33 | ObjectPath,
34 | PackageId,
35 | done,
36 | RootNode,
37 | ObjectType) as (
38 | -- reports
39 | select o.PCMID
40 | , n.CMID
41 | , n.CMID
42 | , n.NAME
43 | , cast(n.NAME as varchar(max))
44 | , r.REFCMID as PackageId
45 | , 0
46 | , cast(n.NAME as varchar(max))
47 | , c.NAME
48 | from CMOBJECTS o
49 | inner join objname n on n.CMID = o.CMID
50 | inner join CMCLASSES c on c.CLASSID = o.CLASSID
51 | inner join CMREFNOORD1 r on r.CMID = o.CMID -- to get package
52 | where c.name = 'report'
53 | --and n.NAME like '%deer%'
54 |
55 | union all
56 | -- dashboards
57 | select o.PCMID
58 | , n.CMID
59 | , n.CMID
60 | , n.NAME
61 | , cast(n.NAME as varchar(max))
62 | , r.REFCMID as PackageId
63 | , 0
64 | , cast(n.NAME as varchar(max))
65 | , c.NAME
66 | from CMOBJECTS o
67 | inner join objname n on n.CMID = o.CMID
68 | inner join CMCLASSES c on c.CLASSID = o.CLASSID
69 | inner join CMREFORD1 r on r.CMID = o.CMID -- to get package
70 | where c.name = 'exploration'
71 | --and n.NAME like '%daily spend%'
72 |
73 | union all
74 | -- parent folders
75 | select o.PCMID
76 | , n.CMID
77 | , r.ObjectId
78 | , r.ObjectName
79 | , cast(n.NAME + '/' + r.ObjectPath as varchar(max))
80 | , r.PackageId
81 | , case when left(n.NAME, @DirectoryNamespaceLength + 1) = @DirectoryNamespace + ':' then 1 else 0 end
82 | , cast(n.NAME as varchar(max))
83 | , r.ObjectType
84 | from CMOBJECTS o
85 | inner join objname n on n.CMID = o.CMID
86 | inner join report r on r.PCMID = n.CMID
87 | where n.CMID != 0
88 | and r.done = 0
89 | )
90 |
91 | -- There will be many paths for the same object.
92 | -- Keep only the path for each that starts at the root.
93 | select r.ObjectId
94 | , r.ObjectName
95 | , r.ObjectType
96 | , replace(replace(r.ObjectPath, r.RootNode, isnull(u.Name, r.RootNode)), '/(en) ', '/') as ObjectPath
97 | , r.PackageId
98 | into #output
99 | from report r
100 | left outer join (
101 | select a.OBJID
102 | , b.NAME
103 |
104 | from CMOBJPROPS1 a
105 | inner join CMOBJPROPS33 b on b.CMID = a.CMID
106 | ) u on u.OBJID = r.RootNode
107 | where (r.ObjectPath like 'Team Content%'
108 | or r.ObjectPath like @DirectoryNamespace + ':%')
109 | order by ObjectPath
110 | ;
111 |
112 | -- data container full path
113 | -- ...for all packages, modules, uploaded files, and datasets
114 | with
115 | objname as (
116 | select o.CMID
117 | , coalesce(n2.name, n.NAME) as 'NAME'
118 | --, n.NAME
119 | --, n2.NAME
120 | from CMOBJECTS o
121 | left outer join CMOBJNAMES n on n.CMID = o.CMID
122 | and n.LOCALEID = 92
123 | left outer join CMOBJNAMES n2 on n2.CMID = o.CMID
124 | and n2.LOCALEID = 118
125 | --order by 2
126 | ),
127 | package (PCMID,
128 | CMID,
129 | ObjectId,
130 | ObjectName,
131 | ObjectPath,
132 | done,
133 | RootNode,
134 | ObjectType) as (
135 | select o.PCMID
136 | , n.CMID
137 | , n.CMID
138 | , n.NAME
139 | , cast(n.NAME as varchar(max))
140 | , 0
141 | , cast(n.NAME as varchar(max))
142 | , c.NAME
143 | from CMOBJECTS o
144 | inner join objname n on n.CMID = o.CMID
145 | inner join CMCLASSES c on c.CLASSID = o.CLASSID
146 | where c.name in ('package', 'module', 'uploadedFile', 'dataSet2')
147 | --and n.NAME like '%factless%'
148 |
149 | union all
150 | select o.PCMID
151 | , n.CMID
152 | , p.ObjectId
153 | , p.ObjectName
154 | , cast(n.NAME + '/' + p.ObjectPath as varchar(max))
155 | , case when left(n.NAME, @DirectoryNamespaceLength + 1) = @DirectoryNamespace + ':' then 1 else 0 end
156 | , cast(n.NAME as varchar(max))
157 | , p.ObjectType
158 | from CMOBJECTS o
159 | inner join objname n on n.CMID = o.CMID
160 | inner join package p on p.PCMID = n.CMID
161 | where n.CMID != 0
162 | and p.done = 0
163 | )
164 |
165 | -- There will be many paths for the same object.
166 | -- Keep only the path for each that starts at the root.
167 | select p.ObjectId
168 | , p.ObjectName
169 | , p.ObjectType
170 | , replace(replace(p.ObjectPath, p.RootNode, isnull(u.Name, p.RootNode)), '/(en) ', '/') as ObjectPath
171 | into #data
172 | from package p
173 | left outer join (
174 | select a.OBJID
175 | , b.NAME
176 |
177 | from CMOBJPROPS1 a
178 | inner join CMOBJPROPS33 b on b.CMID = a.CMID
179 | ) u on u.OBJID = p.RootNode
180 | where (p.ObjectPath like 'Team Content%'
181 | or p.ObjectPath like @DirectoryNamespace + ':%')
182 | order by ObjectPath
183 | ;
184 |
185 |
186 | -- Identify all instances where a data container uses another data container.
187 | ;
188 | with
189 | subpackages as (
190 | select p.ObjectId as PackageId
191 | , p.ObjectPath as PackagePath
192 | , p.ObjectType as PackageType
193 | , sp.ObjectId as SubPackageId
194 | , sp.ObjectPath as SubPackagePath
195 | , sp.ObjectType as SubPackageType
196 | , 0 as depth
197 |
198 | from #data p
199 | left outer join CMREFORD1 ro on ro.CMID = p.ObjectId
200 | left outer join #data sp on sp.ObjectId = ro.REFCMID
201 |
202 | union all
203 | -- "packages" per data module
204 | select p.PackageId
205 | , p.PackagePath
206 | , p.PackageType
207 | , sp.ObjectId as SubPackageId
208 | , sp.ObjectPath as SubPackagePath
209 | , sp.ObjectType as SubPackageType
210 | , p.depth + 1
211 |
212 | from subpackages p
213 | inner join CMREFORD1 ro on ro.CMID = p.SubPackageId
214 | inner join #data sp on sp.ObjectId = ro.REFCMID
215 | where p.depth < 7 -- because of self-referencing data modules
216 |
217 | union all
218 | -- "packages" per dataset
219 | select p.PackageId
220 | , p.PackagePath
221 | , p.PackageType
222 | , sp.ObjectId as SubPackageId
223 | , sp.ObjectPath as SubPackagePath
224 | , sp.ObjectType as SubPackageType
225 | , p.depth + 1
226 |
227 | from subpackages p
228 | inner join CMREFNOORD1 rno on rno.CMID = p.PackageId
229 | inner join #data sp on sp.ObjectId = rno.REFCMID
230 | where p.depth < 7 -- because of self-referencing data modules
231 | )
232 |
233 | select distinct PackageId
234 | , PackagePath
235 | , PackageType
236 | , SubPackageId
237 | , SubPackagePath
238 | , SubPackageType
239 | into #subdata
240 | from subpackages
241 |
242 |
243 | --select *
244 | --from #subdata
245 | --where PackagePath like 'Team Content/Reports/Traffic Operations/South Central Traffic/Deer Signs/%'
246 | --order by PackageId
247 | --, SubPackageId
248 |
249 | -- Show all data containers
250 | -- Recursively attribute usage to subcontainers
251 | ;
252 | with
253 | scusage as (
254 | select distinct d.PackageId
255 | , d.PackagePath
256 | , d.PackageType
257 | --, d.SubPackageId
258 | --, d.SubPackagePath
259 | --, d.SubPackageType
260 | , o.ObjectId
261 | , o.ObjectName
262 | , o.ObjectPath
263 | , o.ObjectType
264 | , 0 as depth
265 | from #subdata d
266 | inner join #output o on o.PackageId = d.PackageId
267 |
268 | union all
269 | select sd.PackageId
270 | , sd.PackagePath
271 | , sd.PackageType
272 | , u.ObjectId
273 | , u.ObjectName
274 | , u.ObjectPath
275 | , u.ObjectType
276 | , u.depth + 1
277 | from #subdata sd
278 | inner join #subdata d on d.SubPackageId = sd.PackageId
279 | inner join scusage u on u.PackageId = d.PackageId
280 | where u.depth < 3
281 | )
282 |
283 | select distinct PackageId
284 | , PackagePath
285 | , PackageType
286 | , ObjectId
287 | , ObjectName
288 | , ObjectPath
289 | , ObjectType
290 | into #scusage
291 | from scusage
292 | order by PackagePath
293 | , ObjectPath
294 |
295 |
296 |
297 | -- Show all data containers and the output objects that use them.
298 | select *
299 | from #scusage
300 | order by PackagePath
301 | , ObjectPath
302 |
303 |
304 |
305 | -- Show all data containers that are not used by any output objects
306 | select distinct d.PackageId
307 | , d.PackagePath
308 | , d.PackageType
309 | from #subdata d
310 |
311 | except
312 | select u.PackageId
313 | , u.PackagePath as UnusedPackagePath
314 | , u.PackageType
315 | from #scusage u
316 |
317 | order by PackagePath
318 |
319 |
320 | /*
321 | drop table #data
322 | drop table #output
323 | drop table #subdata
324 | drop table #scusage
325 | */
326 |
--------------------------------------------------------------------------------
/ContentStore/PermissionsPerUser.sql:
--------------------------------------------------------------------------------
1 |
2 | declare @CognosUserName varchar(max) = 'Hyperion Collision Power User'
3 | declare @CognosUserType varchar(max) = 'group'
4 |
5 | declare @querystring nvarchar(max) = 'SELECT ''WSDOTAD:' + left(@CognosUserType, 1) + ':'' + convert(varchar(max), ObjectGUID, 2) as ObjectGUID
6 | FROM OpenQuery (
7 | ADSI,
8 | ''SELECT sAMAccountName, ObjectGUID
9 | FROM ''''LDAP://WSDOT.LOC/DC=WSDOT,DC=LOC''''
10 | WHERE objectClass = ''''' + @CognosUserType + '''''
11 | and sAMAccountName = ''''' + @CognosUserName + '''''
12 | ''
13 | ) A'
14 |
15 | declare @ObjectGUID table (
16 | ObjectGUID varchar(max)
17 | )
18 | insert into @ObjectGUID
19 | exec sp_executesql @querystring
20 |
21 | declare @pol table (
22 | CMID int,
23 | POLICIES varbinary(max)
24 | )
25 |
26 | declare @b64 table (
27 | id int identity(1,1) not null,
28 | cmid int,
29 | POLICIES varchar(max),
30 | PolicyReadable varchar(max)
31 | )
32 |
33 | declare @heirarchy table (
34 | CMID int,
35 | ObjectName varchar(max),
36 | ObjectPath varchar(max)
37 | )
38 |
39 | insert @pol
40 | select CMID
41 | , cast(POLICIES as varbinary(max)) as POLICIES
42 | from CMPOLICIES
43 | WHERE POLICIES IS NOT NULL
44 | --and cmid = 2525
45 | --and cmid = 2339
46 | ;
47 |
48 | insert @b64 (cmid, POLICIES)
49 | select cmid,
50 | cast('' as xml).value(
51 | 'xs:base64Binary(sql:column("@pol.POLICIES"))', 'varchar(max)'
52 | ) AS POLICIES
53 | from @pol
54 | ;
55 |
56 | with
57 | src (
58 | CMID,
59 | ObjectName,
60 | ObjectPath) as
61 | (
62 | select o.CMID
63 | , n.NAME
64 | , cast(n.NAME as varchar(max))
65 | from CMOBJECTS o
66 | inner join CMOBJNAMES n on n.CMID = o.CMID
67 | inner join CMCLASSES c on c.CLASSID = o.CLASSID
68 | where n.ISDEFAULT = 1
69 | and isdate(n.NAME) = 0
70 | and o.CMID = 2
71 |
72 | union all
73 | select o.CMID
74 | , n.NAME
75 | , cast(src.ObjectPath + '/' + n.NAME as varchar(max))
76 | from CMOBJECTS o
77 | inner join CMOBJNAMES n on n.CMID = o.CMID
78 | inner join CMCLASSES c on c.CLASSID = o.CLASSID
79 | inner join src on src.CMID = o.PCMID
80 | where n.ISDEFAULT = 1
81 | and n.CMID != 0
82 | )
83 | insert into @heirarchy
84 | select *
85 | from src
86 | ;
87 |
88 | declare @j int = 1
89 | declare @jMax int
90 | select @jMax = id
91 | from @b64
92 |
93 | while @j <= @jMax
94 | begin
95 | update @b64
96 | set PolicyReadable = dbo.udf_CognosPermissions(POLICIES)
97 | where id = @j
98 |
99 | set @j = @j + 1
100 | end
101 |
102 |
103 | select o.*
104 | , b.PolicyReadable
105 | from @heirarchy o
106 | inner join @b64 b on b.CMID = o.CMID
107 | inner join @ObjectGUID g on b.PolicyReadable like '%' + g.ObjectGUID + '%'
108 | order by ObjectPath
109 |
110 |
--------------------------------------------------------------------------------
/ContentStore/README.md:
--------------------------------------------------------------------------------
1 | # Cognos Content Store Database
2 | Cognos stores most content in this database.
3 |
4 | I use Microsoft SQL Server. Your mileage may vary.
5 |
6 | Hacking the Cognos Content Store database is not recommended. The correct, supported way to automate Cognos management tasks is by using the Cognos SDK.
7 |
8 | ### ContentStore.txt
9 |
10 | Listing and description of tables in the Content Store database. Found on Cognoise.com. Comments updated as new insights are realized.
11 |
12 | ### ContentStoreCMIDSearch.sql
13 |
14 | Listing and description of tables in the Content Store database. Found on Cognoise.com. Comments updated as new insights are realized.
15 | Limited and formatted specifically for searching for a specific CMID.
16 |
17 | ### CognosScheduleEmailRecipients.sql
18 |
19 | Lists email recipients for schedules.
20 |
21 | ### LocateSchedules.sql
22 |
23 | Outputs the path to each schedule.
24 |
25 | ### OutputSpecs.sql
26 |
27 | Output specifications for reports, dashboards, and data sets within Team Content with the folder structure seen in Cognos. This can be used as part of a routine to write to the file system.
28 |
29 | ### SpecBackup (folder)
30 |
31 | Output specifications for reports, dashboards, and data sets to the file system and push them to a source control repository.
32 |
33 | ### BrokenShortcuts.sql
34 |
35 | Find broken shortcuts and report views.
36 |
37 | ### OwnedObjects.sql
38 |
39 | See which objects a user owns.
40 |
41 | ### PackageReference.sql
42 |
43 | Identifies data containers (packages, data modules, etc.) and which presentation objects (reports, dashboards, etc.) use them.
44 | Also identifies data containers that are not used.
45 | Identifies where a data module uses a dataset that is populated from a data module that uses a dataset that uses a package (etc.)
46 | and attributes the usage (presentation object) to the parent data container.
47 | Whether or not the presentation objects have been used is a different question. This routine considers only object references, not usage stats from the Audit database.
48 |
49 | ### ModuleAndModelSpecs.sql
50 |
51 | Initially intended to allow a system-wide search for packages and models that use a specific data source.
52 |
53 | ### ModulesAndPackages.ps1
54 |
55 | Queries the Content Store and saves specs of packages and data modules to the file system. Includes prettifying the json or xml for easy diffs in source control.
56 | This script has trouble unzipping some PKZipped data. It reports the number of objects that require unzipping and the number of objects unzipped.
57 |
58 |
59 | ## Permissions
60 |
61 | ### SQL-Only
62 |
63 | #### PermissionsPerUser.sql
64 |
65 | Find everywhere that a user (or group) from Active Directory is defined in object permissions in Cognos.
66 |
67 | For objects that inherit permissions, POLICIES is NULL. These are not identified by this query.
68 |
69 | This query processes the CMPOLICIES.POLICIES value for all objects in the Content Store using two, nested functions, then performs the search (filter) on the results. It can take a very long time to run.
70 |
71 | Requires udf_CognosPermissions.sql and ADSI.sql.
72 |
73 | #### udf_CognosPermissions.sql
74 |
75 | Converts CMPOLICIES.POLICIES (image) to a human-readable string.
76 |
77 | Requires udf_ConvertFromBase10.sql
78 |
79 | #### udf_ConvertFromBase10.sql
80 |
81 | Converts a number in base 10 to a string (varchar(255)) containing the number in another number base.
82 |
83 | Used by udf_CognosPermissions to convert 64-bit encoded characters to binary.
84 |
85 | #### ADSI.sql
86 |
87 | Sets up the linked server to query Active Directory.
88 |
89 | From https://www.mssqltips.com/sqlservertip/2580/querying-active-directory-data-from-sql-server/
90 |
91 | Make sure you change the @rmtuser and @rmtpassword variables to a login and password that has access to your Active Directory.
92 |
93 | ### SQL and PowerShell
94 |
95 | If you can't create a linked server and a user-defined function,
96 | maybe you'll have the ability to look up the information using PowerShell.
97 |
98 | #### RoleGroupMembership.ps1
99 |
100 | Lists members of all Cognos roles.
101 |
102 | #### ObjectPermissions.ps1
103 |
104 | Lists what permissions users and groups have to each Cognos object within Team Content (CMID=2).
105 | Takes about 5 minutes to run. Our Content Store has about 190,000 rows in CMOBJECTS with about 7,300 objects within the scope of this script.
106 |
107 | #### ObjectCapabilities.ps1
108 |
109 | Lists what permissions (grant or deny) users and groups have to each capability for each Cognos object within Team Content (CMID=2).
110 | Takes about 5 minutes to run. Our Content Store has about 190,000 rows in CMOBJECTS with about 1,250 objects within the scope of this script.
111 |
--------------------------------------------------------------------------------
/ContentStore/RoleGroupMembership.ps1:
--------------------------------------------------------------------------------
1 | $CognosEnvironment = Read-Host "Cognos Environment (P, Q, D):"
2 | switch($CognosEnvironment) {
3 | "P" {
4 | $dbServer = "ProdDBServer"
5 | $dbName = "ProdDBName"
6 | }
7 | "Q" {
8 | $dbServer = "QADBServer"
9 | $dbName = "QADBName"
10 | }
11 | "D" {
12 | $dbServer = "DevDBServer"
13 | $dbName = "DevDBName"
14 | }
15 | }
16 |
17 | $AuthenticationNamespace = "NamespaceName"
18 |
19 | "
20 |
21 |
22 |
23 | Getting data from the database.
24 | This may take a couple minutes.
25 |
26 |
27 |
28 | "
29 |
30 | $sqlquery = "
31 | declare @DirectoryNamespace varchar(255) = '$AuthenticationNamespace'
32 | ;
33 | with
34 | objname as (
35 | select o.CMID
36 | , coalesce(n2.name, n.NAME) as 'NAME'
37 | from CMOBJECTS o
38 | left outer join CMOBJNAMES n on n.CMID = o.CMID
39 | and n.LOCALEID = 92 -- en
40 | left outer join CMOBJNAMES n2 on n2.CMID = o.CMID
41 | and n2.LOCALEID = 118 -- en-us
42 | ),
43 | rolegroup (
44 | CMID
45 | , ObjectName
46 | , ObjectPath
47 | , ObjectClass
48 | , done
49 | ) as (
50 | select o.CMID
51 | , n.NAME
52 | , cast(n.NAME as varchar(max))
53 | , cast(c.NAME as varchar(max))
54 | , 1
55 | from CMOBJECTS o
56 | inner join objname n on n.CMID = o.CMID
57 | inner join CMCLASSES c on c.CLASSID = o.CLASSID
58 | where n.NAME = 'Cognos'
59 | and c.NAME = 'namespace'
60 |
61 | union all
62 | select o.CMID
63 | , n.NAME
64 | , cast(rg.ObjectPath + '/' + n.NAME as varchar(max))
65 | , cast(c.NAME as varchar(max))
66 | , rg.done + 1
67 | from CMOBJECTS o
68 | inner join objname n on n.CMID = o.CMID
69 | inner join CMCLASSES c on c.CLASSID = o.CLASSID
70 | inner join rolegroup rg on rg.CMID = o.PCMID
71 | where n.CMID != 0
72 | and c.NAME in ('namespaceFolder', 'group', 'role')
73 | ),
74 | members as (
75 | select rg.CMID
76 | , rg.ObjectPath
77 | , rg.ObjectClass
78 | , coalesce(u.NAME, n.NAME) as MemberName
79 | , c.NAME as MemberClass
80 | , o.CMID as MemberCMID
81 | , case when c.NAME = 'group' and n.NAME like @DirectoryNamespace + ':g:%' then
82 | SUBSTRING(n.name, 17, 2) +
83 | SUBSTRING(n.name, 15, 2) +
84 | SUBSTRING(n.name, 13, 2) +
85 | SUBSTRING(n.name, 11, 2) +
86 | '-' +
87 | SUBSTRING(n.name, 21, 2) +
88 | SUBSTRING(n.name, 19, 2) +
89 | '-' +
90 | SUBSTRING(n.name, 25, 2) +
91 | SUBSTRING(n.name, 23, 2) +
92 | '-' +
93 | SUBSTRING(n.name, 27, 4) +
94 | '-' +
95 | SUBSTRING(n.name, 31, 12)
96 | end as MemberObjectGUID
97 | from rolegroup rg
98 | inner join CMREFORD1 r on r.CMID = rg.CMID
99 | inner join CMOBJECTS o on o.CMID = r.REFCMID
100 | inner join objname n on n.CMID = o.CMID
101 | inner join CMCLASSES c on c.CLASSID = o.CLASSID
102 | left outer join CMOBJPROPS33 u on u.CMID = o.CMID
103 | )
104 |
105 | select *
106 | from members
107 | order by ObjectPath
108 | "
109 |
110 | $result = Invoke-Sqlcmd $sqlquery `
111 | -ServerInstance $dbServer `
112 | -Database $dbName `
113 | -MaxCharLength 1000000 `
114 | -ConnectionTimeout 10 `
115 | -QueryTimeout 600 `
116 | -TrustServerCertificate
117 |
118 | $l = $result.length
119 | $i = 0
120 | $startTime = Get-Date
121 | $out = @()
122 |
123 | foreach($row in $result) {
124 | $o = $row.MemberObjectGUID
125 | if ($o.length -gt 1) {
126 | $filter = "ObjectGUID -eq `"$o`""
127 | $g = Get-ADGroup -Filter $filter
128 | if ($g) {
129 | $m = Get-ADGroupMember $g -Recursive
130 | foreach ($member in $m) {
131 | $r = [PSCustomObject]@{}
132 | $r | Add-Member -MemberType NoteProperty -Name 'ObjectPath' -Value $row.ObjectPath
133 | $r | Add-Member -MemberType NoteProperty -Name 'ObjectClass' -Value $row.ObjectClass
134 | $r | Add-Member -MemberType NoteProperty -Name 'MemberClass' -Value 'account'
135 | $r | Add-Member -MemberType NoteProperty -Name 'MemberName' -Value $member.Name
136 | $out += $r
137 | }
138 | }
139 | else {
140 | # group not found in MSAD
141 | $r = [PSCustomObject]@{}
142 | $r | Add-Member -MemberType NoteProperty -Name 'ObjectPath' -Value $row.ObjectPath
143 | $r | Add-Member -MemberType NoteProperty -Name 'ObjectClass' -Value $row.ObjectClass
144 | $r | Add-Member -MemberType NoteProperty -Name 'MemberClass' -Value $row.MemberClass
145 | $r | Add-Member -MemberType NoteProperty -Name 'MemberName' -Value $row.MemberName
146 | $out += $r
147 | }
148 | }
149 | else {
150 | # no ObjectGUID provided
151 | $r = [PSCustomObject]@{}
152 | $r | Add-Member -MemberType NoteProperty -Name 'ObjectPath' -Value $row.ObjectPath
153 | $r | Add-Member -MemberType NoteProperty -Name 'ObjectClass' -Value $row.ObjectClass
154 | $r | Add-Member -MemberType NoteProperty -Name 'MemberClass' -Value $row.MemberClass
155 | $r | Add-Member -MemberType NoteProperty -Name 'MemberName' -Value $row.MemberName
156 | $out += $r
157 | }
158 |
159 | $i++
160 | $p = [int]($i * 100 / $l)
161 | # $elapsed = ((Get-Date) - $startTime).TotalSeconds
162 | # $remainingItems = $l - $i
163 | # $averageItemTime = $elapsed / $i
164 | Write-Progress "Evaluating $l roles and groups" `
165 | -Status "$i evaluated" `
166 | -PercentComplete $p
167 | # -SecondsRemaining ($remainingItems * $averageItemTime)
168 | }
169 | "
170 |
171 |
172 | "
173 |
174 | $f = Join-Path (Join-Path $env:USERPROFILE "Downloads") "RoleGroupMembership$CognosEnvironment.csv"
175 | $out | Export-Csv -Path $f -NoTypeInformation
176 | Start-Process -FilePath $f
177 |
--------------------------------------------------------------------------------
/ContentStore/SpecBackup/README.md:
--------------------------------------------------------------------------------
1 | # Cognos Analytics
2 |
3 | # Backing up reports, dashboards, and data sets from Team Content/Reports
4 |
5 | ## Introduction
6 | Cognos stores the specifications for reports and data sets as XML and dashboards as JSON. It is possible to output the specs to the file system and sync them with a source control system like git. In my case, I manually cloned the repo, then wrote these scripts to do the routine work.
7 |
8 | I use Microsoft SQL Server and Microsoft Windows Server. Your mileage may vary.
9 |
10 | Hacking the Cognos Content Store database is not recommended. The correct, supported way to automate Cognos management tasks is by using the Cognos SDK.
11 |
12 | For supported version control, look for third-party tools like Motio CI.
13 |
14 | I used Windows Task Scheduler to make this run once per day.
15 |
16 | PowerShell can be used to run a query against the Content Store database and save the results to the file system. Git can help with version control so you can see changes over time and revert to the appropriate version of a report in case that's needed. HTMLTidy can clean up XML. This will make it easier to compare report versions. There are some prerequisites.
17 |
18 |
19 | ## Getting Started
20 | 1. Download and install Git for Windows. It should be at e:\install\Git-2.16.2-64-bit.exe.
21 | 1. Configure SSL for git. (see below)
22 | 1. Clone the repository that contains the report backups. It's currently at https://WSDOT@dev.azure.com/WSDOT/Business%20Intelligence%20and%20Reporting/_git/Cognos%20Reports.
23 | 1. Download HTMLTidy (tidy.exe at http://www.html-tidy.org/) into %USERPROFILE%\repos\WindowsTools.
24 | 1. Download and install these components of the Microsoft® SQL Server® 2014 Feature Pack:
25 | - ENU\x64\SQLSysClrTypes.msi (4,188 KB)
26 | - ENU\x64\SharedManagementObjects.msi (7,572 KB)
27 | - ENU\x64\PowerShellTools.msi (2,104 KB)
28 | 1. Create a task in the Windows Task Scheduler to run powershell -file "%USERPROFILE%\repos\ReportBackup\ReportBackup.ps1" once per day.
29 | ! TODO ! Hide the powershell window.
30 |
31 | ## Gotchas
32 | This document and the current state of the source code assume that things are stored in specific locations.
33 | - Repo containing this code: %USERPROFILE%\repos\ReportBackup
34 | - Repo containing the Cognos object specs: %USERPROFILE%\repos\CognosReports
35 | - Repo containing tidy.exe: %USERPROFILE%\repos\WindowsTools
36 |
37 | If these locations are not correct for your environment, track down all of the references in the code and fix them.
38 |
39 |
40 |
41 | ## Files ##
42 |
43 | ### ReportBackup.ps1 ###
44 |
45 | The wrapper. It pulls content from the git repo to ensure we're starting with current content, runs export.ps1 to get the specs from the Content Store, then runs push.ps1 to push the new content up to the remote repo.
46 |
47 | ### export.ps1 ###
48 |
49 | Exports the specs from the Content Store database to files on the local system. For performance reasons, the full content is captured only on Sundays. This enables git to record the deletion of content. On other days, only changes and additions in the last three days are output.
50 |
51 | ### push.ps1 ###
52 |
53 | Tidies the XML or JSON to make it easy to see differences between versions, then pushes the content to the remote repo. Uses HTML Tidy to tidy the XML files.
54 |
55 | ### tidy.exe ###
56 | Included here for convenience because I can. The license states, "Permission is hereby granted to use, copy, modify, and distribute this source code, or portions hereof, documentation and executables, for any purpose...". You may want to be sure you have the current version (SourceForge or Github).
57 |
--------------------------------------------------------------------------------
/ContentStore/SpecBackup/ReportBackup.ps1:
--------------------------------------------------------------------------------
1 | $exportResult = & ((Split-Path $MyInvocation.InvocationName) + "\export.ps1")
2 | if ($exportResult -eq 1) {
3 | #$fldr = ($env:USERPROFILE) + "\repos\CognosReports"
4 | $fldr = Join-Path ($env:USERPROFILE) "\repos\CognosReports"
5 | $msg = "`"Daily backup`""
6 | & ((Split-Path $MyInvocation.InvocationName) + "\push.ps1") $fldr $msg
7 | }
--------------------------------------------------------------------------------
/ContentStore/SpecBackup/export.ps1:
--------------------------------------------------------------------------------
1 | #$d = date
2 | #$dnum = $d.tostring("yyyyMMdd")
3 | $dlog = (date).tostring("yyyy-MM-dd HH:mm:ss.fff ")
4 | $dow = (date).DayofWeek.value__
5 | $thisFolder = (Split-Path $MyInvocation.MyCommand.Source)
6 | $ReportBackupLog = $thisFolder + "\logs\ReportBackupLog.txt"
7 | $repo = "C:\Users\pulsed\repos\CognosReports"
8 |
9 | "$dlog Content Store export beginning" | Out-File -append $ReportBackupLog
10 |
11 |
12 | $sqlquery = "with src (
13 | CMID,
14 | ObjectName,
15 | ObjectPath,
16 | ObjectClass,
17 | Modified) as
18 | (
19 | select o.CMID
20 | , n.NAME
21 | , cast(
22 | replace(
23 | replace(
24 | replace(
25 | replace(
26 | replace(
27 | replace(
28 | replace(
29 | replace(
30 | replace(
31 | n.NAME, char(60), '' -- <
32 | ), char(62), '' -- >
33 | ), char(58), '' -- :
34 | ), char(34), '' -- quote
35 | ), char(47), '' -- /
36 | ), char(92), '' -- \
37 | ), char(124), '' -- |
38 | ), char(63), '' -- ?
39 | ), char(42), '' -- *
40 | ) as varchar(max))
41 | , cast(c.NAME as varchar(max))
42 | , o.MODIFIED
43 | from CMOBJECTS o
44 | inner join CMOBJNAMES n on n.CMID = o.CMID
45 | inner join CMCLASSES c on c.CLASSID = o.CLASSID
46 | where n.ISDEFAULT = 1
47 | and isdate(n.NAME) = 0
48 | and o.CMID = 2
49 |
50 | union all
51 | select o.CMID
52 | , n.NAME
53 | , cast(src.ObjectPath + '/' +
54 | replace(
55 | replace(
56 | replace(
57 | replace(
58 | replace(
59 | replace(
60 | replace(
61 | replace(
62 | replace(
63 | n.NAME, char(60), ''
64 | ), char(62), ''
65 | ), char(58), ''
66 | ), char(34), ''
67 | ), char(47), ''
68 | ), char(92), ''
69 | ), char(124), ''
70 | ), char(63), ''
71 | ), char(42), ''
72 | ) as varchar(max))
73 | , cast(c.NAME as varchar(max))
74 | , o.MODIFIED
75 | from CMOBJECTS o
76 | inner join CMOBJNAMES n on n.CMID = o.CMID
77 | inner join CMCLASSES c on c.CLASSID = o.CLASSID
78 | inner join src on src.CMID = o.PCMID
79 | where n.ISDEFAULT = 1
80 | and n.CMID != 0
81 | ),
82 | obj as (
83 | select CMID
84 | , REPLACE(s.ObjectPath,'/','\') + case when s.ObjectClass = 'exploration' then '.json' else '.xml' end as FilePath
85 | from src s
86 | where s.ObjectClass in ('report', 'exploration', 'dataSet2')
87 | and s.ObjectPath like 'Team Content/Reports%'
88 | )
89 |
90 | select o.FilePath
91 | , s.SPEC as SPEC
92 | from obj o
93 | left join CMOBJPROPS7 s on s.CMID = o.CMID"
94 |
95 | ## If it's Sunday, don't filter the results. Get the entire Content Store.
96 | #if ($dow -ne 0) {
97 | #$sqlquery = $sqlquery + "
98 | # and c.Modified > dateadd(day, -3, getdate())"
99 | #}
100 |
101 | $sqlquery = $sqlquery + "
102 | order by 1"
103 |
104 |
105 |
106 | push-location
107 | $result = Invoke-Sqlcmd $sqlquery -ServerInstance "HQOLYMSQL19P" -Database "IBMCOGNOS" -MaxCharLength 1000000
108 | pop-location
109 |
110 | $l = $result.length
111 |
112 | if ($l -eq 0){
113 | # No results? Something went wrong. Don't change anything.
114 | $dlog = (date).tostring("yyyy-MM-dd hh:mm:ss.fff ")
115 | "$dlog $l reports modified -- something went wrong" | Out-File -append $ReportBackupLog
116 | #"$dlog $sqlquery" | Out-File -append $ReportBackupLog
117 | return 0
118 | }
119 |
120 |
121 | $dlog = (date).tostring("yyyy-MM-dd hh:mm:ss.fff ")
122 | "$dlog $l reports modified" | Out-File -append $ReportBackupLog
123 |
124 |
125 | # If it's Sunday, delete everything under Team Content\Reports.
126 | # This is to delete items that are no longer in the Content Store.
127 | #if ($dow -eq 0) {
128 | $rpts = $repo + "\Team Content\Reports"
129 | Remove-Item -path $rpts -recurse
130 | #}
131 |
132 |
133 | # Write the results to the file system
134 | foreach($row in $result) {
135 | $filepath = $repo + "\" + $row.FilePath
136 | $contents = $row.SPEC
137 | if ($filepath.length -gt 240) {
138 | "The path is too long: $filepath" | Out-File -append $ReportBackupLog
139 | ##Try using 8.3 folder/file naming format
140 | #$folderpath = Split-Path $filepath
141 | #if (Test-Path $folderpath) {
142 | # #The folder exists
143 | # $filename = Split-Path $filepath -Leaf
144 | # $filepath = Join-Path (New-Object -ComObject Scripting.FileSystemObject).GetFolder($folderpath).shortpath $filename
145 | #}
146 | }
147 |
148 | #$fldr = Split-Path $filepath
149 | #if (!(Test-Path $fldr)) {
150 | # "Folder not found: $fldr" | Out-File -append $ReportBackupLog
151 | # "Folder not found: $fldr"
152 | #}
153 |
154 | try {
155 | if(!(Test-Path $filepath)) {
156 | try {
157 | New-Item $filepath -ItemType file -Force -Value $contents
158 | }
159 | catch {
160 | "Error: " + $row.FilePath | Out-File -append $ReportBackupLog
161 | " " + $_.Exception.Message | Out-File -append $ReportBackupLog
162 | #" " + $_.Exception.ItemName | Out-File -append $ReportBackupLog
163 | " " | Out-File -append $ReportBackupLog
164 | }
165 | }
166 | else {
167 | Set-Content -Path $filepath -Value $contents
168 | }
169 | }
170 | catch {
171 | "Error: " + $row.FilePath | Out-File -append $ReportBackupLog
172 | " " + $_.Exception.Message | Out-File -append $ReportBackupLog
173 | #" " + $_.Exception.ItemName | Out-File -append $ReportBackupLog
174 | " " | Out-File -append $ReportBackupLog
175 | }
176 | }
177 |
178 | $dlog = (date).tostring("yyyy-MM-dd HH:mm:ss.fff ")
179 | "$dlog Content Store export complete" | Out-File -append $ReportBackupLog
180 |
181 | return 1
182 |
--------------------------------------------------------------------------------
/ContentStore/SpecBackup/push.ps1:
--------------------------------------------------------------------------------
1 | param([string]$fldr, [string]$msg)
2 |
3 | #cd $fldr
4 |
5 | # Identify all of the changes to reports.
6 | # Push the changes to the git repository.
7 | # Record in a text file what files changed.
8 |
9 |
10 | #$d = date
11 | $dnum = (date).tostring("yyyyMMdd")
12 | $dlog = (date).tostring("yyyy-MM-dd HH:mm:ss.fff ")
13 | $thisFolder = (Split-Path $MyInvocation.MyCommand.Source)
14 | $ReportBackupLog = $thisFolder + "\logs\ReportBackupLog.txt"
15 | $UpdatesLog = $thisFolder + "\logs\updates$dnum.txt"
16 |
17 |
18 | if ($fldr -eq "") {
19 | "$dlog no folder provided" | Out-File -append $ReportBackupLog
20 | exit
21 | }
22 | if (!(Test-Path "$fldr\.git" -PathType Container)) {
23 | # folder path not found
24 | "$dlog $fldr is not a git repository" | Out-File -append $ReportBackupLog
25 | exit
26 | }
27 |
28 | if ($msg -eq "") {
29 | "$dlog no message provided" | Out-File -append $ReportBackupLog
30 | exit
31 | }
32 |
33 |
34 | Set-Location -Path $fldr
35 | #Write-Host "Path set to $fldr"
36 |
37 | # get repo status
38 | $status = git status --porcelain
39 |
40 | # for each item that was changed (modified or added)
41 | # if it's an xml file, tidy the XML
42 |
43 | #Write-Host " " >> "..\updates$dnum.txt"
44 | $cmd = $env:USERPROFILE + "\repos\WindowsTools\tidy.exe"
45 |
46 | foreach ($line in $status) {
47 | if (($line.Substring(0, 3) -eq " M " -Or $line.Substring(0, 3) -eq " A ") -And $line.Substring($line.length - 5, 4) -eq ".xml") {
48 | # we want this one
49 | #$f = "`"" + $fldr + "\" + $line.Substring(4, $line.length - 5) + "`""
50 | #$f = $f.replace("/", "\")
51 | $f = Join-Path $fldr $line.Substring(4, $line.Length - 5)
52 |
53 | if(!(Test-Path $f)) {
54 | "File not found: $f" | Out-File -append $ReportBackupLog
55 | }
56 |
57 | $args = @(
58 | "-q",
59 | "-xml",
60 | "-wrap", "0",
61 | "-indent",
62 | "-o", $f,
63 | $f
64 | )
65 |
66 | # tidy
67 | #& "e:\tools\tidy.bat" $f
68 | #& "e:\tools\tidy.exe" "-q -xml -wrap 0 -indent -o $f $f"
69 | & $cmd $args
70 |
71 | ## record the change locally
72 | ##Write-Host $f
73 | #$f | Out-File -append $UpdatesLog
74 | }
75 |
76 | if (($line.Substring(0, 3) -eq " M " -Or $line.Substring(0, 3) -eq " A ") -And $line.Substring($line.length - 6, 5) -eq ".json") {
77 | # we want this one
78 | $f = "`"" + $fldr + "\" + $line.Substring(4, $line.length - 5) + "`""
79 | $f = $f.replace("/", "\")
80 |
81 | (get-content $f) | convertfrom-json | convertto-json -depth 100 | set-content $f
82 | }
83 | }
84 |
85 |
86 | # now that we've tidied the xml, let's rerun status to see what really changed...
87 | $status = git status --porcelain
88 | # ...and record what changed
89 | foreach ($line in $status) {
90 | if (($line.Substring(0, 3) -eq " M " -Or $line.Substring(0, 3) -eq " A ") -And ($line.Substring($line.length - 5, 4) -eq ".xml" -Or $line.Substring($line.length - 6, 5) -eq ".json")) {
91 | # we want this one
92 | $f = "`"" + $fldr + "\" + $line.Substring(4, $line.length - 5) + "`""
93 | $f = $f.replace("/", "\")
94 |
95 | # record the change locally
96 | #Write-Host $f
97 | $f | Out-File -append $UpdatesLog
98 | }
99 | }
100 |
101 |
102 |
103 | # push the changes to remote git repo
104 | git add -A
105 | git commit -m $msg
106 | git push
107 |
108 | $dlog = (date).tostring("yyyy-MM-dd HH:mm:ss.fff ")
109 | "$dlog git push complete" | Out-File -append $ReportBackupLog
--------------------------------------------------------------------------------
/ContentStore/capabilities.sql:
--------------------------------------------------------------------------------
1 | use IBMCognos
2 | go
3 | ;
4 | declare @DirectoryNamespace varchar(128) = 'MyNamespaceName'
5 | ;
6 | with
7 | capability as (
8 | select o.CMID
9 |
10 | from CMOBJECTS o
11 | inner join CMOBJNAMES n on n.CMID = o.CMID
12 | inner join CMCLASSES c on c.CLASSID = o.CLASSID
13 |
14 | where n.ISDEFAULT = 1
15 | and n.NAME = 'Capability'
16 | and c.NAME = 'capability'
17 | ),
18 | capabilities as (
19 | select cast(n.NAME as varchar(max)) as CapabilityPath
20 | , n.NAME
21 | , c.NAME as class
22 | , o.CMID
23 | , o.PCMID
24 | , o.DISABLED
25 |
26 | from CMOBJECTS o
27 | inner join CMOBJNAMES n on n.CMID = o.CMID
28 | inner join CMCLASSES c on c.CLASSID = o.CLASSID
29 | --inner join capability cap on cap.CMID = o.PCMID
30 |
31 | where n.ISDEFAULT = 1
32 | and n.NAME = 'Capability'
33 | and c.NAME = 'capability'
34 |
35 | union all
36 | select cast(cap.CapabilityPath + '/' + n.NAME as varchar(max))
37 | , n.NAME
38 | , c.NAME
39 | , o.CMID
40 | , o.PCMID
41 | , o.DISABLED
42 | from capabilities cap
43 | inner join CMOBJECTS o on o.PCMID = cap.CMID
44 | inner join CMOBJNAMES n on n.CMID = o.CMID
45 | inner join CMCLASSES c on c.CLASSID = o.CLASSID
46 |
47 | where n.ISDEFAULT = 1
48 | )
49 |
50 | select *
51 | into #capabilities
52 | from capabilities
53 | ;
54 | with
55 | capabilitypolicy as (
56 | select c.CapabilityPath
57 | --, c.NAME
58 | --, c.class
59 | --, c.CMID
60 | --, c.PCMID
61 | , c.DISABLED
62 | , CONVERT(varchar(max), CONVERT(varbinary(max), p.POLICIES, 1), 2) as pol
63 | from #capabilities c
64 | inner join CMPOLICIES p on p.CMID = c.CMID
65 | ),
66 | cte (
67 | CapabilityPath,
68 | pol,
69 | l,
70 | pos,
71 | curr,
72 | valout
73 | ) as (
74 | -- Loop through the value 2 characters (1 hex value) at a time.
75 | -- Convert each value to ASCII.
76 | -- We'll replace anything small (non-printing characters) with LF to keep it simple.
77 | -- That may not be the best solution.
78 | select CapabilityPath
79 | , pol
80 | , len(pol) as l
81 | , 3 as pos
82 | , substring(pol, 1, 2) as curr
83 | , case
84 | when convert(int, convert(varbinary, '0x' + substring(pol, 1, 2), 1)) < 32 then char(10)
85 | else cast(cast(convert(binary(2), '0x' + substring(pol, 1, 2), 1) as char(1)) as varchar(max))
86 | end as valout
87 | from capabilitypolicy
88 | union all
89 | select CapabilityPath
90 | , pol
91 | , l
92 | , pos + 2 as pos
93 | , substring(pol, pos, 2) as curr
94 | , valout +
95 | case
96 | when convert(int, convert(varbinary, '0x' + substring(pol, pos, 2), 1)) < 32 then char(10)
97 | else cast(cast(convert(binary(2), '0x' + substring(pol, pos, 2), 1) as char(1)) as varchar(max))
98 | end as valout
99 | from cte
100 | where pos < l
101 | ),
102 | cte2 as (
103 | -- Rank to identify the final value.
104 | select *
105 | , rank() over (partition by CapabilityPath order by pos desc) as rnk
106 | from cte
107 | ),
108 | a as (
109 | -- We need only the results of the last step.
110 | select CapabilityPath
111 | , valout
112 | from cte2
113 | where rnk = 1
114 | ),
115 | q as (
116 | select CapabilityPath
117 | , ROW_NUMBER() over (partition by CapabilityPath order by CapabilityPath) as rownum -- not reliable because string_split doesn't guarantee order until SQL 2022
118 | --, ROW_NUMBER() over (partition by CapabilityPath order by ordinal) as rownum -- Use with SQL 2022 or later
119 | , value as val
120 | --, substring(value, 11, 32) as val
121 | from a
122 | cross apply string_split(valout, char(10)) -- not reliable because string_split doesn't guarantee order until SQL 2022
123 | --cross apply string_split(valout, char(10), 1) -- Use with SQL 2022 or later
124 | )
125 |
126 | -- Using a temporary table here reduces run time from 88 seconds to 8 seconds.
127 | select *
128 | into #q
129 | from q
130 | OPTION (MAXRECURSION 0)
131 |
132 | --select *
133 | --from #q
134 | --order by CapabilityPath
135 | ;
136 |
137 | with
138 | perms as (
139 | select perm
140 | from (
141 | values
142 | ('execute')
143 | , ('read')
144 | , ('setPolicy')
145 | , ('traverse')
146 | , ('write')
147 | ) v (perm)
148 | ),
149 | capabilityPerms as (
150 | select q.CapabilityPath
151 | , q.rownum
152 | , n.NAME
153 | from #q q
154 | inner join CMOBJNAMES n on n.CMID = cast(SUBSTRING(val, 3, CHARINDEX(':', val, 3) - 3) as int)
155 | where q.val like '::%'
156 | and CHARINDEX(':', val, 3) > 0
157 | and n.ISDEFAULT = 1
158 |
159 | union
160 | select q.CapabilityPath
161 | , q.rownum
162 | , SUBSTRING(val, 3, 400) as 'Name'
163 | from #q q
164 | where q.val like '::%'
165 | and CHARINDEX(':', val, 3) = 0
166 |
167 | union
168 | select q.CapabilityPath
169 | , q.rownum
170 | , 'WSDOT\' + u.NAME
171 | from #q q
172 | inner join CMOBJNAMES n on n.NAME = q.val
173 | inner join cmobjprops33 u on u.CMID = n.CMID
174 | where n.NAME like @DirectoryNamespace + '%'
175 |
176 | union
177 | select q.CapabilityPath
178 | , q.rownum
179 | , p.perm
180 | from #q q
181 | inner join perms p on q.val like '%' + p.perm + '%'
182 | ),
183 | --capabilityPermType as (
184 | -- select cp.CapabilityPath
185 | -- , cp.rownum
186 | -- , cp.NAME
187 | -- from capabilityPerms cp
188 | -- inner join perms p on p.perm = cp.NAME
189 | --),
190 | executeStart as (
191 | select cp.CapabilityPath
192 | , cp.rownum
193 | , cp.NAME
194 | from capabilityPerms cp
195 | where cp.NAME = 'execute'
196 | ),
197 | readStart as (
198 | select cp.CapabilityPath
199 | , cp.rownum
200 | , cp.NAME
201 | from capabilityPerms cp
202 | where cp.NAME = 'read'
203 | ),
204 | setPolicyStart as (
205 | select cp.CapabilityPath
206 | , cp.rownum
207 | , cp.NAME
208 | from capabilityPerms cp
209 | where cp.NAME = 'setPolicy'
210 | ),
211 | traverseStart as (
212 | select cp.CapabilityPath
213 | , cp.rownum
214 | , cp.NAME
215 | from capabilityPerms cp
216 | where cp.NAME = 'traverse'
217 | ),
218 | writeStart as (
219 | select cp.CapabilityPath
220 | , cp.rownum
221 | , cp.NAME
222 | from capabilityPerms cp
223 | where cp.NAME = 'write'
224 | ),
225 | permClass as (
226 | select cp.CapabilityPath
227 | , cp.rownum
228 | , cp.NAME
229 | , es.rownum as executeStart
230 | , rs.rownum as readStart
231 | , ss.rownum as setPolicyStart
232 | , ts.rownum as traverseStart
233 | , ws.rownum as writeStart
234 | from capabilityPerms cp
235 | left outer join executeStart es on es.CapabilityPath = cp.CapabilityPath
236 | left outer join readStart rs on rs.CapabilityPath = cp.CapabilityPath
237 | left outer join setPolicyStart ss on ss.CapabilityPath = cp.CapabilityPath
238 | left outer join traverseStart ts on ts.CapabilityPath = cp.CapabilityPath
239 | left outer join writeStart ws on ws.CapabilityPath = cp.CapabilityPath
240 | )
241 |
242 | select c.CapabilityPath
243 | , case
244 | when pc.rownum between coalesce(pc.executeStart, 999) and coalesce(pc.readStart, pc.setPolicyStart, pc.traverseStart, pc.writeStart, 999)
245 | then 'execute'
246 | when pc.rownum between coalesce(pc.readStart, 999) and coalesce(pc.setPolicyStart, pc.traverseStart, pc.writeStart, 999)
247 | then 'read'
248 | when pc.rownum between coalesce(pc.setPolicyStart, 999) and coalesce(pc.traverseStart, pc.writeStart, 999)
249 | then 'setPolicy'
250 | when pc.rownum between coalesce(pc.traverseStart, 999) and coalesce(pc.writeStart, 999)
251 | then 'traverse'
252 | when pc.rownum between coalesce(pc.writeStart, 999) and 999
253 | then 'write'
254 | else 'inherited'
255 | end as permission
256 | , pc.NAME
257 | from #capabilities c
258 | left outer join permClass pc on pc.CapabilityPath = c.CapabilityPath
259 | and pc.NAME not in (
260 | select perm
261 | from perms
262 | )
263 | --and pc.NAME = 'BI Administrators'
264 | order by 1, 2, 3
265 |
266 | drop table #q
267 | drop table #capabilities
268 |
--------------------------------------------------------------------------------
/ContentStore/udf_CognosPermissions.sql:
--------------------------------------------------------------------------------
1 | create function [dbo].[udf_CognosPermissions](@sIn varchar(max))
2 | returns varchar(max)
3 | as
4 | begin
5 | declare @sBin varchar(max) = ''
6 | declare @sOut varchar(max) = ''
7 | declare @i int = 1
8 | declare @j int = 1
9 | declare @sTemp varchar(8) = ''
10 | declare @iByte int = 0
11 | declare @thisByte varchar(5) = ''
12 |
13 | declare @codes table (
14 | letter char(1) COLLATE Latin1_General_CS_AS,
15 | number int
16 | )
17 |
18 | insert @codes
19 | select 'A', 0
20 | union select 'B', 1
21 | union select 'C', 2
22 | union select 'D', 3
23 | union select 'E', 4
24 | union select 'F', 5
25 | union select 'G', 6
26 | union select 'H', 7
27 | union select 'I', 8
28 | union select 'J', 9
29 | union select 'K', 10
30 | union select 'L', 11
31 | union select 'M', 12
32 | union select 'N', 13
33 | union select 'O', 14
34 | union select 'P', 15
35 | union select 'Q', 16
36 | union select 'R', 17
37 | union select 'S', 18
38 | union select 'T', 19
39 | union select 'U', 20
40 | union select 'V', 21
41 | union select 'W', 22
42 | union select 'X', 23
43 | union select 'Y', 24
44 | union select 'Z', 25
45 | union select 'a', 26
46 | union select 'b', 27
47 | union select 'c', 28
48 | union select 'd', 29
49 | union select 'e', 30
50 | union select 'f', 31
51 | union select 'g', 32
52 | union select 'h', 33
53 | union select 'i', 34
54 | union select 'j', 35
55 | union select 'k', 36
56 | union select 'l', 37
57 | union select 'm', 38
58 | union select 'n', 39
59 | union select 'o', 40
60 | union select 'p', 41
61 | union select 'q', 42
62 | union select 'r', 43
63 | union select 's', 44
64 | union select 't', 45
65 | union select 'u', 46
66 | union select 'v', 47
67 | union select 'w', 48
68 | union select 'x', 49
69 | union select 'y', 50
70 | union select 'z', 51
71 | union select '0', 52
72 | union select '1', 53
73 | union select '2', 54
74 | union select '3', 55
75 | union select '4', 56
76 | union select '5', 57
77 | union select '6', 58
78 | union select '7', 59
79 | union select '8', 60
80 | union select '9', 61
81 | union select '+', 62
82 | union select '/', 63
83 |
84 |
85 | while @i < len(@sIn)
86 | begin
87 | set @sBin = @sBin + right('000000' + dbo.udf_ConvertFromBase10((select number from @codes where letter = substring(@sIn, @i, 1)), 2), 6)
88 | set @i = @i + 1
89 | end
90 |
91 | set @i = 1
92 |
93 | while @i < len(@sBin)
94 | begin
95 | set @sTemp = substring(@sBin, @i, 8)
96 | set @j = 1
97 | set @iByte = 0
98 | while @j <= 8
99 | begin
100 | set @iByte = @iByte + (cast(substring(@sTemp, @j, 1) as int) * (power(2, 8 - @j)))
101 | set @j = @j + 1
102 | end
103 | set @thisByte = case when @iByte = 0 then char(13)
104 | else char(@iByte)
105 | end
106 | set @sOut = @sOut + @thisByte
107 | set @i = @i + 8
108 | end
109 |
110 | return @sOut
111 | end
112 | GO
113 |
--------------------------------------------------------------------------------
/ContentStore/udf_ConvertFromBase10.sql:
--------------------------------------------------------------------------------
1 | CREATE FUNCTION [dbo].[udf_ConvertFromBase10](@num INT, @base TINYINT)
2 | RETURNS VARCHAR(255)
3 | AS
4 |
5 | BEGIN
6 | -- Check for a null value.
7 | IF (@num IS NULL)
8 | RETURN NULL
9 |
10 | -- Declarations
11 | DECLARE @string VARCHAR(255)
12 | DECLARE @return VARCHAR(255)
13 | DECLARE @finished BIT
14 | DECLARE @div INT
15 | DECLARE @rem INT
16 | DECLARE @char CHAR(1)
17 |
18 | -- Initialize
19 | SELECT @string = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'
20 | SELECT @return = CASE WHEN @num <= 0 THEN '0' ELSE '' END
21 | SELECT @finished = CASE WHEN @num <= 0 THEN 1 ELSE 0 END
22 | SELECT @base = CASE WHEN @base < 2 OR @base IS NULL THEN 2 WHEN @base > 36 THEN 36 ELSE @base END
23 |
24 | -- Loop
25 | WHILE @finished = 0
26 | BEGIN
27 |
28 | -- Do the math
29 | SELECT @div = @num / @base
30 | SELECT @rem = @num - (@div * @base)
31 | SELECT @char = SUBSTRING(@string, @rem + 1, 1)
32 | SELECT @return = @char + @return
33 | SELECT @num = @div
34 |
35 | -- Nothing left?
36 | IF @num = 0 SELECT @finished = 1
37 |
38 | END
39 |
40 | -- Done
41 | RETURN @return
42 | END
43 | GO
44 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2018, 2019, 2020, 2021, 2022, 2023, 2024 doug pulse
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/Maintenance/MaintenanceWindow/CognosMaintenance.ps1:
--------------------------------------------------------------------------------
1 | $logfile = "E:\logs\CognosMaintenance.txt"
2 | $datestring = (date).tostring("yyyy-MM-dd")
3 | $dlog = (date).tostring("yyyy-MM-dd hh:mm:ss.fff ")
4 |
5 | "$dlog Start Cognos maintenance" | Out-File -append $logfile
6 |
7 | # set the date to be sure this only happens once
8 | if ($datestring -eq "2020-02-02") {
9 | #Do something
10 | #Log as you go
11 | $msg = ""
12 |
13 |
14 |
15 |
16 | #Log final status
17 | $dlog = (date).tostring("yyyy-MM-dd hh:mm:ss.fff ")
18 | "$dlog Did something" | Out-File -append $logfile
19 | Send-MailMessage -To "email@domain.com" -From "email@domain.com" -Subject "$env:COMPUTERNAME Maintenance" -Body $msg -SmtpServer "server.domain.com" -Port 25
20 | }
21 | else {
22 | "$dlog Nothing to do" | Out-File -append $logfile
23 | Send-MailMessage -To "email@domain.com" -From "email@domain.com" -Subject "$env:COMPUTERNAME Maintenance" -SmtpServer "server.domain.com" -Port 25
24 | }
25 |
26 |
27 | $dlog = (date).tostring("yyyy-MM-dd hh:mm:ss.fff ")
28 | "$dlog End Cognos maintenance" | Out-File -append $logfile
29 |
--------------------------------------------------------------------------------
/Maintenance/MaintenanceWindow/CognosStart.ps1:
--------------------------------------------------------------------------------
1 | $logfile = "E:\logs\CognosMaintenance.txt"
2 | $datestring = (date).tostring("yyyy-MM-dd")
3 | $dlog = (date).tostring("yyyy-MM-dd hh:mm:ss.fff ")
4 |
5 | "$dlog Starting Cognos Please wait 10 minutes for full service startup." | Out-File -append $logfile
6 |
7 | Start-Service -Name "IBM Cognos"
8 |
9 | $dlog = (date).tostring("yyyy-MM-dd hh:mm:ss.fff ")
10 | "$dlog End Cognos maintenance" | Out-File -append $logfile
11 |
--------------------------------------------------------------------------------
/Maintenance/MaintenanceWindow/CognosStop.ps1:
--------------------------------------------------------------------------------
1 | $logfile = "E:\logs\CognosMaintenance.txt"
2 | $datestring = (date).tostring("yyyy-MM-dd")
3 | $dlog = (date).tostring("yyyy-MM-dd hh:mm:ss.fff ")
4 |
5 | "$dlog Start Cognos maintenance" | Out-File -append $logfile
6 | "$dlog Stopping Cognos" | Out-File -append $logfile
7 |
8 | Stop-Service -Name "IBM Cognos"
9 |
--------------------------------------------------------------------------------
/Maintenance/MaintenanceWindow/README.md:
--------------------------------------------------------------------------------
1 | # Maintenance Window
2 | Most Cognos users expect it to be functional during regular business hours. But I work regular business hours. So how do I take Cognos down to perform maintenance tasks that can't be performed while Cognos is running? Or tasks that require me to restart the IBM Cognos service?
3 |
4 | Windows Task Scheduler to the rescue.
5 | Scheduling these three tasks to run daily or weekly outside of business hours meets the need. It can run every day, whether there is maintenance work or not. The maintenance script is configured to only perform actions on a specific day, so it will only happen once. Of course, you can customize it to run every day in a range of dates, or access a separate calendar to manage this. And if you schedule it weekly, an urgent need can be accommodated by scheduling a one-time run.
6 |
7 |
8 |
9 |
CognosStop.ps1
10 |
Stops the IBM Cognos service. I schedule this for 1:30 a.m. Sundays.
11 |
12 |
CognosMaintenance.ps1
13 |
Performs custom maintanance actions. I schedule this for 1:35 a.m. Sundays, providing enough time for the IBM Cognos service to stop before this script runs.
14 |
15 |
CognosStart.ps1
16 |
Starts the IBM Cognos service. I schedule this for 3:05 a.m. Sundays. 90 minutes should be more than enough time to perform maintenance actions.
17 |
18 |
--------------------------------------------------------------------------------
/Maintenance/SSL/README.md:
--------------------------------------------------------------------------------
1 | # SSL Cert Renewal
2 | SSL certificates expire. It's a little embarrassing when your Cognos service stops working because you missed a deadline.
3 |
4 |
5 |
6 |
SSLCertExpiration.csv
7 |
Contains data about your SSL cert expiration dates. Used by SSLExpiration.ps1 I have divided some of this data up by Cognos service (dispatcher, content manager, ...) but my systems are all single-server. Your mileage may vary.
8 |
9 |
SSLExpiration.ps1
10 |
Identifies any SSL certificates that will expire in the next 10 days. This is run daily using Windows Task Scheduler. Calls RequestCognosServerCert.ps1 if appropriate.
11 |
12 |
RequestCongosServerCert.ps1
13 |
As a convenience, because my local webmaster is my Certificate Authority (CA), if the cert about to expire is a server cert, I generate the signing request and automatically email the request to the CA.
14 |
15 |
--------------------------------------------------------------------------------
/Maintenance/SSL/RequestCognosServerCert.ps1:
--------------------------------------------------------------------------------
1 | param([string]$serverName, [string]$certType, [string]$expirationDate)
2 |
3 | $cognos = "E:\Program Files\ibm\cognos\analytics"
4 |
5 | e:
6 | cd "$cognos\bin"
7 |
8 | ThirdPartyCertificateTool.bat -java:local -c -e -d "CN=$serverName.domain.com,O=domain,C=US" -H $serverName.wsdot.loc -a RSA -r encryptRequest.csr -p NoPassWordSet
9 |
10 | $subject = "SSL Cert for $servername"
11 | $from = "DoNotReply@domain.com"
12 | # Assuming your webmaster provides your CA certs...
13 | $to = "Cognos Help ,Domain Webmaster "
14 | $attachment = ".\encrypt.csr"
15 | $body = "The $certType SSL cert for the Cognos service "
16 | $body += "on $serverName "
17 | $body += "will expire on $expirationDate.`r`n"
18 | $body += "Please provide the server cert in PEM (Base-64 encoded ASCII) format "
19 | $body += "for the attached signing request to Cognos Help ."
20 |
21 | Send-MailMessage -From $from -To $to -Subject $subject -Body $body -Attachments $attachment
22 |
--------------------------------------------------------------------------------
/Maintenance/SSL/SSLCertExpiration.csv:
--------------------------------------------------------------------------------
1 | MachineName,MachineDescription,Type,Product,Expires
2 | CognosCMPrd,Cognos Production Content Manager,Root,Cognos Server,1/2/2050
3 | CognosDispPrd,Cognos Production Dispatcher,Root,Cognos Server,1/2/2050
4 | CognosTest,Cognos Test Server,Root,Cognos Server,1/2/2050
5 | CognosCMPrd,Cognos Production Content Manager,Intermediate,Cognos Server,1/2/2030
6 | CognosDispPrd,Cognos Production Dispatcher,Intermediate,Cognos Server,1/2/2030
7 | CognosTest,Cognos Test Server,Intermediate,Cognos Server,1/2/2030
8 | CognosCMPrd,Cognos Production Content Manager,Machine,Cognos Server,10/1/2022
9 | CognosDispPrd,Cognos Production Dispatcher,Machine,Cognos Server,10/1/2022
10 | CognosTest,Cognos Test Server,Machine,Cognos Server,11/1/2022
11 | CognosDispPrd,Cognos Production Gateway,Machine,IIS,10/1/2022
12 | CognosTest,Cognos Test Server,Machine,IIS,1/1/2022
13 | MyClientMachine,Joe's workstation,Machine,Framework Manager,1/20/2023
14 | MyClientMachine,Joe's workstation,Intermediate,Framework Manager,8/20/2034
15 | MyClientMachine,Joe's workstation,Root,Framework Manager,7/23/2054
16 |
--------------------------------------------------------------------------------
/Maintenance/SSL/SSLExpiration.ps1:
--------------------------------------------------------------------------------
1 | # Store the cert expiration dates in a CSV file.
2 | $SSLInfo = Import-Csv -Path "E:\tools\SSLCertExpiration.csv"
3 |
4 | $SMTPServer = "server.domain.com"
5 | $from = "CognosServer "
6 | $to = "Cognos Help "
7 | $subject = "Cognos: An SSL cert is about to expire"
8 |
9 | # The email message can include a link to your documentation regarding your SSL certs.
10 | $wikiURL = "http://wiki.domain.com/wiki.php?id=cognos:admin:ssl_cert_schedules"
11 |
12 | foreach ($e in $SSLInfo) {
13 | $e.Expires=[Datetime]::ParseExact($e.Expires, 'M/d/yyyy', $null)
14 | if ((Get-Date) -gt $e.Expires.AddDays(-10)) {
15 | $certType = $e.Type # root, intermediate, or machine
16 | $certProduct = $e.Product # Cognos Analytics Server, Framework Manager, or IIS
17 | $certMachineName = $e.MachineName
18 | $certMachineDescription = $e.MachineDescription
19 | $certExpirationDate = $e.Expires
20 |
21 | $body = "The $certType SSL cert "
22 | $body += "for $certProduct "
23 | $body += "on $certMachineName ($certMachineDescription) "
24 | $body += "will expire on " + $certExpirationDate.ToString('MM/dd/yyyy') + ".`r`n"
25 | $body += "Please visit $wikiURL"
26 |
27 | Send-MailMessage -From $from -To $to -Subject $subject -Body $body
28 | if ($certProduct -eq "Cognos Server") {
29 | & ((Split-Path $MyInvocation.InvocationName) + "\RequestCognosServerCert.ps1") $certMachineName $certType $certExpirationDate.ToString('MM/dd/yyyy')
30 | }
31 | }
32 | }
33 |
34 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # IBM Cognos Analytics
2 | A bunch of mostly unrelated tools and code samples that may help the Cognos administrator, modeler, or report developer.
3 |
4 | **USE AT YOUR OWN RISK. MOST OF THE METHODS DEMONSTRATED HERE ARE NOT SUPPORTED BY IBM. THIS INFORMATION IS AT THIS LOCATION BECAUSE IT IS A CONVENIENT PLACE FOR ME TO STORE KNOWLEDGE I HAVE COMPILED REGARDING IBM COGNOS ANALYTICS. SOME OF THE CONTENT CONTAINED HEREIN MAY NOT WORK CORRECTLY OR MAY CAUSE PROBLEMS IN YOUR SYSTEM. EVEN THE ITEMS THAT I KNOW WORK FOR ME, MAY NOT WORK IN YOUR ENVIRONMENT.**
5 |
6 | See the README in each folder for details.
7 |
--------------------------------------------------------------------------------
/RESTAPI/ModuleBusinessNames.ps1:
--------------------------------------------------------------------------------
1 | $ExistingVariables = Get-Variable | Select-Object -ExpandProperty Name
2 |
3 | $thisFolder = (Split-Path $MyInvocation.MyCommand.Source)
4 | Set-Location $thisFolder
5 | . ".\fn.ps1"
6 |
7 |
8 | function Get-TableMetadata {
9 | [cmdletbinding()]
10 | param (
11 | [parameter(Mandatory=$true)]
12 | [string]$TableName,
13 | [parameter(Mandatory=$true)]
14 | [object]$TablesMetadata
15 | )
16 | $matchCount = 0
17 | $r = [PSCustomObject]@{}
18 | foreach ($tm in $TablesMetadata) {
19 | if ($tm.TableName -eq $TableName) {
20 | $matchCount++
21 | $r = $r | Select-Object -Property * -ExcludeProperty *
22 | $r | Add-Member -MemberType NoteProperty -Name 'Label' -Value $tm.Label
23 | $r | Add-Member -MemberType NoteProperty -Name 'Description' -Value $tm.Description
24 | }
25 | }
26 |
27 | if ($matchCount -gt 1) {
28 | "Warning: More than 1 record matches $Tablename. Returning last item found."
29 | }
30 |
31 | $r
32 | }
33 |
34 | function Get-ColumnMetadata {
35 | [cmdletbinding()]
36 | param (
37 | [parameter(Mandatory=$true)]
38 | [string]$TableName,
39 | [parameter(Mandatory=$true)]
40 | [string]$ColumnName,
41 | [parameter(Mandatory=$true)]
42 | [object]$ColumnsMetadata
43 | )
44 | $matchCount = 0
45 | $r = [PSCustomObject]@{}
46 | foreach ($cm in $ColumnsMetadata) {
47 | if ($cm.TableName -eq $TableName -and $cm.ColumnName -eq $ColumnName) {
48 | $matchCount++
49 | $r = $r | Select-Object -Property * -ExcludeProperty *
50 | $r | Add-Member -MemberType NoteProperty -Name 'Label' -Value $cm.Label
51 | $r | Add-Member -MemberType NoteProperty -Name 'Description' -Value $cm.Description
52 | }
53 | }
54 |
55 | if ($matchCount -gt 1) {
56 | "Warning: More than 1 record matches $Tablename.$Columnname. Returning last item found."
57 | }
58 |
59 | $r
60 | }
61 |
62 |
63 |
64 | "
65 |
66 |
67 |
68 |
69 |
70 | --------------------------------------
71 | starting
72 | --------------------------------------
73 | "
74 |
75 | $protocol = "https"
76 | $serverName = "yourServerName"
77 | $port = "9300"
78 | $uriBase = "$protocol`://$serverName`:$port"
79 | $contentType = "application/json; charset=utf-8"
80 |
81 | $userNamespace = "yourDirectoryNamespace"
82 | $userName = Read-Host "User Name"
83 | $userPassword = ""
84 | $UserPwd = Read-Host "Password" -AsSecureString
85 | $userPassword = ConvertFrom-SecureString -SecureString $UserPwd -AsPlainText
86 | if (!$userPassword) {
87 | break
88 | }
89 |
90 | $modulePath = Read-Host "Module Path"
91 | $database = Read-Host "Database Name"
92 | $dbEnvironment = Read-Host "Database Environment"
93 |
94 | $sqlParams = @()
95 | $sqlParams += $database
96 | $sqlParams += $dbEnvironment
97 |
98 | "
99 | getting metadata..."
100 | # ---------------------------------------------------------
101 | # Data Library
102 |
103 | $sqlTable = "/* TABLE */
104 | select
105 | EnvironmentName
106 | , HardwareSystemName
107 | , [DatabaseName]
108 | , TableName
109 | , coalesce(BusinessName, '') as BusinessName
110 | , coalesce([Description], '') as [Description]
111 |
112 | from [your database objects]
113 |
114 | where DatabaseMetadata.DatabaseName = ?
115 | and Environment.EnvironmentName = ?
116 |
117 | order by 1, 2, 3, 4
118 | ;
119 | "
120 | $DataCatalogDatabase = "yourDataCatalogDatabaseName"
121 | $DataCatalogServer = "yourDataCatalogServerName"
122 | $rsltTable = Invoke-Sql -datasource $DataCatalogServer -database $DataCatalogDatabase -sqlCommand $sqlTable -parameters $sqlParams
123 | $l = $rsltTable.length
124 |
125 | $tables = @()
126 | foreach($row in $rsltTable) {
127 | $r = [PSCustomObject]@{}
128 | $r | Add-Member -MemberType NoteProperty -Name 'TableName' -Value $row.TableName
129 | $r | Add-Member -MemberType NoteProperty -Name 'Label' -Value $row.BusinessName
130 | $r | Add-Member -MemberType NoteProperty -Name 'Description' -Value $row.Description
131 | $tables += $r
132 | }
133 | "
134 | got $l tables"
135 | if ($l -eq 0) {
136 | " Verify database name and environment."
137 | }
138 |
139 | $sqlColumn = "/* COLUMN */
140 | select
141 | EnvironmentName
142 | , HardwareSystemName as ServerName
143 | , [DatabaseName]
144 | , TableName
145 | , [ColumnName]
146 | , coalesce(BusinessName, '') as BusinessName
147 | , coalesce([Description], '') as [Description]
148 |
149 | from [your database objects]
150 |
151 | where DatabaseMetadata.DatabaseName = ?
152 | and Environment.EnvironmentName = ?
153 |
154 | order by 1, 2, 3, 4, 5
155 | ;
156 | "
157 | $rsltTable = Invoke-Sql -datasource $DataCatalogServer -database $DataCatalogDatabase -sqlCommand $sqlColumn -parameters $sqlParams
158 | $l = $rsltColumn.length
159 |
160 | $columns = @()
161 | foreach($row in $rsltColumn) {
162 | $r = [PSCustomObject]@{}
163 | $r | Add-Member -MemberType NoteProperty -Name 'TableName' -Value $row.TableName
164 | $r | Add-Member -MemberType NoteProperty -Name 'ColumnName' -Value $row.ColumnName
165 | $r | Add-Member -MemberType NoteProperty -Name 'Label' -Value $row.BusinessName
166 | $r | Add-Member -MemberType NoteProperty -Name 'Description' -Value $row.Description
167 | $columns += $r
168 | }
169 | "
170 | got $l columns"
171 | if ($l -eq 0) {
172 | " Verify database name and environment."
173 | }
174 |
175 |
176 |
177 | "
178 | getting data module..."
179 | # ---------------------------------------------------------
180 | # Cognos REST API
181 | # docs at
182 | # http://:/api/api-docs
183 |
184 |
185 | $bdy = [PSCustomObject]@{}
186 | $paramarray = @()
187 | $param = [PSCustomObject]@{}
188 | $param | Add-Member -MemberType NoteProperty -Name 'name' -Value "CAMNamespace"
189 | $param | Add-Member -MemberType NoteProperty -Name 'value' -Value $userNamespace
190 | $paramarray += $param
191 | $param = [PSCustomObject]@{}
192 | $param | Add-Member -MemberType NoteProperty -Name 'name' -Value "CAMUsername"
193 | $param | Add-Member -MemberType NoteProperty -Name 'value' -Value $userName
194 | $paramarray += $param
195 | $param = [PSCustomObject]@{}
196 | $param | Add-Member -MemberType NoteProperty -Name 'name' -Value "CAMPassword"
197 | $param | Add-Member -MemberType NoteProperty -Name 'value' -Value $userPassword
198 | $paramarray += $param
199 | $bdy | Add-Member -MemberType NoteProperty -Name 'parameters' -Value $paramarray
200 |
201 | $body = ConvertTo-Json $bdy
202 |
203 | #"
204 | #/* log in */"
205 | $uri = "$uriBase/api/v1/session"
206 | $a = Invoke-RestMethod -Uri $uri -Method Put -contentType $contentType -SessionVariable "Session" -Body $body
207 |
208 | # "
209 | # #/* get session - fails but gets xsrf token */"
210 | # next line throws error, but retrieves a XSRF-Token cookie
211 | $a = Invoke-RestMethod -Uri $uri -Method Get -contentType $contentType -WebSession $Session -ErrorAction Ignore
212 |
213 |
214 | $Cookies = $Session.Cookies.GetCookies($uri)
215 | $XSRFTOKEN = $Cookies["XSRF-TOKEN"].Value
216 |
217 | $headers = @{
218 | 'x-xsrf-token' = $XSRFTOKEN
219 | 'accept' = $contentType
220 | 'Cache-Control' = 'no-cache'
221 | }
222 |
223 | #"
224 | #/* get modules */"
225 | $uri = "$uriBase/api/v1/modules"
226 | $modules = Invoke-RestMethod -Uri $uri -Method Get -Headers $headers -contentType $contentType -WebSession $Session
227 | $moduleId = ""
228 |
229 | foreach ($m in $modules.modules) {
230 | $path = Join-Path $($m.ancestors.name -join "\") $($m.name)
231 | $mpath = ($path).Replace("\", "/")
232 | if ($mpath -eq $modulePath) {
233 | $moduleId = $m.id
234 | }
235 | }
236 |
237 | if (!$moduleId) {
238 | "
239 |
240 | Module not found
241 | Verify module path and name."
242 | }
243 | else {
244 | #"
245 | #/* get the requested module */"
246 | $uri = "$uriBase/api/v1/modules/$moduleId"
247 | $module = Invoke-RestMethod -Uri $uri -Method Get -Headers $headers -contentType $contentType -WebSession $Session
248 |
249 | #"
250 | #/* get the querySubject */"
251 | $qs = $module.querySubject
252 |
253 | foreach ($q in $qs) {
254 | #"===--- " + $q.identifier + " ---==="
255 | $tm = ""
256 | $tm = Get-TableMetadata -TableName $q.identifier -TablesMetadata $tables
257 | if ($tm.label) {
258 | "label = $($tm.label)"
259 | $q.label = $tm.label
260 | }
261 | if ($tm.Description) {
262 | if (!$q.description) {
263 | $q | Add-Member -MemberType NoteProperty -Name 'description' -Value $tm.Description
264 | }
265 | else {
266 | $q.Description = $tm.Description
267 | }
268 | }
269 | foreach ($qi in $q.item) {
270 | $cm = ""
271 | $cm = Get-ColumnMetadata -TableName $q.identifier -ColumnName $qi.queryItem.identifier -ColumnsMetadata $columns
272 | if ($cm.label) {
273 | $qi.queryItem.label = $cm.label
274 | }
275 | if ($cm.Description) {
276 | if (!$qi.queryItem.description) {
277 | $qi.queryItem | Add-Member -MemberType NoteProperty -Name 'description' -Value $cm.Description
278 | }
279 | else {
280 | $qi.queryItem.description = $cm.Description
281 | }
282 | }
283 | } }
284 | $newModule = $module | ConvertTo-Json -Depth 8
285 |
286 | #"
287 | #/* overwrite the requested module */"
288 | $module = Invoke-RestMethod -Uri $uri -Method Put -Headers $headers -contentType $contentType -WebSession $Session -Body $newModule
289 | }
290 |
291 |
292 |
293 | # log out
294 | $uri = "$uriBase/api/v1/session"
295 | $done = Invoke-RestMethod -Uri $uri -Method Delete -WebSession $Session
296 | $done
297 |
298 |
299 |
300 | $NewVariables = Get-Variable | Select-Object -ExpandProperty Name | Where-Object {$ExistingVariables -notcontains $_ -and $_ -ne "ExistingVariables"}
301 | if ($NewVariables) {
302 | #Write-Host "Removing the following variables:`n`n$NewVariables"
303 | Remove-Variable $NewVariables
304 | }
305 | else {
306 | #Write-Host "No new variables to remove!"
307 | }
308 |
--------------------------------------------------------------------------------
/RESTAPI/README.md:
--------------------------------------------------------------------------------
1 | # Software REST API
2 |
3 | Swagger-based documentation: http://:/api/api-docs
4 |
5 | ## WARNING
6 |
7 | This code was developed to run on Windows 10, Window Server 2012 (or higher), PowerShell 7, SQL Server, Cognos Analytics 11.2.4, my environment, etc. Basically, your mileage may vary.
8 |
9 | ## Content
10 |
11 | #### fn.ps1
12 |
13 | A collection of functions useful for working with the Cognos Analytics REST API.
14 |
15 | #### ModuleBusinessNames.ps1
16 |
17 | Leverage your data catalog to automatically populate a data module with human-readable names and descriptions for tables (query subjects) and columns (query items).
18 |
19 | Assumes you are using Windows, PowerShell 7, SQL Server, Cognos Analytics 11.2.4, maybe other stuff. Basically, your mileage may vary.
20 |
21 | #### REST API Example.ps1
22 |
23 | An example showing how to leverage the common functions found in fn.ps1.
24 |
25 | Requires fn.ps1
26 |
27 | #### getCSV.ps1
28 |
29 | For one report, output all CSV outputs that are stored in Cognos. Requires the CSV output to already be saved in a report version.
30 |
31 | Requires fn.ps1
32 |
33 |
--------------------------------------------------------------------------------
/RESTAPI/REST API Example.ps1:
--------------------------------------------------------------------------------
1 | # docs at
2 | # http://:/api/api-docs
3 |
4 | # $thisFolder = (Split-Path $MyInvocation.MyCommand.Source)
5 | # Set-Location $thisFolder
6 | # $functions = ".\fn.ps1"
7 | $functions = Join-Path $env:USERPROFILE "repos\CognosAdmin\RESTAPI\fn.ps1"
8 | . $functions
9 |
10 | $serverName = Read-Host "Cognos Server Name"
11 |
12 | $CognosSession = start-CognosSession -serverName $serverName
13 |
14 | if ($CognosSession) {
15 | $uriBase = $CognosSession.uriBase
16 | $protocol = $CognosSession.protocol
17 | $serverName = $CognosSession.serverName
18 | $port = $CognosSession.port
19 | $Session = $CognosSession.Session
20 | $headers = $CognosSession.Headers
21 | $contentType = $CognosSession.contentType
22 | #"********************
23 | #Cognos Session:"
24 | #Write-Host $CognosSession
25 | #"********************"
26 |
27 | #=====================================================================================================================
28 | # DDDDD OOO SSS TTTTTTT U U FFFFFF FFFFFF
29 | # D D O O S T U U F F
30 | # D D O O SSS T U U FFFF FFFF
31 | # D D O O S T U U F F
32 | # DDDDD OOO SSS T UUUU F F
33 | #=====================================================================================================================
34 |
35 | "
36 |
37 |
38 |
39 | STARTING
40 |
41 | ========================================
42 | "
43 |
44 | $contentId = "library"
45 | $uri = "$uriBase/api/v1/content/$contentId/items"
46 | $content = Invoke-RestMethod -Uri $uri -Method Get -Headers $headers -contentType $contentType -WebSession $Session
47 | $content.content | Format-List
48 |
49 | #=====================================================================================================================
50 | # DDDDD OOO N N EEEEEE DDDDD OOO IIIII N N GGGG SSS TTTTTTT U U FFFFFF FFFFFF
51 | # D D O O N N N E D D O O I N N N G S T U U F F
52 | # D D O O N N N EEEE D D O O I N N N G GGG SSS T U U FFFF FFFF
53 | # D D O O N NN E D D O O I N NN G G S T U U F F
54 | # DDDDD OOO N N EEEEEE DDDDD OOO IIIII N N GGGG SSS T UUUU F F
55 | #=====================================================================================================================
56 |
57 | stop-CognosSession -CognosSession $CognosSession
58 | }
--------------------------------------------------------------------------------
/RESTAPI/getCSV.ps1:
--------------------------------------------------------------------------------
1 | #$functions = Join-Path $env:USERPROFILE "repos\Cognos\RESTAPI\fn.ps1"
2 | Set-Location $thisFolder
3 | $functions = ".\fn.ps1"
4 | . $functions
5 |
6 |
7 | $serverName = Read-Host "Cognos server name"
8 |
9 | $CognosSession = start-CognosSession -serverName $serverName
10 |
11 | if ($CognosSession) {
12 | $uriBase = $CognosSession.uriBase
13 | # $protocol = $CognosSession.protocol
14 | # $serverName = $CognosSession.serverName
15 | # $port = $CognosSession.port
16 | $Session = $CognosSession.Session
17 | # $headers = $CognosSession.Headers
18 | # $contentType = $CognosSession.contentType
19 |
20 | #=====================================================================================================================
21 | # DDDDD OOO SSS TTTTTTT U U FFFFFF FFFFFF
22 | # D D O O S T U U F F
23 | # D D O O SSS T U U FFFF FFFF
24 | # D D O O S T U U F F
25 | # DDDDD OOO SSS T UUUU F F
26 | #=====================================================================================================================
27 |
28 |
29 | "
30 |
31 |
32 |
33 |
34 |
35 | "
36 |
37 | $path = Read-Host "Path to object"
38 |
39 | $href = get-CognosURIfromPath -path $path -CognosSession $CognosSession
40 |
41 | if ($href) {
42 | $co = get-CognosObjects -hrefItems "$href/items" -CognosSession $CognosSession -objectType "output"
43 |
44 | $b = @()
45 | foreach ($o in $co) {
46 | $b += $o.object.id
47 | }
48 | $storeID = "'$($b -join "','")'"
49 |
50 | # So we found the output. How do we get the CSV content?
51 |
52 |
53 | # There doesn't appear to be a way to do this using the REST API.
54 | # We'll run a query against the Content Store database to get the CSV results.
55 |
56 | $sql = "
57 | with
58 | objname as (
59 | select o.CMID
60 | , coalesce(n2.name, n.NAME) as 'NAME'
61 | from CMOBJECTS o
62 | left outer join CMOBJNAMES n on n.CMID = o.CMID
63 | and n.LOCALEID = 92 -- en
64 | left outer join CMOBJNAMES n2 on n2.CMID = o.CMID
65 | and n2.LOCALEID = 118 -- en-us
66 | ),
67 | r as (
68 | select convert(varchar(max), decompress(CONVERT(varbinary(max), d.DATAPROP, 1)), 2) as doc
69 | , 5 as pos
70 | from CMOBJECTS o
71 | inner join CMSTOREIDS s on s.CMID = o.CMID
72 | inner join objname n on n.CMID = o.CMID
73 | inner join CMCLASSES c on c.CLASSID = o.CLASSID
74 | inner join CMDATA d on d.CMID = o.CMID
75 |
76 | where d.CONTENTTYPE like 'application/csv%'
77 | and s.STOREID in ($storeID)
78 | ),
79 | cte (
80 | doc
81 | , l
82 | , pos
83 | , curr
84 | , valout
85 | ) as (
86 | -- Loop through the value 2 characters (1 hex value) at a time.
87 | -- Convert each value to ASCII.
88 | -- We'll replace anything small (non-printing characters) with LF to keep it simple.
89 | -- That may not be the best solution.
90 | select
91 | doc
92 | , len(doc) as l
93 | , pos + 2 as pos
94 | , substring(doc, pos, 2) as curr
95 | , case
96 | when convert(int, convert(binary(2), '0x' + substring(doc, pos, 2), 1)) = 9 then ','
97 | when convert(int, convert(binary(2), '0x' + substring(doc, pos, 2), 1)) = 10 then char(10)
98 | when convert(int, convert(binary(2), '0x' + substring(doc, pos, 2), 1)) < 32 then ''
99 | else cast(cast( convert(binary(2), '0x' + substring(doc, pos, 2), 1) as char(1)) as varchar(max))
100 | end as valout
101 | from r
102 | union all
103 | select
104 | doc
105 | , l
106 | , pos + 2 as pos
107 | , substring(doc, pos, 2) as curr
108 | , valout +
109 | case
110 | when convert(int, convert(binary(2), '0x' + substring(doc, pos, 2), 1)) = 9 then ','
111 | when convert(int, convert(binary(2), '0x' + substring(doc, pos, 2), 1)) = 10 then char(10)
112 | when convert(int, convert(binary(2), '0x' + substring(doc, pos, 2), 1)) < 32 then ''
113 | else cast(cast( convert(binary(2), '0x' + substring(doc, pos, 2), 1) as char(1)) as varchar(max))
114 | end as valout
115 | from cte
116 | where pos < l
117 | ),
118 | cte2 as (
119 | -- Rank to identify the final value.
120 | select *
121 | , rank() over (partition by doc order by pos desc) as rnk
122 | from cte
123 | )
124 |
125 | select cast(replace(valout, char(9), ',') as varchar(max)) as valout
126 | from cte2
127 | where rnk = 1
128 | OPTION (MAXRECURSION 0)
129 | "
130 |
131 | $DatabaseServer = Read-Host "Content Store database server name"
132 | $ContentStoreDB = Read-Host "Content Store database name"
133 |
134 | $dataset = Invoke-Sqlcmd $sql -ServerInstance $DatabaseServer -Database $ContentStoreDB -MaxCharLength 1000000 -ConnectionTimeout 30 -QueryTimeout 600 -TrustServerCertificate
135 | $l = $dataset.length
136 | #should be one row
137 | "$l rows found"
138 |
139 | $csv = @()
140 | foreach($row in $dataset) {
141 | $csv += $row.valout
142 | }
143 |
144 | $csv
145 | }
146 | else {
147 | "path not found"
148 | }
149 |
150 |
151 | #=====================================================================================================================
152 | # DDDDD OOO N N EEEEEE DDDDD OOO IIIII N N GGGG SSS TTTTTTT U U FFFFFF FFFFFF
153 | # D D O O N N N E D D O O I N N N G S T U U F F
154 | # D D O O N N N EEEE D D O O I N N N G GGG SSS T U U FFFF FFFF
155 | # D D O O N NN E D D O O I N NN G G S T U U F F
156 | # DDDDD OOO N N EEEEEE DDDDD OOO IIIII N N GGGG SSS T UUUU F F
157 | #=====================================================================================================================
158 |
159 | # log out
160 | $uri = "$uriBase/api/v1/session"
161 | $done = Invoke-RestMethod -Uri $uri -Method Delete -WebSession $Session
162 | }
163 | $done
164 |
--------------------------------------------------------------------------------
/ReportSpecifications/README.md:
--------------------------------------------------------------------------------
1 | # ReportSpecifications
2 | Report samples for various purposes. These contain the report spec xml that can be easily imported into Cognos. If you get an error regarding version compatibility, just check the first line of your own report spec and update the version number in the sample to match your environment.
3 |
4 |
5 |
6 |
Scriptable Reports - Order of Methods
7 |
Demonstrates the order in which different events occur in a page module/custom control combination. Uses OrderOfMethodsPageModule.js and OrderOfMethodsCustomControl.js.
8 |
9 |
Prompt Scripts
10 |
Demonstrates some ways to employ Prompts.js.
11 |
12 |
Parameter Value Automation
13 |
How to set a parameter value automatically and invisibly. One example of where this is helpful is to take advantage of database partitioning. For example, the database is partitioned by year, but the prompt page should not require year. A small, quick query can be employed to determine what years are involved based on the other parameter values, then the year or years passed to the main query to make it faster. Uses Prompts.js and PromptAutoFinish.js
14 |
15 |
Parameter Reporter
16 |
Demonstrates how to use ParamDisplay.js, ParameterDisplay.js, and ParameterCapture.js.
17 |
18 |
Date Calculations
19 |
Demonstrates using MS SQL and Cognos Macros to compute various date values.
20 |
21 |
ToolTips
22 |
Show more detail about a data value in a tooltip.
23 |
24 |
VariableOperator
25 |
Ask the user how to filter.
26 |
27 |
Bursting
28 |
A very simple example of using the bursting feature.
29 |
30 |
CrosstabWithRowLabelHeaders
31 |
Use crosstab spaces to add headers to your row labels.
32 |
33 |
CommaDelimitedList
34 |
Use a repeater table to produce comma-delimited output.
35 |
36 |
ComplexLineChart
37 |
How to format a line chart with multiple dimensions.