activerecord 5.2.8.1 → 6.1.6.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 +4 -4
- data/CHANGELOG.md +1255 -596
- data/MIT-LICENSE +3 -1
- data/README.rdoc +7 -5
- data/examples/performance.rb +1 -1
- data/lib/active_record/aggregations.rb +9 -8
- data/lib/active_record/association_relation.rb +30 -10
- data/lib/active_record/associations/alias_tracker.rb +19 -16
- data/lib/active_record/associations/association.rb +100 -41
- data/lib/active_record/associations/association_scope.rb +23 -21
- data/lib/active_record/associations/belongs_to_association.rb +55 -48
- data/lib/active_record/associations/belongs_to_polymorphic_association.rb +7 -6
- data/lib/active_record/associations/builder/association.rb +45 -22
- data/lib/active_record/associations/builder/belongs_to.rb +29 -59
- data/lib/active_record/associations/builder/collection_association.rb +8 -17
- data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +17 -41
- data/lib/active_record/associations/builder/has_many.rb +8 -2
- data/lib/active_record/associations/builder/has_one.rb +33 -2
- data/lib/active_record/associations/builder/singular_association.rb +3 -1
- data/lib/active_record/associations/collection_association.rb +44 -34
- data/lib/active_record/associations/collection_proxy.rb +25 -21
- data/lib/active_record/associations/foreign_association.rb +20 -0
- data/lib/active_record/associations/has_many_association.rb +26 -13
- data/lib/active_record/associations/has_many_through_association.rb +24 -18
- data/lib/active_record/associations/has_one_association.rb +43 -31
- data/lib/active_record/associations/has_one_through_association.rb +5 -5
- data/lib/active_record/associations/join_dependency/join_association.rb +44 -22
- data/lib/active_record/associations/join_dependency/join_part.rb +5 -5
- data/lib/active_record/associations/join_dependency.rb +91 -60
- data/lib/active_record/associations/preloader/association.rb +69 -43
- data/lib/active_record/associations/preloader/through_association.rb +49 -40
- data/lib/active_record/associations/preloader.rb +47 -34
- data/lib/active_record/associations/singular_association.rb +3 -17
- data/lib/active_record/associations/through_association.rb +1 -1
- data/lib/active_record/associations.rb +137 -25
- data/lib/active_record/attribute_assignment.rb +17 -19
- data/lib/active_record/attribute_methods/before_type_cast.rb +13 -7
- data/lib/active_record/attribute_methods/dirty.rb +101 -40
- data/lib/active_record/attribute_methods/primary_key.rb +20 -25
- data/lib/active_record/attribute_methods/query.rb +4 -8
- data/lib/active_record/attribute_methods/read.rb +14 -56
- data/lib/active_record/attribute_methods/serialization.rb +12 -7
- data/lib/active_record/attribute_methods/time_zone_conversion.rb +12 -15
- data/lib/active_record/attribute_methods/write.rb +18 -34
- data/lib/active_record/attribute_methods.rb +81 -143
- data/lib/active_record/attributes.rb +46 -9
- data/lib/active_record/autosave_association.rb +57 -42
- data/lib/active_record/base.rb +4 -17
- data/lib/active_record/callbacks.rb +158 -43
- data/lib/active_record/coders/yaml_column.rb +1 -2
- data/lib/active_record/connection_adapters/abstract/connection_pool.rb +272 -130
- data/lib/active_record/connection_adapters/abstract/database_limits.rb +7 -36
- data/lib/active_record/connection_adapters/abstract/database_statements.rb +167 -146
- data/lib/active_record/connection_adapters/abstract/query_cache.rb +18 -14
- data/lib/active_record/connection_adapters/abstract/quoting.rb +98 -47
- data/lib/active_record/connection_adapters/abstract/savepoints.rb +3 -3
- data/lib/active_record/connection_adapters/abstract/schema_creation.rb +153 -110
- data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +211 -90
- data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +2 -4
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +385 -144
- data/lib/active_record/connection_adapters/abstract/transaction.rb +167 -69
- data/lib/active_record/connection_adapters/abstract_adapter.rb +229 -99
- data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +243 -275
- data/lib/active_record/connection_adapters/column.rb +30 -12
- data/lib/active_record/connection_adapters/deduplicable.rb +29 -0
- data/lib/active_record/connection_adapters/legacy_pool_manager.rb +35 -0
- data/lib/active_record/connection_adapters/mysql/column.rb +1 -1
- data/lib/active_record/connection_adapters/mysql/database_statements.rb +88 -32
- data/lib/active_record/connection_adapters/mysql/explain_pretty_printer.rb +1 -2
- data/lib/active_record/connection_adapters/mysql/quoting.rb +59 -7
- data/lib/active_record/connection_adapters/mysql/schema_creation.rb +34 -10
- data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +48 -32
- data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +18 -7
- data/lib/active_record/connection_adapters/mysql/schema_statements.rb +142 -19
- data/lib/active_record/connection_adapters/mysql/type_metadata.rb +14 -9
- data/lib/active_record/connection_adapters/mysql2_adapter.rb +53 -18
- data/lib/active_record/connection_adapters/pool_config.rb +73 -0
- data/lib/active_record/connection_adapters/pool_manager.rb +47 -0
- data/lib/active_record/connection_adapters/postgresql/column.rb +37 -28
- data/lib/active_record/connection_adapters/postgresql/database_statements.rb +40 -54
- data/lib/active_record/connection_adapters/postgresql/oid/array.rb +1 -2
- data/lib/active_record/connection_adapters/postgresql/oid/bit.rb +1 -4
- data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +3 -5
- data/lib/active_record/connection_adapters/postgresql/oid/date.rb +2 -2
- data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +10 -2
- data/lib/active_record/connection_adapters/postgresql/oid/enum.rb +0 -1
- data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +1 -2
- data/lib/active_record/connection_adapters/postgresql/oid/interval.rb +49 -0
- data/lib/active_record/connection_adapters/postgresql/oid/legacy_point.rb +3 -4
- data/lib/active_record/connection_adapters/postgresql/oid/macaddr.rb +25 -0
- data/lib/active_record/connection_adapters/postgresql/oid/oid.rb +1 -1
- data/lib/active_record/connection_adapters/postgresql/oid/point.rb +3 -4
- data/lib/active_record/connection_adapters/postgresql/oid/range.rb +25 -7
- data/lib/active_record/connection_adapters/postgresql/oid/specialized_string.rb +1 -1
- data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +9 -7
- data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +15 -3
- data/lib/active_record/connection_adapters/postgresql/oid.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/quoting.rb +47 -10
- data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +2 -2
- data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +19 -4
- data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +107 -91
- data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +0 -1
- data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +120 -100
- data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +31 -26
- data/lib/active_record/connection_adapters/postgresql/utils.rb +0 -1
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +224 -120
- data/lib/active_record/connection_adapters/schema_cache.rb +159 -21
- data/lib/active_record/connection_adapters/sql_type_metadata.rb +17 -6
- data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +146 -0
- data/lib/active_record/connection_adapters/sqlite3/quoting.rb +42 -7
- data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +5 -1
- data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +77 -13
- data/lib/active_record/connection_adapters/sqlite3_adapter.rb +174 -186
- data/lib/active_record/connection_adapters/statement_pool.rb +0 -1
- data/lib/active_record/connection_adapters.rb +52 -0
- data/lib/active_record/connection_handling.rb +293 -33
- data/lib/active_record/core.rb +333 -98
- data/lib/active_record/counter_cache.rb +8 -30
- data/lib/active_record/database_configurations/connection_url_resolver.rb +99 -0
- data/lib/active_record/database_configurations/database_config.rb +80 -0
- data/lib/active_record/database_configurations/hash_config.rb +96 -0
- data/lib/active_record/database_configurations/url_config.rb +53 -0
- data/lib/active_record/database_configurations.rb +273 -0
- data/lib/active_record/delegated_type.rb +209 -0
- data/lib/active_record/destroy_association_async_job.rb +36 -0
- data/lib/active_record/dynamic_matchers.rb +3 -4
- data/lib/active_record/enum.rb +108 -36
- data/lib/active_record/errors.rb +62 -19
- data/lib/active_record/explain.rb +10 -6
- data/lib/active_record/explain_subscriber.rb +1 -1
- data/lib/active_record/fixture_set/file.rb +10 -17
- data/lib/active_record/fixture_set/model_metadata.rb +32 -0
- data/lib/active_record/fixture_set/render_context.rb +17 -0
- data/lib/active_record/fixture_set/table_row.rb +152 -0
- data/lib/active_record/fixture_set/table_rows.rb +46 -0
- data/lib/active_record/fixtures.rb +200 -481
- data/lib/active_record/gem_version.rb +3 -3
- data/lib/active_record/inheritance.rb +53 -24
- data/lib/active_record/insert_all.rb +212 -0
- data/lib/active_record/integration.rb +67 -17
- data/lib/active_record/internal_metadata.rb +28 -9
- data/lib/active_record/legacy_yaml_adapter.rb +7 -3
- data/lib/active_record/locking/optimistic.rb +37 -23
- data/lib/active_record/locking/pessimistic.rb +9 -5
- data/lib/active_record/log_subscriber.rb +35 -35
- data/lib/active_record/middleware/database_selector/resolver/session.rb +48 -0
- data/lib/active_record/middleware/database_selector/resolver.rb +92 -0
- data/lib/active_record/middleware/database_selector.rb +77 -0
- data/lib/active_record/migration/command_recorder.rb +96 -44
- data/lib/active_record/migration/compatibility.rb +145 -64
- data/lib/active_record/migration/join_table.rb +0 -1
- data/lib/active_record/migration.rb +206 -157
- data/lib/active_record/model_schema.rb +148 -22
- data/lib/active_record/nested_attributes.rb +4 -7
- data/lib/active_record/no_touching.rb +8 -1
- data/lib/active_record/null_relation.rb +0 -1
- data/lib/active_record/persistence.rb +267 -59
- data/lib/active_record/query_cache.rb +21 -4
- data/lib/active_record/querying.rb +40 -23
- data/lib/active_record/railtie.rb +116 -59
- data/lib/active_record/railties/console_sandbox.rb +2 -4
- data/lib/active_record/railties/controller_runtime.rb +30 -35
- data/lib/active_record/railties/databases.rake +411 -80
- data/lib/active_record/readonly_attributes.rb +4 -0
- data/lib/active_record/reflection.rb +109 -93
- data/lib/active_record/relation/batches/batch_enumerator.rb +25 -9
- data/lib/active_record/relation/batches.rb +44 -35
- data/lib/active_record/relation/calculations.rb +157 -90
- data/lib/active_record/relation/delegation.rb +35 -50
- data/lib/active_record/relation/finder_methods.rb +64 -39
- data/lib/active_record/relation/from_clause.rb +5 -1
- data/lib/active_record/relation/merger.rb +32 -40
- data/lib/active_record/relation/predicate_builder/array_handler.rb +13 -13
- data/lib/active_record/relation/predicate_builder/association_query_value.rb +5 -9
- data/lib/active_record/relation/predicate_builder/basic_object_handler.rb +1 -2
- data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +11 -10
- data/lib/active_record/relation/predicate_builder/range_handler.rb +3 -23
- data/lib/active_record/relation/predicate_builder/relation_handler.rb +1 -1
- data/lib/active_record/relation/predicate_builder.rb +62 -45
- data/lib/active_record/relation/query_attribute.rb +13 -8
- data/lib/active_record/relation/query_methods.rb +476 -187
- data/lib/active_record/relation/record_fetch_warning.rb +3 -3
- data/lib/active_record/relation/spawn_methods.rb +9 -9
- data/lib/active_record/relation/where_clause.rb +115 -62
- data/lib/active_record/relation.rb +379 -115
- data/lib/active_record/result.rb +64 -38
- data/lib/active_record/runtime_registry.rb +2 -2
- data/lib/active_record/sanitization.rb +22 -41
- data/lib/active_record/schema.rb +2 -11
- data/lib/active_record/schema_dumper.rb +54 -9
- data/lib/active_record/schema_migration.rb +7 -9
- data/lib/active_record/scoping/default.rb +4 -8
- data/lib/active_record/scoping/named.rb +17 -24
- data/lib/active_record/scoping.rb +8 -9
- data/lib/active_record/secure_token.rb +16 -8
- data/lib/active_record/serialization.rb +5 -3
- data/lib/active_record/signed_id.rb +116 -0
- data/lib/active_record/statement_cache.rb +49 -6
- data/lib/active_record/store.rb +88 -9
- data/lib/active_record/suppressor.rb +2 -2
- data/lib/active_record/table_metadata.rb +42 -43
- data/lib/active_record/tasks/database_tasks.rb +277 -81
- data/lib/active_record/tasks/mysql_database_tasks.rb +37 -39
- data/lib/active_record/tasks/postgresql_database_tasks.rb +27 -32
- data/lib/active_record/tasks/sqlite_database_tasks.rb +14 -17
- data/lib/active_record/test_databases.rb +24 -0
- data/lib/active_record/test_fixtures.rb +287 -0
- data/lib/active_record/timestamp.rb +43 -32
- data/lib/active_record/touch_later.rb +23 -22
- data/lib/active_record/transactions.rb +62 -118
- data/lib/active_record/translation.rb +1 -1
- data/lib/active_record/type/adapter_specific_registry.rb +3 -13
- data/lib/active_record/type/hash_lookup_type_map.rb +0 -1
- data/lib/active_record/type/serialized.rb +6 -3
- data/lib/active_record/type/time.rb +10 -0
- data/lib/active_record/type/type_map.rb +0 -1
- data/lib/active_record/type/unsigned_integer.rb +0 -1
- data/lib/active_record/type.rb +10 -5
- data/lib/active_record/type_caster/connection.rb +15 -15
- data/lib/active_record/type_caster/map.rb +8 -8
- data/lib/active_record/validations/associated.rb +1 -2
- data/lib/active_record/validations/numericality.rb +35 -0
- data/lib/active_record/validations/uniqueness.rb +38 -30
- data/lib/active_record/validations.rb +4 -3
- data/lib/active_record.rb +13 -12
- data/lib/arel/alias_predication.rb +9 -0
- data/lib/arel/attributes/attribute.rb +41 -0
- data/lib/arel/collectors/bind.rb +29 -0
- data/lib/arel/collectors/composite.rb +39 -0
- data/lib/arel/collectors/plain_string.rb +20 -0
- data/lib/arel/collectors/sql_string.rb +27 -0
- data/lib/arel/collectors/substitute_binds.rb +35 -0
- data/lib/arel/crud.rb +42 -0
- data/lib/arel/delete_manager.rb +18 -0
- data/lib/arel/errors.rb +9 -0
- data/lib/arel/expressions.rb +29 -0
- data/lib/arel/factory_methods.rb +49 -0
- data/lib/arel/insert_manager.rb +49 -0
- data/lib/arel/math.rb +45 -0
- data/lib/arel/nodes/and.rb +32 -0
- data/lib/arel/nodes/ascending.rb +23 -0
- data/lib/arel/nodes/binary.rb +126 -0
- data/lib/arel/nodes/bind_param.rb +44 -0
- data/lib/arel/nodes/case.rb +55 -0
- data/lib/arel/nodes/casted.rb +62 -0
- data/lib/arel/nodes/comment.rb +29 -0
- data/lib/arel/nodes/count.rb +12 -0
- data/lib/arel/nodes/delete_statement.rb +45 -0
- data/lib/arel/nodes/descending.rb +23 -0
- data/lib/arel/nodes/equality.rb +15 -0
- data/lib/arel/nodes/extract.rb +24 -0
- data/lib/arel/nodes/false.rb +16 -0
- data/lib/arel/nodes/full_outer_join.rb +8 -0
- data/lib/arel/nodes/function.rb +44 -0
- data/lib/arel/nodes/grouping.rb +11 -0
- data/lib/arel/nodes/homogeneous_in.rb +76 -0
- data/lib/arel/nodes/in.rb +15 -0
- data/lib/arel/nodes/infix_operation.rb +92 -0
- data/lib/arel/nodes/inner_join.rb +8 -0
- data/lib/arel/nodes/insert_statement.rb +37 -0
- data/lib/arel/nodes/join_source.rb +20 -0
- data/lib/arel/nodes/matches.rb +18 -0
- data/lib/arel/nodes/named_function.rb +23 -0
- data/lib/arel/nodes/node.rb +51 -0
- data/lib/arel/nodes/node_expression.rb +13 -0
- data/lib/arel/nodes/ordering.rb +27 -0
- data/lib/arel/nodes/outer_join.rb +8 -0
- data/lib/arel/nodes/over.rb +15 -0
- data/lib/arel/nodes/regexp.rb +16 -0
- data/lib/arel/nodes/right_outer_join.rb +8 -0
- data/lib/arel/nodes/select_core.rb +67 -0
- data/lib/arel/nodes/select_statement.rb +41 -0
- data/lib/arel/nodes/sql_literal.rb +19 -0
- data/lib/arel/nodes/string_join.rb +11 -0
- data/lib/arel/nodes/table_alias.rb +31 -0
- data/lib/arel/nodes/terminal.rb +16 -0
- data/lib/arel/nodes/true.rb +16 -0
- data/lib/arel/nodes/unary.rb +44 -0
- data/lib/arel/nodes/unary_operation.rb +20 -0
- data/lib/arel/nodes/unqualified_column.rb +22 -0
- data/lib/arel/nodes/update_statement.rb +41 -0
- data/lib/arel/nodes/values_list.rb +9 -0
- data/lib/arel/nodes/window.rb +126 -0
- data/lib/arel/nodes/with.rb +11 -0
- data/lib/arel/nodes.rb +70 -0
- data/lib/arel/order_predications.rb +13 -0
- data/lib/arel/predications.rb +250 -0
- data/lib/arel/select_manager.rb +270 -0
- data/lib/arel/table.rb +118 -0
- data/lib/arel/tree_manager.rb +72 -0
- data/lib/arel/update_manager.rb +34 -0
- data/lib/arel/visitors/dot.rb +308 -0
- data/lib/arel/visitors/mysql.rb +93 -0
- data/lib/arel/visitors/postgresql.rb +120 -0
- data/lib/arel/visitors/sqlite.rb +38 -0
- data/lib/arel/visitors/to_sql.rb +899 -0
- data/lib/arel/visitors/visitor.rb +45 -0
- data/lib/arel/visitors.rb +13 -0
- data/lib/arel/window_predications.rb +9 -0
- data/lib/arel.rb +54 -0
- data/lib/rails/generators/active_record/application_record/application_record_generator.rb +0 -1
- data/lib/rails/generators/active_record/migration/migration_generator.rb +3 -5
- data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb.tt +3 -1
- data/lib/rails/generators/active_record/migration/templates/migration.rb.tt +7 -5
- data/lib/rails/generators/active_record/migration.rb +19 -2
- data/lib/rails/generators/active_record/model/model_generator.rb +39 -2
- data/lib/rails/generators/active_record/model/templates/abstract_base_class.rb.tt +7 -0
- data/lib/rails/generators/active_record/model/templates/model.rb.tt +10 -1
- metadata +116 -30
- data/lib/active_record/attribute_decorators.rb +0 -90
- data/lib/active_record/collection_cache_key.rb +0 -53
- data/lib/active_record/connection_adapters/connection_specification.rb +0 -287
- data/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb +0 -33
- data/lib/active_record/define_callbacks.rb +0 -22
- data/lib/active_record/relation/predicate_builder/base_handler.rb +0 -19
- data/lib/active_record/relation/where_clause_factory.rb +0 -34
@@ -1,8 +1,37 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require "active_support/core_ext/file/atomic"
|
4
|
+
|
3
5
|
module ActiveRecord
|
4
6
|
module ConnectionAdapters
|
5
7
|
class SchemaCache
|
8
|
+
def self.load_from(filename)
|
9
|
+
return unless File.file?(filename)
|
10
|
+
|
11
|
+
read(filename) do |file|
|
12
|
+
if filename.include?(".dump")
|
13
|
+
Marshal.load(file)
|
14
|
+
else
|
15
|
+
if YAML.respond_to?(:unsafe_load)
|
16
|
+
YAML.unsafe_load(file)
|
17
|
+
else
|
18
|
+
YAML.load(file)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def self.read(filename, &block)
|
25
|
+
if File.extname(filename) == ".gz"
|
26
|
+
Zlib::GzipReader.open(filename) { |gz|
|
27
|
+
yield gz.read
|
28
|
+
}
|
29
|
+
else
|
30
|
+
yield File.read(filename)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
private_class_method :read
|
34
|
+
|
6
35
|
attr_reader :version
|
7
36
|
attr_accessor :connection
|
8
37
|
|
@@ -13,6 +42,7 @@ module ActiveRecord
|
|
13
42
|
@columns_hash = {}
|
14
43
|
@primary_keys = {}
|
15
44
|
@data_sources = {}
|
45
|
+
@indexes = {}
|
16
46
|
end
|
17
47
|
|
18
48
|
def initialize_dup(other)
|
@@ -21,26 +51,37 @@ module ActiveRecord
|
|
21
51
|
@columns_hash = @columns_hash.dup
|
22
52
|
@primary_keys = @primary_keys.dup
|
23
53
|
@data_sources = @data_sources.dup
|
54
|
+
@indexes = @indexes.dup
|
24
55
|
end
|
25
56
|
|
26
57
|
def encode_with(coder)
|
27
|
-
|
28
|
-
|
29
|
-
coder["
|
30
|
-
coder["
|
31
|
-
coder["
|
58
|
+
reset_version!
|
59
|
+
|
60
|
+
coder["columns"] = @columns
|
61
|
+
coder["primary_keys"] = @primary_keys
|
62
|
+
coder["data_sources"] = @data_sources
|
63
|
+
coder["indexes"] = @indexes
|
64
|
+
coder["version"] = @version
|
65
|
+
coder["database_version"] = database_version
|
32
66
|
end
|
33
67
|
|
34
68
|
def init_with(coder)
|
35
|
-
@columns
|
36
|
-
@
|
37
|
-
@
|
38
|
-
@
|
39
|
-
@version
|
69
|
+
@columns = coder["columns"]
|
70
|
+
@primary_keys = coder["primary_keys"]
|
71
|
+
@data_sources = coder["data_sources"]
|
72
|
+
@indexes = coder["indexes"] || {}
|
73
|
+
@version = coder["version"]
|
74
|
+
@database_version = coder["database_version"]
|
75
|
+
|
76
|
+
derive_columns_hash_and_deduplicate_values
|
40
77
|
end
|
41
78
|
|
42
79
|
def primary_keys(table_name)
|
43
|
-
@primary_keys
|
80
|
+
@primary_keys.fetch(table_name) do
|
81
|
+
if data_source_exists?(table_name)
|
82
|
+
@primary_keys[deep_deduplicate(table_name)] = deep_deduplicate(connection.primary_key(table_name))
|
83
|
+
end
|
84
|
+
end
|
44
85
|
end
|
45
86
|
|
46
87
|
# A cached lookup for table existence.
|
@@ -48,7 +89,7 @@ module ActiveRecord
|
|
48
89
|
prepare_data_sources if @data_sources.empty?
|
49
90
|
return @data_sources[name] if @data_sources.key? name
|
50
91
|
|
51
|
-
@data_sources[name] = connection.data_source_exists?(name)
|
92
|
+
@data_sources[deep_deduplicate(name)] = connection.data_source_exists?(name)
|
52
93
|
end
|
53
94
|
|
54
95
|
# Add internal cache for table with +table_name+.
|
@@ -57,6 +98,7 @@ module ActiveRecord
|
|
57
98
|
primary_keys(table_name)
|
58
99
|
columns(table_name)
|
59
100
|
columns_hash(table_name)
|
101
|
+
indexes(table_name)
|
60
102
|
end
|
61
103
|
end
|
62
104
|
|
@@ -66,15 +108,32 @@ module ActiveRecord
|
|
66
108
|
|
67
109
|
# Get the columns for a table
|
68
110
|
def columns(table_name)
|
69
|
-
@columns
|
111
|
+
@columns.fetch(table_name) do
|
112
|
+
@columns[deep_deduplicate(table_name)] = deep_deduplicate(connection.columns(table_name))
|
113
|
+
end
|
70
114
|
end
|
71
115
|
|
72
116
|
# Get the columns for a table as a hash, key is the column name
|
73
117
|
# value is the column object.
|
74
118
|
def columns_hash(table_name)
|
75
|
-
@columns_hash
|
76
|
-
[
|
77
|
-
|
119
|
+
@columns_hash.fetch(table_name) do
|
120
|
+
@columns_hash[deep_deduplicate(table_name)] = columns(table_name).index_by(&:name).freeze
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
# Checks whether the columns hash is already cached for a table.
|
125
|
+
def columns_hash?(table_name)
|
126
|
+
@columns_hash.key?(table_name)
|
127
|
+
end
|
128
|
+
|
129
|
+
def indexes(table_name)
|
130
|
+
@indexes.fetch(table_name) do
|
131
|
+
@indexes[deep_deduplicate(table_name)] = deep_deduplicate(connection.indexes(table_name))
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
def database_version # :nodoc:
|
136
|
+
@database_version ||= connection.get_database_version
|
78
137
|
end
|
79
138
|
|
80
139
|
# Clears out internal caches
|
@@ -83,11 +142,13 @@ module ActiveRecord
|
|
83
142
|
@columns_hash.clear
|
84
143
|
@primary_keys.clear
|
85
144
|
@data_sources.clear
|
145
|
+
@indexes.clear
|
86
146
|
@version = nil
|
147
|
+
@database_version = nil
|
87
148
|
end
|
88
149
|
|
89
150
|
def size
|
90
|
-
[@columns, @columns_hash, @primary_keys, @data_sources].
|
151
|
+
[@columns, @columns_hash, @primary_keys, @data_sources].sum(&:size)
|
91
152
|
end
|
92
153
|
|
93
154
|
# Clear out internal caches for the data source +name+.
|
@@ -96,23 +157,100 @@ module ActiveRecord
|
|
96
157
|
@columns_hash.delete name
|
97
158
|
@primary_keys.delete name
|
98
159
|
@data_sources.delete name
|
160
|
+
@indexes.delete name
|
161
|
+
end
|
162
|
+
|
163
|
+
def dump_to(filename)
|
164
|
+
clear!
|
165
|
+
connection.data_sources.each { |table| add(table) }
|
166
|
+
open(filename) { |f|
|
167
|
+
if filename.include?(".dump")
|
168
|
+
f.write(Marshal.dump(self))
|
169
|
+
else
|
170
|
+
f.write(YAML.dump(self))
|
171
|
+
end
|
172
|
+
}
|
99
173
|
end
|
100
174
|
|
101
175
|
def marshal_dump
|
102
|
-
|
103
|
-
|
104
|
-
[@version, @columns,
|
176
|
+
reset_version!
|
177
|
+
|
178
|
+
[@version, @columns, {}, @primary_keys, @data_sources, @indexes, database_version]
|
105
179
|
end
|
106
180
|
|
107
181
|
def marshal_load(array)
|
108
|
-
@version, @columns,
|
182
|
+
@version, @columns, _columns_hash, @primary_keys, @data_sources, @indexes, @database_version = array
|
183
|
+
@indexes ||= {}
|
184
|
+
|
185
|
+
derive_columns_hash_and_deduplicate_values
|
109
186
|
end
|
110
187
|
|
111
188
|
private
|
189
|
+
def reset_version!
|
190
|
+
@version = connection.migration_context.current_version
|
191
|
+
end
|
192
|
+
|
193
|
+
def derive_columns_hash_and_deduplicate_values
|
194
|
+
@columns = deep_deduplicate(@columns)
|
195
|
+
@columns_hash = @columns.transform_values { |columns| columns.index_by(&:name) }
|
196
|
+
@primary_keys = deep_deduplicate(@primary_keys)
|
197
|
+
@data_sources = deep_deduplicate(@data_sources)
|
198
|
+
@indexes = deep_deduplicate(@indexes)
|
199
|
+
end
|
200
|
+
|
201
|
+
if RUBY_VERSION < "2.7"
|
202
|
+
def deep_deduplicate(value)
|
203
|
+
case value
|
204
|
+
when Hash
|
205
|
+
value.transform_keys { |k| deep_deduplicate(k) }.transform_values { |v| deep_deduplicate(v) }
|
206
|
+
when Array
|
207
|
+
value.map { |i| deep_deduplicate(i) }
|
208
|
+
when String
|
209
|
+
if value.tainted?
|
210
|
+
# Ruby 2.6 and 2.7 have slightly different implementations of the String#-@ method.
|
211
|
+
# In Ruby 2.6, the receiver of the String#-@ method is modified under certain
|
212
|
+
# circumstances, and this was later identified as a bug
|
213
|
+
# (https://bugs.ruby-lang.org/issues/15926) and only fixed in Ruby 2.7.
|
214
|
+
value = value.dup
|
215
|
+
end
|
216
|
+
-value
|
217
|
+
when Deduplicable
|
218
|
+
-value
|
219
|
+
else
|
220
|
+
value
|
221
|
+
end
|
222
|
+
end
|
223
|
+
else
|
224
|
+
def deep_deduplicate(value)
|
225
|
+
case value
|
226
|
+
when Hash
|
227
|
+
value.transform_keys { |k| deep_deduplicate(k) }.transform_values { |v| deep_deduplicate(v) }
|
228
|
+
when Array
|
229
|
+
value.map { |i| deep_deduplicate(i) }
|
230
|
+
when String, Deduplicable
|
231
|
+
-value
|
232
|
+
else
|
233
|
+
value
|
234
|
+
end
|
235
|
+
end
|
236
|
+
end
|
112
237
|
|
113
238
|
def prepare_data_sources
|
114
239
|
connection.data_sources.each { |source| @data_sources[source] = true }
|
115
240
|
end
|
241
|
+
|
242
|
+
def open(filename)
|
243
|
+
File.atomic_write(filename) do |file|
|
244
|
+
if File.extname(filename) == ".gz"
|
245
|
+
zipper = Zlib::GzipWriter.new file
|
246
|
+
yield zipper
|
247
|
+
zipper.flush
|
248
|
+
zipper.close
|
249
|
+
else
|
250
|
+
yield file
|
251
|
+
end
|
252
|
+
end
|
253
|
+
end
|
116
254
|
end
|
117
255
|
end
|
118
256
|
end
|
@@ -4,6 +4,8 @@ module ActiveRecord
|
|
4
4
|
# :stopdoc:
|
5
5
|
module ConnectionAdapters
|
6
6
|
class SqlTypeMetadata
|
7
|
+
include Deduplicable
|
8
|
+
|
7
9
|
attr_reader :sql_type, :type, :limit, :precision, :scale
|
8
10
|
|
9
11
|
def initialize(sql_type: nil, type: nil, limit: nil, precision: nil, scale: nil)
|
@@ -16,18 +18,27 @@ module ActiveRecord
|
|
16
18
|
|
17
19
|
def ==(other)
|
18
20
|
other.is_a?(SqlTypeMetadata) &&
|
19
|
-
|
21
|
+
sql_type == other.sql_type &&
|
22
|
+
type == other.type &&
|
23
|
+
limit == other.limit &&
|
24
|
+
precision == other.precision &&
|
25
|
+
scale == other.scale
|
20
26
|
end
|
21
27
|
alias eql? ==
|
22
28
|
|
23
29
|
def hash
|
24
|
-
|
30
|
+
SqlTypeMetadata.hash ^
|
31
|
+
sql_type.hash ^
|
32
|
+
type.hash ^
|
33
|
+
limit.hash ^
|
34
|
+
precision.hash >> 1 ^
|
35
|
+
scale.hash >> 2
|
25
36
|
end
|
26
37
|
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
38
|
+
private
|
39
|
+
def deduplicated
|
40
|
+
@sql_type = -sql_type
|
41
|
+
super
|
31
42
|
end
|
32
43
|
end
|
33
44
|
end
|
@@ -0,0 +1,146 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ActiveRecord
|
4
|
+
module ConnectionAdapters
|
5
|
+
module SQLite3
|
6
|
+
module DatabaseStatements
|
7
|
+
READ_QUERY = ActiveRecord::ConnectionAdapters::AbstractAdapter.build_read_query_regexp(
|
8
|
+
:pragma
|
9
|
+
) # :nodoc:
|
10
|
+
private_constant :READ_QUERY
|
11
|
+
|
12
|
+
def write_query?(sql) # :nodoc:
|
13
|
+
!READ_QUERY.match?(sql)
|
14
|
+
rescue ArgumentError # Invalid encoding
|
15
|
+
!READ_QUERY.match?(sql.b)
|
16
|
+
end
|
17
|
+
|
18
|
+
def explain(arel, binds = [])
|
19
|
+
sql = "EXPLAIN QUERY PLAN #{to_sql(arel, binds)}"
|
20
|
+
SQLite3::ExplainPrettyPrinter.new.pp(exec_query(sql, "EXPLAIN", []))
|
21
|
+
end
|
22
|
+
|
23
|
+
def execute(sql, name = nil) #:nodoc:
|
24
|
+
if preventing_writes? && write_query?(sql)
|
25
|
+
raise ActiveRecord::ReadOnlyError, "Write query attempted while in readonly mode: #{sql}"
|
26
|
+
end
|
27
|
+
|
28
|
+
materialize_transactions
|
29
|
+
mark_transaction_written_if_write(sql)
|
30
|
+
|
31
|
+
log(sql, name) do
|
32
|
+
ActiveSupport::Dependencies.interlock.permit_concurrent_loads do
|
33
|
+
@connection.execute(sql)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def exec_query(sql, name = nil, binds = [], prepare: false)
|
39
|
+
if preventing_writes? && write_query?(sql)
|
40
|
+
raise ActiveRecord::ReadOnlyError, "Write query attempted while in readonly mode: #{sql}"
|
41
|
+
end
|
42
|
+
|
43
|
+
materialize_transactions
|
44
|
+
mark_transaction_written_if_write(sql)
|
45
|
+
|
46
|
+
type_casted_binds = type_casted_binds(binds)
|
47
|
+
|
48
|
+
log(sql, name, binds, type_casted_binds) do
|
49
|
+
ActiveSupport::Dependencies.interlock.permit_concurrent_loads do
|
50
|
+
# Don't cache statements if they are not prepared
|
51
|
+
unless prepare
|
52
|
+
stmt = @connection.prepare(sql)
|
53
|
+
begin
|
54
|
+
cols = stmt.columns
|
55
|
+
unless without_prepared_statement?(binds)
|
56
|
+
stmt.bind_params(type_casted_binds)
|
57
|
+
end
|
58
|
+
records = stmt.to_a
|
59
|
+
ensure
|
60
|
+
stmt.close
|
61
|
+
end
|
62
|
+
else
|
63
|
+
stmt = @statements[sql] ||= @connection.prepare(sql)
|
64
|
+
cols = stmt.columns
|
65
|
+
stmt.reset!
|
66
|
+
stmt.bind_params(type_casted_binds)
|
67
|
+
records = stmt.to_a
|
68
|
+
end
|
69
|
+
|
70
|
+
build_result(columns: cols, rows: records)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
def exec_delete(sql, name = "SQL", binds = [])
|
76
|
+
exec_query(sql, name, binds)
|
77
|
+
@connection.changes
|
78
|
+
end
|
79
|
+
alias :exec_update :exec_delete
|
80
|
+
|
81
|
+
def begin_isolated_db_transaction(isolation) #:nodoc
|
82
|
+
raise TransactionIsolationError, "SQLite3 only supports the `read_uncommitted` transaction isolation level" if isolation != :read_uncommitted
|
83
|
+
raise StandardError, "You need to enable the shared-cache mode in SQLite mode before attempting to change the transaction isolation level" unless shared_cache?
|
84
|
+
|
85
|
+
Thread.current.thread_variable_set("read_uncommitted", @connection.get_first_value("PRAGMA read_uncommitted"))
|
86
|
+
@connection.read_uncommitted = true
|
87
|
+
begin_db_transaction
|
88
|
+
end
|
89
|
+
|
90
|
+
def begin_db_transaction #:nodoc:
|
91
|
+
log("begin transaction", "TRANSACTION") { @connection.transaction }
|
92
|
+
end
|
93
|
+
|
94
|
+
def commit_db_transaction #:nodoc:
|
95
|
+
log("commit transaction", "TRANSACTION") { @connection.commit }
|
96
|
+
reset_read_uncommitted
|
97
|
+
end
|
98
|
+
|
99
|
+
def exec_rollback_db_transaction #:nodoc:
|
100
|
+
log("rollback transaction", "TRANSACTION") { @connection.rollback }
|
101
|
+
reset_read_uncommitted
|
102
|
+
end
|
103
|
+
|
104
|
+
private
|
105
|
+
def reset_read_uncommitted
|
106
|
+
read_uncommitted = Thread.current.thread_variable_get("read_uncommitted")
|
107
|
+
return unless read_uncommitted
|
108
|
+
|
109
|
+
@connection.read_uncommitted = read_uncommitted
|
110
|
+
end
|
111
|
+
|
112
|
+
def execute_batch(statements, name = nil)
|
113
|
+
sql = combine_multi_statements(statements)
|
114
|
+
|
115
|
+
if preventing_writes? && write_query?(sql)
|
116
|
+
raise ActiveRecord::ReadOnlyError, "Write query attempted while in readonly mode: #{sql}"
|
117
|
+
end
|
118
|
+
|
119
|
+
materialize_transactions
|
120
|
+
mark_transaction_written_if_write(sql)
|
121
|
+
|
122
|
+
log(sql, name) do
|
123
|
+
ActiveSupport::Dependencies.interlock.permit_concurrent_loads do
|
124
|
+
@connection.execute_batch2(sql)
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
def last_inserted_id(result)
|
130
|
+
@connection.last_insert_row_id
|
131
|
+
end
|
132
|
+
|
133
|
+
def build_fixture_statements(fixture_set)
|
134
|
+
fixture_set.flat_map do |table_name, fixtures|
|
135
|
+
next if fixtures.empty?
|
136
|
+
fixtures.map { |fixture| build_fixture_sql([fixture], table_name) }
|
137
|
+
end.compact
|
138
|
+
end
|
139
|
+
|
140
|
+
def build_truncate_statement(table_name)
|
141
|
+
"DELETE FROM #{quote_table_name(table_name)}"
|
142
|
+
end
|
143
|
+
end
|
144
|
+
end
|
145
|
+
end
|
146
|
+
end
|
@@ -13,11 +13,11 @@ module ActiveRecord
|
|
13
13
|
end
|
14
14
|
|
15
15
|
def quote_table_name(name)
|
16
|
-
|
16
|
+
self.class.quoted_table_names[name] ||= super.gsub(".", "\".\"").freeze
|
17
17
|
end
|
18
18
|
|
19
19
|
def quote_column_name(name)
|
20
|
-
|
20
|
+
self.class.quoted_column_names[name] ||= %Q("#{super.gsub('"', '""')}")
|
21
21
|
end
|
22
22
|
|
23
23
|
def quoted_time(value)
|
@@ -30,23 +30,58 @@ module ActiveRecord
|
|
30
30
|
end
|
31
31
|
|
32
32
|
def quoted_true
|
33
|
-
|
33
|
+
"1"
|
34
34
|
end
|
35
35
|
|
36
36
|
def unquoted_true
|
37
|
-
|
37
|
+
1
|
38
38
|
end
|
39
39
|
|
40
40
|
def quoted_false
|
41
|
-
|
41
|
+
"0"
|
42
42
|
end
|
43
43
|
|
44
44
|
def unquoted_false
|
45
|
-
|
45
|
+
0
|
46
46
|
end
|
47
47
|
|
48
|
-
|
48
|
+
def column_name_matcher
|
49
|
+
COLUMN_NAME
|
50
|
+
end
|
51
|
+
|
52
|
+
def column_name_with_order_matcher
|
53
|
+
COLUMN_NAME_WITH_ORDER
|
54
|
+
end
|
49
55
|
|
56
|
+
COLUMN_NAME = /
|
57
|
+
\A
|
58
|
+
(
|
59
|
+
(?:
|
60
|
+
# "table_name"."column_name" | function(one or no argument)
|
61
|
+
((?:\w+\.|"\w+"\.)?(?:\w+|"\w+")) | \w+\((?:|\g<2>)\)
|
62
|
+
)
|
63
|
+
(?:(?:\s+AS)?\s+(?:\w+|"\w+"))?
|
64
|
+
)
|
65
|
+
(?:\s*,\s*\g<1>)*
|
66
|
+
\z
|
67
|
+
/ix
|
68
|
+
|
69
|
+
COLUMN_NAME_WITH_ORDER = /
|
70
|
+
\A
|
71
|
+
(
|
72
|
+
(?:
|
73
|
+
# "table_name"."column_name" | function(one or no argument)
|
74
|
+
((?:\w+\.|"\w+"\.)?(?:\w+|"\w+")) | \w+\((?:|\g<2>)\)
|
75
|
+
)
|
76
|
+
(?:\s+ASC|\s+DESC)?
|
77
|
+
)
|
78
|
+
(?:\s*,\s*\g<1>)*
|
79
|
+
\z
|
80
|
+
/ix
|
81
|
+
|
82
|
+
private_constant :COLUMN_NAME, :COLUMN_NAME_WITH_ORDER
|
83
|
+
|
84
|
+
private
|
50
85
|
def _type_cast(value)
|
51
86
|
case value
|
52
87
|
when BigDecimal
|
@@ -3,8 +3,12 @@
|
|
3
3
|
module ActiveRecord
|
4
4
|
module ConnectionAdapters
|
5
5
|
module SQLite3
|
6
|
-
class SchemaCreation <
|
6
|
+
class SchemaCreation < SchemaCreation # :nodoc:
|
7
7
|
private
|
8
|
+
def supports_index_using?
|
9
|
+
false
|
10
|
+
end
|
11
|
+
|
8
12
|
def add_column_options!(sql, options)
|
9
13
|
if options[:collation]
|
10
14
|
sql << " COLLATE \"#{options[:collation]}\""
|
@@ -9,9 +9,9 @@ module ActiveRecord
|
|
9
9
|
exec_query("PRAGMA index_list(#{quote_table_name(table_name)})", "SCHEMA").map do |row|
|
10
10
|
# Indexes SQLite creates implicitly for internal use start with "sqlite_".
|
11
11
|
# See https://www.sqlite.org/fileformat2.html#intschema
|
12
|
-
next if row["name"].
|
12
|
+
next if row["name"].start_with?("sqlite_")
|
13
13
|
|
14
|
-
index_sql = query_value(
|
14
|
+
index_sql = query_value(<<~SQL, "SCHEMA")
|
15
15
|
SELECT sql
|
16
16
|
FROM sqlite_master
|
17
17
|
WHERE name = #{quote(row['name'])} AND type = 'index'
|
@@ -21,19 +21,24 @@ module ActiveRecord
|
|
21
21
|
WHERE name = #{quote(row['name'])} AND type = 'index'
|
22
22
|
SQL
|
23
23
|
|
24
|
-
/\
|
24
|
+
/\bON\b\s*"?(\w+?)"?\s*\((?<expressions>.+?)\)(?:\s*WHERE\b\s*(?<where>.+))?\z/i =~ index_sql
|
25
25
|
|
26
26
|
columns = exec_query("PRAGMA index_info(#{quote(row['name'])})", "SCHEMA").map do |col|
|
27
27
|
col["name"]
|
28
28
|
end
|
29
29
|
|
30
|
-
# Add info on sort order for columns (only desc order is explicitly specified, asc is
|
31
|
-
# the default)
|
32
30
|
orders = {}
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
31
|
+
|
32
|
+
if columns.any?(&:nil?) # index created with an expression
|
33
|
+
columns = expressions
|
34
|
+
else
|
35
|
+
# Add info on sort order for columns (only desc order is explicitly specified,
|
36
|
+
# asc is the default)
|
37
|
+
if index_sql # index_sql can be null in case of primary key indexes
|
38
|
+
index_sql.scan(/"(\w+)" DESC/).flatten.each { |order_column|
|
39
|
+
orders[order_column] = :desc
|
40
|
+
}
|
41
|
+
end
|
37
42
|
end
|
38
43
|
|
39
44
|
IndexDefinition.new(
|
@@ -47,6 +52,61 @@ module ActiveRecord
|
|
47
52
|
end.compact
|
48
53
|
end
|
49
54
|
|
55
|
+
def add_foreign_key(from_table, to_table, **options)
|
56
|
+
alter_table(from_table) do |definition|
|
57
|
+
to_table = strip_table_name_prefix_and_suffix(to_table)
|
58
|
+
definition.foreign_key(to_table, **options)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
def remove_foreign_key(from_table, to_table = nil, **options)
|
63
|
+
to_table ||= options[:to_table]
|
64
|
+
options = options.except(:name, :to_table, :validate)
|
65
|
+
foreign_keys = foreign_keys(from_table)
|
66
|
+
|
67
|
+
fkey = foreign_keys.detect do |fk|
|
68
|
+
table = to_table || begin
|
69
|
+
table = options[:column].to_s.delete_suffix("_id")
|
70
|
+
Base.pluralize_table_names ? table.pluralize : table
|
71
|
+
end
|
72
|
+
table = strip_table_name_prefix_and_suffix(table)
|
73
|
+
fk_to_table = strip_table_name_prefix_and_suffix(fk.to_table)
|
74
|
+
fk_to_table == table && options.all? { |k, v| fk.options[k].to_s == v.to_s }
|
75
|
+
end || raise(ArgumentError, "Table '#{from_table}' has no foreign key for #{to_table || options}")
|
76
|
+
|
77
|
+
foreign_keys.delete(fkey)
|
78
|
+
alter_table(from_table, foreign_keys)
|
79
|
+
end
|
80
|
+
|
81
|
+
def check_constraints(table_name)
|
82
|
+
table_sql = query_value(<<-SQL, "SCHEMA")
|
83
|
+
SELECT sql
|
84
|
+
FROM sqlite_master
|
85
|
+
WHERE name = #{quote_table_name(table_name)} AND type = 'table'
|
86
|
+
UNION ALL
|
87
|
+
SELECT sql
|
88
|
+
FROM sqlite_temp_master
|
89
|
+
WHERE name = #{quote_table_name(table_name)} AND type = 'table'
|
90
|
+
SQL
|
91
|
+
|
92
|
+
table_sql.to_s.scan(/CONSTRAINT\s+(?<name>\w+)\s+CHECK\s+\((?<expression>(:?[^()]|\(\g<expression>\))+)\)/i).map do |name, expression|
|
93
|
+
CheckConstraintDefinition.new(table_name, expression, name: name)
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
def add_check_constraint(table_name, expression, **options)
|
98
|
+
alter_table(table_name) do |definition|
|
99
|
+
definition.check_constraint(expression, **options)
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
def remove_check_constraint(table_name, expression = nil, **options)
|
104
|
+
check_constraints = check_constraints(table_name)
|
105
|
+
chk_name_to_delete = check_constraint_for!(table_name, expression: expression, **options).name
|
106
|
+
check_constraints.delete_if { |chk| chk.name == chk_name_to_delete }
|
107
|
+
alter_table(table_name, foreign_keys(table_name), check_constraints)
|
108
|
+
end
|
109
|
+
|
50
110
|
def create_schema_dumper(options)
|
51
111
|
SQLite3::SchemaDumper.create(self, options)
|
52
112
|
end
|
@@ -56,8 +116,12 @@ module ActiveRecord
|
|
56
116
|
SQLite3::SchemaCreation.new(self)
|
57
117
|
end
|
58
118
|
|
59
|
-
def create_table_definition(
|
60
|
-
SQLite3::TableDefinition.new(
|
119
|
+
def create_table_definition(name, **options)
|
120
|
+
SQLite3::TableDefinition.new(self, name, **options)
|
121
|
+
end
|
122
|
+
|
123
|
+
def validate_index_length!(table_name, new_name, internal = false)
|
124
|
+
super unless internal
|
61
125
|
end
|
62
126
|
|
63
127
|
def new_column_from_field(table_name, field)
|
@@ -74,14 +138,14 @@ module ActiveRecord
|
|
74
138
|
end
|
75
139
|
|
76
140
|
type_metadata = fetch_type_metadata(field["type"])
|
77
|
-
Column.new(field["name"], default, type_metadata, field["notnull"].to_i == 0,
|
141
|
+
Column.new(field["name"], default, type_metadata, field["notnull"].to_i == 0, collation: field["collation"])
|
78
142
|
end
|
79
143
|
|
80
144
|
def data_source_sql(name = nil, type: nil)
|
81
145
|
scope = quoted_scope(name, type: type)
|
82
146
|
scope[:type] ||= "'table','view'"
|
83
147
|
|
84
|
-
sql = "SELECT name FROM sqlite_master WHERE name <> 'sqlite_sequence'"
|
148
|
+
sql = +"SELECT name FROM sqlite_master WHERE name <> 'sqlite_sequence'"
|
85
149
|
sql << " AND name = #{scope[:name]}" if scope[:name]
|
86
150
|
sql << " AND type IN (#{scope[:type]})"
|
87
151
|
sql
|