Module: JDBCHelper::SQL

Defined in:
lib/jdbc-helper/sql.rb

Defined Under Namespace

Classes: Expr, NotNilClass

Class Method Summary collapse

Class Method Details

.check(expr, is_name = false) ⇒ Object

FIXME: Naive protection for SQL Injection

Raises:

  • (ArgumentError)


91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
# File 'lib/jdbc-helper/sql.rb', line 91

def self.check expr, is_name = false
  return nil if expr.nil?

  tag = is_name ? 'Object name' : 'Expression'
  test = expr.gsub(/'[^']*'/, '').gsub(/`[^`]*`/, '').gsub(/"[^"]*"/, '').strip
  raise ArgumentError.new("#{tag} cannot contain (unquoted) semi-colons: #{expr}") if test.include?(';')
  raise ArgumentError.new("#{tag} cannot contain (unquoted) comments: #{expr}") if test.match(%r{--|/\*|\*/})
  raise ArgumentError.new("Unclosed quotation mark: #{expr}") if test.match(/['"`]/)
  raise ArgumentError.new("#{tag} is blank") if test.empty?

  if is_name
    raise ArgumentError.new(
      "#{tag} cannot contain (unquoted) parentheses: #{expr}") if test.match(%r{\(|\)})
  end

  return expr
end

.count(table, conds = nil) ⇒ Object

Generates count SQL with the given conditions



81
82
83
# File 'lib/jdbc-helper/sql.rb', line 81

def self.count table, conds = nil
  check "select count(*) from #{table} #{where_internal conds}".strip
end

.delete(table, conds = nil) ⇒ Object

Generates delete SQL with the given conditions



86
87
88
# File 'lib/jdbc-helper/sql.rb', line 86

def self.delete table, conds = nil
  check "delete from #{table} #{where_internal conds}".strip
end

.expr(str) ⇒ Object

Prevents a string from being quoted



7
8
9
# File 'lib/jdbc-helper/sql.rb', line 7

def self.expr str
  Expr.new str
end

.insert(table, data_hash) ⇒ Object

Generates insert SQL with hash



49
50
51
# File 'lib/jdbc-helper/sql.rb', line 49

def self.insert table, data_hash
  insert_internal 'insert', table, data_hash
end

.insert_ignore(table, data_hash) ⇒ Object

Generates insert ignore SQL (Non-standard syntax)



54
55
56
# File 'lib/jdbc-helper/sql.rb', line 54

def self.insert_ignore table, data_hash
  insert_internal 'insert ignore', table, data_hash
end

.not_nilObject

Returns NotNilClass singleton object



12
13
14
# File 'lib/jdbc-helper/sql.rb', line 12

def self.not_nil
  NotNilClass.singleton
end

.order_by(*criteria) ⇒ Object

Generates SQL order by cluase with the given conditions.



40
41
42
43
# File 'lib/jdbc-helper/sql.rb', line 40

def self.order_by *criteria
  str = criteria.map(&:to_s).reject(&:empty?).join(', ')
  str.empty? ? str : check('order by ' + str)
end

.replace(table, data_hash) ⇒ Object

Generates replace SQL (Non-standard syntax)



59
60
61
# File 'lib/jdbc-helper/sql.rb', line 59

def self.replace table, data_hash
  insert_internal 'replace', table, data_hash
end

.select(table, conds = nil, orders = nil) ⇒ Object

Generates select * SQL with the given conditions



72
73
74
75
76
77
78
# File 'lib/jdbc-helper/sql.rb', line 72

def self.select table, conds = nil, orders = nil
  check [
    "select * from #{table}", 
    where_internal(conds),
    order_by(orders)
  ].reject(&:empty?).join(' ')
end

.update(table, data_hash) ⇒ Object

Generates update SQL with hash. :where element of the given hash is taken out to generate where clause.



65
66
67
68
69
# File 'lib/jdbc-helper/sql.rb', line 65

def self.update table, data_hash
  where_clause = where_internal(data_hash.delete :where)
  updates = data_hash.map { |k, v| "#{k} = #{value v}" }.join(', ')
  check "update #{table} set #{updates} #{where_clause}".strip
end

.value(data) ⇒ Object

Formats the given data so that it can be injected into SQL



17
18
19
20
21
22
23
24
25
26
27
28
29
30
# File 'lib/jdbc-helper/sql.rb', line 17

def self.value data
  case data
  when NilClass
    'null'
  when Fixnum, Bignum, Float
    data
  when JDBCHelper::SQL::Expr
    data.to_s
  when String
    "'#{esc data}'"
  else
    raise NotImplementedError.new("Unsupported datatype: #{data.class}")
  end
end

.where(conds) ⇒ Object

Generates SQL where cluase with the given conditions. Parameter can be either Hash of String.



34
35
36
37
# File 'lib/jdbc-helper/sql.rb', line 34

def self.where conds
  where_clause = where_internal conds
  where_clause.empty? ? where_clause : check(where_clause)
end