Finding images not referenced in a DB table - coldfusion

I get a query of all the files (images) in a directory
<cfset local.teamBase = "#GetDirectoryFromPath(GetBaseTemplatePath())#teamlogo\">
<cfdirectory action="LIST" directory="#local.teamBase#" name="rc.qryTeamLogo">
I later loop over all these filenames, skipping those that are in use
<select name="Logo" <cfif deleted>disabled="disabled"</cfif>>
<option></option>
<cfloop query="rc.qryTeamLogo">
<cfif name EQ mylogo>
<option value="#name#" selected>#name#</option>
<cfelseif request.objTeam.isUsed(name) EQ 1 OR name EQ "thumbs.db">
<!--- Do not show --->
<cfelse>
<option value="#name#">#name#</option>
</cfif>
</cfloop>
</select>
The isUsed() function looks like
<cffunction name="isUsed" returntype="boolean" output="false">
<cfargument name="logo" required="true" type="string">
<cfquery name="qryUsed" datasource="#application.DSN#">
SELECT logo
FROM CCF.team
WHERE logo = <cfqueryparam cfsqltype="CF_SQL_VARCHAR" value="#arguments.logo#">
AND Deleted = 0
</cfquery>
<cfif qryUsed.recordcount EQ 0>
<cfreturn false>
</cfif>
<cfreturn true>
</cffunction>
The problem with this is as more and more files get added, this gets slower and slower.
What I would really like a single query that can assemble the whole thing

You can run one query before your select box
<cfquery name="qryLogos" datasource="#application.DSN#">
SELECT logo
FROM CCF.team
WHERE logo IN (<cfqueryparam cfsqltype="CF_SQL_VARCHAR" value="#valueList(rc.qryTeamLogo.name)#" list="true">)
AND Deleted = 0
</cfquery>
Then set all those logo's into an array and add thumbs.db too, so you have one less check to do.
<cfset allLogs = listToArray(valueList(qryLogos.logo))>
<cfset arrayAppend(allLogs,'thumbs.db')>
and then change your elseif to this
<cfelseif arrayFind(allLogs,name)>
<!--- don't display --->

