Class: Cassanity::Migrator

Inherits:
Object
  • Object
show all
Defined in:
lib/cassanity/migrator.rb

Constant Summary collapse

SupportedDirections =
[:up, :down]

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(keyspace, migrations_path, options = {}) ⇒ Migrator

Returns a new instance of Migrator.



19
20
21
22
23
# File 'lib/cassanity/migrator.rb', line 19

def initialize(keyspace, migrations_path, options = {})
  @keyspace = keyspace
  @migrations_path = Pathname(migrations_path)
  @logger = options[:logger] || default_logger
end

Instance Attribute Details

#keyspaceObject (readonly)

Public: The keyspace all migrations apply to.



11
12
13
# File 'lib/cassanity/migrator.rb', line 11

def keyspace
  @keyspace
end

#loggerObject (readonly)

Public: Where to spit all the logging related to migrations.



17
18
19
# File 'lib/cassanity/migrator.rb', line 17

def logger
  @logger
end

#migrations_pathObject (readonly)

Public: The path to all the migrations.



14
15
16
# File 'lib/cassanity/migrator.rb', line 14

def migrations_path
  @migrations_path
end

Instance Method Details

#assert_valid_direction(direction) ⇒ Object



148
149
150
151
152
# File 'lib/cassanity/migrator.rb', line 148

def assert_valid_direction(direction)
  unless SupportedDirections.include?(direction)
    raise ArgumentError, "#{direction.inspect} is not a valid migration direction"
  end
end

#column_familyObject

Private: The column family storing all migration information.



123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
# File 'lib/cassanity/migrator.rb', line 123

def column_family
  @column_family ||= begin
    column_family = keyspace.column_family({
      name: :migrations,
      schema: {
        primary_key: [:version, :name],
        columns: {
          version: :text,
          name: :text,
          migrated_at: :timestamp,
        },
      },
    })
    column_family.create unless column_family.exists?
    column_family
  end
end

#default_loggerObject

Private



142
143
144
145
146
# File 'lib/cassanity/migrator.rb', line 142

def default_logger
  logger = Logger.new(STDOUT)
  logger.formatter = proc { |_, _, _, msg| "#{msg}\n" }
  logger
end

#log(message) ⇒ Object

Internal: Log a message.



96
97
98
# File 'lib/cassanity/migrator.rb', line 96

def log(message)
  @logger.info message
end

#migrateObject

Public: Runs all pending migrations in order.



26
27
28
# File 'lib/cassanity/migrator.rb', line 26

def migrate
  run_migrations pending_migrations, :up
end

#migrate_to(version, direction = :up) ⇒ Object

Public: Migrates to a version using a direction.

version - The String or Integer version to migrate to. direction - The String or Symbol direction you would like to migrate.



34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
# File 'lib/cassanity/migrator.rb', line 34

def migrate_to(version, direction = :up)
  version = version.to_i
  direction = direction.to_sym
  assert_valid_direction(direction)

  migrations = case direction
  when :up
    pending_migrations.select { |migration| migration.version <= version }
  when :down
    performed_migrations.select { |migration| migration.version > version }
  else
    []
  end

  run_migrations migrations, direction
end

#migrated_down(migration) ⇒ Object

Public: Marks a migration as not run.



63
64
65
66
67
68
69
70
# File 'lib/cassanity/migrator.rb', line 63

def migrated_down(migration)
  column_family.delete({
    where: {
      version: migration.version.to_s,
      name: migration.name,
    },
  })
end

#migrated_up(migration) ⇒ Object

Public: Marks a migration as migrated.



52
53
54
55
56
57
58
59
60
# File 'lib/cassanity/migrator.rb', line 52

def migrated_up(migration)
  column_family.insert({
    data: {
      version: migration.version.to_s,
      name: migration.name,
      migrated_at: Time.now.utc,
    },
  })
end

#migrationsObject

Public: An array of all migrations.



73
74
75
76
77
78
79
# File 'lib/cassanity/migrator.rb', line 73

def migrations
  @migrations ||= begin
    paths = Dir["#{migrations_path}/*.rb"]
    migrations = paths.map { |path| MigrationProxy.new(path) }
    migrations.sort
  end
end

#pending_migrationsObject

Public: An array of the migrations that have not been performed.



91
92
93
# File 'lib/cassanity/migrator.rb', line 91

def pending_migrations
  (migrations - performed_migrations).sort
end

#performed_migrationsObject

Public: An array of the migrations that have been performed.



82
83
84
85
86
87
88
# File 'lib/cassanity/migrator.rb', line 82

def performed_migrations
  rows = column_family.select
  rows.map { |row|
    path = migrations_path.join("#{row['version']}_#{row['name']}.rb")
    MigrationProxy.new(path)
  }.sort
end

#run_migrations(migrations, direction) ⇒ Object

Private



101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
# File 'lib/cassanity/migrator.rb', line 101

def run_migrations(migrations, direction)
  migrations = migrations.sort

  case direction
  when :up
    migrations.each do |migration|
      migration.up(self)
      migrated_up(migration)
    end
  when :down
    migrations = migrations.reverse
    migrations.each do |migration|
      migration.down(self)
      migrated_down(migration)
    end
  end

  {performed: migrations}
end