cftopper.com

Rant Warning: Ruby on Rails Sucks

I think Ruby on Rails sucks. I'm sick of hearing about it.

I just watched all the videos at:

http://www.rubyonrails.org/screencasts

and i'm not excited. OK maybe "sucks" is extreme, but in fairness, it definitely is way over-hyped. It's nowhere near as great as it hype. Really!

One thing I will say, the documentation doesn't make RoR look like a piece-of-cake.

It's late - I'm too tried, lazy and inarticulate to make a decent argument so I'll leave it to the experts... just do a google search for "ruby on rails sucks". I just did... wow apparently I'm not the first to blog this exact opinion - people are sick of reading "yet-another-ruby-sucks-bait-post" so i'll shut up now.

But there, I said it. I'm happy now.

ColdFusion is a much better platform in my humble, biased opinion.

Update

Excellent - Joel shares my opinion.... and he's actually used it. And it makes interesting reading. Aside from all the hype, it looks like RoR ain't no smoking joe.

The solution is to stop playing and start over at the beginning and DO THINGS RIGHT THIS TIME, DAMMIT! Here is an actual entry from the Rails FAQ:

"Q012:That stinks... I want the scaffold code without starting over!

Too bad. Start a new rails project, run scaffold, then manually add the missing stuff to your new project from your old project with copy and paste."

Are we having fun yet?

Tags: ColdFusion | Rant

QueryWizard Version 1.1

Today I made a number of important improvements to the QueryWizard that I started yesterday. Already the QueryWizard is proving to be a useful tool for me. Just unzip this and execute <cf_queryWizard>.

The Query Wizard

I've tried to make the Query Wizard as intelligent as possible.

  • Matching Field Names
    It automatically links up any URL or FORM variables to matching fields. But database fields are often prefixed with the name of the table (at least at DCHQ they always are) so it matches the right hand side of the column name against the variables names.
  • Preview of Field Values
    As you see in the drop down for matching fields I now display a preview of the data that was held in the field when <cf_queryWizard> was executed.
  • Query Name Selection
    The wizard does it best to pick a suitable name for the generated query. If you are INSERTing into the "Monkeys" table, the query will be called "InsertMonkey".
  • Matching indentation level
    You can place <cf_queryWizard> anywhere in your CFM template and the query that is generated in its place will match your indentation keeping everything nice and neat.

Road-map

  • Ability to specify SORT ORDER when doing SELECT
  • Ability to SELECT from multiple tables and specify the join type and clause - this is going to be tricky Messing
  • General improvements to interface including have the generated query not scroll

And with that I'm out of ideas so please download the query wizard and hit me with your suggestions.

Tags: My Work | Tools | WebDev

Javascript: Date.getYear() Gotcha

Working with some older code using firefox whereas during development I would have used IE. It took me a while to track a problem down where a selected date was returning 106 instead of 2006 for the year.

Date.getYear() returns 2006 in IE and 106 in Firefox.

Thats sucks but just use Date.getFullYear() to get around this.

Tags: Tips | WebDev

Finding the filename of the parent tag

Sometimes I've needed a custom tag to perform an operation on the actual code file that called it. However in coldfusion, there is no way (that I know of) to easily get the name or file path of the parent CFM file.

So I used to have to pass in the current file name like this:

<cf_someTag thisFile="#GetCurrentTemplatePath()#">

But yesterday, I cheated. When making the QueryWizard, I thought that the full list of executed templates is available and displayed when an error is thrown. Eureka! I simply throw a deliberate error within the tag, catch the error and extract the data I need like so:

<!--- Get the path to the caller template path by creating a
deliberate error and getting the path from the stack trace --->
<!--- I don't know of a better way! --->
<cfif NOT isdefined( "ATTRIBUTES.thisfile" )>
<cftry>
 <cfset abc = TheVarWontExist>
 <cfcatch type="Any">
  <cfset ATTRIBUTES.thisfile = cfcatch.tagContext[4].template>
 </cfcatch>
</cftry>
</cfif>

I know it probably won't work in everything (read:Bluedragon/CF5) so I still allow the attribute 'thisFile' to be passed, if required.

If there is a better way I am ignorant of, please educate me.

