activerecord 3.2.22.5 → 4.2.11.3
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 +1632 -609
- data/MIT-LICENSE +1 -1
- data/README.rdoc +37 -41
- data/examples/performance.rb +31 -19
- data/examples/simple.rb +4 -4
- data/lib/active_record/aggregations.rb +56 -42
- data/lib/active_record/association_relation.rb +35 -0
- data/lib/active_record/associations/alias_tracker.rb +47 -36
- data/lib/active_record/associations/association.rb +73 -55
- data/lib/active_record/associations/association_scope.rb +143 -82
- data/lib/active_record/associations/belongs_to_association.rb +65 -25
- data/lib/active_record/associations/belongs_to_polymorphic_association.rb +7 -2
- data/lib/active_record/associations/builder/association.rb +125 -31
- data/lib/active_record/associations/builder/belongs_to.rb +89 -61
- data/lib/active_record/associations/builder/collection_association.rb +69 -49
- data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +113 -42
- data/lib/active_record/associations/builder/has_many.rb +8 -64
- data/lib/active_record/associations/builder/has_one.rb +12 -51
- data/lib/active_record/associations/builder/singular_association.rb +23 -17
- data/lib/active_record/associations/collection_association.rb +251 -177
- data/lib/active_record/associations/collection_proxy.rb +963 -63
- data/lib/active_record/associations/foreign_association.rb +11 -0
- data/lib/active_record/associations/has_many_association.rb +113 -22
- data/lib/active_record/associations/has_many_through_association.rb +99 -39
- data/lib/active_record/associations/has_one_association.rb +43 -20
- data/lib/active_record/associations/has_one_through_association.rb +1 -1
- data/lib/active_record/associations/join_dependency/join_association.rb +76 -107
- 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 +230 -156
- data/lib/active_record/associations/preloader/association.rb +96 -55
- data/lib/active_record/associations/preloader/collection_association.rb +3 -3
- data/lib/active_record/associations/preloader/has_many_through.rb +7 -3
- data/lib/active_record/associations/preloader/has_one.rb +1 -1
- data/lib/active_record/associations/preloader/singular_association.rb +3 -3
- data/lib/active_record/associations/preloader/through_association.rb +62 -33
- data/lib/active_record/associations/preloader.rb +101 -79
- data/lib/active_record/associations/singular_association.rb +29 -13
- data/lib/active_record/associations/through_association.rb +30 -16
- data/lib/active_record/associations.rb +463 -345
- data/lib/active_record/attribute.rb +163 -0
- data/lib/active_record/attribute_assignment.rb +142 -151
- data/lib/active_record/attribute_decorators.rb +66 -0
- data/lib/active_record/attribute_methods/before_type_cast.rb +52 -7
- data/lib/active_record/attribute_methods/dirty.rb +137 -57
- data/lib/active_record/attribute_methods/primary_key.rb +50 -36
- data/lib/active_record/attribute_methods/query.rb +5 -4
- data/lib/active_record/attribute_methods/read.rb +73 -106
- data/lib/active_record/attribute_methods/serialization.rb +44 -94
- data/lib/active_record/attribute_methods/time_zone_conversion.rb +49 -45
- data/lib/active_record/attribute_methods/write.rb +57 -44
- data/lib/active_record/attribute_methods.rb +301 -141
- data/lib/active_record/attribute_set/builder.rb +106 -0
- data/lib/active_record/attribute_set.rb +81 -0
- data/lib/active_record/attributes.rb +147 -0
- data/lib/active_record/autosave_association.rb +246 -217
- data/lib/active_record/base.rb +70 -474
- data/lib/active_record/callbacks.rb +66 -28
- data/lib/active_record/coders/json.rb +13 -0
- data/lib/active_record/coders/yaml_column.rb +18 -21
- data/lib/active_record/connection_adapters/abstract/connection_pool.rb +396 -219
- data/lib/active_record/connection_adapters/abstract/database_limits.rb +9 -0
- data/lib/active_record/connection_adapters/abstract/database_statements.rb +167 -164
- data/lib/active_record/connection_adapters/abstract/query_cache.rb +29 -24
- data/lib/active_record/connection_adapters/abstract/quoting.rb +74 -55
- data/lib/active_record/connection_adapters/abstract/savepoints.rb +21 -0
- data/lib/active_record/connection_adapters/abstract/schema_creation.rb +125 -0
- data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +261 -169
- data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +50 -0
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +707 -259
- data/lib/active_record/connection_adapters/abstract/transaction.rb +215 -0
- data/lib/active_record/connection_adapters/abstract_adapter.rb +298 -89
- data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +466 -196
- data/lib/active_record/connection_adapters/column.rb +31 -245
- data/lib/active_record/connection_adapters/connection_specification.rb +275 -0
- data/lib/active_record/connection_adapters/mysql2_adapter.rb +45 -57
- data/lib/active_record/connection_adapters/mysql_adapter.rb +180 -123
- data/lib/active_record/connection_adapters/postgresql/array_parser.rb +93 -0
- data/lib/active_record/connection_adapters/postgresql/column.rb +20 -0
- data/lib/active_record/connection_adapters/postgresql/database_statements.rb +232 -0
- data/lib/active_record/connection_adapters/postgresql/oid/array.rb +100 -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 +46 -0
- data/lib/active_record/connection_adapters/postgresql/oid/date.rb +11 -0
- data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +36 -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/float.rb +21 -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/infinity.rb +13 -0
- data/lib/active_record/connection_adapters/postgresql/oid/integer.rb +11 -0
- data/lib/active_record/connection_adapters/postgresql/oid/json.rb +35 -0
- data/lib/active_record/connection_adapters/postgresql/oid/jsonb.rb +23 -0
- data/lib/active_record/connection_adapters/postgresql/oid/money.rb +43 -0
- data/lib/active_record/connection_adapters/postgresql/oid/point.rb +43 -0
- data/lib/active_record/connection_adapters/postgresql/oid/range.rb +79 -0
- data/lib/active_record/connection_adapters/postgresql/oid/specialized_string.rb +19 -0
- data/lib/active_record/connection_adapters/postgresql/oid/time.rb +11 -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 +36 -0
- data/lib/active_record/connection_adapters/postgresql/quoting.rb +108 -0
- data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +30 -0
- data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +152 -0
- data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +596 -0
- data/lib/active_record/connection_adapters/postgresql/utils.rb +77 -0
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +430 -999
- data/lib/active_record/connection_adapters/schema_cache.rb +52 -27
- data/lib/active_record/connection_adapters/sqlite3_adapter.rb +579 -22
- data/lib/active_record/connection_handling.rb +132 -0
- data/lib/active_record/core.rb +579 -0
- data/lib/active_record/counter_cache.rb +157 -105
- data/lib/active_record/dynamic_matchers.rb +119 -63
- data/lib/active_record/enum.rb +197 -0
- data/lib/active_record/errors.rb +94 -36
- data/lib/active_record/explain.rb +15 -63
- data/lib/active_record/explain_registry.rb +30 -0
- data/lib/active_record/explain_subscriber.rb +9 -5
- data/lib/active_record/fixture_set/file.rb +56 -0
- data/lib/active_record/fixtures.rb +302 -215
- data/lib/active_record/gem_version.rb +15 -0
- data/lib/active_record/inheritance.rb +143 -70
- data/lib/active_record/integration.rb +65 -12
- data/lib/active_record/legacy_yaml_adapter.rb +30 -0
- data/lib/active_record/locale/en.yml +8 -1
- data/lib/active_record/locking/optimistic.rb +73 -52
- data/lib/active_record/locking/pessimistic.rb +5 -5
- data/lib/active_record/log_subscriber.rb +24 -21
- data/lib/active_record/migration/command_recorder.rb +124 -32
- data/lib/active_record/migration/join_table.rb +15 -0
- data/lib/active_record/migration.rb +511 -213
- data/lib/active_record/model_schema.rb +91 -117
- data/lib/active_record/nested_attributes.rb +184 -130
- data/lib/active_record/no_touching.rb +52 -0
- data/lib/active_record/null_relation.rb +81 -0
- data/lib/active_record/persistence.rb +276 -117
- data/lib/active_record/query_cache.rb +19 -37
- data/lib/active_record/querying.rb +28 -18
- data/lib/active_record/railtie.rb +73 -40
- data/lib/active_record/railties/console_sandbox.rb +3 -4
- data/lib/active_record/railties/controller_runtime.rb +4 -3
- data/lib/active_record/railties/databases.rake +141 -416
- data/lib/active_record/railties/jdbcmysql_error.rb +1 -1
- data/lib/active_record/readonly_attributes.rb +1 -4
- data/lib/active_record/reflection.rb +513 -154
- data/lib/active_record/relation/batches.rb +91 -43
- data/lib/active_record/relation/calculations.rb +199 -161
- data/lib/active_record/relation/delegation.rb +116 -25
- data/lib/active_record/relation/finder_methods.rb +362 -248
- data/lib/active_record/relation/merger.rb +193 -0
- data/lib/active_record/relation/predicate_builder/array_handler.rb +48 -0
- data/lib/active_record/relation/predicate_builder/relation_handler.rb +13 -0
- data/lib/active_record/relation/predicate_builder.rb +135 -43
- data/lib/active_record/relation/query_methods.rb +928 -167
- data/lib/active_record/relation/spawn_methods.rb +48 -149
- data/lib/active_record/relation.rb +352 -207
- data/lib/active_record/result.rb +101 -10
- data/lib/active_record/runtime_registry.rb +22 -0
- data/lib/active_record/sanitization.rb +56 -59
- data/lib/active_record/schema.rb +19 -13
- data/lib/active_record/schema_dumper.rb +106 -63
- data/lib/active_record/schema_migration.rb +53 -0
- data/lib/active_record/scoping/default.rb +50 -57
- data/lib/active_record/scoping/named.rb +73 -109
- data/lib/active_record/scoping.rb +58 -123
- data/lib/active_record/serialization.rb +6 -2
- data/lib/active_record/serializers/xml_serializer.rb +12 -22
- data/lib/active_record/statement_cache.rb +111 -0
- data/lib/active_record/store.rb +168 -15
- data/lib/active_record/tasks/database_tasks.rb +299 -0
- data/lib/active_record/tasks/mysql_database_tasks.rb +159 -0
- data/lib/active_record/tasks/postgresql_database_tasks.rb +101 -0
- data/lib/active_record/tasks/sqlite_database_tasks.rb +55 -0
- data/lib/active_record/timestamp.rb +23 -16
- data/lib/active_record/transactions.rb +125 -79
- data/lib/active_record/type/big_integer.rb +13 -0
- data/lib/active_record/type/binary.rb +50 -0
- data/lib/active_record/type/boolean.rb +31 -0
- data/lib/active_record/type/date.rb +50 -0
- data/lib/active_record/type/date_time.rb +54 -0
- data/lib/active_record/type/decimal.rb +64 -0
- data/lib/active_record/type/decimal_without_scale.rb +11 -0
- data/lib/active_record/type/decorator.rb +14 -0
- data/lib/active_record/type/float.rb +19 -0
- data/lib/active_record/type/hash_lookup_type_map.rb +23 -0
- data/lib/active_record/type/integer.rb +59 -0
- data/lib/active_record/type/mutable.rb +16 -0
- data/lib/active_record/type/numeric.rb +36 -0
- data/lib/active_record/type/serialized.rb +62 -0
- data/lib/active_record/type/string.rb +40 -0
- data/lib/active_record/type/text.rb +11 -0
- data/lib/active_record/type/time.rb +26 -0
- data/lib/active_record/type/time_value.rb +38 -0
- data/lib/active_record/type/type_map.rb +64 -0
- data/lib/active_record/type/unsigned_integer.rb +15 -0
- data/lib/active_record/type/value.rb +110 -0
- data/lib/active_record/type.rb +23 -0
- data/lib/active_record/validations/associated.rb +24 -16
- data/lib/active_record/validations/presence.rb +67 -0
- data/lib/active_record/validations/uniqueness.rb +123 -64
- data/lib/active_record/validations.rb +36 -29
- data/lib/active_record/version.rb +5 -7
- data/lib/active_record.rb +66 -46
- data/lib/rails/generators/active_record/migration/migration_generator.rb +53 -8
- data/lib/rails/generators/active_record/{model/templates/migration.rb → migration/templates/create_table_migration.rb} +5 -1
- data/lib/rails/generators/active_record/migration/templates/migration.rb +20 -15
- data/lib/rails/generators/active_record/migration.rb +11 -8
- data/lib/rails/generators/active_record/model/model_generator.rb +9 -4
- data/lib/rails/generators/active_record/model/templates/model.rb +4 -6
- data/lib/rails/generators/active_record/model/templates/module.rb +1 -1
- data/lib/rails/generators/active_record.rb +3 -11
- metadata +101 -45
- 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/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/session_store.rb +0 -360
- data/lib/active_record/test_case.rb +0 -73
- 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,4 +1,5 @@
|
|
1
1
|
require 'active_support/core_ext/big_decimal/conversions'
|
2
|
+
require "active_support/multibyte/chars"
|
2
3
|
|
3
4
|
module ActiveRecord
|
4
5
|
module ConnectionAdapters # :nodoc:
|
@@ -9,70 +10,29 @@ module ActiveRecord
|
|
9
10
|
# records are quoted as their primary key
|
10
11
|
return value.quoted_id if value.respond_to?(:quoted_id)
|
11
12
|
|
12
|
-
|
13
|
-
|
14
|
-
value = value.to_s
|
15
|
-
return "'#{quote_string(value)}'" unless column
|
16
|
-
|
17
|
-
case column.type
|
18
|
-
when :binary then "'#{quote_string(column.string_to_binary(value))}'"
|
19
|
-
when :integer then value.to_i.to_s
|
20
|
-
when :float then value.to_f.to_s
|
21
|
-
else
|
22
|
-
"'#{quote_string(value)}'"
|
23
|
-
end
|
24
|
-
|
25
|
-
when true, false
|
26
|
-
if column && column.type == :integer
|
27
|
-
value ? '1' : '0'
|
28
|
-
else
|
29
|
-
value ? quoted_true : quoted_false
|
30
|
-
end
|
31
|
-
# BigDecimals need to be put in a non-normalized form and quoted.
|
32
|
-
when nil then "NULL"
|
33
|
-
when BigDecimal then value.to_s('F')
|
34
|
-
when Numeric then value.to_s
|
35
|
-
when Date, Time then "'#{quoted_date(value)}'"
|
36
|
-
when Symbol then "'#{quote_string(value.to_s)}'"
|
37
|
-
else
|
38
|
-
"'#{quote_string(YAML.dump(value))}'"
|
13
|
+
if column
|
14
|
+
value = column.cast_type.type_cast_for_database(value)
|
39
15
|
end
|
16
|
+
|
17
|
+
_quote(value)
|
40
18
|
end
|
41
19
|
|
42
20
|
# Cast a +value+ to a type that the database understands. For example,
|
43
21
|
# SQLite does not understand dates, so this method will convert a Date
|
44
22
|
# to a String.
|
45
23
|
def type_cast(value, column)
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
when String, ActiveSupport::Multibyte::Chars
|
50
|
-
value = value.to_s
|
51
|
-
return value unless column
|
52
|
-
|
53
|
-
case column.type
|
54
|
-
when :binary then value
|
55
|
-
when :integer then value.to_i
|
56
|
-
when :float then value.to_f
|
57
|
-
else
|
58
|
-
value
|
59
|
-
end
|
24
|
+
if value.respond_to?(:quoted_id) && value.respond_to?(:id)
|
25
|
+
return value.id
|
26
|
+
end
|
60
27
|
|
61
|
-
|
62
|
-
|
63
|
-
value ? 1 : 0
|
64
|
-
else
|
65
|
-
value ? 't' : 'f'
|
66
|
-
end
|
67
|
-
# BigDecimals need to be put in a non-normalized form and quoted.
|
68
|
-
when nil then nil
|
69
|
-
when BigDecimal then value.to_s('F')
|
70
|
-
when Numeric then value
|
71
|
-
when Date, Time then quoted_date(value)
|
72
|
-
when Symbol then value.to_s
|
73
|
-
else
|
74
|
-
YAML.dump(value)
|
28
|
+
if column
|
29
|
+
value = column.cast_type.type_cast_for_database(value)
|
75
30
|
end
|
31
|
+
|
32
|
+
_type_cast(value)
|
33
|
+
rescue TypeError
|
34
|
+
to_type = column ? " to #{column.type}" : ""
|
35
|
+
raise TypeError, "can't cast #{value.class}#{to_type}"
|
76
36
|
end
|
77
37
|
|
78
38
|
# Quotes a string, escaping any ' (single quote) and \ (backslash)
|
@@ -91,14 +51,34 @@ module ActiveRecord
|
|
91
51
|
quote_column_name(table_name)
|
92
52
|
end
|
93
53
|
|
54
|
+
# Override to return the quoted table name for assignment. Defaults to
|
55
|
+
# table quoting.
|
56
|
+
#
|
57
|
+
# This works for mysql and mysql2 where table.column can be used to
|
58
|
+
# resolve ambiguity.
|
59
|
+
#
|
60
|
+
# We override this in the sqlite3 and postgresql adapters to use only
|
61
|
+
# the column name (as per syntax requirements).
|
62
|
+
def quote_table_name_for_assignment(table, attr)
|
63
|
+
quote_table_name("#{table}.#{attr}")
|
64
|
+
end
|
65
|
+
|
94
66
|
def quoted_true
|
95
67
|
"'t'"
|
96
68
|
end
|
97
69
|
|
70
|
+
def unquoted_true
|
71
|
+
't'
|
72
|
+
end
|
73
|
+
|
98
74
|
def quoted_false
|
99
75
|
"'f'"
|
100
76
|
end
|
101
77
|
|
78
|
+
def unquoted_false
|
79
|
+
'f'
|
80
|
+
end
|
81
|
+
|
102
82
|
def quoted_date(value)
|
103
83
|
if value.acts_like?(:time)
|
104
84
|
zone_conversion_method = ActiveRecord::Base.default_timezone == :utc ? :getutc : :getlocal
|
@@ -110,6 +90,45 @@ module ActiveRecord
|
|
110
90
|
|
111
91
|
value.to_s(:db)
|
112
92
|
end
|
93
|
+
|
94
|
+
private
|
95
|
+
|
96
|
+
def types_which_need_no_typecasting
|
97
|
+
[nil, Numeric, String]
|
98
|
+
end
|
99
|
+
|
100
|
+
def _quote(value)
|
101
|
+
case value
|
102
|
+
when String, ActiveSupport::Multibyte::Chars, Type::Binary::Data
|
103
|
+
"'#{quote_string(value.to_s)}'"
|
104
|
+
when true then quoted_true
|
105
|
+
when false then quoted_false
|
106
|
+
when nil then "NULL"
|
107
|
+
# BigDecimals need to be put in a non-normalized form and quoted.
|
108
|
+
when BigDecimal then value.to_s('F')
|
109
|
+
when Numeric, ActiveSupport::Duration then value.to_s
|
110
|
+
when Date, Time then "'#{quoted_date(value)}'"
|
111
|
+
when Symbol then "'#{quote_string(value.to_s)}'"
|
112
|
+
when Class then "'#{value}'"
|
113
|
+
else
|
114
|
+
"'#{quote_string(YAML.dump(value))}'"
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
def _type_cast(value)
|
119
|
+
case value
|
120
|
+
when Symbol, ActiveSupport::Multibyte::Chars, Type::Binary::Data
|
121
|
+
value.to_s
|
122
|
+
when true then unquoted_true
|
123
|
+
when false then unquoted_false
|
124
|
+
# BigDecimals need to be put in a non-normalized form and quoted.
|
125
|
+
when BigDecimal then value.to_s('F')
|
126
|
+
when Date, Time then quoted_date(value)
|
127
|
+
when *types_which_need_no_typecasting
|
128
|
+
value
|
129
|
+
else raise TypeError
|
130
|
+
end
|
131
|
+
end
|
113
132
|
end
|
114
133
|
end
|
115
134
|
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module ActiveRecord
|
2
|
+
module ConnectionAdapters
|
3
|
+
module Savepoints #:nodoc:
|
4
|
+
def supports_savepoints?
|
5
|
+
true
|
6
|
+
end
|
7
|
+
|
8
|
+
def create_savepoint(name = current_savepoint_name)
|
9
|
+
execute("SAVEPOINT #{name}")
|
10
|
+
end
|
11
|
+
|
12
|
+
def exec_rollback_to_savepoint(name = current_savepoint_name)
|
13
|
+
execute("ROLLBACK TO SAVEPOINT #{name}")
|
14
|
+
end
|
15
|
+
|
16
|
+
def release_savepoint(name = current_savepoint_name)
|
17
|
+
execute("RELEASE SAVEPOINT #{name}")
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,125 @@
|
|
1
|
+
require 'active_support/core_ext/string/strip'
|
2
|
+
|
3
|
+
module ActiveRecord
|
4
|
+
module ConnectionAdapters
|
5
|
+
class AbstractAdapter
|
6
|
+
class SchemaCreation # :nodoc:
|
7
|
+
def initialize(conn)
|
8
|
+
@conn = conn
|
9
|
+
@cache = {}
|
10
|
+
end
|
11
|
+
|
12
|
+
def accept(o)
|
13
|
+
m = @cache[o.class] ||= "visit_#{o.class.name.split('::').last}"
|
14
|
+
send m, o
|
15
|
+
end
|
16
|
+
|
17
|
+
def visit_AddColumn(o)
|
18
|
+
"ADD #{accept(o)}"
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
def visit_AlterTable(o)
|
24
|
+
sql = "ALTER TABLE #{quote_table_name(o.name)} "
|
25
|
+
sql << o.adds.map { |col| visit_AddColumn col }.join(' ')
|
26
|
+
sql << o.foreign_key_adds.map { |fk| visit_AddForeignKey fk }.join(' ')
|
27
|
+
sql << o.foreign_key_drops.map { |fk| visit_DropForeignKey fk }.join(' ')
|
28
|
+
end
|
29
|
+
|
30
|
+
def visit_ColumnDefinition(o)
|
31
|
+
sql_type = type_to_sql(o.type, o.limit, o.precision, o.scale)
|
32
|
+
column_sql = "#{quote_column_name(o.name)} #{sql_type}"
|
33
|
+
add_column_options!(column_sql, column_options(o)) unless o.primary_key?
|
34
|
+
column_sql
|
35
|
+
end
|
36
|
+
|
37
|
+
def visit_TableDefinition(o)
|
38
|
+
create_sql = "CREATE#{' TEMPORARY' if o.temporary} TABLE "
|
39
|
+
create_sql << "#{quote_table_name(o.name)} "
|
40
|
+
create_sql << "(#{o.columns.map { |c| accept c }.join(', ')}) " unless o.as
|
41
|
+
create_sql << "#{o.options}"
|
42
|
+
create_sql << " AS #{@conn.to_sql(o.as)}" if o.as
|
43
|
+
create_sql
|
44
|
+
end
|
45
|
+
|
46
|
+
def visit_AddForeignKey(o)
|
47
|
+
sql = <<-SQL.strip_heredoc
|
48
|
+
ADD CONSTRAINT #{quote_column_name(o.name)}
|
49
|
+
FOREIGN KEY (#{quote_column_name(o.column)})
|
50
|
+
REFERENCES #{quote_table_name(o.to_table)} (#{quote_column_name(o.primary_key)})
|
51
|
+
SQL
|
52
|
+
sql << " #{action_sql('DELETE', o.on_delete)}" if o.on_delete
|
53
|
+
sql << " #{action_sql('UPDATE', o.on_update)}" if o.on_update
|
54
|
+
sql
|
55
|
+
end
|
56
|
+
|
57
|
+
def visit_DropForeignKey(name)
|
58
|
+
"DROP CONSTRAINT #{quote_column_name(name)}"
|
59
|
+
end
|
60
|
+
|
61
|
+
def column_options(o)
|
62
|
+
column_options = {}
|
63
|
+
column_options[:null] = o.null unless o.null.nil?
|
64
|
+
column_options[:default] = o.default unless o.default.nil?
|
65
|
+
column_options[:column] = o
|
66
|
+
column_options[:first] = o.first
|
67
|
+
column_options[:after] = o.after
|
68
|
+
column_options
|
69
|
+
end
|
70
|
+
|
71
|
+
def quote_column_name(name)
|
72
|
+
@conn.quote_column_name name
|
73
|
+
end
|
74
|
+
|
75
|
+
def quote_table_name(name)
|
76
|
+
@conn.quote_table_name name
|
77
|
+
end
|
78
|
+
|
79
|
+
def type_to_sql(type, limit, precision, scale)
|
80
|
+
@conn.type_to_sql type.to_sym, limit, precision, scale
|
81
|
+
end
|
82
|
+
|
83
|
+
def add_column_options!(sql, options)
|
84
|
+
sql << " DEFAULT #{quote_value(options[:default], options[:column])}" if options_include_default?(options)
|
85
|
+
# must explicitly check for :null to allow change_column to work on migrations
|
86
|
+
if options[:null] == false
|
87
|
+
sql << " NOT NULL"
|
88
|
+
end
|
89
|
+
if options[:auto_increment] == true
|
90
|
+
sql << " AUTO_INCREMENT"
|
91
|
+
end
|
92
|
+
sql
|
93
|
+
end
|
94
|
+
|
95
|
+
def quote_value(value, column)
|
96
|
+
column.sql_type ||= type_to_sql(column.type, column.limit, column.precision, column.scale)
|
97
|
+
column.cast_type ||= type_for_column(column)
|
98
|
+
|
99
|
+
@conn.quote(value, column)
|
100
|
+
end
|
101
|
+
|
102
|
+
def options_include_default?(options)
|
103
|
+
options.include?(:default) && !(options[:null] == false && options[:default].nil?)
|
104
|
+
end
|
105
|
+
|
106
|
+
def action_sql(action, dependency)
|
107
|
+
case dependency
|
108
|
+
when :nullify then "ON #{action} SET NULL"
|
109
|
+
when :cascade then "ON #{action} CASCADE"
|
110
|
+
when :restrict then "ON #{action} RESTRICT"
|
111
|
+
else
|
112
|
+
raise ArgumentError, <<-MSG.strip_heredoc
|
113
|
+
'#{dependency}' is not supported for :on_update or :on_delete.
|
114
|
+
Supported values are: :nullify, :cascade, :restrict
|
115
|
+
MSG
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
def type_for_column(column)
|
120
|
+
@conn.lookup_cast_type(column.sql_type)
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|