Categories
Contact Doug!
Learn About Doug!
View Doug Boude's online resume
updated 11/18/2009

View Doug Boude's profile on LinkedIn
Link to me!

Follow Doug Boude on Twitter
Follow me!

Be Doug's friend on Facebook
Befriend me!
(I promise not to follow you home)
OO Lexicon
Chat with Doug!
Recent Entries
You may also be interested in...
Web Hosting

<< December, 2009 >>
SMTWTFS
12345
6789101112
13141516171819
20212223242526
2728293031
Search Blog

Recent Comments
Re: Disappearing IE Popup Window During Save/Open Dialog (by LZ at 4/20 7:58 AM)
Re: Create Dynamic WHERE Clauses in PHP (by pooja at 3/20 7:29 AM)
Re: Just What IS a 'Service Layer', Anyway? (by EugenK at 3/07 7:56 PM)
Re: Using Google as your CF Mail Server (by 5starwebteam.com at 2/25 1:27 AM)
Re: Why Provide for Service layer objects in CFWheels? (by Steven Benjamin at 1/25 11:43 AM)
Re: What is an 'Advanced' Coldfusion Developer? (by ColdFusion Developer at 12/24 5:14 AM)
Re: Equivalent of SQL "TOP X" in Oracle (by Ashenafi Desalegn at 12/06 5:29 AM)
Re: PHP Export to Excel Snippet (by serene at 12/05 1:44 AM)
Re: Just What Is 'Application Logic', Anyway? (by Arif at 11/13 8:06 AM)
Re: Hosts File Changes Not Acknowledged on Vista 64 (by Aaron at 10/22 2:31 PM)
Re: PHP Export to Excel Snippet (by Jafar Shah at 10/10 4:28 AM)
Re: Viewing Option Text (in IE7) that's Wider than the Select List (by Chenelle S at 10/04 12:53 PM)
Re: PHP Export to Excel Snippet (by Kilo at 9/26 5:20 PM)
Re: Porting Coldfusion Code to Mura (by tariq at 9/03 9:51 AM)
Re: Just What IS a 'Service Layer', Anyway? (by James at 8/27 4:06 PM)
Re: Calculating Business Hours (by helen at 8/14 2:54 AM)
Re: What IS 'Business Logic', Anyway? (by dougboude at 8/06 11:30 AM)
Re: What IS 'Business Logic', Anyway? (by Adrianne at 8/06 10:29 AM)
Re: Family Law: The Weapon of Choice for Woman Scorned (by dougboude at 8/04 4:39 PM)
Re: Family Law: The Weapon of Choice for Woman Scorned (by Lola LB at 8/04 7:43 AM)
Archives
Photo Albums
Funnies (5)
Family (3)
RSS

Powered by
BlogCFM v1.11

21 December 2009
A SWEET Little MySQL Function: Group_Concat

The Scenario

You're writing code to perform authentication for a web-based app. Your users live in one table (Site_User), your list of site permissions live in another table (systemRoles), and the two are related via a junction table (jctUserRole) that manages the many to many relationship there. Your backend database: MySQL version 5 or better.

So, in an ideal world, you will be able to write a single query that will both authenticate the user AND retrieve a comma delimited list of their roles contained in a single field; if their credentials are good, your result will only have a single record in it. Typically, however, because of the way many to many relationships are normalized, the "one query" you want will be returning multiple rows...one row for each permission the authenticating user is related to. For example, here is the typical way one would write the authenticating query:


  SELECT u.id AS userid, u.firstname, u.lastname, r.rolename
  FROM Site_User u
  INNER JOIN jctUserRole j ON j.userID = u.id
  INNER JOIN systemroles r ON r.id = j.roleID
  WHERE u.username =  'username'
  AND u.password =  'password'

 

This produces a result that looks like this:

standard mysql query for authentication

We would then be required to write additional code in order to more properly "package" up this user's list of permissions for use within the system.

