<#--
   ******************************************************
   *
   *                       NOTICE
   *
   *  THIS SOFTWARE IS THE PROPERTY OF AND CONTAINS
   *  CONFIDENTIAL INFORMATION OF INFOR, AND SHALL NOT BE
   *  COPIED, USED, NOR DISCLOSED WITHOUT EXPRESS WRITTEN
   *  AUTHORIZATION.  ALTHOUGH PUBLICATION IS NOT
   *  INTENDED, IN THE EVENT OF PUBLICATION, THE
   *  FOLLOWING NOTICE IS APPLICABLE:
   *
   *  Copyright © 2009 Infor. All rights reserved.
   *  The word and design marks set forth herein are
   *  trademarks and/or registered trademarks of Infor
   *  and/or related affiliates and subsidiaries.
   *  All rights reserved. All other trademarks listed
   *  herein are the property of their respective owners.
   *  www.infor.com.
   *
   ******************************************************
  -->
<#if common.queryMethodPresent()>
|****************************** Query List/Show ******************************

<@source.query_statuses/>
	#define MAX_QUERY_LENGTH	8192
<#assign counter = 0>
<#list protected.listProtectedComponents() as c>
	<#list c.componentImplementation.componentImplementationTable as cit>
		<#assign counter = counter + 1>
		<#assign table=cit.table.idref>
		<#assign tableName=table.name>
	#define ${c.componentName}.${tableName}_${cit.position} "t${counter}"
	</#list>
</#list><#--list protected.listProtectedComponents() as c-->

<#list protected.listProtectedComponents() as c>
	|* Query vars for component ${c.componentName}
	string	bl.tables.inselection.${c.componentName}(MAX_QUERY_LENGTH)
	string	bl.select.${c.componentName}(MAX_QUERY_LENGTH)
	string	bl.from.${c.componentName}(MAX_QUERY_LENGTH)
	string	bl.where.${c.componentName}(MAX_QUERY_LENGTH)
	<#if c.componentImplementation.componentFilterHookExpression?exists && c.componentImplementation.componentFilterHookExpression?has_content>
	string  bl.component.filter.hook.${c.componentName}(MAX_QUERY_LENGTH)
	</#if>
	string	bl.orderby.${c.componentName}(MAX_QUERY_LENGTH)
	long	bl.select.bind.counter.${c.componentName}
	long	bl.select.bind.max.${c.componentName}
	string	bl.select.bind.${c.componentName}(1,1)	based
	string	bl.where.bind.${c.componentName}(1,1)	based
	long	bl.where.bind.counter.${c.componentName}
	long	bl.where.bind.max.${c.componentName}
	long	bl.fetches.${c.componentName}
	long	bl.sql.pointer.${c.componentName}
	long	bl.${c.componentName}.query.status
	<#-- list query methods -->
	<#list c.componentImplementation.attributeImplementation as ai>
	boolean bl.${c.componentName}.${common.getAttributeName(ai)}.selected
	boolean bl.${c.componentName}.${common.getAttributeName(ai)}.filtered
	</#list><#--list c.componentImplementation.attributeImplementation as ai-->
	boolean	bl.component.filter.set.${c.componentName}
	<#list c.componentImplementation.componentImplementationTable as cit>
		<#assign table=cit.table.idref>
		<#assign tableName=table.name>
	boolean	bl.${c.componentName}.${tableName}_${cit.position}.filter.is.set
	</#list>
</#list><#--list protected.listProtectedComponents() as c-->

function extern string <@names.ST_DLLCode/>.retrieve.table_alias(long	i)
{
	DllUsage
	EndDllUsage

	on case i
<#assign counter = 0>
<#list protected.listProtectedComponents() as c>
	<#list c.componentImplementation.componentImplementationTable as cit>
		<#assign counter = counter + 1>
		<#assign table=cit.table.idref>
		<#assign tableName=table.name>
	case ${counter}:
		return ("t${counter} ${tableName} (${cit.position}) [Component:${c.componentName}]")
	</#list>
</#list><#--list protected.listProtectedComponents() as c-->
	endcase

	return("")
}

function extern long <@names.ST_DLLCode/>.retrieve.table_alias.count()
{
	DllUsage
	EndDllUsage

	return(${counter})
}

function extern
long <@names.ST_DLLCode/>.set.sorting.expression(boolean	i.sortingExpressionSet)
{				
	bl.SortingExpressionSet = i.sortingExpressionSet

	return(0)
}

function extern
long <@names.ST_DLLCode/>.set.request.filter(
				const	xmlnode	i.filter)
{
	DllUsage
	EndDllUsage

	long	retl

	bl.Filter = i.filter
	
	|* read filter from filter node
	retl = tlbct.dll1000.readFilter(	
				"<@names.ST_Object/>",
				"<@names.ST_DLLCode/>.get.AttributeData." & bl.method,
				bl.Filter,
				bl.FilterExpression)
	RETIFNOK(retl)

	|* set all attributes specified in postfilter
	if bl.PostFilter then
		bl.FilteredAttributes = xmlNewNode("postFiltered")
<#list protected.listProtectedComponents() as c>
	<#list c.componentImplementation.attributeImplementation as ai>
		if bl.${c.componentName}.${common.getAttributeName(ai)}.filtered then
			retl = xmlNewDataElement(
				"attribute", 
				"${c.componentName}.${common.getAttributeName(ai)}", 
				bl.FilteredAttributes)
		endif
	</#list>
</#list>
	endif
<#list protected.listProtectedComponents() as c>
	<#list c.componentImplementation.componentImplementationTable as cit>
		<#assign table=cit.table.idref>
		<#assign tableName=table.name>
		<#if cit.isRootTable>
			<#assign first=true>
			<#list protected.listNonRootTablesOrder(c.componentImplementation, "${tableName}_${cit.position}")?reverse as nrto>
				<#if first=true>
					<#assign first=false>

	|* set for all components filter dependencies for
	|* join on non-root tables	
				</#if>
	if bl.${c.componentName}.${nrto.toTable}.filter.is.set then
		bl.${c.componentName}.${nrto.fromTable}.filter.is.set = true
	endif
			</#list>
		</#if>
	</#list>
</#list>

	return(0)
}

function extern
long <@names.ST_DLLCode/>.get.postfilter(
				ref	boolean	o.postfilter)
{
	DllUsage
	EndDllUsage

	o.postfilter = bl.PostFilter

	return(0)
}

function extern
long <@names.ST_DLLCode/>.get.filter(
				ref	boolean	o.filter)
{
	DllUsage
	EndDllUsage

	o.filter = bl.Filter

	return(0)
}

function extern
long <@names.ST_DLLCode/>.get.filteredAttributes(
				ref	xmlNode	o.filteredAttributes)
{
	DllUsage
	EndDllUsage

	o.filteredAttributes = bl.FilteredAttributes

	return(0)
}

function extern
long <@names.ST_DLLCode/>.get.filter.expression(
				ref	string	o.filterExpression)
{
	DllUsage
	EndDllUsage

	o.filterExpression = bl.FilterExpression

	return(0)
}
<#list protected.listProtectedComponents() as c>
	<#list c.componentImplementation.componentImplementationTable as cit>
		<#assign table=cit.table.idref>
		<#assign tableName=table.name>
		<#if cit.isRootTable>
			<#if c.parentComponentImplementation?exists>
			
function string parentComponentJoin.${c.componentName}()
{
	string	parentJoin(MAX_QUERY_LENGTH)

				<#list c.parentComponentImplementation.componentImplementationTable as pcit>
					<#assign parentTable=pcit.table.idref>
					<#assign parentTableName=parentTable.name>
					<#if pcit.isRootTable>
						<#assign firstjoin=true>
						<#list common.listRelationshipDetails(c.parentComponentImplementation, c.relationshipImplementation) as rd>
							<#if rd.toAttributeImplementation.column?exists>
							<#if firstjoin=true>
								<#assign firstjoin=false>
								<#assign firstfilter=true>	
								<#list protected.listProtectedParentComponents(c.componentName) as pc>
									<#if firstfilter=true>
										<#assign firstfilter=false>
	if bl.component.filter.set.${pc.componentName} = true									
									<#else>
	or bl.component.filter.set.${pc.componentName} = true									
									</#if>
	or hasSiblingChildFilter.${pc.componentName}()
								</#list>
	then
		|* add parent root table with filter inner join
		parentJoin = " inner join ${parentTableName} " & ${c.parentComponentName}.${parentTableName}_${pcit.position}
		parentJoin = parentJoin & " on "
							<#else>
		parentJoin = parentJoin & " and "							
							</#if>
		parentJoin = parentJoin & ${rd.toComponentName}.${tableName}_${cit.position} & ".${rd.toAttributeImplementation.column.value} = "
		parentJoin = parentJoin & ${rd.fromComponentName}.${parentTableName}_${pcit.position} & ".${rd.fromAttributeImplementation.column.value}"
							</#if><#--if rd.toAttributeImplementation.column?exists-->
							<#if !rd_has_next && !firstjoin>
								<#if protected.hasNonRootTable(c.parentComponentImplementation)>
				
		|* add parent non root table with filter join
		parentJoin = parentJoin & nonRootJoin.${c.parentComponentName}.${parentTableName}_${pcit.position}()
								</#if>
								<#if protected.hasProtectedParentComponents(c.parentComponentName)>

		|* add parent of parent component join when filter applied	
		parentJoin = parentJoin & parentComponentJoin.${c.parentComponentName}()
								</#if>
	endif
							</#if>
						</#list>
					</#if>
				</#list>

	return(parentJoin)
}
			</#if>
			<#list protected.listProtectedComponents() as cc>
				<#if c.componentName = cc.parentComponentName>

