Class: DbFuel::Library::ActiveRecord::Upsert

Inherits:
Base
  • Object
show all
Defined in:
lib/db_fuel/library/active_record/upsert.rb

Overview

This job will insert or update records. It will use the unique_keys to first run a query to see if it exists. Each unique_key becomes a WHERE clause. If a record is found it will then update the found record using the primary key specified. If a record is updated or created the record’s id will be set to the primary_keyed_column.

Expected Payload input: array of objects Payload output: array of objects.

Direct Known Subclasses

FindOrInsert, Insert, Update, UpdateAll

Constant Summary

Constants inherited from Base

Base::CREATED_AT, Base::NOW_TYPE, Base::UPDATED_AT

Instance Attribute Summary collapse

Attributes inherited from Base

#db_provider, #debug, #keys_register, #record_transformer, #resolver

Instance Method Summary collapse

Constructor Details

#initialize(table_name:, primary_keyed_column:, keys_register: nil, name: '', attributes: [], debug: false, register: Burner::DEFAULT_REGISTER, separator: '', timestamps: true, unique_attributes: []) ⇒ Upsert

Arguments:

name: name of the job within the Burner::Pipeline.

table_name [required]: name of the table to use for the INSERT OR UPDATE statements.

attributes:  Used to specify which object properties to put into the
             SQL statement and also allows for one last custom transformation
             pipeline, in case the data calls for SQL-specific transformers
             before mutation.

debug:       If debug is set to true (defaults to false) then the SQL statements and
             returned objects will be printed in the output.  Only use this option while
             debugging issues as it will fill
             up the output with (potentially too much) data.

primary_keyed_column [required]: Used to set the object's property to the
                             returned primary key from the
                             INSERT statement or used as the
                             WHERE clause for the UPDATE statement.

separator: Just like other jobs with a 'separator' option, if the objects require
           key-path notation or nested object support, you can set the separator
           to something non-blank (like a period for notation in the
           form of: name.first).

timestamps: If timestamps is true (default behavior) then the updated_at column will
            automatically have its value set
            to the current UTC timestamp if a record was updated.
            If a record was created the
            created_at and updated_at columns will be set.

unique_attributes: Each key will become a WHERE clause in
                   order to check for the existence of a specific record.


59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
# File 'lib/db_fuel/library/active_record/upsert.rb', line 59

def initialize(
  table_name:,
  primary_keyed_column:,
  keys_register: nil,
  name: '',
  attributes: [],
  debug: false,
  register: Burner::DEFAULT_REGISTER,
  separator: '',
  timestamps: true,
  unique_attributes: []
)
  super(
    name: name,
    keys_register: keys_register,
    table_name: table_name,
    attributes: attributes,
    debug: debug,
    register: register,
    separator: separator
  )

  @primary_keyed_column = Modeling::KeyedColumn.make(primary_keyed_column, nullable: true)

  @unique_record_transformer = Modeling::RecordTransformer.new(
    resolver: resolver,
    attributes: unique_attributes
  )

  @timestamps = timestamps

  freeze
end

Instance Attribute Details

#primary_keyed_columnObject (readonly)

Returns the value of attribute primary_keyed_column.



24
25
26
# File 'lib/db_fuel/library/active_record/upsert.rb', line 24

def primary_keyed_column
  @primary_keyed_column
end

#timestampsObject (readonly)

Returns the value of attribute timestamps.



24
25
26
# File 'lib/db_fuel/library/active_record/upsert.rb', line 24

def timestamps
  @timestamps
end

#unique_record_transformerObject (readonly)

Returns the value of attribute unique_record_transformer.



24
25
26
# File 'lib/db_fuel/library/active_record/upsert.rb', line 24

def unique_record_transformer
  @unique_record_transformer
end

Instance Method Details

#perform(output, payload) ⇒ Object

Raises:

  • (ArgumentError)


93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
# File 'lib/db_fuel/library/active_record/upsert.rb', line 93

def perform(output, payload)
  raise ArgumentError, 'primary_keyed_column is required' unless primary_keyed_column

  total_inserted = 0
  total_updated  = 0

  payload[register] = array(payload[register])
  keys              = resolve_key_set(output, payload)

  payload[register].each do |row|
    record_updated = insert_or_update(output, row, payload.time, keys)

    if record_updated
      total_updated += 1
    else
      total_inserted += 1
    end
  end

  output.detail("Total Updated: #{total_updated}")
  output.detail("Total Inserted: #{total_inserted}")
end