lib/props-tree-builder.js
function addProperty(
	topNode, scopePropPath, propPattern, clause, options, valuePropsTrees,
	wcPatterns) {

	// process the pattern parts
	let expandChildren = false;
	const propPatternParts = propPattern.split('.');
	const numParts = propPatternParts.length;
	let parentNode = topNode;
	let patternPrefix = topNode.path, patternSuffix = '';
	for (let i = 0; i < numParts; i++) {
		const propName = propPatternParts[i];

		// check if wildcard
		if (propName === '*') {

			// check if allowed
			if (!wcPatterns)
				throw new common.X2SyntaxError(
					`Invalid property path "${propPattern}":` +
						` wild cards are not allowed here.`);

			// set up the expansion
			expandChildren = true;
			if (i < numParts - 1)
				patternSuffix = '.' + propPatternParts.slice(i + 1).join('.');

			// done looping through pattern parts
			break;
		}

		// get the child node
		let node = parentNode.getChild(propName);

		// create new node if necessary
		if (!node) {

			// create new child node
			node = parentNode.addChild(
				propName, clause, scopePropPath, options, propPattern,
				valuePropsTrees);

		} else { // existing node

			// include the existing node in the clause
			node.addClause(clause);
		}

		// add part to the reconstructed pattern prefix
		patternPrefix += propName + '.';

		// advance down the tree
		parentNode = node;
	}

	// expand selected object
	if (!expandChildren && (parentNode.desc.scalarValueType === 'object')) {

		// set up the expansion
		if (wcPatterns)
			expandChildren = true;
		else if (!(options && options.allowLeafObjects)) // check if allowed
			throw new common.X2SyntaxError(
				`Invalid property path "${propPattern}":` +
					` object properties are not allowed here.`);
	}

	// generate expanded patterns
	if (expandChildren) {

		// make sure there is a children container
		if (!parentNode.childrenContainer)
			throw new common.X2SyntaxError(
				`Invalid property pattern "${propPattern}":` +
					` property ${parentNode.desc.container.nestedPath}` +
					`${parentNode.desc.name} of ` +
					`${String(parentNode.desc.container.recordTypeName)}` +
					` is not an object nor reference and cannot be used as an` +
					` intermediate property in a path.`);

		// generate patterns for all nested properties included by default
		parentNode.childrenContainer.allPropertyNames.forEach(propName => {
			const propDesc = parentNode.childrenContainer.getPropertyDesc(
				propName);
			if (propDesc.fetchByDefault)
				wcPatterns.push(patternPrefix + propName + patternSuffix);
		});
	}

	// return the leaf node
	return parentNode;
}
function addProperty(
	topNode, scopePropPath, propPattern, clause, options, valuePropsTrees,
	wcPatterns) {

	// process the pattern parts
	let expandChildren = false;
	const propPatternParts = propPattern.split('.');
	const numParts = propPatternParts.length;
	let parentNode = topNode;
	let patternPrefix = topNode.path, patternSuffix = '';
	for (let i = 0; i < numParts; i++) {
		const propName = propPatternParts[i];

		// check if wildcard
		if (propName === '*') {

			// check if allowed
			if (!wcPatterns)
				throw new common.X2SyntaxError(
					`Invalid property path "${propPattern}":` +
						` wild cards are not allowed here.`);

			// set up the expansion
			expandChildren = true;
			if (i < numParts - 1)
				patternSuffix = '.' + propPatternParts.slice(i + 1).join('.');

			// done looping through pattern parts
			break;
		}

		// get the child node
		let node = parentNode.getChild(propName);

		// create new node if necessary
		if (!node) {

			// create new child node
			node = parentNode.addChild(
				propName, clause, scopePropPath, options, propPattern,
				valuePropsTrees);

		} else { // existing node

			// include the existing node in the clause
			node.addClause(clause);
		}

		// add part to the reconstructed pattern prefix
		patternPrefix += propName + '.';

		// advance down the tree
		parentNode = node;
	}

	// expand selected object
	if (!expandChildren && (parentNode.desc.scalarValueType === 'object')) {

		// set up the expansion
		if (wcPatterns)
			expandChildren = true;
		else if (!(options && options.allowLeafObjects)) // check if allowed
			throw new common.X2SyntaxError(
				`Invalid property path "${propPattern}":` +
					` object properties are not allowed here.`);
	}

	// generate expanded patterns
	if (expandChildren) {

		// make sure there is a children container
		if (!parentNode.childrenContainer)
			throw new common.X2SyntaxError(
				`Invalid property pattern "${propPattern}":` +
					` property ${parentNode.desc.container.nestedPath}` +
					`${parentNode.desc.name} of ` +
					`${String(parentNode.desc.container.recordTypeName)}` +
					` is not an object nor reference and cannot be used as an` +
					` intermediate property in a path.`);

		// generate patterns for all nested properties included by default
		parentNode.childrenContainer.allPropertyNames.forEach(propName => {
			const propDesc = parentNode.childrenContainer.getPropertyDesc(
				propName);
			if (propDesc.fetchByDefault)
				wcPatterns.push(patternPrefix + propName + patternSuffix);
		});
	}

	// return the leaf node
	return parentNode;
}
function addProperty ( topNode , scopePropPath , propPattern , clause , options , valuePropsTrees , wcPatterns ) { // process the pattern parts let expandChildren = false ; const propPatternParts = propPattern . split ( '.' ) ; const numParts = propPatternParts . length ; let parentNode = topNode ; let patternPrefix = topNode . path , patternSuffix = '' ; for ( let i = 0 ; i < numParts ; i ++ ) { const propName = propPatternParts [ i ] ; // check if wildcard if ( propName === '*' ) { // check if allowed if ( ! wcPatterns ) throw new common . X2SyntaxError ( ` ${ propPattern } ` + ` ` ) ; // set up the expansion expandChildren = true ; if ( i < numParts - 1 ) patternSuffix = '.' + propPatternParts . slice ( i + 1 ) . join ( '.' ) ; // done looping through pattern parts break ; } // get the child node let node = parentNode . getChild ( propName ) ; // create new node if necessary if ( ! node ) { // create new child node node = parentNode . addChild ( propName , clause , scopePropPath , options , propPattern , valuePropsTrees ) ; } else { // existing node // include the existing node in the clause node . addClause ( clause ) ; } // add part to the reconstructed pattern prefix patternPrefix += propName + '.' ; // advance down the tree parentNode = node ; } // expand selected object if ( ! expandChildren && ( parentNode . desc . scalarValueType === 'object' ) ) { // set up the expansion if ( wcPatterns ) expandChildren = true ; else if ( ! ( options && options . allowLeafObjects ) ) // check if allowed throw new common . X2SyntaxError ( ` ${ propPattern } ` + ` ` ) ; } // generate expanded patterns if ( expandChildren ) { // make sure there is a children container if ( ! parentNode . childrenContainer ) throw new common . X2SyntaxError ( ` ${ propPattern } ` + ` ${ parentNode . desc . container . nestedPath } ` + ` ${ parentNode . desc . name } ` + ` ${ String ( parentNode . desc . container . recordTypeName ) } ` + ` ` + ` ` ) ; // generate patterns for all nested properties included by default parentNode . childrenContainer . allPropertyNames . forEach ( propName => { const propDesc = parentNode . childrenContainer . getPropertyDesc ( propName ) ; if ( propDesc . fetchByDefault ) wcPatterns . push ( patternPrefix + propName + patternSuffix ) ; } ) ; } // return the leaf node return parentNode ; }
Add property to the properties tree.

@private
@param {module:x2node-dbos~PropertyTreeNode} topNode Top node of the
properties tree.
@param {?string} scopeColPath Path of the scope collection property. If
provided, the pattern may only belong to the scope collection property's axis.
@param {string} propPattern Property pattern. May be a wildcard pattern if the
<code>clause</code> argument is "select".
@param {string} clause The query clause where the property is used.
@param {Map.<string,module:x2node-dbos~PropertyTreeNode>} valuePropsTrees
Map, to which to add generated value property trees.
@param {Array.<string>} wcPatterns Array, to which to add extra patterns
resulting in the wildcard pattern expansion. Not used unless the
<code>clause</code> argument is "select".
@returns {module:x2node-dbos~PropertyTreeNode} The leaf node representing
the property.
Add property to the properties tree .