activerecord 5.0.7.2 → 5.1.0.beta1

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of activerecord might be problematic. Click here for more details.

Files changed (216) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +389 -2252
  3. data/MIT-LICENSE +1 -1
  4. data/README.rdoc +1 -1
  5. data/examples/performance.rb +28 -28
  6. data/examples/simple.rb +3 -3
  7. data/lib/active_record.rb +20 -20
  8. data/lib/active_record/aggregations.rb +244 -244
  9. data/lib/active_record/association_relation.rb +5 -5
  10. data/lib/active_record/associations.rb +1579 -1569
  11. data/lib/active_record/associations/alias_tracker.rb +1 -1
  12. data/lib/active_record/associations/association.rb +23 -15
  13. data/lib/active_record/associations/association_scope.rb +83 -81
  14. data/lib/active_record/associations/belongs_to_association.rb +0 -1
  15. data/lib/active_record/associations/builder/belongs_to.rb +16 -14
  16. data/lib/active_record/associations/builder/collection_association.rb +1 -2
  17. data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +27 -27
  18. data/lib/active_record/associations/collection_association.rb +74 -241
  19. data/lib/active_record/associations/collection_proxy.rb +144 -70
  20. data/lib/active_record/associations/has_many_association.rb +15 -19
  21. data/lib/active_record/associations/has_many_through_association.rb +12 -5
  22. data/lib/active_record/associations/has_one_association.rb +22 -28
  23. data/lib/active_record/associations/has_one_through_association.rb +5 -1
  24. data/lib/active_record/associations/join_dependency.rb +117 -115
  25. data/lib/active_record/associations/join_dependency/join_association.rb +16 -13
  26. data/lib/active_record/associations/join_dependency/join_base.rb +1 -1
  27. data/lib/active_record/associations/join_dependency/join_part.rb +1 -1
  28. data/lib/active_record/associations/preloader.rb +94 -94
  29. data/lib/active_record/associations/preloader/association.rb +87 -64
  30. data/lib/active_record/associations/preloader/belongs_to.rb +0 -2
  31. data/lib/active_record/associations/preloader/collection_association.rb +6 -6
  32. data/lib/active_record/associations/preloader/has_many.rb +0 -2
  33. data/lib/active_record/associations/preloader/singular_association.rb +6 -8
  34. data/lib/active_record/associations/preloader/through_association.rb +34 -41
  35. data/lib/active_record/associations/singular_association.rb +8 -25
  36. data/lib/active_record/associations/through_association.rb +3 -6
  37. data/lib/active_record/attribute.rb +98 -71
  38. data/lib/active_record/attribute/user_provided_default.rb +4 -2
  39. data/lib/active_record/attribute_assignment.rb +61 -61
  40. data/lib/active_record/attribute_decorators.rb +35 -13
  41. data/lib/active_record/attribute_methods.rb +56 -65
  42. data/lib/active_record/attribute_methods/before_type_cast.rb +7 -7
  43. data/lib/active_record/attribute_methods/dirty.rb +216 -34
  44. data/lib/active_record/attribute_methods/primary_key.rb +78 -73
  45. data/lib/active_record/attribute_methods/read.rb +39 -35
  46. data/lib/active_record/attribute_methods/serialization.rb +7 -7
  47. data/lib/active_record/attribute_methods/time_zone_conversion.rb +35 -58
  48. data/lib/active_record/attribute_methods/write.rb +36 -30
  49. data/lib/active_record/attribute_mutation_tracker.rb +53 -10
  50. data/lib/active_record/attribute_set.rb +9 -6
  51. data/lib/active_record/attribute_set/builder.rb +41 -49
  52. data/lib/active_record/attribute_set/yaml_encoder.rb +41 -0
  53. data/lib/active_record/attributes.rb +21 -21
  54. data/lib/active_record/autosave_association.rb +13 -13
  55. data/lib/active_record/base.rb +24 -22
  56. data/lib/active_record/callbacks.rb +52 -14
  57. data/lib/active_record/coders/yaml_column.rb +9 -11
  58. data/lib/active_record/collection_cache_key.rb +6 -17
  59. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +320 -278
  60. data/lib/active_record/connection_adapters/abstract/database_limits.rb +1 -3
  61. data/lib/active_record/connection_adapters/abstract/database_statements.rb +22 -34
  62. data/lib/active_record/connection_adapters/abstract/query_cache.rb +31 -27
  63. data/lib/active_record/connection_adapters/abstract/quoting.rb +44 -57
  64. data/lib/active_record/connection_adapters/abstract/schema_creation.rb +9 -19
  65. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +78 -79
  66. data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +53 -41
  67. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +99 -93
  68. data/lib/active_record/connection_adapters/abstract/transaction.rb +1 -5
  69. data/lib/active_record/connection_adapters/abstract_adapter.rb +156 -128
  70. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +424 -382
  71. data/lib/active_record/connection_adapters/column.rb +27 -5
  72. data/lib/active_record/connection_adapters/connection_specification.rb +128 -118
  73. data/lib/active_record/connection_adapters/mysql/column.rb +6 -31
  74. data/lib/active_record/connection_adapters/mysql/database_statements.rb +45 -43
  75. data/lib/active_record/connection_adapters/mysql/explain_pretty_printer.rb +22 -22
  76. data/lib/active_record/connection_adapters/mysql/quoting.rb +6 -12
  77. data/lib/active_record/connection_adapters/mysql/schema_creation.rb +49 -45
  78. data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +16 -19
  79. data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +49 -31
  80. data/lib/active_record/connection_adapters/mysql/type_metadata.rb +5 -6
  81. data/lib/active_record/connection_adapters/mysql2_adapter.rb +24 -26
  82. data/lib/active_record/connection_adapters/postgresql/column.rb +1 -28
  83. data/lib/active_record/connection_adapters/postgresql/database_statements.rb +46 -35
  84. data/lib/active_record/connection_adapters/postgresql/explain_pretty_printer.rb +3 -3
  85. data/lib/active_record/connection_adapters/postgresql/oid.rb +22 -21
  86. data/lib/active_record/connection_adapters/postgresql/oid/array.rb +9 -9
  87. data/lib/active_record/connection_adapters/postgresql/oid/bit.rb +5 -3
  88. data/lib/active_record/connection_adapters/postgresql/oid/bytea.rb +1 -1
  89. data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +1 -1
  90. data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +2 -2
  91. data/lib/active_record/connection_adapters/postgresql/oid/enum.rb +3 -3
  92. data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +16 -16
  93. data/lib/active_record/connection_adapters/postgresql/oid/{rails_5_1_point.rb → legacy_point.rb} +9 -16
  94. data/lib/active_record/connection_adapters/postgresql/oid/money.rb +2 -2
  95. data/lib/active_record/connection_adapters/postgresql/oid/oid.rb +13 -0
  96. data/lib/active_record/connection_adapters/postgresql/oid/point.rb +28 -8
  97. data/lib/active_record/connection_adapters/postgresql/oid/range.rb +28 -30
  98. data/lib/active_record/connection_adapters/postgresql/oid/specialized_string.rb +2 -1
  99. data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +51 -51
  100. data/lib/active_record/connection_adapters/postgresql/quoting.rb +38 -36
  101. data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +15 -0
  102. data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +37 -24
  103. data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +19 -23
  104. data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +161 -170
  105. data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +4 -4
  106. data/lib/active_record/connection_adapters/postgresql/utils.rb +9 -7
  107. data/lib/active_record/connection_adapters/postgresql_adapter.rb +179 -152
  108. data/lib/active_record/connection_adapters/schema_cache.rb +16 -7
  109. data/lib/active_record/connection_adapters/sql_type_metadata.rb +3 -3
  110. data/lib/active_record/connection_adapters/sqlite3/explain_pretty_printer.rb +1 -1
  111. data/lib/active_record/connection_adapters/sqlite3/quoting.rb +16 -20
  112. data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +1 -8
  113. data/lib/active_record/connection_adapters/sqlite3/schema_definitions.rb +28 -0
  114. data/lib/active_record/connection_adapters/sqlite3/schema_dumper.rb +17 -0
  115. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +187 -130
  116. data/lib/active_record/connection_adapters/statement_pool.rb +7 -7
  117. data/lib/active_record/connection_handling.rb +14 -26
  118. data/lib/active_record/core.rb +110 -93
  119. data/lib/active_record/counter_cache.rb +62 -13
  120. data/lib/active_record/define_callbacks.rb +20 -0
  121. data/lib/active_record/dynamic_matchers.rb +80 -79
  122. data/lib/active_record/enum.rb +8 -6
  123. data/lib/active_record/errors.rb +58 -15
  124. data/lib/active_record/explain.rb +1 -2
  125. data/lib/active_record/explain_registry.rb +1 -1
  126. data/lib/active_record/explain_subscriber.rb +7 -4
  127. data/lib/active_record/fixture_set/file.rb +11 -8
  128. data/lib/active_record/fixtures.rb +66 -53
  129. data/lib/active_record/gem_version.rb +3 -3
  130. data/lib/active_record/inheritance.rb +93 -79
  131. data/lib/active_record/integration.rb +7 -7
  132. data/lib/active_record/internal_metadata.rb +3 -16
  133. data/lib/active_record/legacy_yaml_adapter.rb +1 -1
  134. data/lib/active_record/locking/optimistic.rb +64 -56
  135. data/lib/active_record/locking/pessimistic.rb +10 -1
  136. data/lib/active_record/log_subscriber.rb +29 -29
  137. data/lib/active_record/migration.rb +155 -172
  138. data/lib/active_record/migration/command_recorder.rb +94 -94
  139. data/lib/active_record/migration/compatibility.rb +76 -37
  140. data/lib/active_record/migration/join_table.rb +6 -6
  141. data/lib/active_record/model_schema.rb +85 -119
  142. data/lib/active_record/nested_attributes.rb +200 -199
  143. data/lib/active_record/null_relation.rb +10 -33
  144. data/lib/active_record/persistence.rb +45 -38
  145. data/lib/active_record/query_cache.rb +4 -8
  146. data/lib/active_record/querying.rb +2 -3
  147. data/lib/active_record/railtie.rb +16 -17
  148. data/lib/active_record/railties/controller_runtime.rb +6 -2
  149. data/lib/active_record/railties/databases.rake +125 -140
  150. data/lib/active_record/railties/jdbcmysql_error.rb +1 -1
  151. data/lib/active_record/readonly_attributes.rb +2 -2
  152. data/lib/active_record/reflection.rb +79 -96
  153. data/lib/active_record/relation.rb +72 -115
  154. data/lib/active_record/relation/batches.rb +87 -58
  155. data/lib/active_record/relation/batches/batch_enumerator.rb +1 -1
  156. data/lib/active_record/relation/calculations.rb +154 -160
  157. data/lib/active_record/relation/delegation.rb +30 -29
  158. data/lib/active_record/relation/finder_methods.rb +195 -226
  159. data/lib/active_record/relation/merger.rb +58 -62
  160. data/lib/active_record/relation/predicate_builder.rb +92 -89
  161. data/lib/active_record/relation/predicate_builder/array_handler.rb +7 -5
  162. data/lib/active_record/relation/predicate_builder/association_query_handler.rb +23 -23
  163. data/lib/active_record/relation/predicate_builder/base_handler.rb +3 -1
  164. data/lib/active_record/relation/predicate_builder/basic_object_handler.rb +0 -8
  165. data/lib/active_record/relation/predicate_builder/polymorphic_array_handler.rb +12 -10
  166. data/lib/active_record/relation/predicate_builder/range_handler.rb +0 -8
  167. data/lib/active_record/relation/query_attribute.rb +1 -1
  168. data/lib/active_record/relation/query_methods.rb +247 -295
  169. data/lib/active_record/relation/record_fetch_warning.rb +3 -3
  170. data/lib/active_record/relation/spawn_methods.rb +4 -5
  171. data/lib/active_record/relation/where_clause.rb +79 -65
  172. data/lib/active_record/relation/where_clause_factory.rb +47 -8
  173. data/lib/active_record/result.rb +29 -31
  174. data/lib/active_record/runtime_registry.rb +3 -3
  175. data/lib/active_record/sanitization.rb +182 -197
  176. data/lib/active_record/schema.rb +3 -3
  177. data/lib/active_record/schema_dumper.rb +14 -37
  178. data/lib/active_record/schema_migration.rb +3 -3
  179. data/lib/active_record/scoping.rb +9 -10
  180. data/lib/active_record/scoping/default.rb +87 -91
  181. data/lib/active_record/scoping/named.rb +16 -28
  182. data/lib/active_record/secure_token.rb +2 -2
  183. data/lib/active_record/statement_cache.rb +13 -15
  184. data/lib/active_record/store.rb +31 -32
  185. data/lib/active_record/suppressor.rb +2 -1
  186. data/lib/active_record/table_metadata.rb +9 -5
  187. data/lib/active_record/tasks/database_tasks.rb +72 -65
  188. data/lib/active_record/tasks/mysql_database_tasks.rb +75 -72
  189. data/lib/active_record/tasks/postgresql_database_tasks.rb +53 -48
  190. data/lib/active_record/tasks/sqlite_database_tasks.rb +18 -16
  191. data/lib/active_record/timestamp.rb +39 -25
  192. data/lib/active_record/touch_later.rb +1 -2
  193. data/lib/active_record/transactions.rb +98 -110
  194. data/lib/active_record/type.rb +17 -13
  195. data/lib/active_record/type/adapter_specific_registry.rb +46 -42
  196. data/lib/active_record/type/decimal_without_scale.rb +9 -0
  197. data/lib/active_record/type/hash_lookup_type_map.rb +3 -3
  198. data/lib/active_record/type/serialized.rb +8 -8
  199. data/lib/active_record/type/text.rb +9 -0
  200. data/lib/active_record/type/time.rb +0 -1
  201. data/lib/active_record/type/type_map.rb +11 -15
  202. data/lib/active_record/type/unsigned_integer.rb +15 -0
  203. data/lib/active_record/type_caster.rb +2 -2
  204. data/lib/active_record/type_caster/connection.rb +8 -6
  205. data/lib/active_record/type_caster/map.rb +3 -1
  206. data/lib/active_record/validations.rb +4 -4
  207. data/lib/active_record/validations/associated.rb +1 -1
  208. data/lib/active_record/validations/presence.rb +2 -2
  209. data/lib/active_record/validations/uniqueness.rb +8 -39
  210. data/lib/active_record/version.rb +1 -1
  211. data/lib/rails/generators/active_record.rb +4 -4
  212. data/lib/rails/generators/active_record/migration.rb +2 -2
  213. data/lib/rails/generators/active_record/migration/migration_generator.rb +37 -34
  214. data/lib/rails/generators/active_record/model/model_generator.rb +9 -9
  215. metadata +22 -13
  216. data/lib/active_record/relation/predicate_builder/class_handler.rb +0 -27
