I have created a number of datasources in Lucee using code. This is for a legacy ColdFusion application that we are migrating to Azure, and per the powers-that-be, they want the DSNs created in code so we can store the DSN passwords in a keystore. I have that part already working.
The datasources look something like this: this.datasources["myDSN"]
If, in the code (Application.cfm), I do this:
<cfset myDSN = this.datasources["myDSN"]>
This will then fail:
<cfquery name="whatever" datasource="#myDSN#">
It fails with "datasource myDSN not found."
BUT, if I do this instead:
<cfquery name="whatever" datasource="#this.datasources['myDSN']#">
... it works fine.
Is there a workaround for this? At last check in this one application alone, there are 368 occurrences of datasource= in 115 files. I'd rather not have to do a bulk search/replace. It makes no sense to me that the variable "myDSN" would fail.
As there are multiple datasources being used, I can't just set the default datasource and remove the datasource= attribute entirely; even then, it'd still require a mass search/replace.
I must be missing something. I've read the Lucee docs on datasources but it hasn't helped. Thanks!
Turns out that Scott Stroz was correct. I switched over to Application.cfc and now it works fine.
Related
I am writing a ColdFusion program that uses cfquery to get data from an AS/400 iSeries table and then output that data to a web page. Some times the Data is in Chinese, but it does not output the Chinese characters correctly.
I built the query below for testing,
<cfprocessingdirective pageEncoding="UTF-8" />
<cfquery name="Test" Datasource = "AS400">
select dsc1 from sales where ref = '123456'
</cfquery>
<cfoutput>#test.dsc1#</cfoutput>
The result should be "M5方头螺栓" but I only get "M5". I did another test running just:
<cfset x = "M5方头螺栓"/>
<cfoutput>#x#</cfoutput>
and it displays the Chinese no problem.
Since ColdFusion can display the characters when they are written out in the code, but not when it goes to get the data through SQL, it seems like the issue is with either my ODBC settings or my ColdFusion Server Data Source Settings but I'm not familiar enough with these settings to know what needs to be changed to get this working.
A workaround was found and discussed within the comments. Adding some details here as an answer for future visitors to this page.
There are a couple of considerations when dealing with Unicode (Chinese) characters:
The data type for the database table must be set to nvarchar
The form processing script (CFML) must be set to utf-8
I believe ColdFusion defaults to this but you can specify the setting to be sure.For example: <cfprocessingDirective pageEncoding=”utf-8″>
Enable "String Format" within the ColdFusion datasource settings
Under the ColdFusion administrator datasource settings select the appropriate datasource you are using. Then click on the "show advanced settings" button. That will show an option for "String Format" Enable High ASCII characters and Unicode for data sources configured for non-Latin characters. Select this option and save the datasource.
The issue for the OP was that they were using an ODBC datasource and the "String Format" option was not available. After some research and the lack of finding any way to configure an ODBC datasource for that setting I recommended trying to use the builtin JDBC driver for "DB2 Universal Database" that comes with ColdFusion. Switching to that driver resolved this issue for the OP.
From the comments
Good info. Though is "Enable String Format..." necessary with the added support for cf_sql_nvarchar in CF10+? – #Leigh
I do believe Leigh is correct that the newer versions of ColdFusion (10 and later) have much better support for nvarchar fields.
Also to note, it looks like some older versions of ColdFusion don't always work with the installed DB2 Universal Driver, and it doesn't look like the older standard versions even have it, I'm not sure if the newer ones have it either, but using the "other" option with jt400.jar, should also work. - #MHall
You've already proven that CF can output UTF-8 characters correctly. Have you tried running that query in the DB console or UI? Do you get the correct charaters?
If the characters were stored as VARCHAR and not NVARCHAR, then there's nothing you can do. The data has to have been properly stored in the first place.
If the characters are stored correctly in the DB, try adding <cfprocessingdirective pageEncoding="utf-8"> at the top of the request. CF should be using UTF-8 by defualt, but this will force the correct character set if, for some reason, it isn't.
I am migrating a very old app (currently running in CF8) to Lucee. But I am running into a problem with what appears to be a custom tag of some sort.
I have tried to make sure that all the virtual directories are the same in IIS for both the old and the new installs. And made sure the mapping and custom tag paths in both the CFIDE and the Lucee Admin are the same.
But I am getting this error. And can't figure out how this cflink is being instantiated.
I have found the location of the erroring code on line 300 the utils.cfc file
I haven't used custom tags in a long time but thought they were generally called with an underscore and the code should like more like <cf_link pageid="#LinkPageID#" Init="start"> if this was being called as a custom tag.
If I go the the current CF server that is running this app I can find that a cfclass files HAS been created
From a file called cflink.cfm in a directory called "tags" even though there seems to be no mapping for the "tags" directory nor is is listed under "custom tags paths" in the administrator.
This App was start in 2003 and as you can imagine has grown into a mis-match of spaghetti code and no one from the beginning is around to ask how this tag is instantiated.
Does anyone with experience in legacy code has any other ideas where I should be looking to try to get this to work? The currently has only a production environment and if I can get it to work on Lucee it will not only be a dev environment that hasn't existed here in 10 years but will be a great way for me to be able to continue showcasing Lucee as a great CFML engine
Adding addition info
Leigh had asked if the init might be a jar reference but in the cflink.cfm file I see this code:
<cfif Attributes.Init IS "start">
<cfset Request.PageID = Attributes.PageID>
<cfset Request.Page_Width = Variables.qParentInfo.Page_Width>
<cfset Request.Page_Height = Variables.qParentInfo.Page_Height>
<cfset Request.Page_TypeID = Variables.qParentInfo.Page_TypeID>
<cfset Request.AddPath = "">
<cfif IsDefined("Attributes.Anchor")>
<cfset Request.Anchor = Attributes.Anchor>
<cfelse>
<cfset Request.Anchor = "">
</cfif>
<cfset Request.IsInternalLink = false>
<cfexit method="EXITTAG">
</cfif>
There are also references to cflink in the code inside tags\cflink.cfm
<cfif Len(Variables.qParentInfo.ParentID) GT 0>
<!--- Add the page title to the end of the path --->
<cfset Request.AddPath = ReplaceNoCase(Variables.qParentInfo.Nav_Title," ","_","ALL") & "/" & Request.AddPath>
<cflink init="working" pageid="#Variables.qParentInfo.ParentID#" popcode="#Attributes.popcode#">
<cfelse> ......</cfif>
Although this may be recursion given it was written in 2004 I kind of doubt it
Adding screen shots of searches
If anyone else runs into this. In CF8, and presuming earlier versions, you could put a cfm file into the ColdFusion8\wwwroot\WEB-INF\cftags Directory and that file in this case ColdFusion8\wwwroot\WEB-INF\cftags\link.cfm Then acts as any other cftag.
I was able to find the person who originally build this app in 2004 and he told me that they did it this way to avoid typing the underscore that they would have typed if they'd done it as a custom tag.
I kind of get it since this tag is used everywhere in the app, literally hundreds of times. Bit boy with a bitch to find.
Now all I have to do is figure out how to move it to the Lucee world in a similar fashion. So it instanciates the same way.
Thanks #Leigh for all your help, you are always amazing!
Adding more information
if there are files in the WEB-INF\lucee\library\tag the corresponding Lucee directory is WEB-INF\lucee\library\tag. These files are read on load and then able to be used as any other cf tag.
For example if you have file WEB-INF\lucee\library\tag\link.cfm it can be called by `cflink'.
Seems like a cool idea but a bit of a bitch for someone to find 10 years after the fact
I was charged with making some modification to an old application, and I created a new page which was being passed a URL parameter page_name, which is a you guessed it a name of a page with .cfm appended. So, in my haste, I continued using it, and was building out my CFC and using the page_name as the identifier for a record. Then I realized that there is a possibility of that name being duplicated in the table, and changed that url parameter to use the page_id, which is unique. I modified my CFC to use the new key, and nothing worked. So I started going through my code and figured I made a typo, started commenting things out, and finally dumped out my CFC object and voila, none of the edits I made were actually being used. This was fairly obvious, since page_name was a string, and page_id was numeric.
So I started googling,The first thing I saw as adjust things in the CFAdmin. I don't have access to it, and restarting the server isn't an option since I'm using an RDS to live code. The next thing I tried was to add applicationStop(), onApplicationStart(), to my Application.cfc. Well the problem is that the Application.cfc, is actually an Application.cfm. So after fiddling with the <cfapplication ... > tag, and nothing being updated, I'm here asking for help.
So is there a quick fix for this? Should I go ahead and create an application.cfc? I hope I explained myself, and sorry for all the text.
Confirm that your cfc is bound to either the session or application scope.
If it is, then you can rename the application in application.cfm and it will reset the object.
If your cfc is NOT bound to session or application scope, you have a cacheing issue. You need to go the the CF admin -> Server Settings -> Cache tab and uncheck component cache and possibly some others.
For further recommendations, ColdFusion Components Inheriting Functions Of Others
Sounds like you have been painted into a corner. Last option IF you have access the the server it self and can get into the C:\ or whatever drive that ColdFusion have been installed on, you can just manually delete the generated Java Class files that the server is using that has the old code. When ColdFusion sees there is no Class file it will recompile the newly changed file and whoa black betty go bam-a-lam your changes will be in production.
For more information here is an posting you can read up on: http://kalyan-coldfusion.blogspot.com/2010/08/how-coldfusion-works-and-its-key.html
Cheers
Having trouble deleting keys from a Solr collection for files.
Updating the Solr collection with this:
<cfoutput query="fileQuery">
<cfset theFile = defaultpath & "#fileID#.pdf" />
<cfif fileExists(theFile)>
<cfindex
action="update"
collection="file_vault_solr"
type="file"
key="#theFile#"
title="#documentName#"
body="fileNumber,documentName"
custom1="/filevault/#filealias#"
custom2="#fileNumber#"
custom3="#documentName#"
>
</cfif>
</cfoutput>
However, when attempting to delete the key from the catalog it simply doesn't work. Here's the code being used to (try to) delete the keys:
<cfoutput query="deletedFile">
<cfset theFile = defaultpath & "#fileID#.pdf" />
<!--- Remove the deleted file from the collection. --->
<cfindex
collection="file_vault_solr"
type="file"
action="Delete"
key="#theFile#"
>
</cfoutput>
The key is not deleted, however. The only thing that has worked has been to purge the whole catalog and re-index all of the documents.
Any insights?
After a lot of debugging I found out.
The reason for this behavior is a very… uh… unfortunate uhm… "design decision" Adobe took when implementing the interface between ColdFusion and Solr.
So you have a Solr collection of indexed files and want to selectively purge the ones that do no longer exist on disk. I'm pretty sure that's the exact situation you've been in.
Let's assume:
there is a file called /path/to/file on your system and
it is indexed in the Solr collection foo.
When you issue a <cfindex collection="foo" action="delete" key="/path/to/file">, ColdFusion sends the following HTTP request to Solr:
POST /solr/foo/update?wt=xml&version=2.2 (application/xml; charset=UTF-8)
<delete><id>1247603285</id></delete>
This is a perfectly reasonable request that Solr will happily fulfill. The only strange thing is the number in the <id>. In any case, the file will be gone from the index after this operation.
Re-index the file and delete it from disk. Now:
there no longer is a file called /path/to/file on your system, but
it is still indexed in the Solr collection foo.
Let's do the same <cfindex action="delete"> operation again.
POST /solr/foo/update?wt=xml&version=2.2 (application/xml; charset=UTF-8)
<delete><id>/path/to/file</id></delete>
Huh? Shouldn't there be a number in the ID?
As it turns out, someone at Adobe thought it would be a jolly smart idea to use numbers for unique IDs of indexed files, to, uhhh, save space, I assume.
However for some inexplicable reason this only happens when the file in question still exists. If it does not exist anymore, ColdFusion will notice and pass the path instead.
Inspecting the number reveals that it would fit into a 32 bit signed integer value. (I've checked, there are plenty of negative values in the uid field of the collection.)
So this looks as if they use some kind of hashing algorithm that returns 32 bits and chuck that in a int. CRC32 springs to mind, but that's not it. Also, java.util.zip.CRC32 returns a long, so there wouldn't be any negative values in the first place.
The other readily available 32 bit hash in Java is ... java.lang.Object.hashCode().
Bingo.
"/path/to/file".hashCode() // -> 1247603285
So the solution is to never delete a file by its path, but always like this:
<cfindex collection="foo" action="delete" key="#path.hashCode()#">
For files that no longer exist this does the right thing.
More importantly: For files that still exist this does the right thing as well - ColdFusion would have sent the hash code anyway.
Until Adobe fixes this problem this is a safe and easy work-around.
Note that the file path is case sensitive and must match exactly with the one stored in the index.
A quick
<cfsearch collection="foo" name="foo">
without any criteria will return all index entries, so retrieving the exact path of orphaned entries it not a big problem.
Eric Lippert explains object hash codes and why it is a bad idea to use them for anything "practical" in an application It's a .NET article but applies to Java just as well.
It boils down to: Adobe should store the actual path in the Solr collection and leave the performance optimization they seem to have attempted to Solr.
I've filed Bug 3589991 against Adobe's ColdFusion bug database.
The key has to match exactly what is in Solr's index. So ensure that "defaultpath" is the same in both and check that the case matches as I believe Solr is case sensitive.
To debug this I would suggest that you add the status="myStatusVar" to the cfindex call . Then on both the add and delete to see what is going on. If the delete is not returning a Deleted Count. Then there is a Key mismatch.
<cfindex
collection="file_vault_solr"
type="file"
action="Delete"
key="#theFile#"
status="myStatusVar"
>
I'm looking for a complete list of tags that are not available in ColdFusion 9 script syntax.
Example:
CFSetting: is one example that is available in Railo but not in CF9 for use in cfscript
CFDocument: I can't find this one so far.
Not an official list by any measure, but this is a list I presented to a private forum a while back, and it didn't receive too much correction (and those corrections have been integrated). It was in the context of what CF does and doesn't need to be implemented, to claim 100% coverage in CFScript.
Summary of omissions:
These ones are significant omissions:
<cfcollection>
<cfexchangecalendar>
<cfexchangeconnection>
<cfexchangecontact>
<cfexchangefilter>
<cfexchangemail>
<cfexchangetask>
<cfexecute>
<cfindex>
<cfinvoke> (support for dynamic method names)
<cflogin>
<cfloginuser>
<cflogout>
<cfmodule>
<cfoutput> (implementation of query looping with grouping)
<cfparam> (fix the bug in that enforced requiredness doesn’t work (ie: param name="foo";))
<cfsearch>
<cfsetting>
<cfwddx>
<cfzip>
<cfzipparam>
There’s a reasonable case for these ones to be implemented:
<cfassociate>
<cfcache>
<cfcontent>
<cfflush>
<cfhtmlhead>
<cfheader>
<cfntauthenticate>
<cfprint>
<cfschedule>
<cfsharepoint>
These ones... I’m ambivalent:
<cfgridupdate>
<cfinsert>
<cfobjectcache>
<cfregistry>
<cfreport>
<cfreportparam>
<cftimer>
<cfupdate>
We don’t need these ones at all, I think:
<cfajaximport>
<cfajaxproxy>
<cfapplet>
<cfcalendar>
<cfchart>
<cfchartdata>
<cfchartseries>
<cfcol>
<cfdiv>
<cfdocument>
<cfdocumentitem>
<cfdocumentsection>
<cffileupload>
<cfform>
<cfformgroup>
<cfformitem>
<cfgraph>
<cfgraphdata>
<cfgrid>
<cfgridcolumn>
<cfgridrow>
<cfinput>
<cflayout>
<cflayoutarea>
<cfmap>
<cfmapitem>
<cfmediaplayer>
<cfmenu>
<cfmenuitem>
<cfpod>
<cfpresentation>
<cfpresentationslide>
<cfpresenter>
<cfselect>
<cfsilent>
<cfslider>
<cfsprydataset>
<cftable>
<cftextarea>
<cftextinput>
<cftooltip>
<cftree>
<cftreeitem>
<cfwindow>
If there's anything here that you think ought to be included in CFScript, please raise an issue here - http://cfbugs.adobe.com/cfbugreport/flexbugui/cfbugtracker/main.html - and cross reference the issue number here.
HTH.
I would argue that there are no commands that are not available as script as you can extend and write the missing bits using cfc's.
Thus wrap your favourite missing <cftag in a cfc and call it using new
However, here is a list of what is supported
http://help.adobe.com/en_US/ColdFusion/9.0/Developing/WSe9cbe5cf462523a02805926a1237efcbfd5-7ffe.html