Class: Simple::SQL::Connection::Inserter

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

Constant Summary collapse

CONFICT_HANDLING =
{
  nil      => "",
  :nothing => "ON CONFLICT DO NOTHING",
  :ignore  => "ON CONFLICT DO NOTHING"
}

Instance Method Summary collapse

Constructor Details

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

  • table_name - the name of the table

  • columns - name of columns, as Array or Array

Raises:

  • (ArgumentError)


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

def initialize(connection, table_name, columns, on_conflict, into)
  expect! on_conflict => CONFICT_HANDLING.keys
  raise ArgumentError, "Cannot insert a record without attributes" if columns.empty?

  @connection = connection
  @table_name = table_name
  @columns = columns
  @into = into

  cols = []
  vals = []

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

  timestamp_columns = @connection.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

Instance Method Details

#encode_json_values!(values) ⇒ Object



76
77
78
# File 'lib/simple/sql/connection/insert.rb', line 76

def encode_json_values!(values)
  indices_of_json_columns.each { |idx| values[idx] = json_encode(values[idx]) }
end

#indices_of_json_columnsObject

determine indices of columns that are JSON(B).



81
82
83
84
85
86
87
88
# File 'lib/simple/sql/connection/insert.rb', line 81

def indices_of_json_columns
  return @indices_of_json_columns if @indices_of_json_columns

  column_types = @connection.reflection.column_types(@table_name)
  @indices_of_json_columns = @columns.each_with_index
                                     .select { |column_name, _idx| %w(json jsonb).include?(column_types[column_name]) }
                                     .map { |_column_name, idx| idx }
end

#insert(records:) ⇒ Object



65
66
67
68
69
70
71
72
73
74
# File 'lib/simple/sql/connection/insert.rb', line 65

def insert(records:)
  @connection.transaction do
    records.map do |record|
      values = record.values_at(*@columns)
      encode_json_values!(values)

      @connection.ask @sql, *values, into: @into
    end
  end
end

#json_encode(value) ⇒ Object



90
91
92
93
# File 'lib/simple/sql/connection/insert.rb', line 90

def json_encode(value)
  return value unless value.is_a?(Hash) || value.is_a?(Array)
  JSON.generate(value)
end