跳到内容 跳到搜索
方法
C
D
E
F
I
N
Q
R
S
包含的模块

常量

CR_SERVER_GONE_ERROR = 2006
 
CR_SERVER_LOST = 2013
 
EMULATE_BOOLEANS_TRUE = { emulate_booleans: true }.freeze
 
ER_CANNOT_ADD_FOREIGN = 1215
 
ER_CANNOT_CREATE_TABLE = 1005
 
ER_CLIENT_INTERACTION_TIMEOUT = 4031
 
ER_CONNECTION_KILLED = 1927
 
ER_DATA_TOO_LONG = 1406
 
ER_DB_CREATE_EXISTS = 1007
 

参见 dev.mysql.com/doc/mysql-errors/en/server-error-reference.html

ER_DO_NOT_HAVE_DEFAULT = 1364
 
ER_DUP_ENTRY = 1062
 
ER_FILSORT_ABORT = 1028
 
ER_FK_INCOMPATIBLE_COLUMNS = 3780
 
ER_LOCK_DEADLOCK = 1213
 
ER_LOCK_WAIT_TIMEOUT = 1205
 
ER_NOT_NULL_VIOLATION = 1048
 
ER_NO_REFERENCED_ROW = 1216
 
ER_NO_REFERENCED_ROW_2 = 1452
 
ER_OUT_OF_RANGE = 1264
 
ER_QUERY_INTERRUPTED = 1317
 
ER_QUERY_TIMEOUT = 3024
 
ER_ROW_IS_REFERENCED = 1217
 
ER_ROW_IS_REFERENCED_2 = 1451
 
ER_SERVER_SHUTDOWN = 1053
 
EXTENDED_TYPE_MAPS = Concurrent::Map.new
 
NATIVE_DATABASE_TYPES = { primary_key: "bigint auto_increment PRIMARY KEY", string: { name: "varchar", limit: 255 }, text: { name: "text" }, integer: { name: "int", limit: 4 }, bigint: { name: "bigint" }, float: { name: "float", limit: 24 }, decimal: { name: "decimal" }, datetime: { name: "datetime" }, timestamp: { name: "timestamp" }, time: { name: "time" }, date: { name: "date" }, binary: { name: "blob" }, blob: { name: "blob" }, boolean: { name: "tinyint", limit: 1 }, json: { name: "json" }, }
 

类公共方法

dbconsole(config, options = {})

# File activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb, line 57
def dbconsole(config, options = {})
  mysql_config = config.configuration_hash

  args = {
    host: "--host",
    port: "--port",
    socket: "--socket",
    username: "--user",
    encoding: "--default-character-set",
    sslca: "--ssl-ca",
    sslcert: "--ssl-cert",
    sslcapath: "--ssl-capath",
    sslcipher: "--ssl-cipher",
    sslkey: "--ssl-key",
    ssl_mode: "--ssl-mode"
  }.filter_map { |opt, arg| "#{arg}=#{mysql_config[opt]}" if mysql_config[opt] }

  if mysql_config[:password] && options[:include_password]
    args << "--password=#{mysql_config[:password]}"
  elsif mysql_config[:password] && !mysql_config[:password].to_s.empty?
    args << "-p"
  end

  args << config.database

  find_cmd_and_exec(ActiveRecord.database_cli[:mysql], *args)
end

emulate_booleans

默认情况下,Mysql2Adapter 将考虑所有类型为 tinyint(1) 的列为布尔值。如果您希望禁用此模拟,您可以将以下行添加到您的 application.rb 文件中

ActiveRecord::ConnectionAdapters::Mysql2Adapter.emulate_booleans = false
# File activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb, line 29
class_attribute :emulate_booleans, default: true

实例公共方法

charset()

返回数据库字符集。

# File activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb, line 297
def charset
  show_variable "character_set_database"
end

check_constraints(table_name)

# File activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb, line 502
      def check_constraints(table_name)
        if supports_check_constraints?
          scope = quoted_scope(table_name)

          sql = <<~SQL
            SELECT cc.constraint_name AS 'name',
                  cc.check_clause AS 'expression'
            FROM information_schema.check_constraints cc
            JOIN information_schema.table_constraints tc
            USING (constraint_schema, constraint_name)
            WHERE tc.table_schema = #{scope[:schema]}
              AND tc.table_name = #{scope[:name]}
              AND cc.constraint_schema = #{scope[:schema]}
          SQL
          sql += " AND cc.table_name = #{scope[:name]}" if mariadb?

          chk_info = internal_exec_query(sql, "SCHEMA")

          chk_info.map do |row|
            options = {
              name: row["name"]
            }
            expression = row["expression"]
            expression = expression[1..-2] if expression.start_with?("(") && expression.end_with?(")")
            expression = strip_whitespace_characters(expression)

            unless mariadb?
              # MySQL returns check constraints expression in an already escaped form.
              # This leads to duplicate escaping later (e.g. when the expression is used in the SchemaDumper).
              expression = expression.gsub("\\'", "'")
            end

            CheckConstraintDefinition.new(table_name, expression, options)
          end
        else
          raise NotImplementedError
        end
      end

