activerecord 3.2.22.5 → 4.2.11.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


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

Files changed (236) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +1632 -609
  3. data/MIT-LICENSE +1 -1
  4. data/README.rdoc +37 -41
  5. data/examples/performance.rb +31 -19
  6. data/examples/simple.rb +4 -4
  7. data/lib/active_record/aggregations.rb +56 -42
  8. data/lib/active_record/association_relation.rb +35 -0
  9. data/lib/active_record/associations/alias_tracker.rb +47 -36
  10. data/lib/active_record/associations/association.rb +73 -55
  11. data/lib/active_record/associations/association_scope.rb +143 -82
  12. data/lib/active_record/associations/belongs_to_association.rb +65 -25
  13. data/lib/active_record/associations/belongs_to_polymorphic_association.rb +7 -2
  14. data/lib/active_record/associations/builder/association.rb +125 -31
  15. data/lib/active_record/associations/builder/belongs_to.rb +89 -61
  16. data/lib/active_record/associations/builder/collection_association.rb +69 -49
  17. data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +113 -42
  18. data/lib/active_record/associations/builder/has_many.rb +8 -64
  19. data/lib/active_record/associations/builder/has_one.rb +12 -51
  20. data/lib/active_record/associations/builder/singular_association.rb +23 -17
  21. data/lib/active_record/associations/collection_association.rb +251 -177
  22. data/lib/active_record/associations/collection_proxy.rb +963 -63
  23. data/lib/active_record/associations/foreign_association.rb +11 -0
  24. data/lib/active_record/associations/has_many_association.rb +113 -22
  25. data/lib/active_record/associations/has_many_through_association.rb +99 -39
  26. data/lib/active_record/associations/has_one_association.rb +43 -20
  27. data/lib/active_record/associations/has_one_through_association.rb +1 -1
  28. data/lib/active_record/associations/join_dependency/join_association.rb +76 -107
  29. data/lib/active_record/associations/join_dependency/join_base.rb +7 -9
  30. data/lib/active_record/associations/join_dependency/join_part.rb +30 -37
  31. data/lib/active_record/associations/join_dependency.rb +230 -156
  32. data/lib/active_record/associations/preloader/association.rb +96 -55
  33. data/lib/active_record/associations/preloader/collection_association.rb +3 -3
  34. data/lib/active_record/associations/preloader/has_many_through.rb +7 -3
  35. data/lib/active_record/associations/preloader/has_one.rb +1 -1
  36. data/lib/active_record/associations/preloader/singular_association.rb +3 -3
  37. data/lib/active_record/associations/preloader/through_association.rb +62 -33
  38. data/lib/active_record/associations/preloader.rb +101 -79
  39. data/lib/active_record/associations/singular_association.rb +29 -13
  40. data/lib/active_record/associations/through_association.rb +30 -16
  41. data/lib/active_record/associations.rb +463 -345
  42. data/lib/active_record/attribute.rb +163 -0
  43. data/lib/active_record/attribute_assignment.rb +142 -151
  44. data/lib/active_record/attribute_decorators.rb +66 -0
  45. data/lib/active_record/attribute_methods/before_type_cast.rb +52 -7
  46. data/lib/active_record/attribute_methods/dirty.rb +137 -57
  47. data/lib/active_record/attribute_methods/primary_key.rb +50 -36
  48. data/lib/active_record/attribute_methods/query.rb +5 -4
  49. data/lib/active_record/attribute_methods/read.rb +73 -106
  50. data/lib/active_record/attribute_methods/serialization.rb +44 -94
  51. data/lib/active_record/attribute_methods/time_zone_conversion.rb +49 -45
  52. data/lib/active_record/attribute_methods/write.rb +57 -44
  53. data/lib/active_record/attribute_methods.rb +301 -141
  54. data/lib/active_record/attribute_set/builder.rb +106 -0
  55. data/lib/active_record/attribute_set.rb +81 -0
  56. data/lib/active_record/attributes.rb +147 -0
  57. data/lib/active_record/autosave_association.rb +246 -217
  58. data/lib/active_record/base.rb +70 -474
  59. data/lib/active_record/callbacks.rb +66 -28
  60. data/lib/active_record/coders/json.rb +13 -0
  61. data/lib/active_record/coders/yaml_column.rb +18 -21
  62. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +396 -219
  63. data/lib/active_record/connection_adapters/abstract/database_limits.rb +9 -0
  64. data/lib/active_record/connection_adapters/abstract/database_statements.rb +167 -164
  65. data/lib/active_record/connection_adapters/abstract/query_cache.rb +29 -24
  66. data/lib/active_record/connection_adapters/abstract/quoting.rb +74 -55
  67. data/lib/active_record/connection_adapters/abstract/savepoints.rb +21 -0
  68. data/lib/active_record/connection_adapters/abstract/schema_creation.rb +125 -0
  69. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +261 -169
  70. data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +50 -0
  71. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +707 -259
  72. data/lib/active_record/connection_adapters/abstract/transaction.rb +215 -0
  73. data/lib/active_record/connection_adapters/abstract_adapter.rb +298 -89
  74. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +466 -196
  75. data/lib/active_record/connection_adapters/column.rb +31 -245
  76. data/lib/active_record/connection_adapters/connection_specification.rb +275 -0
  77. data/lib/active_record/connection_adapters/mysql2_adapter.rb +45 -57
  78. data/lib/active_record/connection_adapters/mysql_adapter.rb +180 -123
  79. data/lib/active_record/connection_adapters/postgresql/array_parser.rb +93 -0
  80. data/lib/active_record/connection_adapters/postgresql/column.rb +20 -0
  81. data/lib/active_record/connection_adapters/postgresql/database_statements.rb +232 -0
  82. data/lib/active_record/connection_adapters/postgresql/oid/array.rb +100 -0
  83. data/lib/active_record/connection_adapters/postgresql/oid/bit.rb +52 -0
  84. data/lib/active_record/connection_adapters/postgresql/oid/bit_varying.rb +13 -0
  85. data/lib/active_record/connection_adapters/postgresql/oid/bytea.rb +15 -0
  86. data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +46 -0
  87. data/lib/active_record/connection_adapters/postgresql/oid/date.rb +11 -0
  88. data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +36 -0
  89. data/lib/active_record/connection_adapters/postgresql/oid/decimal.rb +13 -0
  90. data/lib/active_record/connection_adapters/postgresql/oid/enum.rb +19 -0
  91. data/lib/active_record/connection_adapters/postgresql/oid/float.rb +21 -0
  92. data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +59 -0
  93. data/lib/active_record/connection_adapters/postgresql/oid/inet.rb +13 -0
  94. data/lib/active_record/connection_adapters/postgresql/oid/infinity.rb +13 -0
  95. data/lib/active_record/connection_adapters/postgresql/oid/integer.rb +11 -0
  96. data/lib/active_record/connection_adapters/postgresql/oid/json.rb +35 -0
  97. data/lib/active_record/connection_adapters/postgresql/oid/jsonb.rb +23 -0
  98. data/lib/active_record/connection_adapters/postgresql/oid/money.rb +43 -0
  99. data/lib/active_record/connection_adapters/postgresql/oid/point.rb +43 -0
  100. data/lib/active_record/connection_adapters/postgresql/oid/range.rb +79 -0
  101. data/lib/active_record/connection_adapters/postgresql/oid/specialized_string.rb +19 -0
  102. data/lib/active_record/connection_adapters/postgresql/oid/time.rb +11 -0
  103. data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +109 -0
  104. data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +21 -0
  105. data/lib/active_record/connection_adapters/postgresql/oid/vector.rb +26 -0
  106. data/lib/active_record/connection_adapters/postgresql/oid/xml.rb +28 -0
  107. data/lib/active_record/connection_adapters/postgresql/oid.rb +36 -0
  108. data/lib/active_record/connection_adapters/postgresql/quoting.rb +108 -0
  109. data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +30 -0
  110. data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +152 -0
  111. data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +596 -0
  112. data/lib/active_record/connection_adapters/postgresql/utils.rb +77 -0
  113. data/lib/active_record/connection_adapters/postgresql_adapter.rb +430 -999
  114. data/lib/active_record/connection_adapters/schema_cache.rb +52 -27
  115. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +579 -22
  116. data/lib/active_record/connection_handling.rb +132 -0
  117. data/lib/active_record/core.rb +579 -0
  118. data/lib/active_record/counter_cache.rb +157 -105
  119. data/lib/active_record/dynamic_matchers.rb +119 -63
  120. data/lib/active_record/enum.rb +197 -0
  121. data/lib/active_record/errors.rb +94 -36
  122. data/lib/active_record/explain.rb +15 -63
  123. data/lib/active_record/explain_registry.rb +30 -0
  124. data/lib/active_record/explain_subscriber.rb +9 -5
  125. data/lib/active_record/fixture_set/file.rb +56 -0
  126. data/lib/active_record/fixtures.rb +302 -215
  127. data/lib/active_record/gem_version.rb +15 -0
  128. data/lib/active_record/inheritance.rb +143 -70
  129. data/lib/active_record/integration.rb +65 -12
  130. data/lib/active_record/legacy_yaml_adapter.rb +30 -0
  131. data/lib/active_record/locale/en.yml +8 -1
  132. data/lib/active_record/locking/optimistic.rb +73 -52
  133. data/lib/active_record/locking/pessimistic.rb +5 -5
  134. data/lib/active_record/log_subscriber.rb +24 -21
  135. data/lib/active_record/migration/command_recorder.rb +124 -32
  136. data/lib/active_record/migration/join_table.rb +15 -0
  137. data/lib/active_record/migration.rb +511 -213
  138. data/lib/active_record/model_schema.rb +91 -117
  139. data/lib/active_record/nested_attributes.rb +184 -130
  140. data/lib/active_record/no_touching.rb +52 -0
  141. data/lib/active_record/null_relation.rb +81 -0
  142. data/lib/active_record/persistence.rb +276 -117
  143. data/lib/active_record/query_cache.rb +19 -37
  144. data/lib/active_record/querying.rb +28 -18
  145. data/lib/active_record/railtie.rb +73 -40
  146. data/lib/active_record/railties/console_sandbox.rb +3 -4
  147. data/lib/active_record/railties/controller_runtime.rb +4 -3
  148. data/lib/active_record/railties/databases.rake +141 -416
  149. data/lib/active_record/railties/jdbcmysql_error.rb +1 -1
  150. data/lib/active_record/readonly_attributes.rb +1 -4
  151. data/lib/active_record/reflection.rb +513 -154
  152. data/lib/active_record/relation/batches.rb +91 -43
  153. data/lib/active_record/relation/calculations.rb +199 -161
  154. data/lib/active_record/relation/delegation.rb +116 -25
  155. data/lib/active_record/relation/finder_methods.rb +362 -248
  156. data/lib/active_record/relation/merger.rb +193 -0
  157. data/lib/active_record/relation/predicate_builder/array_handler.rb +48 -0
  158. data/lib/active_record/relation/predicate_builder/relation_handler.rb +13 -0
  159. data/lib/active_record/relation/predicate_builder.rb +135 -43
  160. data/lib/active_record/relation/query_methods.rb +928 -167
  161. data/lib/active_record/relation/spawn_methods.rb +48 -149
  162. data/lib/active_record/relation.rb +352 -207
  163. data/lib/active_record/result.rb +101 -10
  164. data/lib/active_record/runtime_registry.rb +22 -0
  165. data/lib/active_record/sanitization.rb +56 -59
  166. data/lib/active_record/schema.rb +19 -13
  167. data/lib/active_record/schema_dumper.rb +106 -63
  168. data/lib/active_record/schema_migration.rb +53 -0
  169. data/lib/active_record/scoping/default.rb +50 -57
  170. data/lib/active_record/scoping/named.rb +73 -109
  171. data/lib/active_record/scoping.rb +58 -123
  172. data/lib/active_record/serialization.rb +6 -2
  173. data/lib/active_record/serializers/xml_serializer.rb +12 -22
  174. data/lib/active_record/statement_cache.rb +111 -0
  175. data/lib/active_record/store.rb +168 -15
  176. data/lib/active_record/tasks/database_tasks.rb +299 -0
  177. data/lib/active_record/tasks/mysql_database_tasks.rb +159 -0
  178. data/lib/active_record/tasks/postgresql_database_tasks.rb +101 -0
  179. data/lib/active_record/tasks/sqlite_database_tasks.rb +55 -0
  180. data/lib/active_record/timestamp.rb +23 -16
  181. data/lib/active_record/transactions.rb +125 -79
  182. data/lib/active_record/type/big_integer.rb +13 -0
  183. data/lib/active_record/type/binary.rb +50 -0
  184. data/lib/active_record/type/boolean.rb +31 -0
  185. data/lib/active_record/type/date.rb +50 -0
  186. data/lib/active_record/type/date_time.rb +54 -0
  187. data/lib/active_record/type/decimal.rb +64 -0
  188. data/lib/active_record/type/decimal_without_scale.rb +11 -0
  189. data/lib/active_record/type/decorator.rb +14 -0
  190. data/lib/active_record/type/float.rb +19 -0
  191. data/lib/active_record/type/hash_lookup_type_map.rb +23 -0
  192. data/lib/active_record/type/integer.rb +59 -0
  193. data/lib/active_record/type/mutable.rb +16 -0
  194. data/lib/active_record/type/numeric.rb +36 -0
  195. data/lib/active_record/type/serialized.rb +62 -0
  196. data/lib/active_record/type/string.rb +40 -0
  197. data/lib/active_record/type/text.rb +11 -0
  198. data/lib/active_record/type/time.rb +26 -0
  199. data/lib/active_record/type/time_value.rb +38 -0
  200. data/lib/active_record/type/type_map.rb +64 -0
  201. data/lib/active_record/type/unsigned_integer.rb +15 -0
  202. data/lib/active_record/type/value.rb +110 -0
  203. data/lib/active_record/type.rb +23 -0
  204. data/lib/active_record/validations/associated.rb +24 -16
  205. data/lib/active_record/validations/presence.rb +67 -0
  206. data/lib/active_record/validations/uniqueness.rb +123 -64
  207. data/lib/active_record/validations.rb +36 -29
  208. data/lib/active_record/version.rb +5 -7
  209. data/lib/active_record.rb +66 -46
  210. data/lib/rails/generators/active_record/migration/migration_generator.rb +53 -8
  211. data/lib/rails/generators/active_record/{model/templates/migration.rb → migration/templates/create_table_migration.rb} +5 -1
  212. data/lib/rails/generators/active_record/migration/templates/migration.rb +20 -15
  213. data/lib/rails/generators/active_record/migration.rb +11 -8
  214. data/lib/rails/generators/active_record/model/model_generator.rb +9 -4
  215. data/lib/rails/generators/active_record/model/templates/model.rb +4 -6
  216. data/lib/rails/generators/active_record/model/templates/module.rb +1 -1
  217. data/lib/rails/generators/active_record.rb +3 -11
  218. metadata +101 -45
  219. data/examples/associations.png +0 -0
  220. data/lib/active_record/associations/has_and_belongs_to_many_association.rb +0 -63
  221. data/lib/active_record/associations/join_helper.rb +0 -55
  222. data/lib/active_record/associations/preloader/has_and_belongs_to_many.rb +0 -60
  223. data/lib/active_record/attribute_methods/deprecated_underscore_read.rb +0 -32
  224. data/lib/active_record/connection_adapters/abstract/connection_specification.rb +0 -191
  225. data/lib/active_record/connection_adapters/sqlite_adapter.rb +0 -583
  226. data/lib/active_record/dynamic_finder_match.rb +0 -68
  227. data/lib/active_record/dynamic_scope_match.rb +0 -23
  228. data/lib/active_record/fixtures/file.rb +0 -65
  229. data/lib/active_record/identity_map.rb +0 -162
  230. data/lib/active_record/observer.rb +0 -121
  231. data/lib/active_record/session_store.rb +0 -360
  232. data/lib/active_record/test_case.rb +0 -73
  233. data/lib/rails/generators/active_record/observer/observer_generator.rb +0 -15
  234. data/lib/rails/generators/active_record/observer/templates/observer.rb +0 -4
  235. data/lib/rails/generators/active_record/session_migration/session_migration_generator.rb +0 -25
  236. data/lib/rails/generators/active_record/session_migration/templates/migration.rb +0 -12
