Class: Ronin::SQL::Emitter Private

Inherits:
Object
  • Object
show all
Defined in:
lib/ronin/sql/emitter.rb

Overview

This class is part of a private API. You should avoid using this class if possible, as it may be removed or be changed in the future.

Generates raw SQL.

API:

  • private

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(options = {}) ⇒ Emitter

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Initializes the SQL Emitter.

Parameters:

  • (defaults to: {})

    Emitter options.

Options Hash (options):

  • :case (:lower, :upper, :random, nil)

    Case for keywords.

  • :space (String) — default: ' '

    String to use for white-space.

  • :quotes (:single, :double) — default: :single

    Type of quotes to use for Strings.

API:

  • private



58
59
60
61
62
# File 'lib/ronin/sql/emitter.rb', line 58

def initialize(options={})
  @case  = options[:case]
  @space = options.fetch(:space,' ')
  @quotes = options.fetch(:quotes,:single)
end

Instance Attribute Details

#caseObject (readonly)

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

The case to use when emitting keywords

API:

  • private



35
36
37
# File 'lib/ronin/sql/emitter.rb', line 35

def case
  @case
end

#quotesObject (readonly)

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Type of String quotes to use

API:

  • private



41
42
43
# File 'lib/ronin/sql/emitter.rb', line 41

def quotes
  @quotes
end

#spaceObject (readonly)

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

String to use for white-space

API:

  • private



38
39
40
# File 'lib/ronin/sql/emitter.rb', line 38

def space
  @space
end

Instance Method Details

#emit(object) ⇒ String

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Emits a SQL object.

Parameters:

  • The SQL object.

Returns:

  • The raw SQL.

Raises:

  • Could not emit an unknown SQL object.

API:

  • private



298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
# File 'lib/ronin/sql/emitter.rb', line 298

def emit(object)
  case object
  when NilClass              then emit_null
  when TrueClass             then emit_true
  when FalseClass            then emit_false
  when Integer               then emit_integer(object)
  when Float                 then emit_decimal(object)
  when String                then emit_string(object)
  when Literal               then emit(object.value)
  when Symbol                then emit_keyword(object)
  when Field                 then emit_field(object)
  when Array                 then emit_list(object)
  when Hash                  then emit_assignments(object)
  when BinaryExpr, UnaryExpr then emit_expression(object)
  when Function              then emit_function(object)
  when Clause                then emit_clause(object)
  when Statement             then emit_statement(object)
  when StatementList         then emit_statement_list(object)
  else
    if object.respond_to?(:to_sql)
      object.to_sql
    else
      raise(ArgumentError,"cannot emit #{object.class}")
    end
  end
end

#emit_argument(operand) ⇒ String

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Emits a value used in an expression.

Parameters:

  • The operand to emit.

Returns:

  • The raw SQL.

Since:

  • 1.1.0

API:

  • private



233
234
235
236
237
238
# File 'lib/ronin/sql/emitter.rb', line 233

def emit_argument(operand)
  case operand
  when Statement then "(#{emit_statement(operand)})"
  else                emit(operand)
  end
end

#emit_assignments(values) ⇒ String

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Emits a list of columns and assigned values.

Parameters:

  • The column names and values.

Returns:

  • The raw SQL.

API:

  • private



216
217
218
219
220
# File 'lib/ronin/sql/emitter.rb', line 216

def emit_assignments(values)
  values.map { |key,value|
    "#{emit_keyword(key)}=#{emit(value)}"
  }.join(',')
end

#emit_clause(clause) ⇒ String

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Emits a SQL Clause.

Parameters:

  • The SQL Clause.

Returns:

  • The raw SQL.

API:

  • private



334
335
336
337
338
339
340
341
342
# File 'lib/ronin/sql/emitter.rb', line 334

def emit_clause(clause)
  sql = emit_keyword(clause.keyword)

  unless clause.argument.nil?
    sql << @space << emit_argument(clause.argument)
  end

  return sql
end

#emit_clauses(clauses) ⇒ String

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Emits multiple SQL Clauses.

Parameters:

  • The clauses to emit.

Returns:

  • The emitted clauses.

API:

  • private



353
354
355
# File 'lib/ronin/sql/emitter.rb', line 353

def emit_clauses(clauses)
  clauses.map { |clause| emit_clause(clause) }.join(@space)
end

#emit_decimal(decimal) ⇒ String

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Emits a SQL Decimal.

Parameters:

  • The decimal.

Returns:

  • The raw SQL.

API:

  • private



158
159
160
# File 'lib/ronin/sql/emitter.rb', line 158

def emit_decimal(decimal)
  decimal.to_s
end

#emit_expression(expr) ⇒ String

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Emits a SQL expression.

Parameters:

  • The SQL expression.

Returns:

  • The raw SQL.

API:

  • private



249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
# File 'lib/ronin/sql/emitter.rb', line 249