@@ -36,34 +36,34 @@ module ActiveRecord
36
36
 
37
37
  private
38
38
 
39
- def compute_column_widths(result)
40
- [].tap do |widths|
41
- result.columns.each_with_index do |column, i|
42
- cells_in_column = [column] + result.rows.map {|r| r[i].nil? ? 'NULL' : r[i].to_s}
43
- widths << cells_in_column.map(&:length).max
39
+ def compute_column_widths(result)
40
+ [].tap do |widths|
41
+ result.columns.each_with_index do |column, i|
42
+ cells_in_column = [column] + result.rows.map { |r| r[i].nil? ? "NULL" : r[i].to_s }
43
+ widths << cells_in_column.map(&:length).max
44
+ end
44
45
  end
45
46
  end
46
- end
47
47
 
48
- def build_separator(widths)
49
- padding = 1
50
- '+' + widths.map {|w| '-' * (w + (padding*2))}.join('+') + '+'
51
- end
48
+ def build_separator(widths)
49
+ padding = 1
50
+ "+" + widths.map { |w| "-" * (w + (padding * 2)) }.join("+") + "+"
51
+ end
52
52
 
53
- def build_cells(items, widths)
54
- cells = []
55
- items.each_with_index do |item, i|
56
- item = 'NULL' if item.nil?
57
- justifier = item.is_a?(Numeric) ? 'rjust' : 'ljust'
58
- cells << item.to_s.send(justifier, widths[i])
53
+ def build_cells(items, widths)
54
+ cells = []
55
+ items.each_with_index do |item, i|
56
+ item = "NULL" if item.nil?
57
+ justifier = item.is_a?(Numeric) ? "rjust" : "ljust"
58
+ cells << item.to_s.send(justifier, widths[i])
59
+ end
60
+ "| " + cells.join(" | ") + " |"
59
61
  end
