Class: Simple::SQL::Inserter

Inherits:
Object
  • Object
show all
Defined in:
lib/simple/sql/insert.rb

Constant Summary collapse

SQL =
::Simple::SQL
CONFICT_HANDLING =
{
  nil      => "",
  :nothing => "ON CONFLICT DO NOTHING",
  :ignore  => "ON CONFLICT DO NOTHING"
}
@@inserters =
{}

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(table_name:, columns:, on_conflict:, into:) ⇒ Inserter

  • table_name - the name of the table

  • columns - name of columns, as Array or Array

Raises:

  • (ArgumentError)


44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
# File 'lib/simple/sql/insert.rb', line 44

def initialize(table_name:, columns:, on_conflict:, into:)
  raise ArgumentError, "Cannot insert a record without attributes" if columns.empty?

  @columns = columns
  @into = into

  cols = []
  vals = []

  cols += columns
  vals += columns.each_with_index.map { |_, idx| "$#{idx + 1}" }

  timestamp_columns = SQL::Reflection.timestamp_columns(table_name) - columns.map(&:to_s)

  cols += timestamp_columns
  vals += timestamp_columns.map { "now()" }

  returning = into ? "*" : "id"

  @sql = "INSERT INTO #{table_name} (#{cols.join(',')}) VALUES(#{vals.join(',')}) #{confict_handling(on_conflict)} RETURNING #{returning}"
end

Class Method Details

.create(table_name:, columns:, on_conflict:, into:) ⇒ Object



34
35
36
37
38
# File 'lib/simple/sql/insert.rb', line 34

def self.create(table_name:, columns:, on_conflict:, into:)
  expect! on_conflict => CONFICT_HANDLING.keys

  @@inserters[[table_name, columns, on_conflict, into]] ||= new(table_name: table_name, columns: columns, on_conflict: on_conflict, into: into)
end

Instance Method Details

#confict_handling(on_conflict) ⇒ Object



72
73
74
75
76
# File 'lib/simple/sql/insert.rb', line 72

def confict_handling(on_conflict)
  CONFICT_HANDLING.fetch(on_conflict) do
    raise(ArgumentError, "Invalid on_conflict value #{on_conflict.inspect}")
  end
end

#insert(records:) ⇒ Object



78
79
80
81
82
83
84
# File 'lib/simple/sql/insert.rb', line 78

def insert(records:)
  SQL.transaction do
    records.map do |record|
      SQL.ask @sql, *record.values_at(*@columns), into: @into
    end
  end
end