-
Notifications
You must be signed in to change notification settings - Fork 2
/
netexUniqueConstraints.js
71 lines (63 loc) · 1.69 KB
/
netexUniqueConstraints.js
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
70
71
/**
* @name netexUniqueConstraints
* @overview
* @author Concrete IT
*/
const name = "netexUniqueConstraints";
const errors = require("errors");
const types = require("types");
/**
* Make sure every Line is referenced from another element
* @param {types.Context} ctx
* @return {errors.ScriptError[]?}
*/
function main(ctx) {
const xsd = ctx.xsd.parse("netex@1.2").get();
mapConstraints(xsd, ".//xsd:unique")
.forEach(v => ctx.worker.queue("uniqueConstraints", ctx.document, v));
return ctx.worker.run().get();
}
/**
* @param {types.Node} node
* @param {string} selector
*/
function mapConstraints(node, selector) {
return node.find(selector)
.get()
.map(n => {
return {
name: n.attr("name").get(),
selector: n.first(".//xsd:selector").get().attr("xpath").get().replace(/netex:/g, ""),
fields: n.find(".//xsd:field").get().map(n => n.attr("xpath").get()),
};
});
}
/**
* @param {types.Context} ctx
* @return {errors.ScriptError[]?}
*/
function uniqueConstraints(ctx) {
const res = [];
ctx.node.find(ctx.params.selector)
.getOrElse(() => [])
.reduce((/** @type {Record<string, boolean>} */ o, /** @type {types.Node} */ n) => {
const k = attrHash(n, ctx.params.fields);
if (o[k]) {
res.push(errors.ConsistencyError(
`Duplicate reference violates unique constraint "${ctx.params.name}" (key: ${k})`,
{ line: n.line() },
));
}
o[k] = true
return o
}, {});
return res
}
/**
* @param {types.Node} node
* @param {string[]} fields
* @return {string}
*/
function attrHash(node, fields) {
return fields.map((/** @type {string} */ v) => node.textAt(v).get()).join(";");
}