60
- '| ' + cells.join(' | ') + ' |'
61
- end
62
62
 
63
- def build_footer(nrows, elapsed)
64
- rows_label = nrows == 1 ? 'row' : 'rows'
65
- "#{nrows} #{rows_label} in set (%.2f sec)" % elapsed
66
- end
63
+ def build_footer(nrows, elapsed)
64
+ rows_label = nrows == 1 ? "row" : "rows"
65
+ "#{nrows} #{rows_label} in set (%.2f sec)" % elapsed
66
+ end
67
67
  end
68
68
  end
69
69
  end
@@ -2,14 +2,14 @@ module ActiveRecord
2
2
  module ConnectionAdapters
3
3
  module MySQL
4
4
  module Quoting # :nodoc:
5
- QUOTED_TRUE, QUOTED_FALSE = '1'.freeze, '0'.freeze
5
+ QUOTED_TRUE, QUOTED_FALSE = "1".freeze, "0".freeze
6
6
 
7
7
  def quote_column_name(name)
8
- @quoted_column_names[name] ||= "`#{super.gsub('`', '``')}`"
8
+ @quoted_column_names[name] ||= "`#{super.gsub('`', '``')}`".freeze
9
9
  end
10
10
 
11
11
  def quote_table_name(name)
12
- @quoted_table_names[name] ||= super.gsub('.', '`.`')
12
+ @quoted_table_names[name] ||= super.gsub(".", "`.`").freeze
13
13
  end
