rails / rails

Ruby on Rails

This URL has Read+Write access

db045dbb » dhh 2004-11-23 Initial 1 require 'active_record/connection_adapters/abstract_adapter'
19c99acf » jeremy 2006-11-20 MySQL: detect when a NOT NU... 2 require 'set'
67adc0b5 » jeremy 2005-07-03 r1617@asus: jeremy | 2005... 3
0aa0c84c » dhh 2007-01-26 Nodoc the irrelevant (from ... 4 module MysqlCompat #:nodoc:
48d4d43f » jeremy 2006-10-02 MySQL: introduce Mysql::Res... 5 # add all_hashes method to standard mysql-c bindings or pure ruby version
6 def self.define_all_hashes_method!
8949ce09 » jeremy 2006-10-20 MySQL: all_hashes compatibi... 7 raise 'Mysql not loaded' unless defined?(::Mysql)
8
be3a4c3d » jeremy 2006-11-15 Mysql::Result#all_hashes co... 9 target = defined?(Mysql::Result) ? Mysql::Result : MysqlRes
10 return if target.instance_methods.include?('all_hashes')
48d4d43f » jeremy 2006-10-02 MySQL: introduce Mysql::Res... 11
12 # Ruby driver has a version string and returns null values in each_hash
13 # C driver >= 2.7 returns null values in each_hash
be3a4c3d » jeremy 2006-11-15 Mysql::Result#all_hashes co... 14 if Mysql.const_defined?(:VERSION) && (Mysql::VERSION.is_a?(String) || Mysql::VERSION >= 20700)
15 target.class_eval <<-'end_eval'
16 def all_hashes
17 rows = []
18 each_hash { |row| rows << row }
19 rows
48d4d43f » jeremy 2006-10-02 MySQL: introduce Mysql::Res... 20 end
be3a4c3d » jeremy 2006-11-15 Mysql::Result#all_hashes co... 21 end_eval
48d4d43f » jeremy 2006-10-02 MySQL: introduce Mysql::Res... 22
23 # adapters before 2.7 don't have a version constant
24 # and don't return null values in each_hash
25 else
be3a4c3d » jeremy 2006-11-15 Mysql::Result#all_hashes co... 26 target.class_eval <<-'end_eval'
48d4d43f » jeremy 2006-10-02 MySQL: introduce Mysql::Res... 27 def all_hashes
28 rows = []
29 all_fields = fetch_fields.inject({}) { |fields, f| fields[f.name] = nil; fields }
30 each_hash { |row| rows << all_fields.dup.update(row) }
31 rows
32 end
33 end_eval
34 end
be3a4c3d » jeremy 2006-11-15 Mysql::Result#all_hashes co... 35
d41ea51d » jeremy 2007-09-29 Ruby 1.9 compat for instanc... 36 unless target.instance_methods.include?('all_hashes') ||
37 target.instance_methods.include?(:all_hashes)
be3a4c3d » jeremy 2006-11-15 Mysql::Result#all_hashes co... 38 raise "Failed to defined #{target.name}#all_hashes method. Mysql::VERSION = #{Mysql::VERSION.inspect}"
39 end
48d4d43f » jeremy 2006-10-02 MySQL: introduce Mysql::Res... 40 end
41 end
42
db045dbb » dhh 2004-11-23 Initial 43 module ActiveRecord
44 class Base
be3a4c3d » jeremy 2006-11-15 Mysql::Result#all_hashes co... 45 def self.require_mysql
46 # Include the MySQL driver if one hasn't already been loaded
baad1c4c » jeremy 2005-11-21 Simpler Mysql load test. 47 unless defined? Mysql
db045dbb » dhh 2004-11-23 Initial 48 begin
49 require_library_or_gem 'mysql'
50 rescue LoadError => cannot_require_mysql
be3a4c3d » jeremy 2006-11-15 Mysql::Result#all_hashes co... 51 # Use the bundled Ruby/MySQL driver if no driver is already in place
67adc0b5 » jeremy 2005-07-03 r1617@asus: jeremy | 2005... 52 begin
0d5a7d1d » dhh 2007-09-20 Stress that you should real... 53 ActiveRecord::Base.logger.info(
54 "WARNING: You're using the Ruby-based MySQL library that ships with Rails. This library is not suited for production. " +
55 "Please install the C-based MySQL library instead (gem install mysql)."
56 ) if ActiveRecord::Base.logger
57
db045dbb » dhh 2004-11-23 Initial 58 require 'active_record/vendor/mysql'
59 rescue LoadError
60 raise cannot_require_mysql
61 end
62 end
63 end
baad1c4c » jeremy 2005-11-21 Simpler Mysql load test. 64
48d4d43f » jeremy 2006-10-02 MySQL: introduce Mysql::Res... 65 # Define Mysql::Result.all_hashes
66 MysqlCompat.define_all_hashes_method!
be3a4c3d » jeremy 2006-11-15 Mysql::Result#all_hashes co... 67 end
48d4d43f » jeremy 2006-10-02 MySQL: introduce Mysql::Res... 68
be3a4c3d » jeremy 2006-11-15 Mysql::Result#all_hashes co... 69 # Establishes a connection to the database that's used by all Active Record objects.
70 def self.mysql_connection(config) # :nodoc:
f98ec352 » jeremy 2005-09-30 Get rid of old symbolize_st... 71 config = config.symbolize_keys
db045dbb » dhh 2004-11-23 Initial 72 host = config[:host]
73 port = config[:port]
74 socket = config[:socket]
75 username = config[:username] ? config[:username].to_s : 'root'
76 password = config[:password].to_s
67adc0b5 » jeremy 2005-07-03 r1617@asus: jeremy | 2005... 77
db045dbb » dhh 2004-11-23 Initial 78 if config.has_key?(:database)
79 database = config[:database]
80 else
81 raise ArgumentError, "No database specified. Missing argument: database."
82 end
67adc0b5 » jeremy 2005-07-03 r1617@asus: jeremy | 2005... 83
be3a4c3d » jeremy 2006-11-15 Mysql::Result#all_hashes co... 84 require_mysql
ba309a3e » dhh 2005-02-20 Added options to specify an... 85 mysql = Mysql.init
86 mysql.ssl_set(config[:sslkey], config[:sslcert], config[:sslca], config[:sslcapath], config[:sslcipher]) if config[:sslkey]
be3a4c3d » jeremy 2006-11-15 Mysql::Result#all_hashes co... 87
e8f664dd » jeremy 2005-11-22 MySQL, PostgreSQL: reconnec... 88 ConnectionAdapters::MysqlAdapter.new(mysql, logger, [host, username, password, database, port, socket], config)
db045dbb » dhh 2004-11-23 Initial 89 end
90 end
67adc0b5 » jeremy 2005-07-03 r1617@asus: jeremy | 2005... 91
db045dbb » dhh 2004-11-23 Initial 92 module ConnectionAdapters
ea654654 » jamis 2005-09-25 Standardize the interpretat... 93 class MysqlColumn < Column #:nodoc:
c7c3f73f » jeremy 2007-10-06 Reinstate failsafe date/tim... 94 def extract_default(default)
95 if type == :binary || type == :text
96 if default.blank?
e59978aa » jeremy 2008-01-30 MySQL: omit text/blob defau... 97 nil
c7c3f73f » jeremy 2007-10-06 Reinstate failsafe date/tim... 98 else
99 raise ArgumentError, "#{type} columns cannot have a default value: #{default.inspect}"
100 end
101 elsif missing_default_forged_as_empty_string?(default)
102 nil
103 else
104 super
105 end
19c99acf » jeremy 2006-11-20 MySQL: detect when a NOT NU... 106 end
107
ea654654 » jamis 2005-09-25 Standardize the interpretat... 108 private
109 def simplified_type(field_type)
d7123105 » jamis 2006-03-17 Make all tinyint(1) variant... 110 return :boolean if MysqlAdapter.emulate_booleans && field_type.downcase.index("tinyint(1)")
75de3cbb » dhh 2006-03-25 Fixed that MySQL enums shou... 111 return :string if field_type =~ /enum/i
ea654654 » jamis 2005-09-25 Standardize the interpretat... 112 super
113 end
19c99acf » jeremy 2006-11-20 MySQL: detect when a NOT NU... 114
c1abe443 » NZKoz 2008-03-01 Make the mysql schema dumpe... 115 def extract_limit(sql_type)
116 if sql_type =~ /blob|text/i
117 case sql_type
118 when /tiny/i
119 255
120 when /medium/i
121 16777215
122 when /long/i
123 2147483647 # mysql only allows 2^31-1, not 2^32-1, somewhat inconsistently with the tiny/medium/normal cases
124 else
125 super # we could return 65535 here, but we leave it undecorated by default
126 end
127 else
128 super
129 end
130 end
131
19c99acf » jeremy 2006-11-20 MySQL: detect when a NOT NU... 132 # MySQL misreports NOT NULL column default when none is given.
133 # We can't detect this for columns which may have a legitimate ''
269ad971 » jeremy 2007-01-28 MySQL: blob and text column... 134 # default (string) but we can for others (integer, datetime, boolean,
135 # and the rest).
19c99acf » jeremy 2006-11-20 MySQL: detect when a NOT NU... 136 #
137 # Test whether the column has default '', is not null, and is not
138 # a type allowing default ''.
c7c3f73f » jeremy 2007-10-06 Reinstate failsafe date/tim... 139 def missing_default_forged_as_empty_string?(default)
140 type != :string && !null && default == ''
269ad971 » jeremy 2007-01-28 MySQL: blob and text column... 141 end
ea654654 » jamis 2005-09-25 Standardize the interpretat... 142 end
143
1dc0b2a9 » dhh 2005-02-23 Added documentation for dat... 144 # The MySQL adapter will work with both Ruby/MySQL, which is a Ruby-based MySQL adapter that comes bundled with Active Record, and with
145 # the faster C-based MySQL/Ruby adapter (available both as a gem and from http://www.tmtm.org/en/mysql/ruby/).
146 #
147 # Options:
148 #
149 # * <tt>:host</tt> -- Defaults to localhost
150 # * <tt>:port</tt> -- Defaults to 3306
151 # * <tt>:socket</tt> -- Defaults to /tmp/mysql.sock
152 # * <tt>:username</tt> -- Defaults to root
153 # * <tt>:password</tt> -- Defaults to nothing
154 # * <tt>:database</tt> -- The name of the database. No default, must be provided.
6bdcc0cf » Marcel Molina 2007-05-05 Add documentation for :enco... 155 # * <tt>:encoding</tt> -- (Optional) Sets the client encoding by executing "SET NAMES <encoding>" after connection
1dc0b2a9 » dhh 2005-02-23 Added documentation for dat... 156 # * <tt>:sslkey</tt> -- Necessary to use MySQL with an SSL connection
157 # * <tt>:sslcert</tt> -- Necessary to use MySQL with an SSL connection
158 # * <tt>:sslcapath</tt> -- Necessary to use MySQL with an SSL connection
159 # * <tt>:sslcipher</tt> -- Necessary to use MySQL with an SSL connection
ea654654 » jamis 2005-09-25 Standardize the interpretat... 160 #
161 # By default, the MysqlAdapter will consider all columns of type tinyint(1)
162 # as boolean. If you wish to disable this emulation (which was the default
163 # behavior in versions 0.13.1 and earlier) you can add the following line
164 # to your environment.rb file:
165 #
166 # ActiveRecord::ConnectionAdapters::MysqlAdapter.emulate_booleans = false
1dc0b2a9 » dhh 2005-02-23 Added documentation for dat... 167 class MysqlAdapter < AbstractAdapter
ea654654 » jamis 2005-09-25 Standardize the interpretat... 168 @@emulate_booleans = true
169 cattr_accessor :emulate_booleans
170
67adc0b5 » jeremy 2005-07-03 r1617@asus: jeremy | 2005... 171 LOST_CONNECTION_ERROR_MESSAGES = [
f3845822 » dhh 2005-02-20 Fixed that Active Record wo... 172 "Server shutdown in progress",
67adc0b5 » jeremy 2005-07-03 r1617@asus: jeremy | 2005... 173 "Broken pipe",
174 "Lost connection to MySQL server during query",
ac2b2131 » jeremy 2008-02-03 MySQL: memoize column and t... 175 "MySQL server has gone away" ]
176
177 QUOTED_TRUE, QUOTED_FALSE = '1', '0'
b3df9598 » dhh 2005-09-25 Refactored the AbstractAdap... 178
39b71bb8 » jeremy 2005-12-09 MySQL: ensure that @config ... 179 def initialize(connection, logger, connection_options, config)
b3df9598 » dhh 2005-09-25 Refactored the AbstractAdap... 180 super(connection, logger)
39b71bb8 » jeremy 2005-12-09 MySQL: ensure that @config ... 181 @connection_options, @config = connection_options, config
ac2b2131 » jeremy 2008-02-03 MySQL: memoize column and t... 182 @quoted_column_names, @quoted_table_names = {}, {}
e8f664dd » jeremy 2005-11-22 MySQL, PostgreSQL: reconnec... 183 connect
b3df9598 » dhh 2005-09-25 Refactored the AbstractAdap... 184 end
185
186 def adapter_name #:nodoc:
187 'MySQL'
188 end
189
190 def supports_migrations? #:nodoc:
4160b518 » dhh 2005-07-04 Added new Migrations framew... 191 true
192 end
eac7cf0b » dhh 2005-03-01 Added preliminary support f... 193
0aa0c84c » dhh 2007-01-26 Nodoc the irrelevant (from ... 194 def native_database_types #:nodoc:
eac7cf0b » dhh 2005-03-01 Added preliminary support f... 195 {
ef214ecc » dhh 2005-03-10 More incremental work on ac... 196 :primary_key => "int(11) DEFAULT NULL auto_increment PRIMARY KEY",
65786805 » dhh 2005-03-10 More incremental work on ac... 197 :string => { :name => "varchar", :limit => 255 },
198 :text => { :name => "text" },
199 :integer => { :name => "int", :limit => 11 },
200 :float => { :name => "float" },
2a12b568 » jeremy 2006-07-08 r4704@asus: jeremy | 2006... 201 :decimal => { :name => "decimal" },
65786805 » dhh 2005-03-10 More incremental work on ac... 202 :datetime => { :name => "datetime" },
203 :timestamp => { :name => "datetime" },
76879f25 » jeremy 2005-10-23 Map Active Record time to S... 204 :time => { :name => "time" },
65786805 » dhh 2005-03-10 More incremental work on ac... 205 :date => { :name => "date" },
206 :binary => { :name => "blob" },
207 :boolean => { :name => "tinyint", :limit => 1 }
eac7cf0b » dhh 2005-03-01 Added preliminary support f... 208 }
209 end
210
67adc0b5 » jeremy 2005-07-03 r1617@asus: jeremy | 2005... 211
b3df9598 » dhh 2005-09-25 Refactored the AbstractAdap... 212 # QUOTING ==================================================
213
f1a184fe » jeremy 2005-11-21 MySQL: introduce :encoding ... 214 def quote(value, column = nil)
91ea3530 » dhh 2006-03-25 Only string_to_binary if th... 215 if value.kind_of?(String) && column && column.type == :binary && column.class.respond_to?(:string_to_binary)
f1a184fe » jeremy 2005-11-21 MySQL: introduce :encoding ... 216 s = column.class.string_to_binary(value).unpack("H*")[0]
217 "x'#{s}'"
2a12b568 » jeremy 2006-07-08 r4704@asus: jeremy | 2006... 218 elsif value.kind_of?(BigDecimal)
219 "'#{value.to_s("F")}'"
f1a184fe » jeremy 2005-11-21 MySQL: introduce :encoding ... 220 else
221 super
222 end
223 end
224
b3df9598 » dhh 2005-09-25 Refactored the AbstractAdap... 225 def quote_column_name(name) #:nodoc:
ac2b2131 » jeremy 2008-02-03 MySQL: memoize column and t... 226 @quoted_column_names[name] ||= "`#{name}`"
eac7cf0b » dhh 2005-03-01 Added preliminary support f... 227 end
228
9b6207c3 » jeremy 2007-10-15 Quote table names. Defaults... 229 def quote_table_name(name) #:nodoc:
ac2b2131 » jeremy 2008-02-03 MySQL: memoize column and t... 230 @quoted_table_names[name] ||= quote_column_name(name).gsub('.', '`.`')
9b6207c3 » jeremy 2007-10-15 Quote table names. Defaults... 231 end
232
b3df9598 » dhh 2005-09-25 Refactored the AbstractAdap... 233 def quote_string(string) #:nodoc:
e8f664dd » jeremy 2005-11-22 MySQL, PostgreSQL: reconnec... 234 @connection.quote(string)
db045dbb » dhh 2004-11-23 Initial 235 end
67adc0b5 » jeremy 2005-07-03 r1617@asus: jeremy | 2005... 236
b3df9598 » dhh 2005-09-25 Refactored the AbstractAdap... 237 def quoted_true
ac2b2131 » jeremy 2008-02-03 MySQL: memoize column and t... 238 QUOTED_TRUE
b3df9598 » dhh 2005-09-25 Refactored the AbstractAdap... 239 end
ed2a84f9 » jeremy 2007-05-25 MySQL: create_database take... 240
b3df9598 » dhh 2005-09-25 Refactored the AbstractAdap... 241 def quoted_false
ac2b2131 » jeremy 2008-02-03 MySQL: memoize column and t... 242 QUOTED_FALSE
db045dbb » dhh 2004-11-23 Initial 243 end
67adc0b5 » jeremy 2005-07-03 r1617@asus: jeremy | 2005... 244
49eafd8c » jeremy 2007-10-25 Foxy fixtures. Adapter#disa... 245 # REFERENTIAL INTEGRITY ====================================
246
247 def disable_referential_integrity(&block) #:nodoc:
248 old = select_value("SELECT @@FOREIGN_KEY_CHECKS")
249
250 begin
251 update("SET FOREIGN_KEY_CHECKS = 0")
252 yield
253 ensure
254 update("SET FOREIGN_KEY_CHECKS = #{old}")
255 end
256 end
7dc45818 » jamis 2005-09-23 Add ActiveRecord::SchemaDum... 257
680e4742 » jeremy 2005-11-13 r3042@asus: jeremy | 2005... 258 # CONNECTION MANAGEMENT ====================================
259
260 def active?
75d0623b » jeremy 2005-11-28 MySQL: active? compatibilit... 261 if @connection.respond_to?(:stat)
262 @connection.stat
263 else
264 @connection.query 'select 1'
265 end
6c9cfd64 » jeremy 2005-12-03 MySQL: work around ruby-mys... 266
267 # mysql-ruby doesn't raise an exception when stat fails.
268 if @connection.respond_to?(:errno)
269 @connection.errno.zero?
270 else
271 true
272 end
680e4742 » jeremy 2005-11-13 r3042@asus: jeremy | 2005... 273 rescue Mysql::Error
274 false
275 end
276
277 def reconnect!
6bd8e351 » jeremy 2006-02-26 ActiveRecord::Base.remove_c... 278 disconnect!
6c9cfd64 » jeremy 2005-12-03 MySQL: work around ruby-mys... 279 connect
680e4742 » jeremy 2005-11-13 r3042@asus: jeremy | 2005... 280 end
ed2a84f9 » jeremy 2007-05-25 MySQL: create_database take... 281
6bd8e351 » jeremy 2006-02-26 ActiveRecord::Base.remove_c... 282 def disconnect!
283 @connection.close rescue nil
284 end
680e4742 » jeremy 2005-11-13 r3042@asus: jeremy | 2005... 285
286
b3df9598 » dhh 2005-09-25 Refactored the AbstractAdap... 287 # DATABASE STATEMENTS ======================================
7dc45818 » jamis 2005-09-23 Add ActiveRecord::SchemaDum... 288
30fb7b8c » jeremy 2007-09-15 connection.select_rows 'sql... 289 def select_rows(sql, name = nil)
290 @connection.query_with_result = true
291 result = execute(sql, name)
292 rows = []
293 result.each { |row| rows << row }
294 result.free
295 rows
296 end
297
70840d4b » jeremy 2006-11-01 Oracle: resolve test failur... 298 def execute(sql, name = nil) #:nodoc:
680e4742 » jeremy 2005-11-13 r3042@asus: jeremy | 2005... 299 log(sql, name) { @connection.query(sql) }
96c60b0e » jeremy 2005-07-03 r1603@asus: jeremy | 2005... 300 rescue ActiveRecord::StatementInvalid => exception
680e4742 » jeremy 2005-11-13 r3042@asus: jeremy | 2005... 301 if exception.message.split(":").first =~ /Packets out of order/
302 raise ActiveRecord::StatementInvalid, "'Packets out of order' error was received from the database. Please update your mysql bindings (gem install mysql) and read http://dev.mysql.com/doc/mysql/en/password-hashing.html for more information. If you're on Windows, use the Instant Rails installer to get the updated mysql bindings."
96c60b0e » jeremy 2005-07-03 r1603@asus: jeremy | 2005... 303 else
304 raise
f3845822 » dhh 2005-02-20 Fixed that Active Record wo... 305 end
db045dbb » dhh 2004-11-23 Initial 306 end
67adc0b5 » jeremy 2005-07-03 r1617@asus: jeremy | 2005... 307
bfb906a9 » jeremy 2007-09-16 Speed up and simplify query... 308 def insert_sql(sql, name = nil, pk = nil, id_value = nil, sequence_name = nil) #:nodoc:
309 super sql, name
b3df9598 » dhh 2005-09-25 Refactored the AbstractAdap... 310 id_value || @connection.insert_id
311 end
312
bfb906a9 » jeremy 2007-09-16 Speed up and simplify query... 313 def update_sql(sql, name = nil) #:nodoc:
314 super
69cb942d » dhh 2004-12-19 Changed the interface on Ab... 315 @connection.affected_rows
316 end
67adc0b5 » jeremy 2005-07-03 r1617@asus: jeremy | 2005... 317
b3df9598 » dhh 2005-09-25 Refactored the AbstractAdap... 318 def begin_db_transaction #:nodoc:
96c60b0e » jeremy 2005-07-03 r1603@asus: jeremy | 2005... 319 execute "BEGIN"
320 rescue Exception
321 # Transactions aren't supported
db045dbb » dhh 2004-11-23 Initial 322 end
67adc0b5 » jeremy 2005-07-03 r1617@asus: jeremy | 2005... 323
b3df9598 » dhh 2005-09-25 Refactored the AbstractAdap... 324 def commit_db_transaction #:nodoc:
96c60b0e » jeremy 2005-07-03 r1603@asus: jeremy | 2005... 325 execute "COMMIT"
326 rescue Exception
327 # Transactions aren't supported
db045dbb » dhh 2004-11-23 Initial 328 end
67adc0b5 » jeremy 2005-07-03 r1617@asus: jeremy | 2005... 329
b3df9598 » dhh 2005-09-25 Refactored the AbstractAdap... 330 def rollback_db_transaction #:nodoc:
96c60b0e » jeremy 2005-07-03 r1603@asus: jeremy | 2005... 331 execute "ROLLBACK"
332 rescue Exception
333 # Transactions aren't supported
db045dbb » dhh 2004-11-23 Initial 334 end
eac7cf0b » dhh 2005-03-01 Added preliminary support f... 335
67adc0b5 » jeremy 2005-07-03 r1617@asus: jeremy | 2005... 336
0aa0c84c » dhh 2007-01-26 Nodoc the irrelevant (from ... 337 def add_limit_offset!(sql, options) #:nodoc:
89733eae » Marcel Molina 2005-10-09 Optimization refactoring fo... 338 if limit = options[:limit]
339 unless offset = options[:offset]
340 sql << " LIMIT #{limit}"
b02776c2 » jeremy 2005-07-03 r1607@asus: jeremy | 2005... 341 else
89733eae » Marcel Molina 2005-10-09 Optimization refactoring fo... 342 sql << " LIMIT #{offset}, #{limit}"
96c60b0e » jeremy 2005-07-03 r1603@asus: jeremy | 2005... 343 end
f2a29ca4 » dhh 2005-07-01 Added support for ODBC conn... 344 end
ee8d1100 » dhh 2005-03-20 Added adapter independent l... 345 end
f2a29ca4 » dhh 2005-07-01 Added support for ODBC conn... 346
b3df9598 » dhh 2005-09-25 Refactored the AbstractAdap... 347
348 # SCHEMA STATEMENTS ========================================
349
350 def structure_dump #:nodoc:
cee92312 » dhh 2006-03-15 Stop the MySQL adapter cras... 351 if supports_views?
352 sql = "SHOW FULL TABLES WHERE Table_type = 'BASE TABLE'"
353 else
354 sql = "SHOW TABLES"
355 end
ed2a84f9 » jeremy 2007-05-25 MySQL: create_database take... 356
cee92312 » dhh 2006-03-15 Stop the MySQL adapter cras... 357 select_all(sql).inject("") do |structure, table|
358 table.delete('Table_type')
9b6207c3 » jeremy 2007-10-15 Quote table names. Defaults... 359 structure += select_one("SHOW CREATE TABLE #{quote_table_name(table.to_a.first.last)}")["Create Table"] + ";\n\n"
b3df9598 » dhh 2005-09-25 Refactored the AbstractAdap... 360 end
361 end
362
363 def recreate_database(name) #:nodoc:
db045dbb » dhh 2004-11-23 Initial 364 drop_database(name)
365 create_database(name)
366 end
67adc0b5 » jeremy 2005-07-03 r1617@asus: jeremy | 2005... 367
ed2a84f9 » jeremy 2007-05-25 MySQL: create_database take... 368 # Create a new MySQL database with optional :charset and :collation.
369 # Charset defaults to utf8.
370 #
371 # Example:
372 # create_database 'charset_test', :charset => 'latin1', :collation => 'latin1_bin'
373 # create_database 'matt_development'
374 # create_database 'matt_development', :charset => :big5
375 def create_database(name, options = {})
376 if options[:collation]
377 execute "CREATE DATABASE `#{name}` DEFAULT CHARACTER SET `#{options[:charset] || 'utf8'}` COLLATE `#{options[:collation]}`"
378 else
379 execute "CREATE DATABASE `#{name}` DEFAULT CHARACTER SET `#{options[:charset] || 'utf8'}`"
380 end
b3df9598 » dhh 2005-09-25 Refactored the AbstractAdap... 381 end
ed2a84f9 » jeremy 2007-05-25 MySQL: create_database take... 382
b3df9598 » dhh 2005-09-25 Refactored the AbstractAdap... 383 def drop_database(name) #:nodoc:
1e2b3d8b » Marcel Molina 2006-01-12 Escape database name in MyS... 384 execute "DROP DATABASE IF EXISTS `#{name}`"
db045dbb » dhh 2004-11-23 Initial 385 end
67adc0b5 » jeremy 2005-07-03 r1617@asus: jeremy | 2005... 386
0555fc90 » dhh 2006-03-17 Added connection#current_da... 387 def current_database
ed2a84f9 » jeremy 2007-05-25 MySQL: create_database take... 388 select_value 'SELECT DATABASE() as db'
389 end
390
391 # Returns the database character set.
392 def charset
393 show_variable 'character_set_database'
394 end
395
396 # Returns the database collation strategy.
397 def collation
398 show_variable 'collation_database'
0555fc90 » dhh 2006-03-17 Added connection#current_da... 399 end
b3df9598 » dhh 2005-09-25 Refactored the AbstractAdap... 400
401 def tables(name = nil) #:nodoc:
402 tables = []
403 execute("SHOW TABLES", name).each { |field| tables << field[0] }
404 tables
db045dbb » dhh 2004-11-23 Initial 405 end
b3df9598 » dhh 2005-09-25 Refactored the AbstractAdap... 406
9b6207c3 » jeremy 2007-10-15 Quote table names. Defaults... 407 def drop_table(table_name, options = {})
408 super(table_name, options)
409 end
410
b3df9598 » dhh 2005-09-25 Refactored the AbstractAdap... 411 def indexes(table_name, name = nil)#:nodoc:
412 indexes = []
413 current_index = nil
9b6207c3 » jeremy 2007-10-15 Quote table names. Defaults... 414 execute("SHOW KEYS FROM #{quote_table_name(table_name)}", name).each do |row|
b3df9598 » dhh 2005-09-25 Refactored the AbstractAdap... 415 if current_index != row[2]
416 next if row[2] == "PRIMARY" # skip the primary key
417 current_index = row[2]
418 indexes << IndexDefinition.new(row[0], row[2], row[1] == "0", [])
419 end
420
421 indexes.last.columns << row[4]
422 end
423 indexes
424 end
425
426 def columns(table_name, name = nil)#:nodoc:
9b6207c3 » jeremy 2007-10-15 Quote table names. Defaults... 427 sql = "SHOW FIELDS FROM #{quote_table_name(table_name)}"
b3df9598 » dhh 2005-09-25 Refactored the AbstractAdap... 428 columns = []
429 execute(sql, name).each { |field| columns << MysqlColumn.new(field[0], field[4], field[1], field[2] == "YES") }
430 columns
431 end
432
9b6207c3 » jeremy 2007-10-15 Quote table names. Defaults... 433 def create_table(table_name, options = {}) #:nodoc:
434 super(table_name, options.reverse_merge(:options => "ENGINE=InnoDB"))
b3df9598 » dhh 2005-09-25 Refactored the AbstractAdap... 435 end
ed2a84f9 » jeremy 2007-05-25 MySQL: create_database take... 436
9b6207c3 » jeremy 2007-10-15 Quote table names. Defaults... 437 def rename_table(table_name, new_name)
438 execute "RENAME TABLE #{quote_table_name(table_name)} TO #{quote_table_name(new_name)}"
ed2a84f9 » jeremy 2007-05-25 MySQL: create_database take... 439 end
b3df9598 » dhh 2005-09-25 Refactored the AbstractAdap... 440
441 def change_column_default(table_name, column_name, default) #:nodoc:
9b6207c3 » jeremy 2007-10-15 Quote table names. Defaults... 442 current_type = select_one("SHOW COLUMNS FROM #{quote_table_name(table_name)} LIKE '#{column_name}'")["Type"]
0bef1682 » dhh 2005-07-05 Made default changes work i... 443
9b6207c3 » jeremy 2007-10-15 Quote table names. Defaults... 444 execute("ALTER TABLE #{quote_table_name(table_name)} CHANGE #{quote_column_name(column_name)} #{quote_column_name(column_name)} #{current_type} DEFAULT #{quote(default)}")
0bef1682 » dhh 2005-07-05 Made default changes work i... 445 end
eac7cf0b » dhh 2005-03-01 Added preliminary support f... 446
b3df9598 » dhh 2005-09-25 Refactored the AbstractAdap... 447 def change_column(table_name, column_name, type, options = {}) #:nodoc:
6019c268 » jeremy 2007-01-14 change_column accepts :defa... 448 unless options_include_default?(options)
85c86f09 » jeremy 2007-10-07 MySQL: fix change_column on... 449 if column = columns(table_name).find { |c| c.name == column_name.to_s }
450 options[:default] = column.default
7cb1f93b » jeremy 2007-09-28 MySQL: change_column raises... 451 else
452 raise "No such column: #{table_name}.#{column_name}"
453 end
9c5591da » Marcel Molina 2006-05-14 Preserve MySQL boolean colu... 454 end
6019c268 » jeremy 2007-01-14 change_column accepts :defa... 455
9b6207c3 » jeremy 2007-10-15 Quote table names. Defaults... 456 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])}"
f1880cac » dhh 2005-07-05 Sugared up migrations with ... 457 add_column_options!(change_column_sql, options)
458 execute(change_column_sql)
459 end
460
b3df9598 » dhh 2005-09-25 Refactored the AbstractAdap... 461 def rename_column(table_name, column_name, new_column_name) #:nodoc:
9b6207c3 » jeremy 2007-10-15 Quote table names. Defaults... 462 current_type = select_one("SHOW COLUMNS FROM #{quote_table_name(table_name)} LIKE '#{column_name}'")["Type"]
463 execute "ALTER TABLE #{quote_table_name(table_name)} CHANGE #{quote_column_name(column_name)} #{quote_column_name(new_column_name)} #{current_type}"
f1880cac » dhh 2005-07-05 Sugared up migrations with ... 464 end
465
a3754651 » David Heinemeier Hansson 2008-04-25 Added that the MySQL adapte... Comment 466 # Maps logical Rails types to MySQL-specific data types.
467 def type_to_sql(type, limit = nil, precision = nil, scale = nil)
468 return super unless type.to_s == 'integer'
469
470 case limit
471 when 0..3
472 "smallint(#{limit})"
473 when 4..8
474 "int(#{limit})"
475 when 9..20
476 "bigint(#{limit})"
477 else
478 'int(11)'
479 end
480 end
481
eac7cf0b » dhh 2005-03-01 Added preliminary support f... 482
ed2a84f9 » jeremy 2007-05-25 MySQL: create_database take... 483 # SHOW VARIABLES LIKE 'name'
484 def show_variable(name)
eb2e30ef » jeremy 2007-06-20 MySQL: fix show_variable. C... 485 variables = select_all("SHOW VARIABLES LIKE '#{name}'")
486 variables.first['Value'] unless variables.empty?
ed2a84f9 » jeremy 2007-05-25 MySQL: create_database take... 487 end
488
2d208eb3 » NZKoz 2007-10-24 Make sure that the Schema D... 489 # Returns a table's primary key and belonging sequence.
490 def pk_and_sequence_for(table) #:nodoc:
491 keys = []
96557eb3 » NZKoz 2007-10-25 Remove superfluous code and... 492 execute("describe #{quote_table_name(table)}").each_hash do |h|
2d208eb3 » NZKoz 2007-10-24 Make sure that the Schema D... 493 keys << h["Field"]if h["Key"] == "PRI"
494 end
495 keys.length == 1 ? [keys.first, nil] : nil
496 end
497
db045dbb » dhh 2004-11-23 Initial 498 private
e8f664dd » jeremy 2005-11-22 MySQL, PostgreSQL: reconnec... 499 def connect
500 encoding = @config[:encoding]
501 if encoding
224d47e0 » jeremy 2005-12-13 MySQL: allow encoding optio... 502 @connection.options(Mysql::SET_CHARSET_NAME, encoding) rescue nil
e8f664dd » jeremy 2005-11-22 MySQL, PostgreSQL: reconnec... 503 end
0227f86e » jeremy 2007-01-14 MySQL: retain SSL settings ... 504 @connection.ssl_set(@config[:sslkey], @config[:sslcert], @config[:sslca], @config[:sslcapath], @config[:sslcipher]) if @config[:sslkey]
e8f664dd » jeremy 2005-11-22 MySQL, PostgreSQL: reconnec... 505 @connection.real_connect(*@connection_options)
506 execute("SET NAMES '#{encoding}'") if encoding
8f5c12e4 » jeremy 2007-01-28 MySQL: SET SQL_AUTO_IS_NULL... 507
508 # By default, MySQL 'where id is null' selects the last inserted id.
509 # Turn this off. http://dev.rubyonrails.org/ticket/6778
510 execute("SET SQL_AUTO_IS_NULL=0")
e8f664dd » jeremy 2005-11-22 MySQL, PostgreSQL: reconnec... 511 end
512
db045dbb » dhh 2004-11-23 Initial 513 def select(sql, name = nil)
f3845822 » dhh 2005-02-20 Fixed that Active Record wo... 514 @connection.query_with_result = true
515 result = execute(sql, name)
48d4d43f » jeremy 2006-10-02 MySQL: introduce Mysql::Res... 516 rows = result.all_hashes
96c60b0e » jeremy 2005-07-03 r1603@asus: jeremy | 2005... 517 result.free
db045dbb » dhh 2004-11-23 Initial 518 rows
519 end
48d4d43f » jeremy 2006-10-02 MySQL: introduce Mysql::Res... 520
cee92312 » dhh 2006-03-15 Stop the MySQL adapter cras... 521 def supports_views?
522 version[0] >= 5
523 end
48d4d43f » jeremy 2006-10-02 MySQL: introduce Mysql::Res... 524
cee92312 » dhh 2006-03-15 Stop the MySQL adapter cras... 525 def version
526 @version ||= @connection.server_info.scan(/^(\d+)\.(\d+)\.(\d+)/).flatten.map { |v| v.to_i }
527 end
db045dbb » dhh 2004-11-23 Initial 528 end
529 end
c5f53ca3 » jamis 2005-09-25 Remove duplicate 'quote_col... 530 end