function string childJoin.${c.componentName}.${cc.componentName}(const string joinType)
{
	string	childJoin(MAX_QUERY_LENGTH)
	
	childJoin = ""

					<#list cc.componentImplementation.componentImplementationTable as ccit>
						<#assign childTable=ccit.table.idref>
						<#assign childTableName=childTable.name>
						<#if ccit.isRootTable>					
							<#assign first=true>
							<#list common.listRelationshipDetails(c.componentImplementation, cc.relationshipImplementation) as rd>
								<#if rd.toAttributeImplementation.column?exists>
								<#if first=true>
									<#assign first=false>
	|* add child root table with filter join
	childJoin = childJoin & joinType & "join ${childTableName} " & ${rd.toComponentName}.${childTableName}_${ccit.position}
									<#if protected.hasNonRootTable(cc.componentImplementation)>

	|* add join for child non-root table with filter
	childJoin = childJoin & nonRootJoin.${cc.componentName}.${childTableName}_${ccit.position}()
									</#if>
									<#-- add the child joins -->
									<#list protected.listProtectedComponents() as gcc>
										<#if cc.componentName = gcc.parentComponentName>

	|* add child component with filter join 
	childJoin = childJoin & childComponentJoin.${cc.componentName}(joinType)
										</#if>
									</#list>
	childJoin = childJoin & " on "
								<#else>										
	childJoin = childJoin & " and "										
								</#if>
	childJoin = childJoin & ${rd.toComponentName}.${childTableName}_${ccit.position} & ".${rd.toAttributeImplementation.column.value} = "
	childJoin = childJoin & ${rd.fromComponentName}.${tableName}_${cit.position} & ".${rd.fromAttributeImplementation.column.value}"
								</#if><#--if rd.toAttributeImplementation.column?exists-->
							</#list>
						</#if>
					</#list>
					
	return(childJoin)
}				
				</#if>
			</#list>

function string childComponentJoin.${c.componentName}(const string joinType)
{
	string	childComponentJoin(MAX_QUERY_LENGTH)
	
	childComponentJoin = ""
			<#list protected.listProtectedComponents() as cc>
				<#if c.componentName = cc.parentComponentName>

	if bl.component.filter.set.${cc.componentName} = true
					<#list protected.listProtectedChildComponents(cc.componentName) as pcc>
	or bl.component.filter.set.${pcc.componentName} = true	
					</#list>
	then
		 childComponentJoin = childComponentJoin & childJoin.${c.componentName}.${cc.componentName}(joinType)
	endif
				</#if>
			</#list>

	return(childComponentJoin)
}

function boolean hasSiblingChildFilter.${c.componentName}()
{
	long	hasSiblingChildFilter
	
	hasSiblingChildFilter = 0
			<#list protected.listProtectedComponents() as cc>
				<#if c.componentName = cc.parentComponentName>

	if bl.component.filter.set.${cc.componentName} = true
					<#list protected.listProtectedChildComponents(cc.componentName) as pcc>
	or bl.component.filter.set.${pcc.componentName} = true	
					</#list>
	then
		hasSiblingChildFilter = hasSiblingChildFilter + 1
	endif
				</#if>
			</#list>

	return(hasSiblingChildFilter > 1)
}

function boolean hasChildFilter.${c.componentName}()
{
	boolean	hasChildFilter
	
	hasChildFilter = false
			<#list protected.listProtectedComponents() as cc>
				<#if c.componentName = cc.parentComponentName>

	if bl.component.filter.set.${cc.componentName} = true
					<#list protected.listProtectedChildComponents(cc.componentName) as pcc>
	or bl.component.filter.set.${pcc.componentName} = true	
					</#list>
	then
		hasChildFilter = true
	endif
				</#if>
			</#list>

	return(hasChildFilter)
}

function string childComponentExists.${c.componentName}()
{
	string	childExists(MAX_QUERY_LENGTH)
	string	componentJoin(MAX_QUERY_LENGTH)
	string	sepa(5)
	
	childExists = ""
	sepa = ""
	componentJoin = ""
				<#list protected.listProtectedComponents() as cc>
					<#if c.componentName = cc.parentComponentName>

	|* add exists
	if bl.component.filter.set.${cc.componentName} = true
						<#list protected.listProtectedChildComponents(cc.componentName) as pcc>
	or bl.component.filter.set.${pcc.componentName} = true				
						</#list>
	then
		componentJoin = ""
						<#-- add the exists clause -->
						<#list cc.componentImplementation.componentImplementationTable as ccit>
							<#if ccit.isRootTable>
								<#assign childTable=ccit.table.idref>
								<#assign childTableName=childTable.name>
								<#if protected.hasNonRootTable(cc.componentImplementation)>

		|* add child non-root table join
		componentJoin = componentJoin & nonRootJoin.${cc.componentName}.${childTableName}_${ccit.position}()				
								</#if>
								<#if protected.hasProtectedChildComponents(cc.componentName)>

		|* add child component join
		componentJoin = componentJoin & childComponentJoin.${cc.componentName}(" inner ")
								</#if>
								<#if protected.hasProtectedParentComponents(c.componentName)>

		|* add parent component join
		componentJoin = componentJoin & parentComponentJoin.${c.componentName}()
								</#if>
								<#-- make the exists clause -->			
								<#assign first=true>
								<#list common.listRelationshipDetails(c.componentImplementation, cc.relationshipImplementation) as rd>
								<#if rd.toAttributeImplementation.column?exists>
									<#if first=true>
										<#assign first=false>

		|* add child root table with filter exists
		childExists = childExists & sepa & " exists ( select " & ${rd.toComponentName}.${childTableName}_${ccit.position} & ".${rd.toAttributeImplementation.column.value}"
		childExists = childExists & " from ${childTableName} " & ${rd.toComponentName}.${childTableName}_${ccit.position}
		childExists = childExists & componentJoin & " where "
									<#else>						
		childExists = childExists & " and "
									</#if>
		childExists = childExists & ${rd.toComponentName}.${childTableName}_${ccit.position} & ".${rd.toAttributeImplementation.column.value} = "
		childExists = childExists & ${rd.fromComponentName}.${tableName}_${cit.position} & ".${rd.fromAttributeImplementation.column.value}"								
		 							<#if !rd_has_next>
										<#if cc.componentImplementation.componentFilterHookExpression?exists && cc.componentImplementation.componentFilterHookExpression?has_content>
											<#-- A ‘where exists’ or join must not be 
												created for just a component filter hook. 
												But if it is created for a related 
												component, then the component filter 
												hook must be taken into account. -->
		|* add component filter hook from table ${cc.componentName}
		childExists = childExists & " and " & bl.component.filter.hook.${cc.componentName}
		childExists = childExists & " and " & bl.FilterExpression & ")"
										<#else>
		childExists = childExists & " and " & bl.FilterExpression & ")"	
		sepa = " and "
										</#if>
									</#if>
								</#if><#--if rd.toAttributeImplementation.column?exists-->
								</#list>
							</#if>
						</#list>
	endif
					</#if>
				</#list><#-- list protected.listProtectedComponents() as cc -->

	return(childExists)
}
		</#if>

