Returns just a table’s primary key. @override
# File lib/arjdbc/mysql/adapter.rb, line 272 def primary_key(table) #pk_and_sequence = pk_and_sequence_for(table) #pk_and_sequence && pk_and_sequence.first @connection.primary_keys(table).first end
@private backwards-compatibility
@private
# File lib/arjdbc/mysql/adapter.rb, line 127 def self.arel_visitor_type(config = nil) ::Arel::Visitors::MySQL end
@see ActiveRecord::ConnectionAdapters::JdbcColumn#column_types
# File lib/arjdbc/mysql/column.rb, line 5 def self.column_selector [ /mysql/, lambda { |config, column| column.extend(Column) } ] end
@deprecated Use {emulate_booleans?} instead.
# File lib/arjdbc/mysql/adapter.rb, line 87 def self.emulate_booleans; @@emulate_booleans; end
@see emulate_booleans?
# File lib/arjdbc/mysql/adapter.rb, line 89 def self.emulate_booleans=(emulate); @@emulate_booleans = emulate; end
Boolean emulation can be disabled using (or using the adapter method) :
ArJdbc::MySQL.emulate_booleans = false
@see ActiveRecord::ConnectionAdapters::MysqlAdapter#emulate_booleans
# File lib/arjdbc/mysql/adapter.rb, line 85 def self.emulate_booleans?; @@emulate_booleans; end
@see ActiveRecord::ConnectionAdapters::JdbcAdapter#jdbc_connection_class
# File lib/arjdbc/mysql/adapter.rb, line 15 def self.jdbc_connection_class ::ActiveRecord::ConnectionAdapters::MySQLJdbcConnection end
@override
# File lib/arjdbc/mysql/adapter.rb, line 123 def adapter_name ADAPTER_NAME end
@override
# File lib/arjdbc/mysql/adapter.rb, line 393 def add_column(table_name, column_name, type, options = {}) add_column_sql = "ALTER TABLE #{quote_table_name(table_name)} ADD #{quote_column_name(column_name)} #{type_to_sql(type, options[:limit], options[:precision], options[:scale])}" add_column_options!(add_column_sql, options) add_column_position!(add_column_sql, options) execute(add_column_sql) end
# File lib/arjdbc/mysql/adapter.rb, line 454 def add_column_position!(sql, options) if options[:first] sql << " FIRST" elsif options[:after] sql << " AFTER #{quote_column_name(options[:after])}" end end
@note Only used with (non-AREL) ActiveRecord *2.3*. @see Arel::Visitors::MySQL
# File lib/arjdbc/mysql/adapter.rb, line 464 def add_limit_offset!(sql, options) limit, offset = options[:limit], options[:offset] if limit && offset sql << " LIMIT #{offset.to_i}, #{sanitize_limit(limit)}" elsif limit sql << " LIMIT #{sanitize_limit(limit)}" elsif offset sql << " OFFSET #{offset.to_i}" end sql end
# File lib/arjdbc/mysql/adapter.rb, line 137 def case_sensitive_equality_operator "= BINARY" end
# File lib/arjdbc/mysql/adapter.rb, line 141 def case_sensitive_modifier(node) Arel::Nodes::Bin.new(node) end
@override
# File lib/arjdbc/mysql/adapter.rb, line 416 def change_column(table_name, column_name, type, options = {}) column = column_for(table_name, column_name) unless options_include_default?(options) # NOTE: no defaults for BLOB/TEXT columns with MySQL options[:default] = column.default if type != :text && type != :binary end unless options.has_key?(:null) options[:null] = column.null end change_column_sql = "ALTER TABLE #{quote_table_name(table_name)} CHANGE #{quote_column_name(column_name)} #{quote_column_name(column_name)} #{type_to_sql(type, options[:limit], options[:precision], options[:scale])}" add_column_options!(change_column_sql, options) add_column_position!(change_column_sql, options) execute(change_column_sql) end
# File lib/arjdbc/mysql/adapter.rb, line 400 def change_column_default(table_name, column_name, default) column = column_for(table_name, column_name) change_column table_name, column_name, column.sql_type, :default => default end
# File lib/arjdbc/mysql/adapter.rb, line 405 def change_column_null(table_name, column_name, null, default = nil) column = column_for(table_name, column_name) unless null || default.nil? execute("UPDATE #{quote_table_name(table_name)} SET #{quote_column_name(column_name)}=#{quote(default)} WHERE #{quote_column_name(column_name)} IS NULL") end change_column table_name, column_name, column.sql_type, :null => null end
# File lib/arjdbc/mysql/adapter.rb, line 504 def charset show_variable("character_set_database") end
# File lib/arjdbc/mysql/adapter.rb, line 508 def collation show_variable("collation_database") end
Returns an array of `Column` objects for the table specified. @override
# File lib/arjdbc/mysql/adapter.rb, line 331 def columns(table_name, name = nil) sql = "SHOW FULL COLUMNS FROM #{quote_table_name(table_name)}" columns = execute(sql, name || 'SCHEMA') strict = strict_mode? column = ::ActiveRecord::ConnectionAdapters::MysqlAdapter::Column pass_cast_type = respond_to?(:lookup_cast_type) columns.map! do |field| sql_type = field['Type'] null = field['Null'] == "YES" if pass_cast_type cast_type = lookup_cast_type(sql_type) column.new(field['Field'], field['Default'], cast_type, sql_type, null, field['Collation'], strict, field['Extra']) else column.new(field['Field'], field['Default'], sql_type, null, field['Collation'], strict, field['Extra']) end end columns end
# File lib/arjdbc/mysql/adapter.rb, line 35 def configure_connection variables = config[:variables] || {} # By default, MySQL 'where id is null' selects the last inserted id. Turn this off. variables[:sql_auto_is_null] = 0 # execute "SET SQL_AUTO_IS_NULL=0" # Increase timeout so the server doesn't disconnect us. wait_timeout = config[:wait_timeout] wait_timeout = self.class.type_cast_config_to_integer(wait_timeout) variables[:wait_timeout] = wait_timeout.is_a?(Fixnum) ? wait_timeout : 2147483 # Make MySQL reject illegal values rather than truncating or blanking them, see # http://dev.mysql.com/doc/refman/5.0/en/server-sql-mode.html#sqlmode_strict_all_tables # If the user has provided another value for sql_mode, don't replace it. if strict_mode? && ! variables.has_key?(:sql_mode) variables[:sql_mode] = 'STRICT_ALL_TABLES' # SET SQL_MODE='STRICT_ALL_TABLES' end # NAMES does not have an equals sign, see # http://dev.mysql.com/doc/refman/5.0/en/set-statement.html#id944430 # (trailing comma because variable_assignments will always have content) encoding = "NAMES #{config[:encoding]}, " if config[:encoding] # Gather up all of the SET variables... variable_assignments = variables.map do |k, v| if v == ':default' || v == :default "@@SESSION.#{k.to_s} = DEFAULT" # Sets the value to the global or compile default elsif ! v.nil? "@@SESSION.#{k.to_s} = #{quote(v)}" end # or else nil; compact to clear nils out end.compact.join(', ') # ...and send them all in one query execute("SET #{encoding} #{variable_assignments}", :skip_logging) end
@override
# File lib/arjdbc/mysql/adapter.rb, line 358 def create_database(name, options = {}) if options[:collation] execute "CREATE DATABASE `#{name}` DEFAULT CHARACTER SET `#{options[:charset] || 'utf8'}` COLLATE `#{options[:collation]}`" else execute "CREATE DATABASE `#{name}` DEFAULT CHARACTER SET `#{options[:charset] || 'utf8'}`" end end
@override
# File lib/arjdbc/mysql/adapter.rb, line 219 def create_savepoint(name = current_savepoint_name(true)) log("SAVEPOINT #{name}", 'Savepoint') { super } end
@override
# File lib/arjdbc/mysql/adapter.rb, line 376 def create_table(name, options = {}) super(name, {:options => "ENGINE=InnoDB DEFAULT CHARSET=utf8"}.merge(options)) end
# File lib/arjdbc/mysql/adapter.rb, line 371 def current_database select_one("SELECT DATABASE() as db")["db"] end
# File lib/arjdbc/mysql/adapter.rb, line 233 def disable_referential_integrity fk_checks = select_value("SELECT @@FOREIGN_KEY_CHECKS") begin update("SET FOREIGN_KEY_CHECKS = 0") yield ensure update("SET FOREIGN_KEY_CHECKS = #{fk_checks}") end end
@override
# File lib/arjdbc/mysql/adapter.rb, line 367 def drop_database(name) execute "DROP DATABASE IF EXISTS `#{name}`" end
@override
# File lib/arjdbc/mysql/adapter.rb, line 544 def empty_insert_statement_value "VALUES ()" end
Returns an array of indexes for the given table. @override
# File lib/arjdbc/mysql/adapter.rb, line 303 def indexes(table_name, name = nil) indexes = [] current_index = nil result = execute("SHOW KEYS FROM #{quote_table_name(table_name)}", name || 'SCHEMA') result.each do |row| key_name = row['Key_name'] if current_index != key_name next if key_name == 'PRIMARY' # skip the primary key current_index = key_name indexes << if self.class.const_defined?(:INDEX_TYPES) # AR 4.0 mysql_index_type = row['Index_type'].downcase.to_sym index_type = INDEX_TYPES.include?(mysql_index_type) ? mysql_index_type : nil index_using = INDEX_USINGS.include?(mysql_index_type) ? mysql_index_type : nil IndexDefinition.new(row['Table'], key_name, row['Non_unique'].to_i == 0, [], [], nil, nil, index_type, index_using) else IndexDefinition.new(row['Table'], key_name, row['Non_unique'].to_i == 0, [], []) end end indexes.last.columns << row["Column_name"] indexes.last.lengths << row["Sub_part"] end indexes end
@private
# File lib/arjdbc/mysql/adapter.rb, line 20 def init_connection(jdbc_connection) meta = jdbc_connection.meta_data if meta.driver_major_version == 1 # TODO check in driver code # assumes MariaDB 1.x currently elsif meta.driver_major_version < 5 raise ::ActiveRecord::ConnectionNotEstablished, "MySQL adapter requires driver >= 5.0 got: '#{meta.driver_version}'" elsif meta.driver_major_version == 5 && meta.driver_minor_version < 1 config[:connection_alive_sql] ||= 'SELECT 1' # need 5.1 for JDBC 4.0 else # NOTE: since the loaded Java driver class can't change : MySQL.send(:remove_method, :init_connection) rescue nil end end
In the simple case, MySQL allows us to place JOINs directly into the UPDATE query. However, this does not allow for LIMIT, OFFSET and ORDER. To support these, we must use a subquery. However, MySQL is too stupid to create a temporary table for this automatically, so we have to give it some prompting in the form of a subsubquery. Ugh! @private based on mysql_adapter.rb from 3.1-stable
# File lib/arjdbc/mysql/adapter.rb, line 482 def join_to_update(update, select) if select.limit || select.offset || select.orders.any? subsubselect = select.clone subsubselect.projections = [update.key] subselect = Arel::SelectManager.new(select.engine) subselect.project Arel.sql(update.key.name) subselect.from subsubselect.as('__active_record_temp') update.where update.key.in(subselect) else update.table select.source update.wheres = select.constraints end end
# File lib/arjdbc/mysql/adapter.rb, line 145 def limited_update_conditions(where_sql, quoted_table_name, quoted_primary_key) where_sql end
@override
# File lib/arjdbc/mysql/adapter.rb, line 116 def native_database_types NATIVE_DATABASE_TYPES end
Returns a table’s primary key and belonging sequence. @note Not used, only here for potential compatibility with native adapter. @override
# File lib/arjdbc/mysql/adapter.rb, line 281 def pk_and_sequence_for(table) result = execute("SHOW CREATE TABLE #{quote_table_name(table)}", 'SCHEMA').first if result['Create Table'].to_s =~ /PRIMARY KEY\s+(?:USING\s+\w+\s+)?\((.+)\)/ keys = $1.split(","); keys.map! { |key| key.gsub(/[`"]/, "") } return keys.length == 1 ? [ keys.first, nil ] : nil else return nil end end
Returns just a table’s primary key. @override
# File lib/arjdbc/mysql/adapter.rb, line 272 def primary_key(table) #pk_and_sequence = pk_and_sequence_for(table) #pk_and_sequence && pk_and_sequence.first @connection.primary_keys(table).first end
@override
# File lib/arjdbc/mysql/adapter.rb, line 152 def quote(value, column = nil) return value.quoted_id if value.respond_to?(:quoted_id) return value if sql_literal?(value) return value.to_s if column && column.type == :primary_key if value.kind_of?(String) && column && column.type == :binary "x'#{value.unpack("H*")[0]}'" elsif value.kind_of?(BigDecimal) value.to_s("F") else super end end
@override
# File lib/arjdbc/mysql/adapter.rb, line 167 def quote_column_name(name) "`#{name.to_s.gsub('`', '``')}`" end
@override
# File lib/arjdbc/mysql/adapter.rb, line 172 def quote_table_name(name) quote_column_name(name).gsub('.', '`.`') end
@private
# File lib/arjdbc/mysql/adapter.rb, line 351 def recreate_database(name, options = {}) drop_database(name) create_database(name, options) reconnect! end
@override
# File lib/arjdbc/mysql/adapter.rb, line 229 def release_savepoint(name = current_savepoint_name) log("RELEASE SAVEPOINT #{name}", 'Savepoint') { super } end
@override
# File lib/arjdbc/mysql/adapter.rb, line 387 def remove_index!(table_name, index_name) # missing table_name quoting in AR-2.3 execute "DROP INDEX #{quote_column_name(index_name)} ON #{quote_table_name(table_name)}" end
@override
# File lib/arjdbc/mysql/adapter.rb, line 435 def rename_column(table_name, column_name, new_column_name) options = {} if column = columns(table_name).find { |c| c.name == column_name.to_s } type = column.type options[:default] = column.default if type != :text && type != :binary options[:null] = column.null else raise ActiveRecord::ActiveRecordError, "No such column: #{table_name}.#{column_name}" end current_type = select_one("SHOW COLUMNS FROM #{quote_table_name(table_name)} LIKE '#{column_name}'")["Type"] rename_column_sql = "ALTER TABLE #{quote_table_name(table_name)} CHANGE #{quote_column_name(column_name)} #{quote_column_name(new_column_name)} #{current_type}" add_column_options!(rename_column_sql, options) execute(rename_column_sql) rename_column_indexes(table_name, column_name, new_column_name) if respond_to?(:rename_column_indexes) # AR-4.0 SchemaStatements end
@override
# File lib/arjdbc/mysql/adapter.rb, line 381 def rename_table(table_name, new_name) execute "RENAME TABLE #{quote_table_name(table_name)} TO #{quote_table_name(new_name)}" rename_table_indexes(table_name, new_name) if respond_to?(:rename_table_indexes) # AR-4.0 SchemaStatements end
@override
# File lib/arjdbc/mysql/adapter.rb, line 224 def rollback_to_savepoint(name = current_savepoint_name) log("ROLLBACK TO SAVEPOINT #{name}", 'Savepoint') { super } end
# File lib/arjdbc/mysql/adapter.rb, line 498 def show_variable(var) res = execute("show variables like '#{var}'") result_row = res.detect {|row| row["Variable_name"] == var } result_row && result_row["Value"] end
# File lib/arjdbc/mysql/adapter.rb, line 71 def strict_mode? # strict_mode is default since AR 4.0 config.key?(:strict) ? self.class.type_cast_config_to_boolean(config[:strict]) : ::ActiveRecord::VERSION::MAJOR > 3 end
@deprecated no longer used - handled with (AR built-in) Rake tasks
# File lib/arjdbc/mysql/adapter.rb, line 251 def structure_dump # NOTE: due AR (2.3-3.2) compatibility views are not included if supports_views? sql = "SHOW FULL TABLES WHERE Table_type = 'BASE TABLE'" else sql = "SHOW TABLES" end @connection.execute_query_raw(sql).map do |table| # e.g. { "Tables_in_arjdbc_test"=>"big_fields", "Table_type"=>"BASE TABLE" } table.delete('Table_type') table_name = table.to_a.first.last create_table = select_one("SHOW CREATE TABLE #{quote_table_name(table_name)}") "#{create_table['Create Table']};\n\n" end.join end
@override
# File lib/arjdbc/mysql/adapter.rb, line 187 def supports_index_sort_order? # Technically MySQL allows to create indexes with the sort order syntax # but at the moment (5.5) it doesn't yet implement them. true end
@override
# File lib/arjdbc/mysql/adapter.rb, line 177 def supports_migrations? true end
@override
# File lib/arjdbc/mysql/adapter.rb, line 182 def supports_primary_key? true end
@override
# File lib/arjdbc/mysql/adapter.rb, line 214 def supports_savepoints? true end
@override
# File lib/arjdbc/mysql/adapter.rb, line 194 def supports_transaction_isolation? # MySQL 4 technically support transaction isolation, but it is affected by # a bug where the transaction level gets persisted for the whole session: # http://bugs.mysql.com/bug.php?id=39170 version[0] && version[0] >= 5 end
@override
# File lib/arjdbc/mysql/adapter.rb, line 202 def supports_views? version[0] && version[0] >= 5 end
# File lib/arjdbc/mysql/adapter.rb, line 512 def type_to_sql(type, limit = nil, precision = nil, scale = nil) case type.to_s when 'binary' case limit when 0..0xfff; "varbinary(#{limit})" when nil; "blob" when 0x1000..0xffffffff; "blob(#{limit})" else raise(ActiveRecordError, "No binary type has character length #{limit}") end when 'integer' case limit when 1; 'tinyint' when 2; 'smallint' when 3; 'mediumint' when nil, 4, 11; 'int(11)' # compatibility with MySQL default when 5..8; 'bigint' else raise(ActiveRecordError, "No integer type has byte size #{limit}") end when 'text' case limit when 0..0xff; 'tinytext' when nil, 0x100..0xffff; 'text' when 0x10000..0xffffff; 'mediumtext' when 0x1000000..0xffffffff; 'longtext' else raise(ActiveRecordError, "No text type has character length #{limit}") end else super end end
@override make it public just like native MySQL adapter does
# File lib/arjdbc/mysql/adapter.rb, line 244 def update_sql(sql, name = nil) super end
# File lib/arjdbc/mysql/adapter.rb, line 549 def quoted_columns_for_index(column_names, options = {}) length = options[:length] if options.is_a?(Hash) case length when Hash column_names.map { |name| length[name] ? "#{quote_column_name(name)}(#{length[name]})" : quote_column_name(name) } when Fixnum column_names.map { |name| "#{quote_column_name(name)}(#{length})" } else column_names.map { |name| quote_column_name(name) } end end
@override
# File lib/arjdbc/mysql/adapter.rb, line 563 def translate_exception(exception, message) return super unless exception.respond_to?(:errno) case exception.errno when 1062 ::ActiveRecord::RecordNotUnique.new(message, exception) when 1452 ::ActiveRecord::InvalidForeignKey.new(message, exception) else super end end
Generated with the Darkfish Rdoc Generator 2.