• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 365
  • Last Modified:

Coldfusion OOP - creating objects for multiple records in a query

Hi,

I am starting out learning coldfusion OOP development within the coldbox framework so have some very basic questions coming up - the first of which is,

I have a user database which I am now successfully maintaining on a record by record basis using a user.cfc component and userDAO (attached both) which holds my insert, update, delete and select. I am comfortable using the getters and setter and objects for a single record but now have a query of 10 user records and I am not sure how to handle them.

Do I create an object for each? if so how? OR do I hold the query in an object and handle the output on each page.

Any help appreciated.

<cfcomponent displayname="user" output="false">
	<cfproperty name="usrId" type="numeric" default="0" />
	<cfproperty name="usrName" type="string" default="" />
	<cfproperty name="firstName" type="string" default="" />
	<cfproperty name="surname" type="string" default="" />
	<cfproperty name="usrLevel" type="numeric" default="1" />
	<cfproperty name="passwd" type="string" default="" />
    <cfproperty name="zones" type="struct" default="" />
	
	<cfset variables.instance = {
		usrId = 0,
		usrName = '',
		firstName = '',
		surname = '',
		usrLevel = '',
		passwd = '',
		zones = {}
	} />

	<cffunction name="init" access="public" output="true" returntype="any">
		<cfargument name="usrId" required="true" type="numeric" default="0" />
		<cfargument name="usrName" required="true" type="string" default="" />
		<cfargument name="firstName" required="true" type="string" default="" />
		<cfargument name="surname" required="true" type="string" default="" />
		<cfargument name="usrLevel" required="true" type="numeric" default="1" />
		<cfargument name="passwd" required="true" type="string" default="" />
        <cfargument name="zones" required="true" type="struct" default="#structNew()#" />
        
		<cfscript>
		setUsrId(arguments.usrId);
		setUsrName(arguments.usrName);
		setFirstName(arguments.firstName);
		setSurname(arguments.surname);
		setUsrLevel(arguments.usrLevel);
		setPasswd(arguments.passwd);
		setZones(arguments.zones);
		</cfscript>

		<cfreturn this />
	</cffunction>


	<!--- GETTERS --->
	<cffunction name="getUsrId" access="public" output="false">
    	<cfreturn variables.instance.usrId />
	</cffunction>

	<cffunction name="getUsrName" access="public" output="false">
		<cfreturn variables.instance.usrName />
	</cffunction>

	<cffunction name="getFirstName" access="public" output="false">
		<cfreturn variables.instance.firstName />
	</cffunction>

	<cffunction name="getSurname" access="public" output="false">
		<cfreturn variables.instance.surname />
	</cffunction>

	<cffunction name="getUsrLevel" access="public" output="false">
		<cfreturn variables.instance.usrLevel />
	</cffunction>

	<cffunction name="getPasswd" access="public" output="false">
		<cfreturn variables.instance.passwd />
	</cffunction>

	<cffunction name="getZones" access="public" output="false">
		<cfreturn variables.instance.zones />
	</cffunction>


	<!--- SETTERS --->	

	<cffunction name="setUsrId" access="public" output="false">
    	<cfargument name="usrId" required="yes" type="string" />
		<cfset variables.instance.usrId = arguments.usrId />
	</cffunction>

	<cffunction name="setUsrName" access="public" output="false">
    	<cfargument name="usrName" required="yes" type="string" />
		<cfset variables.instance.usrName = arguments.usrName />
	</cffunction>

	<cffunction name="setFirstName" access="public" output="false">
    	<cfargument name="firstName" required="yes" type="string" />
		<cfset variables.instance.firstName = arguments.firstName />
	</cffunction>

	<cffunction name="setSurname" access="public" output="false">
    	<cfargument name="surname" required="yes" type="string" />
		<cfset variables.instance.surname = arguments.surname />
	</cffunction>

	<cffunction name="setUsrLevel" access="public" output="false">
    	<cfargument name="usrLevel" required="yes" type="numeric" />
		<cfset variables.instance.usrLevel = arguments.usrLevel />
	</cffunction>

	<cffunction name="setPasswd" access="public" output="false">
    	<cfargument name="passwd" required="yes" type="string" />
		<cfset variables.instance.passwd = arguments.passwd />
	</cffunction>

	<cffunction name="setZones" access="public" output="false">
    	<cfargument name="zones" required="yes" type="struct" />
		<cfset variables.instance.zones = arguments.zones />
	</cffunction>

	<cffunction name="getMemento" access="public" 
				output="false" 
				hint="I return a dumped struct of the 
						variables.instance scope.">
		<cfreturn variables.instance />
	</cffunction>