function string nonRootJoin.${c.componentName}.${tableName}_${cit.position}()
{
	string	nonRootJoin(MAX_QUERY_LENGTH)
	
	nonRootJoin = ""
		<#-- first every relation from this table to another table -->
		<#list protected.listJOINTables(cit) as joinTableName>
			<#list protected.listNonRootChildren(c.componentImplementation , "${tableName}_${cit.position}") as nrc>
				<#assign first=true>
				<#list protected.listJOINTableDetails(cit, joinTableName) as jtd>
					<#if "${jtd.toTableName}_${jtd.toTablePosition}" = nrc>
						<#if first>
							<#assign first=false>
	|* add non-root table left outer join
	if ${c.componentName}.${nrc}.in.selection() or
	   bl.${c.componentName}.${nrc}.filter.is.set then
		nonRootJoin = nonRootJoin & " left outer join ${jtd.toTableName} " & ${c.componentName}.${nrc}
		nonRootJoin = nonRootJoin & " on "
						<#else>
		nonRootJoin = nonRootJoin & " and "				
						</#if>				
		nonRootJoin = nonRootJoin & ${c.componentName}.${jtd.toTableName}_${jtd.toTablePosition} & ".${jtd.toColumnName} = "
		nonRootJoin = nonRootJoin & ${c.componentName}.${jtd.fromTableName}_${jtd.fromTablePosition} & ".${jtd.fromColumnName}"
					</#if>
					<#if !first && !jtd_has_next>
		nonRootJoin = nonRootJoin & nonRootJoin.${c.componentName}.${nrc}()
	endif
					</#if>
				</#list>
			</#list>
		</#list>
		<#-- secondly every relation from another table to this table -->
		<#list c.componentImplementation.componentImplementationTable as fromcit>
			<#list protected.listJOINTables(fromcit) as joinTableName>
				<#list protected.listNonRootChildren(c.componentImplementation , "${tableName}_${cit.position}") as nrc>
					<#assign first=true>
					<#list protected.listJOINTableDetails(fromcit, joinTableName) as jtd>
						<#if jtd.toTableName=tableName && jtd.toTablePosition=cit.position>
							<#if "${jtd.fromTableName}_${jtd.fromTablePosition}" = nrc>
								<#if first>
									<#assign first=false>

	|* add non-root table left outer join
	if ${c.componentName}.${nrc}.in.selection() or
	   bl.${c.componentName}.${nrc}.filter.is.set then
		nonRootJoin = nonRootJoin & " left outer join ${jtd.fromTableName} " & ${c.componentName}.${nrc}
		nonRootJoin = nonRootJoin & " on "
								<#else>
		nonRootJoin = nonRootJoin & " and "				
								</#if>
		nonRootJoin = nonRootJoin & ${c.componentName}.${jtd.fromTableName}_${jtd.fromTablePosition} & ".${jtd.fromColumnName} = "
		nonRootJoin = nonRootJoin & ${c.componentName}.${jtd.toTableName}_${jtd.toTablePosition} & ".${jtd.toColumnName}"
							</#if>
						</#if>
						<#if !first && !jtd_has_next>
		nonRootJoin = nonRootJoin & nonRootJoin.${c.componentName}.${nrc}()
	endif
						</#if>
					</#list>
				</#list>
			</#list>
		</#list>

	return(nonRootJoin)
}	
	</#list>
</#list>
<#list protected.listProtectedMethods() as m>
	<#assign methodName = m.methodName>
	<#if common.isQueryMethod(methodName) && methodName != "Read">

function extern long <@names.ST_DLLCode/>.get.AttributeData.${methodName}(
				const	string	i.PublicAttribute,
				ref	string	o.Attribute.map,
				ref	string	o.Attribute.alias.map,
				ref	string	o.Attribute.domain,
				ref	long	o.Attribute.datatype,
				ref	boolean	o.Attribute.isRoot,
				ref	boolean	o.Attribute.filter)
{
	on case	trim$(i.PublicAttribute)
	<#-- Important Note:
		This generated function uses in public.sb.common 
		the function generateDuplicatesSelectionPath. 
		When changing the case structure of this function
		always implement these changes also in the
		generateDuplicatesSelectionPath function.
		-->
	<@public.initListPublicAttributes/>
	<@public.resetDuplicatesList/>
	<@public.setDuplicatesList iDuplicatesList=public.generateDuplicatesSelectionPath()/>
	<#assign attributeCounter = 0>
	<#assign functionCounter = 0>
	<#list public.listAllPublicAttributes() as a>
		<#assign attributeCounter = attributeCounter+1>
		<#if 100 < attributeCounter>
			<#assign attributeCounter = 1>
			<#assign functionCounter = functionCounter+1>
	default:
		return( <@names.ST_DLLCode/>.get.AttributeData.${methodName}_${functionCounter}(
			i.PublicAttribute, o.Attribute.map, o.Attribute.alias.map,
			o.Attribute.domain, o.Attribute.datatype, o.Attribute.isRoot,
			o.Attribute.filter) )
	endcase

	return(0)
}