@@ -0,0 +1,159 @@
1
+ module ActiveRecord
2
+ module Tasks # :nodoc:
3
+ class MySQLDatabaseTasks # :nodoc:
4
+ DEFAULT_CHARSET = ENV['CHARSET'] || 'utf8'
5
+ DEFAULT_COLLATION = ENV['COLLATION'] || 'utf8_unicode_ci'
6
+ ACCESS_DENIED_ERROR = 1045
7
+
8
+ delegate :connection, :establish_connection, to: ActiveRecord::Base
9
+
10
+ def initialize(configuration)
11
+ @configuration = configuration
12
+ end
13
+
14
+ def create
15
+ establish_connection configuration_without_database
16
+ connection.create_database configuration['database'], creation_options
17
+ establish_connection configuration
18
+ rescue ActiveRecord::StatementInvalid => error
19
+ if /database exists/ === error.message
20
+ raise DatabaseAlreadyExists
21
+ else
22
+ raise
23
+ end
24
+ rescue error_class => error
25
+ if error.respond_to?(:errno) && error.errno == ACCESS_DENIED_ERROR
26
+ $stdout.print error.error
27
+ establish_connection root_configuration_without_database
28
+ connection.create_database configuration['database'], creation_options
29
+ if configuration['username'] != 'root'
30
+ connection.execute grant_statement.gsub(/\s+/, ' ').strip
31
+ end
32
+ establish_connection configuration
33
+ else
34
+ $stderr.puts error.inspect
35
+ $stderr.puts "Couldn't create database for #{configuration.inspect}, #{creation_options.inspect}"
36
+ $stderr.puts "(If you set the charset manually, make sure you have a matching collation)" if configuration['encoding']
37
+ end
38
+ end
39
+
40
+ def drop
41
+ establish_connection configuration
42
+ connection.drop_database configuration['database']
43
+ end
44
+
45
+ def purge
46
+ establish_connection configuration
47
+ connection.recreate_database configuration['database'], creation_options
48
+ end
49
+
50
+ def charset
51
+ connection.charset
52
+ end
53
+
54
+ def collation
55
+ connection.collation
56
+ end
57
+
58
+ def structure_dump(filename)
59
+ args = prepare_command_options
60
+ args.concat(["--result-file", "#{filename}"])
61
+ args.concat(["--no-data"])
62
+ args.concat(["#{configuration['database']}"])
63
+
64
+ run_cmd('mysqldump', args, 'dumping')
65
+ end
66
+
67
+ def structure_load(filename)
68
+ args = prepare_command_options
69
+ args.concat(['--execute', %{SET FOREIGN_KEY_CHECKS = 0; SOURCE #{filename}; SET FOREIGN_KEY_CHECKS = 1}])
70
+ args.concat(["--database", "#{configuration['database']}"])
71
+
72
+ run_cmd('mysql', args, 'loading')
73
+ end
74
+
75
+ private
76
+
77
+ def configuration
78
+ @configuration
79
+ end
80
+
81
+ def configuration_without_database
82
+ configuration.merge('database' => nil)
83
+ end
84
+
85
+ def creation_options
86
+ Hash.new.tap do |options|
87
+ options[:charset] = configuration['encoding'] if configuration.include? 'encoding'
88
+ options[:collation] = configuration['collation'] if configuration.include? 'collation'
89
+
90
+ # Set default charset only when collation isn't set.
91
+ options[:charset] ||= DEFAULT_CHARSET unless options[:collation]
92
+
93
+ # Set default collation only when charset is also default.
94
+ options[:collation] ||= DEFAULT_COLLATION if options[:charset] == DEFAULT_CHARSET
95
+ end
96
+ end
97
+
98
+ def error_class
99
+ if configuration['adapter'] =~ /jdbc/
100
+ require 'active_record/railties/jdbcmysql_error'
101
+ ArJdbcMySQL::Error
102
+ elsif defined?(Mysql2)
103
+ Mysql2::Error
104
+ elsif defined?(Mysql)
105
+ Mysql::Error
106
+ else
107
+ StandardError
108
+ end
109
+ end
110
+
111
+ def grant_statement
112
+ <<-SQL
113
+ GRANT ALL PRIVILEGES ON #{configuration['database']}.*
114
+ TO '#{configuration['username']}'@'localhost'
115
+ IDENTIFIED BY '#{configuration['password']}' WITH GRANT OPTION;
116
+ SQL
117
+ end
118
+
119
+ def root_configuration_without_database
120
+ configuration_without_database.merge(
121
+ 'username' => 'root',
122
+ 'password' => root_password
123
+ )
124
+ end
125
+
126
+ def root_password
127
+ $stdout.print "Please provide the root password for your MySQL installation\n>"
128
+ $stdin.gets.strip
129
+ end
130
+
131
+ def prepare_command_options
132
+ {
133
+ 'host' => '--host',
134
+ 'port' => '--port',
135
+ 'socket' => '--socket',
136
+ 'username' => '--user',
137
+ 'password' => '--password',
138
+ 'encoding' => '--default-character-set',
139
+ 'sslca' => '--ssl-ca',
140
+ 'sslcert' => '--ssl-cert',
141
+ 'sslcapath' => '--ssl-capath',
142
+ 'sslcipher' => '--ssl-cipher',
143
+ 'sslkey' => '--ssl-key'
144
+ }.map { |opt, arg| "#{arg}=#{configuration[opt]}" if configuration[opt] }.compact
145
+ end
146
+
147
+ def run_cmd(cmd, args, action)
148
+ fail run_cmd_error(cmd, args, action) unless Kernel.system(cmd, *args)
149
+ end
150
+
151
+ def run_cmd_error(cmd, args, action)
152
+ msg = "failed to execute:\n"
153
+ msg << "#{cmd}"
154
+ 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"
155
+ msg
156
+ end
157
+ end
158
+ end
159
+ end
@@ -0,0 +1,101 @@
1
+ module ActiveRecord
2
+ module Tasks # :nodoc:
3
+ class PostgreSQLDatabaseTasks # :nodoc:
4
+ DEFAULT_ENCODING = ENV['CHARSET'] || 'utf8'
5
+
6
+ delegate :connection, :establish_connection, :clear_active_connections!,
7
+ to: ActiveRecord::Base
8
+
9
+ def initialize(configuration)
10
+ @configuration = configuration
11
+ end
12
+
13
+ def create(master_established = false)
14
+ establish_master_connection unless master_established
15
+ connection.create_database configuration['database'],
16
+ configuration.merge('encoding' => encoding)
17
+ establish_connection configuration
18
+ rescue ActiveRecord::StatementInvalid => error
19
+ if /database .* already exists/ === error.message
20
+ raise DatabaseAlreadyExists
21
+ else
22
+ raise
23
+ end
24
+ end
25
+
26
+ def drop
27
+ establish_master_connection
28
+ connection.drop_database configuration['database']
29
+ end
30
+
31
+ def charset
32
+ connection.encoding
33
+ end
34
+
35
+ def collation
36
+ connection.collation
37
+ end
38
+
39
+ def purge
40
+ clear_active_connections!
41
+ drop
42
+ create true
43
+ end
44
+
45
+ def structure_dump(filename)
46
+ set_psql_env
47
+ args = ['-s', '-x', '-O', '-f', filename]
48
+ search_path = configuration['schema_search_path']
49
+ unless search_path.blank?
50
+ args += search_path.split(',').map do |part|
51
+ "--schema=#{part.strip}"
52
+ end
53
+ end
54
+ args << configuration['database']
55
+ run_cmd('pg_dump', args, 'dumping')
56
+ File.open(filename, "a") { |f| f << "SET search_path TO #{connection.schema_search_path};\n\n" }
57
+ end
58
+
59
+ def structure_load(filename)
60
+ set_psql_env
61
+ args = [ '-q', '-f', filename, configuration['database'] ]
62
+ run_cmd('psql', args, 'loading')
63
+ end
64
+
65
+ private
66
+
67
+ def configuration
68
+ @configuration
69
+ end
70
+
71
+ def encoding
72
+ configuration['encoding'] || DEFAULT_ENCODING
73
+ end
74
+
75
+ def establish_master_connection
76
+ establish_connection configuration.merge(
77
+ 'database' => 'postgres',
78
+ 'schema_search_path' => 'public'
79
+ )
80
+ end
81
+
82
+ def set_psql_env
83
+ ENV['PGHOST'] = configuration['host'] if configuration['host']
84
+ ENV['PGPORT'] = configuration['port'].to_s if configuration['port']
85
+ ENV['PGPASSWORD'] = configuration['password'].to_s if configuration['password']
86
+ ENV['PGUSER'] = configuration['username'].to_s if configuration['username']
87
+ end
88
+
89
+ def run_cmd(cmd, args, action)
90
+ fail run_cmd_error(cmd, args, action) unless Kernel.system(cmd, *args)
91
+ end
92
+
93
+ def run_cmd_error(cmd, args, action)
94
+ msg = "failed to execute:\n"
95
+ msg << "#{cmd} #{args.join(' ')}\n\n"
96
+ 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"
97
+ msg
98
+ end
99
+ end
100
+ end
101
+ end
@@ -0,0 +1,55 @@
1
+ module ActiveRecord
2
+ module Tasks # :nodoc:
3
+ class SQLiteDatabaseTasks # :nodoc:
4
+ delegate :connection, :establish_connection, to: ActiveRecord::Base
5
+
6
+ def initialize(configuration, root = ActiveRecord::Tasks::DatabaseTasks.root)
7
+ @configuration, @root = configuration, root
8
+ end
9
+
10
+ def create
11
+ raise DatabaseAlreadyExists if File.exist?(configuration['database'])
12
+
13
+ establish_connection configuration
14
+ connection
15
+ end
16
+
17
+ def drop
18
+ require 'pathname'
19
+ path = Pathname.new configuration['database']
20
+ file = path.absolute? ? path.to_s : File.join(root, path)
21
+
22
+ FileUtils.rm(file) if File.exist?(file)
23
+ end
24
+
25
+ def purge
26
+ drop
27
+ create
28
+ end
29
+
30
+ def charset
31
+ connection.encoding
32
+ end
33
+
34
+ def structure_dump(filename)
35
+ dbfile = configuration['database']
36
+ `sqlite3 #{dbfile} .schema > #{filename}`
37
+ end
38
+
39
+ def structure_load(filename)
40
+ dbfile = configuration['database']
41
+ `sqlite3 #{dbfile} < "#{filename}"`
42
+ end
43
+
44
+ private
45
+
46
+ def configuration
47
+ @configuration
48
+ end
49
+
50
+ def root
51
+ @root
52
+ end
53
+ end
54
+ end
55
+ end
@@ -1,5 +1,3 @@
1
- require 'active_support/core_ext/class/attribute'
2
-
3
1
  module ActiveRecord
4
2
  # = Active Record Timestamp
5
3
  #
@@ -11,9 +9,9 @@ module ActiveRecord
11
9
  #
12
10
  # config.active_record.record_timestamps = false
13
11
  #
14
- # Timestamps are in the local timezone by default but you can use UTC by setting:
12
+ # Timestamps are in UTC by default but you can use the local timezone by setting:
15
13
  #
16
- # config.active_record.default_timezone = :utc
14
+ # config.active_record.default_timezone = :local
17
15
  #
18
16
  # == Time Zone aware attributes
19
17
  #
@@ -37,20 +35,21 @@ module ActiveRecord
37
35
  self.record_timestamps = true
38
36
  end
39
37
 
40
- def initialize_dup(other)
41
- clear_timestamp_attributes
38
+ def initialize_dup(other) # :nodoc:
42
39
  super
40
+ clear_timestamp_attributes
43
41
  end
44
42
 
45
43
  private
46
44
 
47
- def create #:nodoc:
45
+ def _create_record
48
46
  if self.record_timestamps
49
47
  current_time = current_time_from_proper_timezone
50
48
 
51
49
  all_timestamp_attributes.each do |column|
52
- if respond_to?(column) && respond_to?("#{column}=") && self.send(column).nil?
53
- write_attribute(column.to_s, current_time)
50
+ column = column.to_s
51
+ if has_attribute?(column) && !attribute_present?(column)
52
+ write_attribute(column, current_time)
54
53
  end
55
54
  end
56
55
  end
@@ -58,7 +57,7 @@ module ActiveRecord
58
57
  super
59
58
  end
60
59
 
61
- def update(*args) #:nodoc:
60
+ def _update_record(*args)
62
61
  if should_record_timestamps?
63
62
  current_time = current_time_from_proper_timezone
64
63
 
@@ -72,7 +71,7 @@ module ActiveRecord
72
71
  end
73
72
 
74
73
  def should_record_timestamps?
75
- self.record_timestamps && (!partial_updates? || changed? || (attributes.keys & self.class.serialized_attributes.keys).present?)
74
+ self.record_timestamps && (!partial_writes? || changed?)
76
75
  end
77
76
 
78
77
  def timestamp_attributes_for_create_in_model
@@ -87,19 +86,27 @@ module ActiveRecord
87
86
  timestamp_attributes_for_create_in_model + timestamp_attributes_for_update_in_model
88
87
  end
89
88
 
90
- def timestamp_attributes_for_update #:nodoc:
89
+ def timestamp_attributes_for_update
91
90
  [:updated_at, :updated_on]
92
91
  end
93
92
 
94
- def timestamp_attributes_for_create #:nodoc:
93
+ def timestamp_attributes_for_create
95
94
  [:created_at, :created_on]
96
95
  end
97
96
 
98
- def all_timestamp_attributes #:nodoc:
97
+ def all_timestamp_attributes
99
98
  timestamp_attributes_for_create + timestamp_attributes_for_update
100
99
  end
101
100
 
102
- def current_time_from_proper_timezone #:nodoc:
101
+ def max_updated_column_timestamp(timestamp_names = timestamp_attributes_for_update)
102
+ timestamp_names
103
+ .map { |attr| self[attr] }
104
+ .compact
105
+ .map(&:to_time)
106
+ .max
107
+ end
108
+
109
+ def current_time_from_proper_timezone
103
110
  self.class.default_timezone == :utc ? Time.now.utc : Time.now
104
111
  end
105
112
 
@@ -107,7 +114,7 @@ module ActiveRecord
107
114
  def clear_timestamp_attributes
108
115
  all_timestamp_attributes_in_model.each do |attribute_name|
109
116
  self[attribute_name] = nil
110
- changed_attributes.delete(attribute_name)
117
+ clear_attribute_changes([attribute_name])
111
118
  end
112
119
  end
113
120
  end