Utility Functions: CreateMapping() and RemoveMapping()

Some more "stolen" code for today's pair of utility functions. Thanks to FusionGrokker's post on controlling mappings in CF7. As FusionGrokker points out, these functions work in CF7, but its actually hacking global mapping values, so you could have problems.

<cffunction name="CreateMapping" output="false" returntype="void">
    <cfargument name="mapping" type="string" required="true" />
    <cfargument name="path" type="string" required="true" />
    
    <cfset var factory = CreateObject("java", "coldfusion.server.ServiceFactory") />
    <cfset var mappings = factory.runtimeService.getMappings() />
    
    <cfset mappings[arguments.mapping] = arguments.path />
    
    <cfreturn />
</cffunction>

<cffunction name="RemoveMapping" output="false" returntype="void">
    <cfargument name="mapping" type="string" required="true" />
    
    <cfset var factory = CreateObject("java", "coldfusion.server.ServiceFactory") />
    <cfset var mappings = factory.runtimeService.getMappings() />
    
    <cfset StructDelete(mappings, arguments.mapping) />
    
    <cfreturn />
</cffunction>

 

Utility Function: StructDeleteKeys()

A gear I often need to delete struct keys based on a list of items. Its not that I can't just loop the list and call StructDelete(), but it gets old, and this function makes it a little easier.

<cffunction name="StructDeleteKeys" returntype="void">
    <cfargument name="struct" type="struct" requried="true" />
    <cfargument name="keyList" type="string" requried="true" />
    <cfargument name="delimiters" type="string" required="false" default="," />
    
    <cfloop list="#arguments.keyList#" delimiters="#arguments.delimiters#" index="key">
        <cfset StructDelete(arguments.struct, key) />
    </cfloop>
    
    <cfreturn />
</cffunction>

 

Utility Functions: StructToListPairs() and ListPairsToStruct()

Today we have a pair of functions designed to convert structures into list pairs and back again. They serve as the back bone of another pair of functions that I'll release soon. StructToListPairs() is also useful when constructing long links (such as creating "sort" links for tables).

<cffunction name="StructToListPairs" returntype="string">
    <cfargument name="struct" type="struct" requried="true" />
    <cfargument name="delimiter1" type="string" required="false" default="&" />
    <cfargument name="delimiter2" type="string" required="false" default="=" />
    
    <cfset var buffer = CreateObject("java", "java.lang.StringBuffer").init() />
    
    <cfloop collection="#arguments.struct#" item="key">
        <cfset buffer.append(key) />
        <cfset buffer.append(delimiter2) />
        <cfset buffer.append(arguments.struct[key]) />
        <cfset buffer.append(delimiter1) />
    </cfloop>
    
    <cfif buffer.length() gt 1>
        <cfset buffer.setLength(buffer.length()-1) />
    </cfif>
    
    <cfreturn buffer.toString() />
</cffunction>

<cffunction name="ListPairsToStruct" returntype="struct">
    <cfargument name="list" type="string" requried="true" />
    <cfargument name="delimiter1" type="string" required="false" default="&" />
    <cfargument name="delimiter2" type="string" required="false" default="=" />
    
    <cfset var returnValue = StructNew() />
    
    <cfloop list="#arguments.list#" index="pair" delimiters="#arguments.delimiter1#">
        <cfset returnValue[ListFirst(pair, arguments.delimiter2)] = ListLast(pair, arguments.delimiter2) />
    </cfloop>
    
    <cfreturn returnValue />
</cffunction>

 

Utility Functions: Three String Functions

Here is a trio of functions based on a question from Hal Helm's "Are you OO Ready" quiz, in which he mentions that you can do the following:

<cfset x = "something" />
<cfset y = x />
<cfoutput>#y.equals(x)#</cfoutput>

So I came up with these:

<cffunction name="StringToChars" access="public" output="false" returntype="array">
    <cfargument name="string" type="string" required="true" />
    
    <cfreturn arguments.string.toCharArray() />
</cffunction>

<cffunction name="StringEndsWith" access="public" output="false" returntype="boolean">
    <cfargument name="string" type="string" required="true" />
    <cfargument name="suffix" type="string" required="true" />
    
    <cfreturn arguments.string.endsWith(arguments.suffix) />