function long <@names.ST_DLLCode/>.get.AttributeData.${methodName}_${functionCounter}(
				const	string	i.PublicAttribute,
				ref	string	o.Attribute.map,
				ref	string	o.Attribute.alias.map,
				ref	string	o.Attribute.domain,
				ref	long	o.Attribute.datatype,
				ref	boolean	o.Attribute.isRoot,
				ref	boolean	o.Attribute.filter)
{
	on case	trim$(i.PublicAttribute)
		</#if><#--if 100 < attributeCounter-->
		<@public.insertCase iComponent=a iSubSelection=".${a.selectionPath}"/>
		<#if public.caseFound>	
			<#-- Postfiltering: check for a calculated attribute -->
			<#assign filter="true">
			<#if a.attributeImplementation.type=="calculated">			
		bl.PostFilter = true |* Calculated attribute
				<#assign filter="false">
			</#if>
			<#-- Postfiltering: check for a Public attribute mapped to array element -->
					<#-- Postfiltering is ook nodig bij filteren op array elementen. 
						Lees: publiek attribuut is geen array, maar is gemapt op 
						een array element; dit kan ook zonder calculatie via de 
						'additional instructions' op de attribuutimplementatie. 
						(Details in PowerDocs # 42989, zoek op 'additional 
						instructions'.) -->
			<#if a.attributeImplementation.additionalInstructions?exists>			
				<#if filter="true">
		bl.PostFilter = true |* Public attribute mapped to array element
					<#assign filter="false">		
				<#else>
		                     |* Public attribute mapped to array element				
				</#if>		
			</#if>
			<#list protected.listProtectedComponents() as c>
				<#if c.componentName=a.componentName>
			<#-- Postfiltering: check for On execute hook on component itself -->
					<#list c.componentImplementation.methodImplementation as methodImplementation>
						<#if methodName = common.getNameFromMethodImplementation(methodImplementation)>		
							<#if protected.executeMethodHookPresent("on", methodImplementation)>
								<#if filter="true">
		bl.PostFilter = true |* On execute hook defined
									<#assign filter="false">
								<#else>
		                     |* On execute hook defined
								</#if>
							</#if>
							<#break>
						</#if>
					</#list>
			<#-- Postfiltering: check for On execute hook on parent component -->
					<#list protected.listProtectedParentComponents(c.componentName) as pc>
						<#list pc.componentImplementation.methodImplementation as methodImplementation>
							<#if methodName = common.getNameFromMethodImplementation(methodImplementation)>		
								<#if protected.executeMethodHookPresent("on", methodImplementation)>
									<#if filter="true">
		bl.PostFilter = true |* On execute hook defined for parent component									
										<#assign filter="false">
									<#else>
		                     |* On execute hook defined for parent component								
									</#if>
								</#if>
								<#break>
							</#if>
						</#list>
						<#if filter="false">
							<#break>								
						</#if>						
					</#list>
					<#break>
				</#if>
			</#list>
			<#-- Postfiltering: in case post-filtering set the filtered 
				 attribute for selection -->
		bl.${a.componentName}.${common.getAttributeName(a.attributeImplementation)}.filtered = true
			<#-- Postfiltering: Public attribute is an array
				 This is a special case; no filtering AND no postfiltering;
				 Do not change bl.postfilter but only report 'postfilter' to 
				 insert true ("1=1") in filterexpression -->
					<#-- Overigens, als publiek attribuut wel een array is, 
						dan werkt filtering niet (net als bij teksten). 
						Bij gebruik van een attribuut met dimensions > 1 
						moet de methode een result opleveren. 
						(Geen postfiltering dus in dat geval.) -->
			<#assign dimensions=common.getDimensionsForDataType(common.getMandatoryDatatype(a.attributeImplementation))>
			<#if (dimensions?number > 1)>
				<#if filter="true">
					<#assign filter="false">
		|* Public attribute is an array; no postfiltering and no filter					
				<#else>
		|* Public attribute is an array; no filter
				</#if>
			</#if>
			<#if filter="true">
		bl.component.filter.set.${a.componentName} = true
			</#if>
			<#assign ProtMapping=a.attributeName>		
			<#if a.attributeImplementation.type=="column">
				<#assign ProtMapping=a.attributeImplementation.componentImplementationTable.idref.table.idref.name + "." + a.attributeImplementation.column.idref.name>
			</#if><#--if a.attributeImplementation.type=="column"-->
			<#assign aliasProtMapping=a.attributeName>
			<#assign isRootTable=true>
			<#assign counter=0>
			<#list protected.listProtectedComponents() as c>
				<#list c.componentImplementation.componentImplementationTable as cit>
					<#assign counter = counter + 1>
					<#if c.componentName=a.componentName>
						<#if a.attributeImplementation.componentImplementationTable?exists && cit=a.attributeImplementation.componentImplementationTable.idref>
							<#assign aliasProtMapping="t${counter}" + "." + a.attributeImplementation.column.idref.name>
							<#assign table=cit.table.idref>
							<#assign tableName=table.name>
							<#assign isRootTable=cit.isRootTable>
							<#if filter="true">
		bl.${a.componentName}.${tableName}_${cit.position}.filter.is.set = true
							</#if>
							<#break>
						</#if>		
					</#if>
				</#list>
			</#list>
		o.Attribute.map = "${ProtMapping}"
		o.Attribute.alias.map = "${aliasProtMapping}"
		o.Attribute.domain = "${common.getDatatypeName(common.getDatatypeFromAttributeImplementation(a.attributeImplementation))}"
		o.Attribute.datatype = ${common.get_BaanDatatype_from_XMLSchemaDatatype(common.getDatatypeFromAttributeImplementation(a.attributeImplementation))}
			<#if isRootTable>
		o.Attribute.isRoot = true
			<#else>
		o.Attribute.isRoot = false			
			</#if>
<#-- #VERS.sn -->
			<#if filter="true" && a.attributeImplementation.type=="column">
				<#assign tableName = a.attributeImplementation.componentImplementationTable.idref.table.idref.name>
				<#assign columnName = a.attributeImplementation.column.idref.name>
		if not column.${tableName}.${columnName}.exists() then <#-- because filter="true" we know the column is not an array here -->
			| public attribute mapped to non-existing column; use postfiltering instead
			bl.PostFilter = true
			o.Attribute.filter = false
		else
			o.Attribute.filter = ${filter}
		endif
			<#else>
<#-- #VERS.en -->
		o.Attribute.filter = ${filter}
<#-- #VERS.sn -->
			</#if><#--filter="true" && a.attributeImplementation.type=="column"-->
<#-- #VERS.en -->
		break
		</#if>	
	</#list><#--list public.listAllPublicAttributes() as a-->
	default:		
		return(-1)
	endcase
	
	return(0)
}

<#-- To clean up data in SQL vars. -->
function extern long <@names.ST_DLLCode/>.finalize.request.${methodName}(...)
{
	DllUsage
	EndDllUsage

	bl.method.result = ( get.argc() > 0 ) ? get.long.arg(1) : 0

	if bl.before.initialize <> 0 then
		bl.before.initialize = 0
	endif

	set.component.init.vars.to.false()

	return(bl.method.result)
}

		<#list protected.listProtectedComponents() as c>
function extern long <@names.ST_DLLCode/>.finalize.${c.componentName}.${methodName}()
{
	DllUsage
	EndDllUsage
	long	ret

	clean.up.sql.data.${c.componentName}()
	if bl.sql.pointer.${c.componentName} <> 0 then
		ret = sql.close(bl.sql.pointer.${c.componentName})
		bl.sql.pointer.${c.componentName} = 0
	endif
	bl.${c.componentName}.query.status = QUERY.INACTIVE

	return(0)
}

		</#list>
function extern long <@names.ST_DLLCode/>.initialize.request.${methodName}()
{
	DllUsage
	EndDllUsage

	bl.method = "${methodName}"
	bl.method.result = 0	

	set.component.init.vars.to.false()

		<#list protected.listProtectedComponents() as c>
	clean.up.sql.data.${c.componentName}()
	bl.${c.componentName}.query.status = QUERY.INACTIVE
		</#list>
		<#list protected.listProtectedComponents() as c>
			<#if c.componentImplementation.componentFilterHookExpression?exists && c.componentImplementation.componentFilterHookExpression?has_content>
	build.component.filter.hook.for.${c.componentName}()
			</#if>
		</#list>

	return(bl.method.result)
}
	</#if>
</#list>

<#list protected.listProtectedComponents() as c>
function clean.up.sql.data.${c.componentName}()
{
	bl.select.${c.componentName} = ""
	bl.select.bind.counter.${c.componentName} = 0
	bl.tables.inselection.${c.componentName} = ""
	bl.where.${c.componentName} = ""
	bl.component.filter.set.${c.componentName} = false
	<#list c.componentImplementation.componentImplementationTable as cit>
		<#assign table=cit.table.idref>
		<#assign tableName=table.name>
	bl.${c.componentName}.${tableName}_${cit.position}.filter.is.set = false
	</#list>
	<#if c.componentImplementation.componentFilterHookExpression?exists && c.componentImplementation.componentFilterHookExpression?has_content>
	bl.component.filter.hook.${c.componentName} = ""
	</#if>
	bl.where.bind.counter.${c.componentName} = 0
	bl.from.${c.componentName} = ""
	if bl.select.bind.max.${c.componentName} > 0 then
		set.mem(bl.select.bind.${c.componentName}, "")
	endif
	if bl.where.bind.max.${c.componentName} > 0 then
		set.mem(bl.where.bind.${c.componentName}, "")
	endif
	<#list c.componentImplementation.attributeImplementation as ai>
	bl.${c.componentName}.${common.getAttributeName(ai)}.selected = false
	bl.${c.componentName}.${common.getAttributeName(ai)}.filtered = false
	</#list><#--list c.componentImplementation.attributeImplementation as ai-->
	bl.${c.componentName}.query.status = QUERY.INACTIVE
}

	<#list c.componentImplementation.attributeImplementation as ai>
function extern <@names.ST_DLLCode/>.select.${c.componentName}.${common.getAttributeName(ai)}()
{
<#-- #VERS.sn -->
		<#if ai.type=="column">
			<#assign tableName = ai.componentImplementationTable.idref.table.idref.name>
			<#assign columnName = ai.column.idref.name>
 			<#assign dimensions=common.getDimensionsForDataType(common.getMandatoryDatatype(ai))/>
 			<#if (dimensions?number > 1)>
  if column.${tableName}.${columnName}.element.exists(1) then  <#-- check on any existing element will do here -->
			<#else>
				<#assign ar=protected.fillArrayField(ai)>
				<#if ar.array>
  if column.${tableName}.${columnName}.element.exists(${ar.arrayPOS}) then
				<#else>
  if column.${tableName}.${columnName}.exists() then
				</#if> <#-- ar.array -->
			</#if> <#-- (dimensions?number > 1) -->
		</#if> <#-- ai.type=="column" -->
<#-- #VERS.en -->
	bl.${c.componentName}.${common.getAttributeName(ai)}.selected = true
	<#if ai.onGetHookExpression?exists && ai.onGetHookExpression != "">
		<#list ai.attributeImplementationRelationship as ar>
	<@names.ST_DLLCode/>.select.${common.getComponentName(ar.componentImplementation.idref)}.${ar.attributeImplementation.value}()
		</#list>
	</#if>
<#-- #VERS.sn -->
	<#if ai.type=="column">
  else
	| bl.${c.componentName}.${common.getAttributeName(ai)}.selected remains false
  endif
	</#if>
<#-- #VERS.en -->
}

	</#list><#--list c.componentImplementation.attributeImplementation as ai-->
function extern long <@names.ST_DLLCode/>.return.query.status.${c.componentName}()
{
	DllUsage
	EndDllUsage

	return(bl.${c.componentName}.query.status)
}

function extern string <@names.ST_DLLCode/>.retrieve.select.clause.${c.componentName}()
{
	DllUsage
	EndDllUsage

	return(bl.select.${c.componentName})
}

function extern string <@names.ST_DLLCode/>.retrieve.from.clause.${c.componentName}()
{
	DllUsage
	EndDllUsage

	return(bl.from.${c.componentName})
}

function extern string <@names.ST_DLLCode/>.retrieve.where.clause.${c.componentName}()
{
	DllUsage
	EndDllUsage

	return(bl.where.${c.componentName})
}

	<#if c.componentImplementation.componentFilterHookExpression?exists && c.componentImplementation.componentFilterHookExpression?has_content>
function extern string <@names.ST_DLLCode/>.retrieve.component.filter.hook.${c.componentName}()
{
	DllUsage
	EndDllUsage

	return(bl.component.filter.hook.${c.componentName})
}

	</#if>

function extern string <@names.ST_DLLCode/>.retrieve.orderby.clause.${c.componentName}()
{
	DllUsage
	EndDllUsage

	return(bl.orderby.${c.componentName})
}

function extern string <@names.ST_DLLCode/>.retrieve.selectbind.clause.${c.componentName}(long	i)
{
	DllUsage
	EndDllUsage

	return(bl.select.bind.${c.componentName}(${5+c.componentName?length},i))	|* Do no return 'bl.'
}

function extern long <@names.ST_DLLCode/>.retrieve.selectbind.count.${c.componentName}()
{
	DllUsage
	EndDllUsage

	return(bl.select.bind.counter.${c.componentName})
}

function extern string <@names.ST_DLLCode/>.retrieve.wherebind.clause.${c.componentName}(long	i)
{
	DllUsage
	EndDllUsage

	return(bl.where.bind.${c.componentName}(${5+c.componentName?length},i))	|* Do no return 'bl.'
}

function extern long <@names.ST_DLLCode/>.retrieve.wherebind.count.${c.componentName}()
{
	DllUsage
	EndDllUsage

	return(bl.where.bind.counter.${c.componentName})
}

function extern long <@names.ST_DLLCode/>.retrieve.fetch.count.${c.componentName}()
{
	DllUsage
	EndDllUsage

	return(bl.fetches.${c.componentName})
}


function long bind.selection.${c.componentName}(long i)
{
	long	ret
	
	on case strip$(bl.select.bind.${c.componentName}(1,i))
	<#list c.componentImplementation.attributeImplementation as attributeImplementation>
		<#assign attributeName=common.getAttributeName(attributeImplementation)>
	case "bl.${c.componentName}.${attributeName}":
		ret = sql.select.bind(bl.sql.pointer.${c.componentName}, i, 
					bl.${c.componentName}.${attributeName})
		break		
	</#list>
	default:
		if MESSAGE_EXISTS("tlbcts0083") then
			dal.set.error.message("tlbcts0083", "${c.componentName}", strip$(bl.select.bind.${c.componentName}(1,i)))
			|* Error binding attribute %1$s in selection for component %2$s
		else
			dal.set.error.message("@Error binding attribute %s in selection for component ${c.componentName}", 
				strip$(bl.select.bind.${c.componentName}(1,i)))
		endif
	endcase
	return (0)
}

function bind.where.${c.componentName}(long i)
{
	long ret
	
	on case strip$(bl.where.bind.${c.componentName}(1,i))
	<#list c.componentImplementation.attributeImplementation as attributeImplementation>
		<#assign attributeName=common.getAttributeName(attributeImplementation)>
	case "bl.${c.componentName}.${attributeName}":
		ret = sql.where.bind(bl.sql.pointer.${c.componentName}, i, 
					bl.${c.componentName}.${attributeName})
		break		
	</#list>
	endcase
}

function set.setters.after.fetch.${c.componentName}(boolean	i.set)
{
	long	i
	i = 0
	<#list c.componentImplementation.attributeImplementation as attributeImplementation>
		<#assign attributeName=common.getAttributeName(attributeImplementation)>
		<#if common.getMandatoryDatatype(attributeImplementation).dimensions?exists>
			<#assign dimensions=common.getDimensionsForDataType(common.getMandatoryDatatype(attributeImplementation))/>
			<#assign array=true>
		<#else>
			<#assign array=false>
		</#if>
		<#if array>
	if bl.${c.componentName}.${attributeName}.selected then
		for i = 1 to ${dimensions?number}
			bl.${c.componentName}.${attributeName}.set(i) = i.set
		endfor
	endif
		<#else>
	if bl.${c.componentName}.${attributeName}.selected then
		bl.${c.componentName}.${attributeName}.set = i.set
	endif
		</#if>
	</#list>
<#-- #VERS.sn -->
<#-- actually we should only set to true if if corresponding column exists, but that is handled in the 'select' method:
     bl.component.attribute.selected will not be set to true if attribute implementation is mapped to a non-existing column -->
<#-- #VERS.en -->
}

	<#list c.componentImplementation.methodImplementation as methodImplementation>
		<#assign methodName = common.getNameFromMethodImplementation(methodImplementation)>
		<#if common.isQueryMethod(methodName) && !common.isPublishMethod(methodName) && !common.isEventMethod(methodName) &&
		     methodImplementation.processingOrder != "batch" &&
		     protected.hasMethodAlternativeImplementation(methodName)=="">

function extern long <@names.ST_DLLCode/>.finalize.set.${c.componentName}.${methodName}()
{
	DllUsage
	EndDllUsage
	long	ret
	
			<#if !protected.executeMethodHookPresent("on", methodImplementation)>
	ret = sql.break(bl.sql.pointer.${c.componentName})
			</#if>
	return (0)
}

function extern boolean <@names.ST_DLLCode/>.query.on.hook.${c.componentName}.${methodName}(ref string o.hook())
{
	DllUsage
	EndDllUsage
	
			<#if protected.executeMethodHookPresent("on", methodImplementation)>
	o.hook = "Hook.OnExecute.${c.componentName}.${methodName}"
	return (true)
			<#else>
	o.hook = ""
	return (false)
			</#if>
}

function extern
long <@names.ST_DLLCode/>.initialize.${c.componentName}.${methodName}()
{
	DllUsage
	EndDllUsage

	<#if !protected.executeMethodHookPresent("on", methodImplementation)>
	long	i

	</#if>
	build.select.for.${c.componentName}()
	build.from.for.${c.componentName}()
	build.where.for.${c.componentName}()
	<#if methodName == "Show">
	add.show.condition.to.where.${c.componentName}()
	</#if>
	<#if methodName == "Show" && c.componentName == names.businessInterfaceName>
		<#-- do not use order by for top-level in Show method, to allow DBMS to optimise query
		     note that sequence is irrelevant anyway, because only one instance will be read. -->
	build.orderby.for.${c.componentName}(true) | suppress order by
	<#else>
		<#-- suppress order by if (empty) sortingExpression is set, to allow DBMS to optimise query -->
	build.orderby.for.${c.componentName}(bl.SortingExpressionSet)
	</#if>
	
	<#if !protected.executeMethodHookPresent("on", methodImplementation)>
	error.bypass = 1
	bl.sql.pointer.${c.componentName} = sql.parse(combine.query.${c.componentName}(), PARSE.DIALECT.6 + PARSE.SUPPRESS)
	error.bypass = 0
	bl.fetches.${c.componentName} = 0
	if bl.sql.pointer.${c.componentName} <= 0 then
		if MESSAGE_EXISTS("tlbcts0084") then
			dal.set.error.message("tlbcts0084", e, "${c.componentName}", "${methodName}")
			|* Error %1$d in parsing of query for component %2$s in method %3$s
		else
			dal.set.error.message("@Error %d in parsing of query for component ${c.componentName} in method ${methodName}", e)
		endif
		bl.${c.componentName}.query.status = QUERY.ERROR
		return (e)
	endif
	</#if>

	<#if !protected.executeMethodHookPresent("on", methodImplementation)>
	for i = 1 to bl.select.bind.counter.${c.componentName}
		RETIFNOK(bind.selection.${c.componentName}(i))
	endfor

	</#if>
	bl.${c.componentName}.query.status = QUERY.INIT
	
	return (0)
}

function extern
long <@names.ST_DLLCode/>.initialize.set.${c.componentName}.${methodName}()
{
	DllUsage
	EndDllUsage

	long	i
	long	ret
	
	<#if !protected.executeMethodHookPresent("on", methodImplementation)>
	for i = 1 to bl.where.bind.counter.${c.componentName}
		bind.where.${c.componentName}(i)
	endfor

	ret = sql.exec(bl.sql.pointer.${c.componentName})
	</#if>
	bl.${c.componentName}.query.status = QUERY.START
	
	return (0)
}

function extern
long <@names.ST_DLLCode/>.before.execute.${c.componentName}.${methodName}(ref	boolean	io.cancel)
{
	DllUsage
	EndDllUsage
	<#assign AttributeList=[]>
	
	long	i
	i = 0
	<#if c.componentName!=names.businessInterfaceName>
		<#list common.listRelationshipDetails(c.parentComponentImplementation, c.relationshipImplementation) as rd>
			<#assign datatype=common.getDatatype(rd.fromAttributeImplementation)>
			<#assign AttributeList=AttributeList+[{
				"componentImplementation":rd.toComponentImplementation, 
				"componentName":rd.toComponentName,
				"attributeImplementation":rd.toAttributeImplementation,
				"attributeName":rd.toAttributeName
				}]>
		</#list><#--list common.listRelationshipDetails(c.parentComponentImplementation, c.relationshipImplementation) as rd-->
	</#if><#-- c.componentName!=names.businessInterfaceName-->

	<#list c.componentImplementation.attributeImplementation as attributeImplementation>
		<#assign attributeName=common.getAttributeName(attributeImplementation)>
 		<#assign dimensions=common.getDimensionsForDataType(common.getMandatoryDatatype(attributeImplementation))/>
 		<#assign parentID=false>
 		<#list AttributeList as al>
 			<#if al.componentName == c.componentName && al.attributeName == attributeName>
 				<#assign parentID=true>
 			</#if>
 		</#list>
 		<#if parentID == false && !attributeImplementation.isIdentifier>
	    	<#if (dimensions?number > 1)>
	for i = 1 to ${dimensions?number}
		bl.${c.componentName}.${attributeName}.set(i) = false
		bl.${c.componentName}.${attributeName}.get(i) = false
				<#if common.get_BaanDatatype_from_XMLSchemaDatatype(common.getMandatoryDatatype(attributeImplementation))=="DB.STRING">
		bl.${c.componentName}.${attributeName}(1,i) = ${protected.getBaanDataInitializers(attributeImplementation)} 
				<#else>
		bl.${c.componentName}.${attributeName}(i) = ${protected.getBaanDataInitializers(attributeImplementation)} 
				</#if><#--common.get_BaanDatatype_from_XMLSchemaDatatype(common.getMandatoryDatatype(attributeImplementation))=="DB.STRING"-->
	endfor
			<#else>
	bl.${c.componentName}.${attributeName}.set = false
	bl.${c.componentName}.${attributeName}.get = false
	bl.${c.componentName}.${attributeName} = ${protected.getBaanDataInitializers(attributeImplementation)} 
			</#if><#--if dimensions?number > 1-->
		</#if>
	</#list>
	
	
	RETIFNOK( <@names.ST_DLLCode/>.${c.componentName}.${methodName}.set.derived() )

	error.bypass = 1
			<#list protected.listProtectedAttributes(methodName, c.componentName) as pa>
				<#assign scope=common.getScopeFromMethodArgumentImplementation(pa.methodArgumentImplementation)>
				<#if (scope?contains("in") && common.getIsMandatoryFromMethodArgumentImplementation(pa.methodArgumentImplementation))>
	if not bl.${c.componentName}.${common.getAttributeName(pa.attributeImplementation)}.set then
		dal.set.error.message("tlbctst0001",
			"${c.componentName}.${common.getAttributeName(pa.attributeImplementation)}")
		|* Mandatory protected attribute %1$s is not set.
		error.bypass = 0
		return(DALHOOKERROR)
	endif
				</#if><#--if (scope?contains("in") && common.getIsMandatoryFromMethodArgumentImplementation(pa.methodArgumentImplementation))-->
			</#list><#--list protected.listProtectedAttributes(methodName, c.componentName) as pa-->

			<#if protected.executeMethodHookPresent("before", methodImplementation)>
	|* Before Hook
	<@protected.RETIFNOKINITFIN_COMPONENT iComponent=c iMethod=methodImplementation 
		iFun="Hook.BeforeExecute."+c.componentName+"."+methodName
		iCancel=true iHookType="before"/>
			</#if><#--if protected.executeMethodHookPresent("before", methodImplementation)-->
	if io.cancel then
		bl.${c.componentName}.initialize = false
	endif

	error.bypass = 0
	
	return(0)
}

