I am trying to make a threaded discussion board using CFC. However something about recursion in CF / CFC stumped me. It seems that i can't make a function return to it's calling function. The result of this behaviour is that i will only be able to add the first child of the node unless in cases where that current node don't have any children. Sorry if i don't make sense. However i copy pasted the source codes and the content of the database, expected output, and actual output involved in this problem. Any help regarding this problem is greately appreciated.
This is the current contents of the DB / message table
messageid parentid
1 0 2 1
3 1
4 2
5 4
6 4
My output if I invoke generatetree method on treefactory.cfc is 1 2 4 5 6
My expected output is
1
2
4
5
6
3As you can see it only traverse the tree in one direction since it fails to return to the calling function and output 3.
Also please bear with my codes since this is just for rapid prototyping of the application..
<!--- nodebean.cfc --->
<!--- kind of an abstract product for messages --->
<!--- nodeid is the same as messageid for message object --->
<cfcomponent displayname="nodebean">
<cfscript>
variables.instance.nodeid = 0;
variables.instance.parentid = 0;
variables.instance.children = arraynew( 1 );
</cfscript><cffunction name="init" access="public" output="false" returntype="struct">
<cfargument name="nodeid" type="numeric" required="yes" />
<cfargument name="parentid" type="numeric" required="yes" />
<cfset setnodeid( arguments.nodeid ) />
<cfset setparentid( arguments.parentid ) />
<cfset traverse( arguments.nodeid ) />
<cfreturn this />
</cffunction>
<!--- getters and setters --->
<cffunction name="setnodeid" access="public" output="false" returntype="void">
<cfargument name="nodeid" type="numeric" required="true">
<cfset variables.instance.nodeid= arguments.nodeid/>
</cffunction>
<cffunction name="getnodeid" access="public" output="false" returntype="numeric">
<cfreturn variables.instance.nodeid/>
</cffunction>
<cffunction name="setparentid" access="public" output="false" returntype="void">
<cfargument name="parentid" type="numeric" required="true">
<cfset variables.instance.parentid= arguments.parentid/>
</cffunction>
<cffunction name="getparentid" access="public" output="false" returntype="numeric">
<cfreturn variables.instance.parentid/>
</cffunction>
<cffunction name="addchild" access="public" output="false" returntype="void">
<cfargument name="node" type="struct" required="yes" />
<cfset arrayappend(variables.instance.children, node) />
</cffunction>
<cffunction name="getchildren" access="public" output="false" returntype="array">
<cfreturn variables.instance.children />
</cffunction>
<cffunction name="traverse" access="public" output="true" returntype="any">
<cfargument name="nodeid" type="numeric" required="yes" />
<cfset var _recordset = "" />
<cfset var _collectiondao = createobject('component', 'messagegateway') />
<cfset var i = 0 />
<cfset var _child = createobject('component', 'nodebean') />
<cfset _recordset = _collectiondao.selectmessagebyparent( arguments.nodeid ) />
<cfif _recordset.recordcount>
<cfscript>
for(i = 1; i lte _recordset.recordcount; i = i+1){
writeoutput(_recordset.messageid[i] & '<br />');
_child = createobject('component', 'nodebean').init( _recordset.messageid[i], arguments.nodeid );
addchild( _child );
}
</cfscript>
<cfelse>
<cfreturn />
</cfif>
</cffunction>
</cfcomponent>
<!--- tree factory --->
<!-- will take a nodeid as an argument and generate the tree / subtree for that node --->
<cfcomponent displayname="treefactory">
<cffunction name="generatetree" access="public" output="true" returntype="any">
<cfargument name="nodeid" type="numeric" required="yes" />
<cfset var _cruddao = createobject('component', 'messagedao') />
<cfset var _collectiondao = createobject('component', 'messagegateway') />
<cfset var _recordset = "" />
<cfset var _node = createobject('component', 'nodebean') />
<cfset var _child = createobject('component', 'nodebean') />
<cfset var i = 0 />
<cfset _recordset = _cruddao.selectmessage( arguments.nodeid ) />
<cfif _recordset.recordcount>
<cfscript>
_node = createobject('component', 'nodebean').init( _recordset.messageid, _recordset.parentid );
</cfscript>
</cfif>
<cfreturn _node />
</cffunction>
</cfcomponent>
<!--- message gateway--->
<!--- data abstraction layer for queries that will return a collection (multiple records) --->
<cfcomponent displayname="messagegateway">
<cffunction name="selectforumthreads" access="public" output="false" returntype="query">
<cfargument name="forumid" type="numeric" required="no" default="0" />
<cfset var qryselectforumthreads = "" />
<cfquery name="qryselectforumthreads" datasource="#request.dsn#" username="#request.username#" password="#request.password#">
SELECT
*
FROM
message
WHERE
forumid = <cfqueryparam value="#arguments.forumid#" cfsqltype="cf_sql_integer" />
AND threadid = <cfqueryparam value="0" cfsqltype="cf_sql_integer" />
</cfquery>
<cfreturn qryselectforumthreads />
</cffunction>
<cffunction name="selectmessagebyparent" access="public" output="false" returntype="query">
<cfargument name="parentid" type="numeric" required="yes" />
<cfset var qryselectmessagebyparent = "" />
<cfquery name="qryselectmessagebyparent" datasource="#request.dsn#" username="#request.username#" password="#request.password#">
SELECT
messageid
FROM
message
WHERE
parentid = <cfqueryparam value="#arguments.parentid#" cfsqltype="cf_sql_integer" />
</cfquery>
<cfreturn qryselectmessagebyparent />
</cffunction>
</cfcomponent>
----------------------------------------------------------
You are subscribed to cfcdev. To unsubscribe, send an email
to [EMAIL PROTECTED] with the words 'unsubscribe cfcdev' in the message of the email.
CFCDev is run by CFCZone (www.cfczone.org) and supported by Mindtool, Corporation (www.mindtool.com).
An archive of the CFCDev list is available at www.mail-archive.com/[EMAIL PROTECTED]