14
14
 
15
15
  def quoted_true
@@ -32,18 +32,12 @@ module ActiveRecord
32
32
  if supports_datetime_with_precision?
33
33
  super
34
34
  else
35
- super.sub(/\.\d{6}\z/, '')
35
+ super.sub(/\.\d{6}\z/, "")
36
36
  end
37
37
  end
38
38
 
39
- private
40
-
41
- def _quote(value)
42
- if value.is_a?(Type::Binary::Data)
43
- "x'#{value.hex}'"
44
- else
45
- super
46
- end
39
+ def quoted_binary(value)
40
+ "x'#{value.hex}'"
47
41
  end
48
42
  end
49
43
  end
@@ -1,66 +1,70 @@
1
1
  module ActiveRecord
2
2
  module ConnectionAdapters
3
3
  module MySQL
4
- class SchemaCreation < AbstractAdapter::SchemaCreation
5
- delegate :add_sql_comment!, to: :@conn
6
- private :add_sql_comment!
4
+ class SchemaCreation < AbstractAdapter::SchemaCreation # :nodoc:
5
+ delegate :add_sql_comment!, :mariadb?, to: :@conn
6
+ private :add_sql_comment!, :mariadb?
7
7
 
8
8
  private
9
9
 
10
- def visit_DropForeignKey(name)
11
- "DROP FOREIGN KEY #{name}"
12
- end
10
+ def visit_DropForeignKey(name)
11
+ "DROP FOREIGN KEY #{name}"
12
+ end
13
+
14
+ def visit_AddColumnDefinition(o)
15
+ add_column_position!(super, column_options(o.column))
16
+ end
13
17
 
