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
@@ -11,10 +11,10 @@ module ActiveRecord
11
11
 
12
12
  def create
13
13
  establish_connection configuration_without_database
14
- connection.create_database configuration['database'], creation_options
14
+ connection.create_database configuration["database"], creation_options
15
15
  establish_connection configuration
16
16
  rescue ActiveRecord::StatementInvalid => error
17
- if /database exists/ === error.message
17
+ if error.message.include?("database exists")
18
18
  raise DatabaseAlreadyExists
19
19
  else
20
20
  raise
@@ -23,26 +23,26 @@ module ActiveRecord
23
23
  if error.respond_to?(:errno) && error.errno == ACCESS_DENIED_ERROR
24
24
  $stdout.print error.message
25
25
  establish_connection root_configuration_without_database
26
- connection.create_database configuration['database'], creation_options
27
- if configuration['username'] != 'root'
28
- connection.execute grant_statement.gsub(/\s+/, ' ').strip
26
+ connection.create_database configuration["database"], creation_options
27
+ if configuration["username"] != "root"
28
+ connection.execute grant_statement.gsub(/\s+/, " ").strip
29
29
  end
30
30
  establish_connection configuration
31
31
  else
32
32
  $stderr.puts error.inspect
33
33
  $stderr.puts "Couldn't create database for #{configuration.inspect}, #{creation_options.inspect}"
34
- $stderr.puts "(If you set the charset manually, make sure you have a matching collation)" if configuration['encoding']
34
+ $stderr.puts "(If you set the charset manually, make sure you have a matching collation)" if configuration["encoding"]
35
35
  end
36
36
  end
37
37
 
38
38
  def drop
39
39
  establish_connection configuration
40
- connection.drop_database configuration['database']
40
+ connection.drop_database configuration["database"]
41
41
  end
42
42
 
43
43
  def purge
44
44
  establish_connection configuration
45
- connection.recreate_database configuration['database'], creation_options
45
+ connection.recreate_database configuration["database"], creation_options
46
46
  end
47
47
 
48
48
  def charset
@@ -53,99 +53,102 @@ module ActiveRecord
53
53
  connection.collation
54
54
  end
55
55
 
56
- def structure_dump(filename)
56
+ def structure_dump(filename, extra_flags)
57
57
  args = prepare_command_options
58
58
  args.concat(["--result-file", "#{filename}"])
59
59
  args.concat(["--no-data"])
60
60
  args.concat(["--routines"])
61
+ args.concat(["--skip-comments"])
62
+ args.concat(Array(extra_flags)) if extra_flags
61
63
  args.concat(["#{configuration['database']}"])
62
64
 
63
- run_cmd('mysqldump', args, 'dumping')
65
+ run_cmd("mysqldump", args, "dumping")
64
66
  end
65
67
 
66
- def structure_load(filename)
68
+ def structure_load(filename, extra_flags)
67
69
  args = prepare_command_options
