activerecord 4.0.13 → 4.1.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 +745 -2700
- data/README.rdoc +2 -2
- data/examples/performance.rb +30 -18
- data/examples/simple.rb +4 -4
- data/lib/active_record.rb +2 -6
- data/lib/active_record/aggregations.rb +2 -1
- data/lib/active_record/association_relation.rb +0 -4
- data/lib/active_record/associations.rb +87 -43
- data/lib/active_record/associations/alias_tracker.rb +1 -3
- data/lib/active_record/associations/association.rb +8 -16
- data/lib/active_record/associations/association_scope.rb +5 -16
- data/lib/active_record/associations/belongs_to_association.rb +34 -25
- data/lib/active_record/associations/belongs_to_polymorphic_association.rb +1 -1
- data/lib/active_record/associations/builder/association.rb +78 -54
- data/lib/active_record/associations/builder/belongs_to.rb +91 -58
- data/lib/active_record/associations/builder/collection_association.rb +47 -45
- data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +107 -25
- data/lib/active_record/associations/builder/has_many.rb +2 -2
- data/lib/active_record/associations/builder/has_one.rb +5 -7
- data/lib/active_record/associations/builder/singular_association.rb +6 -7
- data/lib/active_record/associations/collection_association.rb +68 -105
- data/lib/active_record/associations/collection_proxy.rb +12 -15
- data/lib/active_record/associations/has_many_association.rb +11 -9
- data/lib/active_record/associations/has_many_through_association.rb +16 -12
- data/lib/active_record/associations/has_one_association.rb +1 -1
- data/lib/active_record/associations/join_dependency.rb +204 -165
- data/lib/active_record/associations/join_dependency/join_association.rb +43 -101
- data/lib/active_record/associations/join_dependency/join_base.rb +6 -8
- data/lib/active_record/associations/join_dependency/join_part.rb +18 -37
- data/lib/active_record/associations/join_helper.rb +2 -11
- data/lib/active_record/associations/preloader.rb +89 -34
- data/lib/active_record/associations/preloader/association.rb +43 -25
- data/lib/active_record/associations/preloader/collection_association.rb +2 -2
- data/lib/active_record/associations/preloader/has_many_through.rb +1 -1
- data/lib/active_record/associations/preloader/singular_association.rb +3 -3
- data/lib/active_record/associations/preloader/through_association.rb +58 -26
- data/lib/active_record/associations/singular_association.rb +6 -5
- data/lib/active_record/associations/through_association.rb +2 -2
- data/lib/active_record/attribute_assignment.rb +5 -2
- data/lib/active_record/attribute_methods.rb +45 -40
- data/lib/active_record/attribute_methods/before_type_cast.rb +2 -1
- data/lib/active_record/attribute_methods/dirty.rb +8 -22
- data/lib/active_record/attribute_methods/primary_key.rb +1 -7
- data/lib/active_record/attribute_methods/read.rb +55 -28
- data/lib/active_record/attribute_methods/serialization.rb +12 -33
- data/lib/active_record/attribute_methods/time_zone_conversion.rb +1 -13
- data/lib/active_record/attribute_methods/write.rb +37 -12
- data/lib/active_record/autosave_association.rb +207 -207
- data/lib/active_record/base.rb +5 -1
- data/lib/active_record/callbacks.rb +2 -2
- data/lib/active_record/connection_adapters/abstract/connection_pool.rb +2 -7
- data/lib/active_record/connection_adapters/abstract/database_statements.rb +11 -22
- data/lib/active_record/connection_adapters/abstract/query_cache.rb +12 -14
- data/lib/active_record/connection_adapters/abstract/quoting.rb +1 -5
- data/lib/active_record/connection_adapters/abstract/savepoints.rb +21 -0
- data/lib/active_record/connection_adapters/abstract/schema_creation.rb +84 -0
- data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +9 -8
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +52 -83
- data/lib/active_record/connection_adapters/abstract/transaction.rb +0 -5
- data/lib/active_record/connection_adapters/abstract_adapter.rb +14 -97
- data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +58 -60
- data/lib/active_record/connection_adapters/column.rb +1 -35
- data/lib/active_record/connection_adapters/connection_specification.rb +2 -2
- data/lib/active_record/connection_adapters/mysql2_adapter.rb +3 -4
- data/lib/active_record/connection_adapters/mysql_adapter.rb +16 -15
- data/lib/active_record/connection_adapters/postgresql/array_parser.rb +24 -18
- data/lib/active_record/connection_adapters/postgresql/cast.rb +20 -16
- data/lib/active_record/connection_adapters/postgresql/database_statements.rb +23 -43
- data/lib/active_record/connection_adapters/postgresql/oid.rb +19 -12
- data/lib/active_record/connection_adapters/postgresql/quoting.rb +28 -23
- data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +8 -30
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +92 -75
- data/lib/active_record/connection_adapters/schema_cache.rb +8 -29
- data/lib/active_record/connection_adapters/sqlite3_adapter.rb +31 -64
- data/lib/active_record/connection_handling.rb +2 -2
- data/lib/active_record/core.rb +22 -43
- data/lib/active_record/counter_cache.rb +7 -7
- data/lib/active_record/enum.rb +100 -0
- data/lib/active_record/errors.rb +10 -5
- data/lib/active_record/fixture_set/file.rb +2 -1
- data/lib/active_record/fixtures.rb +171 -74
- data/lib/active_record/inheritance.rb +16 -22
- data/lib/active_record/integration.rb +52 -1
- data/lib/active_record/locking/optimistic.rb +7 -2
- data/lib/active_record/locking/pessimistic.rb +1 -1
- data/lib/active_record/log_subscriber.rb +5 -12
- data/lib/active_record/migration.rb +62 -46
- data/lib/active_record/migration/command_recorder.rb +7 -13
- data/lib/active_record/model_schema.rb +7 -14
- data/lib/active_record/nested_attributes.rb +10 -8
- data/lib/active_record/no_touching.rb +52 -0
- data/lib/active_record/null_relation.rb +3 -3
- data/lib/active_record/persistence.rb +16 -34
- data/lib/active_record/querying.rb +14 -12
- data/lib/active_record/railtie.rb +0 -50
- data/lib/active_record/railties/databases.rake +12 -15
- data/lib/active_record/readonly_attributes.rb +0 -6
- data/lib/active_record/reflection.rb +189 -75
- data/lib/active_record/relation.rb +69 -94
- data/lib/active_record/relation/batches.rb +57 -23
- data/lib/active_record/relation/calculations.rb +36 -43
- data/lib/active_record/relation/delegation.rb +54 -39
- data/lib/active_record/relation/finder_methods.rb +107 -62
- data/lib/active_record/relation/merger.rb +7 -20
- data/lib/active_record/relation/predicate_builder.rb +57 -38
- data/lib/active_record/relation/predicate_builder/array_handler.rb +29 -0
- data/lib/active_record/relation/predicate_builder/relation_handler.rb +13 -0
- data/lib/active_record/relation/query_methods.rb +110 -98
- data/lib/active_record/relation/spawn_methods.rb +1 -2
- data/lib/active_record/result.rb +45 -6
- data/lib/active_record/runtime_registry.rb +5 -0
- data/lib/active_record/sanitization.rb +6 -8
- data/lib/active_record/schema_dumper.rb +16 -5
- data/lib/active_record/schema_migration.rb +24 -25
- data/lib/active_record/scoping/default.rb +5 -18
- data/lib/active_record/scoping/named.rb +8 -29
- data/lib/active_record/store.rb +56 -28
- data/lib/active_record/tasks/database_tasks.rb +8 -4
- data/lib/active_record/timestamp.rb +4 -4
- data/lib/active_record/transactions.rb +8 -10
- data/lib/active_record/validations/presence.rb +1 -1
- data/lib/active_record/validations/uniqueness.rb +1 -6
- data/lib/active_record/version.rb +1 -1
- data/lib/rails/generators/active_record.rb +2 -8
- data/lib/rails/generators/active_record/migration.rb +18 -0
- data/lib/rails/generators/active_record/migration/migration_generator.rb +4 -0
- data/lib/rails/generators/active_record/model/model_generator.rb +4 -0
- metadata +32 -45
- data/lib/active_record/associations/has_and_belongs_to_many_association.rb +0 -65
- data/lib/active_record/associations/preloader/has_and_belongs_to_many.rb +0 -60
- data/lib/active_record/tasks/firebird_database_tasks.rb +0 -56
- data/lib/active_record/tasks/oracle_database_tasks.rb +0 -45
- data/lib/active_record/tasks/sqlserver_database_tasks.rb +0 -48
- data/lib/active_record/test_case.rb +0 -102
@@ -55,7 +55,7 @@ module ActiveRecord
|
|
55
55
|
begin
|
56
56
|
require path_to_adapter
|
57
57
|
rescue Gem::LoadError => e
|
58
|
-
raise Gem::LoadError, "Specified '#{spec[:adapter]}' for database adapter, but the gem is not loaded. Add `gem '#{e.name}'` to your Gemfile."
|
58
|
+
raise Gem::LoadError, "Specified '#{spec[:adapter]}' for database adapter, but the gem is not loaded. Add `gem '#{e.name}'` to your Gemfile (and ensure its version is at the minimum required by ActiveRecord)."
|
59
59
|
rescue LoadError => e
|
60
60
|
raise LoadError, "Could not load '#{path_to_adapter}'. Make sure that the adapter in config/database.yml is valid. If you use an adapter other than 'mysql', 'mysql2', 'postgresql' or 'sqlite3' add the necessary adapter gem to the Gemfile.", e.backtrace
|
61
61
|
end
|
@@ -74,7 +74,7 @@ module ActiveRecord
|
|
74
74
|
:password => config.password,
|
75
75
|
:port => config.port,
|
76
76
|
:database => config.path.sub(%r{^/},""),
|
77
|
-
:host => config.
|
77
|
+
:host => config.host }
|
78
78
|
|
79
79
|
spec.reject!{ |_,value| value.blank? }
|
80
80
|
|
@@ -1,6 +1,6 @@
|
|
1
1
|
require 'active_record/connection_adapters/abstract_mysql_adapter'
|
2
2
|
|
3
|
-
gem 'mysql2', '~> 0.3.
|
3
|
+
gem 'mysql2', '~> 0.3.13'
|
4
4
|
require 'mysql2'
|
5
5
|
|
6
6
|
module ActiveRecord
|
@@ -207,7 +207,7 @@ module ActiveRecord
|
|
207
207
|
|
208
208
|
# Returns an array of arrays containing the field values.
|
209
209
|
# Order is the same as that returned by +columns+.
|
210
|
-
def select_rows(sql, name = nil
|
210
|
+
def select_rows(sql, name = nil)
|
211
211
|
execute(sql, name).to_a
|
212
212
|
end
|
213
213
|
|
@@ -229,8 +229,7 @@ module ActiveRecord
|
|
229
229
|
|
230
230
|
alias exec_without_stmt exec_query
|
231
231
|
|
232
|
-
# Returns an
|
233
|
-
# column values as values.
|
232
|
+
# Returns an ActiveRecord::Result instance.
|
234
233
|
def select(sql, name = nil, binds = [])
|
235
234
|
exec_query(sql, name)
|
236
235
|
end
|
@@ -160,12 +160,6 @@ module ActiveRecord
|
|
160
160
|
|
161
161
|
# QUOTING ==================================================
|
162
162
|
|
163
|
-
def type_cast(value, column)
|
164
|
-
return super unless value == true || value == false
|
165
|
-
|
166
|
-
value ? 1 : 0
|
167
|
-
end
|
168
|
-
|
169
163
|
def quote_string(string) #:nodoc:
|
170
164
|
@connection.quote(string)
|
171
165
|
end
|
@@ -213,9 +207,9 @@ module ActiveRecord
|
|
213
207
|
|
214
208
|
# DATABASE STATEMENTS ======================================
|
215
209
|
|
216
|
-
def select_rows(sql, name = nil
|
210
|
+
def select_rows(sql, name = nil)
|
217
211
|
@connection.query_with_result = true
|
218
|
-
rows = exec_query(sql, name
|
212
|
+
rows = exec_query(sql, name).rows
|
219
213
|
@connection.more_results && @connection.next_result # invoking stored procedures with CLIENT_MULTI_RESULTS requires this to tidy up else connection will be dropped
|
220
214
|
rows
|
221
215
|
end
|
@@ -425,14 +419,19 @@ module ActiveRecord
|
|
425
419
|
|
426
420
|
if result
|
427
421
|
types = {}
|
422
|
+
fields = []
|
428
423
|
result.fetch_fields.each { |field|
|
424
|
+
field_name = field.name
|
425
|
+
fields << field_name
|
426
|
+
|
429
427
|
if field.decimals > 0
|
430
|
-
types[
|
428
|
+
types[field_name] = Fields::Decimal.new
|
431
429
|
else
|
432
|
-
types[
|
430
|
+
types[field_name] = Fields.find_type field
|
433
431
|
end
|
434
432
|
}
|
435
|
-
|
433
|
+
|
434
|
+
result_set = ActiveRecord::Result.new(fields, result.to_a, types)
|
436
435
|
result.free
|
437
436
|
else
|
438
437
|
result_set = ActiveRecord::Result.new([], [])
|
@@ -468,15 +467,17 @@ module ActiveRecord
|
|
468
467
|
|
469
468
|
def begin_db_transaction #:nodoc:
|
470
469
|
exec_query "BEGIN"
|
471
|
-
rescue Mysql::Error
|
472
|
-
# Transactions aren't supported
|
473
470
|
end
|
474
471
|
|
475
472
|
private
|
476
473
|
|
477
474
|
def exec_stmt(sql, name, binds)
|
478
475
|
cache = {}
|
479
|
-
|
476
|
+
type_casted_binds = binds.map { |col, val|
|
477
|
+
[col, type_cast(val, col)]
|
478
|
+
}
|
479
|
+
|
480
|
+
log(sql, name, type_casted_binds) do
|
480
481
|
if binds.empty?
|
481
482
|
stmt = @connection.prepare(sql)
|
482
483
|
else
|
@@ -487,7 +488,7 @@ module ActiveRecord
|
|
487
488
|
end
|
488
489
|
|
489
490
|
begin
|
490
|
-
stmt.execute(*
|
491
|
+
stmt.execute(*type_casted_binds.map { |_, val| val })
|
491
492
|
rescue Mysql::Error => e
|
492
493
|
# Older versions of MySQL leave the prepared statement in a bad
|
493
494
|
# place when an error occurs. To support older mysql versions, we
|
@@ -2,6 +2,13 @@ module ActiveRecord
|
|
2
2
|
module ConnectionAdapters
|
3
3
|
class PostgreSQLColumn < Column
|
4
4
|
module ArrayParser
|
5
|
+
|
6
|
+
DOUBLE_QUOTE = '"'
|
7
|
+
BACKSLASH = "\\"
|
8
|
+
COMMA = ','
|
9
|
+
BRACKET_OPEN = '{'
|
10
|
+
BRACKET_CLOSE = '}'
|
11
|
+
|
5
12
|
private
|
6
13
|
# Loads pg_array_parser if available. String parsing can be
|
7
14
|
# performed quicker by a native extension, which will not create
|
@@ -12,18 +19,18 @@ module ActiveRecord
|
|
12
19
|
include PgArrayParser
|
13
20
|
rescue LoadError
|
14
21
|
def parse_pg_array(string)
|
15
|
-
parse_data(string
|
22
|
+
parse_data(string)
|
16
23
|
end
|
17
24
|
end
|
18
25
|
|
19
|
-
def parse_data(string
|
20
|
-
local_index =
|
26
|
+
def parse_data(string)
|
27
|
+
local_index = 0
|
21
28
|
array = []
|
22
29
|
while(local_index < string.length)
|
23
30
|
case string[local_index]
|
24
|
-
when
|
31
|
+
when BRACKET_OPEN
|
25
32
|
local_index,array = parse_array_contents(array, string, local_index + 1)
|
26
|
-
when
|
33
|
+
when BRACKET_CLOSE
|
27
34
|
return array
|
28
35
|
end
|
29
36
|
local_index += 1
|
@@ -33,9 +40,9 @@ module ActiveRecord
|
|
33
40
|
end
|
34
41
|
|
35
42
|
def parse_array_contents(array, string, index)
|
36
|
-
is_escaping
|
37
|
-
is_quoted
|
38
|
-
was_quoted
|
43
|
+
is_escaping = false
|
44
|
+
is_quoted = false
|
45
|
+
was_quoted = false
|
39
46
|
current_item = ''
|
40
47
|
|
41
48
|
local_index = index
|
@@ -47,29 +54,29 @@ module ActiveRecord
|
|
47
54
|
else
|
48
55
|
if is_quoted
|
49
56
|
case token
|
50
|
-
when
|
57
|
+
when DOUBLE_QUOTE
|
51
58
|
is_quoted = false
|
52
59
|
was_quoted = true
|
53
|
-
when
|
60
|
+
when BACKSLASH
|
54
61
|
is_escaping = true
|
55
62
|
else
|
56
63
|
current_item << token
|
57
64
|
end
|
58
65
|
else
|
59
66
|
case token
|
60
|
-
when
|
67
|
+
when BACKSLASH
|
61
68
|
is_escaping = true
|
62
|
-
when
|
69
|
+
when COMMA
|
63
70
|
add_item_to_array(array, current_item, was_quoted)
|
64
71
|
current_item = ''
|
65
72
|
was_quoted = false
|
66
|
-
when
|
73
|
+
when DOUBLE_QUOTE
|
67
74
|
is_quoted = true
|
68
|
-
when
|
75
|
+
when BRACKET_OPEN
|
69
76
|
internal_items = []
|
70
77
|
local_index,internal_items = parse_array_contents(internal_items, string, local_index + 1)
|
71
78
|
array.push(internal_items)
|
72
|
-
when
|
79
|
+
when BRACKET_CLOSE
|
73
80
|
add_item_to_array(array, current_item, was_quoted)
|
74
81
|
return local_index,array
|
75
82
|
else
|
@@ -84,9 +91,8 @@ module ActiveRecord
|
|
84
91
|
end
|
85
92
|
|
86
93
|
def add_item_to_array(array, current_item, quoted)
|
87
|
-
|
88
|
-
|
89
|
-
if !quoted && current_item == 'NULL'
|
94
|
+
if current_item.length == 0
|
95
|
+
elsif !quoted && current_item == 'NULL'
|
90
96
|
array.push nil
|
91
97
|
else
|
92
98
|
array.push current_item
|
@@ -17,8 +17,8 @@ module ActiveRecord
|
|
17
17
|
return string unless String === string
|
18
18
|
|
19
19
|
case string
|
20
|
-
when 'infinity';
|
21
|
-
when '-infinity'; -
|
20
|
+
when 'infinity'; Float::INFINITY
|
21
|
+
when '-infinity'; -Float::INFINITY
|
22
22
|
when / BC$/
|
23
23
|
super("-" + string.sub(/ BC$/, ""))
|
24
24
|
else
|
@@ -35,11 +35,11 @@ module ActiveRecord
|
|
35
35
|
end
|
36
36
|
end
|
37
37
|
|
38
|
-
def hstore_to_string(object
|
38
|
+
def hstore_to_string(object)
|
39
39
|
if Hash === object
|
40
|
-
|
41
|
-
|
42
|
-
|
40
|
+
object.map { |k,v|
|
41
|
+
"#{escape_hstore(k)}=>#{escape_hstore(v)}"
|
42
|
+
}.join ','
|
43
43
|
else
|
44
44
|
object
|
45
45
|
end
|
@@ -49,10 +49,10 @@ module ActiveRecord
|
|
49
49
|
if string.nil?
|
50
50
|
nil
|
51
51
|
elsif String === string
|
52
|
-
Hash[string.scan(HstorePair).map { |k,
|
52
|
+
Hash[string.scan(HstorePair).map { |k,v|
|
53
53
|
v = v.upcase == 'NULL' ? nil : v.gsub(/\A"(.*)"\Z/m,'\1').gsub(/\\(.)/, '\1')
|
54
54
|
k = k.gsub(/\A"(.*)"\Z/m,'\1').gsub(/\\(.)/, '\1')
|
55
|
-
[k,
|
55
|
+
[k,v]
|
56
56
|
}]
|
57
57
|
else
|
58
58
|
string
|
@@ -67,7 +67,7 @@ module ActiveRecord
|
|
67
67
|
end
|
68
68
|
end
|
69
69
|
|
70
|
-
def array_to_string(value, column, adapter
|
70
|
+
def array_to_string(value, column, adapter)
|
71
71
|
casted_values = value.map do |val|
|
72
72
|
if String === val
|
73
73
|
if val == "NULL"
|
@@ -119,7 +119,7 @@ module ActiveRecord
|
|
119
119
|
end
|
120
120
|
|
121
121
|
def string_to_array(string, oid)
|
122
|
-
parse_pg_array(string).map{|val| oid
|
122
|
+
parse_pg_array(string).map {|val| type_cast_array(oid, val)}
|
123
123
|
end
|
124
124
|
|
125
125
|
private
|
@@ -142,16 +142,20 @@ module ActiveRecord
|
|
142
142
|
end
|
143
143
|
end
|
144
144
|
|
145
|
-
ARRAY_ESCAPE = "\\" * 2 * 2 # escape the backslash twice for PG arrays
|
146
|
-
|
147
145
|
def quote_and_escape(value)
|
148
146
|
case value
|
149
|
-
when "NULL"
|
147
|
+
when "NULL"
|
150
148
|
value
|
151
149
|
else
|
152
|
-
value
|
153
|
-
|
154
|
-
|
150
|
+
"\"#{value.gsub(/"/,"\\\"")}\""
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
def type_cast_array(oid, value)
|
155
|
+
if ::Array === value
|
156
|
+
value.map {|item| type_cast_array(oid, item)}
|
157
|
+
else
|
158
|
+
oid.type_cast value
|
155
159
|
end
|
156
160
|
end
|
157
161
|
end
|
@@ -46,8 +46,8 @@ module ActiveRecord
|
|
46
46
|
|
47
47
|
# Executes a SELECT query and returns an array of rows. Each row is an
|
48
48
|
# array of field values.
|
49
|
-
def select_rows(sql, name = nil
|
50
|
-
|
49
|
+
def select_rows(sql, name = nil)
|
50
|
+
select_raw(sql, name).last
|
51
51
|
end
|
52
52
|
|
53
53
|
# Executes an INSERT query and returns the new record's ID
|
@@ -134,32 +134,31 @@ module ActiveRecord
|
|
134
134
|
end
|
135
135
|
|
136
136
|
def exec_query(sql, name = 'SQL', binds = [])
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
ret = ActiveRecord::Result.new(fields, result.values, types)
|
150
|
-
result.clear
|
151
|
-
return ret
|
137
|
+
result = without_prepared_statement?(binds) ? exec_no_cache(sql, name, binds) :
|
138
|
+
exec_cache(sql, name, binds)
|
139
|
+
|
140
|
+
types = {}
|
141
|
+
fields = result.fields
|
142
|
+
fields.each_with_index do |fname, i|
|
143
|
+
ftype = result.ftype i
|
144
|
+
fmod = result.fmod i
|
145
|
+
types[fname] = type_map.fetch(ftype, fmod) { |oid, mod|
|
146
|
+
warn "unknown OID: #{fname}(#{oid}) (#{sql})"
|
147
|
+
OID::Identity.new
|
148
|
+
}
|
152
149
|
end
|
150
|
+
|
151
|
+
ret = ActiveRecord::Result.new(fields, result.values, types)
|
152
|
+
result.clear
|
153
|
+
return ret
|
153
154
|
end
|
154
155
|
|
155
156
|
def exec_delete(sql, name = 'SQL', binds = [])
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
affected
|
162
|
-
end
|
157
|
+
result = without_prepared_statement?(binds) ? exec_no_cache(sql, name, binds) :
|
158
|
+
exec_cache(sql, name, binds)
|
159
|
+
affected = result.cmd_tuples
|
160
|
+
result.clear
|
161
|
+
affected
|
163
162
|
end
|
164
163
|
alias :exec_update :exec_delete
|
165
164
|
|
@@ -215,25 +214,6 @@ module ActiveRecord
|
|
215
214
|
def rollback_db_transaction
|
216
215
|
execute "ROLLBACK"
|
217
216
|
end
|
218
|
-
|
219
|
-
def outside_transaction?
|
220
|
-
message = "#outside_transaction? is deprecated. This method was only really used " \
|
221
|
-
"internally, but you can use #transaction_open? instead."
|
222
|
-
ActiveSupport::Deprecation.warn message
|
223
|
-
@connection.transaction_status == PGconn::PQTRANS_IDLE
|
224
|
-
end
|
225
|
-
|
226
|
-
def create_savepoint
|
227
|
-
execute("SAVEPOINT #{current_savepoint_name}")
|
228
|
-
end
|
229
|
-
|
230
|
-
def rollback_to_savepoint
|
231
|
-
execute("ROLLBACK TO SAVEPOINT #{current_savepoint_name}")
|
232
|
-
end
|
233
|
-
|
234
|
-
def release_savepoint
|
235
|
-
execute("RELEASE SAVEPOINT #{current_savepoint_name}")
|
236
|
-
end
|
237
217
|
end
|
238
218
|
end
|
239
219
|
end
|
@@ -6,10 +6,6 @@ module ActiveRecord
|
|
6
6
|
module OID
|
7
7
|
class Type
|
8
8
|
def type; end
|
9
|
-
|
10
|
-
def type_cast_for_write(value)
|
11
|
-
value
|
12
|
-
end
|
13
9
|
end
|
14
10
|
|
15
11
|
class Identity < Type
|
@@ -31,9 +27,6 @@ module ActiveRecord
|
|
31
27
|
class Bytea < Type
|
32
28
|
def type_cast(value)
|
33
29
|
return if value.nil?
|
34
|
-
# This is a flawed heuristic, but it avoids truncation;
|
35
|
-
# we really shouldn’t be calling this with already-unescaped values
|
36
|
-
return value if value.dup.force_encoding("BINARY") =~ /\x00/
|
37
30
|
PGconn.unescape_bytea value
|
38
31
|
end
|
39
32
|
end
|
@@ -232,11 +225,19 @@ module ActiveRecord
|
|
232
225
|
end
|
233
226
|
|
234
227
|
class Hstore < Type
|
228
|
+
def type_cast_for_write(value)
|
229
|
+
ConnectionAdapters::PostgreSQLColumn.hstore_to_string value
|
230
|
+
end
|
231
|
+
|
235
232
|
def type_cast(value)
|
236
233
|
return if value.nil?
|
237
234
|
|
238
235
|
ConnectionAdapters::PostgreSQLColumn.string_to_hstore value
|
239
236
|
end
|
237
|
+
|
238
|
+
def accessor
|
239
|
+
ActiveRecord::Store::StringKeyedHashAccessor
|
240
|
+
end
|
240
241
|
end
|
241
242
|
|
242
243
|
class Cidr < Type
|
@@ -248,11 +249,19 @@ module ActiveRecord
|
|
248
249
|
end
|
249
250
|
|
250
251
|
class Json < Type
|
252
|
+
def type_cast_for_write(value)
|
253
|
+
ConnectionAdapters::PostgreSQLColumn.json_to_string value
|
254
|
+
end
|
255
|
+
|
251
256
|
def type_cast(value)
|
252
257
|
return if value.nil?
|
253
258
|
|
254
259
|
ConnectionAdapters::PostgreSQLColumn.string_to_json value
|
255
260
|
end
|
261
|
+
|
262
|
+
def accessor
|
263
|
+
ActiveRecord::Store::StringKeyedHashAccessor
|
264
|
+
end
|
256
265
|
end
|
257
266
|
|
258
267
|
class TypeMap
|
@@ -292,17 +301,15 @@ module ActiveRecord
|
|
292
301
|
end
|
293
302
|
end
|
294
303
|
|
295
|
-
|
296
|
-
|
297
|
-
# When the PG adapter connects, the pg_type table is queried. The
|
304
|
+
# When the PG adapter connects, the pg_type table is queried. The
|
298
305
|
# key of this hash maps to the `typname` column from the table.
|
299
|
-
#
|
306
|
+
# type_map is then dynamically built with oids as the key and type
|
300
307
|
# objects as values.
|
301
308
|
NAMES = Hash.new { |h,k| # :nodoc:
|
302
309
|
h[k] = OID::Identity.new
|
303
310
|
}
|
304
311
|
|
305
|
-
# Register an OID type named +name+ with a
|
312
|
+
# Register an OID type named +name+ with a typecasting object in
|
306
313
|
# +type+. +name+ should correspond to the `typname` column in
|
307
314
|
# the `pg_type` table.
|
308
315
|
def self.register_type(name, type)
|