But enter the wonderful world of MySQL 5, and the 'group_concat' function. Group_concat allows you to concatenate values into a list based on a specified grouping, and will produce a list of unique values delimited by whatever character you choose (but defaults to a comma). So transforming the above query just a little bit, we get:

 

  SELECT u.id AS userid, u.firstname, u.lastname, GROUP_CONCAT( r.rolename ) AS roles
  FROM Site_User u
  INNER JOIN jctUserRole j ON j.userID = u.id
  INNER JOIN systemroles r ON r.id = j.roleID
  WHERE r.username =  'username'
  AND r.password =  'password'
  GROUP BY u.id, u.firstname, u.lastname

 

And a result set that now looks like this:

mysql authentication query using group_concat

Man, SO much cleaner and nicer, eh? Now you can simply treat the "roles" value as a list...explode it into an array if you want, or leverage ColdFusion's myriad of List functions to interact with it.

Since discovering group_concat, I've found several other uses for it as well, particularly when producing reports for my internal clients...it saves me a lot of iterating over result sets in order to produce value summaries.

You can read the documentation for this function here

Posted by dougboude at 11:29 AM | PRINT THIS POST! | Link | 29 comments



17 December 2009
Using a CFC as a Configuration File
Leveraging The Decorator Pattern
SO, you too find yourself needing to write something that could really benefit from having its settings contained in some external resource. Let's see, what are the choices...we could possibly store our settings in the database and retrieve them at application initialization, if our architecture permits that; we could create an xml file that contains our settings in a nice, nested, readable manner; we could (as one person I mentioned this to suggested) put our settings into an INI file (ya think this person does a little too much .NET? :) ); or we COULD, as I have recently become enlightened to, put our settings into a CFC. Since I am especially partial to the idea of being able to have the choice of hard coding my settings and/or leveraging Coldfusion's dynamic personality to populate them, I went the way of using a CFC.

Allow me to preface the remainder of this post by saying thank you to those out there who have already traveled this road and have made their work open source. By dissecting several different code samples and doing a lot of experimentation, I have been able to enlighten myself as to the mechanics and theory behind it.

SCENARIO
For the sake of illustration, let's say I'm writing a plugin that will be used to provide shopping cart functionality to whatever app is implementing it. Of course, every app's needs, environment, and settings are different, so our plugin needs to be configurable. My goal then is to create a CFC that will contain a nested structure/array of settings that my shopping cart plugin CFC can utilize to control how it is implemented. Sounds simple, right? Or is it... :)

For those who want to skip right to the heart of the matter, you may do so now. For those who, like me, enjoy the layered learning process and the excitement of examining the pieces before putting the puzzle together, let's take a quick look at essential the concepts that allow using a CFC as a configuration file to work.

THE ESSENTIAL CONCEPTS

SCOPE
You already know about scopes in CF and are well versed in how and when to use them, I'm sure. You know, for instance, that if you create a variable within a template and ommit the scope, it is automatically put into the variables scope. You should also be aware, however, that any functions you create within your template also occupy a place within the variables scope. Take this template, for instance, and the accompanying dump:
<cfset thisvar = "Hello" />

<cffunction name="returnIt" access="private" returntype="any">
    <cfargument name="incoming" type="any" />
    <cfreturn arguments.incoming />
</cffunction>

<cfdump var="#variables#" label="MyTemplatesVariables" />


dump of variables scope in a coldfusion template

Interesting, eh? Keep this in mind.

Now, you may also already be aware of the fact that within an instantiated CFC you have scopes as well. I won't spend any time elaborating on those scopes or the differences between them (did that in another post a while back). But I WILL hit you with a short CFC and a dump of its own internal variables scope. Based on our little experiment above with our template, look at the CFC internals and formulate an idea of what you would expect to see. You may see something surprising in this one.

Component A.cfc
<cfcomponent output="false">
    <cffunction name="Foo" access="public" output="false" returntype="any">
        <cfargument name="nuttin" type="string" />
        <cfreturn arguments.nuttin />
    </cffunction>
   
    <cffunction name="Man" access="private" output="false" returntype="any">
        <cfargument name="nuttin" type="string" />
        <cfreturn arguments.nuttin />
    </cffunction>
   
    <cffunction name="Chu" access="remote" output="false" returntype="any">
        <cfargument name="nuttin" type="string" />
        <cfreturn arguments.nuttin />
    </cffunction>
   
    <cffunction name="getMyVariablesScope" access="public" returntype="any">
        <cfset var theseVars = "" />
        <cfsavecontent variable="theseVars">
            <cfdump var="#variables#" label="ComponentAVariables" />
        </cfsavecontent>
        <cfreturn theseVars />
    </cffunction>
