node-opcua-service-filter 2.76.0 → 2.76.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/check_event_clause.d.ts +17 -17
- package/dist/check_event_clause.js +51 -51
- package/dist/check_where_clause.d.ts +3 -3
- package/dist/check_where_clause.js +249 -249
- package/dist/extract_event_field.d.ts +9 -9
- package/dist/extract_event_field.js +52 -52
- package/dist/filter_context.d.ts +11 -11
- package/dist/filter_context.js +2 -2
- package/dist/imports.d.ts +4 -4
- package/dist/imports.js +18 -18
- package/dist/index.d.ts +13 -13
- package/dist/index.js +61 -61
- package/dist/make_content_filter.d.ts +22 -22
- package/dist/make_content_filter.js +120 -120
- package/dist/on_address_space/extract_event_fields.d.ts +10 -10
- package/dist/on_address_space/extract_event_fields.js +17 -17
- package/dist/on_address_space/filter_context_on_address_space.d.ts +19 -19
- package/dist/on_address_space/filter_context_on_address_space.js +108 -108
- package/dist/on_address_space/index.d.ts +2 -2
- package/dist/on_address_space/index.js +18 -18
- package/dist/resolve_operand.d.ts +4 -4
- package/dist/resolve_operand.js +44 -44
- package/dist/tools_event_filter.d.ts +20 -20
- package/dist/tools_event_filter.js +89 -89
- package/package.json +15 -15
|
@@ -1,17 +1,17 @@
|
|
|
1
|
-
import { SimpleAttributeOperand } from "node-opcua-types";
|
|
2
|
-
import { StatusCode } from "node-opcua-status-code";
|
|
3
|
-
import { BaseNode, UAObjectType } from "node-opcua-address-space-base";
|
|
4
|
-
/**
|
|
5
|
-
* @method checkSelectClause
|
|
6
|
-
* @param parentNode
|
|
7
|
-
* @param selectClause
|
|
8
|
-
* @return {Array<StatusCode>}
|
|
9
|
-
*/
|
|
10
|
-
export declare function checkSelectClause(parentNode: BaseNode, selectClause: SimpleAttributeOperand): StatusCode;
|
|
11
|
-
/**
|
|
12
|
-
* @method checkSelectClauses
|
|
13
|
-
* @param eventTypeNode
|
|
14
|
-
* @param selectClauses
|
|
15
|
-
* @return an array of StatusCode
|
|
16
|
-
*/
|
|
17
|
-
export declare function checkSelectClauses(eventTypeNode: UAObjectType, selectClauses: SimpleAttributeOperand[]): StatusCode[];
|
|
1
|
+
import { SimpleAttributeOperand } from "node-opcua-types";
|
|
2
|
+
import { StatusCode } from "node-opcua-status-code";
|
|
3
|
+
import { BaseNode, UAObjectType } from "node-opcua-address-space-base";
|
|
4
|
+
/**
|
|
5
|
+
* @method checkSelectClause
|
|
6
|
+
* @param parentNode
|
|
7
|
+
* @param selectClause
|
|
8
|
+
* @return {Array<StatusCode>}
|
|
9
|
+
*/
|
|
10
|
+
export declare function checkSelectClause(parentNode: BaseNode, selectClause: SimpleAttributeOperand): StatusCode;
|
|
11
|
+
/**
|
|
12
|
+
* @method checkSelectClauses
|
|
13
|
+
* @param eventTypeNode
|
|
14
|
+
* @param selectClauses
|
|
15
|
+
* @return an array of StatusCode
|
|
16
|
+
*/
|
|
17
|
+
export declare function checkSelectClauses(eventTypeNode: UAObjectType, selectClauses: SimpleAttributeOperand[]): StatusCode[];
|
|
@@ -1,52 +1,52 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.checkSelectClauses = exports.checkSelectClause = void 0;
|
|
4
|
-
/**
|
|
5
|
-
* @module node-opcua-address-space
|
|
6
|
-
*/
|
|
7
|
-
const node_opcua_data_model_1 = require("node-opcua-data-model");
|
|
8
|
-
const node_opcua_service_translate_browse_path_1 = require("node-opcua-service-translate-browse-path");
|
|
9
|
-
const node_opcua_status_code_1 = require("node-opcua-status-code");
|
|
10
|
-
/**
|
|
11
|
-
* @method checkSelectClause
|
|
12
|
-
* @param parentNode
|
|
13
|
-
* @param selectClause
|
|
14
|
-
* @return {Array<StatusCode>}
|
|
15
|
-
*/
|
|
16
|
-
function checkSelectClause(parentNode, selectClause) {
|
|
17
|
-
//
|
|
18
|
-
const addressSpace = parentNode.addressSpace;
|
|
19
|
-
// istanbul ignore next
|
|
20
|
-
if (selectClause.typeDefinitionId.isEmpty()) {
|
|
21
|
-
return node_opcua_status_code_1.StatusCodes.Good;
|
|
22
|
-
}
|
|
23
|
-
const eventTypeNode = addressSpace.findEventType(selectClause.typeDefinitionId);
|
|
24
|
-
if (!eventTypeNode || !(eventTypeNode.nodeClass === node_opcua_data_model_1.NodeClass.ObjectType)) {
|
|
25
|
-
// xx console.log("eventTypeNode = ",selectClause.typeDefinitionId.toString());
|
|
26
|
-
// xx console.log("eventTypeNode = ",eventTypeNode);
|
|
27
|
-
// istanbul ignore next
|
|
28
|
-
if (eventTypeNode) {
|
|
29
|
-
console.log(eventTypeNode.toString());
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
// istanbul ignore next
|
|
33
|
-
if (eventTypeNode.nodeClass !== node_opcua_data_model_1.NodeClass.ObjectType) {
|
|
34
|
-
return node_opcua_status_code_1.StatusCodes.BadTypeMismatch;
|
|
35
|
-
}
|
|
36
|
-
// navigate to the innerNode specified by the browsePath [ QualifiedName]
|
|
37
|
-
const browsePath = (0, node_opcua_service_translate_browse_path_1.constructBrowsePathFromQualifiedName)(eventTypeNode, selectClause.browsePath);
|
|
38
|
-
const browsePathResult = addressSpace.browsePath(browsePath);
|
|
39
|
-
return browsePathResult.statusCode;
|
|
40
|
-
}
|
|
41
|
-
exports.checkSelectClause = checkSelectClause;
|
|
42
|
-
/**
|
|
43
|
-
* @method checkSelectClauses
|
|
44
|
-
* @param eventTypeNode
|
|
45
|
-
* @param selectClauses
|
|
46
|
-
* @return an array of StatusCode
|
|
47
|
-
*/
|
|
48
|
-
function checkSelectClauses(eventTypeNode, selectClauses) {
|
|
49
|
-
return selectClauses.map(checkSelectClause.bind(null, eventTypeNode));
|
|
50
|
-
}
|
|
51
|
-
exports.checkSelectClauses = checkSelectClauses;
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.checkSelectClauses = exports.checkSelectClause = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* @module node-opcua-address-space
|
|
6
|
+
*/
|
|
7
|
+
const node_opcua_data_model_1 = require("node-opcua-data-model");
|
|
8
|
+
const node_opcua_service_translate_browse_path_1 = require("node-opcua-service-translate-browse-path");
|
|
9
|
+
const node_opcua_status_code_1 = require("node-opcua-status-code");
|
|
10
|
+
/**
|
|
11
|
+
* @method checkSelectClause
|
|
12
|
+
* @param parentNode
|
|
13
|
+
* @param selectClause
|
|
14
|
+
* @return {Array<StatusCode>}
|
|
15
|
+
*/
|
|
16
|
+
function checkSelectClause(parentNode, selectClause) {
|
|
17
|
+
//
|
|
18
|
+
const addressSpace = parentNode.addressSpace;
|
|
19
|
+
// istanbul ignore next
|
|
20
|
+
if (selectClause.typeDefinitionId.isEmpty()) {
|
|
21
|
+
return node_opcua_status_code_1.StatusCodes.Good;
|
|
22
|
+
}
|
|
23
|
+
const eventTypeNode = addressSpace.findEventType(selectClause.typeDefinitionId);
|
|
24
|
+
if (!eventTypeNode || !(eventTypeNode.nodeClass === node_opcua_data_model_1.NodeClass.ObjectType)) {
|
|
25
|
+
// xx console.log("eventTypeNode = ",selectClause.typeDefinitionId.toString());
|
|
26
|
+
// xx console.log("eventTypeNode = ",eventTypeNode);
|
|
27
|
+
// istanbul ignore next
|
|
28
|
+
if (eventTypeNode) {
|
|
29
|
+
console.log(eventTypeNode.toString());
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
// istanbul ignore next
|
|
33
|
+
if (eventTypeNode.nodeClass !== node_opcua_data_model_1.NodeClass.ObjectType) {
|
|
34
|
+
return node_opcua_status_code_1.StatusCodes.BadTypeMismatch;
|
|
35
|
+
}
|
|
36
|
+
// navigate to the innerNode specified by the browsePath [ QualifiedName]
|
|
37
|
+
const browsePath = (0, node_opcua_service_translate_browse_path_1.constructBrowsePathFromQualifiedName)(eventTypeNode, selectClause.browsePath);
|
|
38
|
+
const browsePathResult = addressSpace.browsePath(browsePath);
|
|
39
|
+
return browsePathResult.statusCode;
|
|
40
|
+
}
|
|
41
|
+
exports.checkSelectClause = checkSelectClause;
|
|
42
|
+
/**
|
|
43
|
+
* @method checkSelectClauses
|
|
44
|
+
* @param eventTypeNode
|
|
45
|
+
* @param selectClauses
|
|
46
|
+
* @return an array of StatusCode
|
|
47
|
+
*/
|
|
48
|
+
function checkSelectClauses(eventTypeNode, selectClauses) {
|
|
49
|
+
return selectClauses.map(checkSelectClause.bind(null, eventTypeNode));
|
|
50
|
+
}
|
|
51
|
+
exports.checkSelectClauses = checkSelectClauses;
|
|
52
52
|
//# sourceMappingURL=check_event_clause.js.map
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { ContentFilter } from "node-opcua-types";
|
|
2
|
-
import { FilterContext } from "./filter_context";
|
|
3
|
-
export declare function checkFilter(filterContext: FilterContext, contentFilter: ContentFilter): boolean;
|
|
1
|
+
import { ContentFilter } from "node-opcua-types";
|
|
2
|
+
import { FilterContext } from "./filter_context";
|
|
3
|
+
export declare function checkFilter(filterContext: FilterContext, contentFilter: ContentFilter): boolean;
|
|
@@ -1,250 +1,250 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.checkFilter = void 0;
|
|
4
|
-
const node_opcua_types_1 = require("node-opcua-types");
|
|
5
|
-
const node_opcua_variant_1 = require("node-opcua-variant");
|
|
6
|
-
const node_opcua_data_model_1 = require("node-opcua-data-model");
|
|
7
|
-
const node_opcua_nodeid_1 = require("node-opcua-nodeid");
|
|
8
|
-
const node_opcua_debug_1 = require("node-opcua-debug");
|
|
9
|
-
const resolve_operand_1 = require("./resolve_operand");
|
|
10
|
-
const warningLog = (0, node_opcua_debug_1.make_warningLog)("Filter");
|
|
11
|
-
function _coerceToBoolean(value) {
|
|
12
|
-
if (value instanceof node_opcua_variant_1.Variant) {
|
|
13
|
-
return _coerceToBoolean(value.value);
|
|
14
|
-
}
|
|
15
|
-
return !!value;
|
|
16
|
-
}
|
|
17
|
-
function _coerceToNumber(value) {
|
|
18
|
-
if (value instanceof node_opcua_variant_1.Variant) {
|
|
19
|
-
return _coerceToNumber(value.value);
|
|
20
|
-
}
|
|
21
|
-
if (typeof value === "string") {
|
|
22
|
-
return parseInt(value, 10);
|
|
23
|
-
}
|
|
24
|
-
if (typeof value === "boolean") {
|
|
25
|
-
return value ? 1 : 0;
|
|
26
|
-
}
|
|
27
|
-
if (typeof value === "number") {
|
|
28
|
-
return value;
|
|
29
|
-
}
|
|
30
|
-
return 0;
|
|
31
|
-
}
|
|
32
|
-
function evaluateOperand(filterContext, filter, operand, coerce) {
|
|
33
|
-
if (operand instanceof node_opcua_types_1.AttributeOperand) {
|
|
34
|
-
return coerce((0, resolve_operand_1.resolveOperand)(filterContext, operand));
|
|
35
|
-
}
|
|
36
|
-
else if (operand instanceof node_opcua_types_1.SimpleAttributeOperand) {
|
|
37
|
-
return coerce((0, resolve_operand_1.resolveOperand)(filterContext, operand));
|
|
38
|
-
}
|
|
39
|
-
else if (operand instanceof node_opcua_types_1.LiteralOperand) {
|
|
40
|
-
return coerce(operand.value);
|
|
41
|
-
}
|
|
42
|
-
else if (operand instanceof node_opcua_types_1.ElementOperand) {
|
|
43
|
-
const index = operand.index;
|
|
44
|
-
return coerce(checkFilterAtIndex(filterContext, filter, index));
|
|
45
|
-
}
|
|
46
|
-
// istanbul ignore
|
|
47
|
-
return coerce(null);
|
|
48
|
-
}
|
|
49
|
-
function checkOfType(filterContext, ofType) {
|
|
50
|
-
// istanbul ignore next
|
|
51
|
-
if (!ofType || !(ofType instanceof node_opcua_types_1.LiteralOperand)) {
|
|
52
|
-
warningLog("checkOfType : unsupported case ! ofType is not a LiteralOperand , ofType = ", ofType === null || ofType === void 0 ? void 0 : ofType.toString());
|
|
53
|
-
return false;
|
|
54
|
-
}
|
|
55
|
-
// istanbul ignore next
|
|
56
|
-
if (ofType.value.dataType !== node_opcua_variant_1.DataType.NodeId) {
|
|
57
|
-
warningLog("invalid operand type (expecting NodeId); got " + node_opcua_variant_1.DataType[ofType.value.dataType]);
|
|
58
|
-
return false;
|
|
59
|
-
}
|
|
60
|
-
const ofTypeNode = ofType.value.value;
|
|
61
|
-
// istanbul ignore next
|
|
62
|
-
if (!ofTypeNode) {
|
|
63
|
-
return false; // the ofType node is not known, we don't know what to do
|
|
64
|
-
}
|
|
65
|
-
const ofTypeNodeNodeClass = filterContext.getNodeClass(ofTypeNode);
|
|
66
|
-
// istanbul ignore next
|
|
67
|
-
if (ofTypeNodeNodeClass !== node_opcua_data_model_1.NodeClass.ObjectType &&
|
|
68
|
-
ofTypeNodeNodeClass !== node_opcua_data_model_1.NodeClass.VariableType &&
|
|
69
|
-
ofTypeNodeNodeClass !== node_opcua_data_model_1.NodeClass.DataType &&
|
|
70
|
-
ofTypeNodeNodeClass !== node_opcua_data_model_1.NodeClass.ReferenceType) {
|
|
71
|
-
warningLog("operand should be a ObjectType " + ofTypeNode.toString());
|
|
72
|
-
return false;
|
|
73
|
-
}
|
|
74
|
-
if (!filterContext.eventSource || filterContext.eventSource.isEmpty()) {
|
|
75
|
-
return false;
|
|
76
|
-
}
|
|
77
|
-
let sourceTypeDefinition = filterContext.eventSource;
|
|
78
|
-
const sourceNodeClass = filterContext.getNodeClass(filterContext.eventSource);
|
|
79
|
-
if (sourceNodeClass === node_opcua_data_model_1.NodeClass.Object || sourceNodeClass === node_opcua_data_model_1.NodeClass.Variable) {
|
|
80
|
-
sourceTypeDefinition = filterContext.getTypeDefinition(filterContext.eventSource);
|
|
81
|
-
if (!sourceTypeDefinition) {
|
|
82
|
-
return false;
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
return filterContext.isSubtypeOf(sourceTypeDefinition, ofTypeNode);
|
|
86
|
-
}
|
|
87
|
-
function checkNot(filterContext, filter, filteredOperands) {
|
|
88
|
-
const operandA = evaluateOperand(filterContext, filter, filteredOperands[0], _coerceToBoolean);
|
|
89
|
-
return !operandA;
|
|
90
|
-
}
|
|
91
|
-
function checkOr(filterContext, filter, filteredOperands) {
|
|
92
|
-
const operandA = evaluateOperand(filterContext, filter, filteredOperands[0], _coerceToBoolean);
|
|
93
|
-
const operandB = evaluateOperand(filterContext, filter, filteredOperands[1], _coerceToBoolean);
|
|
94
|
-
return operandA || operandB;
|
|
95
|
-
}
|
|
96
|
-
/**
|
|
97
|
-
*
|
|
98
|
-
* TRUE if operand[0] and operand[1] are TRUE.
|
|
99
|
-
* The following restrictions apply to the operands:
|
|
100
|
-
* [0]: Any operand that resolves to a Boolean.
|
|
101
|
-
*
|
|
102
|
-
* [1]: Any operand that resolves to a Boolean.
|
|
103
|
-
* If any operand cannot be resolved to a Boolean it is considered a NULL. See below for a discussion on the handling of NULL.
|
|
104
|
-
*/
|
|
105
|
-
function checkAnd(filterContext, filter, filteredOperands) {
|
|
106
|
-
const operandA = evaluateOperand(filterContext, filter, filteredOperands[0], _coerceToBoolean);
|
|
107
|
-
const operandB = evaluateOperand(filterContext, filter, filteredOperands[1], _coerceToBoolean);
|
|
108
|
-
return operandA && operandB;
|
|
109
|
-
}
|
|
110
|
-
function checkLessThan(filterContext, filter, filteredOperands) {
|
|
111
|
-
const operandA = evaluateOperand(filterContext, filter, filteredOperands[0], _coerceToNumber);
|
|
112
|
-
const operandB = evaluateOperand(filterContext, filter, filteredOperands[1], _coerceToNumber);
|
|
113
|
-
return operandA < operandB;
|
|
114
|
-
}
|
|
115
|
-
function checkLessThanOrEqual(filterContext, filter, filteredOperands) {
|
|
116
|
-
const operandA = evaluateOperand(filterContext, filter, filteredOperands[0], _coerceToNumber);
|
|
117
|
-
const operandB = evaluateOperand(filterContext, filter, filteredOperands[1], _coerceToNumber);
|
|
118
|
-
return operandA <= operandB;
|
|
119
|
-
}
|
|
120
|
-
function checkGreaterThan(filterContext, filter, filteredOperands) {
|
|
121
|
-
const operandA = evaluateOperand(filterContext, filter, filteredOperands[0], _coerceToNumber);
|
|
122
|
-
const operandB = evaluateOperand(filterContext, filter, filteredOperands[1], _coerceToNumber);
|
|
123
|
-
return operandA > operandB;
|
|
124
|
-
}
|
|
125
|
-
function checkGreaterThanOrEqual(filterContext, filter, filteredOperands) {
|
|
126
|
-
const operandA = evaluateOperand(filterContext, filter, filteredOperands[0], _coerceToNumber);
|
|
127
|
-
const operandB = evaluateOperand(filterContext, filter, filteredOperands[1], _coerceToNumber);
|
|
128
|
-
return operandA >= operandB;
|
|
129
|
-
}
|
|
130
|
-
function checkEquals(filterContext, filter, filteredOperands) {
|
|
131
|
-
const operandA = evaluateOperand(filterContext, filter, filteredOperands[0], _coerceToNumber);
|
|
132
|
-
const operandB = evaluateOperand(filterContext, filter, filteredOperands[1], _coerceToNumber);
|
|
133
|
-
return operandA === operandB;
|
|
134
|
-
}
|
|
135
|
-
/**
|
|
136
|
-
*
|
|
137
|
-
* TRUE if operand[0] is greater or equal to operand[1] and less than or equal to operand[2].
|
|
138
|
-
* The following restrictions apply to the operands:
|
|
139
|
-
* [0]: Any operand that resolves to an ordered value.
|
|
140
|
-
* [1]: Any operand that resolves to an ordered value.
|
|
141
|
-
* [2]: Any operand that resolves to an ordered value.
|
|
142
|
-
* If the operands are of different types, the system shall perform any implicit conversion to match
|
|
143
|
-
* all operands to a common type. If no implicit conversion is available and the operands are of different
|
|
144
|
-
* types, the particular result is FALSE. See the discussion on data type precedence in Table 123
|
|
145
|
-
* for more information how to convert operands of different types.
|
|
146
|
-
*/
|
|
147
|
-
function checkBetween(filterContext, filter, filteredOperands) {
|
|
148
|
-
const operandA = evaluateOperand(filterContext, filter, filteredOperands[0], _coerceToNumber);
|
|
149
|
-
const operandLow = evaluateOperand(filterContext, filter, filteredOperands[1], _coerceToNumber);
|
|
150
|
-
const operandHigh = evaluateOperand(filterContext, filter, filteredOperands[2], _coerceToNumber);
|
|
151
|
-
return operandA >= operandLow && operandA <= operandHigh;
|
|
152
|
-
}
|
|
153
|
-
/**
|
|
154
|
-
*
|
|
155
|
-
* InList
|
|
156
|
-
* TRUE if operand[0] is equal to one or more of the remaining operands.
|
|
157
|
-
* The Equals Operator is evaluated for operand[0] and each remaining operand in the
|
|
158
|
-
* list. If any Equals evaluation is TRUE, InList returns TRUE
|
|
159
|
-
x*/
|
|
160
|
-
function checkInList(context, filterOperands) {
|
|
161
|
-
const operand0 = filterOperands[0];
|
|
162
|
-
// istanbul ignore next
|
|
163
|
-
if (!(operand0 instanceof node_opcua_types_1.SimpleAttributeOperand)) {
|
|
164
|
-
// unsupported case
|
|
165
|
-
warningLog("FilterOperator.InList operand0 is not a SimpleAttributeOperand " + operand0.constructor.name);
|
|
166
|
-
return false;
|
|
167
|
-
}
|
|
168
|
-
const value = (0, resolve_operand_1.resolveOperand)(context, operand0);
|
|
169
|
-
// istanbul ignore next
|
|
170
|
-
if (value.dataType !== node_opcua_variant_1.DataType.NodeId) {
|
|
171
|
-
return false;
|
|
172
|
-
}
|
|
173
|
-
const nodeId = value.value;
|
|
174
|
-
// istanbul ignore next
|
|
175
|
-
if (!nodeId) {
|
|
176
|
-
return false;
|
|
177
|
-
}
|
|
178
|
-
function _is(nodeId1, operandX) {
|
|
179
|
-
if (operandX.value.dataType !== node_opcua_variant_1.DataType.NodeId) {
|
|
180
|
-
return false;
|
|
181
|
-
}
|
|
182
|
-
const nodeId2 = operandX.value.value;
|
|
183
|
-
const nodeClass = context.getNodeClass(nodeId2);
|
|
184
|
-
if (nodeClass === node_opcua_data_model_1.NodeClass.Unspecified) {
|
|
185
|
-
return false;
|
|
186
|
-
}
|
|
187
|
-
return (0, node_opcua_nodeid_1.sameNodeId)(nodeId1, nodeId2);
|
|
188
|
-
}
|
|
189
|
-
for (let i = 1; i < filterOperands.length; i++) {
|
|
190
|
-
const filterOperand = filterOperands[i];
|
|
191
|
-
if (filterOperand instanceof node_opcua_types_1.LiteralOperand && _is(nodeId, filterOperand)) {
|
|
192
|
-
return true;
|
|
193
|
-
}
|
|
194
|
-
}
|
|
195
|
-
return false;
|
|
196
|
-
}
|
|
197
|
-
// eslint-disable-next-line complexity
|
|
198
|
-
function checkFilterAtIndex(filterContext, filter, index) {
|
|
199
|
-
if (!filter.elements || filter.elements.length === 0) {
|
|
200
|
-
return true;
|
|
201
|
-
}
|
|
202
|
-
const element = filter.elements[index];
|
|
203
|
-
// istanbul ignore next
|
|
204
|
-
if (!element) {
|
|
205
|
-
return true;
|
|
206
|
-
}
|
|
207
|
-
const filterOperands = element.filterOperands || [];
|
|
208
|
-
switch (element.filterOperator) {
|
|
209
|
-
case node_opcua_types_1.FilterOperator.Equals:
|
|
210
|
-
return checkEquals(filterContext, filter, filterOperands);
|
|
211
|
-
case node_opcua_types_1.FilterOperator.LessThan:
|
|
212
|
-
return checkLessThan(filterContext, filter, filterOperands);
|
|
213
|
-
case node_opcua_types_1.FilterOperator.LessThanOrEqual:
|
|
214
|
-
return checkLessThanOrEqual(filterContext, filter, filterOperands);
|
|
215
|
-
case node_opcua_types_1.FilterOperator.GreaterThan:
|
|
216
|
-
return checkGreaterThan(filterContext, filter, filterOperands);
|
|
217
|
-
case node_opcua_types_1.FilterOperator.GreaterThanOrEqual:
|
|
218
|
-
return checkGreaterThanOrEqual(filterContext, filter, filterOperands);
|
|
219
|
-
case node_opcua_types_1.FilterOperator.Between:
|
|
220
|
-
return checkBetween(filterContext, filter, filterOperands);
|
|
221
|
-
case node_opcua_types_1.FilterOperator.And:
|
|
222
|
-
return checkAnd(filterContext, filter, filterOperands);
|
|
223
|
-
case node_opcua_types_1.FilterOperator.Or:
|
|
224
|
-
return checkOr(filterContext, filter, filterOperands);
|
|
225
|
-
case node_opcua_types_1.FilterOperator.Not:
|
|
226
|
-
return checkNot(filterContext, filter, filterOperands);
|
|
227
|
-
case node_opcua_types_1.FilterOperator.OfType:
|
|
228
|
-
return checkOfType(filterContext, element.filterOperands[0]);
|
|
229
|
-
case node_opcua_types_1.FilterOperator.InList:
|
|
230
|
-
return checkInList(filterContext, filterOperands);
|
|
231
|
-
case node_opcua_types_1.FilterOperator.RelatedTo:
|
|
232
|
-
case node_opcua_types_1.FilterOperator.Like:
|
|
233
|
-
case node_opcua_types_1.FilterOperator.BitwiseAnd:
|
|
234
|
-
case node_opcua_types_1.FilterOperator.BitwiseOr:
|
|
235
|
-
case node_opcua_types_1.FilterOperator.Cast:
|
|
236
|
-
case node_opcua_types_1.FilterOperator.InView:
|
|
237
|
-
case node_opcua_types_1.FilterOperator.IsNull:
|
|
238
|
-
default:
|
|
239
|
-
// from Spec OPC Unified Architecture, Part 4 133 Release 1.04
|
|
240
|
-
// Any basic FilterOperator in Table 119 may be used in the whereClause, however, only the
|
|
241
|
-
// OfType_14 FilterOperator from Table 120 is permitted.
|
|
242
|
-
warningLog(`checkFilter: operator ${node_opcua_types_1.FilterOperator[element.filterOperator]} is currently not supported in filter`);
|
|
243
|
-
return false;
|
|
244
|
-
}
|
|
245
|
-
}
|
|
246
|
-
function checkFilter(filterContext, contentFilter) {
|
|
247
|
-
return checkFilterAtIndex(filterContext, contentFilter, 0);
|
|
248
|
-
}
|
|
249
|
-
exports.checkFilter = checkFilter;
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.checkFilter = void 0;
|
|
4
|
+
const node_opcua_types_1 = require("node-opcua-types");
|
|
5
|
+
const node_opcua_variant_1 = require("node-opcua-variant");
|
|
6
|
+
const node_opcua_data_model_1 = require("node-opcua-data-model");
|
|
7
|
+
const node_opcua_nodeid_1 = require("node-opcua-nodeid");
|
|
8
|
+
const node_opcua_debug_1 = require("node-opcua-debug");
|
|
9
|
+
const resolve_operand_1 = require("./resolve_operand");
|
|
10
|
+
const warningLog = (0, node_opcua_debug_1.make_warningLog)("Filter");
|
|
11
|
+
function _coerceToBoolean(value) {
|
|
12
|
+
if (value instanceof node_opcua_variant_1.Variant) {
|
|
13
|
+
return _coerceToBoolean(value.value);
|
|
14
|
+
}
|
|
15
|
+
return !!value;
|
|
16
|
+
}
|
|
17
|
+
function _coerceToNumber(value) {
|
|
18
|
+
if (value instanceof node_opcua_variant_1.Variant) {
|
|
19
|
+
return _coerceToNumber(value.value);
|
|
20
|
+
}
|
|
21
|
+
if (typeof value === "string") {
|
|
22
|
+
return parseInt(value, 10);
|
|
23
|
+
}
|
|
24
|
+
if (typeof value === "boolean") {
|
|
25
|
+
return value ? 1 : 0;
|
|
26
|
+
}
|
|
27
|
+
if (typeof value === "number") {
|
|
28
|
+
return value;
|
|
29
|
+
}
|
|
30
|
+
return 0;
|
|
31
|
+
}
|
|
32
|
+
function evaluateOperand(filterContext, filter, operand, coerce) {
|
|
33
|
+
if (operand instanceof node_opcua_types_1.AttributeOperand) {
|
|
34
|
+
return coerce((0, resolve_operand_1.resolveOperand)(filterContext, operand));
|
|
35
|
+
}
|
|
36
|
+
else if (operand instanceof node_opcua_types_1.SimpleAttributeOperand) {
|
|
37
|
+
return coerce((0, resolve_operand_1.resolveOperand)(filterContext, operand));
|
|
38
|
+
}
|
|
39
|
+
else if (operand instanceof node_opcua_types_1.LiteralOperand) {
|
|
40
|
+
return coerce(operand.value);
|
|
41
|
+
}
|
|
42
|
+
else if (operand instanceof node_opcua_types_1.ElementOperand) {
|
|
43
|
+
const index = operand.index;
|
|
44
|
+
return coerce(checkFilterAtIndex(filterContext, filter, index));
|
|
45
|
+
}
|
|
46
|
+
// istanbul ignore
|
|
47
|
+
return coerce(null);
|
|
48
|
+
}
|
|
49
|
+
function checkOfType(filterContext, ofType) {
|
|
50
|
+
// istanbul ignore next
|
|
51
|
+
if (!ofType || !(ofType instanceof node_opcua_types_1.LiteralOperand)) {
|
|
52
|
+
warningLog("checkOfType : unsupported case ! ofType is not a LiteralOperand , ofType = ", ofType === null || ofType === void 0 ? void 0 : ofType.toString());
|
|
53
|
+
return false;
|
|
54
|
+
}
|
|
55
|
+
// istanbul ignore next
|
|
56
|
+
if (ofType.value.dataType !== node_opcua_variant_1.DataType.NodeId) {
|
|
57
|
+
warningLog("invalid operand type (expecting NodeId); got " + node_opcua_variant_1.DataType[ofType.value.dataType]);
|
|
58
|
+
return false;
|
|
59
|
+
}
|
|
60
|
+
const ofTypeNode = ofType.value.value;
|
|
61
|
+
// istanbul ignore next
|
|
62
|
+
if (!ofTypeNode) {
|
|
63
|
+
return false; // the ofType node is not known, we don't know what to do
|
|
64
|
+
}
|
|
65
|
+
const ofTypeNodeNodeClass = filterContext.getNodeClass(ofTypeNode);
|
|
66
|
+
// istanbul ignore next
|
|
67
|
+
if (ofTypeNodeNodeClass !== node_opcua_data_model_1.NodeClass.ObjectType &&
|
|
68
|
+
ofTypeNodeNodeClass !== node_opcua_data_model_1.NodeClass.VariableType &&
|
|
69
|
+
ofTypeNodeNodeClass !== node_opcua_data_model_1.NodeClass.DataType &&
|
|
70
|
+
ofTypeNodeNodeClass !== node_opcua_data_model_1.NodeClass.ReferenceType) {
|
|
71
|
+
warningLog("operand should be a ObjectType " + ofTypeNode.toString());
|
|
72
|
+
return false;
|
|
73
|
+
}
|
|
74
|
+
if (!filterContext.eventSource || filterContext.eventSource.isEmpty()) {
|
|
75
|
+
return false;
|
|
76
|
+
}
|
|
77
|
+
let sourceTypeDefinition = filterContext.eventSource;
|
|
78
|
+
const sourceNodeClass = filterContext.getNodeClass(filterContext.eventSource);
|
|
79
|
+
if (sourceNodeClass === node_opcua_data_model_1.NodeClass.Object || sourceNodeClass === node_opcua_data_model_1.NodeClass.Variable) {
|
|
80
|
+
sourceTypeDefinition = filterContext.getTypeDefinition(filterContext.eventSource);
|
|
81
|
+
if (!sourceTypeDefinition) {
|
|
82
|
+
return false;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
return filterContext.isSubtypeOf(sourceTypeDefinition, ofTypeNode);
|
|
86
|
+
}
|
|
87
|
+
function checkNot(filterContext, filter, filteredOperands) {
|
|
88
|
+
const operandA = evaluateOperand(filterContext, filter, filteredOperands[0], _coerceToBoolean);
|
|
89
|
+
return !operandA;
|
|
90
|
+
}
|
|
91
|
+
function checkOr(filterContext, filter, filteredOperands) {
|
|
92
|
+
const operandA = evaluateOperand(filterContext, filter, filteredOperands[0], _coerceToBoolean);
|
|
93
|
+
const operandB = evaluateOperand(filterContext, filter, filteredOperands[1], _coerceToBoolean);
|
|
94
|
+
return operandA || operandB;
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
*
|
|
98
|
+
* TRUE if operand[0] and operand[1] are TRUE.
|
|
99
|
+
* The following restrictions apply to the operands:
|
|
100
|
+
* [0]: Any operand that resolves to a Boolean.
|
|
101
|
+
*
|
|
102
|
+
* [1]: Any operand that resolves to a Boolean.
|
|
103
|
+
* If any operand cannot be resolved to a Boolean it is considered a NULL. See below for a discussion on the handling of NULL.
|
|
104
|
+
*/
|
|
105
|
+
function checkAnd(filterContext, filter, filteredOperands) {
|
|
106
|
+
const operandA = evaluateOperand(filterContext, filter, filteredOperands[0], _coerceToBoolean);
|
|
107
|
+
const operandB = evaluateOperand(filterContext, filter, filteredOperands[1], _coerceToBoolean);
|
|
108
|
+
return operandA && operandB;
|
|
109
|
+
}
|
|
110
|
+
function checkLessThan(filterContext, filter, filteredOperands) {
|
|
111
|
+
const operandA = evaluateOperand(filterContext, filter, filteredOperands[0], _coerceToNumber);
|
|
112
|
+
const operandB = evaluateOperand(filterContext, filter, filteredOperands[1], _coerceToNumber);
|
|
113
|
+
return operandA < operandB;
|
|
114
|
+
}
|
|
115
|
+
function checkLessThanOrEqual(filterContext, filter, filteredOperands) {
|
|
116
|
+
const operandA = evaluateOperand(filterContext, filter, filteredOperands[0], _coerceToNumber);
|
|
117
|
+
const operandB = evaluateOperand(filterContext, filter, filteredOperands[1], _coerceToNumber);
|
|
118
|
+
return operandA <= operandB;
|
|
119
|
+
}
|
|
120
|
+
function checkGreaterThan(filterContext, filter, filteredOperands) {
|
|
121
|
+
const operandA = evaluateOperand(filterContext, filter, filteredOperands[0], _coerceToNumber);
|
|
122
|
+
const operandB = evaluateOperand(filterContext, filter, filteredOperands[1], _coerceToNumber);
|
|
123
|
+
return operandA > operandB;
|
|
124
|
+
}
|
|
125
|
+
function checkGreaterThanOrEqual(filterContext, filter, filteredOperands) {
|
|
126
|
+
const operandA = evaluateOperand(filterContext, filter, filteredOperands[0], _coerceToNumber);
|
|
127
|
+
const operandB = evaluateOperand(filterContext, filter, filteredOperands[1], _coerceToNumber);
|
|
128
|
+
return operandA >= operandB;
|
|
129
|
+
}
|
|
130
|
+
function checkEquals(filterContext, filter, filteredOperands) {
|
|
131
|
+
const operandA = evaluateOperand(filterContext, filter, filteredOperands[0], _coerceToNumber);
|
|
132
|
+
const operandB = evaluateOperand(filterContext, filter, filteredOperands[1], _coerceToNumber);
|
|
133
|
+
return operandA === operandB;
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
*
|
|
137
|
+
* TRUE if operand[0] is greater or equal to operand[1] and less than or equal to operand[2].
|
|
138
|
+
* The following restrictions apply to the operands:
|
|
139
|
+
* [0]: Any operand that resolves to an ordered value.
|
|
140
|
+
* [1]: Any operand that resolves to an ordered value.
|
|
141
|
+
* [2]: Any operand that resolves to an ordered value.
|
|
142
|
+
* If the operands are of different types, the system shall perform any implicit conversion to match
|
|
143
|
+
* all operands to a common type. If no implicit conversion is available and the operands are of different
|
|
144
|
+
* types, the particular result is FALSE. See the discussion on data type precedence in Table 123
|
|
145
|
+
* for more information how to convert operands of different types.
|
|
146
|
+
*/
|
|
147
|
+
function checkBetween(filterContext, filter, filteredOperands) {
|
|
148
|
+
const operandA = evaluateOperand(filterContext, filter, filteredOperands[0], _coerceToNumber);
|
|
149
|
+
const operandLow = evaluateOperand(filterContext, filter, filteredOperands[1], _coerceToNumber);
|
|
150
|
+
const operandHigh = evaluateOperand(filterContext, filter, filteredOperands[2], _coerceToNumber);
|
|
151
|
+
return operandA >= operandLow && operandA <= operandHigh;
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
*
|
|
155
|
+
* InList
|
|
156
|
+
* TRUE if operand[0] is equal to one or more of the remaining operands.
|
|
157
|
+
* The Equals Operator is evaluated for operand[0] and each remaining operand in the
|
|
158
|
+
* list. If any Equals evaluation is TRUE, InList returns TRUE
|
|
159
|
+
x*/
|
|
160
|
+
function checkInList(context, filterOperands) {
|
|
161
|
+
const operand0 = filterOperands[0];
|
|
162
|
+
// istanbul ignore next
|
|
163
|
+
if (!(operand0 instanceof node_opcua_types_1.SimpleAttributeOperand)) {
|
|
164
|
+
// unsupported case
|
|
165
|
+
warningLog("FilterOperator.InList operand0 is not a SimpleAttributeOperand " + operand0.constructor.name);
|
|
166
|
+
return false;
|
|
167
|
+
}
|
|
168
|
+
const value = (0, resolve_operand_1.resolveOperand)(context, operand0);
|
|
169
|
+
// istanbul ignore next
|
|
170
|
+
if (value.dataType !== node_opcua_variant_1.DataType.NodeId) {
|
|
171
|
+
return false;
|
|
172
|
+
}
|
|
173
|
+
const nodeId = value.value;
|
|
174
|
+
// istanbul ignore next
|
|
175
|
+
if (!nodeId) {
|
|
176
|
+
return false;
|
|
177
|
+
}
|
|
178
|
+
function _is(nodeId1, operandX) {
|
|
179
|
+
if (operandX.value.dataType !== node_opcua_variant_1.DataType.NodeId) {
|
|
180
|
+
return false;
|
|
181
|
+
}
|
|
182
|
+
const nodeId2 = operandX.value.value;
|
|
183
|
+
const nodeClass = context.getNodeClass(nodeId2);
|
|
184
|
+
if (nodeClass === node_opcua_data_model_1.NodeClass.Unspecified) {
|
|
185
|
+
return false;
|
|
186
|
+
}
|
|
187
|
+
return (0, node_opcua_nodeid_1.sameNodeId)(nodeId1, nodeId2);
|
|
188
|
+
}
|
|
189
|
+
for (let i = 1; i < filterOperands.length; i++) {
|
|
190
|
+
const filterOperand = filterOperands[i];
|
|
191
|
+
if (filterOperand instanceof node_opcua_types_1.LiteralOperand && _is(nodeId, filterOperand)) {
|
|
192
|
+
return true;
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
return false;
|
|
196
|
+
}
|
|
197
|
+
// eslint-disable-next-line complexity
|
|
198
|
+
function checkFilterAtIndex(filterContext, filter, index) {
|
|
199
|
+
if (!filter.elements || filter.elements.length === 0) {
|
|
200
|
+
return true;
|
|
201
|
+
}
|
|
202
|
+
const element = filter.elements[index];
|
|
203
|
+
// istanbul ignore next
|
|
204
|
+
if (!element) {
|
|
205
|
+
return true;
|
|
206
|
+
}
|
|
207
|
+
const filterOperands = element.filterOperands || [];
|
|
208
|
+
switch (element.filterOperator) {
|
|
209
|
+
case node_opcua_types_1.FilterOperator.Equals:
|
|
210
|
+
return checkEquals(filterContext, filter, filterOperands);
|
|
211
|
+
case node_opcua_types_1.FilterOperator.LessThan:
|
|
212
|
+
return checkLessThan(filterContext, filter, filterOperands);
|
|
213
|
+
case node_opcua_types_1.FilterOperator.LessThanOrEqual:
|
|
214
|
+
return checkLessThanOrEqual(filterContext, filter, filterOperands);
|
|
215
|
+
case node_opcua_types_1.FilterOperator.GreaterThan:
|
|
216
|
+
return checkGreaterThan(filterContext, filter, filterOperands);
|
|
217
|
+
case node_opcua_types_1.FilterOperator.GreaterThanOrEqual:
|
|
218
|
+
return checkGreaterThanOrEqual(filterContext, filter, filterOperands);
|
|
219
|
+
case node_opcua_types_1.FilterOperator.Between:
|
|
220
|
+
return checkBetween(filterContext, filter, filterOperands);
|
|
221
|
+
case node_opcua_types_1.FilterOperator.And:
|
|
222
|
+
return checkAnd(filterContext, filter, filterOperands);
|
|
223
|
+
case node_opcua_types_1.FilterOperator.Or:
|
|
224
|
+
return checkOr(filterContext, filter, filterOperands);
|
|
225
|
+
case node_opcua_types_1.FilterOperator.Not:
|
|
226
|
+
return checkNot(filterContext, filter, filterOperands);
|
|
227
|
+
case node_opcua_types_1.FilterOperator.OfType:
|
|
228
|
+
return checkOfType(filterContext, element.filterOperands[0]);
|
|
229
|
+
case node_opcua_types_1.FilterOperator.InList:
|
|
230
|
+
return checkInList(filterContext, filterOperands);
|
|
231
|
+
case node_opcua_types_1.FilterOperator.RelatedTo:
|
|
232
|
+
case node_opcua_types_1.FilterOperator.Like:
|
|
233
|
+
case node_opcua_types_1.FilterOperator.BitwiseAnd:
|
|
234
|
+
case node_opcua_types_1.FilterOperator.BitwiseOr:
|
|
235
|
+
case node_opcua_types_1.FilterOperator.Cast:
|
|
236
|
+
case node_opcua_types_1.FilterOperator.InView:
|
|
237
|
+
case node_opcua_types_1.FilterOperator.IsNull:
|
|
238
|
+
default:
|
|
239
|
+
// from Spec OPC Unified Architecture, Part 4 133 Release 1.04
|
|
240
|
+
// Any basic FilterOperator in Table 119 may be used in the whereClause, however, only the
|
|
241
|
+
// OfType_14 FilterOperator from Table 120 is permitted.
|
|
242
|
+
warningLog(`checkFilter: operator ${node_opcua_types_1.FilterOperator[element.filterOperator]} is currently not supported in filter`);
|
|
243
|
+
return false;
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
function checkFilter(filterContext, contentFilter) {
|
|
247
|
+
return checkFilterAtIndex(filterContext, contentFilter, 0);
|
|
248
|
+
}
|
|
249
|
+
exports.checkFilter = checkFilter;
|
|
250
250
|
//# sourceMappingURL=check_where_clause.js.map
|