After many hours of banging my head on the desk, I've come up with a scheme that actually seems to work. I'll leave the details of it to another, more expansive post, because I've just written a function that I found extremely useful and I wanted to share it.
In my WS scheme, I'm making all my webservice methods pass back a generic object (wsgeneric.cfc, or a subclass of that) which has three properties
- a status code
- an error description (if an error occurs)
- the actual returned data - which may be anything
So, I whipped up a UDF for converting a QueryBean back to a CF query, and here it is:
<cffunction name="queryBeanToQuery" access="public" returntype="query" output="yes">
<cfargument name="objQueryBean" type="any" required="true"/>
<cfscript>
var qry_return = "";
var arrColumns = ArrayNew(1);
var arrRows = arrayNew(1);
var thisRow = 0;
var thisCol = 0;
var numRows = 0;
var thisVal = "";
if( objQueryBean.getClass() EQ "class coldfusion.xml.rpc.QueryBean" ){
arrColumns = objQueryBean.getColumnList();
numCols = arrayLen( arrColumns );
arrRows = objQueryBean.getData();
numRows = arrayLen( arrRows );
// create the return query object
qry_return = QueryNew( ArrayToList(arrColumns) );
// loop round each row
for( thisRow = 1; thisRow LTE numRows; thisRow = thisRow + 1 ){
QueryAddRow( qry_return );
// loop round each column
for( thisCol = 1; thisCol LTE numCols; thisCol = thisCol + 1 ){
// empty columns seem to give rise to undefined array elements!
try{
thisVal = arrRows[thisRow][thisCol];
}
catch(Any e) {
thisVal = "";
}
QuerySetCell( qry_return, arrColumns[thisCol], thisVal );
}
}
return qry_return;
} else {
writeOutput( "THATS not a query bean, it's a #objQueryBean.getClass()#!" );
qry_return = QueryNew("");
return qry_return;
}
</cfscript>
</cffunction>
It's not really production code, but it's saved me a lot of time, and hopefully someone out there will find it useful.
Enjoy!
6 comments:
Please post it to cflib. -Raymond Camden
done!
but if your webservice returns a query, then CF will turn it into a query for you, correct?
yes, if your webservice JUST returns a query.
In this case, I'm encapsulating my query in another object which has a status code, a status description, and the data - which in this case is a query.
When you extract the data from the returned object, you get a QueryBean rather than a reconstructed query.
But if your webservice returns just a striaghtforward query object, then you should be fine.
which is kinda my point... I think (at least in terms of CF), complex return objects should be "value" objects (e.g. they represent a fully encapuslated piece of data), rather than "response" objects, which is what you are doing. Not allowing the WSDL to specify a return type for the DATA circumvents the self-describing nature of webservices.
Agreed - see my previous post where I came to a very similar conclusion.
Post a Comment