</cfcomponent>


Code to instantiate A and retrieve and output its variables scope:
<cfset objA = createobject("component","A") />
<cfoutput>#objA.getMyVariablesScope()#</cfoutput>


dump of variables scope from within a coldfusion cfc

As you probably expected, there in the variables scope are all the functions of the CFC (regardless of what access type we gave them). Additionally, we have the often shunned THIS scope...and looky what THIS is harboring. That's right boys and girls, a reference to (not copy of) the CFC instance. THIS, as you may or may not know, IS accessible from outside the CFC instance. So if we modify slightly the code we used above to instantiate the object, and add a line to give our object another attribute, a subsequent call to getMyVariableScope will reflect the results.

Code to instantiate A and retrieve and output its variables scope:
<cfset objA = createobject("component","A") />
<cfset objA.someFunkyParam = "Doug Boude Rocks" />
<cfoutput>#objA.getMyVariablesScope()#</cfoutput>


dump of variables scope from with a coldfusion cfc

This is perfect behavior for what we're wanting to do! Oh...what is it we are wanting to do? Let's get to the next and last essential concept and see!

THE DECORATOR PATTERN
Here's a term I'm sure most of you have heard of. If you haven't heard specifically of this pattern, I'm sure you've at least heard of design patterns in general. Well, you can and should think of this one exactly as its name sounds. Let's say you figure out that the fastest way to meet chicks is to buy a dog (since you can't afford to buy a baby), so you grab a "mildly malformed" West Highland White terrier from the "we finance anyone" pet store down the street. You invest a few more bucks and take little Timmay to the groomer. When you pick him up later, he is now sporting a lovely red tartan neckerchief and smells of Eau de Tim McGraw. Timmay has been decorated! He's still a midly malformed Westie, only NOW he ALSO has been given the ability to attract hot chicks, AFTER he was born. I know, it was an elaborate analogy, but this is how I entertain myself. So then...since in our mind's eye we want our Config.CFC to be beautifully simple for the end user to populate and we don't want them to have to ignore (and try not to touch) lots of other support methods or worry about inheritance dependencies, what we ideally need to be able to do is provide them a clean, simple CFC that contains only a configure method. When they populate it (or code it to grab its values from elsewhere), we'll take it and then DECORATE it with a method that will allow us to retrieve that same configuration info! Okay, enough of concepts and ideas. On to the solution.

THE SOLUTION
The key players in this scene are:
"ShoppingCart.cfc", a plugin designed to provide shopping cart functionality to any application;
"Config.cfc", a cfc whose sole purpose in life is to provide the developer with a single place in which to maintain relevant ShoppingCart settings;
"configTest.cfm", a cheesy template who just kinda glues this stuff together for us.

First, configTest.cfm.
<cfset objShoppingCart = createObject("component","ShoppingCart").load("Config") />
<cfdump var="#objShoppingCart.getSettings()#">


Straightforward. We're creating our shoppingcart cfc, calling the load method and passing in the class path to our configuration cfc. Then, calling shopping cart's getSettings method just to prove to ourselves that it worked.

Config.cfc.
<cfcomponent output="false">
    <cffunction name="configure" access="public">
        <cfscript>
            settings = {
                environment = {
                    DSN = "dbserver",
                    EmailServer="mail.onelove.com"
                },
                cartSettings = {
                    maxCartItems = "15",
                    salesTax = "true",
                    cartHeading = "One Love to Rule Them All",
                    cancelMessage = "Aw baby, why you leavin?",
                    thankyouMessage = "Stay Cool",
                    daysLeftTillXmas = ceiling(datediff("h",now(),createdate(2009,12,25))/24)
                }
            };
        </cfscript>
    </cffunction>
</cfcomponent>


This is a "hard coded" version, where all the settings are just there. You'll notice at least one of them taking advantage of a PRIME reason to do configuration this way: dynamic values!

ShoppingCart.cfc (scaled down to ONLY the relevant methods needed to illustrate the point of this blog post).
<cfcomponent output="false">
    <cfset variables._settings = "" />
   
    <cffunction name="load" access="public" returntype="any" hint="I load settings from an external CFC">
        <cfargument name="configpath" type="string" required="true" />
        <cfscript>
            var objConfig = createobject("component",arguments.configpath);
            //need to run objConfig's configure() method in order to actually create the
            //configuration settings structure
            objConfig.configure();
           
            //decorate objConfig with our local _getConfig  method :)
            objConfig.getConfig = variables._getConfig;
           
            //execute the method we just added to objConfig to retrieve objConfig's 'settings' struct
            variables._settings = objConfig.getConfig();
           
            return this;
        </cfscript>
    </cffunction>
   
    <cffunction name="getSettings"
        access="public"
        returntype="any"
        hint="I am the method used to get our local configuration values.">
           
        <cfreturn variables._settings />
    </cffunction>
   
    <cffunction name="_getConfig"
        access="private"
        returntype="any"
        hint="I am the private method that will decorate our configuration object!">
       
        <!--- we're counting on our configuration object to have a variable called 'settings'... --->   
        <cfreturn variables.settings />
    </cffunction>
   
</cfcomponent>


You'll want to study this one a bit, and let me point out a few things.

The last method, "_getConfig", serves no other purpose than to decorate our configuration object. Now, you may be thinking, "but I could just put that method inside my configuration object and tell my users to just ignore it!". Yeah, you could; but that's cheesy. So, to avoid smelling of aged Camembert, we hide this method here and add it to our configuration object within the "load" method.

Here's the results of calling configTest.cfm:
dump of coldfusion structure

SUMMARY
In a nutshell, because an object always sports a THIS scope, AND because local functions always exist in the VARIABLES scope, it is a simple matter to attach a new method to an object. If the method you are attaching is written correctly, it can access the methods and values within the object that all of the native methods can. By leveraging this very cool relationship, you can move configuration settings to a CFC.


POST SUMMARY
You may also be thinking, "Dude, I or someone else I don't trust could wreak so much havoc in my code by decorating objects with well-written methods!". And dude, I do believe you're probably correct. I haven't researched much into the security ramifications, or how many ways one might find to defile the sacraments of "clean OO"; but, I know that with CF comes great power, and with great...oh, you know. We've chosen the more lenient world of CF, so it's up to us to respect those freedoms and work with them accordingly. If you don't feel good about that, well, there's always the more communistic "typed" languages, with their greater complexities and unbending rules. :) Hey, some people prefer domination ;) To each his own.
Posted by dougboude at 12:41 PM | PRINT THIS POST! | Link | 0 comments
01 December 2009
(User) Interface-Driven Architecture vs Model Driven Architecture
When Universes Collide

