class Sequel::Mysql2::Database
Attributes
Whether to convert tinyint columns to bool for this database
Public Instance Methods
Connect to the database. In addition to the usual database options, the following options have effect:
- :auto_is_null
-
Set to true to use
MySQL
default behavior of having a filter for an autoincrement column equals NULL to return the last inserted row. - :charset
-
Same as :encoding (:encoding takes precendence)
- :encoding
-
Set all the related character sets for this connection (connection, client, database, server, and results).
The options hash is also passed to mysql2, and can include mysql2 options such as :local_infile.
# File lib/sequel/adapters/mysql2.rb 37 def connect(server) 38 opts = server_opts(server) 39 opts[:username] ||= opts.delete(:user) 40 opts[:flags] ||= 0 41 opts[:flags] |= ::Mysql2::Client::FOUND_ROWS if ::Mysql2::Client.const_defined?(:FOUND_ROWS) 42 opts[:encoding] ||= opts[:charset] 43 conn = ::Mysql2::Client.new(opts) 44 conn.query_options.merge!(:symbolize_keys=>true, :cache_rows=>false) 45 46 if NativePreparedStatements 47 conn.instance_variable_set(:@sequel_default_query_options, conn.query_options.dup) 48 end 49 50 sqls = mysql_connection_setting_sqls 51 52 # Set encoding a slightly different way after connecting, 53 # in case the READ_DEFAULT_GROUP overrode the provided encoding. 54 # Doesn't work across implicit reconnects, but Sequel doesn't turn on 55 # that feature. 56 if encoding = opts[:encoding] 57 sqls.unshift("SET NAMES #{conn.escape(encoding.to_s)}") 58 end 59 60 sqls.each{|sql| log_connection_yield(sql, conn){conn.query(sql)}} 61 62 add_prepared_statements_cache(conn) 63 conn 64 end
# File lib/sequel/adapters/mysql2.rb 66 def execute_dui(sql, opts=OPTS) 67 execute(sql, opts){|c| return c.affected_rows} 68 end
# File lib/sequel/adapters/mysql2.rb 70 def execute_insert(sql, opts=OPTS) 71 execute(sql, opts){|c| return c.last_id} 72 end
Sequel::MySQL::DatabaseMethods#freeze
# File lib/sequel/adapters/mysql2.rb 74 def freeze 75 server_version 76 super 77 end
Return the version of the MySQL
server to which we are connecting.
Sequel::MySQL::DatabaseMethods#server_version
# File lib/sequel/adapters/mysql2.rb 80 def server_version(_server=nil) 81 @server_version ||= super() 82 end
Private Instance Methods
Execute the given SQL
on the given connection. If the :type option is :select, yield the result of the query, otherwise yield the connection if a block is given.
# File lib/sequel/adapters/mysql2.rb 119 def _execute(conn, sql, opts) 120 stream = opts[:stream] 121 if NativePreparedStatements 122 if args = opts[:arguments] 123 args = args.map{|arg| bound_variable_value(arg)} 124 end 125 126 case sql 127 when ::Mysql2::Statement 128 stmt = sql 129 sql = opts[:sql] || '' 130 when Dataset 131 sql = sql.sql 132 close_stmt = true 133 stmt = conn.prepare(sql) 134 end 135 end 136 137 r = log_connection_yield((log_sql = opts[:log_sql]) ? sql + log_sql : sql, conn, args) do 138 if stmt 139 conn.query_options.merge!(:cache_rows=>true, :database_timezone => timezone, :application_timezone => Sequel.application_timezone, :stream=>stream, :cast_booleans=>convert_tinyint_to_bool) 140 stmt.execute(*args) 141 else 142 conn.query(sql, :database_timezone => timezone, :application_timezone => Sequel.application_timezone, :stream=>stream) 143 end 144 end 145 if opts[:type] == :select 146 if r 147 if stream 148 begin 149 r2 = yield r 150 ensure 151 # If r2 is nil, it means the block did not exit normally, 152 # so the rest of the results must be drained to prevent 153 # "commands out of sync" errors. 154 r.each{} unless r2 155 end 156 else 157 yield r 158 end 159 end 160 elsif defined?(yield) 161 yield conn 162 end 163 rescue ::Mysql2::Error => e 164 raise_error(e) 165 ensure 166 if stmt 167 conn.query_options.replace(conn.instance_variable_get(:@sequel_default_query_options)) 168 stmt.close if close_stmt 169 end 170 end
Set the convert_tinyint_to_bool
setting based on the default value.
# File lib/sequel/adapters/mysql2.rb 173 def adapter_initialize 174 self.convert_tinyint_to_bool = true 175 end
Handle bound variable arguments that Mysql2
does not handle natively.
# File lib/sequel/adapters/mysql2.rb 179 def bound_variable_value(arg) 180 case arg 181 when true 182 1 183 when false 184 0 185 when Time, Date 186 @default_dataset.literal_date_or_time(arg, true) 187 else 188 arg 189 end 190 end
# File lib/sequel/adapters/mysql2.rb 193 def connection_execute_method 194 :query 195 end
# File lib/sequel/adapters/mysql2.rb 197 def database_error_classes 198 [::Mysql2::Error] 199 end
# File lib/sequel/adapters/mysql2.rb 201 def database_exception_sqlstate(exception, opts) 202 state = exception.sql_state 203 state unless state == 'HY000' 204 end
# File lib/sequel/adapters/mysql2.rb 206 def dataset_class_default 207 Dataset 208 end
If a connection object is available, try pinging it. Otherwise, if the error is a Mysql2::Error, check the SQL
state and exception message for disconnects.
Sequel::Database#disconnect_error?
# File lib/sequel/adapters/mysql2.rb 213 def disconnect_error?(e, opts) 214 super || 215 ((conn = opts[:conn]) && !conn.ping) || 216 (e.is_a?(::Mysql2::Error) && 217 (e.sql_state =~ /\A08/ || 218 MYSQL_DATABASE_DISCONNECT_ERRORS.match(e.message))) 219 end
Use a native mysql2 prepared statement to implement prepared statements.
# File lib/sequel/adapters/mysql2.rb 88 def execute_prepared_statement(ps_name, opts, &block) 89 if ps_name.is_a?(Sequel::Dataset::ArgumentMapper) 90 ps = ps_name 91 ps_name = ps.prepared_statement_name 92 else 93 ps = prepared_statement(ps_name) 94 end 95 sql = ps.prepared_sql 96 97 synchronize(opts[:server]) do |conn| 98 stmt, ps_sql = conn.prepared_statements[ps_name] 99 unless ps_sql == sql 100 stmt.close if stmt 101 stmt = log_connection_yield("Preparing #{ps_name}: #{sql}", conn){conn.prepare(sql)} 102 conn.prepared_statements[ps_name] = [stmt, sql] 103 end 104 105 opts = Hash[opts] 106 opts[:sql] = "Executing #{ps_name || sql}" 107 if ps_name && ps.log_sql 108 opts[:log_sql] = " (#{sql})" 109 end 110 111 _execute(conn, stmt, opts, &block) 112 end 113 end
Convert tinyint(1) type to boolean if convert_tinyint_to_bool
is true
Sequel::MySQL::DatabaseMethods#schema_column_type
# File lib/sequel/adapters/mysql2.rb 222 def schema_column_type(db_type) 223 convert_tinyint_to_bool && db_type =~ /\Atinyint\(1\)/ ? :boolean : super 224 end