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 126 def _execute(conn, sql, opts) 127 stream = opts[:stream] 128 if NativePreparedStatements 129 if args = opts[:arguments] 130 args = args.map{|arg| bound_variable_value(arg)} 131 end 132 133 case sql 134 when ::Mysql2::Statement 135 stmt = sql 136 sql = opts[:sql] || '' 137 when Dataset 138 sql = sql.sql 139 close_stmt = true 140 stmt = conn.prepare(sql) 141 end 142 end 143 144 r = log_connection_yield((log_sql = opts[:log_sql]) ? sql + log_sql : sql, conn, args) do 145 if stmt 146 conn.query_options.merge!(:cache_rows=>true, :database_timezone => timezone, :application_timezone => Sequel.application_timezone, :stream=>stream, :cast_booleans=>convert_tinyint_to_bool) 147 stmt.execute(*args) 148 else 149 conn.query(sql, :database_timezone => timezone, :application_timezone => Sequel.application_timezone, :stream=>stream) 150 end 151 end 152 if opts[:type] == :select 153 if r 154 if stream 155 begin 156 r2 = yield r 157 ensure 158 # If r2 is nil, it means the block did not exit normally, 159 # so the rest of the results must be drained to prevent 160 # "commands out of sync" errors. 161 r.each{} unless r2 162 end 163 else 164 yield r 165 end 166 end 167 elsif defined?(yield) 168 yield conn 169 end 170 rescue ::Mysql2::Error => e 171 raise_error(e) 172 ensure 173 if stmt 174 conn.query_options.replace(conn.instance_variable_get(:@sequel_default_query_options)) 175 stmt.close if close_stmt 176 end 177 end
Set the convert_tinyint_to_bool
setting based on the default value.
# File lib/sequel/adapters/mysql2.rb 180 def adapter_initialize 181 self.convert_tinyint_to_bool = true 182 end
Handle bound variable arguments that Mysql2
does not handle natively.
# File lib/sequel/adapters/mysql2.rb 186 def bound_variable_value(arg) 187 case arg 188 when true 189 1 190 when false 191 0 192 when Time, Date 193 @default_dataset.literal_date_or_time(arg, true) 194 else 195 arg 196 end 197 end
# File lib/sequel/adapters/mysql2.rb 200 def connection_execute_method 201 :query 202 end
# File lib/sequel/adapters/mysql2.rb 204 def database_error_classes 205 [::Mysql2::Error] 206 end
# File lib/sequel/adapters/mysql2.rb 208 def database_exception_sqlstate(exception, opts) 209 state = exception.sql_state 210 state unless state == 'HY000' 211 end
# File lib/sequel/adapters/mysql2.rb 213 def dataset_class_default 214 Dataset 215 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 220 def disconnect_error?(e, opts) 221 super || 222 ((conn = opts[:conn]) && !conn.ping) || 223 (e.is_a?(::Mysql2::Error) && 224 (e.sql_state =~ /\A08/ || 225 MYSQL_DATABASE_DISCONNECT_ERRORS.match(e.message))) 226 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 if stmt 101 begin 102 stmt.close 103 rescue ::Mysql2::Error 104 # probably Invalid statement handle, can happen from dropping 105 # related table, ignore as we won't be using it again. 106 end 107 end 108 stmt = log_connection_yield("Preparing #{ps_name}: #{sql}", conn){conn.prepare(sql)} 109 conn.prepared_statements[ps_name] = [stmt, sql] 110 end 111 112 opts = Hash[opts] 113 opts[:sql] = "Executing #{ps_name || sql}" 114 if ps_name && ps.log_sql 115 opts[:log_sql] = " (#{sql})" 116 end 117 118 _execute(conn, stmt, opts, &block) 119 end 120 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 229 def schema_column_type(db_type) 230 convert_tinyint_to_bool && db_type =~ /\Atinyint\(1\)/ ? :boolean : super 231 end