Part of what makes me a professional developer, in my opinion, is the fact that I always make it a point to learn and evolve. When what I knew and was certain of yesterday becomes intertwined with some new thing I learn today, great things happen and my understandings and persepectives change. Recently, that very thing occurred regarding my mindset on how to approach any new development project, so I thought I would share the experience and the results.

First, Some Definitions

(User) Interface-Driven Architecture  (aka IDA, care of Mr. Clark Valberg, esquire :) )

(User) Interface-Driven Architecture means that the first thing I do is create a visual, hopefully somewhat interactive prototype of what my finished product will be; I build a mockup of the GUI that demonstrates and represents the functionality of the app as seen from an end user's perspective. At this time, I don't even think about the code that will power the app (at least I try hard not to), but rather focus on the end results. Once the prototype is approved by the client, it is then reverse engineered by the architect and transformed into a living, breathing application.

Model Driven Development

Model Driven Development takes an opposite approach. Forcing yourself to not even consider what the user interface might look like or how it might behave, you architect the application's model based solely on use cases, static class diagrams, and whatever other artifacts you have been given that describe what goals the app will accomplish.You remove yourself so far from the user interface, in fact, that you architect your classes in such a way that ANY user interface could consume your API and all scenarios, present and potential, would be covered.

A Little History

My earlier development years were spent coding mostly by instinct, as I had no formal training on the subject, no mentor whom I desired to emulate, and nobody telling me how they wanted me to do it. So, depending on the project and what kind of direction had been given me, I would often find myself starting a project in different places. If I had been given a clear scope of the functionality the app was to provide, I would typically begin by designing a relational database schema to accommodate that scope. If someone had drawn me a picture on a napkin and handed it to me telling me to "build this", I'd start with an html GUI that simulated functionality so that I could make sure the vision of the requester was the same as mine. And if I was left to my own devices as to how I would approach development, then it just depended on whether or not I was in the mood to design a database or write code as to which I did first.

