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,5 +1,6 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "stringio"
|
3
4
|
|
4
5
|
module ActiveRecord
|
5
6
|
# = Active Record Schema Dumper
|
@@ -12,18 +13,28 @@ module ActiveRecord
|
|
12
13
|
##
|
13
14
|
# :singleton-method:
|
14
15
|
# A list of tables which should not be dumped to the schema.
|
15
|
-
# Acceptable values are strings as well as regexp.
|
16
|
-
#
|
17
|
-
cattr_accessor :ignore_tables
|
18
|
-
@@ignore_tables = []
|
16
|
+
# Acceptable values are strings as well as regexp if ActiveRecord::Base.schema_format == :ruby.
|
17
|
+
# Only strings are accepted if ActiveRecord::Base.schema_format == :sql.
|
18
|
+
cattr_accessor :ignore_tables, default: []
|
19
19
|
|
20
|
-
|
21
|
-
|
22
|
-
|
20
|
+
class << self
|
21
|
+
def dump(connection = ActiveRecord::Base.connection, stream = STDOUT, config = ActiveRecord::Base)
|
22
|
+
connection.create_schema_dumper(generate_options(config)).dump(stream)
|
23
|
+
stream
|
24
|
+
end
|
25
|
+
|
26
|
+
private
|
27
|
+
def generate_options(config)
|
28
|
+
{
|
29
|
+
table_name_prefix: config.table_name_prefix,
|
30
|
+
table_name_suffix: config.table_name_suffix
|
31
|
+
}
|
32
|
+
end
|
23
33
|
end
|
24
34
|
|
25
35
|
def dump(stream)
|
26
36
|
header(stream)
|
37
|
+
extensions(stream)
|
27
38
|
tables(stream)
|
28
39
|
trailer(stream)
|
29
40
|
stream
|
@@ -31,19 +42,24 @@ module ActiveRecord
|
|
31
42
|
|
32
43
|
private
|
33
44
|
|
34
|
-
def initialize(connection)
|
45
|
+
def initialize(connection, options = {})
|
35
46
|
@connection = connection
|
36
|
-
@
|
37
|
-
@
|
47
|
+
@version = connection.migration_context.current_version rescue nil
|
48
|
+
@options = options
|
38
49
|
end
|
39
50
|
|
40
|
-
|
41
|
-
|
51
|
+
# turns 20170404131909 into "2017_04_04_131909"
|
52
|
+
def formatted_version
|
53
|
+
stringified = @version.to_s
|
54
|
+
return stringified unless stringified.length == 14
|
55
|
+
stringified.insert(4, "_").insert(7, "_").insert(10, "_")
|
56
|
+
end
|
42
57
|
|
43
|
-
|
44
|
-
|
45
|
-
|
58
|
+
def define_params
|
59
|
+
@version ? "version: #{formatted_version}" : ""
|
60
|
+
end
|
46
61
|
|
62
|
+
def header(stream)
|
47
63
|
stream.puts <<HEADER
|
48
64
|
# This file is auto-generated from the current state of the database. Instead
|
49
65
|
# of editing this file, please use the migrations feature of Active Record to
|
@@ -55,7 +71,7 @@ module ActiveRecord
|
|
55
71
|
# from scratch. The latter is a flawed and unsustainable approach (the more migrations
|
56
72
|
# you'll amass, the slower it'll run and the greater likelihood for issues).
|
57
73
|
#
|
58
|
-
# It's strongly recommended
|
74
|
+
# It's strongly recommended that you check this file into your version control system.
|
59
75
|
|
60
76
|
ActiveRecord::Schema.define(#{define_params}) do
|
61
77
|
|
@@ -66,17 +82,22 @@ HEADER
|
|
66
82
|
stream.puts "end"
|
67
83
|
end
|
68
84
|
|
85
|
+
# extensions are only supported by PostgreSQL
|
86
|
+
def extensions(stream)
|
87
|
+
end
|
88
|
+
|
69
89
|
def tables(stream)
|
70
|
-
@connection.tables.sort
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
90
|
+
sorted_tables = @connection.tables.sort
|
91
|
+
|
92
|
+
sorted_tables.each do |table_name|
|
93
|
+
table(table_name, stream) unless ignored?(table_name)
|
94
|
+
end
|
95
|
+
|
96
|
+
# dump foreign keys at the end to make sure all dependent tables exist.
|
97
|
+
if @connection.supports_foreign_keys?
|
98
|
+
sorted_tables.each do |tbl|
|
99
|
+
foreign_keys(tbl, stream) unless ignored?(tbl)
|
78
100
|
end
|
79
|
-
table(tbl, stream)
|
80
101
|
end
|
81
102
|
end
|
82
103
|
|
@@ -86,75 +107,46 @@ HEADER
|
|
86
107
|
tbl = StringIO.new
|
87
108
|
|
88
109
|
# first dump primary key column
|
89
|
-
|
90
|
-
pk, _ = @connection.pk_and_sequence_for(table)
|
91
|
-
elsif @connection.respond_to?(:primary_key)
|
92
|
-
pk = @connection.primary_key(table)
|
93
|
-
end
|
110
|
+
pk = @connection.primary_key(table)
|
94
111
|
|
95
112
|
tbl.print " create_table #{remove_prefix_and_suffix(table).inspect}"
|
96
|
-
|
97
|
-
|
98
|
-
|
113
|
+
|
114
|
+
case pk
|
115
|
+
when String
|
116
|
+
tbl.print ", primary_key: #{pk.inspect}" unless pk == "id"
|
117
|
+
pkcol = columns.detect { |c| c.name == pk }
|
118
|
+
pkcolspec = column_spec_for_primary_key(pkcol)
|
119
|
+
if pkcolspec.present?
|
120
|
+
tbl.print ", #{format_colspec(pkcolspec)}"
|
99
121
|
end
|
122
|
+
when Array
|
123
|
+
tbl.print ", primary_key: #{pk.inspect}"
|
100
124
|
else
|
101
|
-
tbl.print ", :
|
125
|
+
tbl.print ", id: false"
|
102
126
|
end
|
103
|
-
|
104
|
-
|
127
|
+
|
128
|
+
table_options = @connection.table_options(table)
|
129
|
+
if table_options.present?
|
130
|
+
tbl.print ", #{format_options(table_options)}"
|
131
|
+
end
|
132
|
+
|
133
|
+
tbl.puts ", force: :cascade do |t|"
|
105
134
|
|
106
135
|
# then dump all non-primary key columns
|
107
|
-
|
108
|
-
raise StandardError, "Unknown type '#{column.sql_type}' for column '#{column.name}'"
|
136
|
+
columns.each do |column|
|
137
|
+
raise StandardError, "Unknown type '#{column.sql_type}' for column '#{column.name}'" unless @connection.valid_type?(column.type)
|
109
138
|
next if column.name == pk
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
# AR has an optimization which handles zero-scale decimals as integers. This
|
114
|
-
# code ensures that the dumper still dumps the column as a decimal.
|
115
|
-
spec[:type] = if column.type == :integer && [/^numeric/, /^decimal/].any? { |e| e.match(column.sql_type) }
|
116
|
-
'decimal'
|
117
|
-
else
|
118
|
-
column.type.to_s
|
119
|
-
end
|
120
|
-
spec[:limit] = column.limit.inspect if column.limit != @types[column.type][:limit] && spec[:type] != 'decimal'
|
121
|
-
spec[:precision] = column.precision.inspect if column.precision
|
122
|
-
spec[:scale] = column.scale.inspect if column.scale
|
123
|
-
spec[:null] = 'false' unless column.null
|
124
|
-
spec[:default] = default_string(column.default) if column.has_default?
|
125
|
-
(spec.keys - [:name, :type]).each{ |k| spec[k].insert(0, "#{k.inspect} => ")}
|
126
|
-
spec
|
127
|
-
end.compact
|
128
|
-
|
129
|
-
# find all migration keys used in this table
|
130
|
-
keys = [:name, :limit, :precision, :scale, :default, :null] & column_specs.map{ |k| k.keys }.flatten
|
131
|
-
|
132
|
-
# figure out the lengths for each column based on above keys
|
133
|
-
lengths = keys.map{ |key| column_specs.map{ |spec| spec[key] ? spec[key].length + 2 : 0 }.max }
|
134
|
-
|
135
|
-
# the string we're going to sprintf our values against, with standardized column widths
|
136
|
-
format_string = lengths.map{ |len| "%-#{len}s" }
|
137
|
-
|
138
|
-
# find the max length for the 'type' column, which is special
|
139
|
-
type_length = column_specs.map{ |column| column[:type].length }.max
|
140
|
-
|
141
|
-
# add column type definition to our format string
|
142
|
-
format_string.unshift " t.%-#{type_length}s "
|
143
|
-
|
144
|
-
format_string *= ''
|
145
|
-
|
146
|
-
column_specs.each do |colspec|
|
147
|
-
values = keys.zip(lengths).map{ |key, len| colspec.key?(key) ? colspec[key] + ", " : " " * len }
|
148
|
-
values.unshift colspec[:type]
|
149
|
-
tbl.print((format_string % values).gsub(/,\s*$/, ''))
|
139
|
+
type, colspec = column_spec(column)
|
140
|
+
tbl.print " t.#{type} #{column.name.inspect}"
|
141
|
+
tbl.print ", #{format_colspec(colspec)}" if colspec.present?
|
150
142
|
tbl.puts
|
151
143
|
end
|
152
144
|
|
145
|
+
indexes_in_create(table, tbl)
|
146
|
+
|
153
147
|
tbl.puts " end"
|
154
148
|
tbl.puts
|
155
149
|
|
156
|
-
indexes(table, tbl)
|
157
|
-
|
158
150
|
tbl.rewind
|
159
151
|
stream.print tbl.read
|
160
152
|
rescue => e
|
@@ -162,47 +154,102 @@ HEADER
|
|
162
154
|
stream.puts "# #{e.message}"
|
163
155
|
stream.puts
|
164
156
|
end
|
165
|
-
|
166
|
-
stream
|
167
157
|
end
|
168
158
|
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
159
|
+
# Keep it for indexing materialized views
|
160
|
+
def indexes(table, stream)
|
161
|
+
if (indexes = @connection.indexes(table)).any?
|
162
|
+
add_index_statements = indexes.map do |index|
|
163
|
+
table_name = remove_prefix_and_suffix(index.table).inspect
|
164
|
+
" add_index #{([table_name] + index_parts(index)).join(', ')}"
|
165
|
+
end
|
166
|
+
|
167
|
+
stream.puts add_index_statements.sort.join("\n")
|
168
|
+
stream.puts
|
177
169
|
end
|
178
170
|
end
|
179
171
|
|
180
|
-
def
|
172
|
+
def indexes_in_create(table, stream)
|
181
173
|
if (indexes = @connection.indexes(table)).any?
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
174
|
+
index_statements = indexes.map do |index|
|
175
|
+
" t.index #{index_parts(index).join(', ')}"
|
176
|
+
end
|
177
|
+
stream.puts index_statements.sort.join("\n")
|
178
|
+
end
|
179
|
+
end
|
180
|
+
|
181
|
+
def index_parts(index)
|
182
|
+
index_parts = [
|
183
|
+
index.columns.inspect,
|
184
|
+
"name: #{index.name.inspect}",
|
185
|
+
]
|
186
|
+
index_parts << "unique: true" if index.unique
|
187
|
+
index_parts << "length: #{format_index_parts(index.lengths)}" if index.lengths.present?
|
188
|
+
index_parts << "order: #{format_index_parts(index.orders)}" if index.orders.present?
|
189
|
+
index_parts << "opclass: #{format_index_parts(index.opclasses)}" if index.opclasses.present?
|
190
|
+
index_parts << "where: #{index.where.inspect}" if index.where
|
191
|
+
index_parts << "using: #{index.using.inspect}" if !@connection.default_index_type?(index)
|
192
|
+
index_parts << "type: #{index.type.inspect}" if index.type
|
193
|
+
index_parts << "comment: #{index.comment.inspect}" if index.comment
|
194
|
+
index_parts
|
195
|
+
end
|
196
|
+
|
197
|
+
def foreign_keys(table, stream)
|
198
|
+
if (foreign_keys = @connection.foreign_keys(table)).any?
|
199
|
+
add_foreign_key_statements = foreign_keys.map do |foreign_key|
|
200
|
+
parts = [
|
201
|
+
"add_foreign_key #{remove_prefix_and_suffix(foreign_key.from_table).inspect}",
|
202
|
+
remove_prefix_and_suffix(foreign_key.to_table).inspect,
|
187
203
|
]
|
188
|
-
statement_parts << ':unique => true' if index.unique
|
189
204
|
|
190
|
-
|
191
|
-
|
205
|
+
if foreign_key.column != @connection.foreign_key_column_for(foreign_key.to_table)
|
206
|
+
parts << "column: #{foreign_key.column.inspect}"
|
207
|
+
end
|
208
|
+
|
209
|
+
if foreign_key.custom_primary_key?
|
210
|
+
parts << "primary_key: #{foreign_key.primary_key.inspect}"
|
211
|
+
end
|
212
|
+
|
213
|
+
if foreign_key.name !~ /^fk_rails_[0-9a-f]{10}$/
|
214
|
+
parts << "name: #{foreign_key.name.inspect}"
|
215
|
+
end
|
192
216
|
|
193
|
-
|
194
|
-
|
217
|
+
parts << "on_update: #{foreign_key.on_update.inspect}" if foreign_key.on_update
|
218
|
+
parts << "on_delete: #{foreign_key.on_delete.inspect}" if foreign_key.on_delete
|
195
219
|
|
196
|
-
|
220
|
+
" #{parts.join(', ')}"
|
197
221
|
end
|
198
222
|
|
199
|
-
stream.puts
|
200
|
-
|
223
|
+
stream.puts add_foreign_key_statements.sort.join("\n")
|
224
|
+
end
|
225
|
+
end
|
226
|
+
|
227
|
+
def format_colspec(colspec)
|
228
|
+
colspec.map { |key, value| "#{key}: #{value}" }.join(", ")
|
229
|
+
end
|
230
|
+
|
231
|
+
def format_options(options)
|
232
|
+
options.map { |key, value| "#{key}: #{value.inspect}" }.join(", ")
|
233
|
+
end
|
234
|
+
|
235
|
+
def format_index_parts(options)
|
236
|
+
if options.is_a?(Hash)
|
237
|
+
"{ #{format_options(options)} }"
|
238
|
+
else
|
239
|
+
options.inspect
|
201
240
|
end
|
202
241
|
end
|
203
242
|
|
204
243
|
def remove_prefix_and_suffix(table)
|
205
|
-
|
244
|
+
prefix = Regexp.escape(@options[:table_name_prefix].to_s)
|
245
|
+
suffix = Regexp.escape(@options[:table_name_suffix].to_s)
|
246
|
+
table.sub(/\A#{prefix}(.+)#{suffix}\z/, "\\1")
|
247
|
+
end
|
248
|
+
|
249
|
+
def ignored?(table_name)
|
250
|
+
[ActiveRecord::Base.schema_migrations_table_name, ActiveRecord::Base.internal_metadata_table_name, ignore_tables].flatten.any? do |ignored|
|
251
|
+
ignored === remove_prefix_and_suffix(table_name)
|
252
|
+
end
|
206
253
|
end
|
207
254
|
end
|
208
255
|
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "active_record/scoping/default"
|
4
|
+
require "active_record/scoping/named"
|
5
|
+
|
6
|
+
module ActiveRecord
|
7
|
+
# This class is used to create a table that keeps track of which migrations
|
8
|
+
# have been applied to a given database. When a migration is run, its schema
|
9
|
+
# number is inserted in to the `SchemaMigration.table_name` so it doesn't need
|
10
|
+
# to be executed the next time.
|
11
|
+
class SchemaMigration < ActiveRecord::Base # :nodoc:
|
12
|
+
class << self
|
13
|
+
def primary_key
|
14
|
+
"version"
|
15
|
+
end
|
16
|
+
|
17
|
+
def table_name
|
18
|
+
"#{table_name_prefix}#{ActiveRecord::Base.schema_migrations_table_name}#{table_name_suffix}"
|
19
|
+
end
|
20
|
+
|
21
|
+
def table_exists?
|
22
|
+
connection.table_exists?(table_name)
|
23
|
+
end
|
24
|
+
|
25
|
+
def create_table
|
26
|
+
unless table_exists?
|
27
|
+
version_options = connection.internal_string_options_for_primary_key
|
28
|
+
|
29
|
+
connection.create_table(table_name, id: false) do |t|
|
30
|
+
t.string :version, version_options
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def drop_table
|
36
|
+
connection.drop_table table_name, if_exists: true
|
37
|
+
end
|
38
|
+
|
39
|
+
def normalize_migration_number(number)
|
40
|
+
"%.3d" % number.to_i
|
41
|
+
end
|
42
|
+
|
43
|
+
def normalized_versions
|
44
|
+
all_versions.map { |v| normalize_migration_number v }
|
45
|
+
end
|
46
|
+
|
47
|
+
def all_versions
|
48
|
+
order(:version).pluck(:version)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def version
|
53
|
+
super.to_i
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module ActiveRecord
|
4
4
|
module Scoping
|
@@ -6,136 +6,146 @@ module ActiveRecord
|
|
6
6
|
extend ActiveSupport::Concern
|
7
7
|
|
8
8
|
included do
|
9
|
-
# Stores the default scope for the class
|
10
|
-
class_attribute :default_scopes, :
|
11
|
-
|
9
|
+
# Stores the default scope for the class.
|
10
|
+
class_attribute :default_scopes, instance_writer: false, instance_predicate: false, default: []
|
11
|
+
class_attribute :default_scope_override, instance_writer: false, instance_predicate: false, default: nil
|
12
12
|
end
|
13
13
|
|
14
14
|
module ClassMethods
|
15
|
-
# Returns a scope for the model without the
|
15
|
+
# Returns a scope for the model without the previously set scopes.
|
16
16
|
#
|
17
17
|
# class Post < ActiveRecord::Base
|
18
18
|
# def self.default_scope
|
19
|
-
# where
|
19
|
+
# where(published: true)
|
20
20
|
# end
|
21
21
|
# end
|
22
22
|
#
|
23
|
-
# Post.all
|
24
|
-
# Post.unscoped.all
|
23
|
+
# Post.all # Fires "SELECT * FROM posts WHERE published = true"
|
24
|
+
# Post.unscoped.all # Fires "SELECT * FROM posts"
|
25
|
+
# Post.where(published: false).unscoped.all # Fires "SELECT * FROM posts"
|
25
26
|
#
|
26
27
|
# This method also accepts a block. All queries inside the block will
|
27
|
-
# not use the
|
28
|
+
# not use the previously set scopes.
|
28
29
|
#
|
29
30
|
# Post.unscoped {
|
30
31
|
# Post.limit(10) # Fires "SELECT * FROM posts LIMIT 10"
|
31
32
|
# }
|
32
|
-
|
33
|
-
# It is recommended to use the block form of unscoped because chaining
|
34
|
-
# unscoped with <tt>scope</tt> does not work. Assuming that
|
35
|
-
# <tt>published</tt> is a <tt>scope</tt>, the following two statements
|
36
|
-
# are equal: the default_scope is applied on both.
|
37
|
-
#
|
38
|
-
# Post.unscoped.published
|
39
|
-
# Post.published
|
40
|
-
def unscoped #:nodoc:
|
33
|
+
def unscoped
|
41
34
|
block_given? ? relation.scoping { yield } : relation
|
42
35
|
end
|
43
36
|
|
37
|
+
# Are there attributes associated with this scope?
|
38
|
+
def scope_attributes? # :nodoc:
|
39
|
+
super || default_scopes.any? || respond_to?(:default_scope)
|
40
|
+
end
|
41
|
+
|
44
42
|
def before_remove_const #:nodoc:
|
45
43
|
self.current_scope = nil
|
46
44
|
end
|
47
45
|
|
48
|
-
|
46
|
+
private
|
49
47
|
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
48
|
+
# Use this macro in your model to set a default scope for all operations on
|
49
|
+
# the model.
|
50
|
+
#
|
51
|
+
# class Article < ActiveRecord::Base
|
52
|
+
# default_scope { where(published: true) }
|
53
|
+
# end
|
54
|
+
#
|
55
|
+
# Article.all # => SELECT * FROM articles WHERE published = true
|
56
|
+
#
|
57
|
+
# The #default_scope is also applied while creating/building a record.
|
58
|
+
# It is not applied while updating a record.
|
59
|
+
#
|
60
|
+
# Article.new.published # => true
|
61
|
+
# Article.create.published # => true
|
62
|
+
#
|
63
|
+
# (You can also pass any object which responds to +call+ to the
|
64
|
+
# +default_scope+ macro, and it will be called when building the
|
65
|
+
# default scope.)
|
66
|
+
#
|
67
|
+
# If you use multiple #default_scope declarations in your model then
|
68
|
+
# they will be merged together:
|
69
|
+
#
|
70
|
+
# class Article < ActiveRecord::Base
|
71
|
+
# default_scope { where(published: true) }
|
72
|
+
# default_scope { where(rating: 'G') }
|
73
|
+
# end
|
74
|
+
#
|
75
|
+
# Article.all # => SELECT * FROM articles WHERE published = true AND rating = 'G'
|
76
|
+
#
|
77
|
+
# This is also the case with inheritance and module includes where the
|
78
|
+
# parent or module defines a #default_scope and the child or including
|
79
|
+
# class defines a second one.
|
80
|
+
#
|
81
|
+
# If you need to do more complex things with a default scope, you can
|
82
|
+
# alternatively define it as a class method:
|
83
|
+
#
|
84
|
+
# class Article < ActiveRecord::Base
|
85
|
+
# def self.default_scope
|
86
|
+
# # Should return a scope, you can call 'super' here etc.
|
87
|
+
# end
|
88
|
+
# end
|
89
|
+
def default_scope(scope = nil, &block) # :doc:
|
90
|
+
scope = block if block_given?
|
91
|
+
|
92
|
+
if scope.is_a?(Relation) || !scope.respond_to?(:call)
|
93
|
+
raise ArgumentError,
|
94
|
+
"Support for calling #default_scope without a block is removed. For example instead " \
|
95
|
+
"of `default_scope where(color: 'red')`, please use " \
|
96
|
+
"`default_scope { where(color: 'red') }`. (Alternatively you can just redefine " \
|
97
|
+
"self.default_scope.)"
|
98
|
+
end
|
99
|
+
|
100
|
+
self.default_scopes += [scope]
|
101
|
+
end
|
102
|
+
|
103
|
+
def build_default_scope(base_rel = nil)
|
104
|
+
return if abstract_class?
|
105
|
+
|
106
|
+
if default_scope_override.nil?
|
107
|
+
self.default_scope_override = !Base.is_a?(method(:default_scope).owner)
|
108
|
+
end
|
99
109
|
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
110
|
+
if default_scope_override
|
111
|
+
# The user has defined their own default scope method, so call that
|
112
|
+
evaluate_default_scope do
|
113
|
+
if scope = default_scope
|
114
|
+
(base_rel ||= relation).merge!(scope)
|
115
|
+
end
|
116
|
+
end
|
117
|
+
elsif default_scopes.any?
|
118
|
+
base_rel ||= relation
|
119
|
+
evaluate_default_scope do
|
120
|
+
default_scopes.inject(base_rel) do |default_scope, scope|
|
121
|
+
scope = scope.respond_to?(:to_proc) ? scope : scope.method(:call)
|
122
|
+
default_scope.merge!(base_rel.instance_exec(&scope))
|
112
123
|
end
|
113
124
|
end
|
114
125
|
end
|
115
126
|
end
|
116
|
-
end
|
117
127
|
|
118
|
-
|
119
|
-
|
120
|
-
|
128
|
+
def ignore_default_scope?
|
129
|
+
ScopeRegistry.value_for(:ignore_default_scope, base_class)
|
130
|
+
end
|
121
131
|
|
122
|
-
|
123
|
-
|
124
|
-
|
132
|
+
def ignore_default_scope=(ignore)
|
133
|
+
ScopeRegistry.set_value_for(:ignore_default_scope, base_class, ignore)
|
134
|
+
end
|
125
135
|
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
136
|
+
# The ignore_default_scope flag is used to prevent an infinite recursion
|
137
|
+
# situation where a default scope references a scope which has a default
|
138
|
+
# scope which references a scope...
|
139
|
+
def evaluate_default_scope
|
140
|
+
return if ignore_default_scope?
|
130
141
|
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
142
|
+
begin
|
143
|
+
self.ignore_default_scope = true
|
144
|
+
yield
|
145
|
+
ensure
|
146
|
+
self.ignore_default_scope = false
|
147
|
+
end
|
136
148
|
end
|
137
|
-
end
|
138
|
-
|
139
149
|
end
|
140
150
|
end
|
141
151
|
end
|