importo 3.0.24 → 3.0.25
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/MIT-LICENSE +1 -1
- data/Rakefile +3 -20
- data/app/controllers/importo/imports_controller.rb +13 -13
- data/app/importers/concerns/exportable.rb +2 -2
- data/app/importers/concerns/importable.rb +10 -10
- data/app/importers/concerns/original.rb +3 -3
- data/app/importers/concerns/result_feedback.rb +2 -2
- data/app/importers/importo/import_job_callback.rb +5 -4
- data/app/jobs/importo/application_job.rb +1 -0
- data/app/jobs/importo/import_job.rb +11 -23
- data/app/jobs/importo/import_scheduled_job.rb +2 -2
- data/app/jobs/importo/purge_import_job.rb +2 -3
- data/app/models/importo/import.rb +4 -7
- data/app/services/importo/import_context.rb +2 -2
- data/app/services/importo/import_service.rb +2 -2
- data/config/routes.rb +5 -5
- data/lib/importo/adapters/sidekiq_batch_adapter.rb +3 -5
- data/lib/importo/configuration.rb +18 -5
- data/lib/importo/engine.rb +0 -11
- data/lib/importo/test_helpers.rb +5 -6
- data/lib/importo/version.rb +1 -1
- data/lib/importo.rb +0 -1
- metadata +8 -24
- data/db/migrate/20251117132125_create_good_jobs.rb +0 -40
- data/db/migrate/20251117132126_create_good_job_settings.rb +0 -20
- data/db/migrate/20251117132127_create_index_good_jobs_jobs_on_priority_created_at_when_unfinished.rb +0 -19
- data/db/migrate/20251117132128_create_good_job_batches.rb +0 -35
- data/db/migrate/20251117132129_create_good_job_executions.rb +0 -33
- data/db/migrate/20251117132130_create_good_jobs_error_event.rb +0 -16
- data/db/migrate/20251117132131_recreate_good_job_cron_indexes_with_conditional.rb +0 -45
- data/db/migrate/20251117132132_create_good_job_labels.rb +0 -15
- data/db/migrate/20251117132133_create_good_job_labels_index.rb +0 -22
- data/db/migrate/20251117132134_remove_good_job_active_id_index.rb +0 -21
- data/db/migrate/20251117132135_create_index_good_job_jobs_for_candidate_lookup.rb +0 -19
- data/db/migrate/20251117132136_create_good_job_execution_error_backtrace.rb +0 -15
- data/db/migrate/20251117132137_create_good_job_process_lock_ids.rb +0 -18
- data/db/migrate/20251117132138_create_good_job_process_lock_indexes.rb +0 -38
- data/db/migrate/20251117132139_create_good_job_execution_duration.rb +0 -15
- data/lib/importo/import_helpers.rb +0 -10
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 58de2b19f5aa87cb2464fd8b9ca56d5d6e4e58ed2561ab9e33a8b31689ab1391
|
|
4
|
+
data.tar.gz: e55c5dfcaa8f59694b33fd00f8abd31bfd8873d2cf317f0133e828c8ea4c3d37
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: f711dee28330a128c7c1b17c89f5648008e86b207a0a08a7500ddbcd89d93b66cb0221bcbf1bcb9b44ecc9cd853289ea94535c2fdcdf9f34d661799b26689053
|
|
7
|
+
data.tar.gz: 667e0ef7154a7a9895b15d1bc22c6301c5e451dc0c780856d86e2bf64c257dd2b3654c48e86de2af9381a533aed23fd1dad777f3ad217a48c48b9d94e5bce248
|
data/MIT-LICENSE
CHANGED
data/Rakefile
CHANGED
|
@@ -1,26 +1,8 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
begin
|
|
4
|
-
require "bundler/setup"
|
|
5
|
-
rescue LoadError
|
|
6
|
-
puts "You must `gem install bundler` and `bundle install` to run rake tasks"
|
|
7
|
-
end
|
|
8
|
-
|
|
9
|
-
require "rdoc/task"
|
|
10
|
-
|
|
11
|
-
RDoc::Task.new(:rdoc) do |rdoc|
|
|
12
|
-
rdoc.rdoc_dir = "rdoc"
|
|
13
|
-
rdoc.title = "Importo"
|
|
14
|
-
rdoc.options << "--line-numbers"
|
|
15
|
-
rdoc.rdoc_files.include("README.md")
|
|
16
|
-
rdoc.rdoc_files.include("lib/**/*.rb")
|
|
17
|
-
end
|
|
1
|
+
require "bundler/setup"
|
|
18
2
|
|
|
19
3
|
APP_RAKEFILE = File.expand_path("test/dummy/Rakefile", __dir__)
|
|
20
4
|
load "rails/tasks/engine.rake"
|
|
21
5
|
|
|
22
|
-
load "rails/tasks/statistics.rake"
|
|
23
|
-
|
|
24
6
|
require "bundler/gem_tasks"
|
|
25
7
|
|
|
26
8
|
require "rake/testtask"
|
|
@@ -28,7 +10,8 @@ require "rake/testtask"
|
|
|
28
10
|
Rake::TestTask.new(:test) do |t|
|
|
29
11
|
t.libs << "test"
|
|
30
12
|
t.pattern = "test/**/*_test.rb"
|
|
31
|
-
t.verbose =
|
|
13
|
+
t.verbose = true
|
|
14
|
+
t.warning = false
|
|
32
15
|
end
|
|
33
16
|
|
|
34
17
|
task default: :test
|
|
@@ -11,37 +11,37 @@ module Importo
|
|
|
11
11
|
def preview
|
|
12
12
|
@import = Import.find(params[:id])
|
|
13
13
|
if @import&.original&.attachment.present?
|
|
14
|
-
@original = Tempfile.new([
|
|
14
|
+
@original = Tempfile.new(["ActiveStorage", @import.original.filename.extension_with_delimiter])
|
|
15
15
|
@original.binmode
|
|
16
16
|
@import.original.download { |block| @original.write(block) }
|
|
17
17
|
@original.flush
|
|
18
18
|
@original.rewind
|
|
19
|
-
sheet =
|
|
19
|
+
sheet = Roo::Excelx.new(@original.path)
|
|
20
20
|
@sheet_data = sheet.parse(headers: true)
|
|
21
|
-
@check_header = @sheet_data.reject{ |h| h.keys == h.values }.map{|h| h.transform_values(&:to_s).compact_blank}.reduce({}, :merge).keys
|
|
21
|
+
@check_header = @sheet_data.reject { |h| h.keys == h.values }.map { |h| h.transform_values(&:to_s).compact_blank }.reduce({}, :merge).keys
|
|
22
22
|
end
|
|
23
|
-
if @sheet_data.nil? || @sheet_data.reject{ |h| h.keys == h.values }.blank?
|
|
24
|
-
Signum.error(Current.user, text: t(
|
|
23
|
+
if @sheet_data.nil? || @sheet_data.reject { |h| h.keys == h.values }.blank?
|
|
24
|
+
Signum.error(Current.user, text: t(".no_file"))
|
|
25
25
|
redirect_to action: :new
|
|
26
26
|
end
|
|
27
27
|
end
|
|
28
28
|
|
|
29
29
|
def create
|
|
30
|
-
unless import_params
|
|
31
|
-
@import = Import.new(kind:
|
|
30
|
+
unless import_params["original"].present?
|
|
31
|
+
@import = Import.new(kind: import_params[:kind], locale: I18n.locale)
|
|
32
32
|
Signum.error(Current.user, text: t(".flash.no_file"))
|
|
33
33
|
render :new
|
|
34
34
|
return
|
|
35
35
|
end
|
|
36
36
|
@import = Import.new(import_params.merge(locale: I18n.locale,
|
|
37
|
-
|
|
37
|
+
importo_ownable: Importo.config.current_import_owner.call))
|
|
38
38
|
if params["commit"] == "Upload" && @import.valid? && @import.save!
|
|
39
39
|
@import.confirm!
|
|
40
40
|
@import.schedule!
|
|
41
|
-
redirect_to importo.new_import_path(params[:kind] || @import.kind)
|
|
41
|
+
redirect_to importo.new_import_path(params[:kind] || @import.kind)
|
|
42
42
|
elsif params["commit"] == "Preview" && @import.valid?
|
|
43
43
|
@import.save!
|
|
44
|
-
redirect_to action: :preview, id: @import.id, kind: @import.kind
|
|
44
|
+
redirect_to action: :preview, id: @import.id, kind: @import.kind
|
|
45
45
|
else
|
|
46
46
|
Signum.error(Current.user, text: t(".flash.error", error: @import.errors&.full_messages&.join(".")))
|
|
47
47
|
render :new
|
|
@@ -51,7 +51,7 @@ module Importo
|
|
|
51
51
|
def cancel
|
|
52
52
|
@import = Import.find(params[:id])
|
|
53
53
|
@import.original.purge if @import.concept?
|
|
54
|
-
Signum.error(Current.user, text: t(
|
|
54
|
+
Signum.error(Current.user, text: t(".flash.cancel", id: @import.id))
|
|
55
55
|
@import.destroy!
|
|
56
56
|
redirect_to action: :new, kind: @import.kind
|
|
57
57
|
end
|
|
@@ -61,7 +61,7 @@ module Importo
|
|
|
61
61
|
if @import.can_revert? && @import.revert
|
|
62
62
|
redirect_to action: :index, notice: "Import reverted"
|
|
63
63
|
else
|
|
64
|
-
redirect_to action: :index, alert:
|
|
64
|
+
redirect_to action: :index, alert: "Import could not be reverted"
|
|
65
65
|
end
|
|
66
66
|
end
|
|
67
67
|
|
|
@@ -72,7 +72,7 @@ module Importo
|
|
|
72
72
|
if @import.valid? && @import.schedule!
|
|
73
73
|
redirect_to action: :index
|
|
74
74
|
else
|
|
75
|
-
Signum.error(Current.user, text: t(
|
|
75
|
+
Signum.error(Current.user, text: t(".flash.error", id: @import.id))
|
|
76
76
|
render :new
|
|
77
77
|
end
|
|
78
78
|
end
|
|
@@ -81,9 +81,9 @@ module Exportable
|
|
|
81
81
|
end
|
|
82
82
|
styles = export_columns.map do |_, c|
|
|
83
83
|
if c.options.dig(:export, :format) == "number" || (c.options.dig(:export, :format).nil? && c.options.dig(:export, :example).is_a?(Numeric))
|
|
84
|
-
|
|
84
|
+
workbook.styles.add_style format_code: "0"
|
|
85
85
|
elsif c.options.dig(:export, :format) == "text" || (c.options.dig(:export, :format).nil? && c.options.dig(:export, :example).is_a?(String))
|
|
86
|
-
|
|
86
|
+
workbook.styles.add_style format_code: "@"
|
|
87
87
|
elsif c.options.dig(:export, :format)
|
|
88
88
|
workbook.styles.add_style format_code: c.options.dig(:export, :format).to_s
|
|
89
89
|
else
|
|
@@ -21,7 +21,7 @@ module Importable
|
|
|
21
21
|
columns.each do |k, col|
|
|
22
22
|
next if col.proc.blank? || row[k].nil?
|
|
23
23
|
|
|
24
|
-
|
|
24
|
+
col.options[:attribute]
|
|
25
25
|
|
|
26
26
|
row[k] = import.column_overrides[col.attribute] if import.column_overrides[col.attribute]
|
|
27
27
|
|
|
@@ -88,7 +88,7 @@ module Importable
|
|
|
88
88
|
end
|
|
89
89
|
|
|
90
90
|
#
|
|
91
|
-
#
|
|
91
|
+
# Callbacks
|
|
92
92
|
#
|
|
93
93
|
def before_build(_record, _row)
|
|
94
94
|
end
|
|
@@ -124,12 +124,12 @@ module Importable
|
|
|
124
124
|
# Does the actual import
|
|
125
125
|
#
|
|
126
126
|
def import!(checked_columns)
|
|
127
|
-
raise ArgumentError,
|
|
127
|
+
raise ArgumentError, "Invalid data structure" unless structure_valid?
|
|
128
128
|
|
|
129
|
-
batch = Importo.config.
|
|
129
|
+
batch = Importo.config.batch_adapter_name.constantize.new
|
|
130
130
|
batch.description = "#{import.original.filename} - #{import.kind}"
|
|
131
131
|
batch.properties = {import_id: import.id}
|
|
132
|
-
if Importo.
|
|
132
|
+
if Importo.sidekiq?
|
|
133
133
|
batch.on_success("Importo::ImportJobCallback")
|
|
134
134
|
else
|
|
135
135
|
batch.on_success = "Importo::ImportJobCallback"
|
|
@@ -144,14 +144,14 @@ module Importable
|
|
|
144
144
|
v.delay.call(attributes[k])
|
|
145
145
|
end
|
|
146
146
|
end
|
|
147
|
-
|
|
148
|
-
Importo
|
|
147
|
+
|
|
148
|
+
method = Importo.sidekiq? ? "perform_async" : "perform_later"
|
|
149
|
+
Importo::ImportJob.set(wait_until: (delay.max * index).seconds.from_now).send(method, JSON.dump(attributes), index, import.id) if delay.present?
|
|
150
|
+
Importo::ImportJob.send(method, JSON.dump(attributes), index, import.id) unless delay.present?
|
|
149
151
|
end
|
|
150
152
|
end
|
|
151
153
|
|
|
152
|
-
if
|
|
153
|
-
batch.enqueue
|
|
154
|
-
end
|
|
154
|
+
batch.enqueue if Importo.good_job?
|
|
155
155
|
|
|
156
156
|
true
|
|
157
157
|
rescue => e
|
|
@@ -110,7 +110,7 @@ module Original
|
|
|
110
110
|
duplicate(row_hash, id)
|
|
111
111
|
end
|
|
112
112
|
|
|
113
|
-
def loop_data_rows(checked_columns =
|
|
113
|
+
def loop_data_rows(checked_columns = nil)
|
|
114
114
|
(data_start_row..spreadsheet.last_row).map do |index|
|
|
115
115
|
row = cells_from_row(index, false)
|
|
116
116
|
|
|
@@ -121,8 +121,8 @@ module Original
|
|
|
121
121
|
end.to_h
|
|
122
122
|
attributes.reject! { |k, _v| headers_added_by_import.include?(k) }
|
|
123
123
|
if checked_columns&.dig(:checked_columns).present?
|
|
124
|
-
selected_columns = checked_columns[:checked_columns].map{|i| col_for(i)&.first}
|
|
125
|
-
attributes.reject!{|k, _v| selected_columns.exclude?(k) }
|
|
124
|
+
selected_columns = checked_columns[:checked_columns].map { |i| col_for(i)&.first }
|
|
125
|
+
attributes.reject! { |k, _v| selected_columns.exclude?(k) }
|
|
126
126
|
end
|
|
127
127
|
yield attributes, index
|
|
128
128
|
end
|
|
@@ -35,7 +35,7 @@ module ResultFeedback
|
|
|
35
35
|
attributes.map do |column, value|
|
|
36
36
|
export_format = columns[column]&.options&.dig(:export, :format)
|
|
37
37
|
format_code = if export_format == "number" || (export_format.nil? && value.is_a?(Numeric))
|
|
38
|
-
"
|
|
38
|
+
"0"
|
|
39
39
|
elsif export_format == "text" || (export_format.nil? && value.is_a?(String))
|
|
40
40
|
"@"
|
|
41
41
|
elsif export_format
|
|
@@ -66,7 +66,7 @@ module ResultFeedback
|
|
|
66
66
|
base = friendly_name || model.class.name
|
|
67
67
|
base = base.to_s unless base.is_a?(String)
|
|
68
68
|
base = base.gsub(/[_\s-]/, "_").pluralize.downcase
|
|
69
|
-
"#{base}#{
|
|
69
|
+
"#{base}#{"_#{suffix}" if suffix.present?}.xlsx"
|
|
70
70
|
end
|
|
71
71
|
|
|
72
72
|
private
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
module Importo
|
|
2
2
|
class ImportJobCallback < ActiveJob::Base
|
|
3
|
-
include Sidekiq::Batch::Callback
|
|
3
|
+
include Sidekiq::Batch::Callback if Importo.sidekiq?
|
|
4
4
|
include Rails.application.routes.url_helpers
|
|
5
5
|
|
|
6
|
-
|
|
7
|
-
|
|
6
|
+
# This is for good_job
|
|
7
|
+
def perform(batch, context)
|
|
8
|
+
import = Import.find(batch.properties[:import_id])
|
|
8
9
|
complete_import(import)
|
|
9
10
|
end
|
|
10
11
|
|
|
@@ -29,11 +30,11 @@ module Importo
|
|
|
29
30
|
end
|
|
30
31
|
end
|
|
31
32
|
|
|
33
|
+
# This is for sidekiq
|
|
32
34
|
def on_complete(status, options)
|
|
33
35
|
options = options.deep_stringify_keys
|
|
34
36
|
import = Import.find(options["import_id"])
|
|
35
37
|
complete_import(import)
|
|
36
38
|
end
|
|
37
|
-
|
|
38
39
|
end
|
|
39
40
|
end
|
|
@@ -1,24 +1,9 @@
|
|
|
1
1
|
module Importo
|
|
2
|
-
|
|
3
|
-
if Importo.config.batch_adapter == Importo::SidekiqBatchAdapter
|
|
4
|
-
Object
|
|
5
|
-
else
|
|
6
|
-
ApplicationJob
|
|
7
|
-
end
|
|
8
|
-
|
|
9
|
-
class ImportJob < base_class
|
|
10
|
-
|
|
2
|
+
class ImportJob < Importo.import_job_base_class_name.constantize
|
|
11
3
|
# No options here, gets added from the adapter
|
|
12
4
|
|
|
13
5
|
def perform(attributes, index, import_id)
|
|
14
|
-
|
|
15
|
-
bid
|
|
16
|
-
else
|
|
17
|
-
batch.id
|
|
18
|
-
end
|
|
19
|
-
batch
|
|
20
|
-
|
|
21
|
-
self.class.execute_row(attributes, index, import_id, false, batch_id)
|
|
6
|
+
self.class.execute_row(attributes, index, import_id, false, defined?(bid) ? bid : batch.id)
|
|
22
7
|
end
|
|
23
8
|
|
|
24
9
|
def self.execute_row(attributes, index, import_id, last_attempt, bid)
|
|
@@ -27,17 +12,20 @@ module Importo
|
|
|
27
12
|
import = Import.find(import_id)
|
|
28
13
|
import.importer.process_data_row(attributes, index, last_attempt: last_attempt)
|
|
29
14
|
|
|
15
|
+
# This should not be needed:
|
|
16
|
+
# https://github.com/sidekiq/sidekiq/wiki/Batches#callbacks
|
|
17
|
+
#
|
|
30
18
|
# Between sidekiq and good job, there's a big difference:
|
|
31
19
|
# - Sidekiq calls on_complete callback when all jobs ran at least once.
|
|
32
20
|
# - GoodJob calls on_complete callback when all jobs are done (including retries).
|
|
33
21
|
# i.e. this logic is only needed for sidekiq
|
|
34
|
-
|
|
35
|
-
|
|
22
|
+
# return unless Importo.sidekiq?
|
|
23
|
+
|
|
24
|
+
# batch = Importo::SidekiqBatchAdapter.find(bid)
|
|
36
25
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
end
|
|
26
|
+
# if !import.completed? && import.can_complete? && batch.finished?
|
|
27
|
+
# ImportJobCallback.perform_now(batch, import.id)
|
|
28
|
+
# end
|
|
41
29
|
end
|
|
42
30
|
end
|
|
43
31
|
end
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
module Importo
|
|
2
|
-
class PurgeImportJob <
|
|
3
|
-
def perform(owner, months,state = nil)
|
|
4
|
-
|
|
2
|
+
class PurgeImportJob < ActiveJob::Base
|
|
3
|
+
def perform(owner, months, state = nil)
|
|
5
4
|
imports = Import.where(importo_ownable: owner, created_at: ..months.months.ago.beginning_of_day)
|
|
6
5
|
imports = imports.where(state: state) if state
|
|
7
6
|
|
|
@@ -12,12 +12,9 @@ module Importo
|
|
|
12
12
|
validates :kind, presence: true
|
|
13
13
|
validates :original, presence: true
|
|
14
14
|
validate :content_validator
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
rescue NoMethodError
|
|
19
|
-
# Weird loading sequence error, is fixed by the lib/importo/helpers
|
|
20
|
-
end
|
|
15
|
+
|
|
16
|
+
has_one_attached :original
|
|
17
|
+
has_one_attached :result
|
|
21
18
|
|
|
22
19
|
state_machine :state, initial: :concept do
|
|
23
20
|
state :confirmed
|
|
@@ -115,7 +112,7 @@ module Importo
|
|
|
115
112
|
private
|
|
116
113
|
|
|
117
114
|
def schedule_import
|
|
118
|
-
ImportService.perform_later(import: self, checked_columns:
|
|
115
|
+
ImportService.perform_later(import: self, checked_columns: checked_columns)
|
|
119
116
|
end
|
|
120
117
|
|
|
121
118
|
def schedule_revert
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
module Importo
|
|
4
4
|
class ImportContext < ApplicationContext
|
|
5
|
-
|
|
6
|
-
|
|
5
|
+
attribute :import, type: Import, typecaster: ->(value) { value.is_a?(Import) ? value : Import.find(value) }
|
|
6
|
+
attribute :checked_columns, type: Array, typecaster: ->(value) { value.is_a?(Array) ? value : [] }
|
|
7
7
|
end
|
|
8
8
|
end
|
|
@@ -4,8 +4,8 @@ module Importo
|
|
|
4
4
|
class ImportService < ApplicationService
|
|
5
5
|
def perform
|
|
6
6
|
context.import.import!
|
|
7
|
-
context.import.importer.import!(checked_columns: context.checked_columns
|
|
8
|
-
rescue
|
|
7
|
+
context.import.importer.import!(checked_columns: context.checked_columns)
|
|
8
|
+
rescue
|
|
9
9
|
context.import.failure!
|
|
10
10
|
context.fail!
|
|
11
11
|
end
|
data/config/routes.rb
CHANGED
|
@@ -8,9 +8,9 @@ Importo::Engine.routes.draw do
|
|
|
8
8
|
post :cancel
|
|
9
9
|
end
|
|
10
10
|
end
|
|
11
|
-
get
|
|
12
|
-
get
|
|
13
|
-
get
|
|
14
|
-
get
|
|
15
|
-
root to:
|
|
11
|
+
get ":kind/new", to: "imports#new", as: :new_import
|
|
12
|
+
get ":kind/sample", to: "imports#sample", as: :sample_import
|
|
13
|
+
get ":kind/export", to: "imports#export", as: :export
|
|
14
|
+
get ":kind/:id/preview", to: "imports#preview", as: :preview
|
|
15
|
+
root to: "imports#index"
|
|
16
16
|
end
|
|
@@ -8,7 +8,6 @@ if !defined?(Sidekiq::Batch)
|
|
|
8
8
|
end
|
|
9
9
|
end
|
|
10
10
|
|
|
11
|
-
|
|
12
11
|
module Importo
|
|
13
12
|
class SidekiqBatchAdapter
|
|
14
13
|
attr_reader :description
|
|
@@ -32,13 +31,13 @@ module Importo
|
|
|
32
31
|
end
|
|
33
32
|
|
|
34
33
|
def finished?
|
|
35
|
-
status = Sidekiq::Batch::Status.new(
|
|
34
|
+
status = Sidekiq::Batch::Status.new(@instance.bid)
|
|
36
35
|
status.complete?
|
|
37
36
|
end
|
|
38
37
|
|
|
39
38
|
class << self
|
|
40
|
-
def
|
|
41
|
-
Object
|
|
39
|
+
def import_job_base_class_name
|
|
40
|
+
"Object"
|
|
42
41
|
end
|
|
43
42
|
|
|
44
43
|
def find(id)
|
|
@@ -76,6 +75,5 @@ end
|
|
|
76
75
|
|
|
77
76
|
require_relative "../../../app/jobs/importo/import_job"
|
|
78
77
|
|
|
79
|
-
|
|
80
78
|
Importo::ImportJob.send(:include, Sidekiq::Job)
|
|
81
79
|
Importo::ImportJob.send(:include, Importo::SidekiqBatchAdapter::ImportJobIncludes)
|
|
@@ -46,7 +46,7 @@ module Importo
|
|
|
46
46
|
option :current_import_owner, default: lambda {}
|
|
47
47
|
option :queue_name, default: :import
|
|
48
48
|
# You can either use GoodJob::Batch or Importo::SidekiqBatchAdapter
|
|
49
|
-
option :
|
|
49
|
+
option :batch_adapter_name, default: "Importo::SidekiqBatchAdapter"
|
|
50
50
|
|
|
51
51
|
option :admin_visible_imports, default: lambda { Importo::Import.where(importo_ownable: Importo.config.current_import_owner) }
|
|
52
52
|
option(:admin_can_destroy,
|
|
@@ -54,10 +54,6 @@ module Importo
|
|
|
54
54
|
false
|
|
55
55
|
end)
|
|
56
56
|
|
|
57
|
-
# You can either use GoodJob::Batch or Importo::SidekiqBatchAdapter
|
|
58
|
-
option :batch_adapter, default: lambda { Importo::SidekiqBatchAdapter }, proc: true
|
|
59
|
-
option :import_job_base_class, default: "Object"
|
|
60
|
-
|
|
61
57
|
# Extra links relevant for this import: { link_name: { icon: 'far fa-..', url: '...' } }
|
|
62
58
|
option(:admin_extra_links,
|
|
63
59
|
default: lambda do |import|
|
|
@@ -84,5 +80,22 @@ module Importo
|
|
|
84
80
|
def reset_config!
|
|
85
81
|
@config = Configuration.new
|
|
86
82
|
end
|
|
83
|
+
|
|
84
|
+
def sidekiq?
|
|
85
|
+
config.batch_adapter_name == "Importo::SidekiqBatchAdapter"
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
def good_job?
|
|
89
|
+
config.batch_adapter_name == "GoodJob::Batch"
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
def import_job_base_class_name
|
|
93
|
+
if sidekiq?
|
|
94
|
+
"Object"
|
|
95
|
+
else
|
|
96
|
+
require_dependency "importo/application_job"
|
|
97
|
+
"::Importo::ApplicationJob"
|
|
98
|
+
end
|
|
99
|
+
end
|
|
87
100
|
end
|
|
88
101
|
end
|
data/lib/importo/engine.rb
CHANGED
|
@@ -13,16 +13,5 @@ require "with_advisory_lock"
|
|
|
13
13
|
module Importo
|
|
14
14
|
class Engine < ::Rails::Engine
|
|
15
15
|
isolate_namespace Importo
|
|
16
|
-
|
|
17
|
-
initializer "importo.active_storage.attached" do
|
|
18
|
-
config.after_initialize do
|
|
19
|
-
ActiveSupport.on_load(:active_record) do
|
|
20
|
-
Importo::Import.include(ImportHelpers)
|
|
21
|
-
|
|
22
|
-
# For now put this here to ensure compatibility
|
|
23
|
-
require "importo/adapters/sidekiq_batch_adapter"
|
|
24
|
-
end
|
|
25
|
-
end
|
|
26
|
-
end
|
|
27
16
|
end
|
|
28
17
|
end
|
data/lib/importo/test_helpers.rb
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true-
|
|
2
2
|
|
|
3
|
-
require "axlsx"
|
|
4
|
-
require "roo/excelx"
|
|
3
|
+
# require "axlsx"
|
|
4
|
+
# require "roo/excelx"
|
|
5
5
|
|
|
6
6
|
module Importo
|
|
7
7
|
module TestHelpers
|
|
@@ -30,11 +30,10 @@ module Importo
|
|
|
30
30
|
import.save!
|
|
31
31
|
import.confirm
|
|
32
32
|
import.schedule
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
ImportJobCallback.new.on_success(:success,{import_id: import.id})
|
|
33
|
+
if Importo.sidekiq?
|
|
34
|
+
ImportJobCallback.new.on_complete(:success, {import_id: import.id})
|
|
36
35
|
end
|
|
37
|
-
import
|
|
36
|
+
import.reload
|
|
38
37
|
end
|
|
39
38
|
end
|
|
40
39
|
end
|
data/lib/importo/version.rb
CHANGED
data/lib/importo.rb
CHANGED
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: importo
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 3.0.
|
|
4
|
+
version: 3.0.25
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Andre Meij
|
|
@@ -9,7 +9,7 @@ authors:
|
|
|
9
9
|
autorequire:
|
|
10
10
|
bindir: bin
|
|
11
11
|
cert_chain: []
|
|
12
|
-
date:
|
|
12
|
+
date: 2026-01-08 00:00:00.000000000 Z
|
|
13
13
|
dependencies:
|
|
14
14
|
- !ruby/object:Gem::Dependency
|
|
15
15
|
name: caxlsx
|
|
@@ -17,14 +17,14 @@ dependencies:
|
|
|
17
17
|
requirements:
|
|
18
18
|
- - "~>"
|
|
19
19
|
- !ruby/object:Gem::Version
|
|
20
|
-
version:
|
|
20
|
+
version: '4'
|
|
21
21
|
type: :runtime
|
|
22
22
|
prerelease: false
|
|
23
23
|
version_requirements: !ruby/object:Gem::Requirement
|
|
24
24
|
requirements:
|
|
25
25
|
- - "~>"
|
|
26
26
|
- !ruby/object:Gem::Version
|
|
27
|
-
version:
|
|
27
|
+
version: '4'
|
|
28
28
|
- !ruby/object:Gem::Dependency
|
|
29
29
|
name: csv
|
|
30
30
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -59,28 +59,28 @@ dependencies:
|
|
|
59
59
|
requirements:
|
|
60
60
|
- - "~>"
|
|
61
61
|
- !ruby/object:Gem::Version
|
|
62
|
-
version: '
|
|
62
|
+
version: '3'
|
|
63
63
|
type: :runtime
|
|
64
64
|
prerelease: false
|
|
65
65
|
version_requirements: !ruby/object:Gem::Requirement
|
|
66
66
|
requirements:
|
|
67
67
|
- - "~>"
|
|
68
68
|
- !ruby/object:Gem::Version
|
|
69
|
-
version: '
|
|
69
|
+
version: '3'
|
|
70
70
|
- !ruby/object:Gem::Dependency
|
|
71
71
|
name: roo-xls
|
|
72
72
|
requirement: !ruby/object:Gem::Requirement
|
|
73
73
|
requirements:
|
|
74
74
|
- - "~>"
|
|
75
75
|
- !ruby/object:Gem::Version
|
|
76
|
-
version: '
|
|
76
|
+
version: '2'
|
|
77
77
|
type: :runtime
|
|
78
78
|
prerelease: false
|
|
79
79
|
version_requirements: !ruby/object:Gem::Requirement
|
|
80
80
|
requirements:
|
|
81
81
|
- - "~>"
|
|
82
82
|
- !ruby/object:Gem::Version
|
|
83
|
-
version: '
|
|
83
|
+
version: '2'
|
|
84
84
|
- !ruby/object:Gem::Dependency
|
|
85
85
|
name: satis
|
|
86
86
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -345,21 +345,6 @@ files:
|
|
|
345
345
|
- db/migrate/20190827093548_add_selected_fields_to_import.rb
|
|
346
346
|
- db/migrate/20230510051447_remove_result_from_imports.rb
|
|
347
347
|
- db/migrate/20230510083043_create_importo_results.rb
|
|
348
|
-
- db/migrate/20251117132125_create_good_jobs.rb
|
|
349
|
-
- db/migrate/20251117132126_create_good_job_settings.rb
|
|
350
|
-
- db/migrate/20251117132127_create_index_good_jobs_jobs_on_priority_created_at_when_unfinished.rb
|
|
351
|
-
- db/migrate/20251117132128_create_good_job_batches.rb
|
|
352
|
-
- db/migrate/20251117132129_create_good_job_executions.rb
|
|
353
|
-
- db/migrate/20251117132130_create_good_jobs_error_event.rb
|
|
354
|
-
- db/migrate/20251117132131_recreate_good_job_cron_indexes_with_conditional.rb
|
|
355
|
-
- db/migrate/20251117132132_create_good_job_labels.rb
|
|
356
|
-
- db/migrate/20251117132133_create_good_job_labels_index.rb
|
|
357
|
-
- db/migrate/20251117132134_remove_good_job_active_id_index.rb
|
|
358
|
-
- db/migrate/20251117132135_create_index_good_job_jobs_for_candidate_lookup.rb
|
|
359
|
-
- db/migrate/20251117132136_create_good_job_execution_error_backtrace.rb
|
|
360
|
-
- db/migrate/20251117132137_create_good_job_process_lock_ids.rb
|
|
361
|
-
- db/migrate/20251117132138_create_good_job_process_lock_indexes.rb
|
|
362
|
-
- db/migrate/20251117132139_create_good_job_execution_duration.rb
|
|
363
348
|
- lib/generators/importo/USAGE
|
|
364
349
|
- lib/generators/importo/importer_generator.rb
|
|
365
350
|
- lib/generators/importo/install_generator.rb
|
|
@@ -376,7 +361,6 @@ files:
|
|
|
376
361
|
- lib/importo/configuration.rb
|
|
377
362
|
- lib/importo/engine.rb
|
|
378
363
|
- lib/importo/import_column.rb
|
|
379
|
-
- lib/importo/import_helpers.rb
|
|
380
364
|
- lib/importo/test_helpers.rb
|
|
381
365
|
- lib/importo/version.rb
|
|
382
366
|
homepage: https://github.com/entdec/importo
|
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
class CreateGoodJobs < ActiveRecord::Migration[7.0]
|
|
4
|
-
def change
|
|
5
|
-
# Uncomment for Postgres v12 or earlier to enable gen_random_uuid() support
|
|
6
|
-
# enable_extension 'pgcrypto'
|
|
7
|
-
|
|
8
|
-
create_table :good_jobs, id: :uuid do |t|
|
|
9
|
-
t.text :queue_name
|
|
10
|
-
t.integer :priority
|
|
11
|
-
t.jsonb :serialized_params
|
|
12
|
-
t.datetime :scheduled_at
|
|
13
|
-
t.datetime :performed_at
|
|
14
|
-
t.datetime :finished_at
|
|
15
|
-
t.text :error
|
|
16
|
-
|
|
17
|
-
t.timestamps
|
|
18
|
-
|
|
19
|
-
t.uuid :active_job_id
|
|
20
|
-
t.text :concurrency_key
|
|
21
|
-
t.text :cron_key
|
|
22
|
-
t.uuid :retried_good_job_id
|
|
23
|
-
t.datetime :cron_at
|
|
24
|
-
end
|
|
25
|
-
|
|
26
|
-
create_table :good_job_processes, id: :uuid do |t|
|
|
27
|
-
t.timestamps
|
|
28
|
-
t.jsonb :state
|
|
29
|
-
end
|
|
30
|
-
|
|
31
|
-
add_index :good_jobs, :scheduled_at, where: "(finished_at IS NULL)", name: :index_good_jobs_on_scheduled_at
|
|
32
|
-
add_index :good_jobs, [:queue_name, :scheduled_at], where: "(finished_at IS NULL)", name: :index_good_jobs_on_queue_name_and_scheduled_at
|
|
33
|
-
add_index :good_jobs, [:active_job_id, :created_at], name: :index_good_jobs_on_active_job_id_and_created_at
|
|
34
|
-
add_index :good_jobs, :concurrency_key, where: "(finished_at IS NULL)", name: :index_good_jobs_on_concurrency_key_when_unfinished
|
|
35
|
-
add_index :good_jobs, [:cron_key, :created_at], name: :index_good_jobs_on_cron_key_and_created_at
|
|
36
|
-
add_index :good_jobs, [:cron_key, :cron_at], name: :index_good_jobs_on_cron_key_and_cron_at, unique: true
|
|
37
|
-
add_index :good_jobs, [:active_job_id], name: :index_good_jobs_on_active_job_id
|
|
38
|
-
add_index :good_jobs, [:finished_at], where: "retried_good_job_id IS NULL AND finished_at IS NOT NULL", name: :index_good_jobs_jobs_on_finished_at
|
|
39
|
-
end
|
|
40
|
-
end
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
class CreateGoodJobSettings < ActiveRecord::Migration[7.0]
|
|
4
|
-
def change
|
|
5
|
-
reversible do |dir|
|
|
6
|
-
dir.up do
|
|
7
|
-
# Ensure this incremental update migration is idempotent
|
|
8
|
-
# with monolithic install migration.
|
|
9
|
-
return if connection.table_exists?(:good_job_settings)
|
|
10
|
-
end
|
|
11
|
-
end
|
|
12
|
-
|
|
13
|
-
create_table :good_job_settings, id: :uuid do |t|
|
|
14
|
-
t.timestamps
|
|
15
|
-
t.text :key
|
|
16
|
-
t.jsonb :value
|
|
17
|
-
t.index :key, unique: true
|
|
18
|
-
end
|
|
19
|
-
end
|
|
20
|
-
end
|
data/db/migrate/20251117132127_create_index_good_jobs_jobs_on_priority_created_at_when_unfinished.rb
DELETED
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
class CreateIndexGoodJobsJobsOnPriorityCreatedAtWhenUnfinished < ActiveRecord::Migration[7.0]
|
|
4
|
-
disable_ddl_transaction!
|
|
5
|
-
|
|
6
|
-
def change
|
|
7
|
-
reversible do |dir|
|
|
8
|
-
dir.up do
|
|
9
|
-
# Ensure this incremental update migration is idempotent
|
|
10
|
-
# with monolithic install migration.
|
|
11
|
-
return if connection.index_name_exists?(:good_jobs, :index_good_jobs_jobs_on_priority_created_at_when_unfinished)
|
|
12
|
-
end
|
|
13
|
-
end
|
|
14
|
-
|
|
15
|
-
add_index :good_jobs, [:priority, :created_at], order: { priority: "DESC NULLS LAST", created_at: :asc },
|
|
16
|
-
where: "finished_at IS NULL", name: :index_good_jobs_jobs_on_priority_created_at_when_unfinished,
|
|
17
|
-
algorithm: :concurrently
|
|
18
|
-
end
|
|
19
|
-
end
|
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
class CreateGoodJobBatches < ActiveRecord::Migration[7.0]
|
|
4
|
-
def change
|
|
5
|
-
reversible do |dir|
|
|
6
|
-
dir.up do
|
|
7
|
-
# Ensure this incremental update migration is idempotent
|
|
8
|
-
# with monolithic install migration.
|
|
9
|
-
return if connection.table_exists?(:good_job_batches)
|
|
10
|
-
end
|
|
11
|
-
end
|
|
12
|
-
|
|
13
|
-
create_table :good_job_batches, id: :uuid do |t|
|
|
14
|
-
t.timestamps
|
|
15
|
-
t.text :description
|
|
16
|
-
t.jsonb :serialized_properties
|
|
17
|
-
t.text :on_finish
|
|
18
|
-
t.text :on_success
|
|
19
|
-
t.text :on_discard
|
|
20
|
-
t.text :callback_queue_name
|
|
21
|
-
t.integer :callback_priority
|
|
22
|
-
t.datetime :enqueued_at
|
|
23
|
-
t.datetime :discarded_at
|
|
24
|
-
t.datetime :finished_at
|
|
25
|
-
end
|
|
26
|
-
|
|
27
|
-
change_table :good_jobs do |t|
|
|
28
|
-
t.uuid :batch_id
|
|
29
|
-
t.uuid :batch_callback_id
|
|
30
|
-
|
|
31
|
-
t.index :batch_id, where: "batch_id IS NOT NULL"
|
|
32
|
-
t.index :batch_callback_id, where: "batch_callback_id IS NOT NULL"
|
|
33
|
-
end
|
|
34
|
-
end
|
|
35
|
-
end
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
class CreateGoodJobExecutions < ActiveRecord::Migration[7.0]
|
|
4
|
-
def change
|
|
5
|
-
reversible do |dir|
|
|
6
|
-
dir.up do
|
|
7
|
-
# Ensure this incremental update migration is idempotent
|
|
8
|
-
# with monolithic install migration.
|
|
9
|
-
return if connection.table_exists?(:good_job_executions)
|
|
10
|
-
end
|
|
11
|
-
end
|
|
12
|
-
|
|
13
|
-
create_table :good_job_executions, id: :uuid do |t|
|
|
14
|
-
t.timestamps
|
|
15
|
-
|
|
16
|
-
t.uuid :active_job_id, null: false
|
|
17
|
-
t.text :job_class
|
|
18
|
-
t.text :queue_name
|
|
19
|
-
t.jsonb :serialized_params
|
|
20
|
-
t.datetime :scheduled_at
|
|
21
|
-
t.datetime :finished_at
|
|
22
|
-
t.text :error
|
|
23
|
-
|
|
24
|
-
t.index [:active_job_id, :created_at], name: :index_good_job_executions_on_active_job_id_and_created_at
|
|
25
|
-
end
|
|
26
|
-
|
|
27
|
-
change_table :good_jobs do |t|
|
|
28
|
-
t.boolean :is_discrete
|
|
29
|
-
t.integer :executions_count
|
|
30
|
-
t.text :job_class
|
|
31
|
-
end
|
|
32
|
-
end
|
|
33
|
-
end
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
class CreateGoodJobsErrorEvent < ActiveRecord::Migration[7.0]
|
|
4
|
-
def change
|
|
5
|
-
reversible do |dir|
|
|
6
|
-
dir.up do
|
|
7
|
-
# Ensure this incremental update migration is idempotent
|
|
8
|
-
# with monolithic install migration.
|
|
9
|
-
return if connection.column_exists?(:good_jobs, :error_event)
|
|
10
|
-
end
|
|
11
|
-
end
|
|
12
|
-
|
|
13
|
-
add_column :good_jobs, :error_event, :integer, limit: 2
|
|
14
|
-
add_column :good_job_executions, :error_event, :integer, limit: 2
|
|
15
|
-
end
|
|
16
|
-
end
|
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
class RecreateGoodJobCronIndexesWithConditional < ActiveRecord::Migration[7.0]
|
|
4
|
-
disable_ddl_transaction!
|
|
5
|
-
|
|
6
|
-
def change
|
|
7
|
-
reversible do |dir|
|
|
8
|
-
dir.up do
|
|
9
|
-
unless connection.index_name_exists?(:good_jobs, :index_good_jobs_on_cron_key_and_created_at_cond)
|
|
10
|
-
add_index :good_jobs, [:cron_key, :created_at], where: "(cron_key IS NOT NULL)",
|
|
11
|
-
name: :index_good_jobs_on_cron_key_and_created_at_cond, algorithm: :concurrently
|
|
12
|
-
end
|
|
13
|
-
unless connection.index_name_exists?(:good_jobs, :index_good_jobs_on_cron_key_and_cron_at_cond)
|
|
14
|
-
add_index :good_jobs, [:cron_key, :cron_at], where: "(cron_key IS NOT NULL)", unique: true,
|
|
15
|
-
name: :index_good_jobs_on_cron_key_and_cron_at_cond, algorithm: :concurrently
|
|
16
|
-
end
|
|
17
|
-
|
|
18
|
-
if connection.index_name_exists?(:good_jobs, :index_good_jobs_on_cron_key_and_created_at)
|
|
19
|
-
remove_index :good_jobs, name: :index_good_jobs_on_cron_key_and_created_at
|
|
20
|
-
end
|
|
21
|
-
if connection.index_name_exists?(:good_jobs, :index_good_jobs_on_cron_key_and_cron_at)
|
|
22
|
-
remove_index :good_jobs, name: :index_good_jobs_on_cron_key_and_cron_at
|
|
23
|
-
end
|
|
24
|
-
end
|
|
25
|
-
|
|
26
|
-
dir.down do
|
|
27
|
-
unless connection.index_name_exists?(:good_jobs, :index_good_jobs_on_cron_key_and_created_at)
|
|
28
|
-
add_index :good_jobs, [:cron_key, :created_at],
|
|
29
|
-
name: :index_good_jobs_on_cron_key_and_created_at, algorithm: :concurrently
|
|
30
|
-
end
|
|
31
|
-
unless connection.index_name_exists?(:good_jobs, :index_good_jobs_on_cron_key_and_cron_at)
|
|
32
|
-
add_index :good_jobs, [:cron_key, :cron_at], unique: true,
|
|
33
|
-
name: :index_good_jobs_on_cron_key_and_cron_at, algorithm: :concurrently
|
|
34
|
-
end
|
|
35
|
-
|
|
36
|
-
if connection.index_name_exists?(:good_jobs, :index_good_jobs_on_cron_key_and_created_at_cond)
|
|
37
|
-
remove_index :good_jobs, name: :index_good_jobs_on_cron_key_and_created_at_cond
|
|
38
|
-
end
|
|
39
|
-
if connection.index_name_exists?(:good_jobs, :index_good_jobs_on_cron_key_and_cron_at_cond)
|
|
40
|
-
remove_index :good_jobs, name: :index_good_jobs_on_cron_key_and_cron_at_cond
|
|
41
|
-
end
|
|
42
|
-
end
|
|
43
|
-
end
|
|
44
|
-
end
|
|
45
|
-
end
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
class CreateGoodJobLabels < ActiveRecord::Migration[7.0]
|
|
4
|
-
def change
|
|
5
|
-
reversible do |dir|
|
|
6
|
-
dir.up do
|
|
7
|
-
# Ensure this incremental update migration is idempotent
|
|
8
|
-
# with monolithic install migration.
|
|
9
|
-
return if connection.column_exists?(:good_jobs, :labels)
|
|
10
|
-
end
|
|
11
|
-
end
|
|
12
|
-
|
|
13
|
-
add_column :good_jobs, :labels, :text, array: true
|
|
14
|
-
end
|
|
15
|
-
end
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
class CreateGoodJobLabelsIndex < ActiveRecord::Migration[7.0]
|
|
4
|
-
disable_ddl_transaction!
|
|
5
|
-
|
|
6
|
-
def change
|
|
7
|
-
reversible do |dir|
|
|
8
|
-
dir.up do
|
|
9
|
-
unless connection.index_name_exists?(:good_jobs, :index_good_jobs_on_labels)
|
|
10
|
-
add_index :good_jobs, :labels, using: :gin, where: "(labels IS NOT NULL)",
|
|
11
|
-
name: :index_good_jobs_on_labels, algorithm: :concurrently
|
|
12
|
-
end
|
|
13
|
-
end
|
|
14
|
-
|
|
15
|
-
dir.down do
|
|
16
|
-
if connection.index_name_exists?(:good_jobs, :index_good_jobs_on_labels)
|
|
17
|
-
remove_index :good_jobs, name: :index_good_jobs_on_labels
|
|
18
|
-
end
|
|
19
|
-
end
|
|
20
|
-
end
|
|
21
|
-
end
|
|
22
|
-
end
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
class RemoveGoodJobActiveIdIndex < ActiveRecord::Migration[7.0]
|
|
4
|
-
disable_ddl_transaction!
|
|
5
|
-
|
|
6
|
-
def change
|
|
7
|
-
reversible do |dir|
|
|
8
|
-
dir.up do
|
|
9
|
-
if connection.index_name_exists?(:good_jobs, :index_good_jobs_on_active_job_id)
|
|
10
|
-
remove_index :good_jobs, name: :index_good_jobs_on_active_job_id
|
|
11
|
-
end
|
|
12
|
-
end
|
|
13
|
-
|
|
14
|
-
dir.down do
|
|
15
|
-
unless connection.index_name_exists?(:good_jobs, :index_good_jobs_on_active_job_id)
|
|
16
|
-
add_index :good_jobs, :active_job_id, name: :index_good_jobs_on_active_job_id
|
|
17
|
-
end
|
|
18
|
-
end
|
|
19
|
-
end
|
|
20
|
-
end
|
|
21
|
-
end
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
class CreateIndexGoodJobJobsForCandidateLookup < ActiveRecord::Migration[7.0]
|
|
4
|
-
disable_ddl_transaction!
|
|
5
|
-
|
|
6
|
-
def change
|
|
7
|
-
reversible do |dir|
|
|
8
|
-
dir.up do
|
|
9
|
-
# Ensure this incremental update migration is idempotent
|
|
10
|
-
# with monolithic install migration.
|
|
11
|
-
return if connection.index_name_exists?(:good_jobs, :index_good_job_jobs_for_candidate_lookup)
|
|
12
|
-
end
|
|
13
|
-
end
|
|
14
|
-
|
|
15
|
-
add_index :good_jobs, [:priority, :created_at], order: { priority: "ASC NULLS LAST", created_at: :asc },
|
|
16
|
-
where: "finished_at IS NULL", name: :index_good_job_jobs_for_candidate_lookup,
|
|
17
|
-
algorithm: :concurrently
|
|
18
|
-
end
|
|
19
|
-
end
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
class CreateGoodJobExecutionErrorBacktrace < ActiveRecord::Migration[7.0]
|
|
4
|
-
def change
|
|
5
|
-
reversible do |dir|
|
|
6
|
-
dir.up do
|
|
7
|
-
# Ensure this incremental update migration is idempotent
|
|
8
|
-
# with monolithic install migration.
|
|
9
|
-
return if connection.column_exists?(:good_job_executions, :error_backtrace)
|
|
10
|
-
end
|
|
11
|
-
end
|
|
12
|
-
|
|
13
|
-
add_column :good_job_executions, :error_backtrace, :text, array: true
|
|
14
|
-
end
|
|
15
|
-
end
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
class CreateGoodJobProcessLockIds < ActiveRecord::Migration[7.0]
|
|
4
|
-
def change
|
|
5
|
-
reversible do |dir|
|
|
6
|
-
dir.up do
|
|
7
|
-
# Ensure this incremental update migration is idempotent
|
|
8
|
-
# with monolithic install migration.
|
|
9
|
-
return if connection.column_exists?(:good_jobs, :locked_by_id)
|
|
10
|
-
end
|
|
11
|
-
end
|
|
12
|
-
|
|
13
|
-
add_column :good_jobs, :locked_by_id, :uuid
|
|
14
|
-
add_column :good_jobs, :locked_at, :datetime
|
|
15
|
-
add_column :good_job_executions, :process_id, :uuid
|
|
16
|
-
add_column :good_job_processes, :lock_type, :integer, limit: 2
|
|
17
|
-
end
|
|
18
|
-
end
|
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
class CreateGoodJobProcessLockIndexes < ActiveRecord::Migration[7.0]
|
|
4
|
-
disable_ddl_transaction!
|
|
5
|
-
|
|
6
|
-
def change
|
|
7
|
-
reversible do |dir|
|
|
8
|
-
dir.up do
|
|
9
|
-
unless connection.index_name_exists?(:good_jobs, :index_good_jobs_on_priority_scheduled_at_unfinished_unlocked)
|
|
10
|
-
add_index :good_jobs, [:priority, :scheduled_at],
|
|
11
|
-
order: { priority: "ASC NULLS LAST", scheduled_at: :asc },
|
|
12
|
-
where: "finished_at IS NULL AND locked_by_id IS NULL",
|
|
13
|
-
name: :index_good_jobs_on_priority_scheduled_at_unfinished_unlocked,
|
|
14
|
-
algorithm: :concurrently
|
|
15
|
-
end
|
|
16
|
-
|
|
17
|
-
unless connection.index_name_exists?(:good_jobs, :index_good_jobs_on_locked_by_id)
|
|
18
|
-
add_index :good_jobs, :locked_by_id,
|
|
19
|
-
where: "locked_by_id IS NOT NULL",
|
|
20
|
-
name: :index_good_jobs_on_locked_by_id,
|
|
21
|
-
algorithm: :concurrently
|
|
22
|
-
end
|
|
23
|
-
|
|
24
|
-
unless connection.index_name_exists?(:good_job_executions, :index_good_job_executions_on_process_id_and_created_at)
|
|
25
|
-
add_index :good_job_executions, [:process_id, :created_at],
|
|
26
|
-
name: :index_good_job_executions_on_process_id_and_created_at,
|
|
27
|
-
algorithm: :concurrently
|
|
28
|
-
end
|
|
29
|
-
end
|
|
30
|
-
|
|
31
|
-
dir.down do
|
|
32
|
-
remove_index(:good_jobs, name: :index_good_jobs_on_priority_scheduled_at_unfinished_unlocked) if connection.index_name_exists?(:good_jobs, :index_good_jobs_on_priority_scheduled_at_unfinished_unlocked)
|
|
33
|
-
remove_index(:good_jobs, name: :index_good_jobs_on_locked_by_id) if connection.index_name_exists?(:good_jobs, :index_good_jobs_on_locked_by_id)
|
|
34
|
-
remove_index(:good_job_executions, name: :index_good_job_executions_on_process_id_and_created_at) if connection.index_name_exists?(:good_job_executions, :index_good_job_executions_on_process_id_and_created_at)
|
|
35
|
-
end
|
|
36
|
-
end
|
|
37
|
-
end
|
|
38
|
-
end
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
class CreateGoodJobExecutionDuration < ActiveRecord::Migration[7.0]
|
|
4
|
-
def change
|
|
5
|
-
reversible do |dir|
|
|
6
|
-
dir.up do
|
|
7
|
-
# Ensure this incremental update migration is idempotent
|
|
8
|
-
# with monolithic install migration.
|
|
9
|
-
return if connection.column_exists?(:good_job_executions, :duration)
|
|
10
|
-
end
|
|
11
|
-
end
|
|
12
|
-
|
|
13
|
-
add_column :good_job_executions, :duration, :interval
|
|
14
|
-
end
|
|
15
|
-
end
|