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.

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:

  • options (Hash) (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.



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



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



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



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:

  • object (#to_sql)

    The SQL object.

Returns:

Raises:

  • (ArgumentError)

    Could not emit an unknown SQL object.



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:

  • operand (Statement, #to_sql)

    The operand to emit.

Returns:

Since:

  • 1.1.0



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:

  • values (Hash{Field,Symbol => Object})

    The column names and values.

Returns:



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:

  • clause (Clause)

    The SQL Clause.

Returns:



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:

  • clauses (Array<Clause>)

    The clauses to emit.

Returns:

  • (String)

    The emitted clauses.



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:

  • decimal (Float)

    The decimal.

Returns:



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:

Returns:



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:



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:

Returns:



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:

  • function (Function)

    The SQL function.

Returns:



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:

  • int (Integer)

    The Integer.

Returns:



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:

  • keyword (Symbol, Array<Symbol>)

    The SQL keyword.

Returns:



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:

  • list (#map)

    The list of elements.

Returns:



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:

  • ("NULL")


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:

  • op (Array<Symbol>, Symbol)

    The operator symbol.

Returns:



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:

Returns:



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:

Returns:



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:

  • string (String)

    The String.

Returns:



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:



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

def emit_true
  "1=1"
end