14
- def visit_ColumnDefinition(o)
15
- o.sql_type = type_to_sql(o.type, o.limit, o.precision, o.scale, o.unsigned)
16
- super
17
- end
18
+ def visit_ChangeColumnDefinition(o)
19
+ change_column_sql = "CHANGE #{quote_column_name(o.name)} #{accept(o.column)}"
20
+ add_column_position!(change_column_sql, column_options(o.column))
21
+ end
18
22
 
19
- def visit_AddColumnDefinition(o)
20
- add_column_position!(super, column_options(o.column))
21
- end
23
+ def add_table_options!(create_sql, options)
24
+ add_sql_comment!(super, options[:comment])
25
+ end
22
26
 
23
- def visit_ChangeColumnDefinition(o)
24
- change_column_sql = "CHANGE #{quote_column_name(o.name)} #{accept(o.column)}"
25
- add_column_position!(change_column_sql, column_options(o.column))
26
- end
27
+ def add_column_options!(sql, options)
28
+ # By default, TIMESTAMP columns are NOT NULL, cannot contain NULL values,
29
+ # and assigning NULL assigns the current timestamp. To permit a TIMESTAMP
30
+ # column to contain NULL, explicitly declare it with the NULL attribute.
31
+ # See http://dev.mysql.com/doc/refman/5.7/en/timestamp-initialization.html
32
+ if /\Atimestamp\b/.match?(options[:column].sql_type) && !options[:primary_key]
33
+ sql << " NULL" unless options[:null] == false || options_include_default?(options)
34
+ end
27
35
 
