Class: Dekiru::DataMigration::Operator

Inherits:
Object
  • Object
show all
Defined in:
lib/dekiru/data_migration/operator.rb

Overview

Data migration operator with transaction control and progress tracking

Direct Known Subclasses

Dekiru::DataMigrationOperator

Defined Under Namespace

Classes: NestedTransactionError

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(title, options = {}) ⇒ Operator

Returns a new instance of Operator.



19
20
21
22
23
24
25
26
27
28
29
30
# File 'lib/dekiru/data_migration/operator.rb', line 19

def initialize(title, options = {})
  @title = title
  @options = options
  @logger = @options.fetch(:logger) do
    Logger.new(Rails.root.join("log/data_migration_#{Time.current.strftime("%Y%m%d%H%M")}.log"))
  end
  @stream = @options.fetch(:output, $stdout)
  @without_transaction = @options.fetch(:without_transaction, false)
  @side_effects = Hash.new do |hash, key|
    hash[key] = Hash.new(0)
  end
end

Instance Attribute Details

#canceledObject (readonly)

Returns the value of attribute canceled.



13
14
15
# File 'lib/dekiru/data_migration/operator.rb', line 13

def canceled
  @canceled
end

#ended_atObject (readonly)

Returns the value of attribute ended_at.



13
14
15
# File 'lib/dekiru/data_migration/operator.rb', line 13

def ended_at
  @ended_at
end

#errorObject (readonly)

Returns the value of attribute error.



13
14
15
# File 'lib/dekiru/data_migration/operator.rb', line 13

def error
  @error
end

#loggerObject (readonly)

Returns the value of attribute logger.



13
14
15
# File 'lib/dekiru/data_migration/operator.rb', line 13

def logger
  @logger
end

#resultObject (readonly)

Returns the value of attribute result.



13
14
15
# File 'lib/dekiru/data_migration/operator.rb', line 13

def result
  @result
end

#started_atObject (readonly)

Returns the value of attribute started_at.



13
14
15
# File 'lib/dekiru/data_migration/operator.rb', line 13

def started_at
  @started_at
end

#streamObject (readonly)

Returns the value of attribute stream.



13
14
15
# File 'lib/dekiru/data_migration/operator.rb', line 13

def stream
  @stream
end

#titleObject (readonly)

Returns the value of attribute title.



13
14
15
# File 'lib/dekiru/data_migration/operator.rb', line 13

def title
  @title
end

Class Method Details

.execute(title, options = {}, &block) ⇒ Object



15
16
17
# File 'lib/dekiru/data_migration/operator.rb', line 15

def self.execute(title, options = {}, &block)
  new(title, options).execute(&block)
end

Instance Method Details

#durationObject



60
61
62
# File 'lib/dekiru/data_migration/operator.rb', line 60

def duration
  ((ended_at || Time.current) - started_at)
end

#each_with_progress(enum, options = {}) ⇒ Object

rubocop:disable Metrics/MethodLength



64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
# File 'lib/dekiru/data_migration/operator.rb', line 64

def each_with_progress(enum, options = {}) # rubocop:disable Metrics/MethodLength
  options = options.dup
  options[:total] ||= begin
    (enum.size == Float::INFINITY ? nil : enum.size)
  rescue StandardError
    nil
  end
  options[:format] ||= options[:total] ? "%a |%b>>%i| %p%% %t" : "%a |%b>>%i| ??%% %t"
  options[:output] = stream

  @pb = ::ProgressBar.create(options)
  enum.each do |item|
    yield item
    @pb.increment
  end
  @pb.finish
end

#execute(&block) ⇒ Object

rubocop:disable Metrics/AbcSize,Metrics/MethodLength



32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
# File 'lib/dekiru/data_migration/operator.rb', line 32

def execute(&block) # rubocop:disable Metrics/AbcSize,Metrics/MethodLength
  @started_at = Time.current
  log "Start: #{title} at #{started_at}\n\n"
  if @without_transaction
    run(&block)
    @result = true
  else
    raise NestedTransactionError if current_transaction_open?

    @result = transaction_provider.within_transaction do
      run(&block)
      log "Finished execution: #{title}"
      confirm?("\nAre you sure to commit?")
    end
  end
  log "Finished successfully: #{title}" if @result == true
rescue StandardError => e
  @error = e
  @result = false
ensure
  @ended_at = Time.current
  log "Total time: #{duration.round(2)} sec"

  raise error if error

  return @result # rubocop:disable Lint/EnsureReturn
end

#find_each_with_progress(target_scope, options = {}, &block) ⇒ Object



82
83
84
85
86
# File 'lib/dekiru/data_migration/operator.rb', line 82

def find_each_with_progress(target_scope, options = {}, &block)
  # `LocalJumpError: no block given (yield)` が出る場合、 find_each メソッドが enumerator を返していない可能性があります
  # 直接 each_with_progress を使うか、 find_each が enumerator を返すように修正してください
  each_with_progress(target_scope.find_each, options, &block)
end