The next natural step in my personal evolution was to attempt to leave chaos behind and adopt standards and methodologies to allow me to be more efficient and DRY. This abandonment of solely using instinct as a methodology (which actually didn't work too badly for me) occurred when CF 7 was about 6 months old. At this point I began listening to the OO buzz, attending conferences, opening my mind to ideas and concepts that were new to me, and leveraging CFCs and frameworks; all in an effort to apply rhyme and reason to my approach to development. Even so, there was still no clear starting point; every project began differently.

So, about two years ago, I settled on the fact that (User) Interface-Driven Architecture was THE way to go. By designing the customer-approved, semi-functioning GUI first, I could avoid the developer's most arch nemesis, Scope Creep, and ensure that both the customer and myself both had the exact same end result in mind. It makes perfect sense, right? It does indeed. But, does it always? This is where my road forks.

For the past six months, our local RIA user group has been building a media player as a group using AS3. The group manager is basically leading the sessions, as he is a seasoned AS3 architect, and it has been within these sessions that I have come to see and appreciate the value and application of the Model-driven approach. It all gelled for me during our most recent session when one of the attendees who was having some difficulty following the abstractness of the classes and their relationships raised his hand and asked that we stop working on the model and build the GUI that would consume it. For him, seeing the GUI would help him assimilate all of the model pieces we had been writing for the past several months. The group manager then took a moment to expound upon why he thought it good to purposefully NOT create the GUI. In a nutshell, creating the model with the GUI in mind would cause us to design a backend that would be limited to only what the GUI needed and would hinder our creativity as we thought out the specifics of our model's behavior, organization, and flexibility.

The two poles of my thinking collided at that moment, and out of the momentary synapsial confusion that followed emerged the same two ideas, intact. This time, however, rather than me viewing them as opposing ideas where only one could rule, I saw them as inverse to one another, yet equal in their relevance and application. Which one ruled, then, depended entirely upon the circumstances and goals of the specific project at hand.

(User) Interface-Driven Architecture evolved in response to the need to help clients answer the one question they have such a hard time with: "What is it that I really want?", and it is in this context where this approach rules. With a visual, interactive interface in place at the beginning of the project, there is little room for unplanned scope creep to stall or even derail a project's progress. If the goal then of the project is to "build this customer exactly what he wants", then this is definitely the approach I would go with, hands down.

In the opposite universe, there are times when the goal of the project is to produce something more of an enterprise nature that must be able to expand and contract, bear dynamic loads, and present a consumable API to third parties of unknown origin. This scenario then clearly shines the spotlight on the architecture of the model. Although the user interface always matters, if we were to design it first and then attempt to build a model that accommodated only its needs, we would in many senses be forcing ourselves to think inside of the box that the GUI built around us, and thus likely end up with a product  much less robust than it could have and should have been. For a project such as this, then, I say that the Model-driven approach is the way to go, hands down.

 


Conclusion

As you can tell, I still feel very passionate about (User) Interface-Driven Architecture, and will continue to use it and apply it where I see it as a best approach. It is very sound, and very effective at producing happy customers and a nearly unmovable project scope, except where it is concentual. I now also feel very passionate about Model Driven Architecture as well, and find it to be a more liberating experience, if you will, when designing applications of a grander, more enterprise scale. This approach places absolutely no bounds on your ability to explore possibilities and configurations, the only confines at all (if you can call them that) being the resulting API your project will expose, if one is to be created.

Of course, I'm always learning and evolving, and one day in the future I may have a completely new perspective on application architecture. It never hurts, though, to share your epiphanies along the way; you never know what will be produced when your epiphany collides with someone else's universe.

Keep evolving, my friends.

Posted by dougboude at 2:18 PM | PRINT THIS POST! | Link | 10 comments