</cffunction>

<cffunction name="StringBeginsWith" access="public" output="false" returntype="boolean">
    <cfargument name="string" type="string" required="true" />
    <cfargument name="prefix" type="string" required="true" />
    
    <cfreturn arguments.string.startsWith(arguments.prefix) />
</cffunction>

 

Utility Function: PatternExtract()

Yet another Pattern based utility function. PatternExtract() takes a pattern and gives you make a structure with values based on the groups. Additional function arguments (beyond pattern and string) are used to determine the keys (in order) that match with the groups.

<cffunction name="PatternExtract" output="false" returntype="struct">
    <cfargument name="pattern" type="string" required="true" />
    <cfargument name="string" type="string" required="true" />

    <cfset var returnValue = StructNew() />
    <cfset var array = Duplicate(arguments) />

    <cfset ArrayDeleteAt(array, 1) />
    <cfset ArrayDeleteAt(array, 2) />

    <cfif IsSimpleValue(arguments.pattern)>
        <cfset arguments.pattern = CreateObject("java", "java.util.regex.Pattern").compile(arguments.pattern) />
    </cfif>
    
    <cfset local.matcher = arguments.pattern.matcher(arguments.string)>

    <cfif local.matcher.matches()>
        <cfset local.groups = local.matcher.groupCount() />
        <cfloop from="1" to="#local.groups#" index="x">
            <cfset returnValue[array[x]] = local.matcher.group(x) />
        </cfloop>
    </cfif>

    <cfreturn returnValue />
</cffunction>

I coded this in a hurry, so yeah its a little sloppy. I'll try and update this post with a more refined version.

 

Utility Function: QueryAddRowData()

This one probably isn't original, but I wanted to be able to add whole rows to query sets in a simple manner. The built in functions let you add new columns in a simple way, but not new rows. Thats kind of weird, since I'd think that people would want to add rows more often the columns. QueryAddRowData() is designed to be flexible in its allowed inputs, working with structs, arrays, and lists.

<cffunction name="QueryAddRowData" access="public" output="false" returntype="void">
    <cfargument name="query" type="query" required="true" />
    <cfargument name="data" type="any" required="true" />
    <cfargument name="delimiter" type="string" required="false" default="," />
    
    <cfset var local = StructNew() />
    
    <cfif NOT (IsArray(arguments.data) OR (IsStruct(arguments.data) AND NOT isObject(arguments.data)) OR IsSimpleValue(arguments.data))>
        <cfthrow errorcode="QueryAddRowData" message="Invalid data for argument data. Valid types are array, struct, and string." />
    </cfif>
    
    <cfset QueryAddRow(arguments.query) />
    
    <cfif IsArray(arguments.data)>
        <cfset local.columns = ListToArray(arguments.query.columnList) />
        <cfloop from="1" to="#ArrayLen(local.columns)#" index="x">
            <cfset QuerySetCell(arguments.query, local.columns[x], arguments.data[x]) />
        </cfloop>    
        
    <cfelseif IsStruct(arguments.data) AND NOT isObject(arguments.data)>
        <cfloop collection="#arguments.data#" item="column">
            <cfset QuerySetCell(arguments.query, column, arguments.data[column]) />
        </cfloop>
    <cfelseif IsSimpleValue(arguments.data)>
        <cfset local.data = ListToArray(arguments.data, arguments.delimiter) />
        <cfset local.columns = ListToArray(arguments.query.columnList) />
        <cfloop from="1" to="#ArrayLen(local.columns)#" index="x">
            <cfset QuerySetCell(arguments.query, local.columns[x], local.data[x]) />
        </cfloop>    
    </cfif>
    
    <cfreturn />
</cffunction>

Please note that with arrays and lists, the data must be ordered as it would be in the Query.columnList (alphabetically).

 

More Entries

Jon in Chicago, July 2008

I'm Jon Hartmann and I'm a C# .Net developer by day, a ColdFusion guru by night, and all around Javascript fanatic. Stay right here to read my technical posts as I grapple with mysterious error messages, user interface design questions, and all things baffling and irksome about programming for the web. Learn more about me.

Post a job. Find one. authenticjobs.com

Interested in becoming a sponsor? Contact me.