I was writing a webservice today and part of what I wanted to return was a query.
However the query also returns things I don't want like the sql, which shows database table names etc.
Since this is a webservice for a 3rd party developer, I didn't want them to have this. I tried using convertQueryForGrid which dropped the sql but seems to break access to the query data also, or at least the rules are different.
So I looked around asked a few people and got the answer not possible. I asked Steve Onnis on Skype and he also said not possible. But a few hours later came back with this.
Now I couldn't write this, but understand (kinda) what its doing, its generating a long complex variable using regEx and evaluating it. Very scary, but very cool indeed.
8 comments:
I would call this a nice proof-of-concept, but would never use it in any serious production environment. I avoid usage of the Evaluate() function at all times because it just means trouble.
I would go with a UDF. Shouldn't be that hard.
I agree, its very cool, and shows the possibilities but I do use a small function and loop over in real use.
And why exactly is Evaluate() bad? Its performence has improved heaps since CF6 and i honestly don't see why it is so bad...unless someone can prove its evilness?
@Steve Onnis: It has everything to do with the principle behind the function: allowing unknown code to be executed on the server. It's just a potential security risk and should therefore be avoided at all times.
At least, that's what I think. :)
So its isn't a performence issue then, a security issue? If you are in control over what is being evaluated then the argument is void as as far as i am concerned. Like anything..it's bad if you use it poorly
@Steve Onnis
Yeah I was wondering the same thing. I generally don't use Evaluate() if there is another efficient way to get around it (there often is).
Performance from what I hear has improved greatly and as for security in this case, the inputs look pretty controlled to me. Looks secure. A speed comparison to a looped solution might be cool to see.
Nice post Dale, bookmarked :)
Oh and well done Steve, I didn't see that you had written it :)
Hmmm, you don't need those parentheses, and since a column name must be at least one character, you should use + instead of *, so the expression can be: '\b[^,]+\b'
With the replace being: '"\0" : "##q.\0[1]##"'
Actually, no need for the word boundaries either, it can be '[^,]+' and '##q['\0'][1]##'
And case-sensitivity doesn't come into it, so overall it could be changed to:
<cfset qRow = deserializeJson("{#evaluate(DE("#REReplace(q.ColumnList, '[^,]+', '"\0" : "##q["\0"][1]##"', 'ALL')#"))#}") />
However, I can't think of any benefit to that over doing a simple loop:
<cfset qRow = StructNew() />
<cfloop index="CurCol" list="#q.ColumnList#">
<cfset qRow[CurCol] = q[CurCol][1] />
</cfloop>
If you want that to be one line, make it a function and do:
<cfset qRow = QueryRowToStruct(q,1) />
Post a Comment