Module: Lhm

Extended by:
Lhm, Throttler
Included in:
Lhm
Defined in:
lib/lhm.rb,
lib/lhm/table.rb,
lib/lhm/chunker.rb,
lib/lhm/command.rb,
lib/lhm/invoker.rb,
lib/lhm/printer.rb,
lib/lhm/version.rb,
lib/lhm/migrator.rb,
lib/lhm/entangler.rb,
lib/lhm/migration.rb,
lib/lhm/throttler.rb,
lib/lhm/connection.rb,
lib/lhm/sql_helper.rb,
lib/lhm/intersection.rb,
lib/lhm/throttler/time.rb,
lib/lhm/atomic_switcher.rb,
lib/lhm/locked_switcher.rb

Overview

Copyright © 2011 - 2013, SoundCloud Ltd., Rany Keddo, Tobias Bielohlawek, Tobias Schmidt

Defined Under Namespace

Modules: Command, Printer, SqlHelper, Throttler Classes: AtomicSwitcher, Chunker, Connection, Entangler, Error, Intersection, Invoker, LockedSwitcher, Migration, Migrator, Table

Constant Summary collapse

DEFAULT_LOGGER_OPTIONS =
{ level: Logger::INFO, file: STDOUT }
VERSION =
'2.2.0'

Constants included from Throttler

Throttler::CLASSES

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Throttler

setup_throttler, throttler

Class Method Details

.loggerObject



108
109
110
111
112
113
114
115
116
# File 'lib/lhm.rb', line 108

def self.logger
  @@logger ||=
    begin
      logger = Logger.new(DEFAULT_LOGGER_OPTIONS[:file])
      logger.level = DEFAULT_LOGGER_OPTIONS[:level]
      logger.formatter = nil
      logger
    end
end

.logger=(new_logger) ⇒ Object



104
105
106
# File 'lib/lhm.rb', line 104

def self.logger=(new_logger)
  @@logger = new_logger
end

Instance Method Details

#adapterObject



96
97
98
99
100
101
102
# File 'lib/lhm.rb', line 96

def adapter
  @@adapter ||=
    begin
      raise 'Please call Lhm.setup' unless defined?(ActiveRecord)
      ActiveRecord::Base.connection
    end
end

#change_table(table_name, options = {}) {|Migrator| ... } ⇒ Boolean

Alters a table with the changes described in the block

Parameters:

  • table_name (String, Symbol)

    Name of the table

  • options (Hash) (defaults to: {})

    Optional options to alter the chunk / switch behavior

Options Hash (options):

  • :stride (Fixnum)

    Size of a chunk (defaults to: 40,000)

  • :throttle (Fixnum)

    Time to wait between chunks in milliseconds (defaults to: 100)

  • :start (Fixnum)

    Primary Key position at which to start copying chunks

  • :limit (Fixnum)

    Primary Key position at which to stop copying chunks

  • :atomic_switch (Boolean)

    Use atomic switch to rename tables (defaults to: true) If using a version of mysql affected by atomic switch bug, LHM forces user to set this option (see SqlHelper#supports_atomic_switch?)

Yields:

  • (Migrator)

    Yielded Migrator object records the changes

Returns:

  • (Boolean)

    Returns true if the migration finishes

Raises:

  • (Error)

    Raises Lhm::Error in case of a error and aborts the migration



46
47
48
49
50
51
52
# File 'lib/lhm.rb', line 46

def change_table(table_name, options = {}, &block)
  origin = Table.parse(table_name, connection)
  invoker = Invoker.new(origin, connection)
  block.call(invoker.migrator)
  invoker.run(options)
  true
end

#cleanup(run = false, options = {}) ⇒ Object

Cleanup tables and triggers

Parameters:

  • run (Boolean) (defaults to: false)

    execute now or just display information

  • options (Hash) (defaults to: {})

    Optional options to alter cleanup behaviour

Options Hash (options):

  • :until (Time)

    Filter to only remove tables up to specified time (defaults to: nil)



60
61
62
63
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
89
90
# File 'lib/lhm.rb', line 60

def cleanup(run = false, options = {})
  lhm_tables = connection.select_values('show tables').select { |name| name =~ /^lhm(a|n)_/ }
  if options[:until]
    lhm_tables.select! { |table|
      table_date_time = Time.strptime(table, 'lhma_%Y_%m_%d_%H_%M_%S')
      table_date_time <= options[:until]
    }
  end

  lhm_triggers = connection.select_values('show triggers').collect do |trigger|
    trigger.respond_to?(:trigger) ? trigger.trigger : trigger
  end.select { |name| name =~ /^lhmt/ }

  if run
    lhm_triggers.each do |trigger|
      connection.execute("drop trigger if exists #{trigger}")
    end
    lhm_tables.each do |table|
      connection.execute("drop table if exists #{table}")
    end
    true
  elsif lhm_tables.empty? && lhm_triggers.empty?
    puts 'Everything is clean. Nothing to do.'
    true
  else
    puts "Existing LHM backup tables: #{lhm_tables.join(', ')}."
    puts "Existing LHM triggers: #{lhm_triggers.join(', ')}."
    puts 'Run Lhm.cleanup(true) to drop them all.'
    false
  end
end

#setup(adapter) ⇒ Object



92
93
94
# File 'lib/lhm.rb', line 92

def setup(adapter)
  @@adapter = adapter
end