Load the file information into XML. Shread the XML into a table and JOIN on that.
<cfset local.teamBase = "#GetDirectoryFromPath(GetBaseTemplatePath())#teamlogo\">
<cfset local.qryTeamLogo = DirectoryList(local.teamBase, false, "query")>
<cfsavecontent variable="local.xmlTeamLogo">
<ul class="xoxo">
<cfoutput query="local.qryTeamLogo">
<li><code>#xmlformat(name)#</code></li>
</cfoutput>
</ul>
</cfsavecontent>
<cfquery name="local.qryResult">
DECLARE #xmlTeamLogo xml = <cfqueryparam cfsqltype="CF_SQL_varchar" value="#local.xmlTeamLogo#">
SELECT Value AS Name
FROM dbo.udfXOXORead(#xmlTeamLogo)
WHERE NOT Value IN (
SELECT Logo
FROM CCF.Team WITH (NOLOCK)
WHERE Deleted = 0
)
</cfquery>
The Table Valued Function
create function [dbo].[udfXOXORead](#xmlData xml)
returns #tblmessage TABLE (
[value] nvarchar(max) NULL
)
as
begin
INSERT INTO #tblMessage
SELECT Tbl.Col.value('(code)[1]', 'nvarchar(max)') AS [value]
FROM #xmlData.nodes('/ul/li') Tbl(Col)
RETURN
end

Related

notify a user if there are no matching records found - coldfusion

How do you create something to notify a user if there are no matching records found with the queries you run?
I have a queries.cfm that I run like this:
<cfset result = {} />
<cftry>
<cfset date1 = CREATEODBCDATETIME(form.StartDate & '00:00:00')>
<cfset date2 = CREATEODBCDATETIME(form.EndDate & '23:59:59')>
<cfquery datasource="#application.dsn#" name="GetEmployeeInfo">
SELECT trans_location, date, associate
FROM cl_checklists
WHERE date >= <cfqueryparam value="#date1#" cfsqltype="cf_sql_timestamp" />
AND date <= <cfqueryparam value="#date2#" cfsqltype="cf_sql_timestamp" />
AND trans_location IN ( <cfqueryparam value="#FORM.location#" cfsqltype="cf_sql_varchar" list="true" /> )
AND associate IN ( <cfqueryparam value="#FORM.EmployeeName#" cfsqltype="cf_sql_varchar" list="true" /> )
</cfquery>
<cfquery datasource="#application.dsn#" name="GetLocationInfo">
SELECT trans_location, date, associate
FROM cl_checklists
WHERE date >= <cfqueryparam value="#date1#" cfsqltype="cf_sql_timestamp" />
AND date <= <cfqueryparam value="#date2#" cfsqltype="cf_sql_timestamp" />
AND trans_location IN ( <cfqueryparam value="#FORM.location#" cfsqltype="cf_sql_varchar" list="true" /> )
</cfquery>
<cffunction name="getop_id" access="public" returntype="string">
<cfargument name="associate" >
<cfquery name="spitOutop_id" datasource="#application.userinfo_dsn#">
SELECT assoc_name
FROM dbo.tco_associates
WHERE assoc_id= #arguments.associate#
</cfquery>
<cfreturn spitOutop_id.assoc_name >
</cffunction>
<cfquery name="allAssociatesQry" dbtype="query">
SELECT DISTINCT associate, COUNT(*) AS associateCount FROM GetEmployeeInfo GROUP BY associate ORDER BY associate
</cfquery>
<table border="1" id="Checklist_Stats">
<thead>
<th><strong>Associate Name</strong></th>
<th><strong>Location</strong></th>
<th><strong>Checklists Generated by Associate</strong></th>
<th><strong>Checklists Generated by Selected Location(s)</strong></th>
<th><strong>Associate Percentage of Location Total</strong></th>
</thead>
<tbody>
<!--- aggregate variables --->
<cfset aggrAssociateChecklist = 0>
<cfset aggrLocationChecklist = 0>
<cfloop query="allAssociatesQry">
<!--- get Associate's name --->
<cfset thisAssociateCode = trim(allAssociatesQry.associate)>
<cfset thisAssociateName = getop_id(thisAssociateCode) />
<!--- 1.1 get all trans_location code and total counts for the current Associate --->
<cfquery name="allLocCodeForAssociateQry" dbtype="query">
SELECT trans_location,count(trans_location) AS locCntr FROM GetEmployeeInfo WHERE associate='#thisAssociateCode#' GROUP BY trans_location ORDER BY trans_location
</cfquery>
<!--- 1.2 get the aggregate of checklist count generated by the current Associate for each location --->
<cfquery name="qTotalChecklistCountForAssociate" dbtype="query">
SELECT SUM(locCntr) AS totalAssocChecklist FROM allLocCodeForAssociateQry
</cfquery>
<!--- 2.1 get the total location checklist for each location available for the current Associate --->
<cfquery name="allLocChecklistForAssociateQry" dbtype="query">
SELECT trans_location,count(trans_location) AS totalLocCount FROM GetLocationInfo WHERE trans_location IN (#QuotedValueList(allLocCodeForAssociateQry.trans_location)#) GROUP BY trans_location ORDER BY trans_location
</cfquery>
<!--- 2.2 get the aggregate of location checklist generated by the current Associate --->
<cfquery name="qTotalLocChecklistForAssociate" dbtype="query">
SELECT SUM(totalLocCount) AS totalLocChecklist FROM allLocChecklistForAssociateQry
</cfquery>
<!--- display record for the current Associate --->
<cfoutput query="allLocCodeForAssociateQry">
<tr>
<!---<td><strong>#thisAssociateCode#</strong></td>--->
<td><strong>#thisAssociateName#</strong></td>
<td>#allLocCodeForAssociateQry.trans_location#</td>
<td>#allLocCodeForAssociateQry.locCntr#</td>
<td>#allLocChecklistForAssociateQry['totalLocCount'][CurrentRow]#</td>
<td>#NumberFormat((allLocCodeForAssociateQry.locCntr/allLocChecklistForAssociateQry['totalLocCount'][CurrentRow]) * 100, '9.99')#%</td>
</tr>
<cfset thisAssociateName = "" />
</cfoutput>
<!--- 3.1 get sub total for each Associate group --->
<cfset totalAssocChecklist = qTotalChecklistCountForAssociate.totalAssocChecklist>
<cfset totalLocChecklist = qTotalLocChecklistForAssociate.totalLocChecklist>
<!--- 3.2 add to the aggregate --->
<cfset aggrAssociateChecklist += totalAssocChecklist>
<cfset aggrLocationChecklist += totalLocChecklist>
<!--- display sub total for each Associate group --->
<cfoutput>
<tr>
<td>Associate Total</td>
<td></td>
<td>#totalAssocChecklist#</td>
<td>#totalLocChecklist#</td>
<td>#NumberFormat((totalAssocChecklist/totalLocChecklist) * 100, '9.99')#%</td>
</tr>
</cfoutput>
</cfloop>
<!--- display calculated aggregate at the end of the result --->
<!--- <cfoutput>
<tr>
<td><strong>Total</strong></td>
<td></td>
<td>#aggrAssociateChecklist#</td>
<td>#aggrLocationChecklist#</td>
<td>#NumberFormat((aggrAssociateChecklist/aggrLocationChecklist) * 100, '9.99')#%</td>
</tr>
</cfoutput>--->
</tbody>
</table>
<cfcatch type="any">
<cfset result.error = CFCATCH.message >
<cfset result.detail = CFCATCH.detail >
</cfcatch>
</cftry>
But I am trying to notify the user when no results come back based on there search.
I was trying to do a catch for the results if there 0 do something but have been unsuccessful. Would any Cold Fusion gurus like to assist me in how you alert your users when there query came back empty.
I tried:
<cfif #allAssociatesQry# is 0>
<cfif #allAssociatesQry# is null>
<cfif #allAssociatesQry# is "">
<cfif allAssociatesQry is 0>
<cfif allAssociatesQry is null>
<cfif allAssociatesQry is "">
Don't use try/catch. That's for code that doesn't run successfully. All you need is this:
<cfquery name="q">
sql
</cfquery>
<cfif q.recordcount is 0>
code for no records
<cfelse>
display records
</cfif>

ISSUE with ColdFusion TRANSACTION and Data Concurrency

I am creating and assigning a value in a variable at the top of the function. But somehow the value gets replaced with other user's table record. This happened when two users doing transaction at same time with different records. Also it is happening only once in a while.
I have mentioned the issue in comments in below code.
<cffunction name="functionname" output="true">
<cfargument name="formData">
<cftransaction action="begin">
<cftry>
<cfquery name="getDoc_no" datasource="#variables.dsn#">
SELECT CONCAT(TO_CHAR(SYSDATE,'YYYY'),WORK_REQ_SEQ.NEXTVAL) as NEXT_NO FROM DUAL
</cfquery>
<cfset doc_no_seq=getDoc_no.NEXT_NO> <!---creating variable doc_no_seq --->
<cfquery name="getWo_no" datasource="#variables.dsn#">
SELECT WORK_ORDER_SEQ.nextval as NEXT_NO FROM DUAL
</cfquery>
<cfset Trns_seq=getWo_no.NEXT_NO> <!--- creating variable Trns_seq --->
<cfquery name="insert1" datasource="#variables.dsn#">
INSERT into WORK_ORDER
(
DOC_NO,
TRANS_ID
)
Values
(
<cfqueryparam value="#doc_no_seq#" cfsqltype="cf_sql_integer">, <!--- Inserted CORRECT doc_no_seq value --->
<cfqueryparam value="#Trns_seq#" cfsqltype="cf_sql_integer"> <!--- Inserted CORRECT Trns_seq value --->
)
</cfquery>
<cfif isdefined("IdnoRes") and IdnoRes gt 0>
<cfloop from="1" to="#IdnoRes#" index="q">
<cfif trim(Evaluate("rsc_grp_id_#q#")) is not "" and trim(Evaluate("qty_#q#")) is not "">
<cfquery name="insert2" datasource="#variables.dsn#">
INSERT into REQ_RESOURCE_DTLS
(
DOC_NO ,
TRANS_ID
)
Values
(
<cfqueryparam value="#doc_no_seq#" cfsqltype="cf_sql_integer">, <!--- Inserted WRONG doc_no_seq value --->
<cfqueryparam value="#Trns_seq#" cfsqltype="cf_sql_integer"> <!--- Inserted WRONG Trns_seq value --->
)
</cfquery>
</cfif>
</cfloop>
</cfif>
<cfif isdefined("Idnojob") and Idnojob gt 0>
<cfloop from="1" to="#Idnojob#" index="q">
<cfif trim(Evaluate("frm_des_#q#")) is not "" and trim(Evaluate("to_des_#q#")) is not "">
<cfquery name="insert3" datasource="#variables.dsn#">
INSERT into JOB_SEQ_DTLS
(
DOC_NO ,
TRANS_ID
)
Values
(
<cfqueryparam value="#doc_no_seq#" cfsqltype="cf_sql_integer">, <!--- Inserted WRONG doc_no_seq value --->
<cfqueryparam value="#Trns_seq#" cfsqltype="cf_sql_integer"> <!--- Inserted WRONG Trns_seq value --->
)
</cfquery>
</cfif>
</cfloop>
</cfif>
<cftransaction action="commit" />
<cfcatch type="any">
<cftransaction action="rollback" />
</cfcatch>
</cftry>
</cftransaction>
<cfreturn 1>

ColdFusion autosuggest in text field is not responsive

I have a text field that I want to autosuggest values based on a query. I have a main file along with a separate file (getdata.cfc) that holds my query.
Here is the text field portion of my main file:
<cfinput name="search_query" autosuggest="url:getdata.cfc?suggestvalue={cfautosuggestvalue}" maxResultsDisplay="10" showAutoSuggestLoadingIcon="true" size="10" />
Here is the code in getdata.cfc:
<cfcomponent>
<cffunction name="get_data" access="remote" output="false">
<cfargument name="suggestvalue" required="true">
<cfquery name="get_data" datasource="#application.DSN#">
SELECT DISTINCT myItem
FROM myTable
WHERE myItem LIKE <cfqueryparam value="#suggestvalue#%"
cfsqltype="cf_sql_varchar">
ORDER BY myItem
</cfquery>
<cfif get_data.recordCount eq 1>
<cfreturn ",#get_data.myItem#">
<cfelse>
<cfreturn ValueList(get_data.myItem)>
</cfif>
</cffunction>
</cfcomponent>
The text field shows up fine, but when I type a word no autosuggest values show up. Nothing happens. The text is just displayed as I type it.
Any suggestions? Thank you!
I switched away to using jquery plugins from a lot of CF stuff, but here is an example I have that works in some old production code
<cfinput type="text" name="email" id="email" autosuggest="cfc:cfc.users.lookupEmail({cfautosuggestvalue})" maxresultsdisplayed = "25">
<cffunction name="lookupEmail" access="remote" returntype="array">
<cfargument name="search" type="any" required="false" default="">
<!--- Define variables --->
<cfset var data="">
<cfset var result=ArrayNew(1)>
<!--- Do search --->
<cfquery name="data" datasource="datasource" maxrows="25" cachedwithin="#CreateTimeSpan(0,0,30,0)#">
SELECT distinct email
FROM users
WHERE email LIKE <cfqueryparam cfsqltype="cf_sql_varchar" value="#arguments.search#%">
ORDER BY email
</cfquery>
<!--- Build result array --->
<cfloop query="data">
<cfset ArrayAppend(result, email)>
</cfloop>
<!--- And return it --->
<cfreturn result>
</cffunction>
maybe this helps
also make sure you have your cfform tags around your form, and make sure that your /cfide folder is mapped to your website.
looking at your code and comparing it... it may be the way your calling the cfc (filename)
try: autosuggest="cfc:getdata.get_data.({cfautosuggestvalue})"

ColdFusion: Common Update Pattern

I usually create update statements like this. But I know there is a better way. How can I approve upon this? *Note the sample below is pseudo demo, may not run.
<cffunction name="updateEmp" returntype="void">
<cfargument name="empId" required="yes" hint="empId">
<cfargument name="firstName" required="yes" hint="firstName">
<cfargument name="lastName" required="yes" hint="lastName">
<!--- Get emp details in db --->
<cfquery datasource="#ds#" name="getEmployee">
SELECT *
FROM Employee
WHERE emp_id = <cfqueryparam
value="#arguments.empId#"
CFSQLType="CF_SQL_INTEGER">
</cfquery>
<!--- If employee is in db or if emp db details are different --->
<cfif getEmployee.recordCount eq 1
and getEmployee.firstName neq trim(arguments.firstName)
or getEmployee.lastName neq trim(arguments.lastName)>
<cfquery name="UpdateExistingEmployee" datasource="#ds#">
UPDATE Employee
SET 1 = 1
<cfif getEmployee.firstName neq trim(arguments.firstName)>
,firstName = <cfqueryparam
value="#arguments.firstName#"
CFSQLType="CF_SQL_VARCHAR" >
</cfif>
<cfif getEmployee.lastName neq trim(arguments.lastName)>
,lastName = <cfqueryparam
value="#arguments.lastName#"
CFSQLType="CF_SQL_VARCHAR" >
</cfif>
WHERE emp_id=<cfqueryparam
value="#emp_id#"
CFSQLType="CF_SQL_INTEGER">
</cfquery>
</cfif>
<!--- maybe return success? --->
</cffunction>
Edited:
<cffunction name="updateEmp" returntype="void">
<cfargument name="empId" required="yes" hint="empId">
<cfargument name="firstName" required="yes" hint="firstName">
<cfargument name="lastName" required="yes" hint="lastName">
<cfquery name="UpdateExistingEmployee" datasource="#ds#">
UPDATE Employee
SET firstName = <cfqueryparam
value="#arguments.firstName#"
CFSQLType="CF_SQL_VARCHAR" >
,lastName = <cfqueryparam
value="#arguments.lastName#"
CFSQLType="CF_SQL_VARCHAR" >
WHERE emp_id=<cfqueryparam
value="#emp_id#"
CFSQLType="CF_SQL_INTEGER">
</cfquery>
<!--- maybe return success? --->
</cffunction>
Not sure what you are trying to improve. If you just want to write less code you might just do an update:
<cffunction name="updateEmp" returntype="void">
<cfargument name="empId" required="yes" hint="empId">
<cfargument name="firstName" required="yes" hint="firstName">
<cfargument name="lastName" required="yes" hint="lastName">
<cfquery name="UpdateExistingEmployee" datasource="#ds#">
UPDATE Employee
SET firstName = <cfqueryparam value="#arguments.firstName#" CFSQLType="CF_SQL_VARCHAR">
,lastName = <cfqueryparam value="#arguments.lastName#" CFSQLType="CF_SQL_VARCHAR" >
WHERE emp_id=<cfqueryparam value="#emp_id#" CFSQLType="CF_SQL_INTEGER">
</cfquery>
</cffunction>
The check for an existing record is pretty much superfluous since the where clause will prevent any action if no emp_id matches, and why bother checking if the names match? If they do, then you just updated them to be the same, if they don't you're going to update them anyway. There's no logical reason to be doing all that checking.
Maybe check out Coldfusion ORM? Or, for something that would require less drastic changes to your codebase, you could use DataMgr (which really helps cut down on CRUD): http://datamgr.riaforge.org/

Problems getting the id from the result

I'm returning 2 results from a stored proc and trying to display a logo if one of them has badgeid 2. They have a badge id column with values of 1 and 2. I'm trying to do this but it won't work:
<cfif qBadges.badgeid EQ 2>
logo here
</cfif>
If I change it to 1 it will show the old logo. 2 is a new logo I just added. Thanks!
Edit
<cfstoredproc procedure="sel_MemberBadges_p" datasource="DSN">
<cfprocparam type="In" cfsqltype="CF_SQL_INTEGER" value="#ID#">
<cfprocresult name="qBadges">
</cfstoredproc>
<cfif qBadges.badgeid EQ 2>
new logo here
<cfelseif qBadges.badgeid EQ 1>
old logo
</cfif>
Do this
<cfif qBadges.badgeid[1] EQ 2>
new logo here
<cfelseif qBadges.badgeid[2] EQ 1>
old logo
</cfif>
It is because unless you specify what row you want it will return the first one.
Try dumping out the result so you can see the badge id values:
<cfstoredproc procedure="sel_MemberBadges_p" datasource="DSN">
<cfprocparam type="In" cfsqltype="CF_SQL_INTEGER" value="#ID#">
<cfprocresult name="qBadges">
</cfstoredproc>
<cfdump var="#qBadges#" />
<cfabort />
<cfif qBadges.badgeid EQ 2>
new logo here
<cfelseif qBadges.badgeid EQ 1>
old logo
</cfif>