March 11, 2010

Pages


Search Site


Subscribe

...to receive future posts via email.

Topics



Archives

Entries for month: June 2007

Notes from CFUnited Day 1

June 28 2007 by Adam

Since all of your favorite well known bloggers are covering what actually went on in the different classes, I thought I would just write about 2 things that struck a chord with me.

The first is something that Hal Helms said during his talk on OO Programming using CFCs. He gave us the old Buddhist proverb: "If you see The Buddha on the street, kill him." (because the real Buddha is the one you internalize, blah blah blah), and then he gave us the programmers equivalent: (Paraphrasing) Don't do what I say just because of who I claim to be or who you think I am. Take my advice as an example and try it yourself. See if it works for you. Try other things, too. Make mistakes.

The reason that this caught my attention was that he's right. As much as we idolize some of the "big names" in the CF community, we have to remember that we are being paid (by our clients) to provide them the most optimal solution for their individual situation, and sometimes that deviates from the standard or from what so called experts claim are best practices. It was a great reminder to think for myself and realize that my own knowledge adds value to the situation.

The second was the Open Source BOF discussion led by Raymond Camden. It was a very laid back discussion, but what I took away from it were two things. First, that writing open source software can be a great marketing tool to advertise your abilities and create leads for custom consulting projects. Ray has more or less made his career out of the projects he lands based on the clout earned from his Open Source projects.

And secondly, that working on O.S. software that interests you will provide an engaging opportunity to learn and explore new ideas, which should be considered valuable experience by your company. Someone at the BOF mentioned the likelihood that each of our contracts state that anything we work on, even in our own personal time, is the IP of the company. Some will argue that you should be allowed or encouraged to spend part of your work week on personal projects (Google does).

Of course this depends on your individual situation, and it's understandable that if you're a billable resource then your boss wants to keep you billable as much as possible. Whether or not your boss will let you work on personal projects one afternoon a week, if you're reading this, you probably would work on them in your free time anyway. I know I will, and do.

So far, I think this conference has already paid for itself in the knowledge I've picked up and the contacts I've made. Heck, it even pays for my new subscription to Fusion Authority.

Posted in CFUnited 07 |

Can it be? It's finally here?

June 23 2007 by Adam

CFMenuCal α1 is, dare I say, ready for you to play with!

Considering that this is an alpha release, there is no way to modify user data (aka meals, settings) on-page. You'll need to edit config.cfm to change those things. Of course, this isn't a problem for you, because you're taking advantage of the ColdFusion 8 public beta, right?

I would love to get some feedback from anyone who plays with it. What do you like or dislike about it? What do you think should work differently? Feature requests, bug reports… bring it on!

Posted in CFMenuCal | My projects | Scorpio |

ColdFusion8 doesn't create Client Variable tables for MySQL

June 21 2007 by Adam

…and potentially other database types.

Tonight I installed the latest CF8 beta on my home file/web server so that I can continue development and tinkering even in the event of a catastrophe. The server is running Ubuntu and MySQL, which to be honest, means this is the first time I've had to store client variables in a MySQL database. In the past, MS SQL Server has always at least been an option, and I never bothered before.

In the event that you might need the code to create these tables, because I did, you can find it here. I gather that this is not a new development (the page I linked indicates that these instructions are for MX), but I personally would have thought that now that MySQL is an officially supported DBMS, they would have implemented such a remedial feature.

If you can't be bothered to click through, here's the code:

<cfquery datasource="mydatasource">   CREATE TABLE cdata (     cfid varchar(64) NOT NULL default '',     app varchar(64) NOT NULL default '',     data longtext NOT NULL,     PRIMARY KEY (cfid,app)   ); </cfquery> <cfquery datasource="mydatasource">   CREATE TABLE cglobal (     cfid varchar(64) NOT NULL default '',     data longtext NOT NULL,     lvisit timestamp(14) NOT NULL,     KEY cfid (cfid),     KEY lvisit (lvisit)   ); </cfquery>

Posted in ColdFusion | Scorpio |

inAction -or- Murphey's Law In Action

June 20 2007 by Adam

The day that you make grandiose plans to spend hours working on a project when you get home, is the day that you leave the power supplies for both of your laptops at the office.

I am not giving up on or abandoning CFMenuCal, I promise.

I really want to work on it, and as soon as I have the means (when power supply availability and free time intersect) I intend to do just that. If absolutely nothing else, I'm planning on working on it during evenings or down time during CFUnited; because I'm shy and I'm sure that I'll end up alone in a corner somewhere. Bet your bottom dollar.

Posted in CFMenuCal | Meta |

Handling BLOBs with a CFC

June 11 2007 by Adam

I recently had to write a component to handle writing BLOB data to a database, and reading it back out. I don't think it deserves a project on RIAForge/etc, but think that it's worth posting the code here for anyone who may find themselves needing something similar.

This code was used to store images in a SQL Server database field defined as an "image" type, and has not been tested for other data types or against other DBMS', but should work just as well storing other binary formats (audio, etc), and in nearly any DBMS.

I'll post a breakdown of each function, and then list the entire contents of the cfc at the end.

Read on for the code…

Setup: First we need to define the component, and set some private data; namely the datasource, table name, primary key name, and BLOB field name.

<cfcomponent name="blob">     <!— private data —>     <!— set default values, override with setProps() —>     <cfset this.tbl            = "myTable">     <cfset this.keyName        = "primary_key_id">     <cfset this.blobName       = "blob_field_name">     <cfset this.dsn            = "cf_datasource_name"> … </cfcomponent>

