activerecord 1.0.0 → 4.0.0

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 (255) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +2102 -0
  3. data/MIT-LICENSE +20 -0
  4. data/README.rdoc +213 -0
  5. data/examples/performance.rb +172 -0
  6. data/examples/simple.rb +14 -0
  7. data/lib/active_record/aggregations.rb +180 -84
  8. data/lib/active_record/associations/alias_tracker.rb +76 -0
  9. data/lib/active_record/associations/association.rb +248 -0
  10. data/lib/active_record/associations/association_scope.rb +135 -0
  11. data/lib/active_record/associations/belongs_to_association.rb +92 -0
  12. data/lib/active_record/associations/belongs_to_polymorphic_association.rb +35 -0
  13. data/lib/active_record/associations/builder/association.rb +108 -0
  14. data/lib/active_record/associations/builder/belongs_to.rb +98 -0
  15. data/lib/active_record/associations/builder/collection_association.rb +89 -0
  16. data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +39 -0
  17. data/lib/active_record/associations/builder/has_many.rb +15 -0
  18. data/lib/active_record/associations/builder/has_one.rb +25 -0
  19. data/lib/active_record/associations/builder/singular_association.rb +32 -0
  20. data/lib/active_record/associations/collection_association.rb +608 -0
  21. data/lib/active_record/associations/collection_proxy.rb +986 -0
  22. data/lib/active_record/associations/has_and_belongs_to_many_association.rb +58 -39
  23. data/lib/active_record/associations/has_many_association.rb +116 -85
  24. data/lib/active_record/associations/has_many_through_association.rb +197 -0
  25. data/lib/active_record/associations/has_one_association.rb +102 -0
  26. data/lib/active_record/associations/has_one_through_association.rb +36 -0
  27. data/lib/active_record/associations/join_dependency/join_association.rb +174 -0
  28. data/lib/active_record/associations/join_dependency/join_base.rb +24 -0
  29. data/lib/active_record/associations/join_dependency/join_part.rb +78 -0
  30. data/lib/active_record/associations/join_dependency.rb +235 -0
  31. data/lib/active_record/associations/join_helper.rb +45 -0
  32. data/lib/active_record/associations/preloader/association.rb +121 -0
  33. data/lib/active_record/associations/preloader/belongs_to.rb +17 -0
  34. data/lib/active_record/associations/preloader/collection_association.rb +24 -0
  35. data/lib/active_record/associations/preloader/has_and_belongs_to_many.rb +60 -0
  36. data/lib/active_record/associations/preloader/has_many.rb +17 -0
  37. data/lib/active_record/associations/preloader/has_many_through.rb +19 -0
  38. data/lib/active_record/associations/preloader/has_one.rb +23 -0
  39. data/lib/active_record/associations/preloader/has_one_through.rb +9 -0
  40. data/lib/active_record/associations/preloader/singular_association.rb +21 -0
  41. data/lib/active_record/associations/preloader/through_association.rb +63 -0
  42. data/lib/active_record/associations/preloader.rb +178 -0
  43. data/lib/active_record/associations/singular_association.rb +64 -0
  44. data/lib/active_record/associations/through_association.rb +87 -0
  45. data/lib/active_record/associations.rb +1437 -431
  46. data/lib/active_record/attribute_assignment.rb +201 -0
  47. data/lib/active_record/attribute_methods/before_type_cast.rb +70 -0
  48. data/lib/active_record/attribute_methods/dirty.rb +118 -0
  49. data/lib/active_record/attribute_methods/primary_key.rb +122 -0
  50. data/lib/active_record/attribute_methods/query.rb +40 -0
  51. data/lib/active_record/attribute_methods/read.rb +107 -0
  52. data/lib/active_record/attribute_methods/serialization.rb +162 -0
  53. data/lib/active_record/attribute_methods/time_zone_conversion.rb +59 -0
  54. data/lib/active_record/attribute_methods/write.rb +63 -0
  55. data/lib/active_record/attribute_methods.rb +393 -0
  56. data/lib/active_record/autosave_association.rb +426 -0
  57. data/lib/active_record/base.rb +268 -930
  58. data/lib/active_record/callbacks.rb +203 -230
  59. data/lib/active_record/coders/yaml_column.rb +38 -0
  60. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +638 -0
  61. data/lib/active_record/connection_adapters/abstract/database_limits.rb +67 -0
  62. data/lib/active_record/connection_adapters/abstract/database_statements.rb +390 -0
  63. data/lib/active_record/connection_adapters/abstract/query_cache.rb +95 -0
  64. data/lib/active_record/connection_adapters/abstract/quoting.rb +129 -0
  65. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +501 -0
  66. data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +70 -0
  67. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +873 -0
  68. data/lib/active_record/connection_adapters/abstract/transaction.rb +203 -0
  69. data/lib/active_record/connection_adapters/abstract_adapter.rb +389 -275
  70. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +782 -0
  71. data/lib/active_record/connection_adapters/column.rb +318 -0
  72. data/lib/active_record/connection_adapters/connection_specification.rb +96 -0
  73. data/lib/active_record/connection_adapters/mysql2_adapter.rb +273 -0
  74. data/lib/active_record/connection_adapters/mysql_adapter.rb +517 -90
  75. data/lib/active_record/connection_adapters/postgresql/array_parser.rb +97 -0
  76. data/lib/active_record/connection_adapters/postgresql/cast.rb +152 -0
  77. data/lib/active_record/connection_adapters/postgresql/database_statements.rb +242 -0
  78. data/lib/active_record/connection_adapters/postgresql/oid.rb +366 -0
  79. data/lib/active_record/connection_adapters/postgresql/quoting.rb +171 -0
  80. data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +30 -0
  81. data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +489 -0
  82. data/lib/active_record/connection_adapters/postgresql_adapter.rb +911 -138
  83. data/lib/active_record/connection_adapters/schema_cache.rb +129 -0
  84. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +624 -0
  85. data/lib/active_record/connection_adapters/statement_pool.rb +40 -0
  86. data/lib/active_record/connection_handling.rb +98 -0
  87. data/lib/active_record/core.rb +463 -0
  88. data/lib/active_record/counter_cache.rb +122 -0
  89. data/lib/active_record/dynamic_matchers.rb +131 -0
  90. data/lib/active_record/errors.rb +213 -0
  91. data/lib/active_record/explain.rb +38 -0
  92. data/lib/active_record/explain_registry.rb +30 -0
  93. data/lib/active_record/explain_subscriber.rb +29 -0
  94. data/lib/active_record/fixture_set/file.rb +55 -0
  95. data/lib/active_record/fixtures.rb +892 -138
  96. data/lib/active_record/inheritance.rb +200 -0
  97. data/lib/active_record/integration.rb +60 -0
  98. data/lib/active_record/locale/en.yml +47 -0
  99. data/lib/active_record/locking/optimistic.rb +181 -0
  100. data/lib/active_record/locking/pessimistic.rb +77 -0
  101. data/lib/active_record/log_subscriber.rb +82 -0
  102. data/lib/active_record/migration/command_recorder.rb +164 -0
  103. data/lib/active_record/migration/join_table.rb +15 -0
  104. data/lib/active_record/migration.rb +1015 -0
  105. data/lib/active_record/model_schema.rb +345 -0
  106. data/lib/active_record/nested_attributes.rb +546 -0
  107. data/lib/active_record/null_relation.rb +65 -0
  108. data/lib/active_record/persistence.rb +509 -0
  109. data/lib/active_record/query_cache.rb +56 -0
  110. data/lib/active_record/querying.rb +62 -0
  111. data/lib/active_record/railtie.rb +205 -0
  112. data/lib/active_record/railties/console_sandbox.rb +5 -0
  113. data/lib/active_record/railties/controller_runtime.rb +50 -0
  114. data/lib/active_record/railties/databases.rake +402 -0
  115. data/lib/active_record/railties/jdbcmysql_error.rb +16 -0
  116. data/lib/active_record/readonly_attributes.rb +30 -0
  117. data/lib/active_record/reflection.rb +544 -87
  118. data/lib/active_record/relation/batches.rb +93 -0
  119. data/lib/active_record/relation/calculations.rb +399 -0
  120. data/lib/active_record/relation/delegation.rb +125 -0
  121. data/lib/active_record/relation/finder_methods.rb +349 -0
  122. data/lib/active_record/relation/merger.rb +161 -0
  123. data/lib/active_record/relation/predicate_builder.rb +106 -0
  124. data/lib/active_record/relation/query_methods.rb +1044 -0
  125. data/lib/active_record/relation/spawn_methods.rb +73 -0
  126. data/lib/active_record/relation.rb +655 -0
  127. data/lib/active_record/result.rb +67 -0
  128. data/lib/active_record/runtime_registry.rb +17 -0
  129. data/lib/active_record/sanitization.rb +168 -0
  130. data/lib/active_record/schema.rb +65 -0
  131. data/lib/active_record/schema_dumper.rb +204 -0
  132. data/lib/active_record/schema_migration.rb +39 -0
  133. data/lib/active_record/scoping/default.rb +146 -0
  134. data/lib/active_record/scoping/named.rb +175 -0
  135. data/lib/active_record/scoping.rb +82 -0
  136. data/lib/active_record/serialization.rb +22 -0
  137. data/lib/active_record/serializers/xml_serializer.rb +197 -0
  138. data/lib/active_record/statement_cache.rb +26 -0
  139. data/lib/active_record/store.rb +156 -0
  140. data/lib/active_record/tasks/database_tasks.rb +203 -0
  141. data/lib/active_record/tasks/firebird_database_tasks.rb +56 -0
  142. data/lib/active_record/tasks/mysql_database_tasks.rb +143 -0
  143. data/lib/active_record/tasks/oracle_database_tasks.rb +45 -0
  144. data/lib/active_record/tasks/postgresql_database_tasks.rb +90 -0
  145. data/lib/active_record/tasks/sqlite_database_tasks.rb +51 -0
  146. data/lib/active_record/tasks/sqlserver_database_tasks.rb +48 -0
  147. data/lib/active_record/test_case.rb +96 -0
  148. data/lib/active_record/timestamp.rb +119 -0
  149. data/lib/active_record/transactions.rb +366 -69
  150. data/lib/active_record/translation.rb +22 -0
  151. data/lib/active_record/validations/associated.rb +49 -0
  152. data/lib/active_record/validations/presence.rb +65 -0
  153. data/lib/active_record/validations/uniqueness.rb +225 -0
  154. data/lib/active_record/validations.rb +64 -185
  155. data/lib/active_record/version.rb +11 -0
  156. data/lib/active_record.rb +149 -24
  157. data/lib/rails/generators/active_record/migration/migration_generator.rb +62 -0
  158. data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb +19 -0
  159. data/lib/rails/generators/active_record/migration/templates/migration.rb +39 -0
  160. data/lib/rails/generators/active_record/model/model_generator.rb +48 -0
  161. data/lib/rails/generators/active_record/model/templates/model.rb +10 -0
  162. data/lib/rails/generators/active_record/model/templates/module.rb +7 -0
  163. data/lib/rails/generators/active_record.rb +23 -0
  164. metadata +261 -161
  165. data/CHANGELOG +0 -581
  166. data/README +0 -361
  167. data/RUNNING_UNIT_TESTS +0 -36
  168. data/dev-utils/eval_debugger.rb +0 -9
  169. data/examples/associations.png +0 -0
  170. data/examples/associations.rb +0 -87
  171. data/examples/shared_setup.rb +0 -15
  172. data/examples/validation.rb +0 -88
  173. data/install.rb +0 -60
  174. data/lib/active_record/associations/association_collection.rb +0 -70
  175. data/lib/active_record/connection_adapters/sqlite_adapter.rb +0 -107
  176. data/lib/active_record/deprecated_associations.rb +0 -70
  177. data/lib/active_record/observer.rb +0 -71
  178. data/lib/active_record/support/class_attribute_accessors.rb +0 -43
  179. data/lib/active_record/support/class_inheritable_attributes.rb +0 -37
  180. data/lib/active_record/support/clean_logger.rb +0 -10
  181. data/lib/active_record/support/inflector.rb +0 -70
  182. data/lib/active_record/vendor/mysql.rb +0 -1117
  183. data/lib/active_record/vendor/simple.rb +0 -702
  184. data/lib/active_record/wrappers/yaml_wrapper.rb +0 -15
  185. data/lib/active_record/wrappings.rb +0 -59
  186. data/rakefile +0 -122
  187. data/test/abstract_unit.rb +0 -16
  188. data/test/aggregations_test.rb +0 -34
  189. data/test/all.sh +0 -8
  190. data/test/associations_test.rb +0 -477
  191. data/test/base_test.rb +0 -513
  192. data/test/class_inheritable_attributes_test.rb +0 -33
  193. data/test/connections/native_mysql/connection.rb +0 -24
  194. data/test/connections/native_postgresql/connection.rb +0 -24
  195. data/test/connections/native_sqlite/connection.rb +0 -24
  196. data/test/deprecated_associations_test.rb +0 -336
  197. data/test/finder_test.rb +0 -67
  198. data/test/fixtures/accounts/signals37 +0 -3
  199. data/test/fixtures/accounts/unknown +0 -2
  200. data/test/fixtures/auto_id.rb +0 -4
  201. data/test/fixtures/column_name.rb +0 -3
  202. data/test/fixtures/companies/first_client +0 -6
  203. data/test/fixtures/companies/first_firm +0 -4
  204. data/test/fixtures/companies/second_client +0 -6
  205. data/test/fixtures/company.rb +0 -37
  206. data/test/fixtures/company_in_module.rb +0 -33
  207. data/test/fixtures/course.rb +0 -3
  208. data/test/fixtures/courses/java +0 -2
  209. data/test/fixtures/courses/ruby +0 -2
  210. data/test/fixtures/customer.rb +0 -30
  211. data/test/fixtures/customers/david +0 -6
  212. data/test/fixtures/db_definitions/mysql.sql +0 -96
  213. data/test/fixtures/db_definitions/mysql2.sql +0 -4
  214. data/test/fixtures/db_definitions/postgresql.sql +0 -113
  215. data/test/fixtures/db_definitions/postgresql2.sql +0 -4
  216. data/test/fixtures/db_definitions/sqlite.sql +0 -85
  217. data/test/fixtures/db_definitions/sqlite2.sql +0 -4
  218. data/test/fixtures/default.rb +0 -2
  219. data/test/fixtures/developer.rb +0 -8
  220. data/test/fixtures/developers/david +0 -2
  221. data/test/fixtures/developers/jamis +0 -2
  222. data/test/fixtures/developers_projects/david_action_controller +0 -2
  223. data/test/fixtures/developers_projects/david_active_record +0 -2
  224. data/test/fixtures/developers_projects/jamis_active_record +0 -2
  225. data/test/fixtures/entrant.rb +0 -3
  226. data/test/fixtures/entrants/first +0 -3
  227. data/test/fixtures/entrants/second +0 -3
  228. data/test/fixtures/entrants/third +0 -3
  229. data/test/fixtures/fixture_database.sqlite +0 -0
  230. data/test/fixtures/fixture_database_2.sqlite +0 -0
  231. data/test/fixtures/movie.rb +0 -5
  232. data/test/fixtures/movies/first +0 -2
  233. data/test/fixtures/movies/second +0 -2
  234. data/test/fixtures/project.rb +0 -3
  235. data/test/fixtures/projects/action_controller +0 -2
  236. data/test/fixtures/projects/active_record +0 -2
  237. data/test/fixtures/reply.rb +0 -21
  238. data/test/fixtures/subscriber.rb +0 -5
  239. data/test/fixtures/subscribers/first +0 -2
  240. data/test/fixtures/subscribers/second +0 -2
  241. data/test/fixtures/topic.rb +0 -20
  242. data/test/fixtures/topics/first +0 -9
  243. data/test/fixtures/topics/second +0 -8
  244. data/test/fixtures_test.rb +0 -20
  245. data/test/inflector_test.rb +0 -104
  246. data/test/inheritance_test.rb +0 -125
  247. data/test/lifecycle_test.rb +0 -110
  248. data/test/modules_test.rb +0 -21
  249. data/test/multiple_db_test.rb +0 -46
  250. data/test/pk_test.rb +0 -57
  251. data/test/reflection_test.rb +0 -78
  252. data/test/thread_safety_test.rb +0 -33
  253. data/test/transactions_test.rb +0 -83
  254. data/test/unconnected_test.rb +0 -24
  255. data/test/validations_test.rb +0 -126
