Class: Tina4::Migration

Inherits:
Object
  • Object
show all
Defined in:
lib/tina4/migration.rb

Constant Summary collapse

TRACKING_TABLE =
"tina4_migration"

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(db, migrations_dir: nil) ⇒ Migration

Returns a new instance of Migration.



10
11
12
13
14
# File 'lib/tina4/migration.rb', line 10

def initialize(db, migrations_dir: nil)
  @db = db
  @migrations_dir = migrations_dir || resolve_migrations_dir
  ensure_tracking_table
end

Instance Attribute Details

#dbObject (readonly)

Returns the value of attribute db.



8
9
10
# File 'lib/tina4/migration.rb', line 8

def db
  @db
end

#migrations_dirObject (readonly)

Returns the value of attribute migrations_dir.



8
9
10
# File 'lib/tina4/migration.rb', line 8

def migrations_dir
  @migrations_dir
end

Instance Method Details

#create(name) ⇒ Object

Create a new migration file



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
# File 'lib/tina4/migration.rb', line 64

def create(name)
  FileUtils.mkdir_p(@migrations_dir)
  timestamp = Time.now.strftime("%Y%m%d%H%M%S")
  filename = "#{timestamp}_#{name.gsub(/\s+/, '_')}.rb"
  filepath = File.join(@migrations_dir, filename)

  File.write(filepath, <<~RUBY)
    # frozen_string_literal: true
    # Migration: #{name}
    # Created: #{Time.now}

    class #{classify(name)} < Tina4::MigrationBase
      def up(db)
        # db.exec("CREATE TABLE ...")
      end

      def down(db)
        # db.exec("DROP TABLE IF EXISTS ...")
      end
    end
  RUBY

  Tina4::Log.info("Created migration: #{filename}")
  filepath
end

#get_appliedObject

Get list of applied migration records (public alias for completed_migrations)



91
92
93
# File 'lib/tina4/migration.rb', line 91

def get_applied
  completed_migrations
end

#get_filesObject

Get all migration files on disk, excluding .down files



101
102
103
104
105
# File 'lib/tina4/migration.rb', line 101

def get_files
  migration_files = Dir.glob(File.join(@migrations_dir, "*.sql")).reject { |f| f.end_with?(".down.sql") }
  migration_files += Dir.glob(File.join(@migrations_dir, "*.rb"))
  migration_files.map { |f| File.basename(f) }.sort
end

#get_pendingObject

Get list of pending migration filenames (public alias for pending_migrations)



96
97
98
# File 'lib/tina4/migration.rb', line 96

def get_pending
  pending_migrations.map { |f| File.basename(f) }
end

#migrateObject Also known as: run

Run all pending migrations



17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
# File 'lib/tina4/migration.rb', line 17

def migrate
  pending = pending_migrations
  if pending.empty?
    Tina4::Log.info("No pending migrations")
    return []
  end

  batch = next_batch_number
  results = []
  pending.each do |file|
    result = run_migration(file, batch)
    results << result
    # Stop on failure
    break if result[:status] == "failed"
  end
  results
end

#rollback(steps = 1) ⇒ Object

Rollback last batch (or N steps)



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

def rollback(steps = 1)
  completed = completed_migrations_with_batch
  return [] if completed.empty?

  # Get the last N unique batches
  batches = completed.map { |m| m[:batch] }.uniq.sort.reverse
  batches_to_rollback = batches.first(steps)

  results = []
  completed.select { |m| batches_to_rollback.include?(m[:batch]) }
           .sort_by { |m| -m[:id] }
           .each do |migration|
    result = rollback_migration(migration[:migration_name])
    results << result
  end
  results
end

#statusObject



56
57
58
59
60
61
# File 'lib/tina4/migration.rb', line 56

def status
  {
    completed: completed_migrations,
    pending: pending_migrations.map { |f| File.basename(f) }
  }
end