activerecord 3.2.22.5 → 5.2.8
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.
- checksums.yaml +5 -5
- data/CHANGELOG.md +657 -621
- data/MIT-LICENSE +2 -2
- data/README.rdoc +41 -46
- data/examples/performance.rb +55 -42
- data/examples/simple.rb +6 -5
- data/lib/active_record/aggregations.rb +264 -236
- data/lib/active_record/association_relation.rb +40 -0
- data/lib/active_record/associations/alias_tracker.rb +47 -42
- data/lib/active_record/associations/association.rb +127 -75
- data/lib/active_record/associations/association_scope.rb +126 -92
- data/lib/active_record/associations/belongs_to_association.rb +78 -27
- data/lib/active_record/associations/belongs_to_polymorphic_association.rb +9 -4
- data/lib/active_record/associations/builder/association.rb +117 -32
- data/lib/active_record/associations/builder/belongs_to.rb +135 -60
- data/lib/active_record/associations/builder/collection_association.rb +61 -54
- data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +120 -42
- data/lib/active_record/associations/builder/has_many.rb +10 -64
- data/lib/active_record/associations/builder/has_one.rb +19 -51
- data/lib/active_record/associations/builder/singular_association.rb +28 -18
- data/lib/active_record/associations/collection_association.rb +226 -293
- data/lib/active_record/associations/collection_proxy.rb +1067 -69
- data/lib/active_record/associations/foreign_association.rb +13 -0
- data/lib/active_record/associations/has_many_association.rb +83 -47
- data/lib/active_record/associations/has_many_through_association.rb +98 -65
- data/lib/active_record/associations/has_one_association.rb +57 -20
- data/lib/active_record/associations/has_one_through_association.rb +18 -9
- data/lib/active_record/associations/join_dependency/join_association.rb +48 -126
- data/lib/active_record/associations/join_dependency/join_base.rb +11 -12
- data/lib/active_record/associations/join_dependency/join_part.rb +35 -42
- data/lib/active_record/associations/join_dependency.rb +212 -164
- data/lib/active_record/associations/preloader/association.rb +95 -89
- data/lib/active_record/associations/preloader/through_association.rb +84 -44
- data/lib/active_record/associations/preloader.rb +123 -111
- data/lib/active_record/associations/singular_association.rb +33 -24
- data/lib/active_record/associations/through_association.rb +60 -26
- data/lib/active_record/associations.rb +1759 -1506
- data/lib/active_record/attribute_assignment.rb +60 -193
- data/lib/active_record/attribute_decorators.rb +90 -0
- data/lib/active_record/attribute_methods/before_type_cast.rb +55 -8
- data/lib/active_record/attribute_methods/dirty.rb +113 -74
- data/lib/active_record/attribute_methods/primary_key.rb +106 -77
- data/lib/active_record/attribute_methods/query.rb +8 -5
- data/lib/active_record/attribute_methods/read.rb +63 -114
- data/lib/active_record/attribute_methods/serialization.rb +60 -90
- data/lib/active_record/attribute_methods/time_zone_conversion.rb +69 -43
- data/lib/active_record/attribute_methods/write.rb +43 -45
- data/lib/active_record/attribute_methods.rb +366 -149
- data/lib/active_record/attributes.rb +266 -0
- data/lib/active_record/autosave_association.rb +312 -225
- data/lib/active_record/base.rb +114 -505
- data/lib/active_record/callbacks.rb +145 -67
- data/lib/active_record/coders/json.rb +15 -0
- data/lib/active_record/coders/yaml_column.rb +32 -23
- data/lib/active_record/collection_cache_key.rb +53 -0
- data/lib/active_record/connection_adapters/abstract/connection_pool.rb +883 -284
- data/lib/active_record/connection_adapters/abstract/database_limits.rb +16 -2
- data/lib/active_record/connection_adapters/abstract/database_statements.rb +350 -200
- data/lib/active_record/connection_adapters/abstract/query_cache.rb +82 -27
- data/lib/active_record/connection_adapters/abstract/quoting.rb +150 -65
- data/lib/active_record/connection_adapters/abstract/savepoints.rb +23 -0
- data/lib/active_record/connection_adapters/abstract/schema_creation.rb +146 -0
- data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +477 -284
- data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +95 -0
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +1100 -310
- data/lib/active_record/connection_adapters/abstract/transaction.rb +283 -0
- data/lib/active_record/connection_adapters/abstract_adapter.rb +450 -118
- data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +657 -446
- data/lib/active_record/connection_adapters/column.rb +50 -255
- data/lib/active_record/connection_adapters/connection_specification.rb +287 -0
- data/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb +33 -0
- data/lib/active_record/connection_adapters/mysql/column.rb +27 -0
- data/lib/active_record/connection_adapters/mysql/database_statements.rb +140 -0
- data/lib/active_record/connection_adapters/mysql/explain_pretty_printer.rb +72 -0
- data/lib/active_record/connection_adapters/mysql/quoting.rb +44 -0
- data/lib/active_record/connection_adapters/mysql/schema_creation.rb +73 -0
- data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +87 -0
- data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +80 -0
- data/lib/active_record/connection_adapters/mysql/schema_statements.rb +148 -0
- data/lib/active_record/connection_adapters/mysql/type_metadata.rb +35 -0
- data/lib/active_record/connection_adapters/mysql2_adapter.rb +59 -210
- data/lib/active_record/connection_adapters/postgresql/column.rb +44 -0
- data/lib/active_record/connection_adapters/postgresql/database_statements.rb +163 -0
- data/lib/active_record/connection_adapters/postgresql/explain_pretty_printer.rb +44 -0
- data/lib/active_record/connection_adapters/postgresql/oid/array.rb +92 -0
- data/lib/active_record/connection_adapters/postgresql/oid/bit.rb +56 -0
- data/lib/active_record/connection_adapters/postgresql/oid/bit_varying.rb +15 -0
- data/lib/active_record/connection_adapters/postgresql/oid/bytea.rb +17 -0
- data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +50 -0
- data/lib/active_record/connection_adapters/postgresql/oid/date.rb +23 -0
- data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +23 -0
- data/lib/active_record/connection_adapters/postgresql/oid/decimal.rb +15 -0
- data/lib/active_record/connection_adapters/postgresql/oid/enum.rb +21 -0
- data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +71 -0
- data/lib/active_record/connection_adapters/postgresql/oid/inet.rb +15 -0
- data/lib/active_record/connection_adapters/postgresql/oid/jsonb.rb +15 -0
- data/lib/active_record/connection_adapters/postgresql/oid/legacy_point.rb +45 -0
- data/lib/active_record/connection_adapters/postgresql/oid/money.rb +41 -0
- data/lib/active_record/connection_adapters/postgresql/oid/oid.rb +15 -0
- data/lib/active_record/connection_adapters/postgresql/oid/point.rb +65 -0
- data/lib/active_record/connection_adapters/postgresql/oid/range.rb +97 -0
- data/lib/active_record/connection_adapters/postgresql/oid/specialized_string.rb +18 -0
- data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +111 -0
- data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +23 -0
- data/lib/active_record/connection_adapters/postgresql/oid/vector.rb +28 -0
- data/lib/active_record/connection_adapters/postgresql/oid/xml.rb +30 -0
- data/lib/active_record/connection_adapters/postgresql/oid.rb +34 -0
- data/lib/active_record/connection_adapters/postgresql/quoting.rb +168 -0
- data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +43 -0
- data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +65 -0
- data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +206 -0
- data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +50 -0
- data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +774 -0
- data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +39 -0
- data/lib/active_record/connection_adapters/postgresql/utils.rb +81 -0
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +620 -1080
- data/lib/active_record/connection_adapters/schema_cache.rb +85 -36
- data/lib/active_record/connection_adapters/sql_type_metadata.rb +34 -0
- data/lib/active_record/connection_adapters/sqlite3/explain_pretty_printer.rb +21 -0
- data/lib/active_record/connection_adapters/sqlite3/quoting.rb +67 -0
- data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +17 -0
- data/lib/active_record/connection_adapters/sqlite3/schema_definitions.rb +19 -0
- data/lib/active_record/connection_adapters/sqlite3/schema_dumper.rb +18 -0
- data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +106 -0
- data/lib/active_record/connection_adapters/sqlite3_adapter.rb +545 -27
- data/lib/active_record/connection_adapters/statement_pool.rb +34 -13
- data/lib/active_record/connection_handling.rb +145 -0
- data/lib/active_record/core.rb +559 -0
- data/lib/active_record/counter_cache.rb +200 -105
- data/lib/active_record/define_callbacks.rb +22 -0
- data/lib/active_record/dynamic_matchers.rb +107 -69
- data/lib/active_record/enum.rb +244 -0
- data/lib/active_record/errors.rb +245 -60
- data/lib/active_record/explain.rb +35 -71
- data/lib/active_record/explain_registry.rb +32 -0
- data/lib/active_record/explain_subscriber.rb +18 -9
- data/lib/active_record/fixture_set/file.rb +82 -0
- data/lib/active_record/fixtures.rb +418 -275
- data/lib/active_record/gem_version.rb +17 -0
- data/lib/active_record/inheritance.rb +209 -100
- data/lib/active_record/integration.rb +116 -21
- data/lib/active_record/internal_metadata.rb +45 -0
- data/lib/active_record/legacy_yaml_adapter.rb +48 -0
- data/lib/active_record/locale/en.yml +9 -1
- data/lib/active_record/locking/optimistic.rb +107 -94
- data/lib/active_record/locking/pessimistic.rb +20 -8
- data/lib/active_record/log_subscriber.rb +99 -34
- data/lib/active_record/migration/command_recorder.rb +199 -64
- data/lib/active_record/migration/compatibility.rb +217 -0
- data/lib/active_record/migration/join_table.rb +17 -0
- data/lib/active_record/migration.rb +893 -296
- data/lib/active_record/model_schema.rb +328 -175
- data/lib/active_record/nested_attributes.rb +338 -242
- data/lib/active_record/no_touching.rb +58 -0
- data/lib/active_record/null_relation.rb +68 -0
- data/lib/active_record/persistence.rb +557 -170
- data/lib/active_record/query_cache.rb +14 -43
- data/lib/active_record/querying.rb +36 -24
- data/lib/active_record/railtie.rb +147 -52
- data/lib/active_record/railties/console_sandbox.rb +5 -4
- data/lib/active_record/railties/controller_runtime.rb +13 -6
- data/lib/active_record/railties/databases.rake +206 -488
- data/lib/active_record/readonly_attributes.rb +4 -6
- data/lib/active_record/reflection.rb +734 -228
- data/lib/active_record/relation/batches/batch_enumerator.rb +69 -0
- data/lib/active_record/relation/batches.rb +249 -52
- data/lib/active_record/relation/calculations.rb +330 -284
- data/lib/active_record/relation/delegation.rb +135 -37
- data/lib/active_record/relation/finder_methods.rb +450 -287
- data/lib/active_record/relation/from_clause.rb +26 -0
- data/lib/active_record/relation/merger.rb +193 -0
- data/lib/active_record/relation/predicate_builder/array_handler.rb +48 -0
- data/lib/active_record/relation/predicate_builder/association_query_value.rb +46 -0
- data/lib/active_record/relation/predicate_builder/base_handler.rb +19 -0
- data/lib/active_record/relation/predicate_builder/basic_object_handler.rb +20 -0
- data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +56 -0
- data/lib/active_record/relation/predicate_builder/range_handler.rb +42 -0
- data/lib/active_record/relation/predicate_builder/relation_handler.rb +19 -0
- data/lib/active_record/relation/predicate_builder.rb +132 -43
- data/lib/active_record/relation/query_attribute.rb +45 -0
- data/lib/active_record/relation/query_methods.rb +1037 -221
- data/lib/active_record/relation/record_fetch_warning.rb +51 -0
- data/lib/active_record/relation/spawn_methods.rb +48 -151
- data/lib/active_record/relation/where_clause.rb +186 -0
- data/lib/active_record/relation/where_clause_factory.rb +34 -0
- data/lib/active_record/relation.rb +451 -359
- data/lib/active_record/result.rb +129 -20
- data/lib/active_record/runtime_registry.rb +24 -0
- data/lib/active_record/sanitization.rb +164 -136
- data/lib/active_record/schema.rb +31 -19
- data/lib/active_record/schema_dumper.rb +154 -107
- data/lib/active_record/schema_migration.rb +56 -0
- data/lib/active_record/scoping/default.rb +108 -98
- data/lib/active_record/scoping/named.rb +125 -112
- data/lib/active_record/scoping.rb +77 -123
- data/lib/active_record/secure_token.rb +40 -0
- data/lib/active_record/serialization.rb +10 -6
- data/lib/active_record/statement_cache.rb +121 -0
- data/lib/active_record/store.rb +175 -16
- data/lib/active_record/suppressor.rb +61 -0
- data/lib/active_record/table_metadata.rb +82 -0
- data/lib/active_record/tasks/database_tasks.rb +337 -0
- data/lib/active_record/tasks/mysql_database_tasks.rb +115 -0
- data/lib/active_record/tasks/postgresql_database_tasks.rb +143 -0
- data/lib/active_record/tasks/sqlite_database_tasks.rb +83 -0
- data/lib/active_record/timestamp.rb +80 -41
- data/lib/active_record/touch_later.rb +64 -0
- data/lib/active_record/transactions.rb +240 -119
- data/lib/active_record/translation.rb +2 -0
- data/lib/active_record/type/adapter_specific_registry.rb +136 -0
- data/lib/active_record/type/date.rb +9 -0
- data/lib/active_record/type/date_time.rb +9 -0
- data/lib/active_record/type/decimal_without_scale.rb +15 -0
- data/lib/active_record/type/hash_lookup_type_map.rb +25 -0
- data/lib/active_record/type/internal/timezone.rb +17 -0
- data/lib/active_record/type/json.rb +30 -0
- data/lib/active_record/type/serialized.rb +71 -0
- data/lib/active_record/type/text.rb +11 -0
- data/lib/active_record/type/time.rb +21 -0
- data/lib/active_record/type/type_map.rb +62 -0
- data/lib/active_record/type/unsigned_integer.rb +17 -0
- data/lib/active_record/type.rb +79 -0
- data/lib/active_record/type_caster/connection.rb +33 -0
- data/lib/active_record/type_caster/map.rb +23 -0
- data/lib/active_record/type_caster.rb +9 -0
- data/lib/active_record/validations/absence.rb +25 -0
- data/lib/active_record/validations/associated.rb +35 -18
- data/lib/active_record/validations/length.rb +26 -0
- data/lib/active_record/validations/presence.rb +68 -0
- data/lib/active_record/validations/uniqueness.rb +133 -75
- data/lib/active_record/validations.rb +53 -43
- data/lib/active_record/version.rb +7 -7
- data/lib/active_record.rb +89 -57
- data/lib/rails/generators/active_record/application_record/application_record_generator.rb +27 -0
- data/lib/rails/generators/active_record/application_record/templates/application_record.rb.tt +5 -0
- data/lib/rails/generators/active_record/migration/migration_generator.rb +61 -8
- data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb.tt +24 -0
- data/lib/rails/generators/active_record/migration/templates/migration.rb.tt +46 -0
- data/lib/rails/generators/active_record/migration.rb +28 -8
- data/lib/rails/generators/active_record/model/model_generator.rb +23 -22
- data/lib/rails/generators/active_record/model/templates/model.rb.tt +13 -0
- data/lib/rails/generators/active_record/model/templates/{module.rb → module.rb.tt} +1 -1
- data/lib/rails/generators/active_record.rb +10 -16
- metadata +141 -62
- data/examples/associations.png +0 -0
- data/lib/active_record/associations/has_and_belongs_to_many_association.rb +0 -63
- data/lib/active_record/associations/join_helper.rb +0 -55
- data/lib/active_record/associations/preloader/belongs_to.rb +0 -17
- data/lib/active_record/associations/preloader/collection_association.rb +0 -24
- data/lib/active_record/associations/preloader/has_and_belongs_to_many.rb +0 -60
- data/lib/active_record/associations/preloader/has_many.rb +0 -17
- data/lib/active_record/associations/preloader/has_many_through.rb +0 -15
- data/lib/active_record/associations/preloader/has_one.rb +0 -23
- data/lib/active_record/associations/preloader/has_one_through.rb +0 -9
- data/lib/active_record/associations/preloader/singular_association.rb +0 -21
- data/lib/active_record/attribute_methods/deprecated_underscore_read.rb +0 -32
- data/lib/active_record/connection_adapters/abstract/connection_specification.rb +0 -191
- data/lib/active_record/connection_adapters/mysql_adapter.rb +0 -441
- data/lib/active_record/connection_adapters/sqlite_adapter.rb +0 -583
- data/lib/active_record/dynamic_finder_match.rb +0 -68
- data/lib/active_record/dynamic_scope_match.rb +0 -23
- data/lib/active_record/fixtures/file.rb +0 -65
- data/lib/active_record/identity_map.rb +0 -162
- data/lib/active_record/observer.rb +0 -121
- data/lib/active_record/railties/jdbcmysql_error.rb +0 -16
- data/lib/active_record/serializers/xml_serializer.rb +0 -203
- data/lib/active_record/session_store.rb +0 -360
- data/lib/active_record/test_case.rb +0 -73
- data/lib/rails/generators/active_record/migration/templates/migration.rb +0 -34
- data/lib/rails/generators/active_record/model/templates/migration.rb +0 -15
- data/lib/rails/generators/active_record/model/templates/model.rb +0 -12
- data/lib/rails/generators/active_record/observer/observer_generator.rb +0 -15
- data/lib/rails/generators/active_record/observer/templates/observer.rb +0 -4
- data/lib/rails/generators/active_record/session_migration/session_migration_generator.rb +0 -25
- data/lib/rails/generators/active_record/session_migration/templates/migration.rb +0 -12
@@ -1,86 +1,50 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "active_record/explain_registry"
|
2
4
|
|
3
5
|
module ActiveRecord
|
4
6
|
module Explain
|
5
|
-
|
6
|
-
|
7
|
-
# If a query takes longer than these many seconds we log its query plan
|
8
|
-
# automatically. nil disables this feature.
|
9
|
-
class_attribute :auto_explain_threshold_in_seconds, :instance_writer => false
|
10
|
-
self.auto_explain_threshold_in_seconds = nil
|
11
|
-
end
|
12
|
-
end
|
13
|
-
|
14
|
-
# If the database adapter supports explain and auto explain is enabled,
|
15
|
-
# this method triggers EXPLAIN logging for the queries triggered by the
|
16
|
-
# block if it takes more than the threshold as a whole. That is, the
|
17
|
-
# threshold is not checked against each individual query, but against the
|
18
|
-
# duration of the entire block. This approach is convenient for relations.
|
19
|
-
|
20
|
-
#
|
21
|
-
# The available_queries_for_explain thread variable collects the queries
|
22
|
-
# to be explained. If the value is nil, it means queries are not being
|
23
|
-
# currently collected. A false value indicates collecting is turned
|
24
|
-
# off. Otherwise it is an array of queries.
|
25
|
-
def logging_query_plan # :nodoc:
|
26
|
-
return yield unless logger
|
27
|
-
|
28
|
-
threshold = auto_explain_threshold_in_seconds
|
29
|
-
current = Thread.current
|
30
|
-
if connection.supports_explain? && threshold && current[:available_queries_for_explain].nil?
|
31
|
-
begin
|
32
|
-
queries = current[:available_queries_for_explain] = []
|
33
|
-
start = Time.now
|
34
|
-
result = yield
|
35
|
-
logger.warn(exec_explain(queries)) if Time.now - start > threshold
|
36
|
-
result
|
37
|
-
ensure
|
38
|
-
current[:available_queries_for_explain] = nil
|
39
|
-
end
|
40
|
-
else
|
41
|
-
yield
|
42
|
-
end
|
43
|
-
end
|
44
|
-
|
45
|
-
# Relation#explain needs to be able to collect the queries regardless of
|
46
|
-
# whether auto explain is enabled. This method serves that purpose.
|
7
|
+
# Executes the block with the collect flag enabled. Queries are collected
|
8
|
+
# asynchronously by the subscriber and returned.
|
47
9
|
def collecting_queries_for_explain # :nodoc:
|
48
|
-
|
49
|
-
|
50
|
-
|
10
|
+
ExplainRegistry.collect = true
|
11
|
+
yield
|
12
|
+
ExplainRegistry.queries
|
51
13
|
ensure
|
52
|
-
|
53
|
-
current[:available_queries_for_explain] = original
|
14
|
+
ExplainRegistry.reset
|
54
15
|
end
|
55
16
|
|
56
17
|
# Makes the adapter execute EXPLAIN for the tuples of queries and bindings.
|
57
18
|
# Returns a formatted string ready to be logged.
|
58
19
|
def exec_explain(queries) # :nodoc:
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
end.join("\n")
|
20
|
+
str = queries.map do |sql, binds|
|
21
|
+
msg = "EXPLAIN for: #{sql}".dup
|
22
|
+
unless binds.empty?
|
23
|
+
msg << " "
|
24
|
+
msg << binds.map { |attr| render_bind(attr) }.inspect
|
25
|
+
end
|
26
|
+
msg << "\n"
|
27
|
+
msg << connection.explain(sql, binds)
|
68
28
|
end.join("\n")
|
69
|
-
end
|
70
29
|
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
# EXPLAINs, manual calls to +ActiveRecord::Relation#explain+ run.
|
78
|
-
def silence_auto_explain
|
79
|
-
current = Thread.current
|
80
|
-
original, current[:available_queries_for_explain] = current[:available_queries_for_explain], false
|
81
|
-
yield
|
82
|
-
ensure
|
83
|
-
current[:available_queries_for_explain] = original
|
30
|
+
# Overriding inspect to be more human readable, especially in the console.
|
31
|
+
def str.inspect
|
32
|
+
self
|
33
|
+
end
|
34
|
+
|
35
|
+
str
|
84
36
|
end
|
37
|
+
|
38
|
+
private
|
39
|
+
|
40
|
+
def render_bind(attr)
|
41
|
+
value = if attr.type.binary? && attr.value
|
42
|
+
"<#{attr.value_for_database.to_s.bytesize} bytes of binary data>"
|
43
|
+
else
|
44
|
+
connection.type_cast(attr.value_for_database)
|
45
|
+
end
|
46
|
+
|
47
|
+
[attr.name, value]
|
48
|
+
end
|
85
49
|
end
|
86
50
|
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "active_support/per_thread_registry"
|
4
|
+
|
5
|
+
module ActiveRecord
|
6
|
+
# This is a thread locals registry for EXPLAIN. For example
|
7
|
+
#
|
8
|
+
# ActiveRecord::ExplainRegistry.queries
|
9
|
+
#
|
10
|
+
# returns the collected queries local to the current thread.
|
11
|
+
#
|
12
|
+
# See the documentation of ActiveSupport::PerThreadRegistry
|
13
|
+
# for further details.
|
14
|
+
class ExplainRegistry # :nodoc:
|
15
|
+
extend ActiveSupport::PerThreadRegistry
|
16
|
+
|
17
|
+
attr_accessor :queries, :collect
|
18
|
+
|
19
|
+
def initialize
|
20
|
+
reset
|
21
|
+
end
|
22
|
+
|
23
|
+
def collect?
|
24
|
+
@collect
|
25
|
+
end
|
26
|
+
|
27
|
+
def reset
|
28
|
+
@collect = false
|
29
|
+
@queries = []
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -1,23 +1,32 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "active_support/notifications"
|
4
|
+
require "active_record/explain_registry"
|
2
5
|
|
3
6
|
module ActiveRecord
|
4
7
|
class ExplainSubscriber # :nodoc:
|
5
|
-
def
|
6
|
-
|
7
|
-
|
8
|
-
|
8
|
+
def start(name, id, payload)
|
9
|
+
# unused
|
10
|
+
end
|
11
|
+
|
12
|
+
def finish(name, id, payload)
|
13
|
+
if ExplainRegistry.collect? && !ignore_payload?(payload)
|
14
|
+
ExplainRegistry.queries << payload.values_at(:sql, :binds)
|
9
15
|
end
|
10
16
|
end
|
11
17
|
|
12
18
|
# SCHEMA queries cannot be EXPLAINed, also we do not want to run EXPLAIN on
|
13
|
-
# our own EXPLAINs
|
19
|
+
# our own EXPLAINs no matter how loopingly beautiful that would be.
|
14
20
|
#
|
15
21
|
# On the other hand, we want to monitor the performance of our real database
|
16
22
|
# queries, not the performance of the access to the query cache.
|
17
|
-
IGNORED_PAYLOADS = %w(SCHEMA EXPLAIN
|
18
|
-
EXPLAINED_SQLS = /\A\s*(select|update|delete|insert)\b/i
|
23
|
+
IGNORED_PAYLOADS = %w(SCHEMA EXPLAIN)
|
24
|
+
EXPLAINED_SQLS = /\A\s*(with|select|update|delete|insert)\b/i
|
19
25
|
def ignore_payload?(payload)
|
20
|
-
payload[:exception] ||
|
26
|
+
payload[:exception] ||
|
27
|
+
payload[:cached] ||
|
28
|
+
IGNORED_PAYLOADS.include?(payload[:name]) ||
|
29
|
+
payload[:sql] !~ EXPLAINED_SQLS
|
21
30
|
end
|
22
31
|
|
23
32
|
ActiveSupport::Notifications.subscribe("sql.active_record", new)
|
@@ -0,0 +1,82 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "erb"
|
4
|
+
require "yaml"
|
5
|
+
|
6
|
+
module ActiveRecord
|
7
|
+
class FixtureSet
|
8
|
+
class File # :nodoc:
|
9
|
+
include Enumerable
|
10
|
+
|
11
|
+
##
|
12
|
+
# Open a fixture file named +file+. When called with a block, the block
|
13
|
+
# is called with the filehandle and the filehandle is automatically closed
|
14
|
+
# when the block finishes.
|
15
|
+
def self.open(file)
|
16
|
+
x = new file
|
17
|
+
block_given? ? yield(x) : x
|
18
|
+
end
|
19
|
+
|
20
|
+
def initialize(file)
|
21
|
+
@file = file
|
22
|
+
end
|
23
|
+
|
24
|
+
def each(&block)
|
25
|
+
rows.each(&block)
|
26
|
+
end
|
27
|
+
|
28
|
+
def model_class
|
29
|
+
config_row["model_class"]
|
30
|
+
end
|
31
|
+
|
32
|
+
private
|
33
|
+
def rows
|
34
|
+
@rows ||= raw_rows.reject { |fixture_name, _| fixture_name == "_fixture" }
|
35
|
+
end
|
36
|
+
|
37
|
+
def config_row
|
38
|
+
@config_row ||= begin
|
39
|
+
row = raw_rows.find { |fixture_name, _| fixture_name == "_fixture" }
|
40
|
+
if row
|
41
|
+
row.last
|
42
|
+
else
|
43
|
+
{ 'model_class': nil }
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def raw_rows
|
49
|
+
@raw_rows ||= begin
|
50
|
+
data = YAML.load(render(IO.read(@file)))
|
51
|
+
data ? validate(data).to_a : []
|
52
|
+
rescue ArgumentError, Psych::SyntaxError => error
|
53
|
+
raise Fixture::FormatError, "a YAML error occurred parsing #{@file}. Please note that YAML must be consistently indented using spaces. Tabs are not allowed. Please have a look at http://www.yaml.org/faq.html\nThe exact error was:\n #{error.class}: #{error}", error.backtrace
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def prepare_erb(content)
|
58
|
+
erb = ERB.new(content)
|
59
|
+
erb.filename = @file
|
60
|
+
erb
|
61
|
+
end
|
62
|
+
|
63
|
+
def render(content)
|
64
|
+
context = ActiveRecord::FixtureSet::RenderContext.create_subclass.new
|
65
|
+
prepare_erb(content).result(context.get_binding)
|
66
|
+
end
|
67
|
+
|
68
|
+
# Validate our unmarshalled data.
|
69
|
+
def validate(data)
|
70
|
+
unless Hash === data || YAML::Omap === data
|
71
|
+
raise Fixture::FormatError, "fixture is not a hash: #{@file}"
|
72
|
+
end
|
73
|
+
|
74
|
+
invalid = data.reject { |_, row| Hash === row }
|
75
|
+
if invalid.any?
|
76
|
+
raise Fixture::FormatError, "fixture key is not a hash: #{@file}, keys: #{invalid.keys.inspect}"
|
77
|
+
end
|
78
|
+
data
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|