activerecord 3.2.19 → 5.0.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of activerecord might be problematic. Click here for more details.
- checksums.yaml +7 -0
- data/CHANGELOG.md +1715 -604
- data/MIT-LICENSE +2 -2
- data/README.rdoc +40 -45
- data/examples/performance.rb +33 -22
- data/examples/simple.rb +3 -4
- data/lib/active_record/aggregations.rb +76 -51
- data/lib/active_record/association_relation.rb +35 -0
- data/lib/active_record/associations/alias_tracker.rb +54 -40
- data/lib/active_record/associations/association.rb +76 -56
- data/lib/active_record/associations/association_scope.rb +125 -93
- data/lib/active_record/associations/belongs_to_association.rb +57 -28
- data/lib/active_record/associations/belongs_to_polymorphic_association.rb +7 -2
- data/lib/active_record/associations/builder/association.rb +120 -32
- data/lib/active_record/associations/builder/belongs_to.rb +115 -62
- data/lib/active_record/associations/builder/collection_association.rb +61 -53
- data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +117 -43
- data/lib/active_record/associations/builder/has_many.rb +9 -65
- data/lib/active_record/associations/builder/has_one.rb +18 -52
- data/lib/active_record/associations/builder/singular_association.rb +18 -19
- data/lib/active_record/associations/collection_association.rb +268 -186
- data/lib/active_record/associations/collection_proxy.rb +1003 -63
- data/lib/active_record/associations/foreign_association.rb +11 -0
- data/lib/active_record/associations/has_many_association.rb +81 -41
- data/lib/active_record/associations/has_many_through_association.rb +76 -55
- data/lib/active_record/associations/has_one_association.rb +51 -21
- data/lib/active_record/associations/has_one_through_association.rb +1 -1
- data/lib/active_record/associations/join_dependency/join_association.rb +83 -108
- data/lib/active_record/associations/join_dependency/join_base.rb +7 -9
- data/lib/active_record/associations/join_dependency/join_part.rb +30 -37
- data/lib/active_record/associations/join_dependency.rb +239 -155
- data/lib/active_record/associations/preloader/association.rb +97 -62
- data/lib/active_record/associations/preloader/collection_association.rb +2 -8
- data/lib/active_record/associations/preloader/has_many_through.rb +7 -3
- data/lib/active_record/associations/preloader/has_one.rb +0 -8
- data/lib/active_record/associations/preloader/singular_association.rb +3 -3
- data/lib/active_record/associations/preloader/through_association.rb +75 -33
- data/lib/active_record/associations/preloader.rb +111 -79
- data/lib/active_record/associations/singular_association.rb +35 -13
- data/lib/active_record/associations/through_association.rb +41 -19
- data/lib/active_record/associations.rb +727 -501
- data/lib/active_record/attribute/user_provided_default.rb +28 -0
- data/lib/active_record/attribute.rb +213 -0
- data/lib/active_record/attribute_assignment.rb +32 -162
- data/lib/active_record/attribute_decorators.rb +67 -0
- data/lib/active_record/attribute_methods/before_type_cast.rb +52 -7
- data/lib/active_record/attribute_methods/dirty.rb +101 -61
- data/lib/active_record/attribute_methods/primary_key.rb +50 -36
- data/lib/active_record/attribute_methods/query.rb +7 -6
- data/lib/active_record/attribute_methods/read.rb +56 -117
- data/lib/active_record/attribute_methods/serialization.rb +43 -96
- data/lib/active_record/attribute_methods/time_zone_conversion.rb +93 -42
- data/lib/active_record/attribute_methods/write.rb +34 -45
- data/lib/active_record/attribute_methods.rb +333 -144
- data/lib/active_record/attribute_mutation_tracker.rb +70 -0
- data/lib/active_record/attribute_set/builder.rb +108 -0
- data/lib/active_record/attribute_set.rb +108 -0
- data/lib/active_record/attributes.rb +265 -0
- data/lib/active_record/autosave_association.rb +285 -223
- data/lib/active_record/base.rb +95 -490
- data/lib/active_record/callbacks.rb +95 -61
- data/lib/active_record/coders/json.rb +13 -0
- data/lib/active_record/coders/yaml_column.rb +28 -19
- data/lib/active_record/collection_cache_key.rb +40 -0
- data/lib/active_record/connection_adapters/abstract/connection_pool.rb +724 -277
- data/lib/active_record/connection_adapters/abstract/database_limits.rb +9 -0
- data/lib/active_record/connection_adapters/abstract/database_statements.rb +199 -192
- data/lib/active_record/connection_adapters/abstract/query_cache.rb +31 -26
- data/lib/active_record/connection_adapters/abstract/quoting.rb +140 -57
- data/lib/active_record/connection_adapters/abstract/savepoints.rb +21 -0
- data/lib/active_record/connection_adapters/abstract/schema_creation.rb +147 -0
- data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +419 -276
- data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +105 -0
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +963 -276
- data/lib/active_record/connection_adapters/abstract/transaction.rb +232 -0
- data/lib/active_record/connection_adapters/abstract_adapter.rb +397 -106
- data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +643 -342
- data/lib/active_record/connection_adapters/column.rb +30 -259
- data/lib/active_record/connection_adapters/connection_specification.rb +263 -0
- data/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb +22 -0
- data/lib/active_record/connection_adapters/mysql/column.rb +50 -0
- data/lib/active_record/connection_adapters/mysql/database_statements.rb +125 -0
- data/lib/active_record/connection_adapters/mysql/explain_pretty_printer.rb +70 -0
- data/lib/active_record/connection_adapters/mysql/quoting.rb +51 -0
- data/lib/active_record/connection_adapters/mysql/schema_creation.rb +67 -0
- data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +93 -0
- data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +54 -0
- data/lib/active_record/connection_adapters/mysql/type_metadata.rb +32 -0
- data/lib/active_record/connection_adapters/mysql2_adapter.rb +47 -196
- data/lib/active_record/connection_adapters/postgresql/column.rb +15 -0
- data/lib/active_record/connection_adapters/postgresql/database_statements.rb +170 -0
- data/lib/active_record/connection_adapters/postgresql/explain_pretty_printer.rb +42 -0
- data/lib/active_record/connection_adapters/postgresql/oid/array.rb +70 -0
- data/lib/active_record/connection_adapters/postgresql/oid/bit.rb +52 -0
- data/lib/active_record/connection_adapters/postgresql/oid/bit_varying.rb +13 -0
- data/lib/active_record/connection_adapters/postgresql/oid/bytea.rb +15 -0
- data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +48 -0
- data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +21 -0
- data/lib/active_record/connection_adapters/postgresql/oid/decimal.rb +13 -0
- data/lib/active_record/connection_adapters/postgresql/oid/enum.rb +19 -0
- data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +59 -0
- data/lib/active_record/connection_adapters/postgresql/oid/inet.rb +13 -0
- data/lib/active_record/connection_adapters/postgresql/oid/json.rb +10 -0
- data/lib/active_record/connection_adapters/postgresql/oid/jsonb.rb +23 -0
- data/lib/active_record/connection_adapters/postgresql/oid/money.rb +39 -0
- data/lib/active_record/connection_adapters/postgresql/oid/point.rb +43 -0
- data/lib/active_record/connection_adapters/postgresql/oid/rails_5_1_point.rb +50 -0
- data/lib/active_record/connection_adapters/postgresql/oid/range.rb +93 -0
- data/lib/active_record/connection_adapters/postgresql/oid/specialized_string.rb +15 -0
- data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +109 -0
- data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +21 -0
- data/lib/active_record/connection_adapters/postgresql/oid/vector.rb +26 -0
- data/lib/active_record/connection_adapters/postgresql/oid/xml.rb +28 -0
- data/lib/active_record/connection_adapters/postgresql/oid.rb +31 -0
- data/lib/active_record/connection_adapters/postgresql/quoting.rb +116 -0
- data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +49 -0
- data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +180 -0
- data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +47 -0
- data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +682 -0
- data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +35 -0
- data/lib/active_record/connection_adapters/postgresql/utils.rb +77 -0
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +558 -1039
- data/lib/active_record/connection_adapters/schema_cache.rb +74 -36
- data/lib/active_record/connection_adapters/sql_type_metadata.rb +32 -0
- data/lib/active_record/connection_adapters/sqlite3/explain_pretty_printer.rb +19 -0
- data/lib/active_record/connection_adapters/sqlite3/quoting.rb +48 -0
- data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +22 -0
- data/lib/active_record/connection_adapters/sqlite3_adapter.rb +538 -24
- data/lib/active_record/connection_adapters/statement_pool.rb +31 -12
- data/lib/active_record/connection_handling.rb +155 -0
- data/lib/active_record/core.rb +561 -0
- data/lib/active_record/counter_cache.rb +146 -105
- data/lib/active_record/dynamic_matchers.rb +101 -64
- data/lib/active_record/enum.rb +234 -0
- data/lib/active_record/errors.rb +153 -56
- data/lib/active_record/explain.rb +15 -63
- data/lib/active_record/explain_registry.rb +30 -0
- data/lib/active_record/explain_subscriber.rb +10 -6
- data/lib/active_record/fixture_set/file.rb +77 -0
- data/lib/active_record/fixtures.rb +355 -232
- data/lib/active_record/gem_version.rb +15 -0
- data/lib/active_record/inheritance.rb +144 -79
- data/lib/active_record/integration.rb +66 -13
- data/lib/active_record/internal_metadata.rb +56 -0
- data/lib/active_record/legacy_yaml_adapter.rb +46 -0
- data/lib/active_record/locale/en.yml +9 -1
- data/lib/active_record/locking/optimistic.rb +77 -56
- data/lib/active_record/locking/pessimistic.rb +6 -6
- data/lib/active_record/log_subscriber.rb +53 -28
- data/lib/active_record/migration/command_recorder.rb +166 -33
- data/lib/active_record/migration/compatibility.rb +126 -0
- data/lib/active_record/migration/join_table.rb +15 -0
- data/lib/active_record/migration.rb +792 -264
- data/lib/active_record/model_schema.rb +192 -130
- data/lib/active_record/nested_attributes.rb +238 -145
- data/lib/active_record/no_touching.rb +52 -0
- data/lib/active_record/null_relation.rb +89 -0
- data/lib/active_record/persistence.rb +357 -157
- data/lib/active_record/query_cache.rb +22 -43
- data/lib/active_record/querying.rb +34 -23
- data/lib/active_record/railtie.rb +88 -48
- data/lib/active_record/railties/console_sandbox.rb +3 -4
- data/lib/active_record/railties/controller_runtime.rb +5 -4
- data/lib/active_record/railties/databases.rake +170 -422
- data/lib/active_record/railties/jdbcmysql_error.rb +1 -1
- data/lib/active_record/readonly_attributes.rb +2 -5
- data/lib/active_record/reflection.rb +715 -189
- data/lib/active_record/relation/batches/batch_enumerator.rb +67 -0
- data/lib/active_record/relation/batches.rb +203 -50
- data/lib/active_record/relation/calculations.rb +203 -194
- data/lib/active_record/relation/delegation.rb +103 -25
- data/lib/active_record/relation/finder_methods.rb +457 -261
- data/lib/active_record/relation/from_clause.rb +32 -0
- data/lib/active_record/relation/merger.rb +167 -0
- data/lib/active_record/relation/predicate_builder/array_handler.rb +43 -0
- data/lib/active_record/relation/predicate_builder/association_query_handler.rb +88 -0
- data/lib/active_record/relation/predicate_builder/base_handler.rb +17 -0
- data/lib/active_record/relation/predicate_builder/basic_object_handler.rb +17 -0
- data/lib/active_record/relation/predicate_builder/class_handler.rb +27 -0
- data/lib/active_record/relation/predicate_builder/polymorphic_array_handler.rb +57 -0
- data/lib/active_record/relation/predicate_builder/range_handler.rb +33 -0
- data/lib/active_record/relation/predicate_builder/relation_handler.rb +13 -0
- data/lib/active_record/relation/predicate_builder.rb +153 -48
- data/lib/active_record/relation/query_attribute.rb +19 -0
- data/lib/active_record/relation/query_methods.rb +1019 -194
- data/lib/active_record/relation/record_fetch_warning.rb +49 -0
- data/lib/active_record/relation/spawn_methods.rb +46 -150
- data/lib/active_record/relation/where_clause.rb +174 -0
- data/lib/active_record/relation/where_clause_factory.rb +38 -0
- data/lib/active_record/relation.rb +450 -245
- data/lib/active_record/result.rb +104 -12
- data/lib/active_record/runtime_registry.rb +22 -0
- data/lib/active_record/sanitization.rb +120 -94
- data/lib/active_record/schema.rb +28 -18
- data/lib/active_record/schema_dumper.rb +141 -74
- data/lib/active_record/schema_migration.rb +50 -0
- data/lib/active_record/scoping/default.rb +64 -57
- data/lib/active_record/scoping/named.rb +93 -108
- data/lib/active_record/scoping.rb +73 -121
- data/lib/active_record/secure_token.rb +38 -0
- data/lib/active_record/serialization.rb +7 -5
- data/lib/active_record/statement_cache.rb +113 -0
- data/lib/active_record/store.rb +173 -15
- data/lib/active_record/suppressor.rb +58 -0
- data/lib/active_record/table_metadata.rb +68 -0
- data/lib/active_record/tasks/database_tasks.rb +313 -0
- data/lib/active_record/tasks/mysql_database_tasks.rb +151 -0
- data/lib/active_record/tasks/postgresql_database_tasks.rb +110 -0
- data/lib/active_record/tasks/sqlite_database_tasks.rb +59 -0
- data/lib/active_record/timestamp.rb +42 -24
- data/lib/active_record/touch_later.rb +58 -0
- data/lib/active_record/transactions.rb +233 -105
- data/lib/active_record/type/adapter_specific_registry.rb +130 -0
- data/lib/active_record/type/date.rb +7 -0
- data/lib/active_record/type/date_time.rb +7 -0
- data/lib/active_record/type/hash_lookup_type_map.rb +23 -0
- data/lib/active_record/type/internal/abstract_json.rb +29 -0
- data/lib/active_record/type/internal/timezone.rb +15 -0
- data/lib/active_record/type/serialized.rb +63 -0
- data/lib/active_record/type/time.rb +20 -0
- data/lib/active_record/type/type_map.rb +64 -0
- data/lib/active_record/type.rb +72 -0
- data/lib/active_record/type_caster/connection.rb +29 -0
- data/lib/active_record/type_caster/map.rb +19 -0
- data/lib/active_record/type_caster.rb +7 -0
- data/lib/active_record/validations/absence.rb +23 -0
- data/lib/active_record/validations/associated.rb +33 -18
- data/lib/active_record/validations/length.rb +24 -0
- data/lib/active_record/validations/presence.rb +66 -0
- data/lib/active_record/validations/uniqueness.rb +128 -68
- data/lib/active_record/validations.rb +48 -40
- data/lib/active_record/version.rb +5 -7
- data/lib/active_record.rb +71 -47
- data/lib/rails/generators/active_record/migration/migration_generator.rb +56 -8
- data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb +24 -0
- data/lib/rails/generators/active_record/migration/templates/migration.rb +28 -16
- data/lib/rails/generators/active_record/migration.rb +18 -8
- data/lib/rails/generators/active_record/model/model_generator.rb +38 -16
- data/lib/rails/generators/active_record/model/templates/application_record.rb +5 -0
- data/lib/rails/generators/active_record/model/templates/model.rb +7 -6
- data/lib/rails/generators/active_record/model/templates/module.rb +1 -1
- data/lib/rails/generators/active_record.rb +3 -11
- metadata +188 -134
- 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/has_and_belongs_to_many.rb +0 -60
- 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/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/model/templates/migration.rb +0 -15
- 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,4 @@
|
|
1
1
|
require 'stringio'
|
2
|
-
require 'active_support/core_ext/big_decimal'
|
3
2
|
|
4
3
|
module ActiveRecord
|
5
4
|
# = Active Record Schema Dumper
|
@@ -17,13 +16,24 @@ module ActiveRecord
|
|
17
16
|
cattr_accessor :ignore_tables
|
18
17
|
@@ignore_tables = []
|
19
18
|
|
20
|
-
|
21
|
-
|
22
|
-
|
19
|
+
class << self
|
20
|
+
def dump(connection=ActiveRecord::Base.connection, stream=STDOUT, config = ActiveRecord::Base)
|
21
|
+
new(connection, generate_options(config)).dump(stream)
|
22
|
+
stream
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
def generate_options(config)
|
27
|
+
{
|
28
|
+
table_name_prefix: config.table_name_prefix,
|
29
|
+
table_name_suffix: config.table_name_suffix
|
30
|
+
}
|
31
|
+
end
|
23
32
|
end
|
24
33
|
|
25
34
|
def dump(stream)
|
26
35
|
header(stream)
|
36
|
+
extensions(stream)
|
27
37
|
tables(stream)
|
28
38
|
trailer(stream)
|
29
39
|
stream
|
@@ -31,18 +41,14 @@ module ActiveRecord
|
|
31
41
|
|
32
42
|
private
|
33
43
|
|
34
|
-
def initialize(connection)
|
44
|
+
def initialize(connection, options = {})
|
35
45
|
@connection = connection
|
36
|
-
@types = @connection.native_database_types
|
37
46
|
@version = Migrator::current_version rescue nil
|
47
|
+
@options = options
|
38
48
|
end
|
39
49
|
|
40
50
|
def header(stream)
|
41
|
-
define_params = @version ? ":
|
42
|
-
|
43
|
-
if stream.respond_to?(:external_encoding) && stream.external_encoding
|
44
|
-
stream.puts "# encoding: #{stream.external_encoding.name}"
|
45
|
-
end
|
51
|
+
define_params = @version ? "version: #{@version}" : ""
|
46
52
|
|
47
53
|
stream.puts <<HEADER
|
48
54
|
# This file is auto-generated from the current state of the database. Instead
|
@@ -55,7 +61,7 @@ module ActiveRecord
|
|
55
61
|
# from scratch. The latter is a flawed and unsustainable approach (the more migrations
|
56
62
|
# you'll amass, the slower it'll run and the greater likelihood for issues).
|
57
63
|
#
|
58
|
-
# It's strongly recommended
|
64
|
+
# It's strongly recommended that you check this file into your version control system.
|
59
65
|
|
60
66
|
ActiveRecord::Schema.define(#{define_params}) do
|
61
67
|
|
@@ -66,17 +72,30 @@ HEADER
|
|
66
72
|
stream.puts "end"
|
67
73
|
end
|
68
74
|
|
75
|
+
def extensions(stream)
|
76
|
+
return unless @connection.supports_extensions?
|
77
|
+
extensions = @connection.extensions
|
78
|
+
if extensions.any?
|
79
|
+
stream.puts " # These are extensions that must be enabled in order to support this database"
|
80
|
+
extensions.each do |extension|
|
81
|
+
stream.puts " enable_extension #{extension.inspect}"
|
82
|
+
end
|
83
|
+
stream.puts
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
69
87
|
def tables(stream)
|
70
|
-
@connection.
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
88
|
+
sorted_tables = @connection.data_sources.sort - @connection.views
|
89
|
+
|
90
|
+
sorted_tables.each do |table_name|
|
91
|
+
table(table_name, stream) unless ignored?(table_name)
|
92
|
+
end
|
93
|
+
|
94
|
+
# dump foreign keys at the end to make sure all dependent tables exist.
|
95
|
+
if @connection.supports_foreign_keys?
|
96
|
+
sorted_tables.each do |tbl|
|
97
|
+
foreign_keys(tbl, stream) unless ignored?(tbl)
|
78
98
|
end
|
79
|
-
table(tbl, stream)
|
80
99
|
end
|
81
100
|
end
|
82
101
|
|
@@ -86,51 +105,57 @@ HEADER
|
|
86
105
|
tbl = StringIO.new
|
87
106
|
|
88
107
|
# first dump primary key column
|
89
|
-
if @connection.respond_to?(:
|
90
|
-
pk
|
91
|
-
|
108
|
+
if @connection.respond_to?(:primary_keys)
|
109
|
+
pk = @connection.primary_keys(table)
|
110
|
+
pk = pk.first unless pk.size > 1
|
111
|
+
else
|
92
112
|
pk = @connection.primary_key(table)
|
93
113
|
end
|
94
114
|
|
95
115
|
tbl.print " create_table #{remove_prefix_and_suffix(table).inspect}"
|
96
|
-
|
97
|
-
|
98
|
-
|
116
|
+
|
117
|
+
case pk
|
118
|
+
when String
|
119
|
+
tbl.print ", primary_key: #{pk.inspect}" unless pk == 'id'
|
120
|
+
pkcol = columns.detect { |c| c.name == pk }
|
121
|
+
pkcolspec = @connection.column_spec_for_primary_key(pkcol)
|
122
|
+
if pkcolspec.present?
|
123
|
+
pkcolspec.each do |key, value|
|
124
|
+
tbl.print ", #{key}: #{value}"
|
125
|
+
end
|
99
126
|
end
|
127
|
+
when Array
|
128
|
+
tbl.print ", primary_key: #{pk.inspect}"
|
100
129
|
else
|
101
|
-
tbl.print ", :
|
130
|
+
tbl.print ", id: false"
|
131
|
+
end
|
132
|
+
tbl.print ", force: :cascade"
|
133
|
+
|
134
|
+
table_options = @connection.table_options(table)
|
135
|
+
tbl.print ", options: #{table_options.inspect}" unless table_options.blank?
|
136
|
+
|
137
|
+
if comment = @connection.table_comment(table).presence
|
138
|
+
tbl.print ", comment: #{comment.inspect}"
|
102
139
|
end
|
103
|
-
|
140
|
+
|
104
141
|
tbl.puts " do |t|"
|
105
142
|
|
106
143
|
# then dump all non-primary key columns
|
107
144
|
column_specs = columns.map do |column|
|
108
|
-
raise StandardError, "Unknown type '#{column.sql_type}' for column '#{column.name}'"
|
145
|
+
raise StandardError, "Unknown type '#{column.sql_type}' for column '#{column.name}'" unless @connection.valid_type?(column.type)
|
109
146
|
next if column.name == pk
|
110
|
-
|
111
|
-
spec[:name] = column.name.inspect
|
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
|
147
|
+
@connection.column_spec(column)
|
127
148
|
end.compact
|
128
149
|
|
129
150
|
# find all migration keys used in this table
|
130
|
-
keys =
|
151
|
+
keys = @connection.migration_keys
|
131
152
|
|
132
153
|
# figure out the lengths for each column based on above keys
|
133
|
-
lengths = keys.map{ |key|
|
154
|
+
lengths = keys.map { |key|
|
155
|
+
column_specs.map { |spec|
|
156
|
+
spec[key] ? spec[key].length + 2 : 0
|
157
|
+
}.max
|
158
|
+
}
|
134
159
|
|
135
160
|
# the string we're going to sprintf our values against, with standardized column widths
|
136
161
|
format_string = lengths.map{ |len| "%-#{len}s" }
|
@@ -150,11 +175,11 @@ HEADER
|
|
150
175
|
tbl.puts
|
151
176
|
end
|
152
177
|
|
178
|
+
indexes_in_create(table, tbl)
|
179
|
+
|
153
180
|
tbl.puts " end"
|
154
181
|
tbl.puts
|
155
182
|
|
156
|
-
indexes(table, tbl)
|
157
|
-
|
158
183
|
tbl.rewind
|
159
184
|
stream.print tbl.read
|
160
185
|
rescue => e
|
@@ -166,43 +191,85 @@ HEADER
|
|
166
191
|
stream
|
167
192
|
end
|
168
193
|
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
194
|
+
# Keep it for indexing materialized views
|
195
|
+
def indexes(table, stream)
|
196
|
+
if (indexes = @connection.indexes(table)).any?
|
197
|
+
add_index_statements = indexes.map do |index|
|
198
|
+
table_name = remove_prefix_and_suffix(index.table).inspect
|
199
|
+
" add_index #{([table_name]+index_parts(index)).join(', ')}"
|
200
|
+
end
|
201
|
+
|
202
|
+
stream.puts add_index_statements.sort.join("\n")
|
203
|
+
stream.puts
|
177
204
|
end
|
178
205
|
end
|
179
206
|
|
180
|
-
def
|
207
|
+
def indexes_in_create(table, stream)
|
181
208
|
if (indexes = @connection.indexes(table)).any?
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
209
|
+
index_statements = indexes.map do |index|
|
210
|
+
" t.index #{index_parts(index).join(', ')}"
|
211
|
+
end
|
212
|
+
stream.puts index_statements.sort.join("\n")
|
213
|
+
end
|
214
|
+
end
|
215
|
+
|
216
|
+
def index_parts(index)
|
217
|
+
index_parts = [
|
218
|
+
index.columns.inspect,
|
219
|
+
"name: #{index.name.inspect}",
|
220
|
+
]
|
221
|
+
index_parts << 'unique: true' if index.unique
|
222
|
+
|
223
|
+
index_lengths = (index.lengths || []).compact
|
224
|
+
index_parts << "length: #{Hash[index.columns.zip(index.lengths)].inspect}" if index_lengths.any?
|
225
|
+
|
226
|
+
index_orders = index.orders || {}
|
227
|
+
index_parts << "order: #{index.orders.inspect}" if index_orders.any?
|
228
|
+
index_parts << "where: #{index.where.inspect}" if index.where
|
229
|
+
index_parts << "using: #{index.using.inspect}" if index.using
|
230
|
+
index_parts << "type: #{index.type.inspect}" if index.type
|
231
|
+
index_parts << "comment: #{index.comment.inspect}" if index.comment
|
232
|
+
index_parts
|
233
|
+
end
|
234
|
+
|
235
|
+
def foreign_keys(table, stream)
|
236
|
+
if (foreign_keys = @connection.foreign_keys(table)).any?
|
237
|
+
add_foreign_key_statements = foreign_keys.map do |foreign_key|
|
238
|
+
parts = [
|
239
|
+
"add_foreign_key #{remove_prefix_and_suffix(foreign_key.from_table).inspect}",
|
240
|
+
remove_prefix_and_suffix(foreign_key.to_table).inspect,
|
187
241
|
]
|
188
|
-
statement_parts << ':unique => true' if index.unique
|
189
242
|
|
190
|
-
|
191
|
-
|
243
|
+
if foreign_key.column != @connection.foreign_key_column_for(foreign_key.to_table)
|
244
|
+
parts << "column: #{foreign_key.column.inspect}"
|
245
|
+
end
|
246
|
+
|
247
|
+
if foreign_key.custom_primary_key?
|
248
|
+
parts << "primary_key: #{foreign_key.primary_key.inspect}"
|
249
|
+
end
|
250
|
+
|
251
|
+
if foreign_key.name !~ /^fk_rails_[0-9a-f]{10}$/
|
252
|
+
parts << "name: #{foreign_key.name.inspect}"
|
253
|
+
end
|
192
254
|
|
193
|
-
|
194
|
-
|
255
|
+
parts << "on_update: #{foreign_key.on_update.inspect}" if foreign_key.on_update
|
256
|
+
parts << "on_delete: #{foreign_key.on_delete.inspect}" if foreign_key.on_delete
|
195
257
|
|
196
|
-
|
258
|
+
" #{parts.join(', ')}"
|
197
259
|
end
|
198
260
|
|
199
|
-
stream.puts
|
200
|
-
stream.puts
|
261
|
+
stream.puts add_foreign_key_statements.sort.join("\n")
|
201
262
|
end
|
202
263
|
end
|
203
264
|
|
204
265
|
def remove_prefix_and_suffix(table)
|
205
|
-
table.gsub(/^(#{
|
266
|
+
table.gsub(/^(#{@options[:table_name_prefix]})(.+)(#{@options[:table_name_suffix]})$/, "\\2")
|
267
|
+
end
|
268
|
+
|
269
|
+
def ignored?(table_name)
|
270
|
+
[ActiveRecord::Base.schema_migrations_table_name, ActiveRecord::Base.internal_metadata_table_name, ignore_tables].flatten.any? do |ignored|
|
271
|
+
ignored === remove_prefix_and_suffix(table_name)
|
272
|
+
end
|
206
273
|
end
|
207
274
|
end
|
208
275
|
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
require 'active_record/scoping/default'
|
2
|
+
require 'active_record/scoping/named'
|
3
|
+
|
4
|
+
module ActiveRecord
|
5
|
+
# This class is used to create a table that keeps track of which migrations
|
6
|
+
# have been applied to a given database. When a migration is run, its schema
|
7
|
+
# number is inserted in to the `SchemaMigration.table_name` so it doesn't need
|
8
|
+
# to be executed the next time.
|
9
|
+
class SchemaMigration < ActiveRecord::Base # :nodoc:
|
10
|
+
class << self
|
11
|
+
def primary_key
|
12
|
+
"version"
|
13
|
+
end
|
14
|
+
|
15
|
+
def table_name
|
16
|
+
"#{table_name_prefix}#{ActiveRecord::Base.schema_migrations_table_name}#{table_name_suffix}"
|
17
|
+
end
|
18
|
+
|
19
|
+
def table_exists?
|
20
|
+
ActiveSupport::Deprecation.silence { connection.table_exists?(table_name) }
|
21
|
+
end
|
22
|
+
|
23
|
+
def create_table
|
24
|
+
unless table_exists?
|
25
|
+
version_options = connection.internal_string_options_for_primary_key
|
26
|
+
|
27
|
+
connection.create_table(table_name, id: false) do |t|
|
28
|
+
t.string :version, version_options
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def drop_table
|
34
|
+
connection.drop_table table_name, if_exists: true
|
35
|
+
end
|
36
|
+
|
37
|
+
def normalize_migration_number(number)
|
38
|
+
"%.3d" % number.to_i
|
39
|
+
end
|
40
|
+
|
41
|
+
def normalized_versions
|
42
|
+
pluck(:version).map { |v| normalize_migration_number v }
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def version
|
47
|
+
super.to_i
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -1,46 +1,45 @@
|
|
1
|
-
require 'active_support/concern'
|
2
|
-
|
3
1
|
module ActiveRecord
|
4
2
|
module Scoping
|
5
3
|
module Default
|
6
4
|
extend ActiveSupport::Concern
|
7
5
|
|
8
6
|
included do
|
9
|
-
# Stores the default scope for the class
|
10
|
-
class_attribute :default_scopes, :
|
7
|
+
# Stores the default scope for the class.
|
8
|
+
class_attribute :default_scopes, instance_writer: false, instance_predicate: false
|
9
|
+
class_attribute :default_scope_override, instance_writer: false, instance_predicate: false
|
10
|
+
|
11
11
|
self.default_scopes = []
|
12
|
+
self.default_scope_override = nil
|
12
13
|
end
|
13
14
|
|
14
15
|
module ClassMethods
|
15
|
-
# Returns a scope for the model without the
|
16
|
+
# Returns a scope for the model without the previously set scopes.
|
16
17
|
#
|
17
18
|
# class Post < ActiveRecord::Base
|
18
19
|
# def self.default_scope
|
19
|
-
# where
|
20
|
+
# where(published: true)
|
20
21
|
# end
|
21
22
|
# end
|
22
23
|
#
|
23
|
-
# Post.all
|
24
|
-
# Post.unscoped.all
|
24
|
+
# Post.all # Fires "SELECT * FROM posts WHERE published = true"
|
25
|
+
# Post.unscoped.all # Fires "SELECT * FROM posts"
|
26
|
+
# Post.where(published: false).unscoped.all # Fires "SELECT * FROM posts"
|
25
27
|
#
|
26
28
|
# This method also accepts a block. All queries inside the block will
|
27
|
-
# not use the
|
29
|
+
# not use the previously set scopes.
|
28
30
|
#
|
29
31
|
# Post.unscoped {
|
30
32
|
# Post.limit(10) # Fires "SELECT * FROM posts LIMIT 10"
|
31
33
|
# }
|
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:
|
34
|
+
def unscoped
|
41
35
|
block_given? ? relation.scoping { yield } : relation
|
42
36
|
end
|
43
37
|
|
38
|
+
# Are there attributes associated with this scope?
|
39
|
+
def scope_attributes? # :nodoc:
|
40
|
+
super || default_scopes.any? || respond_to?(:default_scope)
|
41
|
+
end
|
42
|
+
|
44
43
|
def before_remove_const #:nodoc:
|
45
44
|
self.current_scope = nil
|
46
45
|
end
|
@@ -51,81 +50,90 @@ module ActiveRecord
|
|
51
50
|
# the model.
|
52
51
|
#
|
53
52
|
# class Article < ActiveRecord::Base
|
54
|
-
# default_scope where(:
|
53
|
+
# default_scope { where(published: true) }
|
55
54
|
# end
|
56
55
|
#
|
57
56
|
# Article.all # => SELECT * FROM articles WHERE published = true
|
58
57
|
#
|
59
|
-
# The
|
60
|
-
# applied while updating a record.
|
58
|
+
# The #default_scope is also applied while creating/building a record.
|
59
|
+
# It is not applied while updating a record.
|
61
60
|
#
|
62
61
|
# Article.new.published # => true
|
63
62
|
# Article.create.published # => true
|
64
63
|
#
|
65
|
-
# You can also
|
66
|
-
#
|
67
|
-
#
|
68
|
-
# default_scope { where(:published_at => Time.now - 1.week) }
|
69
|
-
# end
|
64
|
+
# (You can also pass any object which responds to +call+ to the
|
65
|
+
# +default_scope+ macro, and it will be called when building the
|
66
|
+
# default scope.)
|
70
67
|
#
|
71
|
-
#
|
72
|
-
#
|
73
|
-
#
|
74
|
-
# If you use multiple <tt>default_scope</tt> declarations in your model then they will
|
75
|
-
# be merged together:
|
68
|
+
# If you use multiple #default_scope declarations in your model then
|
69
|
+
# they will be merged together:
|
76
70
|
#
|
77
71
|
# class Article < ActiveRecord::Base
|
78
|
-
# default_scope where(:
|
79
|
-
# default_scope where(:
|
72
|
+
# default_scope { where(published: true) }
|
73
|
+
# default_scope { where(rating: 'G') }
|
80
74
|
# end
|
81
75
|
#
|
82
76
|
# Article.all # => SELECT * FROM articles WHERE published = true AND rating = 'G'
|
83
77
|
#
|
84
|
-
# This is also the case with inheritance and module includes where the
|
85
|
-
# defines a
|
78
|
+
# This is also the case with inheritance and module includes where the
|
79
|
+
# parent or module defines a #default_scope and the child or including
|
80
|
+
# class defines a second one.
|
86
81
|
#
|
87
|
-
# If you need to do more complex things with a default scope, you can
|
88
|
-
# define it as a class method:
|
82
|
+
# If you need to do more complex things with a default scope, you can
|
83
|
+
# alternatively define it as a class method:
|
89
84
|
#
|
90
85
|
# class Article < ActiveRecord::Base
|
91
86
|
# def self.default_scope
|
92
87
|
# # Should return a scope, you can call 'super' here etc.
|
93
88
|
# end
|
94
89
|
# end
|
95
|
-
def default_scope(scope =
|
90
|
+
def default_scope(scope = nil)
|
96
91
|
scope = Proc.new if block_given?
|
97
|
-
|
92
|
+
|
93
|
+
if scope.is_a?(Relation) || !scope.respond_to?(:call)
|
94
|
+
raise ArgumentError,
|
95
|
+
"Support for calling #default_scope without a block is removed. For example instead " \
|
96
|
+
"of `default_scope where(color: 'red')`, please use " \
|
97
|
+
"`default_scope { where(color: 'red') }`. (Alternatively you can just redefine " \
|
98
|
+
"self.default_scope.)"
|
99
|
+
end
|
100
|
+
|
101
|
+
self.default_scopes += [scope]
|
98
102
|
end
|
99
103
|
|
100
|
-
def build_default_scope
|
101
|
-
if
|
104
|
+
def build_default_scope(base_rel = nil) # :nodoc:
|
105
|
+
return if abstract_class?
|
106
|
+
|
107
|
+
if self.default_scope_override.nil?
|
108
|
+
self.default_scope_override = !Base.is_a?(method(:default_scope).owner)
|
109
|
+
end
|
110
|
+
|
111
|
+
if self.default_scope_override
|
112
|
+
# The user has defined their own default scope method, so call that
|
102
113
|
evaluate_default_scope { default_scope }
|
103
114
|
elsif default_scopes.any?
|
115
|
+
base_rel ||= relation
|
104
116
|
evaluate_default_scope do
|
105
|
-
default_scopes.inject(
|
106
|
-
|
107
|
-
|
108
|
-
elsif !scope.is_a?(Relation) && scope.respond_to?(:call)
|
109
|
-
default_scope.merge(scope.call)
|
110
|
-
else
|
111
|
-
default_scope.merge(scope)
|
112
|
-
end
|
117
|
+
default_scopes.inject(base_rel) do |default_scope, scope|
|
118
|
+
scope = scope.respond_to?(:to_proc) ? scope : scope.method(:call)
|
119
|
+
default_scope.merge(base_rel.instance_exec(&scope))
|
113
120
|
end
|
114
121
|
end
|
115
122
|
end
|
116
123
|
end
|
117
124
|
|
118
|
-
def ignore_default_scope?
|
119
|
-
|
125
|
+
def ignore_default_scope? # :nodoc:
|
126
|
+
ScopeRegistry.value_for(:ignore_default_scope, base_class)
|
120
127
|
end
|
121
128
|
|
122
|
-
def ignore_default_scope=(ignore)
|
123
|
-
|
129
|
+
def ignore_default_scope=(ignore) # :nodoc:
|
130
|
+
ScopeRegistry.set_value_for(:ignore_default_scope, base_class, ignore)
|
124
131
|
end
|
125
132
|
|
126
|
-
# The ignore_default_scope flag is used to prevent an infinite recursion
|
127
|
-
# a default scope references a scope which has a default
|
128
|
-
|
133
|
+
# The ignore_default_scope flag is used to prevent an infinite recursion
|
134
|
+
# situation where a default scope references a scope which has a default
|
135
|
+
# scope which references a scope...
|
136
|
+
def evaluate_default_scope # :nodoc:
|
129
137
|
return if ignore_default_scope?
|
130
138
|
|
131
139
|
begin
|
@@ -135,7 +143,6 @@ module ActiveRecord
|
|
135
143
|
self.ignore_default_scope = false
|
136
144
|
end
|
137
145
|
end
|
138
|
-
|
139
146
|
end
|
140
147
|
end
|
141
148
|
end
|