module DbSchema

Constants

VERSION

Attributes

current_schema[R]

Public Class Methods

configuration() click to toggle source
# File lib/db_schema.rb, line 69
def configuration
  @configuration ||= Configuration.new
end
configure(params) click to toggle source
# File lib/db_schema.rb, line 50
def configure(params)
  @configuration = configuration.merge(params)
end
configure_from_yaml(yaml_path, environment, **other_options) click to toggle source
# File lib/db_schema.rb, line 54
def configure_from_yaml(yaml_path, environment, **other_options)
  data = Utils.symbolize_keys(YAML.load_file(yaml_path))
  filtered_data = Utils.filter_by_keys(
    data[environment.to_sym],
    *%i(adapter host port database username password)
  )
  renamed_data = Utils.rename_keys(filtered_data, username: :user)

  configure(renamed_data.merge(other_options))
end
connection=(external_connection) click to toggle source
# File lib/db_schema.rb, line 65
def connection=(external_connection)
  @external_connection = external_connection
end
describe(&block) click to toggle source
# File lib/db_schema.rb, line 23
def describe(&block)
  with_connection do |connection|
    desired = DSL.new(block)
    validate(desired.schema)
    Normalizer.new(desired.schema, connection).normalize_tables

    connection.transaction do
      actual_schema = run_migrations(desired.migrations, connection)
      changes = Changes.between(desired.schema, actual_schema)
      log_changes(changes) if configuration.log_changes?

      if configuration.dry_run?
        raise Sequel::Rollback
      else
        @current_schema = desired.schema
        return if changes.empty?
      end

      Runner.new(changes, connection).run!

      if configuration.post_check_enabled?
        perform_post_check(desired.schema, connection)
      end
    end
  end
end
reset!() click to toggle source
# File lib/db_schema.rb, line 73
def reset!
  @external_connection = nil
  @configuration = nil
  @current_schema = nil
end

Private Class Methods

log_changes(changes) click to toggle source
# File lib/db_schema.rb, line 136
def log_changes(changes)
  return if changes.empty?

  puts 'DbSchema is applying these changes to the database:'
  if changes.respond_to?(:ai)
    puts changes.ai
  else
    puts changes.inspect
  end
end
log_migration(migration) click to toggle source
# File lib/db_schema.rb, line 132
def log_migration(migration)
  puts "DbSchema is running migration #{migration.name.ai}"
end
perform_post_check(desired_schema, connection) click to toggle source
# File lib/db_schema.rb, line 147
    def perform_post_check(desired_schema, connection)
      unapplied_changes = Changes.between(desired_schema, Reader.reader_for(connection).read_schema)
      return if unapplied_changes.empty?

      readable_changes = if unapplied_changes.respond_to?(:ai)
        unapplied_changes.ai
      else
        unapplied_changes.inspect
      end

      message = <<-ERROR
Your database still differs from the expected schema after applying it; if you are 100% sure this is ok you can turn these checks off with DbSchema.configure(post_check: false). Here are the differences:

#{readable_changes}
      ERROR

      raise SchemaMismatch, message
    end
run_migrations(migrations, connection) click to toggle source
# File lib/db_schema.rb, line 116
def run_migrations(migrations, connection)
  @current_schema = Reader.reader_for(connection).read_schema

  migrations.reduce(@current_schema) do |schema, migration|
    migrator = Migrator.new(migration)

    if migrator.applicable?(schema)
      log_migration(migration) if configuration.log_changes?
      migrator.run!(connection)
      Reader.reader_for(connection).read_schema
    else
      schema
    end
  end
end
validate(schema) click to toggle source
# File lib/db_schema.rb, line 102
def validate(schema)
  validation_result = Validator.validate(schema)

  unless validation_result.valid?
    message = "Requested schema is invalid:\n\n"

    validation_result.errors.each do |error|
      message << "* #{error}\n"
    end

    raise InvalidSchemaError, message
  end
end
with_connection() { |external_connection| ... } click to toggle source
# File lib/db_schema.rb, line 80
def with_connection
  raise ArgumentError unless block_given?

  if @external_connection
    yield @external_connection
  else
    Sequel.connect(
      adapter:  configuration.adapter,
      host:     configuration.host,
      port:     configuration.port,
      database: configuration.database,
      user:     configuration.user,
      password: configuration.password
    ) do |db|
      db.extension :pg_enum
      db.extension :pg_array

      yield db
    end
  end
end