Repository navigation
Expand file tree
/
Copy pathReportStats.qll
More file actions
69 lines (51 loc) · 1.48 KB
/
Copy pathReportStats.qll
File metadata and controls
69 lines (51 loc) · 1.48 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
/**
* Provides the `ReportStats` module for reporting database quality statistics.
*/
overlay[local?]
module;
signature module StatsSig {
int getNumberOfOk();
int getNumberOfNotOk();
string getOkText();
string getNotOkText();
}
module ReportStats<StatsSig Stats> {
predicate numberOfOk(string key, int value) {
value = Stats::getNumberOfOk() and
key = "Number of " + Stats::getOkText()
}
predicate numberOfNotOk(string key, int value) {
value = Stats::getNumberOfNotOk() and
key = "Number of " + Stats::getNotOkText()
}
predicate percentageOfOk(string key, float value) {
value = Stats::getNumberOfOk() * 100.0 / (Stats::getNumberOfOk() + Stats::getNumberOfNotOk()) and
key = "Percentage of " + Stats::getOkText()
}
predicate keyValuePair(string key, float value) {
numberOfOk(key, value) or
numberOfNotOk(key, value) or
percentageOfOk(key, value)
}
}
/**
* Stats where each Ok/NotOk occurrence has an associated entity.
*/
signature module EntityStatsSig {
class Candidate {
predicate isOk();
}
string getOkText();
string getNotOkText();
}
module EntityReportStats<EntityStatsSig Input> {
private import Input
private module StatsInput implements StatsSig {
int getNumberOfOk() { result = count(Candidate c | c.isOk()) }
int getNumberOfNotOk() { result = count(Candidate c | not c.isOk()) }
import Input
}
import StatsInput
private module ScalarReport = ReportStats<StatsInput>;
import ScalarReport
}