I am working on a new project. It was the result of my need to figure out a few things in a different project I was working on.
I have named this project "CFCMApper". Basically it maps out all the dependences between CFCs. The mapper will crawl a directory recursively and find all the CFCs. It will take what it finds and map out other object calls are made from inside the CFCs. IT will then store the results and create a browsable version. You can then see what object calls are being made by a CFC. You will also be able to do the inverse and see what CFCs are calling an specific object.
This is not a replacement for the CFC explorer that ships with ColdFusion. It is merely a tool to see the dependences between objects. The CFC explorer does not examine the code for object calls nor does it create a list of dependences. The CFCMapper does not go into detail about the CFC.
More details to come as I work out all the code. I will be setting up a website for it very soon so stay tuned. The website will allow you to sign-up to get a prerelease version to take it for a test drive. If you want to get an alpha version to play around with send me an email (dave@dkferguson.com) and I'll get it to you.
--Dave
Thursday, December 21, 2006
Tuesday, December 19, 2006
Store Object in CF Query
I was working on an application that takes an xml document and transforms it into a simulated database query return. I made a minor typo and discovered something that I did not know was possible. Instead of putting the xmlText into the cell I actually put the whole xml node into the cell. For example:
TheQuery = QueryNew("col1, col2");
TheXML = XMLParse("c:\thexml.xml", false);
void = QueryAddRow(TheQuery , 1);
void = QuerySetCell(TheQuery , "col1", TheXML.rootNode.xmlChildren[i].subNode.xmlText);
void = QuerySetCell(TheQuery , "col2", TheXML.rootNode.xmlChildren[i].subNode);
In the example above the output would have the xmltext of the subNode in col1 and the entire subNode in col2.
I am not quite sure how or where to use this. However, knowing it is possible may be handy someday.
--Dave
TheQuery = QueryNew("col1, col2");
TheXML = XMLParse("c:\thexml.xml", false);
void = QueryAddRow(TheQuery , 1);
void = QuerySetCell(TheQuery , "col1", TheXML.rootNode.xmlChildren[i].subNode.xmlText);
void = QuerySetCell(TheQuery , "col2", TheXML.rootNode.xmlChildren[i].subNode);
In the example above the output would have the xmltext of the subNode in col1 and the entire subNode in col2.
I am not quite sure how or where to use this. However, knowing it is possible may be handy someday.
--Dave
Thursday, December 14, 2006
Looping query output
There are a few way to output query, CFloop or CFOutput. When you want to get fancy you can use cfloop and reference the query like an array for example:
<CFLOOP INDEX="z" FROM="1" TO="#Query.recordcount#">
#query.column[z]#
</CFLOOP>
Now, here is where the fun comes in. I was writing an app where I needed to see what was in the next row so I could do something with the current row. I had this in my code:
#query.column[z+1]#
This worked perfectly fine and I had no issues. However, I forgot to add an if to make sure I was not on the last row before I checked the next row. Instead of getting an error I got a strange response. I actually got a blank result. So, I then got curious. So, I did this:
#IsDefined(query.column[1])# -- #query.column[1]#
I got this as a response:
NO -- 123
In conclusion I discovered 2 things:
1: isDefined on a query column using array syntax always returns no.
2: Query column output using array syntax can reference a nonexistent row and not error.
<CFLOOP INDEX="z" FROM="1" TO="#Query.recordcount#">
#query.column[z]#
</CFLOOP>
Now, here is where the fun comes in. I was writing an app where I needed to see what was in the next row so I could do something with the current row. I had this in my code:
#query.column[z+1]#
This worked perfectly fine and I had no issues. However, I forgot to add an if to make sure I was not on the last row before I checked the next row. Instead of getting an error I got a strange response. I actually got a blank result. So, I then got curious. So, I did this:
#IsDefined(query.column[1])# -- #query.column[1]#
I got this as a response:
NO -- 123
In conclusion I discovered 2 things:
1: isDefined on a query column using array syntax always returns no.
2: Query column output using array syntax can reference a nonexistent row and not error.
Tuesday, December 12, 2006
CFDUMP inside CFCSCRIPT
It is true, you can not call CF tags from inside CFSCRIPT. However, you can call a function that can run CF tags. Using this knowledge you can to a wealth of things. Most importantly you can do a CFDUMP inside CFSCRIPT. Here is an example of how to call a function that does a CFDUMP from inside CFSCRIPT:
<CFSCRIPT>
sampleArray = Arraynew(1);
for (z = 1; z LT 100; z=z+1){
sampleArray[z] = z;
if (z EQ 50){
writeoutput(dumpIt(sampleArray));
}
}
</CFSCRIPT>
<CFFUNCTION NAME="dumpIt">
<CFARGUMENT NAME="theData" REQUIRED="YES" TYPE="ANY">
<CFSAVECONTENT VARIABLE="theDump">
<CFDUMP VAR="theData">
</CFSAVECONTENT>
<CFRETURN theDump>
</CFFUNCTION>
<CFSCRIPT>
sampleArray = Arraynew(1);
for (z = 1; z LT 100; z=z+1){
sampleArray[z] = z;
if (z EQ 50){
writeoutput(dumpIt(sampleArray));
}
}
</CFSCRIPT>
<CFFUNCTION NAME="dumpIt">
<CFARGUMENT NAME="theData" REQUIRED="YES" TYPE="ANY">
<CFSAVECONTENT VARIABLE="theDump">
<CFDUMP VAR="theData">
</CFSAVECONTENT>
<CFRETURN theDump>
</CFFUNCTION>
Monday, December 11, 2006
CFC Explorer Returns eronious message
I was working with a CFC today and ran into an odd issue with the CFC explorer. The issue seems to be specific to the EXTENDS attribute of the CFCOMPONENT tag. The problem shows up when the EXTENDS attribute points to a CFC that does not exist. But it is actually not that simple. Lets say you build a CFC without the EXTENDS then call the CFC and have it show in the CFC explorer. Then you edit the CFC and add the EXTENDS attribute and refresh the CFC explorer window. Now if the EXTENDS points to a valid CFC then everything is fine. However, if it points to a CFC that does not exist you will get a weird error. Instead of a CF error claiming that the EXTENDS points to an invalid CFC you will get this error:
' cannot be found on this server.
If this happens just call the cfc directly again and you will get the actual error message.
--Dave
Component not found
The component definition file for component 'If this happens just call the cfc directly again and you will get the actual error message.
--Dave
Sunday, December 10, 2006
Gateways calling gateways
I am currently working on a project that entails directory watcher gateways and scheduled tasks to call asynchronous gateways. Then the asynchronous can call other asynchronous gateways and basically keep a server side process running non stop. Unfortunately I can not go into the details of the application but I am learning more about how to "tame the animal". Once I get all running and tested I will share with you all some of the cool tricks I have come up with. As well as some "lessons learned".
A couple things I have learned already:
1: How clean up and restart failed processes due to a crash.
2: How to prevent multiple processes from firing the same asynchronous process.
That is it for now,
--Dave
A couple things I have learned already:
1: How clean up and restart failed processes due to a crash.
2: How to prevent multiple processes from firing the same asynchronous process.
That is it for now,
--Dave
Saturday, December 09, 2006
Commitment to help
So,
I have been doing this internet development thing for years (10+ to be exact). Over the years I have spent some time helping others with their code issues. I have mentored others and helped them expand their abilities. I spent some time in the forums trying to answer peoples questions and give quality answers.
Recently I decided to write an article, (coming soon to a journal near you). While I was writing the article I realized a few things;
1: I have a ton of knowledge that I should share.
2: I could write something that is wrong or not the "best practice".
Here is how I decided to solve these. First, try and write more articles. Write about things that people could use in their applications. Secondly, best practice is a myth (my opinion) and everyone is wrong at least once.
So, look to this blog for new and interesting things I discover while doing what I do best, writing code.
That is it for now,
--Dave
I have been doing this internet development thing for years (10+ to be exact). Over the years I have spent some time helping others with their code issues. I have mentored others and helped them expand their abilities. I spent some time in the forums trying to answer peoples questions and give quality answers.
Recently I decided to write an article, (coming soon to a journal near you). While I was writing the article I realized a few things;
1: I have a ton of knowledge that I should share.
2: I could write something that is wrong or not the "best practice".
Here is how I decided to solve these. First, try and write more articles. Write about things that people could use in their applications. Secondly, best practice is a myth (my opinion) and everyone is wrong at least once.
So, look to this blog for new and interesting things I discover while doing what I do best, writing code.
That is it for now,
--Dave
Subscribe to:
Posts (Atom)