123456789_123456789_123456789_123456789_123456789_

Class: ActiveRecord::InternalMetadata

Do not use. This class is for internal use only.
Relationships & Source Files
Namespace Children
Classes:
Inherits: Object
Defined in: activerecord/lib/active_record/internal_metadata.rb

Overview

This class is used to create a table that keeps track of values and keys such as which environment migrations were run in.

This is enabled by default. To disable this functionality set use_metadata_table to false in your database configuration.

Class Method Summary

Instance Attribute Summary

Instance Method Summary

Constructor Details

.new(connection) ⇒ InternalMetadata

[ GitHub ]

  
# File 'activerecord/lib/active_record/internal_metadata.rb', line 18

def initialize(connection)
  @connection = connection
  @arel_table = Arel::Table.new(table_name)
end

Instance Attribute Details

#arel_table (readonly)

[ GitHub ]

  
# File 'activerecord/lib/active_record/internal_metadata.rb', line 16

attr_reader :connection, :arel_table

#connection (readonly)

[ GitHub ]

  
# File 'activerecord/lib/active_record/internal_metadata.rb', line 16

attr_reader :connection, :arel_table

#enabled?Boolean (readonly)

[ GitHub ]

  
# File 'activerecord/lib/active_record/internal_metadata.rb', line 23

def enabled?
  connection.
end

#table_exists?Boolean (readonly)

[ GitHub ]

  
# File 'activerecord/lib/active_record/internal_metadata.rb', line 93

def table_exists?
  connection.schema_cache.data_source_exists?(table_name)
end

Instance Method Details

#[](key)

[ GitHub ]

  
# File 'activerecord/lib/active_record/internal_metadata.rb', line 45

def [](key)
  return unless enabled?

  if entry = select_entry(key)
    entry[value_key]
  end
end

#[]=(key, value)

[ GitHub ]

  
# File 'activerecord/lib/active_record/internal_metadata.rb', line 39

def []=(key, value)
  return unless enabled?

  update_or_create_entry(key, value)
end

#count

[ GitHub ]

  
# File 'activerecord/lib/active_record/internal_metadata.rb', line 59

def count
  sm = Arel::SelectManager.new(arel_table)
  sm.project(*Arel::Nodes::Count.new([Arel.star]))

  connection.select_values(sm, "#{self.class} Count").first
end

#create_entry(key, value) (private)

[ GitHub ]

  
# File 'activerecord/lib/active_record/internal_metadata.rb', line 116

def create_entry(key, value)
  im = Arel::InsertManager.new(arel_table)
  im.insert [
    [arel_table[primary_key], key],
    [arel_table[value_key], value],
    [arel_table[:created_at], current_time],
    [arel_table[:updated_at], current_time]
  ]

  connection.insert(im, "#{self.class} Create", primary_key, key)
end

#create_table

Creates an internal metadata table with columns key and value

[ GitHub ]

  
# File 'activerecord/lib/active_record/internal_metadata.rb', line 75

def create_table
  return unless enabled?

  unless connection.table_exists?(table_name)
    connection.create_table(table_name, id: false) do |t|
      t.string :key, **connection.internal_string_options_for_primary_key
      t.string :value
      t.timestamps
    end
  end
end

#create_table_and_set_flags(environment, schema_sha1 = nil)

[ GitHub ]

  
# File 'activerecord/lib/active_record/internal_metadata.rb', line 66

def create_table_and_set_flags(environment, schema_sha1 = nil)
  return unless enabled?

  create_table
  update_or_create_entry(:environment, environment)
  update_or_create_entry(:schema_sha1, schema_sha1) if schema_sha1
end

#current_time (private)

[ GitHub ]

  
# File 'activerecord/lib/active_record/internal_metadata.rb', line 112

def current_time
  connection.default_timezone == :utc ? Time.now.utc : Time.now
end

#delete_all_entries

[ GitHub ]

  
# File 'activerecord/lib/active_record/internal_metadata.rb', line 53

def delete_all_entries
  dm = Arel::DeleteManager.new(arel_table)

  connection.delete(dm, "#{self.class} Destroy")
end

#drop_table

[ GitHub ]

  
# File 'activerecord/lib/active_record/internal_metadata.rb', line 87

def drop_table
  return unless enabled?

  connection.drop_table table_name, if_exists: true
end

#primary_key

[ GitHub ]

  
# File 'activerecord/lib/active_record/internal_metadata.rb', line 27

def primary_key
  "key"
end

#select_entry(key) (private)

[ GitHub ]

  
# File 'activerecord/lib/active_record/internal_metadata.rb', line 140

def select_entry(key)
  sm = Arel::SelectManager.new(arel_table)
  sm.project(Arel::Nodes::SqlLiteral.new("*"))
  sm.where(arel_table[primary_key].eq(Arel::Nodes::BindParam.new(key)))
  sm.order(arel_table[primary_key].asc)
  sm.limit = 1

  connection.select_all(sm, "#{self.class} Load").first
end

#table_name

[ GitHub ]

  
# File 'activerecord/lib/active_record/internal_metadata.rb', line 35

def table_name
  "#{ActiveRecord::Base.table_name_prefix}#{ActiveRecord::Base.}#{ActiveRecord::Base.table_name_suffix}"
end

#update_entry(key, new_value) (private)

[ GitHub ]

  
# File 'activerecord/lib/active_record/internal_metadata.rb', line 128

def update_entry(key, new_value)
  um = Arel::UpdateManager.new(arel_table)
  um.set [
    [arel_table[value_key], new_value],
    [arel_table[:updated_at], current_time]
  ]

  um.where(arel_table[primary_key].eq(key))

  connection.update(um, "#{self.class} Update")
end

#update_or_create_entry(key, value) (private)

[ GitHub ]

  
# File 'activerecord/lib/active_record/internal_metadata.rb', line 98

def update_or_create_entry(key, value)
  entry = select_entry(key)

  if entry
    if entry[value_key] != value
      update_entry(key, value)
    else
      entry[value_key]
    end
  else
    create_entry(key, value)
  end
end

#value_key

[ GitHub ]

  
# File 'activerecord/lib/active_record/internal_metadata.rb', line 31

def value_key
  "value"
end