def emit_expression(expr)
  op = emit_operator(expr.operator)

  case expr
  when BinaryExpr
    left, right = emit_argument(expr.left), emit_argument(expr.right)

    case op
    when /^\W+$/ then "#{left}#{op}#{right}"
    else              [left, op, right].join(@space)
    end
  when UnaryExpr
    operand = emit_argument(expr.operand)

    case expr.operator
    when /^\W+$/ then "#{op}#{operand}"
    else              [op, operand].join(@space)
    end
  end
end

#emit_falseString

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Emits a false value.

Returns:

  • The raw SQL.

API:

  • private



122
123
124
# File 'lib/ronin/sql/emitter.rb', line 122

def emit_false
  "1=0"
end

#emit_field(field) ⇒ String

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Emits a SQL field.

Parameters:

  • The SQL field.

Returns:

  • The raw SQL.

API:

  • private



184
185
186
187
188
189
190
191
192
# File 'lib/ronin/sql/emitter.rb', line 184

def emit_field(field)
  name = emit_keyword(field.name)

  if field.parent
    name = "#{emit_field(field.parent)}.#{name}"
  end

  return name
end

#emit_function(function) ⇒ String

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Emits a SQL function.

Parameters:

  • The SQL function.

Returns:

  • The raw SQL.

API:

  • private



279
280
281
282
283
284
# File 'lib/ronin/sql/emitter.rb', line 279

def emit_function(function)
  name      = emit_keyword(function.name)
  arguments = function.arguments.map { |value| emit_argument(value) }

  return "#{name}(#{arguments.join(',')})"
end

#emit_integer(int) ⇒ String

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Emits a SQL Integer.

Parameters:

  • The Integer.

Returns:

  • The raw SQL.

API:

  • private



145
146
147
# File 'lib/ronin/sql/emitter.rb', line 145

def emit_integer(int)
  int.to_s
end

#emit_keyword(keyword) ⇒ String

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Emits a SQL keyword.

Parameters:

  • The SQL keyword.

Returns:

  • The raw SQL.

API:

  • private



73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
# File 'lib/ronin/sql/emitter.rb', line 73

def emit_keyword(keyword)
  keyword = Array(keyword).join(@space)

  case @case
  when :upper  then keyword.upcase
  when :lower  then keyword.downcase
  when :random
    keyword.tap do
      (keyword.length / 2).times do
        index = rand(keyword.length)
        keyword[index] = keyword[index].swapcase
      end
    end
  else
    keyword
  end
end

#emit_list(list) ⇒ String

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Emits a list of elements.

Parameters:

  • The list of elements.

Returns:

  • The raw SQL.

API:

  • private



203
204
205
# File 'lib/ronin/sql/emitter.rb', line 203

def emit_list(list)
  '(' + list.map { |element| emit(element) }.join(',') + ')'
end

#emit_null"NULL"

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Emits the NULL value.

Returns:

API:

  • private



112
113
114
# File 'lib/ronin/sql/emitter.rb', line 112

def emit_null
  emit_keyword(:NULL)
end

#emit_operator(op) ⇒ String

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Emits a SQL operator.

Parameters:

  • The operator symbol.

Returns:

  • The raw SQL.

API:

  • private



100
101
102
103
104
105
# File 'lib/ronin/sql/emitter.rb', line 100

def emit_operator(op)
  case op
  when /^\W+$/          then op.to_s
  else                       emit_keyword(op)
  end
end

#emit_statement(stmt) ⇒ String

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Emits a SQL Statement.

Parameters:

  • The SQL Statement.

Returns:

  • The raw SQL.

API:

  • private



366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
# File 'lib/ronin/sql/emitter.rb', line 366

def emit_statement(stmt)
  sql = emit_keyword(stmt.keyword)

  unless stmt.argument.nil?
    case stmt.argument
    when Array
      sql << @space << if stmt.argument.length == 1
                         emit_argument(stmt.argument[0])
                       else
                         emit_list(stmt.argument)
                       end
    else
      sql << @space << emit_argument(stmt.argument)
    end
  end

  unless stmt.clauses.empty?
    sql << @space << emit_clauses(stmt.clauses)
  end

  return sql
end

#emit_statement_list(list) ⇒ String

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Emits a full SQL statement list.

Parameters:

  • The SQL statement list.

Returns:

  • The raw SQL.

API:

  • private



398
399
400
401
402
# File 'lib/ronin/sql/emitter.rb', line 398

def emit_statement_list(list)
  list.statements.map { |stmt|
    emit_statement(stmt)
  }.join(";#{@space}")
end

#emit_string(string) ⇒ String

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Emits a SQL String.

Parameters:

  • The String.

Returns:

  • The raw SQL.

API:

  • private



171
172
173
# File 'lib/ronin/sql/emitter.rb', line 171

def emit_string(string)
  string.sql_escape(@quotes)
end

#emit_trueString

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Emits a true value.

Returns:

  • The raw SQL.

API:

  • private



132
133
134
# File 'lib/ronin/sql/emitter.rb', line 132

def emit_true
  "1=1"
end