function extern
long <@names.ST_DLLCode/>.execute.${c.componentName}.${methodName}()
{
	DllUsage
	EndDllUsage
			<#if protected.executeMethodHookPresent("on", methodImplementation)>
	boolean	anythingFetched
	boolean	loc.default

	<@protected.RETIFNOKINITFIN_COMPONENT iComponent=c iMethod=methodImplementation 
		iFun="Hook.OnExecute."+c.componentName+"."+methodName
		iHookType="on" iQueryMethod=true/>

	if anythingFetched then
		bl.${c.componentName}.query.status = QUERY.FETCH
	else
		bl.${c.componentName}.query.status = QUERY.END
	endif

	return (0)
			<#else>
	long	ret

	ret = sql.fetch(bl.sql.pointer.${c.componentName})
	on case ret
	case 0:
		bl.fetches.${c.componentName} = bl.fetches.${c.componentName} + 1
		bl.${c.componentName}.query.status = QUERY.FETCH
		set.setters.after.fetch.${c.componentName}(true)
		return (0)
	case eendfile:
	case ENOREC:
	bl.${c.componentName}.query.status = QUERY.END
		set.setters.after.fetch.${c.componentName}(false)
		return (0)
	default:
		bl.${c.componentName}.query.status = QUERY.ERROR
		if ret = -1 then
			ret = handle.result(e)
		endif
		if MESSAGE_EXISTS("tlbcts0085") then
			dal.set.error.message("tlbcts0085", ret, "${methodName}")
			|* Error %1$d in method %2$s
		else
			dal.set.error.message("@Error %d in method ${methodName}", ret)
		endif
		return (DALHOOKERROR)
	endcase
			</#if>
}

