Module: MultiInsert::QueryBuilder

Defined in:
lib/multi_insert/query_builder.rb

Constant Summary collapse

INSERT_DEFAULTS =
{
  time: true
}

Class Method Summary collapse

Class Method Details

.insert(table, columns, values, opts = {}) ⇒ Object



9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
# File 'lib/multi_insert/query_builder.rb', line 9

def self.insert(table, columns, values, opts = {})
  ar = ActiveRecord::Base.connection

  opts = INSERT_DEFAULTS.merge(opts)

  now = Time.now.to_s(:db) if opts[:time]
  table = ar.quote_table_name(table.to_s)

  # Format columns
  columns = columns + [:created_at, :updated_at] if opts[:time]
  columns = columns.map!{|c| ar.quote_column_name(c.to_s)}
  columns = join_params(columns)

  # Format values
  if opts[:time]
    values = values.map{|v| v + [now, now]}
  end
  values = values.map{|v| join_params(v.map{|vv| ar.quote(vv)})}.join(',')

  "INSERT INTO #{table} #{columns} VALUES #{values}"
end

.join_params(params) ⇒ Object



76
77
78
# File 'lib/multi_insert/query_builder.rb', line 76

def self.join_params(params)
  "(" + params.join(',') + ")"
end

.on_conflict(column) ⇒ Object



36
37
38
39
40
41
42
43
44
# File 'lib/multi_insert/query_builder.rb', line 36

def self.on_conflict(column)
  if column.nil?
    "ON CONFLICT"
  else
    column = [column] unless column.kind_of?(Array)
    columns = column.map{|c| ActiveRecord::Base.connection.quote_column_name(c.to_s)}.join(',')
    "ON CONFLICT (#{columns})"
  end
end

.on_conflict_do_nothing(column) ⇒ Object



46
47
48
# File 'lib/multi_insert/query_builder.rb', line 46

def self.on_conflict_do_nothing(column)
  "#{on_conflict(column)} DO NOTHING"
end

.on_conflict_do_update(column, values, opts = {}) ⇒ Object



50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
# File 'lib/multi_insert/query_builder.rb', line 50

def self.on_conflict_do_update(column, values, opts = {})
  opts = INSERT_DEFAULTS.merge(opts)
  if values.is_a?(Symbol) || values.is_a?(String)
    values = { values => :excluded }
  elsif values.is_a?(Array)
    values = values.product([:excluded]).to_h
  end
  if opts[:time]
    now = Time.now.to_s(:db)
    values[:updated_at] = now
  end
  arr = []
  values.each do |key, value|
    v = nil
    key = ActiveRecord::Base.connection.quote_column_name(key.to_s)
    if value == :excluded
      v = "excluded.#{key}"
    else
      v = ActiveRecord::Base.connection.quote(value)
    end
    arr << "#{key} = #{v}"
  end
  values = arr.join(', ')
  "#{on_conflict(column)} DO UPDATE SET #{values}"
end

.returning(columns) ⇒ Object



31
32
33
34
# File 'lib/multi_insert/query_builder.rb', line 31

def self.returning(columns)
  columns = columns.map{|c| ActiveRecord::Base.connection.quote_column_name(c.to_s)}.join(',')
  "RETURNING #{columns}"
end