@@ -0,0 +1,51 @@
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 = Rails.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
+ alias :purge :drop
25
+
26
+ def charset
27
+ connection.encoding
28
+ end
29
+
30
+ def structure_dump(filename)
31
+ dbfile = configuration['database']
32
+ `sqlite3 #{dbfile} .schema > #{filename}`
33
+ end
34
+
35
+ def structure_load(filename)
36
+ dbfile = configuration['database']
37
+ `sqlite3 #{dbfile} < "#{filename}"`
38
+ end
39
+
40
+ private
41
+
42
+ def configuration
43
+ @configuration
44
+ end
45
+
46
+ def root
47
+ @root
48
+ end
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,48 @@
1
+ require 'shellwords'
2
+
3
+ module ActiveRecord
4
+ module Tasks # :nodoc:
5
+ class SqlserverDatabaseTasks # :nodoc:
6
+ delegate :connection, :establish_connection, to: ActiveRecord::Base
7
+
8
+ def initialize(configuration)
9
+ ActiveSupport::Deprecation.warn "This database tasks were deprecated, because this tasks should be served by the 3rd party adapter."
10
+ @configuration = configuration
11
+ end
12
+
13
+ def create
14
+ $stderr.puts 'sorry, your database adapter is not supported yet, feel free to submit a patch'
15
+ end
16
+
17
+ def drop
18
+ $stderr.puts 'sorry, your database adapter is not supported yet, feel free to submit a patch'
19
+ end
20
+
21
+ def purge
22
+ test = configuration.deep_dup
23
+ test_database = test['database']
24
+ test['database'] = 'master'
25
+ establish_connection(test)
26
+ connection.recreate_database!(test_database)
27
+ end
28
+
29
+ def charset
30
+ $stderr.puts 'sorry, your database adapter is not supported yet, feel free to submit a patch'
31
+ end
32
+
33
+ def structure_dump(filename)
34
+ Kernel.system("smoscript -s #{configuration['host']} -d #{configuration['database']} -u #{configuration['username']} -p #{configuration['password']} -f #{filename} -A -U")
35
+ end
36
+
37
+ def structure_load(filename)
38
+ Kernel.system("sqlcmd -S #{configuration['host']} -d #{configuration['database']} -U #{configuration['username']} -P #{configuration['password']} -i #{filename}")
39
+ end
40
+
41
+ private
42
+
43
+ def configuration
44
+ @configuration
45
+ end
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,96 @@
1
+ require 'active_support/test_case'
2
+
3
+ ActiveSupport::Deprecation.warn('ActiveRecord::TestCase is deprecated, please use ActiveSupport::TestCase')
4
+ module ActiveRecord
5
+ # = Active Record Test Case
6
+ #
7
+ # Defines some test assertions to test against SQL queries.
8
+ class TestCase < ActiveSupport::TestCase #:nodoc:
9
+ def teardown
10
+ SQLCounter.clear_log
11
+ end
12
+
13
+ def assert_date_from_db(expected, actual, message = nil)
14
+ # SybaseAdapter doesn't have a separate column type just for dates,
15
+ # so the time is in the string and incorrectly formatted
16
+ if current_adapter?(:SybaseAdapter)
17
+ assert_equal expected.to_s, actual.to_date.to_s, message
18
+ else
19
+ assert_equal expected.to_s, actual.to_s, message
20
+ end
21
+ end
22
+
23
+ def assert_sql(*patterns_to_match)
24
+ SQLCounter.clear_log
25
+ yield
26
+ SQLCounter.log_all
27
+ ensure
28
+ failed_patterns = []
29
+ patterns_to_match.each do |pattern|
30
+ failed_patterns << pattern unless SQLCounter.log_all.any?{ |sql| pattern === sql }
31
+ end
32
+ assert failed_patterns.empty?, "Query pattern(s) #{failed_patterns.map{ |p| p.inspect }.join(', ')} not found.#{SQLCounter.log.size == 0 ? '' : "\nQueries:\n#{SQLCounter.log.join("\n")}"}"
33
+ end
34
+
35
+ def assert_queries(num = 1, options = {})
36
+ ignore_none = options.fetch(:ignore_none) { num == :any }
37
+ SQLCounter.clear_log
38
+ yield
39
+ ensure
40
+ the_log = ignore_none ? SQLCounter.log_all : SQLCounter.log
41
+ if num == :any
42
+ assert_operator the_log.size, :>=, 1, "1 or more queries expected, but none were executed."
43
+ else
44
+ mesg = "#{the_log.size} instead of #{num} queries were executed.#{the_log.size == 0 ? '' : "\nQueries:\n#{the_log.join("\n")}"}"
45
+ assert_equal num, the_log.size, mesg
46
+ end
47
+ end
48
+
49
+ def assert_no_queries(&block)
50
+ assert_queries(0, :ignore_none => true, &block)
51
+ end
52
+
53
+ end
54
+
55
+ class SQLCounter
56
+ class << self
57
+ attr_accessor :ignored_sql, :log, :log_all
58
+ def clear_log; self.log = []; self.log_all = []; end
59
+ end
60
+
61
+ self.clear_log
62
+
63
+ self.ignored_sql = [/^PRAGMA/, /^SELECT currval/, /^SELECT CAST/, /^SELECT @@IDENTITY/, /^SELECT @@ROWCOUNT/, /^SAVEPOINT/, /^ROLLBACK TO SAVEPOINT/, /^RELEASE SAVEPOINT/, /^SHOW max_identifier_length/, /^BEGIN/, /^COMMIT/]
64
+
65
+ # FIXME: this needs to be refactored so specific database can add their own
66
+ # ignored SQL, or better yet, use a different notification for the queries
67
+ # instead examining the SQL content.
68
+ oracle_ignored = [/^select .*nextval/i, /^SAVEPOINT/, /^ROLLBACK TO/, /^\s*select .* from all_triggers/im]
69
+ mysql_ignored = [/^SHOW TABLES/i, /^SHOW FULL FIELDS/]
70
+ postgresql_ignored = [/^\s*select\b.*\bfrom\b.*pg_namespace\b/im, /^\s*select\b.*\battname\b.*\bfrom\b.*\bpg_attribute\b/im, /^SHOW search_path/i]
71
+ sqlite3_ignored = [/^\s*SELECT name\b.*\bFROM sqlite_master/im]
72
+
73
+ [oracle_ignored, mysql_ignored, postgresql_ignored, sqlite3_ignored].each do |db_ignored_sql|
74
+ ignored_sql.concat db_ignored_sql
75
+ end
76
+
77
+ attr_reader :ignore
78
+
79
+ def initialize(ignore = Regexp.union(self.class.ignored_sql))
80
+ @ignore = ignore
81
+ end
82
+
83
+ def call(name, start, finish, message_id, values)
84
+ sql = values[:sql]
85
+
86
+ # FIXME: this seems bad. we should probably have a better way to indicate
87
+ # the query was cached
88
+ return if 'CACHE' == values[:name]
89
+
90
+ self.class.log_all << sql
91
+ self.class.log << sql unless ignore =~ sql
92
+ end
93
+ end
94
+
95
+ ActiveSupport::Notifications.subscribe('sql.active_record', SQLCounter.new)
96
+ end
@@ -0,0 +1,119 @@
1
+
2
+ module ActiveRecord
3
+ # = Active Record Timestamp
4
+ #
5
+ # Active Record automatically timestamps create and update operations if the
6
+ # table has fields named <tt>created_at/created_on</tt> or
7
+ # <tt>updated_at/updated_on</tt>.
8
+ #
9
+ # Timestamping can be turned off by setting:
10
+ #
11
+ # config.active_record.record_timestamps = false
12
+ #
13
+ # Timestamps are in the local timezone by default but you can use UTC by setting:
14
+ #
15
+ # config.active_record.default_timezone = :utc
16
+ #
17
+ # == Time Zone aware attributes
18
+ #
19
+ # By default, ActiveRecord::Base keeps all the datetime columns time zone aware by executing following code.
20
+ #
21
+ # config.active_record.time_zone_aware_attributes = true
22
+ #
23
+ # This feature can easily be turned off by assigning value <tt>false</tt> .
24
+ #
25
+ # If your attributes are time zone aware and you desire to skip time zone conversion to the current Time.zone
26
+ # when reading certain attributes then you can do following:
27
+ #
28
+ # class Topic < ActiveRecord::Base
29
+ # self.skip_time_zone_conversion_for_attributes = [:written_on]
30
+ # end
31
+ module Timestamp
32
+ extend ActiveSupport::Concern
33
+
34
+ included do
35
+ class_attribute :record_timestamps
36
+ self.record_timestamps = true
37
+ end
38
+
39
+ def initialize_dup(other) # :nodoc:
40
+ clear_timestamp_attributes
41
+ super
42
+ end
43
+
44
+ private
45
+
46
+ def create_record
47
+ if self.record_timestamps
48
+ current_time = current_time_from_proper_timezone
49
+
50
+ all_timestamp_attributes.each do |column|
51
+ if respond_to?(column) && respond_to?("#{column}=") && self.send(column).nil?
52
+ write_attribute(column.to_s, current_time)
53
+ end
54
+ end
55
+ end
56
+
57
+ super
58
+ end
59
+
60
+ def update_record(*args)
61
+ if should_record_timestamps?
62
+ current_time = current_time_from_proper_timezone
63
+
64
+ timestamp_attributes_for_update_in_model.each do |column|
65
+ column = column.to_s
66
+ next if attribute_changed?(column)
67
+ write_attribute(column, current_time)
68
+ end
69
+ end
70
+ super
71
+ end
72
+
73
+ def should_record_timestamps?
74
+ self.record_timestamps && (!partial_writes? || changed? || (attributes.keys & self.class.serialized_attributes.keys).present?)
75
+ end
76
+
77
+ def timestamp_attributes_for_create_in_model
78
+ timestamp_attributes_for_create.select { |c| self.class.column_names.include?(c.to_s) }
79
+ end
80
+
81
+ def timestamp_attributes_for_update_in_model
82
+ timestamp_attributes_for_update.select { |c| self.class.column_names.include?(c.to_s) }
83
+ end
84
+
85
+ def all_timestamp_attributes_in_model
86
+ timestamp_attributes_for_create_in_model + timestamp_attributes_for_update_in_model
87
+ end
88
+
89
+ def timestamp_attributes_for_update
90
+ [:updated_at, :updated_on]
91
+ end
92
+
93
+ def timestamp_attributes_for_create
94
+ [:created_at, :created_on]
95
+ end
96
+
97
+ def all_timestamp_attributes
98
+ timestamp_attributes_for_create + timestamp_attributes_for_update
99
+ end
100
+
101
+ def max_updated_column_timestamp
102
+ if (timestamps = timestamp_attributes_for_update.map { |attr| self[attr] }.compact).present?
103
+ timestamps.map { |ts| ts.to_time }.max
104
+ end
105
+ end
106
+
107
+ def current_time_from_proper_timezone
108
+ self.class.default_timezone == :utc ? Time.now.utc : Time.now
109
+ end
110
+
111
+ # Clear attributes and changed_attributes
112
+ def clear_timestamp_attributes
113
+ all_timestamp_attributes_in_model.each do |attribute_name|
114
+ self[attribute_name] = nil
115
+ changed_attributes.delete(attribute_name)
116
+ end
117
+ end
118
+ end
119
+ end