function extern 
long <@names.ST_DLLCode/>.after.execute.${c.componentName}.${methodName}()
{
	DllUsage
	EndDllUsage
			<#if protected.executeMethodHookPresent("after", methodImplementation)>
			
	boolean	anythingFetched
	
	if bl.${c.componentName}.query.status = QUERY.FETCH then
		anythingFetched = true
	else
		anythingFetched = false
	endif

				<#assign MArguments="">
	<@protected.RETIFNOKINITFIN_COMPONENT iComponent=c iMethod=methodImplementation 
		iFun="Hook.AfterExecute."+c.componentName+"."+methodName
		iHookType="after" iAfter=false/> 
			</#if>	
	bl.${c.componentName}.initialize = false
	return(0)
}
		</#if>
	</#list>

function string combine.query.${c.componentName}()
{
	return (
		strip$(add.select.ifnot.empty.${c.componentName}()) & " " &
		strip$(add.from.ifnot.empty.${c.componentName}()) & " " &
		strip$(add.where.ifnot.empty.${c.componentName}()) & " " &
		strip$(add.orderby.ifnot.empty.${c.componentName}())
			)
}

function string add.select.ifnot.empty.${c.componentName}()
{
	if not isspace(bl.select.${c.componentName}) then
		return ("select " & bl.select.${c.componentName})
	endif
	return ("")
}

function string add.from.ifnot.empty.${c.componentName}()
{
	if not isspace(bl.from.${c.componentName}) then
		return ("from " & bl.from.${c.componentName})
	endif
	return ("")
}

function string add.where.ifnot.empty.${c.componentName}()
{
	if not isspace(bl.where.${c.componentName}) then
		return ("where " & bl.where.${c.componentName})
	endif
	
	return ("")
}

function string add.orderby.ifnot.empty.${c.componentName}()
{
	if not isspace(bl.orderby.${c.componentName}) then
		return ("order by " & bl.orderby.${c.componentName})
	endif
	return ("")
}

function build.select.for.${c.componentName}()
{
	string	sepa(1)
	
	<#assign first = true>
	sepa = ""
	bl.select.${c.componentName} = ""

	<#list c.componentImplementation.componentImplementationTable as cit>
		<#assign table=cit.table.idref>
		<#assign tableName=table.name>
	build.select.for.${c.componentName}.${tableName}_${cit.position}(sepa)
	</#list><#--list c.componentImplementationTable as cit-->

	set.nonroot.dependencies.for.${c.componentName}()
}

function set.nonroot.dependencies.for.${c.componentName}()
{
	|* set non-root table selection dependencies
	<#list c.componentImplementation.componentImplementationTable as cit>
		<#assign table=cit.table.idref>
		<#assign tableName=table.name>
		<#if cit.isRootTable>
			<#assign first=true>
			<#list protected.listNonRootTablesOrder(c.componentImplementation, "${tableName}_${cit.position}")?reverse as nrto>
	if ${c.componentName}.${nrto.toTable}.in.selection() and
	   not ${c.componentName}.${nrto.fromTable}.in.selection() then
		bl.tables.inselection.${c.componentName} =
			bl.tables.inselection.${c.componentName} & ";${nrto.fromTable};"
	endif
			</#list>
		</#if>
	</#list>
}

function build.from.for.${c.componentName}()
{
	string sepa(1)

	sepa = ""
	bl.from.${c.componentName} = ""
	<#list  c.componentImplementation.componentImplementationTable as cit>
		<#assign table=cit.table.idref>
		<#assign tableName=table.name>
		<#if cit.isRootTable>

	if ${c.componentName}.${tableName}_${cit.position}.in.selection() then
		bl.from.${c.componentName} = bl.from.${c.componentName} & sepa &  
			"${tableName} " & ${c.componentName}.${tableName}_${cit.position}
		sepa = ","
	endif
			<#--For filter on parent component table: root table [inner] join parent 
				table (in case of a parent root table), or: root table [inner] join 
				parent root table join parent non-root table (in case of 
				a parent non-root table).-->
			<#if c.parentComponentImplementation?exists>

	|* add (inner) join with parent component
	if bl.component.filter.set.${c.componentName} = true or
	   hasSiblingChildFilter.${c.parentComponentName}() then
		bl.from.${c.componentName} = bl.from.${c.componentName} &
			parentComponentJoin.${c.componentName}()
	endif
				<#list protected.listProtectedParentComponents(c.componentName) as ppc>
					<#if protected.hasSiblingComponents(ppc.componentName, c.componentName)>

	|* add left outer join to parent for sibling filtering
	if hasSiblingChildFilter.${ppc.componentName}() and
	   ( bl.component.filter.set.${c.componentName} = true or 
	     hasChildFilter.${c.componentName}()  ) then
						<#list protected.listSiblingComponents(ppc.componentName, c.componentName) as sc>
		bl.from.${c.componentName} = bl.from.${c.componentName} &
			childJoin.${ppc.componentName}.${sc.componentName}(" left outer ")				
						</#list>
	endif
					</#if>
				</#list>
			</#if>
			<#--For filter on non-root table of the component itself (if non-root
				table is not selected already): root table join non-root table.-->
			<#if protected.hasNonRootTable(c.componentImplementation)>

	|* add join with non-root child of table ${tableName}_${cit.position}
	bl.from.${c.componentName} = bl.from.${c.componentName} &
		nonRootJoin.${c.componentName}.${tableName}_${cit.position}()
			</#if>
			<#if protected.hasProtectedChildComponents(c.componentName)>

	|* add left outer join with children for sibling filtering
	if hasSiblingChildFilter.${c.componentName}() then
		bl.from.${c.componentName} = bl.from.${c.componentName} &
			childComponentJoin.${c.componentName}(" left outer ")
	endif
			</#if>
		</#if>
	</#list>
}

function build.where.for.${c.componentName}()
{
	string sepa(5)
	<#assign first = true>

	sepa = ""
	bl.where.${c.componentName} =
	<#list c.componentImplementation.componentImplementationTable as cit>
		<#assign table=cit.table.idref>
		<#assign tableName=table.name>
		<#if first>
			<#assign first = false>
		<#else>
			&
		</#if>
		build.where.for.${c.componentName}.${tableName}_${cit.position}(sepa)
	</#list><#--list c.componentImplementationTable as cit-->
<#--#identifierfix.sn-->
	<#if first>
			""
			${logger.warn(object, "No implementation table defined for component '"+c.componentName+"'")}
	<#else>
<#--#identifierfix.en-->

	|* add exists when filter active on child component
	if hasChildFilter.${c.componentName}() and
	   not hasSiblingChildFilter.${c.componentName}() then
		bl.where.${c.componentName} = bl.where.${c.componentName} &
			sepa & childComponentExists.${c.componentName}()
	else
		|* apply filter
		if bl.component.filter.set.${c.componentName} = true 
		or hasSiblingChildFilter.${c.componentName}() then
			bl.where.${c.componentName} = bl.where.${c.componentName} &
				sepa & bl.FilterExpression	
		endif
	endif
<#--#identifierfix.sn-->
	</#if>
<#--#identifierfix.en-->
}

	<#if c.componentImplementation.componentFilterHookExpression?exists && c.componentImplementation.componentFilterHookExpression?has_content>