</cfcomponent>



<cfcomponent displayname="userDAO" output="false" hint="User DAO Class for fake user table">

	<cfset variables.instance = {
        dataSource = ''
    } />

	<cffunction name="init" access="public" output="false" returntype="any">

		<cfreturn this>
	</cffunction>

	<cffunction name="createUser" access="public" output="true" returntype="numeric">
		<cfargument name="user" required="true" type="user" />
        
        <cfset var qInsert = '' />
        <cfset var insertResult = 0 />

        <cfquery name="qInsert" 
        	datasource="mDns"
            result="insertResult">
            INSERT INTO users (
            	usrName, firstName, surname, usrLevel, password, dateCreated) 
            VALUES (
                <cfqueryparam cfsqltype="cf_sql_varchar" value="#arguments.user.getUsrName()#" />,
                <cfqueryparam cfsqltype="cf_sql_varchar" value="#arguments.user.getfirstName()#" />,
                <cfqueryparam cfsqltype="cf_sql_varchar" value="#arguments.user.getSurname()#" />,
                <cfqueryparam cfsqltype="cf_sql_varchar" value="#arguments.user.getUsrLevel()#" />,
                <cfqueryparam cfsqltype="cf_sql_varchar" value="#arguments.user.getPasswd()#" />,
                NOW()
			)
		</cfquery>                

		<cfreturn insertResult.generatedKey />
	</cffunction>


	<cffunction name="getUserById" access="public" output="true">
    	<cfargument name="usrId" required="true" type="numeric" />

        <cfset var objUser = '' />
        
        <cfquery name="qSearch"
        	datasource="mdns">
            SELECT * 
            FROM users 
            WHERE usrId = <cfqueryparam cfsqltype="cf_sql_integer" value="#arguments.usrId#" />
		</cfquery>

		<cfif qSearch.recordCount>
        <cfset objUser = createObject('component','managedDNS.dev.ultraApi.user').init(
			qSearch.usrId,
			qSearch.usrName,
			qSearch.firstName,
			qSearch.surname,
			qSearch.usrLevel,
			qSearch.password,
			structNew()) />
		</cfif>
		
        <cfreturn objUser />
    </cffunction>

	<cffunction name="getUserBySearchTerm" access="public" output="true">
    	<cfargument name="searchTerm" required="true" type="string" default="" />

        <cfset var objUser = '' />
        
        <cfquery name="qSearch"
        	datasource="mdns">
            SELECT * 
            FROM users 
            WHERE usrName LIKE  % <cfqueryparam cfsqltype="cf_sql_varchar" value="#arguments.usrId#" />%
		</cfquery>

		<cfif qSearch.recordCount gt 0>
        <cfset objUser = createObject('component','managedDNS.dev.ultraApi.user').init(
			qSearch.usrId,
			qSearch.usrName,
			qSearch.firstName,
			qSearch.surname,
			qSearch.usrLevel,
			qSearch.password,
			structNew()) />
		</cfif>
		
        <cfreturn objUser />
    </cffunction>


	<cffunction name="updateUser" access="public" output="false">
		<cfargument name="user" required="true" type="user" />

        <cfset var boolSuccess = true />
		
		<cftry>
            <cfquery name="qUpdate"
                datasource="mdns">
                UPDATE users SET 
                usrName = <cfqueryparam cfsqltype="cf_sql_varchar" value="#arguments.user.getUsrName()#" />,
                firstName = <cfqueryparam cfsqltype="cf_sql_varchar" value="#arguments.user.getFirstName()#" />,
                surname = <cfqueryparam cfsqltype="cf_sql_varchar" value="#arguments.user.getSurname()#" />,
                usrLevel = <cfqueryparam cfsqltype="cf_sql_integer" value="#arguments.user.getUsrLevel()#" />,
                password = <cfqueryparam cfsqltype="cf_sql_varchar" value="#arguments.user.getPasswd()#" />
                WHERE usrId = <cfqueryparam cfsqltype="cf_sql_integer" value="#arguments.user.getUsrId()#" />
            </cfquery>
            
            <cfcatch type="database">
	            <cfset boolSuccess = false />
            </cfcatch>
        </cftry>
        
		<cfreturn boolSuccess />
	</cffunction>