setProps(): Though we're setting default values for our private data, we want to allow the user to override these values to suit their needs.

    <!— allow changing of default private data through a method —>     <cffunction name="setProps" access="remote">         <cfargument name="table"        required="yes">         <cfargument name="keyName"       required="yes">         <cfargument name="blobName"      required="yes">         <cfargument name="datasource"   required="yes">         <cfset this.tbl            = arguments.table>         <cfset this.keyName        = arguments.keyName>         <cfset this.blobName       = arguments.blobName>         <cfset this.dsn            = arguments.datasource>     </cffunction>

addBlob(): This function updates this.blobName in this.table where this.keyName matches arguments.keyValue. Or in laymans terms, it takes as input the BLOB data, and the unique identifier for the record where you want to add your BLOB, and adds it (overwriting anything that may already exist there). Returns TRUE on success, or FALSE on error.

    <!— insert the blob (via update) —>     <cffunction name="addBlob" access="remote">         <cfargument name="keyValue"        required="yes">         <cfargument name="blob_data"       required="yes">         <cftry>             <cfquery name="addBlob" datasource="#this.dsn#">                 update      #this.tbl#                 set         #this.blobName# = <cfqueryparam CFSQLType="CF_SQL_BLOB" value="#arguments.blob_data#">                 where       #this.keyName# = #arguments.keyValue#             </cfquery>             <cfcatch type="any">                 <cfreturn false> <!— return false on error —>             </cfcatch>         </cftry>         <cfreturn true>     </cffunction>

nullifyBlob(): We need a function to remove the BLOB, of course. Simply pass in the primary key value, and it will return TRUE on success, or FALSE on error.

    <!— NULLify the blob —>     <cffunction name="nullifyBlob" access="remote">         <cfargument name="keyValue" required="yes">         <cftry>             <cfquery name="nullifyBlob" datasource="#this.dsn#">                 update       #this.tbl#                 set          #this.blobname# = NULL                 where        #this.keyName# = #arguments.keyValue#             </cfquery>             <cfcatch type="any">                 <cfreturn false> <!— return false on error —>             </cfcatch>         </cftry>         <cfreturn true>     </cffunction>

getBlob(): Last, but certainly not least, we need a method to get the BLOB data back out of the database. This function takes only the primary key value of the record you want to retrieve a BLOB from, and returns a STRUCT containing two keys: success which will indicate whether or not there was an error (TRUE or FALSE), and BLOB which contains the BLOB data, or an empty string if there was an error.

    <!— return blob —>     <cffunction name="getBlob" access="remote">         <cfargument name="keyValue" required="yes">         <cfset variables.retVal = StructNew()>         <cftry>             <cfquery name="getBlob" datasource="#this.dsn#">                 select       #this.blobname#                 from         #this.tbl#                 where        #this.keyName# = #arguments.keyValue#             </cfquery>             <cfcatch type="any">                 <cfset variables.retVal.success = false> <!— return false on error —>                 <cfset variables.retVal.blob = "">                 <cfreturn variables.retVal>             </cfcatch>         </cftry>         <cfset variables.retVal.success = true>         <cfset variables.retVal.blob = evaluate("getBlob.#this.blobname#")>         <cfreturn variables.retVal>     </cffunction>

And so to bring it all together…

blob.cfc:

<cfcomponent name="blob">     <!— private data —>     <!— set default values, override with setProps() —>     <cfset this.tbl            = "myTable">     <cfset this.keyName        = "primary_key_id">     <cfset this.blobName       = "blob_field_name">     <cfset this.dsn            = "cf_datasource_name">     <!— allow changing of default private data through a method —>     <cffunction name="setProps" access="remote">         <cfargument name="table"        required="yes">         <cfargument name="keyName"       required="yes">         <cfargument name="blobName"      required="yes">         <cfargument name="datasource"   required="yes">         <cfset this.tbl            = arguments.table>         <cfset this.keyName        = arguments.keyName>         <cfset this.blobName       = arguments.blobName>         <cfset this.dsn            = arguments.datasource>     </cffunction>     <!— insert the blob (via update) —>     <cffunction name="addBlob" access="remote">         <cfargument name="keyValue"        required="yes">         <cfargument name="blob_data"       required="yes">         <cftry>             <cfquery name="addBlob" datasource="#this.dsn#">                 update      #this.tbl#                 set         #this.blobName# = <cfqueryparam CFSQLType="CF_SQL_BLOB" value="#arguments.blob_data#">                 where       #this.keyName# = #arguments.keyValue#             </cfquery>             <cfcatch type="any">                 <cfreturn false> <!— return false on error —>             </cfcatch>         </cftry>         <cfreturn true>     </cffunction>     <!— NULLify the blob —>     <cffunction name="nullifyBlob" access="remote">         <cfargument name="keyValue" required="yes">         <cftry>             <cfquery name="nullifyBlob" datasource="#this.dsn#">                 update       #this.tbl#                 set          #this.blobname# = NULL                 where        #this.keyName# = #arguments.keyValue#             </cfquery>             <cfcatch type="any">                 <cfreturn false> <!— return false on error —>             </cfcatch>         </cftry>         <cfreturn true>     </cffunction>     <!— return blob —>     <cffunction name="getBlob" access="remote">         <cfargument name="keyValue" required="yes">         <cfset variables.retVal = StructNew()>         <cftry>             <cfquery name="getBlob" datasource="#this.dsn#">                 select       #this.blobname#                 from         #this.tbl#                 where        #this.keyName# = #arguments.keyValue#             </cfquery>             <cfcatch type="any">                 <cfset variables.retVal.success = false> <!— return false on error —>                 <cfset variables.retVal.blob = "">                 <cfreturn variables.retVal>             </cfcatch>         </cftry>         <cfset variables.retVal.success = true>         <cfset variables.retVal.blob = evaluate("getBlob.#this.blobname#")>         <cfreturn variables.retVal>     </cffunction> </cfcomponent>

Happy Blobbing.

Posted in ColdFusion |