function build.component.filter.hook.for.${c.componentName}()
{
	long	retl

	retl = Hook.Filter.${c.componentImplementation.component.value}(bl.component.filter.hook.${c.componentName})	
}

	</#if>
function build.orderby.for.${c.componentName}(
		boolean	i.suppress.order.by) | use empty order by, do not sort
{
	if i.suppress.order.by then
		bl.orderby.${c.componentName} = ""
	else	
	<#list c.componentImplementation.componentImplementationTable as cit>
		<#if cit.isRootTable>
		bl.orderby.${c.componentName} = ${c.componentName}.${cit.table.idref.name}_${cit.position} & "._index1"
		</#if>
	</#list><#--list c.componentImplementationTable as cit-->
	endif
}

function add.field.where.bind.${c.componentName}(string i.attr.field(${common.CompAttrLen()}), ref long o.number)
{
	long	i
	|* Already present ???
	for i = 1 to bl.where.bind.counter.${c.componentName}
		if strip$(i.attr.field) = strip$(bl.where.bind.${c.componentName}(1, i)) then
			o.number = i
			return
		endif
	endfor
	bl.where.bind.counter.${c.componentName} = bl.where.bind.counter.${c.componentName} + 1
	if bl.where.bind.counter.${c.componentName} > bl.where.bind.max.${c.componentName} then
		bl.where.bind.max.${c.componentName} = bl.where.bind.max.${c.componentName} + 100
		alloc.mem(bl.where.bind.${c.componentName}, ${common.CompAttrLen()}, bl.where.bind.max.${c.componentName})
	endif
	bl.where.bind.${c.componentName}(1,bl.where.bind.counter.${c.componentName}) = i.attr.field
	o.number = bl.where.bind.counter.${c.componentName}
}

function add.field.select.bind.${c.componentName}(string i.attr.field(${common.CompAttrLen()}))
{
	bl.select.bind.counter.${c.componentName} = bl.select.bind.counter.${c.componentName} + 1
	if bl.select.bind.counter.${c.componentName} > bl.select.bind.max.${c.componentName} then
		bl.select.bind.max.${c.componentName} = bl.select.bind.max.${c.componentName} + 100
		alloc.mem(bl.select.bind.${c.componentName}, ${common.CompAttrLen()}, bl.select.bind.max.${c.componentName})
	endif
	bl.select.bind.${c.componentName}(1,bl.select.bind.counter.${c.componentName}) = i.attr.field
}
	<#--TODO use selectbind if table is used twice. -->

	<#list c.componentImplementation.componentImplementationTable as cit>
		<#assign table=cit.table.idref>
		<#assign tableName=table.name>
		<#if cit.isRootTable>
function add.show.condition.to.where.${c.componentName}()
{
	string	sepa(5)
	long	where.number
	
	if isspace(bl.where.${c.componentName}) then
		sepa = ""
	else
		sepa = " and "
	endif
	where.number = 0
			<#list table.column as tc>
				<#list protected.searchattrimpl(c.componentImplementation, cit, tc.name, false, false) as an>
				<#assign attributeName = an.attributeName>
					<#list c.componentImplementation.attributeImplementation as ca>
						<#if ca.isIdentifier && ca.type=="column" && ca.name == attributeName &&
							 ca.componentImplementationTable.idref.table.value == tableName && ca.column.value == tc.name>
	if bl.${c.componentName}.${attributeName}.set then
		add.field.where.bind.${c.componentName}("bl.${c.componentName}.${attributeName}", where.number)
		bl.where.${c.componentName} = strip$(bl.where.${c.componentName}) & sepa & 
			${c.componentName}.${tableName}_${cit.position} & ".${tc.name} = :" & str$(where.number) | bl.where.bind.counter.${c.componentName})
		sepa = " and "
	endif
						</#if>
					</#list>
				</#list>
			</#list>
}
		</#if>

function build.select.for.${c.componentName}.${tableName}_${cit.position}(ref string sepa())
{
|	long	fieldcount
	boolean	in.selection
	
	in.selection = false
		<#list c.componentImplementation.attributeImplementation as ai>
			<#assign attributeName=common.getAttributeName(ai)>
			<#if ai.type == "column">
				<#if ai.componentImplementationTable.idref.table.idref.name == tableName &&
					 ai.componentImplementationTable.idref.position == cit.position>
	if bl.${c.componentName}.${attributeName}.selected then
		add.field.select.bind.${c.componentName}("bl.${c.componentName}.${attributeName}")
		bl.select.${c.componentName} = bl.select.${c.componentName} & sepa &
					<#assign dimensions=common.getDimensionsForDataType(common.getMandatoryDatatype(ai))/>
					<#if (dimensions?number > 1)>
			${c.componentName}.${tableName}_${cit.position} & ".${ai.column.value}:" & str$(bl.select.bind.counter.${c.componentName})
					<#else>
						<#assign ar=protected.fillArrayField(ai)>
			${c.componentName}.${tableName}_${cit.position} & ".${ai.column.value}${ar.arrayFLD}:" & str$(bl.select.bind.counter.${c.componentName})
					</#if><#--if (dimensions?number > 1)-->
		sepa = ","
		in.selection = true
	endif
				</#if>
			</#if>
		</#list>

	if in.selection then
		bl.tables.inselection.${c.componentName} = bl.tables.inselection.${c.componentName} &
			";${tableName}_${cit.position};"
	endif
}

function boolean ${c.componentName}.${tableName}_${cit.position}.in.selection()
{
	long	p
	
	p = pos(bl.tables.inselection.${c.componentName}, "${tableName}_${cit.position}")
	
	return (p > 0)
}

function string build.where.for.${c.componentName}.${tableName}_${cit.position}(ref string sepa())
{
	string	field.where(MAX_QUERY_LENGTH)
	long	where.number
	<#-- 
		- if component <> root, add main key attribute to where for root table. 
		- if table <> root add root table fields to where.
	-->

	if not ${c.componentName}.${tableName}_${cit.position}.in.selection() and
	   isspace(bl.FilterExpression) then
		return ("")
	else
		<#assign AttributeList=[]>
		<#if c.componentName!=names.businessInterfaceName>
			<#list common.listRelationshipDetails(c.parentComponentImplementation, c.relationshipImplementation) as rd>
				<#assign datatype=common.getDatatype(rd.fromAttributeImplementation)>
				<#assign AttributeList=AttributeList+[{
					"componentImplementation":rd.toComponentImplementation, 
					"componentName":rd.toComponentName,
					"attributeImplementation":rd.toAttributeImplementation,
					"attributeName":rd.toAttributeName
					}]>
			</#list><#--list common.listRelationshipDetails(c.parentComponentImplementation, c.relationshipImplementation) as rd-->
		</#if><#-- c.componentName!=names.businessInterfaceName-->
		field.where = ""
		where.number = 0
		<#if c.parentComponentName !="" && cit.isRootTable><#-- non Root component -->
			<#-- add identifiers -->
			<#list table.column as tc>
				<#list protected.searchattrimpl(c.componentImplementation, cit, tc.name, false, false) as an>
				<#assign attributeName = an.attributeName>
					<#list c.componentImplementation.attributeImplementation as ca>
						<#if ca.isIdentifier && ca.type=="column" && ca.name == attributeName && 
						     ca.componentImplementationTable.value == tableName && ca.column.value == tc.name>
							<#assign parentID=false>
 							<#list AttributeList as al>
 								<#if al.componentName == c.componentName && al.attributeName == attributeName>
 									<#assign parentID=true>
 								</#if>
	 						</#list>
	 						<#if parentID>
		add.field.where.bind.${c.componentName}("bl.${c.componentName}.${attributeName}", where.number)
		field.where = field.where & sepa & ${c.componentName}.${tableName}_${cit.position} & ".${tc.name} = :" & str$(where.number)|bl.where.bind.counter.${c.componentName})
		sepa = " and "
							</#if>
						</#if>
					</#list>
				</#list>
			</#list>
		</#if>
		<#if cit.isRootTable>		
			<#if c.componentImplementation.componentFilterHookExpression?exists && c.componentImplementation.componentFilterHookExpression?has_content>
			<#-- only for root tables -->
			<#-- A ‘where exists’ or join must not be 
				created for just a component filter hook. 
				But if it is created for a related 
				component, then the component filter 
				hook must be taken into account. -->
		|* add component filter hook
		field.where = field.where & sepa & bl.component.filter.hook.${c.componentName}
		sepa = " and "
			</#if>
		</#if>
	endif

	return (field.where)
}
	</#list><#--list c.componentImplementationTable as cit-->
</#list><#--list protected.listProtectedComponents() as c-->
</#if><#--if common.queryMethodPresent()-->

<#list protected.listProtectedComponents() as c>
	<#list protected.listProtectedAssociatedAttributes(c.componentImplementation) as aa>
		<#assign objectName="o${aa.toBusinessInterfaceImplementation.implementationIdentifier[0..4]}bl${aa.toBusinessInterfaceImplementation.implementationIdentifier[5..7]}st00">
		<#assign scriptName="${aa.toBusinessInterfaceImplementation.implementationIdentifier[0..4]}.bl${aa.toBusinessInterfaceImplementation.implementationIdentifier[5..7]}st00">

