Getting Started With Code Generators - Part 2

In the last post in the Project Learn series we installed the Illudium PU-36 Code Generator. This post will go into a little more detail and we will actually get into generating some code.

Before I get started I should give a quick mention that the actual application that we will be building in this series will be an extremely simple Content Management System (CMS). Essentially the system will have a users table, a pages table and a few other miscellaneous tables (tables for links, link targets, etc). I figured this would be the easiest way to dig into the code generators and framework while still being something that is actually a (hopefully) usable end product.

If you'd like to build along with this series you can download the attached scripts by clicking on 'Download' below. There are two scripts in the zip - one for creating the table structure in MSSQL 2000 and another for 2005. I will not be adding support for any other dbms since I really do not use any other dbms. After you have the zips, create a database called CMS and point a CF datasource to that db. Run the table creation scripts and you're database is ready to go.

So now we have our db, our CF DSN and the code generator. Open the code generator and you should notice that the new DSN 'CMS' should be available in the DSN drop down. I believe appending ?reload=1 to the url will reinit the DSNs if yours is not shown (I'm sure Brian will confirm if that is true). The next step is to chose a table and a template and enter the dot notation path to where your components will eventually reside. In my case my path will be 'cms.com.user'. Note - in looking ahead at the Mach-ii documentation this path should/may/will probably change in the future, but for now I'm just evaluating the generator - not customizing any of the code so I will come back later and regenerate the code with the proper path if I choose to ultimately use the resulting code.

Before I go further let me jump back to the Template option in the generator. For this let me quote Brian's documentation:

The generator allows you to choose the set of templates that you would like to generate against, allowing you the ability to add custom templates without modifying the core code. The custom stylesheets should be placed in a subfolder of /xsl/projects/. You will find a copy of the core files in there under the prototype folder that you can copy or rename. There is also an included set of templates for using Mark Mandel's Transfer ORM project.

I chose the 'default' template. In conjunction with the other options defined above you are now ready to make some code - just click on the 'Generate' button and several tabs of components are created. So far pretty simple I must say.

At this point we now have 6 components generated for us - bean, DAO, gateway, service, to and coldspring. Being new to full blown OO I am a little confused at this point. I'm OK with the bean, DAOand gateway. Beans are your individual data elements at the lowest level - essentially each column in your table represents a bean. Bean components have what are called 'assecors' - essentially your get and set methods. Here is an example of the userId getter and setter:

<cffunction name="setuserId" access="public" returntype="void" output="false">
   <cfargument name="userId" type="string" required="true" />
   <cfset variables.instance.userId = arguments.userId />
</cffunction>
<cffunction name="getuserId" access="public" returntype="string" output="false">
   <cfreturn variables.instance.userId />
</cffunction>

So what I'm picturing is a form in the application that will be posted with the individual form fields being used to 'set' the beans. Later I'm assuming that the DAO will 'get' the bean to do simple CRUD operations (note to self: in what scope will the beans ultimately be held?).

Before moving on to the DAO, let me add that Brian has a super cool feature in the bean component - a validate() method. Here's a snippet of the portion of the validate() function as it relates to the userId field from the database:

<cfset var errors = arrayNew(1) />
<cfset var thisError = structNew() />
      
<!--- userId --->
<cfif (NOT len(trim(getuserId())))>
   <cfset thisError.field = "userId" />
   <cfset thisError.type = "required" />
   <cfset thisError.message = "userId is required" />
   <cfset arrayAppend(errors,duplicate(thisError)) />
</cfif>
<cfif (len(trim(getuserId())) AND NOT IsSimpleValue(trim(getuserId())))>
   <cfset thisError.field = "userId" />
   <cfset thisError.type = "invalidType" />
   <cfset thisError.message = "userId is not a string" />
   <cfset arrayAppend(errors,duplicate(thisError)) />
</cfif>

Here Brian has built in validation based on the dbms metadata. He's determined that our userId is both required (does not allow null inserts) and nvarchar (isSimpleValue) and has pre-built the validation for us to return an array of structs containing all failed validation checks for all of the beans in this method. I'm sure I'd clean up the messages a little bit to make them a little more user friendly, but the fact that the code is in place seems to be a huge timesaver. I'm seeing this being tied into the form submission later on when we are 'setting' our beans.

Another cool feature is the dump method:

<cffunction name="dump" access="public" output="true" return="void">
   <cfargument name="abort" type="boolean" default="false" />
   <cfdump var="#variables.instance#" />
   <cfif arguments.abort>
      <cfabort />
   </cfif>
</cffunction>

The DAO is basically your general CRUD methods. I won't go into too much detail - everything generated looks very usable with minimal (if any) alteration. The one nice method I see (which I assume is probably pretty standard OO practice) is the save() method.

<cffunction name="save" access="public" output="false" returntype="boolean">
   <cfargument name="user" type="cms.com.user" required="true" />   
   <cfset var success = false />
   <cfif exists(arguments.user)>
    <cfset success = update(arguments.user) />
   <cfelse>
      <cfset success = create(arguments.user) />
   </cfif>
      
      <cfreturn success />
</cffunction>

This method accepts the bean its only argument. It checks whether or not the primary key (userId) exists in the table and returns boolean. If it exists then the update() method is called. If not then the create() method is called. (note to self: would the userId be created then in a hidden form field?).

The next component to review is the gateway. The gateway is used to return an entire record set (or records by value) for your table. This method I can see needing to be customized for certain elements. For example when generating the 'page' elements for our CMS we'll certainly want to return a page with the associated 'link' elements, so the gateway will likely need to be customized as such.

So that covers the bean, DAO and gateway creation using the Illudium PU-36 Code Generator. The service component I'm sure will eventually act as a service layer with Mach-ii. A service layer is what the framework will talk to instead of directly talking to the component. This allows are model to be easily plugged into another framework in the future if we so chose to.

Overall I have to say that I am impressed with Brian's tool. The only complaint that I have so far is that I can not find the 'Save To File' button! The generated code seems clean, concise and appears to be ready to roll with little modification.

In my next post I'll take a look at cfcPowerTools to generate some more code. Overall I'm feeling a little confused, a little enlightened about OO. I'm sure as I dig my way through this many of these things will start to make sense for me.

Update: After talking with Brian it seems that the version that I obtained from Google Code was old - the new and most recent version is available at RIAForge. You can find it here: http://cfcgenerator.riaforge.org/

Related Blog Entries

Comments
Todd, great review! Thanks for taking the time. A few comments - 1) yes, reload = 1 will reset the application scope. Basically, all the datasources are loaded in when the application starts. 2) I am not sure save() is necessarily standard practice though it is fairly common. 3) Sounds like you may have an older download somehow. I cannot confirm that the Google code one is correct since my firewall blocks that site at work. I have confirmed though that the RIAForge one is current and has the save to file feature in it. The version in SVN on Google code should also be current (note: the flex version is now the only version in the trunk...you do not need to find it in the branches as in the past).
# Posted By Brian Rinaldi | 2/14/07 8:50 AM
Good series of posts.

