Class: Edgestitch::Mysql::Dump

Inherits:
Object
  • Object
show all
Defined in:
lib/edgestitch/mysql/dump.rb

Overview

Wrapper for the mysqldump tool to dump specific tables and migration data

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(config) ⇒ Dump

Returns a new instance of Dump.

Parameters:

  • config (ActiveRecord::DatabaseConfigurations::DatabaseConfig)

    rails database configuration



54
55
56
57
58
59
60
61
62
63
# File 'lib/edgestitch/mysql/dump.rb', line 54

def initialize(config)
  hash = config.respond_to?(:configuration_hash) ? config.configuration_hash : config.config
  @database = hash["database"] || hash[:database]
  @config = {
    "-h" => hash["host"] || hash[:host],
    "-u" => hash["username"] || hash[:username],
    "-p" => hash["password"] || hash[:password],
    "--port=" => hash["port"] || hash[:port],
  }
end

Class Method Details

.sanitize_create_table(sql) ⇒ Object

Sanitizes a DDL code with some opinionated preferences:

  • Constraints starting with ‘_fk` will start with `fk`

  • Clear empty lines (with empty spaces even)

  • Reorder constraints (@see Edgestitch::Mysql::StructureConstraintOrderMunger)

Parameters:

  • sql (String)

    the DDL code to sanitize

Returns:

  • String the same DDL sanitized



23
24
25
26
27
28
29
30
31
32
# File 'lib/edgestitch/mysql/dump.rb', line 23

def self.sanitize_create_table(sql)
  comment_instructions_regex = %r{^/\*![0-9]{5}\s+[^;]+;\s*$}

  cleanups = sql.gsub(/\s+AUTO_INCREMENT=\d+/, "")
                .gsub(/CONSTRAINT `_+fk_/, "CONSTRAINT `fk_")
                .gsub(comment_instructions_regex, "")
                .gsub(/\n\s*\n\s*\n/, "\n\n")
                .strip
  ::Edgestitch::Mysql::StructureConstraintOrderMunger.munge(cleanups)
end

.sanitize_migration_timestamps(sql) ⇒ Object

Sanitizes a DML code to insert migration timestamps with opinionated preferences:

  • One timestamp per line

  • Except for the first line, they all start with a comma

  • Semicolomn is in a separate line from the last one

The above preferences come from the idea of minimizing merge conflicts, or make them easily handled by git automatically

Parameters:

  • sql (String)

    the DML code to sanitize

Returns:

  • String the same DML sanitized



46
47
48
49
50
# File 'lib/edgestitch/mysql/dump.rb', line 46

def self.sanitize_migration_timestamps(sql)
  sql.gsub("VALUES ", "VALUES\n")
     .gsub(",", "\n,")
     .gsub(";", "\n;")
end

Instance Method Details

#export_migrations(migrations) ⇒ Object

Exports INSERT statements for the given migration names.

The INSERT statements are in groups of 50 migrations per multi-insert statement.

Notice: this does not export the creation of the schema_migrations table.

Parameters:

  • migrations (Array<Integer,String>)

    migration ids/timestamps

Returns:

  • String the INSERT statements.



86
87
88
89
90
91
92
93
94
95
# File 'lib/edgestitch/mysql/dump.rb', line 86

def export_migrations(migrations)
  migrations.in_groups_of(50, false).map do |versions|
    self.class.sanitize_migration_timestamps execute(
      "--compact", "--skip-lock-tables", "--set-gtid-purged=OFF",
      "--no-create-info", "--column-statistics=0",
      "schema_migrations",
      "-w", "version IN (#{versions.join(',')})"
    )
  end.join
end

#export_tables(tables) ⇒ Object

Exports DDL for the given tables in a mysql compatible way

Parameters:

  • tables (Array<String>)

    table names

Returns:

  • String the DDL for the given tables



69
70
71
72
73
74
75
76
# File 'lib/edgestitch/mysql/dump.rb', line 69

def export_tables(tables)
  return if tables.empty?

  self.class.sanitize_create_table(
    execute("--compact", "--skip-lock-tables", "--no-data", "--set-gtid-purged=OFF",
            "--column-statistics=0", *tables)
  )
end