28
- def add_table_options!(create_sql, options)
29
- add_sql_comment!(super, options[:comment])
30
- end
36
+ if charset = options[:charset]
37
+ sql << " CHARACTER SET #{charset}"
38
+ end
31
39
 
32
- def column_options(o)
33
- column_options = super
34
- column_options[:charset] = o.charset
35
- column_options
36
- end
40
+ if collation = options[:collation]
41
+ sql << " COLLATE #{collation}"
42
+ end
37
43
 
38
- def add_column_options!(sql, options)
39
- if charset = options[:charset]
40
- sql << " CHARACTER SET #{charset}"
41
- end
44
+ if as = options[:as]
45
+ sql << " AS (#{as})"
46
+ if options[:stored]
47
+ sql << (mariadb? ? " PERSISTENT" : " STORED")
48
+ end
49
+ end
42
50
 
43
- if collation = options[:collation]
44
- sql << " COLLATE #{collation}"
51
+ add_sql_comment!(super, options[:comment])
45
52
  end
46
53
 
47
- add_sql_comment!(super, options[:comment])
48
- end
54
+ def add_column_position!(sql, options)
55
+ if options[:first]
56
+ sql << " FIRST"
57
+ elsif options[:after]
58
+ sql << " AFTER #{quote_column_name(options[:after])}"
59
+ end
49
60
 
50
- def add_column_position!(sql, options)
51
- if options[:first]
52
- sql << " FIRST"
53
- elsif options[:after]
54
- sql << " AFTER #{quote_column_name(options[:after])}"
61
+ sql
55
62
  end
56
63
 
57
- sql
58
- end
59
-
60
- def index_in_create(table_name, column_name, options)
61
- index_name, index_type, index_columns, _, _, index_using, comment = @conn.add_index_options(table_name, column_name, options)
62
- add_sql_comment!("#{index_type} INDEX #{quote_column_name(index_name)} #{index_using} (#{index_columns})", comment)
63
- end
64
+ def index_in_create(table_name, column_name, options)
65
+ index_name, index_type, index_columns, _, _, index_using, comment = @conn.add_index_options(table_name, column_name, options)
66
+ add_sql_comment!("#{index_type} INDEX #{quote_column_name(index_name)} #{index_using} (#{index_columns})", comment)
67
+ end
64
68
  end
65
69
  end
66
70
  end
@@ -3,7 +3,7 @@ module ActiveRecord
3
3
  module MySQL
4
4
  module ColumnMethods
5
5
  def primary_key(name, type = :primary_key, **options)
6
- options[:auto_increment] = true if type == :bigint && !options.key?(:default)
6
+ options[:auto_increment] = true if [:integer, :bigint].include?(type) && !options.key?(:default)
7
7
  super
8
8
  end
9
9
 
@@ -56,33 +56,30 @@ module ActiveRecord
56
56
  end
57
57
  end
58
58
 
59
- class ColumnDefinition < ActiveRecord::ConnectionAdapters::ColumnDefinition
60
- attr_accessor :charset, :unsigned
61
- end
62
-
63
59
  class TableDefinition < ActiveRecord::ConnectionAdapters::TableDefinition
64
60
  include ColumnMethods
65
61
 
66
- def new_column_definition(name, type, options) # :nodoc:
67
- column = super
68
- case column.type
62
+ def new_column_definition(name, type, **options) # :nodoc:
63
+ case type
64
+ when :virtual
65
+ type = options[:type]
69
66
  when :primary_key
70
- column.type = :integer
71
- column.auto_increment = true
67
+ type = :integer
68
+ options[:limit] ||= 8
69
+ options[:auto_increment] = true
70
+ options[:primary_key] = true
72
71
  when /\Aunsigned_(?<type>.+)\z/
73
- column.type = $~[:type].to_sym
74
- column.unsigned = true
72
+ type = $~[:type].to_sym
73
+ options[:unsigned] = true
75
74
  end
76
- column.unsigned ||= options[:unsigned]
77
- column.charset = options[:charset]
78
- column
75
+
76
+ super
79
77
  end
80
78
 
81
79
  private
82
-
83
- def create_column_definition(name, type)
84
- MySQL::ColumnDefinition.new(name, type)
85
- end
80
+ def aliased_types(name, fallback)
81
+ fallback
82
+ end
86
83
  end
87
84
 
