views:

420

answers:

1

On this question I solved the problem of querying Google Datastore to retrieve stuff by user (com.google.appengine.api.users.User) like this:

User user = userService.getCurrentUser();
String select_query = "select from " + Greeting.class.getName(); 
Query query = pm.newQuery(select_query); 
query.setFilter("author == paramAuthor"); 
query.declareParameters("java.lang.String paramAuthor"); 
greetings = (List<Greeting>) query.execute(user);

The above works fine - but after a bit of messing around I realized this syntax in not very practical as the need to build more complicated queries arises - so I decided to manually build my filters and now I got for example something like the following (where the filter is usually passed in as a string variable but now is built inline for simplicity):

User user = userService.getCurrentUser();    
String select_query = "select from " + Greeting.class.getName(); 
Query query = pm.newQuery(select_query); 
query.setFilter("author == '"+ user.getEmail() +"'");  
greetings = (List<Greeting>) query.execute();

Obviously this won't work even if this syntax with field = 'value' is supported by JDOQL and it works fine on other fields (String types and Enums). The other strange thing is that looking at the Data viewer in the app-engine dashboard the 'author' field is stored as type User but the value is '[email protected]', and then again when I set it up as parameter (the case above that works fine) I am declaring the parameter as a String then passing down an instance of User (user) which gets serialized with a simple toString() (I guess).

Anyone any idea?

+1  A: 

Using string substitution in query languages is always a bad idea. It's far too easy for a user to break out and mess with your environment, and it introduces a whole collection of encoding issues, etc.

What was wrong with your earlier parameter substitution approach? As far as I'm aware, it supports everything, and it sidesteps any parsing issues. As far as the problem with knowing how many arguments to pass goes, you can use Query.executeWithMap or Query.executeWithArray to execute a query with an unknown number of arguments.

Nick Johnson
Hi thanks for your answer - this shows what's the problem with parameter substitution (asked another question as it is a slightly different issue)
JohnIdol
forgot the link --> http://stackoverflow.com/questions/935762/how-to-dynamically-build-jdo-queries-on-multiple-parameters
JohnIdol
Updated my answer.
Nick Johnson
I am now using Query.executeWithArray - thanks for your suggestion
JohnIdol