68
- args.concat(['--execute', %{SET FOREIGN_KEY_CHECKS = 0; SOURCE #{filename}; SET FOREIGN_KEY_CHECKS = 1}])
70
+ args.concat(["--execute", %{SET FOREIGN_KEY_CHECKS = 0; SOURCE #{filename}; SET FOREIGN_KEY_CHECKS = 1}])
69
71
  args.concat(["--database", "#{configuration['database']}"])
72
+ args.concat(Array(extra_flags)) if extra_flags
70
73
 
71
- run_cmd('mysql', args, 'loading')
74
+ run_cmd("mysql", args, "loading")
72
75
  end
73
76
 
74
77
  private
75
78
 
76
- def configuration
77
- @configuration
78
- end
79
+ def configuration
80
+ @configuration
81
+ end
79
82
 
80
- def configuration_without_database
81
- configuration.merge('database' => nil)
82
- end
83
+ def configuration_without_database
84
+ configuration.merge("database" => nil)
85
+ end
83
86
 
84
- def creation_options
85
- Hash.new.tap do |options|
86
- options[:charset] = configuration['encoding'] if configuration.include? 'encoding'
87
- options[:collation] = configuration['collation'] if configuration.include? 'collation'
87
+ def creation_options
88
+ Hash.new.tap do |options|
89
+ options[:charset] = configuration["encoding"] if configuration.include? "encoding"
90
+ options[:collation] = configuration["collation"] if configuration.include? "collation"
91
+ end
88
92
  end
89
- end
90
93
 
91
- def error_class
92
- if configuration['adapter'] =~ /jdbc/
93
- require 'active_record/railties/jdbcmysql_error'
94
- ArJdbcMySQL::Error
95
- elsif defined?(Mysql2)
96
- Mysql2::Error
97
- else
98
- StandardError
94
+ def error_class
95
+ if configuration["adapter"].include?("jdbc")
96
+ require "active_record/railties/jdbcmysql_error"
97
+ ArJdbcMySQL::Error
98
+ elsif defined?(Mysql2)
99
+ Mysql2::Error
100
+ else
101
+ StandardError
102
+ end
99
103
  end
100
- end
101
104
 
102
- def grant_statement
103
- <<-SQL
105
+ def grant_statement
106
+ <<-SQL
104
107
  GRANT ALL PRIVILEGES ON #{configuration['database']}.*
105
108
  TO '#{configuration['username']}'@'localhost'
106
109
  IDENTIFIED BY '#{configuration['password']}' WITH GRANT OPTION;
107
- SQL
108
- end
110
+ SQL
111
+ end
109
112
 
110
- def root_configuration_without_database
111
- configuration_without_database.merge(
112
- 'username' => 'root',
113
- 'password' => root_password
114
- )
115
- end
113
+ def root_configuration_without_database
114
+ configuration_without_database.merge(
115
+ "username" => "root",
116
+ "password" => root_password
117
+ )
118
+ end
116
119
 
117
- def root_password
118
- $stdout.print "Please provide the root password for your MySQL installation\n>"
119
- $stdin.gets.strip
120
- end
120
+ def root_password
121
+ $stdout.print "Please provide the root password for your MySQL installation\n>"
122
+ $stdin.gets.strip
123
+ end
121
124
 
122
- def prepare_command_options
123
- args = {
124
- 'host' => '--host',
125
- 'port' => '--port',
126
- 'socket' => '--socket',
127
- 'username' => '--user',
128
- 'password' => '--password',
129
- 'encoding' => '--default-character-set',
130
- 'sslca' => '--ssl-ca',
131
- 'sslcert' => '--ssl-cert',
132
- 'sslcapath' => '--ssl-capath',
133
- 'sslcipher' => '--ssl-cipher',
134
- 'sslkey' => '--ssl-key'
135
- }.map { |opt, arg| "#{arg}=#{configuration[opt]}" if configuration[opt] }.compact
136
-
137
- args
138
- end
125
+ def prepare_command_options
126
+ args = {
127
+ "host" => "--host",
128
+ "port" => "--port",
129
+ "socket" => "--socket",
130
+ "username" => "--user",
131
+ "password" => "--password",
132
+ "encoding" => "--default-character-set",
133
+ "sslca" => "--ssl-ca",
134
+ "sslcert" => "--ssl-cert",
135
+ "sslcapath" => "--ssl-capath",
136
+ "sslcipher" => "--ssl-cipher",
137
+ "sslkey" => "--ssl-key"
138
+ }.map { |opt, arg| "#{arg}=#{configuration[opt]}" if configuration[opt] }.compact
139
+
140
+ args
141
+ end
139
142
 
140
- def run_cmd(cmd, args, action)
141
- fail run_cmd_error(cmd, args, action) unless Kernel.system(cmd, *args)
142
- end
143
+ def run_cmd(cmd, args, action)
144
+ fail run_cmd_error(cmd, args, action) unless Kernel.system(cmd, *args)
145
+ end
143
146
 
144
- def run_cmd_error(cmd, args, action)
145
- msg = "failed to execute: `#{cmd}`\n"
146
- msg << "Please check the output above for any errors and make sure that `#{cmd}` is installed in your PATH and has proper permissions.\n\n"
147
- msg
148
- end
147
+ def run_cmd_error(cmd, args, action)
148
+ msg = "failed to execute: `#{cmd}`\n"
149
+ msg << "Please check the output above for any errors and make sure that `#{cmd}` is installed in your PATH and has proper permissions.\n\n"
150
+ msg
151
+ end
149
152
  end
150
153
  end
151
154
  end
@@ -1,7 +1,8 @@
1
1
  module ActiveRecord
2
2
  module Tasks # :nodoc:
3
3
  class PostgreSQLDatabaseTasks # :nodoc:
4
- DEFAULT_ENCODING = ENV['CHARSET'] || 'utf8'
4
+ DEFAULT_ENCODING = ENV["CHARSET"] || "utf8"
5
+ ON_ERROR_STOP_1 = "ON_ERROR_STOP=1".freeze
5
6
 
6
7
  delegate :connection, :establish_connection, :clear_active_connections!,
7
8
  to: ActiveRecord::Base
@@ -12,11 +13,11 @@ module ActiveRecord
12
13
 
13
14
  def create(master_established = false)
14
15
  establish_master_connection unless master_established
15
- connection.create_database configuration['database'],
16
- configuration.merge('encoding' => encoding)
16
+ connection.create_database configuration["database"],
17
+ configuration.merge("encoding" => encoding)
17
18
  establish_connection configuration
18
19
  rescue ActiveRecord::StatementInvalid => error
19
- if error.cause.is_a?(PG::DuplicateDatabase)
20
+ if /database .* already exists/.match?(error.message)
20
21
  raise DatabaseAlreadyExists
21
22
  else
22
23
  raise
@@ -25,7 +26,7 @@ module ActiveRecord
25
26
 
26
27
  def drop
27
28
  establish_master_connection
28
- connection.drop_database configuration['database']
29
+ connection.drop_database configuration["database"]
29
30
  end
30
31
 
31
32
  def charset
@@ -42,69 +43,73 @@ module ActiveRecord
42
43
  create true
43
44
  end
44
45
 
45
- def structure_dump(filename)
46
+ def structure_dump(filename, extra_flags)
46
47
  set_psql_env
47
48
 
48
- search_path = case ActiveRecord::Base.dump_schemas
49
- when :schema_search_path
50
- configuration['schema_search_path']
51
- when :all
52
- nil
53
- when String
54
- ActiveRecord::Base.dump_schemas
55
- end
49
+ search_path = \
50
+ case ActiveRecord::Base.dump_schemas
51
+ when :schema_search_path
52
+ configuration["schema_search_path"]
53
+ when :all
54
+ nil
55
+ when String
56
+ ActiveRecord::Base.dump_schemas
57
+ end
56
58
 
57
- args = ['-s', '-x', '-O', '-f', filename]
59
+ args = ["-s", "-x", "-O", "-f", filename]
60
+ args.concat(Array(extra_flags)) if extra_flags
58
61
  unless search_path.blank?
59
- args += search_path.split(',').map do |part|
62
+ args += search_path.split(",").map do |part|
60
63
  "--schema=#{part.strip}"
61
64
  end
62
65
  end
63
- args << configuration['database']
64
- run_cmd('pg_dump', args, 'dumping')
66
+ args << configuration["database"]
67
+ run_cmd("pg_dump", args, "dumping")
65
68
  File.open(filename, "a") { |f| f << "SET search_path TO #{connection.schema_search_path};\n\n" }
66
69
  end
67
70
 
68
- def structure_load(filename)
71
+ def structure_load(filename, extra_flags)
69
72
  set_psql_env
70
- args = [ '-q', '-f', filename, configuration['database'] ]
71
- run_cmd('psql', args, 'loading' )
73
+ args = ["-v", ON_ERROR_STOP_1, "-q", "-f", filename]
74
+ args.concat(Array(extra_flags)) if extra_flags
75
+ args << configuration["database"]
76
+ run_cmd("psql", args, "loading")
72
77
  end
73
78
 
74
79
  private
75
80
 
76
- def configuration
77
- @configuration
78
- end
81
+ def configuration
82
+ @configuration
83
+ end
79
84
 
80
- def encoding
81
- configuration['encoding'] || DEFAULT_ENCODING
82
- end
85
+ def encoding
86
+ configuration["encoding"] || DEFAULT_ENCODING
87
+ end
83
88
 
84
- def establish_master_connection
85
- establish_connection configuration.merge(
86
- 'database' => 'postgres',
87
- 'schema_search_path' => 'public'
88
- )
89
- end
89
+ def establish_master_connection
90
+ establish_connection configuration.merge(
91
+ "database" => "postgres",
92
+ "schema_search_path" => "public"
93
+ )
94
+ end
90
95
 
91
- def set_psql_env
92
- ENV['PGHOST'] = configuration['host'] if configuration['host']
93
- ENV['PGPORT'] = configuration['port'].to_s if configuration['port']
94
- ENV['PGPASSWORD'] = configuration['password'].to_s if configuration['password']
95
- ENV['PGUSER'] = configuration['username'].to_s if configuration['username']
96
- end
96
+ def set_psql_env
97
+ ENV["PGHOST"] = configuration["host"] if configuration["host"]
98
+ ENV["PGPORT"] = configuration["port"].to_s if configuration["port"]
99
+ ENV["PGPASSWORD"] = configuration["password"].to_s if configuration["password"]
100
+ ENV["PGUSER"] = configuration["username"].to_s if configuration["username"]
101
+ end
97
102
 
98
- def run_cmd(cmd, args, action)
99
- fail run_cmd_error(cmd, args, action) unless Kernel.system(cmd, *args)
100
- end
103
+ def run_cmd(cmd, args, action)
104
+ fail run_cmd_error(cmd, args, action) unless Kernel.system(cmd, *args)
105
+ end
101
106
 
102
- def run_cmd_error(cmd, args, action)
103
- msg = "failed to execute:\n"
104
- msg << "#{cmd} #{args.join(' ')}\n\n"
105
- msg << "Please check the output above for any errors and make sure that `#{cmd}` is installed in your PATH and has proper permissions.\n\n"
106
- msg
107
- end
107
+ def run_cmd_error(cmd, args, action)
108
+ msg = "failed to execute:\n"
109
+ msg << "#{cmd} #{args.join(' ')}\n\n"
110
+ msg << "Please check the output above for any errors and make sure that `#{cmd}` is installed in your PATH and has proper permissions.\n\n"
111
+ msg
112
+ end
108
113
  end
109
114
  end
110
115
  end
@@ -8,20 +8,20 @@ module ActiveRecord
8
8
  end
9
9
 
10
10
  def create
11
- raise DatabaseAlreadyExists if File.exist?(configuration['database'])
11
+ raise DatabaseAlreadyExists if File.exist?(configuration["database"])
12
12
 
13
13
  establish_connection configuration
14
14
  connection
15
15
  end
16
16
 
17
17
  def drop
18
- require 'pathname'
19
- path = Pathname.new configuration['database']
18
+ require "pathname"
19
+ path = Pathname.new configuration["database"]
20
20
  file = path.absolute? ? path.to_s : File.join(root, path)
21
21
 
22
22
  FileUtils.rm(file)
23
23
  rescue Errno::ENOENT => error
24
- raise NoDatabaseError.new(error.message, error)
24
+ raise NoDatabaseError.new(error.message)
25
25
  end
26
26
 
27
27
  def purge
@@ -35,25 +35,27 @@ module ActiveRecord
35
35
  connection.encoding
36
36
  end
37
37
 
38
- def structure_dump(filename)
39
- dbfile = configuration['database']
40
- `sqlite3 #{dbfile} .schema > #{filename}`
38
+ def structure_dump(filename, extra_flags)
39
+ dbfile = configuration["database"]
40
+ flags = extra_flags.join(" ") if extra_flags
41
+ `sqlite3 #{flags} #{dbfile} .schema > #{filename}`
41
42
  end
42
43
 
43
- def structure_load(filename)
44
- dbfile = configuration['database']
45
- `sqlite3 #{dbfile} < "#{filename}"`
44
+ def structure_load(filename, extra_flags)
45
+ dbfile = configuration["database"]
46
+ flags = extra_flags.join(" ") if extra_flags
47
+ `sqlite3 #{flags} #{dbfile} < "#{filename}"`
46
48
  end
47
49
 
48
50
  private
49
51
 
50
- def configuration
51
- @configuration
52
- end
52
+ def configuration
53
+ @configuration
54
+ end
53
55
 
54
- def root
55
- @root
56
- end
56
+ def root
57
+ @root
58
+ end
57
59
  end
58
60
  end
59
61
  end
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module ActiveRecord
2
3
  # = Active Record \Timestamp
3
4
  #
@@ -51,15 +52,41 @@ module ActiveRecord
51
52
  clear_timestamp_attributes
52
53
  end
53
54
 
55
+ class_methods do
56
+ private
57
+ def timestamp_attributes_for_create_in_model
58
+ timestamp_attributes_for_create.select { |c| column_names.include?(c) }
59
+ end
60
+
61
+ def timestamp_attributes_for_update_in_model
62
+ timestamp_attributes_for_update.select { |c| column_names.include?(c) }
63
+ end
64
+
65
+ def all_timestamp_attributes_in_model
66
+ timestamp_attributes_for_create_in_model + timestamp_attributes_for_update_in_model
67
+ end
68
+
69
+ def timestamp_attributes_for_create
70
+ ["created_at", "created_on"]
71
+ end
72
+
73
+ def timestamp_attributes_for_update
74
+ ["updated_at", "updated_on"]
75
+ end
76
+
77
+ def current_time_from_proper_timezone
78
+ default_timezone == :utc ? Time.now.utc : Time.now
79
+ end
80
+ end
81
+
54
82
  private
55
83
 
56
84
  def _create_record
57
- if self.record_timestamps
85
+ if record_timestamps
58
86
  current_time = current_time_from_proper_timezone
59
87
 
60
- all_timestamp_attributes.each do |column|
61
- column = column.to_s
62
- if has_attribute?(column) && !attribute_present?(column)
88
+ all_timestamp_attributes_in_model.each do |column|
89
+ if !attribute_present?(column)
63
90
  write_attribute(column, current_time)
64
91
  end
65
92
  end
@@ -73,8 +100,7 @@ module ActiveRecord
73
100
  current_time = current_time_from_proper_timezone
74
101
 
75
102
  timestamp_attributes_for_update_in_model.each do |column|
76
- column = column.to_s
77
- next if attribute_changed?(column)
103
+ next if will_save_change_to_attribute?(column)
78
104
  write_attribute(column, current_time)
79
105
  end
80
106
  end
@@ -82,34 +108,26 @@ module ActiveRecord
82
108
  end
83
109
 
84
110
  def should_record_timestamps?
85
- self.record_timestamps && (!partial_writes? || changed?)
111
+ record_timestamps && (!partial_writes? || has_changes_to_save?)
86
112
  end
87
113
 
88
114
  def timestamp_attributes_for_create_in_model
89
- timestamp_attributes_for_create.select { |c| self.class.column_names.include?(c.to_s) }
115
+ self.class.send(:timestamp_attributes_for_create_in_model)
90
116
  end
91
117
 
92
118
  def timestamp_attributes_for_update_in_model
93
- timestamp_attributes_for_update.select { |c| self.class.column_names.include?(c.to_s) }
119
+ self.class.send(:timestamp_attributes_for_update_in_model)
94
120
  end
95
121
 
96
122
  def all_timestamp_attributes_in_model
97
- timestamp_attributes_for_create_in_model + timestamp_attributes_for_update_in_model
98
- end
99
-
100
- def timestamp_attributes_for_update
101
- [:updated_at, :updated_on]
102
- end
103
-
104
- def timestamp_attributes_for_create
105
- [:created_at, :created_on]
123
+ self.class.send(:all_timestamp_attributes_in_model)
106
124
  end
107
125
 
108
- def all_timestamp_attributes
109
- timestamp_attributes_for_create + timestamp_attributes_for_update
126
+ def current_time_from_proper_timezone
127
+ self.class.send(:current_time_from_proper_timezone)
110
128
  end
111
129
 
112
- def max_updated_column_timestamp(timestamp_names = timestamp_attributes_for_update)
130
+ def max_updated_column_timestamp(timestamp_names = self.class.send(:timestamp_attributes_for_update))
113
131
  timestamp_names
114
132
  .map { |attr| self[attr] }
115
133
  .compact
@@ -117,10 +135,6 @@ module ActiveRecord
117
135
  .max
118
136
  end
119
137
 
120
- def current_time_from_proper_timezone
121
- self.class.default_timezone == :utc ? Time.now.utc : Time.now
122
- end
123
-
124
138
  # Clear attributes and changed_attributes
125
139
  def clear_timestamp_attributes
126
140
  all_timestamp_attributes_in_model.each do |attribute_name|