A Ruby DSL for bulding SQL SELECT queries
Switch branches/tags
Nothing to show
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Failed to load latest commit information.



Boroda is a tiny library for SQL SELECT query generation. The library provides a DSL which is as close as possible to SQL. Just look at the code:

require 'boroda'

sql = Boroda.build do
  from :posts, :users
  select posts.*
  where (posts.author_id == users.id) & (users.name == 'Vlad Semenov')

The result:

SELECT posts.*
FROM posts, users
WHERE (posts.author_id = users.id) AND (users.name = 'Vlad Semenov')

As you see we are writing SQL queries in a pure ruby. Let's try to make something a little bit more complex.

min_rating = 5
sql = Boroda.build do
  from :posts => :p
  left join :comments => :c
  on c.post_id == p.id
  select p.id, p.title, p.content, c.id.count => :comment_count
  group by p.id
  where (p.title.like '%programming%') | # select all posts containing 'programming' in the title
        (p.rating > min_rating) # or having the rating greater than 5
  order by p.created_at.desc
  limit 10
  offset 20

The result:

SELECT p.id, p.title, p.content, COUNT(c.id) AS comment_count
FROM posts AS p
LEFT JOIN comments AS c
ON c.post_id = p.id
WHERE (p.title LIKE '%programming%') OR (p.rating > 5)
ORDER BY p.created_at DESC

Now let's see in general how to write queries using Boroda. Due to some techical limitations it was nessesary to change an order of SQL statements. The from method must be called first. A table name should be a symbol. You can specify aliases of tables passing a hash to the method like it is done in the second code snippet. Next you should specify join. The order you can call DSL methods:

from tables
[[left|right] [outer|inner] join tables
on condition | using columns
[select columns]
[ where condition
| group by columns
| having condition
| order by columns
| limit number
| offset number ]*

In other words, you can call all methods from the last group in any order. Boroda will take care of building a correct SQL query.

Next operators which are used in condition in where and having clauses have the same meaning which they have in SQL: +, -, *, /, >, <, >=, <=.

Due to some limitations in Ruby on operator overloading several operators vary from their SQL originals:

a == b    # =>  a = b
a <=> b   # =>  a <> b
(a) & (b) # =>  (a) AND (b)
(a) | (b) # =>  (a) OR (b)

Warning! It is absolutely necessary to use brackets around operands in last two cases. Otherwise you can get an unepected results. It is connected with the fact that this to operators have a very high priority in Ruby.

I don't recommend to use Boroda in production as far as it could be vulnerable to SQL injections.

By the way, boroda (борода) is the Russian for 'beard'.