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:
<cfquery name="getShots" datasource="#application.dsn#">
we can instead just do:
<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:
<cfset s = {num1="2",num2="67"}>
<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:
<cfset application.mail = {server="127.0.0.1",username="mail",password="pass"}>
and then pass it to your cfmail tags:
<cfmail to="some@where.com" from="admin@foo.com" subject="Your Email" attributeCollection="#application.mail#">
foo
</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?
Archived Comments
I use it a bit, but not for the purpose you're demonstrating. Instead I use it as a more elegant way to handle conditional attributes. Example:
<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>
Handy for those of us using shared hosting, didn't know about it.
Ah yeah, that's a good one. You could image:
<cfif devServer>
cc to me
</cfif>
You can already control the mail settings at a server level in Administrator.
We do this always, and never specify mail server etc on the <CFMAIL tag
i'm used to enclose the cfmail tag in a cfc, init'ed with some attributes whose default values are the dafaults and call a sendmail(...) method to send emails.
salvatore
Hey Ray
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?
I use attribute collections extensively so that I can call tags via cfscript that don't have native cfscript support. Lately I've been mixing a lot of CF functionality with Java functionality, so being able to write everything in cfscript makes my code a lot easier to read.
I guess it can be handy at times to not have to declare the datasource at all times, but I also know of applications where you rather want to keep that option: multiple databases, multiple datasources!
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.
@Steven:
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)
@todd sharp: Can ORM's such as Hibernate and Transfer not work with multiple datasources? Or was it just a generally 'wanted' feature in this case.
@Steven - To be honest, I'm not sure the answer to that. Maybe Ray knows - he's travelling today if I remember correctly so let's see what he says later.
Afaik, Transfer is one DSN only. Not sure about Hibernate. To be honest, this doesn't concern me too much. In the 15 years I've been in dev, I think I've had 2 clients who needed multiple, and even then, the second one was used maybe 10% of the time, so this new CF9 feature will still be pretty useful in cases where you might have multiple DSNs in play.
Jody, this is a bit off topic. Can you ping me directly via my contact form?
@Steven, ORMs operate on a single data source because the syntax tends to be:
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.
I think only the government uses more than one datasource. In my office, our main CF server connects to two MySQL servers and one DB2 server on an AS400, and one other datasource on our FECS server. The two main sources are the DR2 and one of the MySQL servers. That makes up about 85% with the DB2 coming in at about 35%.
Is that liberal math? 85%+35% != 100%....
No, of the 85%, 35% is DB2
@Gary - It was a joke ;)
You're telling me. All these servers and connections. Just so we can know when it's time to go to lunch and take our breaks.