aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord/lib/active_record/connection_adapters
diff options
context:
space:
mode:
authorDickson S. Guedes <guedes@guedesoft.net>2012-09-05 14:01:21 -0300
committerDickson S. Guedes <guedes@guedesoft.net>2012-09-05 22:39:43 -0300
commit3b516b5beb79f7e8c1fdd123e7d5a03c00349cdf (patch)
treebc37c5a7d54e4fc8c6aafb83b6548fb69940b514 /activerecord/lib/active_record/connection_adapters
parentddaeaefc2a454be9d893ef3c546793cc47b0db84 (diff)
downloadrails-3b516b5beb79f7e8c1fdd123e7d5a03c00349cdf.tar.gz
rails-3b516b5beb79f7e8c1fdd123e7d5a03c00349cdf.tar.bz2
rails-3b516b5beb79f7e8c1fdd123e7d5a03c00349cdf.zip
ActiveRecord support to PostgreSQL 9.2 JSON type
This implements the support to encode/decode JSON data to/from database and creating columns of type JSON using a native type [1] supported by PostgreSQL from version 9.2. [1] http://www.postgresql.org/docs/9.2/static/datatype-json.html
Diffstat (limited to 'activerecord/lib/active_record/connection_adapters')
-rw-r--r--activerecord/lib/active_record/connection_adapters/column.rb1
-rw-r--r--activerecord/lib/active_record/connection_adapters/postgresql/cast.rb16
-rw-r--r--activerecord/lib/active_record/connection_adapters/postgresql/oid.rb9
-rw-r--r--activerecord/lib/active_record/connection_adapters/postgresql/quoting.rb8
-rw-r--r--activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb13
5 files changed, 44 insertions, 3 deletions
diff --git a/activerecord/lib/active_record/connection_adapters/column.rb b/activerecord/lib/active_record/connection_adapters/column.rb
index d0237848c7..0390168461 100644
--- a/activerecord/lib/active_record/connection_adapters/column.rb
+++ b/activerecord/lib/active_record/connection_adapters/column.rb
@@ -124,6 +124,7 @@ module ActiveRecord
when :boolean then "#{klass}.value_to_boolean(#{var_name})"
when :hstore then "#{klass}.string_to_hstore(#{var_name})"
when :inet, :cidr then "#{klass}.string_to_cidr(#{var_name})"
+ when :json then "#{klass}.string_to_json(#{var_name})"
else var_name
end
end
diff --git a/activerecord/lib/active_record/connection_adapters/postgresql/cast.rb b/activerecord/lib/active_record/connection_adapters/postgresql/cast.rb
index 20e482dcc2..b59195f98a 100644
--- a/activerecord/lib/active_record/connection_adapters/postgresql/cast.rb
+++ b/activerecord/lib/active_record/connection_adapters/postgresql/cast.rb
@@ -37,6 +37,22 @@ module ActiveRecord
end
end
+ def json_to_string(object)
+ if Hash === object
+ ActiveSupport::JSON.encode(object)
+ else
+ object
+ end
+ end
+
+ def string_to_json(string)
+ if String === string
+ ActiveSupport::JSON.decode(string)
+ else
+ string
+ end
+ end
+
def string_to_cidr(string)
if string.nil?
nil
diff --git a/activerecord/lib/active_record/connection_adapters/postgresql/oid.rb b/activerecord/lib/active_record/connection_adapters/postgresql/oid.rb
index 6657491c06..b8e7687b21 100644
--- a/activerecord/lib/active_record/connection_adapters/postgresql/oid.rb
+++ b/activerecord/lib/active_record/connection_adapters/postgresql/oid.rb
@@ -145,6 +145,14 @@ module ActiveRecord
end
end
+ class Json < Type
+ def type_cast(value)
+ return if value.nil?
+
+ ConnectionAdapters::PostgreSQLColumn.string_to_json value
+ end
+ end
+
class TypeMap
def initialize
@mapping = {}
@@ -244,6 +252,7 @@ module ActiveRecord
register_type 'polygon', OID::Identity.new
register_type 'circle', OID::Identity.new
register_type 'hstore', OID::Hstore.new
+ register_type 'json', OID::Json.new
register_type 'cidr', OID::Cidr.new
alias_type 'inet', 'cidr'
diff --git a/activerecord/lib/active_record/connection_adapters/postgresql/quoting.rb b/activerecord/lib/active_record/connection_adapters/postgresql/quoting.rb
index 1ae7443cde..152258a2f4 100644
--- a/activerecord/lib/active_record/connection_adapters/postgresql/quoting.rb
+++ b/activerecord/lib/active_record/connection_adapters/postgresql/quoting.rb
@@ -22,6 +22,7 @@ module ActiveRecord
when Hash
case column.sql_type
when 'hstore' then super(PostgreSQLColumn.hstore_to_string(value), column)
+ when 'json' then super(PostgreSQLColumn.json_to_string(value), column)
else super
end
when IPAddr
@@ -66,8 +67,11 @@ module ActiveRecord
return super unless 'bytea' == column.sql_type
{ :value => value, :format => 1 }
when Hash
- return super unless 'hstore' == column.sql_type
- PostgreSQLColumn.hstore_to_string(value)
+ case column.sql_type
+ when 'hstore' then PostgreSQLColumn.hstore_to_string(value)
+ when 'json' then PostgreSQLColumn.json_to_string(value)
+ else super
+ end
when IPAddr
return super unless ['inet','cidr'].includes? column.sql_type
PostgreSQLColumn.cidr_to_string(value)
diff --git a/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb b/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb
index 956e83bfd8..c508afb33e 100644
--- a/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb
+++ b/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb
@@ -106,6 +106,9 @@ module ActiveRecord
# Hstore
when /\A'(.*)'::hstore\z/
$1
+ # JSON
+ when /\A'(.*)'::json\z/
+ $1
# Object identifier types
when /\A-?\d+\z/
$1
@@ -201,6 +204,9 @@ module ActiveRecord
# UUID type
when 'uuid'
:uuid
+ # JSON type
+ when 'json'
+ :json
# Small and big integer types
when /^(?:small|big)int$/
:integer
@@ -267,6 +273,10 @@ module ActiveRecord
def uuid(name, options = {})
column(name, 'uuid', options)
end
+
+ def json(name, options = {})
+ column(name, 'json', options)
+ end
end
ADAPTER_NAME = 'PostgreSQL'
@@ -290,7 +300,8 @@ module ActiveRecord
inet: { name: "inet" },
cidr: { name: "cidr" },
macaddr: { name: "macaddr" },
- uuid: { name: "uuid" }
+ uuid: { name: "uuid" },
+ json: { name: "json" }
}
include Quoting