88
85
  class Table < ActiveRecord::ConnectionAdapters::Table
@@ -1,21 +1,17 @@
1
1
  module ActiveRecord
2
2
  module ConnectionAdapters
3
3
  module MySQL
4
- module ColumnDumper
5
- def column_spec_for_primary_key(column)
6
- if column.bigint?
7
- spec = { id: :bigint.inspect }
8
- spec[:default] = schema_default(column) || 'nil' unless column.auto_increment?
9
- else
10
- spec = super
11
- end
12
- spec[:unsigned] = 'true' if column.unsigned?
13
- spec
14
- end
15
-
4
+ module ColumnDumper # :nodoc:
16
5
  def prepare_column_options(column)
17
6
  spec = super
18
- spec[:unsigned] = 'true' if column.unsigned?
7
+ spec[:unsigned] = "true" if column.unsigned?
8
+
9
+ if supports_virtual_columns? && column.virtual?
10
+ spec[:as] = extract_expression_for_virtual_column(column)
11
+ spec[:stored] = "true" if /\b(?:STORED|PERSISTENT)\b/.match?(column.extra)
12
+ spec = { type: schema_type(column).inspect }.merge!(spec)
13
+ end
14
+
19
15
  spec
20
16
  end
21
17
 
@@ -25,29 +21,51 @@ module ActiveRecord
25
21
 
26
22
  private
27
23
 
28
- def default_primary_key?(column)
29
- super && column.auto_increment?
30
- end
24
+ def default_primary_key?(column)
25
+ super && column.auto_increment? && !column.unsigned?
26
+ end
31
27
 
32
- def schema_type(column)
33
- if column.sql_type == 'tinyblob'
34
- :blob
35
- else
36
- super
28
+ def explicit_primary_key_default?(column)
29
+ column.type == :integer && !column.auto_increment?
37
30
  end
38
- end
39
31
 
40
- def schema_precision(column)
41
- super unless /time/ === column.sql_type && column.precision == 0
42
- end
32
+ def schema_type(column)
33
+ case column.sql_type
34
+ when /\Atimestamp\b/
35
+ :timestamp
36
+ when "tinyblob"
37
+ :blob
38
+ else
39
+ super
40
+ end
41
+ end
43
42
 
44
- def schema_collation(column)
45
- if column.collation && table_name = column.table_name
46
- @table_collation_cache ||= {}
47
- @table_collation_cache[table_name] ||= select_one("SHOW TABLE STATUS LIKE '#{table_name}'")["Collation"]
48
- column.collation.inspect if column.collation != @table_collation_cache[table_name]
43
+ def schema_precision(column)
44
+ super unless /\A(?:date)?time(?:stamp)?\b/.match?(column.sql_type) && column.precision == 0
45
+ end
46
+
47
+ def schema_collation(column)
48
+ if column.collation && table_name = column.table_name
49
+ @table_collation_cache ||= {}
50
+ @table_collation_cache[table_name] ||= select_one("SHOW TABLE STATUS LIKE '#{table_name}'")["Collation"]
51
+ column.collation.inspect if column.collation != @table_collation_cache[table_name]
52
+ end
53
+ end
54
+
55
+ def extract_expression_for_virtual_column(column)
56
+ if mariadb?
57
+ create_table_info = create_table_info(column.table_name)
58
+ if %r/#{quote_column_name(column.name)} #{Regexp.quote(column.sql_type)} AS \((?<expression>.+?)\) #{column.extra}/m =~ create_table_info
59
+ $~[:expression].inspect
60
+ end
61
+ else
62
+ sql = "SELECT generation_expression FROM information_schema.columns" \
63
+ " WHERE table_schema = #{quote(@config[:database])}" \
64
+ " AND table_name = #{quote(column.table_name)}" \
65
+ " AND column_name = #{quote(column.name)}"
66
+ select_value(sql, "SCHEMA").inspect
67
+ end
49
68
  end
50
- end
51
69
  end
52
70
  end
53
71
  end
@@ -2,13 +2,12 @@ module ActiveRecord
2
2
  module ConnectionAdapters
3
3
  module MySQL
4
4
  class TypeMetadata < DelegateClass(SqlTypeMetadata) # :nodoc:
5
- attr_reader :extra, :strict
5
+ attr_reader :extra
6
6
 
7
- def initialize(type_metadata, extra: "", strict: false)
7
+ def initialize(type_metadata, extra: "")
8
8
  super(type_metadata)