</cfcomponent>

Open in new window

0
fajizzle
Asked:
fajizzle
  • 4
  • 3
  • 3
1 Solution
 
donnievCommented:
This may not help you as it doesn't relate to ColdBox but I use an array of objects when I retrieve the results of a query and pass the array around the application including to the client. Details here: http://blog.vawterconsultingservices.com
0
 
fajizzleAuthor Commented:
Hi, thanks for your response, sorry it has taken me a while to get back to you but I have been trying to build some code that does the same sort of thing as yours.

I am looping through and creating a bean for each user and then loading into a structure so at any point I can just go <cfset myName = rrBeanCollection[myPos].getUserName() this seems to work really well but the passing of the objects around the system is an issue as I use client scope and this doesn't seem to like anything other than basic data types.

Are you using client scope?
0
 
donnievCommented:
Most of our work makes extensive use of cfc's which are in general scope agnostic so we just pass information around as arguments to the cfc. We do not use client scope.I suppose if you needed to use simple data types you could searialize your bean to store it and then deserialize it when you needed data.
0
How to Use the Help Bell

Need to boost the visibility of your question for solutions? Use the Experts Exchange Help Bell to confirm priority levels and contact subject-matter experts for question attention.  Check out this how-to article for more information.

 
_agx_Commented:
(not for points...)

     > I use client scope and this doesn't seem to like anything other than basic data types.

Yeah, they only supports simple types.  Can I ask why you're using the client scope? It seems like an unusual, and potentially slow, use of the client scope.

   > Do I create an object for each? if so how?
   > OR do I hold the query in an object and handle the output on each page.

Personally I think it depends on what the data's used for. IMO there's not much benefit in adding the o/h of creating a bunch of objects if you're just doing a cfoutput. Just my $0.02.

That said, I don't use ColdBox either and don't know of any ColdBox experts floating around right now.  I hate to send people elsewhere, but frameworks are very specialized.  You'd probably have better luck asking about "ColdBox best practices" on their mailing list.  

0
 
fajizzleAuthor Commented:
I am using client scope as this is a client project and that was their instruction. I would tend to use session myself for storing user specific data but haven't had to do this OO thing before so am not sure what scope to use that would persist at all times for that user session?

I totally agree about building objects being silly when just outputting a query too. In this case I am just need to hold several records as a bean and move them about a bit. There is plenty of documentation for creating a single data object but nothing mentions more than 1!
0
 
_agx_Commented:
> that was their instruction.

Um.. are they CF developers? ;-)

Hm... I'm still wondering why. ie What's the plain english requirement? Because which scope you should use, depends on a number of factors. what you're storing, why you're storing it, for how long and how frequently you need to access/update it.  There are exceptions, but usually the client scope is used for minimal amounts of data, like "my preferences".  

0
 
fajizzleAuthor Commented:
that's what I had always assumed. I normally tend to use session as it is far more flexible but I have been instructed no to. Is there any other than session, client or application that would possibly be considered for holding data structures to pass around?
 
0
 
_agx_Commented:
What are their reasons for saying don't use the session scope? Because doing something just because the client says so usually doesn't end well ;) There should be solid reasons behind that kind of design decision.

As far as persistent scopes, that's pretty much it.  How much data are you talking about and is it used/updated on every request? I'm totally in the dark.
0
 
donnievCommented:
Seems to me that session scope is the best if you need to maintain state. It can get huge if you just keep stuffing stuff there but used judiciously it is very useful. Like any other technique it is subject to abuse but that doesn't mean you should avoid it. Sounds to me like your client may have heard some horror story about session scope and made an arbitrary decision or maybe the environment is load balanced and doesn't have the capability to manage sticky sessions.
0
 
_agx_Commented:
Yeah, that's why I think they should find out more about the client's reasoning.
0

Featured Post

Free Tool: Port Scanner

Check which ports are open to the outside world. Helps make sure that your firewall rules are working as intended.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

  • 4
  • 3
  • 3
Tackle projects and never again get stuck behind a technical roadblock.
Join Now