Class: ROM::SQL::Commands::Postgres::Upsert

Inherits:
Create
  • Object
show all
Defined in:
lib/rom/sql/extensions/postgres/commands.rb

Overview

Upsert command

Uses a feature of PostgreSQL 9.5 commonly called an “upsert”. The command been called attempts to perform an insert and can make an update (or silently do nothing) in case of the insertion was unsuccessful due to a violation of a unique constraint. Very important implementation detail is that the whole operation is atomic, i.e. aware of concurrent transactions, and doesn’t raise exceptions if used properly.

See PG’s docs in INSERT statement for details www.postgresql.org/docs/current/static/sql-insert.html

Normally, the command should configured via class level settings. By default, that is without any settings provided, the command uses ON CONFLICT DO NOTHING clause.

This implementation uses Sequel’s API underneath, the docs are available at sequel.jeremyevans.net/rdoc-adapters/classes/Sequel/Postgres/DatasetMethods.html#method-i-insert_conflict

Instance Attribute Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#conflict_targetObject (readonly)



79
# File 'lib/rom/sql/extensions/postgres/commands.rb', line 79

option :conflict_target, default: -> { self.class.conflict_target }

#constraintSymbol (readonly)



75
# File 'lib/rom/sql/extensions/postgres/commands.rb', line 75

option :constraint, default: -> { self.class.constraint }

#update_statementObject (readonly)



83
# File 'lib/rom/sql/extensions/postgres/commands.rb', line 83

option :update_statement, default: -> { self.class.update_statement }

#update_whereObject (readonly)



87
# File 'lib/rom/sql/extensions/postgres/commands.rb', line 87

option :update_where, default: -> { self.class.update_where }

Instance Method Details

#execute(tuples) ⇒ Array<Hash>

Tries to insert provided tuples and do an update (or nothing) when the inserted record violates a unique constraint and hence cannot be appended to the table



96
97
98
99
100
101
102
# File 'lib/rom/sql/extensions/postgres/commands.rb', line 96

def execute(tuples)
  inserted_tuples = with_input_tuples(tuples) do |tuple|
    upsert(input[tuple], upsert_options)
  end

  inserted_tuples.flatten(1)
end

#upsert_optionsObject

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.



105
106
107
108
109
110
111
112
# File 'lib/rom/sql/extensions/postgres/commands.rb', line 105

def upsert_options
  @upsert_options ||= {
    constraint: constraint,
    target: conflict_target,
    update_where: update_where,
    update: update_statement
  }
end