activerecord 4.1.16 → 4.2.0.beta1
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 +634 -2185
- data/README.rdoc +15 -10
- data/lib/active_record.rb +2 -1
- data/lib/active_record/aggregations.rb +12 -8
- data/lib/active_record/associations.rb +58 -33
- data/lib/active_record/associations/association.rb +1 -1
- data/lib/active_record/associations/association_scope.rb +53 -21
- data/lib/active_record/associations/belongs_to_association.rb +15 -5
- data/lib/active_record/associations/builder/association.rb +16 -5
- data/lib/active_record/associations/builder/belongs_to.rb +7 -29
- data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +2 -11
- data/lib/active_record/associations/builder/has_one.rb +2 -2
- data/lib/active_record/associations/builder/singular_association.rb +8 -1
- data/lib/active_record/associations/collection_association.rb +32 -44
- data/lib/active_record/associations/collection_proxy.rb +1 -10
- data/lib/active_record/associations/has_many_association.rb +60 -14
- data/lib/active_record/associations/has_many_through_association.rb +34 -23
- data/lib/active_record/associations/has_one_association.rb +0 -1
- data/lib/active_record/associations/join_dependency.rb +7 -9
- data/lib/active_record/associations/join_dependency/join_association.rb +18 -14
- data/lib/active_record/associations/preloader.rb +2 -2
- data/lib/active_record/associations/preloader/association.rb +9 -5
- data/lib/active_record/associations/preloader/through_association.rb +3 -3
- data/lib/active_record/associations/singular_association.rb +16 -1
- data/lib/active_record/associations/through_association.rb +6 -22
- data/lib/active_record/attribute.rb +131 -0
- data/lib/active_record/attribute_assignment.rb +19 -11
- data/lib/active_record/attribute_decorators.rb +66 -0
- data/lib/active_record/attribute_methods.rb +53 -90
- data/lib/active_record/attribute_methods/before_type_cast.rb +2 -2
- data/lib/active_record/attribute_methods/dirty.rb +85 -42
- data/lib/active_record/attribute_methods/primary_key.rb +6 -8
- data/lib/active_record/attribute_methods/read.rb +14 -57
- data/lib/active_record/attribute_methods/serialization.rb +12 -146
- data/lib/active_record/attribute_methods/time_zone_conversion.rb +32 -40
- data/lib/active_record/attribute_methods/write.rb +8 -23
- data/lib/active_record/attribute_set.rb +77 -0
- data/lib/active_record/attribute_set/builder.rb +32 -0
- data/lib/active_record/attributes.rb +122 -0
- data/lib/active_record/autosave_association.rb +11 -21
- data/lib/active_record/base.rb +9 -19
- data/lib/active_record/connection_adapters/abstract/connection_pool.rb +69 -45
- data/lib/active_record/connection_adapters/abstract/database_statements.rb +22 -42
- data/lib/active_record/connection_adapters/abstract/quoting.rb +59 -60
- data/lib/active_record/connection_adapters/abstract/schema_creation.rb +37 -2
- data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +102 -21
- data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +9 -33
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +178 -55
- data/lib/active_record/connection_adapters/abstract/transaction.rb +120 -115
- data/lib/active_record/connection_adapters/abstract_adapter.rb +143 -57
- data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +156 -107
- data/lib/active_record/connection_adapters/column.rb +13 -244
- data/lib/active_record/connection_adapters/connection_specification.rb +6 -20
- data/lib/active_record/connection_adapters/mysql2_adapter.rb +12 -15
- data/lib/active_record/connection_adapters/mysql_adapter.rb +55 -143
- data/lib/active_record/connection_adapters/postgresql/array_parser.rb +15 -27
- data/lib/active_record/connection_adapters/postgresql/column.rb +20 -0
- data/lib/active_record/connection_adapters/postgresql/database_statements.rb +39 -20
- data/lib/active_record/connection_adapters/postgresql/oid.rb +29 -388
- data/lib/active_record/connection_adapters/postgresql/oid/array.rb +96 -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 +14 -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 +27 -0
- data/lib/active_record/connection_adapters/postgresql/oid/decimal.rb +13 -0
- data/lib/active_record/connection_adapters/postgresql/oid/enum.rb +17 -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 +76 -0
- data/lib/active_record/connection_adapters/postgresql/oid/specialized_string.rb +15 -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 +85 -0
- data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +26 -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/quoting.rb +42 -122
- data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +4 -4
- data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +154 -0
- data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +86 -34
- data/lib/active_record/connection_adapters/postgresql/utils.rb +66 -0
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +188 -452
- data/lib/active_record/connection_adapters/schema_cache.rb +14 -28
- data/lib/active_record/connection_adapters/sqlite3_adapter.rb +54 -47
- data/lib/active_record/connection_handling.rb +1 -1
- data/lib/active_record/core.rb +119 -22
- data/lib/active_record/counter_cache.rb +60 -6
- data/lib/active_record/enum.rb +9 -10
- data/lib/active_record/errors.rb +27 -26
- data/lib/active_record/explain.rb +1 -1
- data/lib/active_record/fixtures.rb +52 -45
- data/lib/active_record/gem_version.rb +3 -3
- data/lib/active_record/inheritance.rb +33 -8
- data/lib/active_record/integration.rb +4 -4
- data/lib/active_record/locking/optimistic.rb +34 -16
- data/lib/active_record/migration.rb +22 -32
- data/lib/active_record/migration/command_recorder.rb +19 -2
- data/lib/active_record/migration/join_table.rb +1 -1
- data/lib/active_record/model_schema.rb +39 -48
- data/lib/active_record/nested_attributes.rb +8 -18
- data/lib/active_record/persistence.rb +39 -22
- data/lib/active_record/query_cache.rb +3 -3
- data/lib/active_record/querying.rb +1 -8
- data/lib/active_record/railtie.rb +17 -10
- data/lib/active_record/railties/databases.rake +47 -42
- data/lib/active_record/readonly_attributes.rb +0 -1
- data/lib/active_record/reflection.rb +225 -92
- data/lib/active_record/relation.rb +35 -11
- data/lib/active_record/relation/batches.rb +0 -2
- data/lib/active_record/relation/calculations.rb +28 -32
- data/lib/active_record/relation/delegation.rb +1 -1
- data/lib/active_record/relation/finder_methods.rb +42 -20
- data/lib/active_record/relation/merger.rb +0 -1
- data/lib/active_record/relation/predicate_builder.rb +1 -22
- data/lib/active_record/relation/predicate_builder/array_handler.rb +16 -11
- data/lib/active_record/relation/predicate_builder/relation_handler.rb +0 -4
- data/lib/active_record/relation/query_methods.rb +98 -62
- data/lib/active_record/relation/spawn_methods.rb +6 -7
- data/lib/active_record/result.rb +16 -9
- data/lib/active_record/sanitization.rb +8 -1
- data/lib/active_record/schema.rb +0 -1
- data/lib/active_record/schema_dumper.rb +51 -9
- data/lib/active_record/schema_migration.rb +4 -0
- data/lib/active_record/scoping/default.rb +5 -4
- data/lib/active_record/serializers/xml_serializer.rb +3 -7
- data/lib/active_record/statement_cache.rb +79 -5
- data/lib/active_record/store.rb +5 -5
- data/lib/active_record/tasks/database_tasks.rb +37 -5
- data/lib/active_record/tasks/mysql_database_tasks.rb +10 -16
- data/lib/active_record/tasks/postgresql_database_tasks.rb +2 -2
- data/lib/active_record/timestamp.rb +9 -7
- data/lib/active_record/transactions.rb +35 -21
- data/lib/active_record/type.rb +20 -0
- data/lib/active_record/type/binary.rb +40 -0
- data/lib/active_record/type/boolean.rb +19 -0
- data/lib/active_record/type/date.rb +46 -0
- data/lib/active_record/type/date_time.rb +43 -0
- data/lib/active_record/type/decimal.rb +40 -0
- data/lib/active_record/type/decimal_without_scale.rb +11 -0
- data/lib/active_record/type/float.rb +19 -0
- data/lib/active_record/type/hash_lookup_type_map.rb +19 -0
- data/lib/active_record/type/integer.rb +23 -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 +51 -0
- data/lib/active_record/type/string.rb +36 -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 +48 -0
- data/lib/active_record/type/value.rb +101 -0
- data/lib/active_record/validations.rb +21 -16
- data/lib/active_record/validations/uniqueness.rb +9 -23
- data/lib/rails/generators/active_record/migration/migration_generator.rb +8 -4
- data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb +1 -1
- data/lib/rails/generators/active_record/model/templates/model.rb +1 -1
- metadata +71 -14
- data/lib/active_record/connection_adapters/postgresql/cast.rb +0 -168
@@ -92,7 +92,7 @@ module ActiveRecord
|
|
92
92
|
|
93
93
|
table = Arel::Table.new(table_name, arel_engine).alias(default_table_name)
|
94
94
|
PredicateBuilder.build_from_hash(self, attrs, table).map { |b|
|
95
|
-
connection.visitor.
|
95
|
+
connection.visitor.compile b
|
96
96
|
}.join(' AND ')
|
97
97
|
end
|
98
98
|
alias_method :sanitize_sql_hash, :sanitize_sql_hash_for_conditions
|
@@ -107,6 +107,13 @@ module ActiveRecord
|
|
107
107
|
end.join(', ')
|
108
108
|
end
|
109
109
|
|
110
|
+
# Sanitizes a +string+ so that it is safe to use within an SQL
|
111
|
+
# LIKE statement. This method uses +escape_character+ to escape all occurrences of "\", "_" and "%"
|
112
|
+
def sanitize_sql_like(string, escape_character = "\\")
|
113
|
+
pattern = Regexp.union(escape_character, "%", "_")
|
114
|
+
string.gsub(pattern) { |x| [escape_character, x].join }
|
115
|
+
end
|
116
|
+
|
110
117
|
# Accepts an array of conditions. The array has each value
|
111
118
|
# sanitized and interpolated into the SQL statement.
|
112
119
|
# ["name='%s' and group_id='%s'", "foo'bar", 4] returns "name='foo''bar' and group_id='4'"
|
data/lib/active_record/schema.rb
CHANGED
@@ -91,16 +91,17 @@ HEADER
|
|
91
91
|
end
|
92
92
|
|
93
93
|
def tables(stream)
|
94
|
-
@connection.tables.sort
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
94
|
+
sorted_tables = @connection.tables.sort
|
95
|
+
|
96
|
+
sorted_tables.each do |table_name|
|
97
|
+
table(table_name, stream) unless ignored?(table_name)
|
98
|
+
end
|
99
|
+
|
100
|
+
# dump foreign keys at the end to make sure all dependent tables exist.
|
101
|
+
if @connection.supports_foreign_keys?
|
102
|
+
sorted_tables.each do |tbl|
|
103
|
+
foreign_keys(tbl, stream)
|
102
104
|
end
|
103
|
-
table(tbl, stream)
|
104
105
|
end
|
105
106
|
end
|
106
107
|
|
@@ -213,8 +214,49 @@ HEADER
|
|
213
214
|
end
|
214
215
|
end
|
215
216
|
|
217
|
+
def foreign_keys(table, stream)
|
218
|
+
if (foreign_keys = @connection.foreign_keys(table)).any?
|
219
|
+
add_foreign_key_statements = foreign_keys.map do |foreign_key|
|
220
|
+
parts = [
|
221
|
+
'add_foreign_key ' + remove_prefix_and_suffix(foreign_key.from_table).inspect,
|
222
|
+
remove_prefix_and_suffix(foreign_key.to_table).inspect,
|
223
|
+
]
|
224
|
+
|
225
|
+
if foreign_key.column != @connection.foreign_key_column_for(foreign_key.to_table)
|
226
|
+
parts << ('column: ' + foreign_key.column.inspect)
|
227
|
+
end
|
228
|
+
|
229
|
+
if foreign_key.custom_primary_key?
|
230
|
+
parts << ('primary_key: ' + foreign_key.primary_key.inspect)
|
231
|
+
end
|
232
|
+
|
233
|
+
if foreign_key.name !~ /^fk_rails_[0-9a-f]{10}$/
|
234
|
+
parts << ('name: ' + foreign_key.name.inspect)
|
235
|
+
end
|
236
|
+
|
237
|
+
parts << ('on_update: ' + foreign_key.on_update.inspect) if foreign_key.on_update
|
238
|
+
parts << ('on_delete: ' + foreign_key.on_delete.inspect) if foreign_key.on_delete
|
239
|
+
|
240
|
+
' ' + parts.join(', ')
|
241
|
+
end
|
242
|
+
|
243
|
+
stream.puts add_foreign_key_statements.sort.join("\n")
|
244
|
+
end
|
245
|
+
end
|
246
|
+
|
216
247
|
def remove_prefix_and_suffix(table)
|
217
248
|
table.gsub(/^(#{@options[:table_name_prefix]})(.+)(#{@options[:table_name_suffix]})$/, "\\2")
|
218
249
|
end
|
250
|
+
|
251
|
+
def ignored?(table_name)
|
252
|
+
['schema_migrations', ignore_tables].flatten.any? do |ignored|
|
253
|
+
case ignored
|
254
|
+
when String; remove_prefix_and_suffix(table_name) == ignored
|
255
|
+
when Regexp; remove_prefix_and_suffix(table_name) =~ ignored
|
256
|
+
else
|
257
|
+
raise StandardError, 'ActiveRecord::SchemaDumper.ignore_tables accepts an array of String and / or Regexp values.'
|
258
|
+
end
|
259
|
+
end
|
260
|
+
end
|
219
261
|
end
|
220
262
|
end
|
@@ -11,7 +11,7 @@ module ActiveRecord
|
|
11
11
|
end
|
12
12
|
|
13
13
|
module ClassMethods
|
14
|
-
# Returns a scope for the model without the
|
14
|
+
# Returns a scope for the model without the previously set scopes.
|
15
15
|
#
|
16
16
|
# class Post < ActiveRecord::Base
|
17
17
|
# def self.default_scope
|
@@ -19,11 +19,12 @@ module ActiveRecord
|
|
19
19
|
# end
|
20
20
|
# end
|
21
21
|
#
|
22
|
-
# Post.all
|
23
|
-
# Post.unscoped.all
|
22
|
+
# Post.all # Fires "SELECT * FROM posts WHERE published = true"
|
23
|
+
# Post.unscoped.all # Fires "SELECT * FROM posts"
|
24
|
+
# Post.where(published: false).unscoped.all # Fires "SELECT * FROM posts"
|
24
25
|
#
|
25
26
|
# This method also accepts a block. All queries inside the block will
|
26
|
-
# not use the
|
27
|
+
# not use the previously set scopes.
|
27
28
|
#
|
28
29
|
# Post.unscoped {
|
29
30
|
# Post.limit(10) # Fires "SELECT * FROM posts LIMIT 10"
|
@@ -180,13 +180,9 @@ module ActiveRecord #:nodoc:
|
|
180
180
|
class Attribute < ActiveModel::Serializers::Xml::Serializer::Attribute #:nodoc:
|
181
181
|
def compute_type
|
182
182
|
klass = @serializable.class
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
klass.columns_hash[name].type
|
187
|
-
else
|
188
|
-
NilClass
|
189
|
-
end
|
183
|
+
column = klass.columns_hash[name] || Type::Value.new
|
184
|
+
|
185
|
+
type = ActiveSupport::XmlMini::TYPE_NAMES[value.class.name] || column.type
|
190
186
|
|
191
187
|
{ :text => :string,
|
192
188
|
:time => :datetime }[type] || type
|
@@ -14,13 +14,87 @@ module ActiveRecord
|
|
14
14
|
# The relation returned by the block is cached, and for each +execute+ call the cached relation gets duped.
|
15
15
|
# Database is queried when +to_a+ is called on the relation.
|
16
16
|
class StatementCache
|
17
|
-
|
18
|
-
|
19
|
-
|
17
|
+
class Substitute; end
|
18
|
+
|
19
|
+
class Query
|
20
|
+
def initialize(sql)
|
21
|
+
@sql = sql
|
22
|
+
end
|
23
|
+
|
24
|
+
def sql_for(binds, connection)
|
25
|
+
@sql
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
class PartialQuery < Query
|
30
|
+
def initialize values
|
31
|
+
@values = values
|
32
|
+
@indexes = values.each_with_index.find_all { |thing,i|
|
33
|
+
Arel::Nodes::BindParam === thing
|
34
|
+
}.map(&:last)
|
35
|
+
end
|
36
|
+
|
37
|
+
def sql_for(binds, connection)
|
38
|
+
val = @values.dup
|
39
|
+
binds = binds.dup
|
40
|
+
@indexes.each { |i| val[i] = connection.quote(*binds.shift.reverse) }
|
41
|
+
val.join
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def self.query(visitor, ast)
|
46
|
+
Query.new visitor.accept(ast, Arel::Collectors::SQLString.new).value
|
47
|
+
end
|
48
|
+
|
49
|
+
def self.partial_query(visitor, ast, collector)
|
50
|
+
collected = visitor.accept(ast, collector).value
|
51
|
+
PartialQuery.new collected
|
52
|
+
end
|
53
|
+
|
54
|
+
class Params
|
55
|
+
def bind; Substitute.new; end
|
20
56
|
end
|
21
57
|
|
22
|
-
|
23
|
-
|
58
|
+
class BindMap
|
59
|
+
def initialize(bind_values)
|
60
|
+
@indexes = []
|
61
|
+
@bind_values = bind_values
|
62
|
+
|
63
|
+
bind_values.each_with_index do |(_, value), i|
|
64
|
+
if Substitute === value
|
65
|
+
@indexes << i
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
def bind(values)
|
71
|
+
bvs = @bind_values.map { |pair| pair.dup }
|
72
|
+
@indexes.each_with_index { |offset,i| bvs[offset][1] = values[i] }
|
73
|
+
bvs
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
attr_reader :bind_map, :query_builder
|
78
|
+
|
79
|
+
def self.create(connection, block = Proc.new)
|
80
|
+
relation = block.call Params.new
|
81
|
+
bind_map = BindMap.new relation.bind_values
|
82
|
+
query_builder = connection.cacheable_query relation.arel
|
83
|
+
new query_builder, bind_map
|
84
|
+
end
|
85
|
+
|
86
|
+
def initialize(query_builder, bind_map)
|
87
|
+
@query_builder = query_builder
|
88
|
+
@bind_map = bind_map
|
89
|
+
end
|
90
|
+
|
91
|
+
def execute(params, klass, connection)
|
92
|
+
bind_values = bind_map.bind params
|
93
|
+
|
94
|
+
sql = query_builder.sql_for bind_values, connection
|
95
|
+
|
96
|
+
klass.find_by_sql sql, bind_values
|
24
97
|
end
|
98
|
+
alias :call :execute
|
25
99
|
end
|
26
100
|
end
|
data/lib/active_record/store.rb
CHANGED
@@ -99,7 +99,7 @@ module ActiveRecord
|
|
99
99
|
self.local_stored_attributes[store_attribute] |= keys
|
100
100
|
end
|
101
101
|
|
102
|
-
def _store_accessors_module
|
102
|
+
def _store_accessors_module # :nodoc:
|
103
103
|
@_store_accessors_module ||= begin
|
104
104
|
mod = Module.new
|
105
105
|
include mod
|
@@ -129,10 +129,10 @@ module ActiveRecord
|
|
129
129
|
|
130
130
|
private
|
131
131
|
def store_accessor_for(store_attribute)
|
132
|
-
|
132
|
+
type_for_attribute(store_attribute.to_s).accessor
|
133
133
|
end
|
134
134
|
|
135
|
-
class HashAccessor
|
135
|
+
class HashAccessor # :nodoc:
|
136
136
|
def self.read(object, attribute, key)
|
137
137
|
prepare(object, attribute)
|
138
138
|
object.public_send(attribute)[key]
|
@@ -151,7 +151,7 @@ module ActiveRecord
|
|
151
151
|
end
|
152
152
|
end
|
153
153
|
|
154
|
-
class StringKeyedHashAccessor < HashAccessor
|
154
|
+
class StringKeyedHashAccessor < HashAccessor # :nodoc:
|
155
155
|
def self.read(object, attribute, key)
|
156
156
|
super object, attribute, key.to_s
|
157
157
|
end
|
@@ -161,7 +161,7 @@ module ActiveRecord
|
|
161
161
|
end
|
162
162
|
end
|
163
163
|
|
164
|
-
class IndifferentHashAccessor < ActiveRecord::Store::HashAccessor
|
164
|
+
class IndifferentHashAccessor < ActiveRecord::Store::HashAccessor # :nodoc:
|
165
165
|
def self.prepare(object, store_attribute)
|
166
166
|
attribute = object.send(store_attribute)
|
167
167
|
unless attribute.is_a?(ActiveSupport::HashWithIndifferentAccess)
|
@@ -6,7 +6,7 @@ module ActiveRecord
|
|
6
6
|
# <tt>ActiveRecord::Tasks::DatabaseTasks</tt> is a utility class, which encapsulates
|
7
7
|
# logic behind common tasks used to manage database and migrations.
|
8
8
|
#
|
9
|
-
# The tasks defined here are used
|
9
|
+
# The tasks defined here are used with Rake tasks provided by Active Record.
|
10
10
|
#
|
11
11
|
# In order to use DatabaseTasks, a few config values need to be set. All the needed
|
12
12
|
# config values are set by Rails already, so it's necessary to do it only if you
|
@@ -14,7 +14,6 @@ module ActiveRecord
|
|
14
14
|
# (in such case after configuring the database tasks, you can also use the rake tasks
|
15
15
|
# defined in Active Record).
|
16
16
|
#
|
17
|
-
#
|
18
17
|
# The possible config values are:
|
19
18
|
#
|
20
19
|
# * +env+: current environment (like Rails.env).
|
@@ -28,7 +27,7 @@ module ActiveRecord
|
|
28
27
|
# Example usage of +DatabaseTasks+ outside Rails could look as such:
|
29
28
|
#
|
30
29
|
# include ActiveRecord::Tasks
|
31
|
-
# DatabaseTasks.database_configuration = YAML.
|
30
|
+
# DatabaseTasks.database_configuration = YAML.load_file('my_database_config.yml')
|
32
31
|
# DatabaseTasks.db_dir = 'db'
|
33
32
|
# # other settings...
|
34
33
|
#
|
@@ -59,7 +58,11 @@ module ActiveRecord
|
|
59
58
|
end
|
60
59
|
|
61
60
|
def fixtures_path
|
62
|
-
@fixtures_path ||=
|
61
|
+
@fixtures_path ||= if ENV['FIXTURES_PATH']
|
62
|
+
File.join(root, ENV['FIXTURES_PATH'])
|
63
|
+
else
|
64
|
+
File.join(root, 'test', 'fixtures')
|
65
|
+
end
|
63
66
|
end
|
64
67
|
|
65
68
|
def root
|
@@ -107,6 +110,8 @@ module ActiveRecord
|
|
107
110
|
def drop(*arguments)
|
108
111
|
configuration = arguments.first
|
109
112
|
class_for_adapter(configuration['adapter']).new(*arguments).drop
|
113
|
+
rescue ActiveRecord::NoDatabaseError
|
114
|
+
$stderr.puts "Database '#{configuration['database']}' does not exist"
|
110
115
|
rescue Exception => error
|
111
116
|
$stderr.puts error, *(error.backtrace)
|
112
117
|
$stderr.puts "Couldn't drop #{configuration['database']}"
|
@@ -122,6 +127,16 @@ module ActiveRecord
|
|
122
127
|
}
|
123
128
|
end
|
124
129
|
|
130
|
+
def migrate
|
131
|
+
verbose = ENV["VERBOSE"] ? ENV["VERBOSE"] == "true" : true
|
132
|
+
version = ENV["VERSION"] ? ENV["VERSION"].to_i : nil
|
133
|
+
scope = ENV['SCOPE']
|
134
|
+
Migration.verbose = verbose
|
135
|
+
Migrator.migrate(Migrator.migrations_paths, version) do |migration|
|
136
|
+
scope.blank? || scope == migration.scope
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
125
140
|
def charset_current(environment = env)
|
126
141
|
charset ActiveRecord::Base.configurations[environment]
|
127
142
|
end
|
@@ -144,6 +159,18 @@ module ActiveRecord
|
|
144
159
|
class_for_adapter(configuration['adapter']).new(configuration).purge
|
145
160
|
end
|
146
161
|
|
162
|
+
def purge_all
|
163
|
+
each_local_configuration { |configuration|
|
164
|
+
purge configuration
|
165
|
+
}
|
166
|
+
end
|
167
|
+
|
168
|
+
def purge_current(environment = env)
|
169
|
+
each_current_configuration(environment) { |configuration|
|
170
|
+
purge configuration
|
171
|
+
}
|
172
|
+
end
|
173
|
+
|
147
174
|
def structure_dump(*arguments)
|
148
175
|
configuration = arguments.first
|
149
176
|
filename = arguments.delete_at 1
|
@@ -157,6 +184,10 @@ module ActiveRecord
|
|
157
184
|
end
|
158
185
|
|
159
186
|
def load_schema(format = ActiveRecord::Base.schema_format, file = nil)
|
187
|
+
ActiveSupport::Deprecation.warn(<<-MESSAGE.strip_heredoc)
|
188
|
+
This method will act on a specific connection in the future.
|
189
|
+
To act on the current connection, use `load_schema_current` instead.
|
190
|
+
MESSAGE
|
160
191
|
load_schema_current(format, file)
|
161
192
|
end
|
162
193
|
|
@@ -167,11 +198,13 @@ module ActiveRecord
|
|
167
198
|
when :ruby
|
168
199
|
file ||= File.join(db_dir, "schema.rb")
|
169
200
|
check_schema_file(file)
|
201
|
+
purge(configuration)
|
170
202
|
ActiveRecord::Base.establish_connection(configuration)
|
171
203
|
load(file)
|
172
204
|
when :sql
|
173
205
|
file ||= File.join(db_dir, "structure.sql")
|
174
206
|
check_schema_file(file)
|
207
|
+
purge(configuration)
|
175
208
|
structure_load(configuration, file)
|
176
209
|
else
|
177
210
|
raise ArgumentError, "unknown format #{format.inspect}"
|
@@ -182,7 +215,6 @@ module ActiveRecord
|
|
182
215
|
each_current_configuration(environment) { |configuration|
|
183
216
|
load_schema_for configuration, format, file
|
184
217
|
}
|
185
|
-
ActiveRecord::Base.establish_connection(environment.to_sym)
|
186
218
|
end
|
187
219
|
|
188
220
|
def check_schema_file(filename)
|
@@ -124,26 +124,20 @@ IDENTIFIED BY '#{configuration['password']}' WITH GRANT OPTION;
|
|
124
124
|
end
|
125
125
|
|
126
126
|
def root_password
|
127
|
-
$stdout.print "Please provide the root password for your
|
127
|
+
$stdout.print "Please provide the root password for your MySQL installation\n>"
|
128
128
|
$stdin.gets.strip
|
129
129
|
end
|
130
130
|
|
131
131
|
def prepare_command_options(command)
|
132
|
-
args =
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
'sslcapath' => '--ssl-capath',
|
142
|
-
'sslcipher' => '--ssl-cipher',
|
143
|
-
'sslkey' => '--ssl-key'
|
144
|
-
}.map { |opt, arg| "#{arg}=#{configuration[opt]}" if configuration[opt] }.compact
|
145
|
-
|
146
|
-
[command, *args]
|
132
|
+
args = [command]
|
133
|
+
args.concat(['--user', configuration['username']]) if configuration['username']
|
134
|
+
args << "--password=#{configuration['password']}" if configuration['password']
|
135
|
+
args.concat(['--default-character-set', configuration['encoding']]) if configuration['encoding']
|
136
|
+
configuration.slice('host', 'port', 'socket').each do |k, v|
|
137
|
+
args.concat([ "--#{k}", v.to_s ]) if v
|
138
|
+
end
|
139
|
+
|
140
|
+
args
|
147
141
|
end
|
148
142
|
end
|
149
143
|
end
|
@@ -51,10 +51,10 @@ module ActiveRecord
|
|
51
51
|
search_path = search_path.split(",").map{|search_path_part| "--schema=#{Shellwords.escape(search_path_part.strip)}" }.join(" ")
|
52
52
|
end
|
53
53
|
|
54
|
-
command = "pg_dump -s -x -O -f #{Shellwords.escape(filename)} #{search_path} #{Shellwords.escape(configuration['database'])}"
|
54
|
+
command = "pg_dump -i -s -x -O -f #{Shellwords.escape(filename)} #{search_path} #{Shellwords.escape(configuration['database'])}"
|
55
55
|
raise 'Error dumping database' unless Kernel.system(command)
|
56
56
|
|
57
|
-
File.open(filename, "a") { |f| f << "SET search_path TO #{
|
57
|
+
File.open(filename, "a") { |f| f << "SET search_path TO #{connection.schema_search_path};\n\n" }
|
58
58
|
end
|
59
59
|
|
60
60
|
def structure_load(filename)
|