Lisp comprehensions => SQL

From: [email protected] [mailto:[email protected]]
Sent: Wednesday, December 06, 2006 1:15 PM

implied by those three separate method calls.
employees.select{|e| (e.name == ‘John’) & (e.salary > 50)}.sort_by{|e|

salary is greater than 50. Return that result set. That’s a discrete

OK, I agree.
I’ve came to proposed version in two stages:

  1. was excited about idea on “list comprehension as database request”
    ideom
  2. was translated the “common” list comprehension to Ruby-style one.
    Hence the controversial result.
    Idea I ruled by was shown in Links[1] language overview and looks like

where (prefix != “”)
take(10,
for (var w ← wordlist)
where (w.word ~ /{prefix}.*/)
orderby (w.word)
[w]
)

Which, in turn, looks like “only one” method call. Where ruby’s
equivalent
is several calls.

So, for consistency, the idea must look like you’ve shown:

employees.select{|e| (e.name == ‘John’) & (e.salary > 50)}.sort_by{|e|
e.age}[2…10].run

or, may be

employees.do{ select{|e| (e.name == ‘John’) & (e.salary >
50)}.sort_by{|e|
e.age}[2…10] }

Hmm. I see, while I’m writing this, you have already posted the nearly
same
:slight_smile:

V.

  1. http://groups.inf.ed.ac.uk/links/

Victor “Zverok” Shepelev wrote:

#generates "select * from Employees where name = ‘John’ and salary > 50

But the realization of above seems to be interesting task (for RubyQuiz, may
be?)

Thanks for your patience. And sorry me my English.

I think Og can already do this, more or less.

T.

employees.select{|e| (e.name == ‘John’) & (e.salary > 50)}.sort_by{|e|
e.age}[2…10].run

or, may be

employees.do{ select{|e| (e.name == ‘John’) & (e.salary > 50)}.sort_by{|e|
e.age}[2…10] }

Hmm. I see, while I’m writing this, you have already posted the nearly same
:slight_smile:

Yep.

I will work on supporting that style of declaration with Kansas. Should
flow pretty easily from what Kansas does now, and I like the idea of
using
[x…y] for LIMIT.

Kirk H.

On Dec 5, 2006, at 2:27 PM, Victor Zverok S. wrote:

queries

that conditions is NOT plain Ruby, but custom DSL.
end
What do you think about?
There are quite a few more features in ez-where then the example
above. ez-where is only a where clause generator. It doesnt ourput
complete selects. But there are many ways to use it besides the above:

You can make it write the :include statements for you

articles = Article.find_where(:all) do |article|
article.title =~ ‘Lorem%’
article.author.name == ‘Ezra’
article.comments.user.name == ‘Fab’
end

The above just creates the following hashes and passes them to a
normal AR#find

:include => { :author => {}, :comments => { :user => {} } }
:conditions => ["(articles.title LIKE ? AND (authors.name = ?) AND
(users.name = ?))", “Lorem%”, “Ezra”, “Fab”]

But you can use it without active record at all to generate where
clauses for you:

a = c(:authors) { name == ‘jimbob’ }

b = c(:articles) { title =~ ‘%ruby%’ }

(a + b).to_sql

=> ["(authors.name = ?) AND (articles.title LIKE ?)", “jimbob”, "%

ruby%"]

(a | b).to_sql

=> ["(authors.name = ?) OR (articles.title LIKE ?)", “jimbob”, "%

ruby%"]

(a - b).to_sql

=> ["(authors.name = ?) AND NOT (articles.title LIKE ?)", “jimbob”,

“%ruby%”]

c = c(:tags) {any_of(:name, :comment, :metadata) =~ ‘%ruby%’}

c.to_sql

=> ["(tags.name LIKE ? OR tags.comment LIKE ? OR tags.metadata

LIKE ?)", “%ruby%”, “%ruby%”, “%ruby%”]

(a + b | c).to_sql

=> ["((authors.name = ?) AND (articles.title LIKE ?)) OR (tags.name

LIKE ? OR tags.comment LIKE ? OR tags.metadata LIKE ?)", “jimbob”, “%
ruby%”, “%ruby%”, “%ruby%”, “%ruby%”]

Make sure you get this from the rubyforge repository and not the old
version. This plugin is heavily test driven.

svn://rubyforge.org//var/svn/ez-where

Cheers
– Ezra Z.
– Lead Rails Evangelist
[email protected]
– Engine Y., Serious Rails Hosting
– (866) 518-YARD (9273)