I just wanted to refer you to some articles that really helped me "get" the principles behind OO, from Robert Martin.

http://butunclebob.com/ArticleS.UncleBob.Principle...

In particular, the first 5 that relate to class design helped me the most (though, I will always remain a student on this, I think).
# Posted By Sammy Larbi | 2/14/07 9:56 AM
Great article. I'm learning alot from reading this series.

When you pick a table for code generation, can you specify only some of the table's fields? I often have tables with 30-40 fields (I did not design these), but I only need the CFC to work with 5-10 of the fields.
# Posted By Bruce | 2/14/07 9:57 AM
Bruce - you can not specify. This generator only works within the existing table structure.
# Posted By todd sharp | 2/14/07 10:53 AM
I'll +1 for the Illudium Code Gen. I also just installed it, and whereas I haven't used it in anger yet... I was angry that I've been typing out a lot of code for the past few years rather than coding the heavy work and making it easy.
Cheers for a great wee tool Brian.
# Posted By dc | 2/14/07 11:35 AM
Anyone using this with OSX/CF7.0.2? Installed it, added my CF admin password, checked to make sure I have Data & Services>Flex Integration enabled and . . . nothing when I load the main page.
# Posted By Lola LB | 2/14/07 12:33 PM
Lola, I developed it on OSX with 7.0.2 (on Mactel). It should pick up any MySQL 5, MSSQL or Oracle datasources since those are what is supported (MySQL 4.1 support was contributed, I just need to get around to plugging it in). If it doesn't find any of those you should get a message saying so. Are you seeing an error?
# Posted By Brian Rinaldi | 2/14/07 12:43 PM
I'm not seeing anything - just the Debugging Information and Scope Variables. There isn't even any CF Error messages displaying. I believe i do have Flash Player 9 installed.
# Posted By Lola LB | 2/14/07 12:59 PM
Here's more . . . this won't load under Safari. When I call it under Firefox, it does load the page, but I get error messages in this sequence (occuring twice): Send failed, Client.Error.MessageSend, Fault occured in GetTemplatesCommand. After I click through the OK buttons, the form fields show up but datasource picklist is not populated.
# Posted By Lola LB | 2/14/07 1:05 PM
lola, did you get the version from RIAForge? I was having the same errors as you with the version from Google until I tweaked the naming conventions. Tweaking shouldn't be necessary with the RIAForge version.
# Posted By todd sharp | 2/14/07 1:16 PM
Yes, this is the version from RIAForge.
# Posted By Lola LB | 2/14/07 5:23 PM
Lola, have you been able to run other Flex 2 applications locally. I have had a couple of reports along these lines and it appeared to be something wrong in the CF 7.0.2. install. I know it is not a the best solution, but I was told by a couple of these cases that reinstalling CF worked. Basically the CF/Flex communication wasn't working in these cases.

If this isn't the case here, let me know.
# Posted By Brian Rinaldi | 2/15/07 9:54 PM
Thanks for explaining the difference between a DAO and a Gateway. That's what I was looking for and I found it in your post.

BTW, have you looked at this page in Safari or Firefox? Its' unreadable. On a humourous note, I initially was going to put in a comment to that effect before reading the article, and the captcha I got was "F U". So I didn't post :-)
# Posted By Andrew Clarke | 8/21/07 10:26 AM

Calendar

Sun Mon Tue Wed Thu Fri Sat
  12345
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30 31   

Subscribe

Enter your email address to subscribe to this blog.

Tags

actionscript ajax blogging cfsnippets coldfusion flash forms flex misc model-glue off topic personal project learn slidesix sql

Recent Comments

More CF+Java: Compiling Classes And Persisting Objects
Getburl said: I have been attempting to get Db4o working in my CF application and I have not succeeded. I would lo... [More]

Thoughts On Ajax Frameworks And ColdFusion/Adobe
Erast said: http://fanniecollins.10gb... emo http://gracetrevino.phree...... [More]

Extending Ext With Ext Extensions
Erast said: http://fanniecollins.10gb... emo http://gracetrevino.phree...... [More]

CF Needs An Open Source Contact List Importer
Kay Smoljak said: Heh, the fact that sites DO it doesn't mean they SHOULD. To us it's ok, but to a non-tech-savvy user... [More]

A Few Project Updates
Helena said: Now punctually what is the situation ? [More]

RSS


coldfusionbloggers

FullAsAGoog MXNA

Consumed By Feed-Squirrel.com