collation()

返回数据库排序规则策略。

# File activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb, line 302
def collation
  show_variable "collation_database"
end

create_database(name, options = {})

创建一个新的 MySQL 数据库,带有可选的 :charset:collation。字符集默认为 utf8mb4。

示例

create_database 'charset_test', charset: 'latin1', collation: 'latin1_bin'
create_database 'matt_development'
create_database 'matt_development', charset: :big5
# File activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb, line 272
def create_database(name, options = {})
  if options[:collation]
    execute "CREATE DATABASE #{quote_table_name(name)} DEFAULT COLLATE #{quote_table_name(options[:collation])}"
  elsif options[:charset]
    execute "CREATE DATABASE #{quote_table_name(name)} DEFAULT CHARACTER SET #{quote_table_name(options[:charset])}"
  elsif row_format_dynamic_by_default?
    execute "CREATE DATABASE #{quote_table_name(name)} DEFAULT CHARACTER SET `utf8mb4`"
  else
    raise "Configure a supported :charset and ensure innodb_large_prefix is enabled to support indexes on varchar(255) string columns."
  end
end

current_database()

# File activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb, line 292
def current_database
  query_value("SELECT database()", "SCHEMA")
end

drop_table(*table_names, **options)

从数据库中删除一个或多个表。

:force

设置为 :cascade 以删除依赖对象。默认为 false。

:if_exists

设置为 true 仅在表存在时才删除它。默认为 false。

:temporary

设置为 true 以删除临时表。默认为 false。

虽然此命令忽略了大多数 options 以及是否提供了一个块,但将其提供给迁移的 change 方法可能会有帮助,以便它可以被还原。在这种情况下,options 以及块将被 create_table 使用,除非你提供了多个不支持的表。

# File activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb, line 350
def drop_table(*table_names, **options)
  table_names.each { |table_name| schema_cache.clear_data_source_cache!(table_name.to_s) }
  execute "DROP#{' TEMPORARY' if options[:temporary]} TABLE#{' IF EXISTS' if options[:if_exists]} #{table_names.map { |table_name| quote_table_name(table_name) }.join(', ')}#{' CASCADE' if options[:force] == :cascade}"
end

foreign_keys(table_name)

# File activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb, line 457
      def foreign_keys(table_name)
        raise ArgumentError unless table_name.present?

        scope = quoted_scope(table_name)

        # MySQL returns 1 row for each column of composite foreign keys.
        fk_info = internal_exec_query(<<~SQL, "SCHEMA")
          SELECT fk.referenced_table_name AS 'to_table',
                 fk.referenced_column_name AS 'primary_key',
                 fk.column_name AS 'column',
                 fk.constraint_name AS 'name',
                 fk.ordinal_position AS 'position',
                 rc.update_rule AS 'on_update',
                 rc.delete_rule AS 'on_delete'
          FROM information_schema.referential_constraints rc
          JOIN information_schema.key_column_usage fk
          USING (constraint_schema, constraint_name)
          WHERE fk.referenced_column_name IS NOT NULL
            AND fk.table_schema = #{scope[:schema]}
            AND fk.table_name = #{scope[:name]}
            AND rc.constraint_schema = #{scope[:schema]}
            AND rc.table_name = #{scope[:name]}
        SQL

        grouped_fk = fk_info.group_by { |row| row["name"] }.values.each { |group| group.sort_by! { |row| row["position"] } }
        grouped_fk.map do |group|
          row = group.first
          options = {
            name: row["name"],
            on_update: extract_foreign_key_action(row["on_update"]),
            on_delete: extract_foreign_key_action(row["on_delete"])
          }

          if group.one?
            options[:column] = unquote_identifier(row["column"])
            options[:primary_key] = row["primary_key"]
          else
            options[:column] = group.map { |row| unquote_identifier(row["column"]) }
            options[:primary_key] = group.map { |row| row["primary_key"] }
          end

          ForeignKeyDefinition.new(table_name, unquote_identifier(row["to_table"]), options)
        end
      end

index_algorithms()