Tags: ColdFusion | Tips

I've been thinking about making this tag to quickly knock out queries for literally years now. The advantage of doing this at run-time is that we have access to the list of variables that are available.

So lets say you made a contact form and on the contact form's action page you want to insert the details into the database...

  1. Just type <cf_queryWizard> on the action page and run it - i.e. submit the form. Then wizard opens in a new window.
  2. Choose type "insert"
  3. Choose the table that will store the records
  4. Match each database field to the correct FORM variable provided in the list.
  5. Click "Insert this query".

I spent the last 6 hours writing it but I'm hoping that we'll all benefit from this. I'm giving it out completely free to all fellow ColdFusion developers. I'd love to see this in wide usage so please let everybody know about it.

Notes

  • The tag works best if you have the variables "APPLICATION.datasource", "APPLICATION.db_username" and "APPLICATION.db_password" but if not you can pass in your own datasource, username and password as normal. e.g.
    <cf_queryWizard datasource="#myds#" username="#myusername'" password="#mypass#">
  • You can not place this is the customtags directory - It calls itself as a standalone coldfusion page and needs to be present in the directory.
  • There was no way to figure out which file is executing the tag so I cheated Messing
    I got around this by deliberately creating an error and getting the parent file name from the cfcatch.tagcontext. A clever hack but might cause this tag to not work with BlueDragon etc so I also allow you to pass in the path the current file like so: <cf_queryWizard thisfile="#GetCurrentTemplatePath()#">.
  • You can run <cf_queryWizard abort="yes"> to halt execution until the query is programmed.
  • Note: You can only have one of these on a page at a time. I'll fix that for version 2.
  • Security Note: It should be completely secure so long as only a developer gets to execute this. The permissions to edit are session/uuid based.

Hit me with your feedback. Source code is open - fell free to hack. Sorry for lack of comments - I just ploughed this out.

Update

Dan spotted a bug when using this with Internet Explorer. Fixed now.

Tags: My Work | Tools

MySQL Data Storage: InnoDB vs MyISAM

For those who don't know, InnoDB and MyISAM are the 2 main data storage engines available in MySQL. In our literally hundreds of database-driven websites and projects at Digital Crew, we use both the InnoDB and MyISAM storage engines, often together on the individual tables within a project.

So which engine should we use for a given table? Is it OK to mix and match the 2 different table types within a project?

I researched this issue a year ago and found a myriad of different opinions with no conclusive advice but I did so again this morning and here is the outcome as sent in an email to the rest of the Digital Crew team.

Guys, I was concerned that we shouldn't mix InnoDB and MyISAM table types within a database but after searching nobody seems to say that is an issue.

It boils down to this, we can mix and match MyISAM and InnoDB tables as we please but should consider which the storage engine as follows:

