activerecord 4.2.0 → 5.2.8.1
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 +640 -928
- data/MIT-LICENSE +2 -2
- data/README.rdoc +10 -11
- data/examples/performance.rb +32 -31
- data/examples/simple.rb +5 -4
- data/lib/active_record/aggregations.rb +264 -247
- data/lib/active_record/association_relation.rb +24 -6
- data/lib/active_record/associations/alias_tracker.rb +29 -35
- data/lib/active_record/associations/association.rb +87 -41
- data/lib/active_record/associations/association_scope.rb +106 -132
- data/lib/active_record/associations/belongs_to_association.rb +55 -36
- data/lib/active_record/associations/belongs_to_polymorphic_association.rb +8 -8
- data/lib/active_record/associations/builder/association.rb +29 -38
- data/lib/active_record/associations/builder/belongs_to.rb +77 -30
- data/lib/active_record/associations/builder/collection_association.rb +14 -23
- data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +50 -39
- data/lib/active_record/associations/builder/has_many.rb +6 -4
- data/lib/active_record/associations/builder/has_one.rb +13 -6
- data/lib/active_record/associations/builder/singular_association.rb +15 -11
- data/lib/active_record/associations/collection_association.rb +145 -266
- data/lib/active_record/associations/collection_proxy.rb +242 -138
- data/lib/active_record/associations/foreign_association.rb +13 -0
- data/lib/active_record/associations/has_many_association.rb +35 -75
- data/lib/active_record/associations/has_many_through_association.rb +51 -69
- data/lib/active_record/associations/has_one_association.rb +39 -24
- data/lib/active_record/associations/has_one_through_association.rb +18 -9
- data/lib/active_record/associations/join_dependency/join_association.rb +40 -81
- data/lib/active_record/associations/join_dependency/join_base.rb +10 -9
- data/lib/active_record/associations/join_dependency/join_part.rb +12 -12
- data/lib/active_record/associations/join_dependency.rb +134 -154
- data/lib/active_record/associations/preloader/association.rb +85 -116
- data/lib/active_record/associations/preloader/through_association.rb +85 -74
- data/lib/active_record/associations/preloader.rb +83 -93
- data/lib/active_record/associations/singular_association.rb +27 -40
- data/lib/active_record/associations/through_association.rb +48 -23
- data/lib/active_record/associations.rb +1732 -1596
- data/lib/active_record/attribute_assignment.rb +58 -182
- data/lib/active_record/attribute_decorators.rb +39 -15
- data/lib/active_record/attribute_methods/before_type_cast.rb +12 -5
- data/lib/active_record/attribute_methods/dirty.rb +94 -125
- data/lib/active_record/attribute_methods/primary_key.rb +86 -71
- data/lib/active_record/attribute_methods/query.rb +4 -2
- data/lib/active_record/attribute_methods/read.rb +45 -63
- data/lib/active_record/attribute_methods/serialization.rb +40 -20
- data/lib/active_record/attribute_methods/time_zone_conversion.rb +62 -36
- data/lib/active_record/attribute_methods/write.rb +31 -46
- data/lib/active_record/attribute_methods.rb +170 -117
- data/lib/active_record/attributes.rb +201 -74
- data/lib/active_record/autosave_association.rb +118 -45
- data/lib/active_record/base.rb +60 -48
- data/lib/active_record/callbacks.rb +97 -57
- data/lib/active_record/coders/json.rb +3 -1
- data/lib/active_record/coders/yaml_column.rb +37 -13
- data/lib/active_record/collection_cache_key.rb +53 -0
- data/lib/active_record/connection_adapters/abstract/connection_pool.rb +712 -284
- data/lib/active_record/connection_adapters/abstract/database_limits.rb +10 -5
- data/lib/active_record/connection_adapters/abstract/database_statements.rb +254 -87
- data/lib/active_record/connection_adapters/abstract/query_cache.rb +72 -22
- data/lib/active_record/connection_adapters/abstract/quoting.rb +119 -52
- data/lib/active_record/connection_adapters/abstract/savepoints.rb +6 -4
- data/lib/active_record/connection_adapters/abstract/schema_creation.rb +67 -46
- data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +328 -217
- data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +81 -36
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +617 -212
- data/lib/active_record/connection_adapters/abstract/transaction.rb +139 -75
- data/lib/active_record/connection_adapters/abstract_adapter.rb +332 -191
- data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +567 -563
- data/lib/active_record/connection_adapters/column.rb +50 -41
- data/lib/active_record/connection_adapters/connection_specification.rb +147 -135
- 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 +42 -195
- data/lib/active_record/connection_adapters/postgresql/column.rb +35 -11
- data/lib/active_record/connection_adapters/postgresql/database_statements.rb +46 -115
- data/lib/active_record/connection_adapters/postgresql/explain_pretty_printer.rb +44 -0
- data/lib/active_record/connection_adapters/postgresql/oid/array.rb +50 -57
- data/lib/active_record/connection_adapters/postgresql/oid/bit.rb +10 -6
- data/lib/active_record/connection_adapters/postgresql/oid/bit_varying.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid/bytea.rb +5 -2
- data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +5 -1
- data/lib/active_record/connection_adapters/postgresql/oid/date.rb +13 -1
- data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +9 -13
- data/lib/active_record/connection_adapters/postgresql/oid/decimal.rb +3 -1
- data/lib/active_record/connection_adapters/postgresql/oid/enum.rb +7 -3
- data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +31 -19
- data/lib/active_record/connection_adapters/postgresql/oid/inet.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid/jsonb.rb +3 -11
- data/lib/active_record/connection_adapters/postgresql/oid/legacy_point.rb +45 -0
- data/lib/active_record/connection_adapters/postgresql/oid/money.rb +7 -9
- data/lib/active_record/connection_adapters/postgresql/oid/{integer.rb → oid.rb} +6 -2
- data/lib/active_record/connection_adapters/postgresql/oid/point.rb +33 -11
- data/lib/active_record/connection_adapters/postgresql/oid/range.rb +52 -34
- data/lib/active_record/connection_adapters/postgresql/oid/specialized_string.rb +4 -1
- data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +65 -51
- data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +5 -3
- data/lib/active_record/connection_adapters/postgresql/oid/vector.rb +3 -1
- data/lib/active_record/connection_adapters/postgresql/oid/xml.rb +3 -1
- data/lib/active_record/connection_adapters/postgresql/oid.rb +23 -25
- data/lib/active_record/connection_adapters/postgresql/quoting.rb +107 -47
- data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +27 -14
- data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +65 -0
- data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +144 -90
- data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +50 -0
- data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +466 -280
- data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +39 -0
- data/lib/active_record/connection_adapters/postgresql/utils.rb +12 -8
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +439 -330
- data/lib/active_record/connection_adapters/schema_cache.rb +48 -24
- 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 +269 -324
- data/lib/active_record/connection_adapters/statement_pool.rb +34 -13
- data/lib/active_record/connection_handling.rb +40 -27
- data/lib/active_record/core.rb +205 -202
- data/lib/active_record/counter_cache.rb +80 -37
- data/lib/active_record/define_callbacks.rb +22 -0
- data/lib/active_record/dynamic_matchers.rb +87 -105
- data/lib/active_record/enum.rb +136 -90
- data/lib/active_record/errors.rb +180 -52
- data/lib/active_record/explain.rb +23 -11
- data/lib/active_record/explain_registry.rb +4 -2
- data/lib/active_record/explain_subscriber.rb +11 -6
- data/lib/active_record/fixture_set/file.rb +35 -9
- data/lib/active_record/fixtures.rb +193 -135
- data/lib/active_record/gem_version.rb +5 -3
- data/lib/active_record/inheritance.rb +148 -112
- data/lib/active_record/integration.rb +70 -28
- 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 +3 -2
- data/lib/active_record/locking/optimistic.rb +92 -98
- data/lib/active_record/locking/pessimistic.rb +15 -3
- data/lib/active_record/log_subscriber.rb +95 -33
- data/lib/active_record/migration/command_recorder.rb +133 -90
- data/lib/active_record/migration/compatibility.rb +217 -0
- data/lib/active_record/migration/join_table.rb +8 -6
- data/lib/active_record/migration.rb +594 -267
- data/lib/active_record/model_schema.rb +292 -111
- data/lib/active_record/nested_attributes.rb +266 -214
- data/lib/active_record/no_touching.rb +8 -2
- data/lib/active_record/null_relation.rb +24 -37
- data/lib/active_record/persistence.rb +350 -119
- data/lib/active_record/query_cache.rb +13 -24
- data/lib/active_record/querying.rb +19 -17
- data/lib/active_record/railtie.rb +117 -35
- data/lib/active_record/railties/console_sandbox.rb +2 -0
- data/lib/active_record/railties/controller_runtime.rb +9 -3
- data/lib/active_record/railties/databases.rake +160 -174
- data/lib/active_record/readonly_attributes.rb +5 -4
- data/lib/active_record/reflection.rb +447 -288
- data/lib/active_record/relation/batches/batch_enumerator.rb +69 -0
- data/lib/active_record/relation/batches.rb +204 -55
- data/lib/active_record/relation/calculations.rb +259 -244
- data/lib/active_record/relation/delegation.rb +67 -60
- data/lib/active_record/relation/finder_methods.rb +290 -253
- data/lib/active_record/relation/from_clause.rb +26 -0
- data/lib/active_record/relation/merger.rb +91 -68
- data/lib/active_record/relation/predicate_builder/array_handler.rb +24 -23
- 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 +7 -1
- data/lib/active_record/relation/predicate_builder.rb +118 -92
- data/lib/active_record/relation/query_attribute.rb +45 -0
- data/lib/active_record/relation/query_methods.rb +446 -389
- data/lib/active_record/relation/record_fetch_warning.rb +51 -0
- data/lib/active_record/relation/spawn_methods.rb +18 -16
- 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 +287 -339
- data/lib/active_record/result.rb +54 -36
- data/lib/active_record/runtime_registry.rb +6 -4
- data/lib/active_record/sanitization.rb +155 -124
- data/lib/active_record/schema.rb +30 -24
- data/lib/active_record/schema_dumper.rb +91 -87
- data/lib/active_record/schema_migration.rb +19 -19
- data/lib/active_record/scoping/default.rb +102 -84
- data/lib/active_record/scoping/named.rb +81 -32
- data/lib/active_record/scoping.rb +45 -26
- data/lib/active_record/secure_token.rb +40 -0
- data/lib/active_record/serialization.rb +5 -5
- data/lib/active_record/statement_cache.rb +45 -35
- data/lib/active_record/store.rb +42 -36
- 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 +136 -95
- data/lib/active_record/tasks/mysql_database_tasks.rb +59 -89
- data/lib/active_record/tasks/postgresql_database_tasks.rb +84 -31
- data/lib/active_record/tasks/sqlite_database_tasks.rb +44 -16
- data/lib/active_record/timestamp.rb +70 -38
- data/lib/active_record/touch_later.rb +64 -0
- data/lib/active_record/transactions.rb +208 -123
- 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 +4 -41
- data/lib/active_record/type/date_time.rb +4 -38
- data/lib/active_record/type/decimal_without_scale.rb +6 -2
- data/lib/active_record/type/hash_lookup_type_map.rb +13 -5
- 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 +30 -15
- data/lib/active_record/type/text.rb +2 -2
- data/lib/active_record/type/time.rb +11 -16
- data/lib/active_record/type/type_map.rb +15 -17
- data/lib/active_record/type/unsigned_integer.rb +9 -7
- data/lib/active_record/type.rb +79 -23
- 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 +13 -4
- data/lib/active_record/validations/length.rb +26 -0
- data/lib/active_record/validations/presence.rb +14 -13
- data/lib/active_record/validations/uniqueness.rb +41 -32
- data/lib/active_record/validations.rb +38 -35
- data/lib/active_record/version.rb +3 -1
- data/lib/active_record.rb +36 -21
- 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 +43 -35
- data/lib/rails/generators/active_record/migration/templates/{create_table_migration.rb → create_table_migration.rb.tt} +8 -6
- data/lib/rails/generators/active_record/migration/templates/{migration.rb → migration.rb.tt} +8 -7
- data/lib/rails/generators/active_record/migration.rb +18 -1
- data/lib/rails/generators/active_record/model/model_generator.rb +18 -22
- data/lib/rails/generators/active_record/model/templates/{model.rb → model.rb.tt} +3 -0
- data/lib/rails/generators/active_record.rb +7 -5
- metadata +77 -53
- 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_many.rb +0 -17
- data/lib/active_record/associations/preloader/has_many_through.rb +0 -19
- 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.rb +0 -149
- data/lib/active_record/attribute_set/builder.rb +0 -86
- data/lib/active_record/attribute_set.rb +0 -77
- data/lib/active_record/connection_adapters/mysql_adapter.rb +0 -491
- data/lib/active_record/connection_adapters/postgresql/array_parser.rb +0 -93
- data/lib/active_record/connection_adapters/postgresql/oid/float.rb +0 -21
- data/lib/active_record/connection_adapters/postgresql/oid/infinity.rb +0 -13
- data/lib/active_record/connection_adapters/postgresql/oid/json.rb +0 -35
- data/lib/active_record/connection_adapters/postgresql/oid/time.rb +0 -11
- data/lib/active_record/railties/jdbcmysql_error.rb +0 -16
- data/lib/active_record/serializers/xml_serializer.rb +0 -193
- data/lib/active_record/type/big_integer.rb +0 -13
- data/lib/active_record/type/binary.rb +0 -50
- data/lib/active_record/type/boolean.rb +0 -30
- data/lib/active_record/type/decimal.rb +0 -40
- data/lib/active_record/type/decorator.rb +0 -14
- data/lib/active_record/type/float.rb +0 -19
- data/lib/active_record/type/integer.rb +0 -55
- data/lib/active_record/type/mutable.rb +0 -16
- data/lib/active_record/type/numeric.rb +0 -36
- data/lib/active_record/type/string.rb +0 -36
- data/lib/active_record/type/time_value.rb +0 -38
- data/lib/active_record/type/value.rb +0 -101
- /data/lib/rails/generators/active_record/model/templates/{module.rb → module.rb.tt} +0 -0
@@ -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,14 +13,13 @@ 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
20
|
class << self
|
21
|
-
def dump(connection=ActiveRecord::Base.connection, stream=STDOUT, config = ActiveRecord::Base)
|
22
|
-
|
21
|
+
def dump(connection = ActiveRecord::Base.connection, stream = STDOUT, config = ActiveRecord::Base)
|
22
|
+
connection.create_schema_dumper(generate_options(config)).dump(stream)
|
23
23
|
stream
|
24
24
|
end
|
25
25
|
|
@@ -44,18 +44,22 @@ module ActiveRecord
|
|
44
44
|
|
45
45
|
def initialize(connection, options = {})
|
46
46
|
@connection = connection
|
47
|
-
@
|
48
|
-
@version = Migrator::current_version rescue nil
|
47
|
+
@version = connection.migration_context.current_version rescue nil
|
49
48
|
@options = options
|
50
49
|
end
|
51
50
|
|
52
|
-
|
53
|
-
|
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
|
54
57
|
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
+
def define_params
|
59
|
+
@version ? "version: #{formatted_version}" : ""
|
60
|
+
end
|
58
61
|
|
62
|
+
def header(stream)
|
59
63
|
stream.puts <<HEADER
|
60
64
|
# This file is auto-generated from the current state of the database. Instead
|
61
65
|
# of editing this file, please use the migrations feature of Active Record to
|
@@ -78,16 +82,8 @@ HEADER
|
|
78
82
|
stream.puts "end"
|
79
83
|
end
|
80
84
|
|
85
|
+
# extensions are only supported by PostgreSQL
|
81
86
|
def extensions(stream)
|
82
|
-
return unless @connection.supports_extensions?
|
83
|
-
extensions = @connection.extensions
|
84
|
-
if extensions.any?
|
85
|
-
stream.puts " # These are extensions that must be enabled in order to support this database"
|
86
|
-
extensions.each do |extension|
|
87
|
-
stream.puts " enable_extension #{extension.inspect}"
|
88
|
-
end
|
89
|
-
stream.puts
|
90
|
-
end
|
91
87
|
end
|
92
88
|
|
93
89
|
def tables(stream)
|
@@ -114,62 +110,43 @@ HEADER
|
|
114
110
|
pk = @connection.primary_key(table)
|
115
111
|
|
116
112
|
tbl.print " create_table #{remove_prefix_and_suffix(table).inspect}"
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
tbl.print ",
|
125
|
-
tbl.print %Q(, default: "#{pkcol.default_function}") if pkcol.default_function
|
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)}"
|
126
121
|
end
|
122
|
+
when Array
|
123
|
+
tbl.print ", primary_key: #{pk.inspect}"
|
127
124
|
else
|
128
125
|
tbl.print ", id: false"
|
129
126
|
end
|
130
|
-
|
131
|
-
|
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|"
|
132
134
|
|
133
135
|
# then dump all non-primary key columns
|
134
|
-
|
136
|
+
columns.each do |column|
|
135
137
|
raise StandardError, "Unknown type '#{column.sql_type}' for column '#{column.name}'" unless @connection.valid_type?(column.type)
|
136
138
|
next if column.name == pk
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
# find all migration keys used in this table
|
141
|
-
keys = @connection.migration_keys
|
142
|
-
|
143
|
-
# figure out the lengths for each column based on above keys
|
144
|
-
lengths = keys.map { |key|
|
145
|
-
column_specs.map { |spec|
|
146
|
-
spec[key] ? spec[key].length + 2 : 0
|
147
|
-
}.max
|
148
|
-
}
|
149
|
-
|
150
|
-
# the string we're going to sprintf our values against, with standardized column widths
|
151
|
-
format_string = lengths.map{ |len| "%-#{len}s" }
|
152
|
-
|
153
|
-
# find the max length for the 'type' column, which is special
|
154
|
-
type_length = column_specs.map{ |column| column[:type].length }.max
|
155
|
-
|
156
|
-
# add column type definition to our format string
|
157
|
-
format_string.unshift " t.%-#{type_length}s "
|
158
|
-
|
159
|
-
format_string *= ''
|
160
|
-
|
161
|
-
column_specs.each do |colspec|
|
162
|
-
values = keys.zip(lengths).map{ |key, len| colspec.key?(key) ? colspec[key] + ", " : " " * len }
|
163
|
-
values.unshift colspec[:type]
|
164
|
-
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?
|
165
142
|
tbl.puts
|
166
143
|
end
|
167
144
|
|
145
|
+
indexes_in_create(table, tbl)
|
146
|
+
|
168
147
|
tbl.puts " end"
|
169
148
|
tbl.puts
|
170
149
|
|
171
|
-
indexes(table, tbl)
|
172
|
-
|
173
150
|
tbl.rewind
|
174
151
|
stream.print tbl.read
|
175
152
|
rescue => e
|
@@ -177,30 +154,14 @@ HEADER
|
|
177
154
|
stream.puts "# #{e.message}"
|
178
155
|
stream.puts
|
179
156
|
end
|
180
|
-
|
181
|
-
stream
|
182
157
|
end
|
183
158
|
|
159
|
+
# Keep it for indexing materialized views
|
184
160
|
def indexes(table, stream)
|
185
161
|
if (indexes = @connection.indexes(table)).any?
|
186
162
|
add_index_statements = indexes.map do |index|
|
187
|
-
|
188
|
-
|
189
|
-
index.columns.inspect,
|
190
|
-
"name: #{index.name.inspect}",
|
191
|
-
]
|
192
|
-
statement_parts << 'unique: true' if index.unique
|
193
|
-
|
194
|
-
index_lengths = (index.lengths || []).compact
|
195
|
-
statement_parts << "length: #{Hash[index.columns.zip(index.lengths)].inspect}" if index_lengths.any?
|
196
|
-
|
197
|
-
index_orders = index.orders || {}
|
198
|
-
statement_parts << "order: #{index.orders.inspect}" if index_orders.any?
|
199
|
-
statement_parts << "where: #{index.where.inspect}" if index.where
|
200
|
-
statement_parts << "using: #{index.using.inspect}" if index.using
|
201
|
-
statement_parts << "type: #{index.type.inspect}" if index.type
|
202
|
-
|
203
|
-
" #{statement_parts.join(', ')}"
|
163
|
+
table_name = remove_prefix_and_suffix(index.table).inspect
|
164
|
+
" add_index #{([table_name] + index_parts(index)).join(', ')}"
|
204
165
|
end
|
205
166
|
|
206
167
|
stream.puts add_index_statements.sort.join("\n")
|
@@ -208,6 +169,31 @@ HEADER
|
|
208
169
|
end
|
209
170
|
end
|
210
171
|
|
172
|
+
def indexes_in_create(table, stream)
|
173
|
+
if (indexes = @connection.indexes(table)).any?
|
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
|
+
|
211
197
|
def foreign_keys(table, stream)
|
212
198
|
if (foreign_keys = @connection.foreign_keys(table)).any?
|
213
199
|
add_foreign_key_statements = foreign_keys.map do |foreign_key|
|
@@ -238,12 +224,30 @@ HEADER
|
|
238
224
|
end
|
239
225
|
end
|
240
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
|
240
|
+
end
|
241
|
+
end
|
242
|
+
|
241
243
|
def remove_prefix_and_suffix(table)
|
242
|
-
|
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")
|
243
247
|
end
|
244
248
|
|
245
249
|
def ignored?(table_name)
|
246
|
-
[
|
250
|
+
[ActiveRecord::Base.schema_migrations_table_name, ActiveRecord::Base.internal_metadata_table_name, ignore_tables].flatten.any? do |ignored|
|
247
251
|
ignored === remove_prefix_and_suffix(table_name)
|
248
252
|
end
|
249
253
|
end
|
@@ -1,43 +1,39 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
require
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "active_record/scoping/default"
|
4
|
+
require "active_record/scoping/named"
|
4
5
|
|
5
6
|
module ActiveRecord
|
6
|
-
class
|
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:
|
7
12
|
class << self
|
8
13
|
def primary_key
|
9
|
-
|
14
|
+
"version"
|
10
15
|
end
|
11
16
|
|
12
17
|
def table_name
|
13
18
|
"#{table_name_prefix}#{ActiveRecord::Base.schema_migrations_table_name}#{table_name_suffix}"
|
14
19
|
end
|
15
20
|
|
16
|
-
def index_name
|
17
|
-
"#{table_name_prefix}unique_#{ActiveRecord::Base.schema_migrations_table_name}#{table_name_suffix}"
|
18
|
-
end
|
19
|
-
|
20
21
|
def table_exists?
|
21
22
|
connection.table_exists?(table_name)
|
22
23
|
end
|
23
24
|
|
24
|
-
def create_table
|
25
|
+
def create_table
|
25
26
|
unless table_exists?
|
26
|
-
version_options =
|
27
|
-
version_options[:limit] = limit if limit
|
27
|
+
version_options = connection.internal_string_options_for_primary_key
|
28
28
|
|
29
29
|
connection.create_table(table_name, id: false) do |t|
|
30
|
-
t.
|
30
|
+
t.string :version, version_options
|
31
31
|
end
|
32
|
-
connection.add_index table_name, :version, unique: true, name: index_name
|
33
32
|
end
|
34
33
|
end
|
35
34
|
|
36
35
|
def drop_table
|
37
|
-
|
38
|
-
connection.remove_index table_name, name: index_name
|
39
|
-
connection.drop_table(table_name)
|
40
|
-
end
|
36
|
+
connection.drop_table table_name, if_exists: true
|
41
37
|
end
|
42
38
|
|
43
39
|
def normalize_migration_number(number)
|
@@ -45,7 +41,11 @@ module ActiveRecord
|
|
45
41
|
end
|
46
42
|
|
47
43
|
def normalized_versions
|
48
|
-
|
44
|
+
all_versions.map { |v| normalize_migration_number v }
|
45
|
+
end
|
46
|
+
|
47
|
+
def all_versions
|
48
|
+
order(:version).pluck(:version)
|
49
49
|
end
|
50
50
|
end
|
51
51
|
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module ActiveRecord
|
2
4
|
module Scoping
|
3
5
|
module Default
|
@@ -5,9 +7,8 @@ module ActiveRecord
|
|
5
7
|
|
6
8
|
included do
|
7
9
|
# Stores the default scope for the class.
|
8
|
-
class_attribute :default_scopes, instance_writer: false, instance_predicate: false
|
9
|
-
|
10
|
-
self.default_scopes = []
|
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
|
11
12
|
end
|
12
13
|
|
13
14
|
module ClassMethods
|
@@ -15,7 +16,7 @@ module ActiveRecord
|
|
15
16
|
#
|
16
17
|
# class Post < ActiveRecord::Base
|
17
18
|
# def self.default_scope
|
18
|
-
# where
|
19
|
+
# where(published: true)
|
19
20
|
# end
|
20
21
|
# end
|
21
22
|
#
|
@@ -33,101 +34,118 @@ module ActiveRecord
|
|
33
34
|
block_given? ? relation.scoping { yield } : relation
|
34
35
|
end
|
35
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
|
+
|
36
42
|
def before_remove_const #:nodoc:
|
37
43
|
self.current_scope = nil
|
38
44
|
end
|
39
45
|
|
40
|
-
|
46
|
+
private
|
41
47
|
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
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
|
-
|
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]
|
92
101
|
end
|
93
102
|
|
94
|
-
|
95
|
-
|
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
|
96
109
|
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
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))
|
123
|
+
end
|
105
124
|
end
|
106
125
|
end
|
107
126
|
end
|
108
|
-
end
|
109
127
|
|
110
|
-
|
111
|
-
|
112
|
-
|
128
|
+
def ignore_default_scope?
|
129
|
+
ScopeRegistry.value_for(:ignore_default_scope, base_class)
|
130
|
+
end
|
113
131
|
|
114
|
-
|
115
|
-
|
116
|
-
|
132
|
+
def ignore_default_scope=(ignore)
|
133
|
+
ScopeRegistry.set_value_for(:ignore_default_scope, base_class, ignore)
|
134
|
+
end
|
135
|
+
|
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?
|
117
141
|
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
begin
|
125
|
-
self.ignore_default_scope = true
|
126
|
-
yield
|
127
|
-
ensure
|
128
|
-
self.ignore_default_scope = false
|
142
|
+
begin
|
143
|
+
self.ignore_default_scope = true
|
144
|
+
yield
|
145
|
+
ensure
|
146
|
+
self.ignore_default_scope = false
|
147
|
+
end
|
129
148
|
end
|
130
|
-
end
|
131
149
|
end
|
132
150
|
end
|
133
151
|
end
|