Yesterday I was reading an article on Ben Forta's blog, Look, No Datasource, where he described how in ColdFusion 9, we can specify a default datasource at the application level that can then be used with all tags that use a datasource attribute. So instead of doing:
1 <cfquery name="getShots" datasource="#application.dsn#">
we can instead just do:
1 <cfquery name="getShots">
This is cool and all, but a reader commented that it would be nice if we could also supply default mail settings at the server level. I agree with him, it would be nice. Things like datasources, mail settings, etc, are typically high level things that individual tags should not need to worry about.
It occurred to me that he may not be aware of a feature, added in ColdFusion 8, which kind of allows for this right now. For a long time custom tags have supported an attributeCollection argument. This is a structure that acts like passed in arguments. So if a custom tag takes two arguments, num1 and num2, I could actually pass them in like so:
1 <cfset s = {num1="2",num2="67"}>
2 <cf_foo attributeCollection="#s#">
That's not a great example as it didn't save me any keystrokes, but I think you get the idea. ColdFusion 8 simply expanded this to built in tags. So taking the reader's comment about mail, you could, if you wanted, do this in your Application.cfc file:
2 <cf_foo attributeCollection="#s#">
1 <cfset application.mail = {server="127.0.0.1",username="mail",password="pass"}>
and then pass it to your cfmail tags:
1 <cfmail to="some@where.com" from="admin@foo.com" subject="Your Email" attributeCollection="#application.mail#">
2 foo
3 </cfmail>
Ok, so again, there isn't a huge savings in keystrokes, but it does allow you to change your mail tags from one central structure. Mail server doesn't require a password anymore? Just remove it from the struct. Want to supply a failto attribute? Add it to the struct and every cfmail tag uses the struct will be updated.
I've got to be honest and say that I've not yet used this in production (mainly because I keep forgetting about it!) but it's pretty powerful stuff. Anyone out there using it?
2 foo
3 </cfmail>
Comment 1 written by todd sharp on 21 June 2009, at 9:41 PM
<cfset m = structNew() />
<cfset m.to = "address@mail.com" />
<cfif iWantACopy>
<cfset m.cc = "me@my.com" />
</cfif>
<cfmail attributeCollection="#m#">ray is a jedi</cfmail>
Comment 2 written by Raymond Camden on 21 June 2009, at 9:58 PM
<cfif devServer>
cc to me
</cfif>
Comment 3 written by Paul on 21 June 2009, at 9:58 PM
Comment 4 written by Dale Fraser on 21 June 2009, at 11:46 PM
We do this always, and never specify mail server etc on the <CFMAIL tag
Comment 5 written by salvatore fusto on 22 June 2009, at 2:30 AM
salvatore
Comment 6 written by Jody Fitzpatrick on 22 June 2009, at 5:22 AM
I have a question about SoZo Hosting if you know anything about them.
1.) Are the reliable?
2.) Do you think they can support 10,000+ active users at the same time?
I assume that you would recommend them being that you have a banner linking to their site.
If you are not sure it's okay... Just wondering, and once I order I will make sure I click on your banner so you can get the sale lead... you taught me a lot an really helped me with the auto refresh div.
P.S
Could your Captcha get any simplier?
Comment 7 written by Robert Haddan on 22 June 2009, at 10:22 AM
Comment 8 written by Steven Esser on 22 June 2009, at 10:33 AM
Happens from time to time to my applications that there is need to use two datasources. Then I suppose that you will have to use the datasource argument at all cfqueries.
For cfmail I don't make use of the server settings as I have set that on server level. I just have to keep specifying from and to's etc but I suppose you could write an easy function that checks for debug level or something so that I receive the message instead of the emailaddress meant for the application.
Comment 9 written by todd sharp on 22 June 2009, at 10:50 AM
As it's been said, the default datasource (this.datasource) can be overridden at the tag level. The reason they added this feature is for ORM (Hibernate) integration. There needed to be a way for CF to know which datasource it was dealing with behind the scenes, so this.datasource was added to specify a default datasource.
(Per Adam Lehman at our UG tour meeting last week)
Comment 10 written by Steven Esser on 22 June 2009, at 11:51 AM
Comment 11 written by todd sharp on 22 June 2009, at 12:13 PM
Comment 12 written by Raymond Camden on 22 June 2009, at 2:26 PM
Comment 13 written by Raymond Camden on 22 June 2009, at 3:06 PM
Comment 14 written by Sean Corfield on 22 June 2009, at 9:25 PM
obj = orm.load(objectID);
... do stuff to obj ...
obj.save(); // or orm.save(obj);
So the data source is bound into the ORM essentially at initialization time.
With Transfer, you can have multiple Transfer factory instances, one per data source, if you want but, like Ray says, most applications have one main transactional data source and perhaps a separate reporting data source (for which you would not use ORM).
I suspect it would make the Hibernate integration more difficult to use if there had to be some way to have separate instances per data source. Based on what Adobe has shown of Hibernate integration, it looks like they've spent a lot of time on making it very easy to use.
Comment 15 written by Gary Funk on 22 June 2009, at 9:39 PM
Comment 16 written by todd sharp on 22 June 2009, at 9:49 PM
Comment 17 written by Gary Funk on 22 June 2009, at 11:28 PM
Comment 18 written by todd sharp on 23 June 2009, at 7:52 AM
Comment 19 written by Gary Funk on 23 June 2009, at 8:20 AM
[Add Comment] [Subscribe to Comments]