Use MyISAM when:

  1. Speed is important - ( "MyISAM is slightly faster" )
  2. The data isn't too critical ( "unreliable and slow, related to table size, table repair process" ) 
  3. You need Full-Text search support - (InnoDB doesn't support full text search, that said MyISAM is meant to be none-too-great at it with large data sets either - use Lucene when data set gets massive)

Use InnoDB for tables when:

  1. Referential integrity must be enforced ("if you need foreign key constraints or transactions, you can only use InnoDB" )
  2. The table gets a lot of writes ( "If you have a lot of concurrent inserts/updates I would recommend InnoDB since it supports row-locking." )
  3. The table will be big (100Mb+ - "For reliability and performance, we use InnoDB for almost everything at Wikipedia - we just can't afford the downtime implied by MyISAM use and check table for 400GB of data when we get a crash." )
  4. The table is critical ( "InnoDB is safer" )

So if we are going to mix and match storage engines, use the advice above to help choose the correct type. On the other hand, James Day, a MySQL Support Engineer and Wikipedia engineer recommends that people use InnoDB all the time unless for some reason if becomes apparent that you need MyISAM:

I'd go with InnoDB until it's been proved that it's unsuitable. The first reason is reliability. Get a crash with MyISAM and you have the unreliable and slow, related to table size, table repair process. Same thing with InnoDB and you instead get the fixed time, fast and reliable log apply/rollback process. As the data set gets bigger, this matters more and more, as it does if you want to do things like sleep instead of being woken up in the middle of the night to fix a crashed table.

For reliability and performance, we use InnoDB for almost everything at Wikipedia - we just can't afford the downtime implied by MyISAM use and check table for 400GB of data when we get a crash.

The speed advantage of MyISAM is overstated IMO. LiveJournal with a mostly write environment saw a big increase in speed when it switched from MyISAM to InnoDB and they are very happy with InnoDB.

At Wikipedia we achieved some major performance gains by exploiting the way InnoDB clusters records by their primary key. Took some quite common queries from 50 seeks per result page to 1 or 2 seeks per page. Worse, the code at that time allowed people to go back 50,000 rows using LIMIT, causing 50,000 seeks and a DOS vulnerability. Big improvement to working set size from the change as well, so the results were more often in cache. It's so great an advantage that like the write caching it could be a dealbreaker for anything MySQL might do about alternatives to InnoDB.

With InnoDB, if you don't need repeatability, you might also switch to the least consistent transaction isolation level for a particular query, since that can reduce the locking work InnoDB needs to do. That is, assuming that you really do need only the MyISAM lack of guarantees.

On the other hand, a crazy bit of code did once use SELECT ... FOR UPDATE to scan every row of a table. Switching that table to MyISAM was a quick hack until it could be fixed. The table locking of MyISAM was way faster than watching InnoDB lock every row individually.

We used to use MyISAM for fulltext, duplicating the data in the InnoDB master table. Once the query rate grew sufficiently high and the data size grew past a gigabyte or so it became completely unacceptable on performance grounds, taking more than half of our database server capacity and still not working well. We abandoned it and switched to Lucene. By that point we were in the top thousand sites on the net, so it had survived pretty well.

I'm also as MySQL Support Engineer but these views are from my Wikipedia role, not the MySQL one.

James Day

http://mysqldatabaseadministration.blogspot.com/2006/02/innodb-or-myisam-whats-your-preference.html

I'm going to take James Advice and use InnoDB for almost everything and MyISAM only when its suits.

About Topper on ColdFusion

Peter Coppinger aka Topper is a neurotic web monster who spends most of his chaotic life developing ColdFusion web applications when not drinking himself into a stupor and scheming his plans for world dominance.

Peter founded Digital Crew way back in 1999. Digital Crew run CFTagStore.com and have also produced lots of powerful ColdFusion tools like ProFlashUpload and CFMyAdmin.

I made this site to share my thoughts, tips and tools with fellow ColdFusion developers.

If your a ColdFusion developer, go ahead and subscribe to this site and in exchange i'll try to provide quality content to make it worth your while.
RSS Feed for Topper on ColdFusion

I'm speaking at CF-United Europe!

CFDevCon I'm going to be speaking at CFDevCon08! It's my second time speaking in front of more than 10 people so please lend your support.

The topic is:
Introducting TeamworkCMS and Site Engine - Building better websites in half the time or something like that..

Digging

My Work - Just Finished

  • modules.cit.ie
    Web-=based modules/programmes designer tool and database system for Cork institute of technology.
  • Teamwork Project Manager
    The top secret project is finally released. The project management app will rock your world - give it a go.
  • PMG
    New website for Project Management Group website.
  • Digital Warehouse Wholesale
    Added wholesale products to existing client website.
  • New Digital Crew documentation website
    New version of documentation.digital-crew.com using new InfinityCMS site engine. It's done now. Just add content.
  • PFH Company Webite
    New website/CMS/Newsletter System for prestigious Irish IT company.
  • Module Manager for CIT
    CIT is switching to module based courses. We are making an application for managing/submitting these modules. Gettig there.
  • Bons Secours Cork Hospital Intranet
    New Intranet for Bons Secours hospital in Cork. Considering turning this Intranet system into stand-alone product.
  • Revamping InfinityCMS
    I'm making major improvements to our content management solution, InfinityCMS. Making it faster, more powerful and easier to check into/out-of source control. Done but it's always going to be evolving.
  • BPC Update
    Minor functionality update for internal Pfizer Best Process Chemistry project.