aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord/lib/active_record/connection_adapters/postgresql/oid/array.rb
diff options
context:
space:
mode:
authorLars Kanis <lars@greiz-reinsdorf.de>2015-03-22 18:27:55 +0100
committerLars Kanis <lars@greiz-reinsdorf.de>2015-03-25 15:05:24 +0100
commit647eb2cf1cd65b0391e3584361f0fc76246e64f3 (patch)
tree29ba4ebaabf3068cbc08ea52bcf5a87509c8c630 /activerecord/lib/active_record/connection_adapters/postgresql/oid/array.rb
parent9f2f268666e2f5d861905f4740943c85ea70f76e (diff)
downloadrails-647eb2cf1cd65b0391e3584361f0fc76246e64f3.tar.gz
rails-647eb2cf1cd65b0391e3584361f0fc76246e64f3.tar.bz2
rails-647eb2cf1cd65b0391e3584361f0fc76246e64f3.zip
PostgreSQL, Use ruby-pg's built-in capabilities for array en-/decoding in C.
This obsoletes the ruby based implementations.
Diffstat (limited to 'activerecord/lib/active_record/connection_adapters/postgresql/oid/array.rb')
-rw-r--r--activerecord/lib/active_record/connection_adapters/postgresql/oid/array.rb56
1 files changed, 6 insertions, 50 deletions
diff --git a/activerecord/lib/active_record/connection_adapters/postgresql/oid/array.rb b/activerecord/lib/active_record/connection_adapters/postgresql/oid/array.rb
index f486c5ecb7..3de794f797 100644
--- a/activerecord/lib/active_record/connection_adapters/postgresql/oid/array.rb
+++ b/activerecord/lib/active_record/connection_adapters/postgresql/oid/array.rb
@@ -5,29 +5,20 @@ module ActiveRecord
class Array < Type::Value # :nodoc:
include Type::Helpers::Mutable
- # Loads pg_array_parser if available. String parsing can be
- # performed quicker by a native extension, which will not create
- # a large amount of Ruby objects that will need to be garbage
- # collected. pg_array_parser has a C and Java extension
- begin
- require 'pg_array_parser'
- include PgArrayParser
- rescue LoadError
- require 'active_record/connection_adapters/postgresql/array_parser'
- include PostgreSQL::ArrayParser
- end
-
attr_reader :subtype, :delimiter
delegate :type, :user_input_in_time_zone, :limit, to: :subtype
def initialize(subtype, delimiter = ',')
@subtype = subtype
@delimiter = delimiter
+
+ @pg_encoder = PG::TextEncoder::Array.new name: "#{type}[]", delimiter: delimiter
+ @pg_decoder = PG::TextDecoder::Array.new name: "#{type}[]", delimiter: delimiter
end
def deserialize(value)
if value.is_a?(::String)
- type_cast_array(parse_pg_array(value), :deserialize)
+ type_cast_array(@pg_decoder.decode(value), :deserialize)
else
super
end
@@ -35,14 +26,14 @@ module ActiveRecord
def cast(value)
if value.is_a?(::String)
- value = parse_pg_array(value)
+ value = @pg_decoder.decode(value)
end
type_cast_array(value, :cast)
end
def serialize(value)
if value.is_a?(::Array)
- cast_value_for_database(value)
+ @pg_encoder.encode(type_cast_array(value, :serialize))
else
super
end
@@ -63,41 +54,6 @@ module ActiveRecord
@subtype.public_send(method, value)
end
end
-
- def cast_value_for_database(value)
- if value.is_a?(::Array)
- casted_values = value.map { |item| cast_value_for_database(item) }
- "{#{casted_values.join(delimiter)}}"
- else
- quote_and_escape(subtype.serialize(value))
- end
- end
-
- ARRAY_ESCAPE = "\\" * 2 * 2 # escape the backslash twice for PG arrays
-
- def quote_and_escape(value)
- case value
- when ::String
- if string_requires_quoting?(value)
- value = value.gsub(/\\/, ARRAY_ESCAPE)
- value.gsub!(/"/,"\\\"")
- %("#{value}")
- else
- value
- end
- when nil then "NULL"
- else value
- end
- end
-
- # See http://www.postgresql.org/docs/9.2/static/arrays.html#ARRAYS-IO
- # for a list of all cases in which strings will be quoted.
- def string_requires_quoting?(string)
- string.empty? ||
- string == "NULL" ||
- string =~ /[\{\}"\\\s]/ ||
- string.include?(delimiter)
- end
end
end
end