# File lib/sequel/plugins/upsert.rb, line 66 def primary_key_columns_are_same_as_identifying_columns upsert_primary_key_columns == self.class.upsert_plugin_identifying_columns.sort end
module Sequel::Plugins::Upsert::InstanceMethods
Attributes
dirty stateful attribute because we can’t pass any opts through to the _insert_dataset
method
Public Instance Methods
Source
# File lib/sequel/plugins/upsert.rb, line 20 def upsert(opts = {}) @upsert_plugin_upserting = true if postgres? || mysql? save(opts) else manual_upsert(opts) end load_values_from_previously_inserted_object unless id self rescue Sequel::NoExistingObject load_values_from_previously_inserted_object self ensure @upsert_plugin_upserting = false end
Private Instance Methods
Source
# File lib/sequel/plugins/upsert.rb, line 84 def _insert_dataset if upsert_plugin_upserting if postgres? super.insert_conflict(update: values_to_update, target: self.class.upsert_plugin_identifying_columns) elsif mysql? columns_to_update = values_to_update.keys - self.class.upsert_plugin_identifying_columns super.on_duplicate_key_update(*columns_to_update) else super end else super end end
naughty override of Sequel
private method to avoid having to rewrite the whole save method logic
Calls superclass method
Source
# File lib/sequel/plugins/upsert.rb, line 115 def columns_to_not_update_when_exists @columns_to_not_update ||= self.class.upsert_plugin_ignore_columns_on_update || (self.class.upsert_plugin_identifying_columns + [:created_at, self.class.primary_key]).flatten end
Source
# File lib/sequel/plugins/upsert.rb, line 111 def columns_with_nil_values self.class.columns.each_with_object({}) {|key, hash| hash[key] = nil } end
Source
# File lib/sequel/plugins/upsert.rb, line 55 def find_previously_inserted_object query = self.class.upsert_plugin_identifying_columns.each_with_object({}) do | column_name, q | q[column_name] = values[column_name] end model.where(query).single_record end
Source
# File lib/sequel/plugins/upsert.rb, line 38 def load_values_from_previously_inserted_object set_primary_key_columns_from_previously_inserted_object refresh end
Source
# File lib/sequel/plugins/upsert.rb, line 70 def manual_upsert(opts) # Can use slice when we drop support for Ruby 2.4 query = values.select{ |k, _| self.class.upsert_plugin_identifying_columns.include?(k) } existing_record = model.where(query).single_record if existing_record existing_record.set(values_to_update) existing_record.save(opts) else save(opts) end end
Source
# File lib/sequel/plugins/upsert.rb, line 99 def mysql? model.db.adapter_scheme.to_s =~ /mysql/ end
Source
# File lib/sequel/plugins/upsert.rb, line 103 def postgres? model.db.adapter_scheme.to_s =~ /postgres/ end
Source
Source
# File lib/sequel/plugins/upsert.rb, line 43 def set_primary_key_columns_from_previously_inserted_object if !primary_key_columns_are_same_as_identifying_columns existing_record = find_previously_inserted_object upsert_primary_key_columns.each do | column | self.send("#{column}=".to_sym, existing_record[column]) end # Need to clear out the _update_dataset when the NoExistingObject is thrown because # the ID gets incremented somewhere in the Sequel code @this = nil end end
Source
# File lib/sequel/plugins/upsert.rb, line 62 def upsert_primary_key_columns @upsert_primary_key_columns ||= [*primary_key].sort end
Source
# File lib/sequel/plugins/upsert.rb, line 107 def values_to_update columns_with_nil_values.merge(values).reject{ |k, _| columns_to_not_update_when_exists.include?(k) } end