class Diary::Query::Select

Public Class Methods

new(table, context=nil) click to toggle source
# File lib/diary-ruby/database/query.rb, line 5
def initialize(table, context=nil)
  @table_name = table
  @context = context
  @additions = []
end

Public Instance Methods

all() click to toggle source
# File lib/diary-ruby/database/query.rb, line 33
def all
  return self unless context
  result = execute_in_context(self.to_sql)
  context.materialize(result)
end
context() click to toggle source
# File lib/diary-ruby/database/query.rb, line 11
def context
  @context
end
count()
Alias for: size
each(&block) click to toggle source
# File lib/diary-ruby/database/query.rb, line 39
def each(&block)
  return self unless context
  result = execute_in_context(self.to_sql)
  context.materialize(result).each(&block)
end
execute_in_context(sql) click to toggle source
evaluation conditions, called when Select is given a context

FIXME: it's gross that Query::Select knows about Model

# File lib/diary-ruby/database/query.rb, line 18
def execute_in_context(sql)
  Diary.debug("[Query::Select execute_in_context] connection.execute(#{ sql.inspect })")
  if Array === sql
    context.connection.execute(*sql)
  else
    context.connection.execute(sql)
  end
end
exists?(*conditions) click to toggle source
# File lib/diary-ruby/database/query.rb, line 64
def exists?(*conditions)
  if conditions.size > 0
    @additions = []
    @additions << Where.new(*conditions)
    @additions << Limit.new(1)
  end
  c = self.count
  c && c > 0
end
first() click to toggle source
# File lib/diary-ruby/database/query.rb, line 27
def first
  return self unless context
  result = execute_in_context(self.limit(1).to_sql)
  context.materialize(result)[0]
end
group_by(*conditions) click to toggle source
# File lib/diary-ruby/database/query.rb, line 90
def group_by(*conditions)
  @additions << GroupBy.new(*conditions)
  self
end
limit(*conditions) click to toggle source
# File lib/diary-ruby/database/query.rb, line 85
def limit(*conditions)
  @additions << Limit.new(*conditions)
  self
end
map(&block) click to toggle source
# File lib/diary-ruby/database/query.rb, line 45
def map(&block)
  return self unless context
  result = execute_in_context(self.to_sql)
  context.materialize(result).map(&block)
end
order(*conditions) click to toggle source
# File lib/diary-ruby/database/query.rb, line 80
def order(*conditions)
  @additions << Order.new(*conditions)
  self
end
select(column_query) click to toggle source
# File lib/diary-ruby/database/query.rb, line 60
def select(column_query)
  @column_query = column_query
end
size() click to toggle source
# File lib/diary-ruby/database/query.rb, line 51
def size
  return self unless context
  result = execute_in_context(self.to_sql)
  result.size
end
Also aliased as: count
to_sql() click to toggle source
# File lib/diary-ruby/database/query.rb, line 95
def to_sql
  # combine @additions in order: WHERE () GROUP BY () ORDER () LIMIT ()

  sql_string = []
  bind_vars = []

  wheres = @additions.select {|a| Where === a}
  group_bys = @additions.select {|a| GroupBy === a}
  orders = @additions.select {|a| Order === a}
  limits = @additions.select {|a| Limit === a}

  if wheres.size > 0
    sql_string << "WHERE"

    where_params = []

    wheres = wheres.each do |w|
      if w.has_bound_vars?
        bind_vars << w.prepared_statement.bind_vars
      end

      where_params << w.prepared_statement.sql_string
    end

    sql_string << where_params.map {|wp|
      "(#{ wp })"
    }.join(' OR ')
  end

  if group_bys.size > 0
    sql_string << "GROUP BY #{group_bys.map {|gb| gb.prepared_statement.sql_string}.join(', ')}"
  end

  if orders.size > 0
    sql_string << "ORDER BY #{orders.map {|ord| ord.prepared_statement.sql_string}.join(', ')}"
  end

  if limits.size > 0
    # only 1 allowed, last takes precedence
    limit = limits.last
    sql_string << "LIMIT #{limit.prepared_statement.sql_string}"
  end

  query = [
    "SELECT #{ @column_query || '*' }",
    "FROM `#{ @table_name }`",
    sql_string
  ].join(' ')

  # once to_sql is called, the Query is reset
  @additions = []

  # return sqlite compatible SQL
  returning = if bind_vars.size > 0
                [query, bind_vars.flatten]
              else
                query
              end
  returning
end
where(*conditions) click to toggle source
# File lib/diary-ruby/database/query.rb, line 74
def where(*conditions)
  # multiple wheres are OR'd
  @additions << Where.new(*conditions)
  self
end