activerecord 3.2.19 → 5.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 (264) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +1715 -604
  3. data/MIT-LICENSE +2 -2
  4. data/README.rdoc +40 -45
  5. data/examples/performance.rb +33 -22
  6. data/examples/simple.rb +3 -4
  7. data/lib/active_record/aggregations.rb +76 -51
  8. data/lib/active_record/association_relation.rb +35 -0
  9. data/lib/active_record/associations/alias_tracker.rb +54 -40
  10. data/lib/active_record/associations/association.rb +76 -56
  11. data/lib/active_record/associations/association_scope.rb +125 -93
  12. data/lib/active_record/associations/belongs_to_association.rb +57 -28
  13. data/lib/active_record/associations/belongs_to_polymorphic_association.rb +7 -2
  14. data/lib/active_record/associations/builder/association.rb +120 -32
  15. data/lib/active_record/associations/builder/belongs_to.rb +115 -62
  16. data/lib/active_record/associations/builder/collection_association.rb +61 -53
  17. data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +117 -43
  18. data/lib/active_record/associations/builder/has_many.rb +9 -65
  19. data/lib/active_record/associations/builder/has_one.rb +18 -52
  20. data/lib/active_record/associations/builder/singular_association.rb +18 -19
  21. data/lib/active_record/associations/collection_association.rb +268 -186
  22. data/lib/active_record/associations/collection_proxy.rb +1003 -63
  23. data/lib/active_record/associations/foreign_association.rb +11 -0
  24. data/lib/active_record/associations/has_many_association.rb +81 -41
  25. data/lib/active_record/associations/has_many_through_association.rb +76 -55
  26. data/lib/active_record/associations/has_one_association.rb +51 -21
  27. data/lib/active_record/associations/has_one_through_association.rb +1 -1
  28. data/lib/active_record/associations/join_dependency/join_association.rb +83 -108
  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 +239 -155
  32. data/lib/active_record/associations/preloader/association.rb +97 -62
  33. data/lib/active_record/associations/preloader/collection_association.rb +2 -8
  34. data/lib/active_record/associations/preloader/has_many_through.rb +7 -3
  35. data/lib/active_record/associations/preloader/has_one.rb +0 -8
  36. data/lib/active_record/associations/preloader/singular_association.rb +3 -3
  37. data/lib/active_record/associations/preloader/through_association.rb +75 -33
  38. data/lib/active_record/associations/preloader.rb +111 -79
  39. data/lib/active_record/associations/singular_association.rb +35 -13
  40. data/lib/active_record/associations/through_association.rb +41 -19
  41. data/lib/active_record/associations.rb +727 -501
  42. data/lib/active_record/attribute/user_provided_default.rb +28 -0
  43. data/lib/active_record/attribute.rb +213 -0
  44. data/lib/active_record/attribute_assignment.rb +32 -162
  45. data/lib/active_record/attribute_decorators.rb +67 -0
  46. data/lib/active_record/attribute_methods/before_type_cast.rb +52 -7
  47. data/lib/active_record/attribute_methods/dirty.rb +101 -61
  48. data/lib/active_record/attribute_methods/primary_key.rb +50 -36
  49. data/lib/active_record/attribute_methods/query.rb +7 -6
  50. data/lib/active_record/attribute_methods/read.rb +56 -117
  51. data/lib/active_record/attribute_methods/serialization.rb +43 -96
  52. data/lib/active_record/attribute_methods/time_zone_conversion.rb +93 -42
  53. data/lib/active_record/attribute_methods/write.rb +34 -45
  54. data/lib/active_record/attribute_methods.rb +333 -144
  55. data/lib/active_record/attribute_mutation_tracker.rb +70 -0
  56. data/lib/active_record/attribute_set/builder.rb +108 -0
  57. data/lib/active_record/attribute_set.rb +108 -0
  58. data/lib/active_record/attributes.rb +265 -0
  59. data/lib/active_record/autosave_association.rb +285 -223
  60. data/lib/active_record/base.rb +95 -490
  61. data/lib/active_record/callbacks.rb +95 -61
  62. data/lib/active_record/coders/json.rb +13 -0
  63. data/lib/active_record/coders/yaml_column.rb +28 -19
  64. data/lib/active_record/collection_cache_key.rb +40 -0
  65. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +724 -277
  66. data/lib/active_record/connection_adapters/abstract/database_limits.rb +9 -0
  67. data/lib/active_record/connection_adapters/abstract/database_statements.rb +199 -192
  68. data/lib/active_record/connection_adapters/abstract/query_cache.rb +31 -26
  69. data/lib/active_record/connection_adapters/abstract/quoting.rb +140 -57
  70. data/lib/active_record/connection_adapters/abstract/savepoints.rb +21 -0
  71. data/lib/active_record/connection_adapters/abstract/schema_creation.rb +147 -0
  72. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +419 -276
  73. data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +105 -0
  74. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +963 -276
  75. data/lib/active_record/connection_adapters/abstract/transaction.rb +232 -0
  76. data/lib/active_record/connection_adapters/abstract_adapter.rb +397 -106
  77. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +643 -342
  78. data/lib/active_record/connection_adapters/column.rb +30 -259
  79. data/lib/active_record/connection_adapters/connection_specification.rb +263 -0
  80. data/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb +22 -0
  81. data/lib/active_record/connection_adapters/mysql/column.rb +50 -0
  82. data/lib/active_record/connection_adapters/mysql/database_statements.rb +125 -0
  83. data/lib/active_record/connection_adapters/mysql/explain_pretty_printer.rb +70 -0
  84. data/lib/active_record/connection_adapters/mysql/quoting.rb +51 -0
  85. data/lib/active_record/connection_adapters/mysql/schema_creation.rb +67 -0
  86. data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +93 -0
  87. data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +54 -0
  88. data/lib/active_record/connection_adapters/mysql/type_metadata.rb +32 -0
  89. data/lib/active_record/connection_adapters/mysql2_adapter.rb +47 -196
  90. data/lib/active_record/connection_adapters/postgresql/column.rb +15 -0
  91. data/lib/active_record/connection_adapters/postgresql/database_statements.rb +170 -0
  92. data/lib/active_record/connection_adapters/postgresql/explain_pretty_printer.rb +42 -0
  93. data/lib/active_record/connection_adapters/postgresql/oid/array.rb +70 -0
  94. data/lib/active_record/connection_adapters/postgresql/oid/bit.rb +52 -0
  95. data/lib/active_record/connection_adapters/postgresql/oid/bit_varying.rb +13 -0
  96. data/lib/active_record/connection_adapters/postgresql/oid/bytea.rb +15 -0
  97. data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +48 -0
  98. data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +21 -0
  99. data/lib/active_record/connection_adapters/postgresql/oid/decimal.rb +13 -0
  100. data/lib/active_record/connection_adapters/postgresql/oid/enum.rb +19 -0
  101. data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +59 -0
  102. data/lib/active_record/connection_adapters/postgresql/oid/inet.rb +13 -0
  103. data/lib/active_record/connection_adapters/postgresql/oid/json.rb +10 -0
  104. data/lib/active_record/connection_adapters/postgresql/oid/jsonb.rb +23 -0
  105. data/lib/active_record/connection_adapters/postgresql/oid/money.rb +39 -0
  106. data/lib/active_record/connection_adapters/postgresql/oid/point.rb +43 -0
  107. data/lib/active_record/connection_adapters/postgresql/oid/rails_5_1_point.rb +50 -0
  108. data/lib/active_record/connection_adapters/postgresql/oid/range.rb +93 -0
  109. data/lib/active_record/connection_adapters/postgresql/oid/specialized_string.rb +15 -0
  110. data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +109 -0
  111. data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +21 -0
  112. data/lib/active_record/connection_adapters/postgresql/oid/vector.rb +26 -0
  113. data/lib/active_record/connection_adapters/postgresql/oid/xml.rb +28 -0
  114. data/lib/active_record/connection_adapters/postgresql/oid.rb +31 -0
  115. data/lib/active_record/connection_adapters/postgresql/quoting.rb +116 -0
  116. data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +49 -0
  117. data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +180 -0
  118. data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +47 -0
  119. data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +682 -0
  120. data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +35 -0
  121. data/lib/active_record/connection_adapters/postgresql/utils.rb +77 -0
  122. data/lib/active_record/connection_adapters/postgresql_adapter.rb +558 -1039
  123. data/lib/active_record/connection_adapters/schema_cache.rb +74 -36
  124. data/lib/active_record/connection_adapters/sql_type_metadata.rb +32 -0
  125. data/lib/active_record/connection_adapters/sqlite3/explain_pretty_printer.rb +19 -0
  126. data/lib/active_record/connection_adapters/sqlite3/quoting.rb +48 -0
  127. data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +22 -0
  128. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +538 -24
  129. data/lib/active_record/connection_adapters/statement_pool.rb +31 -12
  130. data/lib/active_record/connection_handling.rb +155 -0
  131. data/lib/active_record/core.rb +561 -0
  132. data/lib/active_record/counter_cache.rb +146 -105
  133. data/lib/active_record/dynamic_matchers.rb +101 -64
  134. data/lib/active_record/enum.rb +234 -0
  135. data/lib/active_record/errors.rb +153 -56
  136. data/lib/active_record/explain.rb +15 -63
  137. data/lib/active_record/explain_registry.rb +30 -0
  138. data/lib/active_record/explain_subscriber.rb +10 -6
  139. data/lib/active_record/fixture_set/file.rb +77 -0
  140. data/lib/active_record/fixtures.rb +355 -232
  141. data/lib/active_record/gem_version.rb +15 -0
  142. data/lib/active_record/inheritance.rb +144 -79
  143. data/lib/active_record/integration.rb +66 -13
  144. data/lib/active_record/internal_metadata.rb +56 -0
  145. data/lib/active_record/legacy_yaml_adapter.rb +46 -0
  146. data/lib/active_record/locale/en.yml +9 -1
  147. data/lib/active_record/locking/optimistic.rb +77 -56
  148. data/lib/active_record/locking/pessimistic.rb +6 -6
  149. data/lib/active_record/log_subscriber.rb +53 -28
  150. data/lib/active_record/migration/command_recorder.rb +166 -33
  151. data/lib/active_record/migration/compatibility.rb +126 -0
  152. data/lib/active_record/migration/join_table.rb +15 -0
  153. data/lib/active_record/migration.rb +792 -264
  154. data/lib/active_record/model_schema.rb +192 -130
  155. data/lib/active_record/nested_attributes.rb +238 -145
  156. data/lib/active_record/no_touching.rb +52 -0
  157. data/lib/active_record/null_relation.rb +89 -0
  158. data/lib/active_record/persistence.rb +357 -157
  159. data/lib/active_record/query_cache.rb +22 -43
  160. data/lib/active_record/querying.rb +34 -23
  161. data/lib/active_record/railtie.rb +88 -48
  162. data/lib/active_record/railties/console_sandbox.rb +3 -4
  163. data/lib/active_record/railties/controller_runtime.rb +5 -4
  164. data/lib/active_record/railties/databases.rake +170 -422
  165. data/lib/active_record/railties/jdbcmysql_error.rb +1 -1
  166. data/lib/active_record/readonly_attributes.rb +2 -5
  167. data/lib/active_record/reflection.rb +715 -189
  168. data/lib/active_record/relation/batches/batch_enumerator.rb +67 -0
  169. data/lib/active_record/relation/batches.rb +203 -50
  170. data/lib/active_record/relation/calculations.rb +203 -194
  171. data/lib/active_record/relation/delegation.rb +103 -25
  172. data/lib/active_record/relation/finder_methods.rb +457 -261
  173. data/lib/active_record/relation/from_clause.rb +32 -0
  174. data/lib/active_record/relation/merger.rb +167 -0
  175. data/lib/active_record/relation/predicate_builder/array_handler.rb +43 -0
  176. data/lib/active_record/relation/predicate_builder/association_query_handler.rb +88 -0
  177. data/lib/active_record/relation/predicate_builder/base_handler.rb +17 -0
  178. data/lib/active_record/relation/predicate_builder/basic_object_handler.rb +17 -0
  179. data/lib/active_record/relation/predicate_builder/class_handler.rb +27 -0
  180. data/lib/active_record/relation/predicate_builder/polymorphic_array_handler.rb +57 -0
  181. data/lib/active_record/relation/predicate_builder/range_handler.rb +33 -0
  182. data/lib/active_record/relation/predicate_builder/relation_handler.rb +13 -0
  183. data/lib/active_record/relation/predicate_builder.rb +153 -48
  184. data/lib/active_record/relation/query_attribute.rb +19 -0
  185. data/lib/active_record/relation/query_methods.rb +1019 -194
  186. data/lib/active_record/relation/record_fetch_warning.rb +49 -0
  187. data/lib/active_record/relation/spawn_methods.rb +46 -150
  188. data/lib/active_record/relation/where_clause.rb +174 -0
  189. data/lib/active_record/relation/where_clause_factory.rb +38 -0
  190. data/lib/active_record/relation.rb +450 -245
  191. data/lib/active_record/result.rb +104 -12
  192. data/lib/active_record/runtime_registry.rb +22 -0
  193. data/lib/active_record/sanitization.rb +120 -94
  194. data/lib/active_record/schema.rb +28 -18
  195. data/lib/active_record/schema_dumper.rb +141 -74
  196. data/lib/active_record/schema_migration.rb +50 -0
  197. data/lib/active_record/scoping/default.rb +64 -57
  198. data/lib/active_record/scoping/named.rb +93 -108
  199. data/lib/active_record/scoping.rb +73 -121
  200. data/lib/active_record/secure_token.rb +38 -0
  201. data/lib/active_record/serialization.rb +7 -5
  202. data/lib/active_record/statement_cache.rb +113 -0
  203. data/lib/active_record/store.rb +173 -15
  204. data/lib/active_record/suppressor.rb +58 -0
  205. data/lib/active_record/table_metadata.rb +68 -0
  206. data/lib/active_record/tasks/database_tasks.rb +313 -0
  207. data/lib/active_record/tasks/mysql_database_tasks.rb +151 -0
  208. data/lib/active_record/tasks/postgresql_database_tasks.rb +110 -0
  209. data/lib/active_record/tasks/sqlite_database_tasks.rb +59 -0
  210. data/lib/active_record/timestamp.rb +42 -24
  211. data/lib/active_record/touch_later.rb +58 -0
  212. data/lib/active_record/transactions.rb +233 -105
  213. data/lib/active_record/type/adapter_specific_registry.rb +130 -0
  214. data/lib/active_record/type/date.rb +7 -0
  215. data/lib/active_record/type/date_time.rb +7 -0
  216. data/lib/active_record/type/hash_lookup_type_map.rb +23 -0
  217. data/lib/active_record/type/internal/abstract_json.rb +29 -0
  218. data/lib/active_record/type/internal/timezone.rb +15 -0
  219. data/lib/active_record/type/serialized.rb +63 -0
  220. data/lib/active_record/type/time.rb +20 -0
  221. data/lib/active_record/type/type_map.rb +64 -0
  222. data/lib/active_record/type.rb +72 -0
  223. data/lib/active_record/type_caster/connection.rb +29 -0
  224. data/lib/active_record/type_caster/map.rb +19 -0
  225. data/lib/active_record/type_caster.rb +7 -0
  226. data/lib/active_record/validations/absence.rb +23 -0
  227. data/lib/active_record/validations/associated.rb +33 -18
  228. data/lib/active_record/validations/length.rb +24 -0
  229. data/lib/active_record/validations/presence.rb +66 -0
  230. data/lib/active_record/validations/uniqueness.rb +128 -68
  231. data/lib/active_record/validations.rb +48 -40
  232. data/lib/active_record/version.rb +5 -7
  233. data/lib/active_record.rb +71 -47
  234. data/lib/rails/generators/active_record/migration/migration_generator.rb +56 -8
  235. data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb +24 -0
  236. data/lib/rails/generators/active_record/migration/templates/migration.rb +28 -16
  237. data/lib/rails/generators/active_record/migration.rb +18 -8
  238. data/lib/rails/generators/active_record/model/model_generator.rb +38 -16
  239. data/lib/rails/generators/active_record/model/templates/application_record.rb +5 -0
  240. data/lib/rails/generators/active_record/model/templates/model.rb +7 -6
  241. data/lib/rails/generators/active_record/model/templates/module.rb +1 -1
  242. data/lib/rails/generators/active_record.rb +3 -11
  243. metadata +188 -134
  244. data/examples/associations.png +0 -0
  245. data/lib/active_record/associations/has_and_belongs_to_many_association.rb +0 -63
  246. data/lib/active_record/associations/join_helper.rb +0 -55
  247. data/lib/active_record/associations/preloader/has_and_belongs_to_many.rb +0 -60
  248. data/lib/active_record/attribute_methods/deprecated_underscore_read.rb +0 -32
  249. data/lib/active_record/connection_adapters/abstract/connection_specification.rb +0 -191
  250. data/lib/active_record/connection_adapters/mysql_adapter.rb +0 -441
  251. data/lib/active_record/connection_adapters/sqlite_adapter.rb +0 -583
  252. data/lib/active_record/dynamic_finder_match.rb +0 -68
  253. data/lib/active_record/dynamic_scope_match.rb +0 -23
  254. data/lib/active_record/fixtures/file.rb +0 -65
  255. data/lib/active_record/identity_map.rb +0 -162
  256. data/lib/active_record/observer.rb +0 -121
  257. data/lib/active_record/serializers/xml_serializer.rb +0 -203
  258. data/lib/active_record/session_store.rb +0 -360
  259. data/lib/active_record/test_case.rb +0 -73
  260. data/lib/rails/generators/active_record/model/templates/migration.rb +0 -15
  261. data/lib/rails/generators/active_record/observer/observer_generator.rb +0 -15
  262. data/lib/rails/generators/active_record/observer/templates/observer.rb +0 -4
  263. data/lib/rails/generators/active_record/session_migration/session_migration_generator.rb +0 -25
  264. data/lib/rails/generators/active_record/session_migration/templates/migration.rb +0 -12
