Class: Exodus::Migration

Inherits:
Object
  • Object
show all
Extended by:
TextFormatter
Includes:
MongoMapper::Document
Defined in:
lib/exodus/migrations/migration.rb

Constant Summary collapse

UP =
'up'
DOWN =
'down'

Class Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from TextFormatter

super_print

Constructor Details

#initialize(args = {}) ⇒ Migration

Makes sure status get instanciated on migration’s instanciation



107
108
109
110
# File 'lib/exodus/migrations/migration.rb', line 107

def initialize(args = {})
  self.build_status(args[:status])
  super(args)
end

Class Attribute Details

.migration_numberObject

Returns the value of attribute migration_number.



19
20
21
# File 'lib/exodus/migrations/migration.rb', line 19

def migration_number
  @migration_number
end

Class Method Details

.db_statusObject

Prints in the console all migrations that has been ran at least once with their name and description



83
84
85
86
87
88
89
90
91
# File 'lib/exodus/migrations/migration.rb', line 83

def db_status
  status_info = [["Migration n#:", "Name:", "Direction:", "Current Status:", "Arguments:", "Last completion Date:", "Current Message:"]]

  status_info |= Migration.all.map do|migration|
    [migration.class.migration_number, migration.class.name, *migration.status.to_a_string]
  end

  super_print(status_info)
end

.format(migration, args = {}) ⇒ Object

Formats a given migration making sure the first argument is a class and the second one -if it exists- is a none empty hash



66
67
68
69
# File 'lib/exodus/migrations/migration.rb', line 66

def format(migration, args = {})
  migration_klass = migration.is_a?(String) ? migration.constantize : migration
  args.is_a?(Hash) && args.empty? ? [migration_klass] : [migration_klass, args]
end

.inherited(klass) ⇒ Object

Overides #inherited to have an easy and reliable way to find all migrations Migrations need to have embedded callbacks on depending on the MM’s version



23
24
25
26
27
28
# File 'lib/exodus/migrations/migration.rb', line 23

def inherited(klass)
  klass.embedded_callbacks_on if defined?(MongoMapper::Plugins::EmbeddedCallbacks::ClassMethods) #MongoMapper version compatibility
  klass.migration_number = 0
  @migrations << [klass]
  super(klass)
end

.listObject

Prints in the console all migrations class with their name and description



72
73
74
75
76
77
78
79
80
# File 'lib/exodus/migrations/migration.rb', line 72

def list
  last_info = [["Migration n#:", "Name:", "Description:"]]

  last_info |= Migration.sort_all.map do|migration, args|
    [migration.migration_number, migration.name, migration.new.description]
  end

  super_print(last_info, 70)
end

.load_all(migrations) ⇒ Object

Using a list of migrations Formats and overrides migrations without arguments using ones that have given arguments Removes duplicates migrations: list of migrations => [[MyMigration, => ‘some_args’]]



39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
# File 'lib/exodus/migrations/migration.rb', line 39

def load_all(migrations)
  if migrations
    migrations.each do |migration, args|
      if migration
        formated_migration = format(migration, args || {})
        migration, args = formated_migration

        unless @migrations.include?(formated_migration)
          @migrations.delete_if {|loaded_migration, loaded_args| migration == loaded_migration && (loaded_args.nil? || loaded_args.empty?) }
          @migrations << formated_migration
        end
      end
    end 
  end

  @migrations
end

.load_custom(migrations) ⇒ Object

Using a list of migrations formats them and removes duplicates migrations: list of migrations => [[MyMigration, => ‘some_args’]]



59
60
61
62
# File 'lib/exodus/migrations/migration.rb', line 59

def load_custom(migrations)
  migrations ||= []
  migrations.map {|migration_str, args| format(migration_str, args) }.uniq
end

.rerunnable_safe=(safe) ⇒ Object



93
94
95
96
97
98
99
# File 'lib/exodus/migrations/migration.rb', line 93

def rerunnable_safe=(safe)
  migrations = Migration.instance_variable_get("@migrations")
  deletion = migrations.delete([self])
  Migration.instance_variable_set("@migrations", migrations) if deletion

  @rerunnable_safe = safe
end

.rerunnable_safe?Boolean

Returns:

  • (Boolean)


101
102
103
# File 'lib/exodus/migrations/migration.rb', line 101

def rerunnable_safe?
  @rerunnable_safe == true
end

.sort_allObject

Sorts all migrations by migration number



31
32
33
# File 'lib/exodus/migrations/migration.rb', line 31

def sort_all
  @migrations.sort_by {|migration,args| migration.migration_number }
end

Instance Method Details

#characteristicObject



145
146
147
# File 'lib/exodus/migrations/migration.rb', line 145

def characteristic
  "#{self.class}: #{self.status.arguments}"
end

#completed?(direction) ⇒ Boolean

Checks if a migration as been completed

Returns:

  • (Boolean)


139
140
141
142
143
# File 'lib/exodus/migrations/migration.rb', line 139

def completed?(direction) 
  return false if self.status.execution_time == 0
  (direction == UP && self.status.current_status == self.status_complete) || 
  (direction == DOWN && self.status.current_status == 0)
end

#eql?(other_migration) ⇒ Boolean

Returns:

  • (Boolean)


149
150
151
# File 'lib/exodus/migrations/migration.rb', line 149

def eql?(other_migration)
  self.class == other_migration.class && self.status.arguments == other_migration.status.arguments
end

#failure=(exception) ⇒ Object

Sets an error to migration status



124
125
126
127
128
129
# File 'lib/exodus/migrations/migration.rb', line 124

def failure=(exception)
  self.status.error = MigrationError.new(
    :error_message => exception.message, 
    :error_class => exception.class, 
    :error_backtrace => exception.backtrace)
end

#hashObject



153
154
155
# File 'lib/exodus/migrations/migration.rb', line 153

def hash
  self.class.hash ^ self.status.arguments.hash
end

#is_runnable?(direction) ⇒ Boolean

Checks if a migration can be run

Returns:

  • (Boolean)


132
133
134
135
136
# File 'lib/exodus/migrations/migration.rb', line 132

def is_runnable?(direction)
  self.class.rerunnable_safe? || 
  (direction == UP && status.current_status < status_complete) || 
  (direction == DOWN && status.current_status > 0)
end

#run(direction) ⇒ Object

Runs the migration following the direction sets the status, the execution time and the last succesful_completion date



114
115
116
117
118
119
120
121
# File 'lib/exodus/migrations/migration.rb', line 114

def run(direction)
  self.status.direction = direction

  # reset the status if the job is rerunnable and has already be completed
  self.status.reset! if self.class.rerunnable_safe? && completed?(direction) 
  self.status.execution_time = time_it { self.send(direction) }
  self.status.last_succesful_completion = Time.now
end