提交 aee310c1 编写于 作者: N Nick Burns

add option in database config for metadata table

    - adds the option `metadata_table` to a database connection
上级 4bbb1d4e
......@@ -111,6 +111,10 @@ def replica?
@config[:replica] || false
end
def use_metadata_table?
@config.fetch(:use_metadata_table, true)
end
# Determines whether writes are currently being prevents.
#
# Returns true if the connection is a replica, or if +prevent_writes+
......
......@@ -6,8 +6,15 @@
module ActiveRecord
# This class is used to create a table that keeps track of values and keys such
# as which environment migrations were run in.
#
# It is possible to enable or disable this functionality by setting the
# adapter configuration option `use_metadata_table` to false
class InternalMetadata < ActiveRecord::Base # :nodoc:
class << self
def enabled?
ActiveRecord::Base.connection.use_metadata_table?
end
def _internal?
true
end
......@@ -21,15 +28,21 @@ def table_name
end
def []=(key, value)
return unless enabled?
find_or_initialize_by(key: key).update!(value: value)
end
def [](key)
return unless enabled?
where(key: key).pluck(:value).first
end
# Creates an internal metadata table with columns +key+ and +value+
def create_table
return unless enabled?
unless table_exists?
key_options = connection.internal_string_options_for_primary_key
......@@ -42,6 +55,8 @@ def create_table
end
def drop_table
return unless enabled?
connection.drop_table table_name, if_exists: true
end
end
......
......@@ -190,6 +190,13 @@ def initialize(current: nil, stored: nil)
end
end
class EnvironmentStorageError < ActiveRecordError #:nodoc:
def initialize
msg = +"You are attempting to store the environment in a database where metadata is disabled.\n"
msg << "Check your database configuration to see if this is inteded."
end
end
# = Active Record Migrations
#
# Migrations can manage the evolution of a schema used by several physical
......@@ -1143,6 +1150,7 @@ def protected_environment?
end
def last_stored_environment
return nil unless ActiveRecord::InternalMetadata.enabled?
return nil if current_version == 0
raise NoEnvironmentInSchemaError unless ActiveRecord::InternalMetadata.table_exists?
......
......@@ -8,6 +8,7 @@ databases = ActiveRecord::Tasks::DatabaseTasks.setup_initial_database_yaml
db_namespace = namespace :db do
desc "Set the environment value for the database"
task "environment:set" => :load_config do
raise ActiveRecord::EnvironmentStorageError unless ActiveRecord::InternalMetadata.enabled?
ActiveRecord::InternalMetadata.create_table
ActiveRecord::InternalMetadata[:environment] = ActiveRecord::Base.connection.migration_context.current_environment
end
......
......@@ -348,7 +348,10 @@ def schema_up_to_date?(configuration, format = ActiveRecord::Base.schema_format,
return true unless File.exist?(file)
ActiveRecord::Base.establish_connection(db_config)
return false unless ActiveRecord::InternalMetadata.enabled?
return false unless ActiveRecord::InternalMetadata.table_exists?
ActiveRecord::InternalMetadata[:schema_sha1] == schema_sha1(file)
end
......
......@@ -640,6 +640,16 @@ def test_internal_metadata_stores_environment_when_other_data_exists
assert_equal "bar", ActiveRecord::InternalMetadata[:foo]
end
def test_internal_metadata_not_used_when_not_enabled
ActiveRecord::InternalMetadata.stub(:enabled?, false) do
migrations_path = MIGRATIONS_ROOT + "/valid"
migrator = ActiveRecord::MigrationContext.new(migrations_path, @schema_migration)
migrator.up
assert_not ActiveRecord::InternalMetadata[:environment]
end
end
def test_proper_table_name_on_migration
reminder_class = new_isolated_reminder_class
migration = ActiveRecord::Migration.new
......
......@@ -1258,6 +1258,16 @@ development:
Change the username and password in the `development` section as appropriate.
#### Configuring Metadata Storage
By default Rails will store information about your environment and schema in an internal table. If you do not want this table to be created, and are willing to give up the protections it provides (useful when working with a shared database and a database user that can not create tables).
```yaml
development:
adapter: postgresql
use_metadata_table: false
```
### Creating Rails Environments
By default Rails ships with three environments: "development", "test", and "production". While these are sufficient for most use cases, there are circumstances when you want more environments.
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册