# File activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb, line 189
def index_algorithms
  {
    default: "ALGORITHM = DEFAULT",
    copy:    "ALGORITHM = COPY",
    inplace: "ALGORITHM = INPLACE",
    instant: "ALGORITHM = INSTANT",
  }
end

native_database_types()

# File activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb, line 185
def native_database_types
  NATIVE_DATABASE_TYPES
end

quote_string(string)

将字符串引用以供 SQL 输入使用。

# File activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb, line 685
def quote_string(string)
  with_raw_connection(allow_retry: true, materialize_transactions: false) do |connection|
    connection.escape(string)
  end
end

recreate_database(name, options = {})

删除在 name 属性上指定的数据库,并使用提供的 options 重新创建它。

# File activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb, line 258
def recreate_database(name, options = {})
  drop_database(name)
  sql = create_database(name, options)
  reconnect!
  sql
end

rename_index(table_name, old_name, new_name)

# File activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb, line 355
def rename_index(table_name, old_name, new_name)
  if supports_rename_index?
    validate_index_length!(table_name, new_name)

    execute "ALTER TABLE #{quote_table_name(table_name)} RENAME INDEX #{quote_table_name(old_name)} TO #{quote_table_name(new_name)}"
  else
    super
  end
end

rename_table(table_name, new_name, **options)

重命名一个表。

示例

rename_table('octopuses', 'octopi')
# File activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb, line 327
def rename_table(table_name, new_name, **options)
  validate_table_length!(new_name) unless options[:_uses_legacy_table_name]
  schema_cache.clear_data_source_cache!(table_name.to_s)
  schema_cache.clear_data_source_cache!(new_name.to_s)
  execute "RENAME TABLE #{quote_table_name(table_name)} TO #{quote_table_name(new_name)}"
  rename_table_indexes(table_name, new_name, **options)
end

show_variable(name)

SHOW VARIABLES LIKE ‘name’

# File activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb, line 571
def show_variable(name)
  query_value("SELECT @@#{name}", "SCHEMA", materialize_transactions: false, allow_retry: true)
rescue ActiveRecord::StatementInvalid
  nil
end

strict_mode?()

# File activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb, line 622
def strict_mode?
  self.class.type_cast_config_to_boolean(@config.fetch(:strict, true))
end

supports_advisory_locks?()

# File activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb, line 161
def supports_advisory_locks?
  true
end

supports_bulk_alter?()

# File activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb, line 96
def supports_bulk_alter?
  true
end

supports_check_constraints?()

# File activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb, line 128
def supports_check_constraints?
  if mariadb?
    database_version >= "10.3.10" || (database_version < "10.3" && database_version >= "10.2.22")
  else
    database_version >= "8.0.16"
  end
end

supports_common_table_expressions?()

# File activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb, line 153
def supports_common_table_expressions?
  if mariadb?
    database_version >= "10.2.1"
  else
    database_version >= "8.0.1"
  end
end

supports_datetime_with_precision?()

# File activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb, line 140
def supports_datetime_with_precision?
  true
end

supports_explain?()

# File activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb, line 116
def supports_explain?
  true
end

supports_expression_index?()

# File activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb, line 104
def supports_expression_index?
  !mariadb? && database_version >= "8.0.13"
end

supports_foreign_keys?()

# File activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb, line 124
def supports_foreign_keys?
  true
end

supports_index_sort_order?()

# File activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb, line 100
def supports_index_sort_order?
  mariadb? ? database_version >= "10.8.1" : database_version >= "8.0.1"
end

supports_indexes_in_create?()

# File activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb, line 120
def supports_indexes_in_create?
  true
end

supports_insert_on_duplicate_skip?()

# File activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb, line 165
def supports_insert_on_duplicate_skip?
  true
end

supports_insert_on_duplicate_update?()

# File activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb, line 169
def supports_insert_on_duplicate_update?
  true
end

supports_insert_returning?()

# File activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb, line 173
def supports_insert_returning?
  mariadb? && database_version >= "10.5.0"
end

supports_optimizer_hints?()

# File activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb, line 149
def supports_optimizer_hints?
  !mariadb? && database_version >= "5.7.7"
end

supports_restart_db_transaction?()

# File activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb, line 112
def supports_restart_db_transaction?
  true
end

supports_transaction_isolation?()

# File activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb, line 108
def supports_transaction_isolation?
  true
end

supports_views?()

# File activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb, line 136
def supports_views?
  true
end

supports_virtual_columns?()

# File activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb, line 144
def supports_virtual_columns?
  mariadb? || database_version >= "5.7.5"
end