@@ -1,360 +0,0 @@
1
- require 'action_dispatch/middleware/session/abstract_store'
2
-
3
- module ActiveRecord
4
- # = Active Record Session Store
5
- #
6
- # A session store backed by an Active Record class. A default class is
7
- # provided, but any object duck-typing to an Active Record Session class
8
- # with text +session_id+ and +data+ attributes is sufficient.
9
- #
10
- # The default assumes a +sessions+ tables with columns:
11
- # +id+ (numeric primary key),
12
- # +session_id+ (string, :limit => 255), and
13
- # +data+ (text or longtext; careful if your session data exceeds 65KB).
14
- #
15
- # The +session_id+ column should always be indexed for speedy lookups.
16
- # Session data is marshaled to the +data+ column in Base64 format.
17
- # If the data you write is larger than the column's size limit,
18
- # ActionController::SessionOverflowError will be raised.
19
- #
20
- # You may configure the table name, primary key, and data column.
21
- # For example, at the end of <tt>config/application.rb</tt>:
22
- #
23
- # ActiveRecord::SessionStore::Session.table_name = 'legacy_session_table'
24
- # ActiveRecord::SessionStore::Session.primary_key = 'session_id'
25
- # ActiveRecord::SessionStore::Session.data_column_name = 'legacy_session_data'
26
- #
27
- # Note that setting the primary key to the +session_id+ frees you from
28
- # having a separate +id+ column if you don't want it. However, you must
29
- # set <tt>session.model.id = session.session_id</tt> by hand! A before filter
30
- # on ApplicationController is a good place.
31
- #
32
- # Since the default class is a simple Active Record, you get timestamps
33
- # for free if you add +created_at+ and +updated_at+ datetime columns to
34
- # the +sessions+ table, making periodic session expiration a snap.
35
- #
36
- # You may provide your own session class implementation, whether a
37
- # feature-packed Active Record or a bare-metal high-performance SQL
38
- # store, by setting
39
- #
40
- # ActiveRecord::SessionStore.session_class = MySessionClass
41
- #
42
- # You must implement these methods:
43
- #
44
- # self.find_by_session_id(session_id)
45
- # initialize(hash_of_session_id_and_data, options_hash = {})
46
- # attr_reader :session_id
47
- # attr_accessor :data
48
- # save
49
- # destroy
50
- #
51
- # The example SqlBypass class is a generic SQL session store. You may
52
- # use it as a basis for high-performance database-specific stores.
53
- class SessionStore < ActionDispatch::Session::AbstractStore
54
- module ClassMethods # :nodoc:
55
- def marshal(data)
56
- ::Base64.encode64(Marshal.dump(data)) if data
57
- end
58
-
59
- def unmarshal(data)
60
- Marshal.load(::Base64.decode64(data)) if data
61
- end
62
-
63
- def drop_table!
64
- connection.schema_cache.clear_table_cache!(table_name)
65
- connection.drop_table table_name
66
- end
67
-
68
- def create_table!
69
- connection.schema_cache.clear_table_cache!(table_name)
70
- connection.create_table(table_name) do |t|
71
- t.string session_id_column, :limit => 255
72
- t.text data_column_name
73
- end
74
- connection.add_index table_name, session_id_column, :unique => true
75
- end
76
- end
77
-
78
- # The default Active Record class.
79
- class Session < ActiveRecord::Base
80
- extend ClassMethods
81
-
82
- ##
83
- # :singleton-method:
84
- # Customizable data column name. Defaults to 'data'.
85
- cattr_accessor :data_column_name
86
- self.data_column_name = 'data'
87
-
88
- attr_accessible :session_id, :data, :marshaled_data
89
-
90
- before_save :marshal_data!
91
- before_save :raise_on_session_data_overflow!
92
-
93
- class << self
94
- def data_column_size_limit
95
- @data_column_size_limit ||= columns_hash[data_column_name].limit
96
- end
97
-
98
- # Hook to set up sessid compatibility.
99
- def find_by_session_id(session_id)
100
- setup_sessid_compatibility!
101
- find_by_session_id(session_id)
102
- end
103
-
104
- private
105
- def session_id_column
106
- 'session_id'
107
- end
108
-
109
- # Compatibility with tables using sessid instead of session_id.
110
- def setup_sessid_compatibility!
111
- # Reset column info since it may be stale.
112
- reset_column_information
113
- if columns_hash['sessid']
114
- def self.find_by_session_id(*args)
115
- find_by_sessid(*args)
116
- end
117
-
118
- define_method(:session_id) { sessid }
119
- define_method(:session_id=) { |session_id| self.sessid = session_id }
120
- else
121
- class << self; remove_method :find_by_session_id; end
122
-
123
- def self.find_by_session_id(session_id)
124
- find :first, :conditions => {:session_id=>session_id}
125
- end
126
- end
127
- end
128
- end
129
-
130
- def initialize(attributes = nil, options = {})
131
- @data = nil
132
- super
133
- end
134
-
135
- # Lazy-unmarshal session state.
136
- def data
137
- @data ||= self.class.unmarshal(read_attribute(@@data_column_name)) || {}
138
- end
139
-
140
- attr_writer :data
141
-
142
- # Has the session been loaded yet?
143
- def loaded?
144
- @data
145
- end
146
-
147
- private
148
- def marshal_data!
149
- return false unless loaded?
150
- write_attribute(@@data_column_name, self.class.marshal(data))
151
- end
152
-
153
- # Ensures that the data about to be stored in the database is not
154
- # larger than the data storage column. Raises
155
- # ActionController::SessionOverflowError.
156
- def raise_on_session_data_overflow!
157
- return false unless loaded?
158
- limit = self.class.data_column_size_limit
159
- if limit and read_attribute(@@data_column_name).size > limit
160
- raise ActionController::SessionOverflowError
161
- end
162
- end
163
- end
164
-
165
- # A barebones session store which duck-types with the default session
166
- # store but bypasses Active Record and issues SQL directly. This is
167
- # an example session model class meant as a basis for your own classes.
168
- #
169
- # The database connection, table name, and session id and data columns
170
- # are configurable class attributes. Marshaling and unmarshaling
171
- # are implemented as class methods that you may override. By default,
172
- # marshaling data is
173
- #
174
- # ::Base64.encode64(Marshal.dump(data))
175
- #
176
- # and unmarshaling data is
177
- #
178
- # Marshal.load(::Base64.decode64(data))
179
- #
180
- # This marshaling behavior is intended to store the widest range of
181
- # binary session data in a +text+ column. For higher performance,
182
- # store in a +blob+ column instead and forgo the Base64 encoding.
183
- class SqlBypass
184
- extend ClassMethods
185
-
186
- ##
187
- # :singleton-method:
188
- # The table name defaults to 'sessions'.
189
- cattr_accessor :table_name
190
- @@table_name = 'sessions'
191
-
192
- ##
193
- # :singleton-method:
194
- # The session id field defaults to 'session_id'.
195
- cattr_accessor :session_id_column
196
- @@session_id_column = 'session_id'
197
-
198
- ##
199
- # :singleton-method:
200
- # The data field defaults to 'data'.
201
- cattr_accessor :data_column
202
- @@data_column = 'data'
203
-
204
- class << self
205
- alias :data_column_name :data_column
206
-
207
- # Use the ActiveRecord::Base.connection by default.
208
- attr_writer :connection
209
-
210
- # Use the ActiveRecord::Base.connection_pool by default.
211
- attr_writer :connection_pool
212
-
213
- def connection
214
- @connection ||= ActiveRecord::Base.connection
215
- end
216
-
217
- def connection_pool
218
- @connection_pool ||= ActiveRecord::Base.connection_pool
219
- end
220
-
221
- # Look up a session by id and unmarshal its data if found.
222
- def find_by_session_id(session_id)
223
- if record = connection.select_one("SELECT * FROM #{@@table_name} WHERE #{@@session_id_column}=#{connection.quote(session_id)}")
224
- new(:session_id => session_id, :marshaled_data => record['data'])
225
- end
226
- end
227
- end
228
-
229
- delegate :connection, :connection=, :connection_pool, :connection_pool=, :to => self
230
-
231
- attr_reader :session_id, :new_record
232
- alias :new_record? :new_record
233
-
234
- attr_writer :data
235
-
236
- # Look for normal and marshaled data, self.find_by_session_id's way of
237
- # telling us to postpone unmarshaling until the data is requested.
238
- # We need to handle a normal data attribute in case of a new record.
239
- def initialize(attributes)
240
- @session_id = attributes[:session_id]
241
- @data = attributes[:data]
242
- @marshaled_data = attributes[:marshaled_data]
243
- @new_record = @marshaled_data.nil?
244
- end
245
-
246
- # Lazy-unmarshal session state.
247
- def data
248
- unless @data
249
- if @marshaled_data
250
- @data, @marshaled_data = self.class.unmarshal(@marshaled_data) || {}, nil
251
- else
252
- @data = {}
253
- end
254
- end
255
- @data
256
- end
257
-
258
- def loaded?
259
- @data
260
- end
261
-
262
- def save
263
- return false unless loaded?
264
- marshaled_data = self.class.marshal(data)
265
- connect = connection
266
-
267
- if @new_record
268
- @new_record = false
269
- connect.update <<-end_sql, 'Create session'
270
- INSERT INTO #{table_name} (
271
- #{connect.quote_column_name(session_id_column)},
272
- #{connect.quote_column_name(data_column)} )
273
- VALUES (
274
- #{connect.quote(session_id)},
275
- #{connect.quote(marshaled_data)} )
276
- end_sql
277
- else
278
- connect.update <<-end_sql, 'Update session'
279
- UPDATE #{table_name}
280
- SET #{connect.quote_column_name(data_column)}=#{connect.quote(marshaled_data)}
281
- WHERE #{connect.quote_column_name(session_id_column)}=#{connect.quote(session_id)}
282
- end_sql
283
- end
284
- end
285
-
286
- def destroy
287
- return if @new_record
288
-
289
- connect = connection
290
- connect.delete <<-end_sql, 'Destroy session'
291
- DELETE FROM #{table_name}
292
- WHERE #{connect.quote_column_name(session_id_column)}=#{connect.quote(session_id)}
293
- end_sql
294
- end
295
- end
296
-
297
- # The class used for session storage. Defaults to
298
- # ActiveRecord::SessionStore::Session
299
- cattr_accessor :session_class
300
- self.session_class = Session
301
-
302
- SESSION_RECORD_KEY = 'rack.session.record'
303
- ENV_SESSION_OPTIONS_KEY = Rack::Session::Abstract::ENV_SESSION_OPTIONS_KEY
304
-
305
- private
306
- def get_session(env, sid)
307
- Base.silence do
308
- unless sid and session = @@session_class.find_by_session_id(sid)
309
- # If the sid was nil or if there is no pre-existing session under the sid,
310
- # force the generation of a new sid and associate a new session associated with the new sid
311
- sid = generate_sid
312
- session = @@session_class.new(:session_id => sid, :data => {})
313
- end
314
- env[SESSION_RECORD_KEY] = session
315
- [sid, session.data]
316
- end
317
- end
318
-
319
- def set_session(env, sid, session_data, options)
320
- Base.silence do
321
- record = get_session_model(env, sid)
322
- record.data = session_data
323
- return false unless record.save
324
-
325
- session_data = record.data
326
- if session_data && session_data.respond_to?(:each_value)
327
- session_data.each_value do |obj|
328
- obj.clear_association_cache if obj.respond_to?(:clear_association_cache)
329
- end
330
- end
331
- end
332
-
333
- sid
334
- end
335
-
336
- def destroy_session(env, session_id, options)
337
- if sid = current_session_id(env)
338
- Base.silence do
339
- get_session_model(env, sid).destroy
340
- env[SESSION_RECORD_KEY] = nil
341
- end
342
- end
343
-
344
- generate_sid unless options[:drop]
345
- end
346
-
347
- def get_session_model(env, sid)
348
- if env[ENV_SESSION_OPTIONS_KEY][:id].nil?
349
- env[SESSION_RECORD_KEY] = find_session(sid)
350
- else
351
- env[SESSION_RECORD_KEY] ||= find_session(sid)
352
- end
353
- end
354
-
355
- def find_session(id)
356
- @@session_class.find_by_session_id(id) ||
357
- @@session_class.new(:session_id => id, :data => {})
358
- end
359
- end
360
- end
@@ -1,73 +0,0 @@
1
- module ActiveRecord
2
- # = Active Record Test Case
3
- #
4
- # Defines some test assertions to test against SQL queries.
5
- class TestCase < ActiveSupport::TestCase #:nodoc:
6
- setup :cleanup_identity_map
7
-
8
- def setup
9
- cleanup_identity_map
10
- end
11
-
12
- def cleanup_identity_map
13
- ActiveRecord::IdentityMap.clear
14
- end
15
-
16
- # Backport skip to Ruby 1.8. test/unit doesn't support it, so just
17
- # make it a noop.
18
- unless instance_methods.map(&:to_s).include?("skip")
19
- def skip(message)
20
- end
21
- end
22
-
23
- def assert_date_from_db(expected, actual, message = nil)
24
- # SybaseAdapter doesn't have a separate column type just for dates,
25
- # so the time is in the string and incorrectly formatted
26
- if current_adapter?(:SybaseAdapter)
27
- assert_equal expected.to_s, actual.to_date.to_s, message
28
- else
29
- assert_equal expected.to_s, actual.to_s, message
30
- end
31
- end
32
-
33
- def assert_sql(*patterns_to_match)
34
- ActiveRecord::SQLCounter.log = []
35
- yield
36
- ActiveRecord::SQLCounter.log
37
- ensure
38
- failed_patterns = []
39
- patterns_to_match.each do |pattern|
40
- failed_patterns << pattern unless ActiveRecord::SQLCounter.log.any?{ |sql| pattern === sql }
41
- end
42
- assert failed_patterns.empty?, "Query pattern(s) #{failed_patterns.map{ |p| p.inspect }.join(', ')} not found.#{ActiveRecord::SQLCounter.log.size == 0 ? '' : "\nQueries:\n#{ActiveRecord::SQLCounter.log.join("\n")}"}"
43
- end
44
-
45
- def assert_queries(num = 1)
46
- ActiveRecord::SQLCounter.log = []
47
- yield
48
- ensure
49
- assert_equal num, ActiveRecord::SQLCounter.log.size, "#{ActiveRecord::SQLCounter.log.size} instead of #{num} queries were executed.#{ActiveRecord::SQLCounter.log.size == 0 ? '' : "\nQueries:\n#{ActiveRecord::SQLCounter.log.join("\n")}"}"
50
- end
51
-
52
- def assert_no_queries(&block)
53
- prev_ignored_sql = ActiveRecord::SQLCounter.ignored_sql
54
- ActiveRecord::SQLCounter.ignored_sql = []
55
- assert_queries(0, &block)
56
- ensure
57
- ActiveRecord::SQLCounter.ignored_sql = prev_ignored_sql
58
- end
59
-
60
- def with_kcode(kcode)
61
- if RUBY_VERSION < '1.9'
62
- orig_kcode, $KCODE = $KCODE, kcode
63
- begin
64
- yield
65
- ensure
66
- $KCODE = orig_kcode
67
- end
68
- else
69
- yield
70
- end
71
- end
72
- end
73
- end
@@ -1,15 +0,0 @@
1
- class <%= migration_class_name %> < ActiveRecord::Migration
2
- def change
3
- create_table :<%= table_name %> do |t|
4
- <% attributes.each do |attribute| -%>
5
- t.<%= attribute.type %> :<%= attribute.name %><%= attribute.inject_options %>
6
- <% end -%>
7
- <% if options[:timestamps] %>
8
- t.timestamps
9
- <% end -%>
10
- end
11
- <% attributes_with_index.each do |attribute| -%>
12
- add_index :<%= table_name %>, :<%= attribute.index_name %><%= attribute.inject_index_options %>
13
- <% end -%>
14
- end
15
- end
@@ -1,15 +0,0 @@
1
- require 'rails/generators/active_record'
2
-
3
- module ActiveRecord
4
- module Generators
5
- class ObserverGenerator < Base
6
- check_class_collision :suffix => "Observer"
7
-
8
- def create_observer_file
9
- template 'observer.rb', File.join('app/models', class_path, "#{file_name}_observer.rb")
10
- end
11
-
12
- hook_for :test_framework
13
- end
14
- end
15
- end
@@ -1,4 +0,0 @@
1
- <% module_namespacing do -%>
2
- class <%= class_name %>Observer < ActiveRecord::Observer
3
- end
4
- <% end -%>
@@ -1,25 +0,0 @@
1
- require 'rails/generators/active_record'
2
- require 'active_support/core_ext/object/inclusion'
3
-
4
- module ActiveRecord
5
- module Generators
6
- class SessionMigrationGenerator < Base
7
- argument :name, :type => :string, :default => "add_sessions_table"
8
-
9
- def create_migration_file
10
- migration_template "migration.rb", "db/migrate/#{file_name}.rb"
11
- end
12
-
13
- protected
14
-
15
- def session_table_name
16
- current_table_name = ActiveRecord::SessionStore::Session.table_name
17
- if current_table_name.in?(["sessions", "session"])
18
- current_table_name = (ActiveRecord::Base.pluralize_table_names ? 'session'.pluralize : 'session')
19
- end
20
- current_table_name
21
- end
22
-
23
- end
24
- end
25
- end
@@ -1,12 +0,0 @@
1
- class <%= migration_class_name %> < ActiveRecord::Migration
2
- def change
3
- create_table :<%= session_table_name %> do |t|
4
- t.string :session_id, :null => false
5
- t.text :data
6
- t.timestamps
7
- end
8
-
9
- add_index :<%= session_table_name %>, :session_id
10
- add_index :<%= session_table_name %>, :updated_at
11
- end
12
- end