UPDATE 8/31/2011
Guillaume Laforge almost did it:
http://gaelyk.appspot.com/tutorial/app-engine-shortcuts#query
It looks like he is doing an AST conversion to take off:
alias as Entity
Little. Cool stuff, Groovy 1.8 + AST transform = LINQ-esque queries on the JVM. The GL solution needs additional work, as far as I can see, in order to get the full capabilities of the queries (for example, subqueries, join syntax (field), etc.), but Gaelyk, apparently, is not required for its project.
EDIT
As a workaround to achieve pure LINQ syntax, I decided to define aliases. Not a huge deal and removes the main obstacle, which is likely to require complex transformations of AST to break out.
So, instead of:
from c as Composite join t as Teams ...
Now I define aliases (note: you need to do this to automatically fill in the fields):
def(Teams t,Composite c,Schools s) = [Teams.new(),Composite.new(),Schools.new()]
and use map syntax for from, join, etc.
from c:Composite join t:Teams ...
To solve problem # 2 (see the original below), add instance level getProperty methods for each pogo alias (the scope of which is limited to closing the ORM in which it is called nice). We simply return the name of the row property when we create the sql statement.
[t,c,s].each{Object o-> o.metaClass.getProperty = { String k-> k } }
Making "good" progress; -)
Now, to figure out what to do with "=" is difficult because the set property is empty. You may need to use eq, neq, gt, etc., but he really would prefer alphabetic characters to ensure readability closer to sql.
If interested, LINQ does quite a bit backstage. John Skeet (praise his name) has a nice answer: How does LINQ work inside?
ORIGINAL
Checked LINQ, very impressed.
// LINQ example var games = from t in Teams from g in t.Games where g.gameID = 212 select new { g.gameDate,g.gameTime }; // Seeking Groovy Nirvana latest { Integer teamID-> from c as Composite join t as Teams join s as Schools on ( schoolID = { from Teams where t.schoolID = s.schoolID } ) where t.teamID = "$teamID" select c.location, c.gameType, s.schoolName group c.gameID order c.gameDate, c.gameTime }
The proposed version of Groovy compiles fine, and if I define the aliases c, t, s with their corresponding POGO, I get a strong typed auocomplete IDE by field, nice. However, nowhere near LINQ, where there are no (visible) variable definitions other than the query itself, is completely autonomous and strongly typed, wow.
OK, can this be done in Groovy? I think (hopefully) yes, but I hung up on 2 questions:
1) How to implicitly populate an alias variable without a definition? I am currently redefining asType () to String so in "cc as Composite", c gets cast to Composite. Great, but the IDE "thinks" that there is a line in the closing area of โโundefined c and, therefore, there is no autocomplete of the POGO fields; - (
2) Since # 1 is not resolved, I define aliases as described above, so I can get auto-complete. Great, hacked (compared to LINQ), but does the trick. The problem here is that in "select c.location, c.gameType ..." I would like the fields not to be evaluated, but simply return "c.location" to the ORM selection method, rather than null (this is its default value ) getProperty () should work here, but I need it to apply only to pogo fields when called from the ORM scope (for example, for certain fields, such as select, order, group, etc.). The bit is lost there, maybe there is a way to annotate the orm methods or just call the "special" pogo getProperty through calls to the orm method (which is the closure delegate in the above nirvana request).
It should be noted that I do not want to create an exhaustive LINQ for Groovy, but this is one specific LINQ subset that I would like to see.