function long private.Read.${aa.fromComponentName}.${aa.fromAttributeName}()
{
	#pragma used dll ${objectName}

	<#assign dimensions=common.getDimensionsForDataType(common.getMandatoryDatatype(aa.fromAttributeImplementation))/>
	<#if (dimensions?number > 1)>
	long	i
	for i = 1 to ${dimensions?number}
		<#if common.get_BaanDatatype_from_XMLSchemaDatatype(common.getMandatoryDatatype(aa.fromAttributeImplementation))=="DB.STRING">
		bl.${aa.fromComponentName}.${aa.fromAttributeName}(1,i) = ""
		<#else>
		bl.${aa.fromComponentName}.${aa.fromAttributeName}(i) = ${protected.getBaanDataInitializers(aa.fromAttributeImplementation)}
		</#if><#--common.get_BaanDatatype_from_XMLSchemaDatatype(common.getMandatoryDatatype(attributeImplementation))=="DB.STRING"-->
		bl.${aa.fromComponentName}.${aa.fromAttributeName}.set(i) = false
	endfor
	<#else>
	bl.${aa.fromComponentName}.${aa.fromAttributeName} = ${protected.getBaanDataInitializers(aa.fromAttributeImplementation)}
	bl.${aa.fromComponentName}.${aa.fromAttributeName}.set = false
	</#if><#--if dimensions?number > 1-->

		<#list common.listRelationshipDetails(aa.fromComponentImplementation,aa.relationshipImplementation) as rd>
	RETIFNOK(<@names.ST_DLLCode/>.get.${aa.fromComponentName}.${rd.fromAttributeName}(
		bl.${aa.fromComponentName}.${rd.fromAttributeName}))
	if isspace(bl.${aa.fromComponentName}.${rd.fromAttributeName}) or 
		not <@names.ST_DLLCode/>.is.set.${aa.fromComponentName}.${rd.fromAttributeName}() then
		return(0)
	endif
		</#list><#--list common.listRelationshipDetails(aa.fromComponentImplementation,aa.relationshipImplementation) as rd-->

	RETIFNOK(private.Read.BDE.${aa.toComponentName}(
		<#assign first=true>
		<#list common.listRelationshipDetails(aa.fromComponentImplementation,aa.relationshipImplementation) as rd>
			<#if !first>,<#else><#assign first=false></#if>bl.${aa.fromComponentName}.${rd.fromAttributeName}
		</#list>))

	<#if (dimensions?number > 1)>
	RETIFNOK(${scriptName}.get.${aa.toComponentName}.${aa.toAttributeName}(
		bl.${aa.fromComponentName}.${aa.fromAttributeName},
		bl.${aa.fromComponentName}.${aa.fromAttributeName}.set))
	<#else>
	RETIFNOK(${scriptName}.get.${aa.toComponentName}.${aa.toAttributeName}(
		bl.${aa.fromComponentName}.${aa.fromAttributeName}))
	bl.${aa.fromComponentName}.${aa.fromAttributeName}.set = true
	</#if><#--if dimensions?number > 1-->
	return(0)
}
	</#list><#--list protected.listProtectedAssociatedAttributes(c.componentImplementation) as aa-->
</#list><#--list protected.listProtectedComponents() as c-->

<#assign ToCmpList=[]>
<#list protected.listProtectedComponents() as c>
	<#list protected.listProtectedAssociatedAttributes(c.componentImplementation) as aa>
		<#assign objectName="o${aa.toBusinessInterfaceImplementation.implementationIdentifier[0..4]}bl${aa.toBusinessInterfaceImplementation.implementationIdentifier[5..7]}st00">
		<#assign scriptName="${aa.toBusinessInterfaceImplementation.implementationIdentifier[0..4]}.bl${aa.toBusinessInterfaceImplementation.implementationIdentifier[5..7]}st00">
		<#assign insert=true>
		<#list ToCmpList as tList>
			<#if tList.toComp == aa.toComponentName>
				<#assign insert=false>
			</#if>
		</#list>
		<#if insert>
			<#assign ToCmpList=ToCmpList+[{
					"toComp":aa.toComponentName
					}]>

function long private.Read.BDE.${aa.toComponentName}(
			<#assign first=true>
			<#list common.listRelationshipDetails(aa.fromComponentImplementation,aa.relationshipImplementation) as rd>
				<#if !first>,<#else><#assign first=false></#if>	domain	 ${common.getDatatypeName(common.getDatatype(rd.toAttributeImplementation))} i.${aa.toComponentName}.${rd.toAttributeName}
			</#list>
						)
{
			<#list common.listRelationshipDetails(aa.fromComponentImplementation,aa.relationshipImplementation) as rd>
	static domain	${common.getDatatypeName(common.getDatatype(rd.toAttributeImplementation))} local.${aa.toComponentName}.${rd.toAttributeName}
			</#list><#--list common.listRelationshipDetails(aa.fromComponentImplementation,aa.relationshipImplementation) as rd-->

			<#assign first=true>
			<#list common.listRelationshipDetails(aa.fromComponentImplementation,aa.relationshipImplementation) as rd>
				<#if first>

	if local.${aa.toComponentName}.${rd.toAttributeName} = i.${aa.toComponentName}.${rd.toAttributeName}
				<#else>
	   and local.${aa.toComponentName}.${rd.toAttributeName} = i.${aa.toComponentName}.${rd.toAttributeName}
				</#if>
				<#assign first=false>
			</#list><#--list common.listRelationshipDetails(aa.fromComponentImplementation,aa.relationshipImplementation) as rd-->
			<#if !first>
				then
		return(0)
	endif
			</#if>
			<#list common.listRelationshipDetails(aa.fromComponentImplementation,aa.relationshipImplementation) as rd>
	local.${aa.toComponentName}.${rd.toAttributeName} = i.${aa.toComponentName}.${rd.toAttributeName}
			</#list><#--list common.listRelationshipDetails(aa.fromComponentImplementation,aa.relationshipImplementation) as rd-->
	
			<#list common.listRelationshipDetails(aa.fromComponentImplementation,aa.relationshipImplementation) as rd>
	RETIFNOK(${scriptName}.set.${aa.toComponentName}.${rd.toAttributeName}(
		i.${aa.toComponentName}.${rd.toAttributeName}))
			</#list><#--list common.listRelationshipDetails(aa.fromComponentImplementation,aa.relationshipImplementation) as rd-->
	
	RETIFNOK(${scriptName}.execute.${aa.toComponentName}.Read())
	return(0)
}
		</#if>
	</#list><#--list protected.listProtectedAssociatedAttributes(c.componentImplementation) as aa-->
</#list><#--list protected.listProtectedComponents() as c-->

<#assign AFSComponentPresent=false>
<#list protected.listProtectedComponents() as c>
	<#if protected.isFunctionServerComponent(c.componentImplementation)>
		<#assign AFSComponentPresent=true>
		<#break>
	</#if>
</#list>
<#if common.queryMethodPresent() && !AFSComponentPresent>
function extern long <@names.ST_DLLCode/>.convert.relation.ID(
			string	iRelID(200))
{
	on case strip$(iRelID)
	<#assign RelCounter=0>
	<#assign aarList=[]>
	<#list protected.listProtectedComponents() as c>
		<#list protected.listProtectedAssociatedAttributes(c.componentImplementation) as aa>
			<#if aa.relationshipImplementation.relationship?has_content>
				<#assign aar=aa.relationshipImplementation.relationship.idref.name>
			<#else>
				<#assign aar=aa.relationshipImplementation.name>
			</#if>
			<#if !protected.containedIn(aar,aarList)>
				<#assign aarList=aarList+[aar]>
				<#assign RelCounter=RelCounter + 1>
	case "${aar}":
		return (${RelCounter})
			</#if>
		</#list><#--list protected.listProtectedAssociatedAttributes(c.componentImplementation) as aa-->
	</#list><#--list protected.listProtectedComponents() as c-->
	endcase
	
	return (0)
}

	<#if protected.ReducedExecs()>
		<#if protected.calculatedFieldPresent()>
function extern boolean <@names.ST_DLLCode/>.attr.is.calculated(	const string i.comp,
					const string i.attr)
{
	string	comp.attr(${common.CompAttrLen()})

	comp.attr = (isspace(i.comp)) ? i.attr : i.comp & "." & i.attr

	on case comp.attr
			<#list protected.listProtectedComponents() as c>
				<#list c.componentImplementation.attributeImplementation as ai>
					<#if ai.type=="calculated">
	case "${c.componentName}.${common.getAttributeName(ai)}":
		return(true)
					</#if><#--if ai.type=="calculated"-->
				</#list><#--list c.componentImplementation.attributeImplementation as ai-->
			</#list><#--list protected.listProtectedComponents() as c-->
	endcase
	return(false)
}
		</#if><#--if protected.calculatedFieldPresent()-->
	</#if><#--if protected.ReducedExecs()-->
</#if><#--if common.queryMethodPresent()-->
