Class: Diary::Query::Select

Inherits:
Object
  • Object
show all
Defined in:
lib/diary-ruby/database/query.rb

Instance Method Summary collapse

Constructor Details

#initialize(table, context = nil) ⇒ Select

Returns a new instance of Select.



5
6
7
8
9
# File 'lib/diary-ruby/database/query.rb', line 5

def initialize(table, context=nil)
  @table_name = table
  @context = context
  @additions = []
end

Instance Method Details

#allObject



33
34
35
36
37
# 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

#contextObject



11
12
13
# File 'lib/diary-ruby/database/query.rb', line 11

def context
  @context
end

#each(&block) ⇒ Object



39
40
41
42
43
# 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) ⇒ Object

evaluation conditions, called when Select is given a context FIXME: it’s gross that Query::Select knows about Model



18
19
20
21
22
23
24
25
# 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) ⇒ Boolean

Returns:

  • (Boolean)


64
65
66
67
68
69
70
71
72
# 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

#firstObject



27
28
29
30
31
# 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) ⇒ Object



90
91
92
93
# File 'lib/diary-ruby/database/query.rb', line 90

def group_by(*conditions)
  @additions << GroupBy.new(*conditions)
  self
end

#limit(*conditions) ⇒ Object



85
86
87
88
# File 'lib/diary-ruby/database/query.rb', line 85

def limit(*conditions)
  @additions << Limit.new(*conditions)
  self
end

#map(&block) ⇒ Object



45
46
47
48
49
# 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) ⇒ Object



80
81
82
83
# File 'lib/diary-ruby/database/query.rb', line 80

def order(*conditions)
  @additions << Order.new(*conditions)
  self
end

#select(column_query) ⇒ Object



60
61
62
# File 'lib/diary-ruby/database/query.rb', line 60

def select(column_query)
  @column_query = column_query
end

#sizeObject Also known as: count



51
52
53
54
55
# 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

#to_sqlObject



95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
# 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) ⇒ Object



74
75
76
77
78
# File 'lib/diary-ruby/database/query.rb', line 74

def where(*conditions)
  # multiple wheres are OR'd
  @additions << Where.new(*conditions)
  self
end