9
9
  @type_metadata = type_metadata
10
10
  @extra = extra
11
- @strict = strict
12
11
  end
13
12
 
14
13
  def ==(other)
@@ -23,9 +22,9 @@ module ActiveRecord
23
22
 
24
23
  protected
25
24
 
26
- def attributes_for_hash
27
- [self.class, @type_metadata, extra, strict]
28
- end
25
+ def attributes_for_hash
26
+ [self.class, @type_metadata, extra]
27
+ end
29
28
  end
30
29
  end
31
30
  end
@@ -1,9 +1,9 @@
1
- require 'active_record/connection_adapters/abstract_mysql_adapter'
2
- require 'active_record/connection_adapters/mysql/database_statements'
1
+ require "active_record/connection_adapters/abstract_mysql_adapter"
2
+ require "active_record/connection_adapters/mysql/database_statements"
3
3
 
4
- gem 'mysql2', '>= 0.3.18', '< 0.6.0'
5
- require 'mysql2'
6
- raise 'mysql2 0.4.3 is not supported. Please upgrade to 0.4.4+' if Mysql2::VERSION == '0.4.3'
4
+ gem "mysql2", ">= 0.3.18", "< 0.5"
5
+ require "mysql2"
6
+ raise "mysql2 0.4.3 is not supported. Please upgrade to 0.4.4+" if Mysql2::VERSION == "0.4.3"
7
7
 
8
8
  module ActiveRecord
9
9
  module ConnectionHandling # :nodoc:
@@ -11,15 +11,13 @@ module ActiveRecord
11
11
  def mysql2_connection(config)
12
12
  config = config.symbolize_keys
13
13
 
14
- config[:username] = 'root' if config[:username].nil?
14
+ config[:username] = "root" if config[:username].nil?
15
15
  config[:flags] ||= 0
16
16
 
17
- if Mysql2::Client.const_defined? :FOUND_ROWS
18
- if config[:flags].kind_of? Array
19
- config[:flags].push "FOUND_ROWS".freeze
20
- else
21
- config[:flags] |= Mysql2::Client::FOUND_ROWS
22
- end
17
+ if config[:flags].kind_of? Array
18
+ config[:flags].push "FOUND_ROWS".freeze
19
+ else
20
+ config[:flags] |= Mysql2::Client::FOUND_ROWS
23
21
  end
24
22
 
25
23
  client = Mysql2::Client.new(config)
@@ -35,7 +33,7 @@ module ActiveRecord
35
33
 
36
34
  module ConnectionAdapters
37
35
  class Mysql2Adapter < AbstractMysqlAdapter
38
- ADAPTER_NAME = 'Mysql2'.freeze
36
+ ADAPTER_NAME = "Mysql2".freeze
39
37
 
40
38
  include MySQL::DatabaseStatements
41
39
 
@@ -46,7 +44,7 @@ module ActiveRecord
46
44
  end
47
45
 
48
46
  def supports_json?
49
- !mariadb? && version >= '5.7.8'
47
+ !mariadb? && version >= "5.7.8"
50
48
  end
51
49
 
52
50
  def supports_comments?
@@ -65,7 +63,7 @@ module ActiveRecord
65
63
 
66
64
  def each_hash(result) # :nodoc:
67
65
  if block_given?
68
- result.each(:as => :hash, :symbolize_keys => true) do |row|
66
+ result.each(as: :hash, symbolize_keys: true) do |row|
69
67
  yield row
70
68
  end
71
69
  else
@@ -109,19 +107,19 @@ module ActiveRecord
109
107
 
110
108
  private
111
109
 
112
- def connect
113
- @connection = Mysql2::Client.new(@config)
114
- configure_connection
115
- end
110
+ def connect
111
+ @connection = Mysql2::Client.new(@config)
112
+ configure_connection
113
+ end
116
114
 
117
- def configure_connection
118
- @connection.query_options.merge!(:as => :array)
119
- super
120
- end
115
+ def configure_connection
116
+ @connection.query_options.merge!(as: :array)
117
+ super
118
+ end
121
119
 
122
- def full_version
123
- @full_version ||= @connection.server_info[:version]
124
- end
120
+ def full_version
121
+ @full_version ||= @connection.server_info[:version]
122
+ end
125
123
  end
126
124
  end
127
125
  end