Permalink
Browse files

Merge pull request #9484 from senny/9480_change_table_and_hstore

Support PostgreSQL specific column types when using `change_table`.

We use `TableDefinition` for `#create_table` and `Table` for `#change_table`.
The PostgreSQL sepcific types were only defined on `TableDefinition` so they needed to be added to `Table` as well.
  • Loading branch information...
2 parents a389438 + 5d0ca74 commit 8f6b70f1fd49b8520a744cc90102051043faf315 @carlosantoniodasilva carlosantoniodasilva committed Feb 28, 2013
View
@@ -1,5 +1,17 @@
## Rails 4.0.0 (unreleased) ##
+* Support PostgreSQL specific column types when using `change_table`.
+ Fixes #9480.
+
+ Example:
+
+ change_table :authors do |t|
+ t.hstore :books
+ t.json :metadata
+ end
+
+ *Yves Senn*
+
* Revert 408227d9c5ed7d, 'quote numeric'. This introduced some regressions.
*Steve Klabnik*
@@ -44,8 +44,8 @@ def add_column_options!(sql, options)
# Represents the schema of an SQL table in an abstract way. This class
# provides methods for manipulating the schema representation.
#
- # Inside migration files, the +t+ object in +create_table+ and
- # +change_table+ is actually of this type:
+ # Inside migration files, the +t+ object in +create_table+
+ # is actually of this type:
#
# class SomeMigration < ActiveRecord::Migration
# def up
@@ -489,7 +489,7 @@ def remove_references(*args)
args.each do |name|
@base.add_column(@table_name, name, column_type, options)
end
- end
+ end
end
private
@@ -156,7 +156,7 @@ def column_exists?(table_name, column_name, type = nil, options = {})
#
# See also TableDefinition#column for details on how to create columns.
def create_table(table_name, options = {})
- td = table_definition
+ td = create_table_definition
td.primary_key(options[:primary_key] || Base.get_primary_key(table_name.to_s.singularize)) unless options[:id] == false
yield td if block_given?
@@ -298,10 +298,10 @@ def drop_join_table(table_1, table_2, options = {})
def change_table(table_name, options = {})
if supports_bulk_alter? && options[:bulk]
recorder = ActiveRecord::Migration::CommandRecorder.new(self)
- yield Table.new(table_name, recorder)
+ yield update_table_definition(table_name, recorder)
bulk_change_table(table_name, recorder.commands)
else
- yield Table.new(table_name, self)
+ yield update_table_definition(table_name, self)
end
end
@@ -727,9 +727,13 @@ def rename_column_indexes(table_name, column_name, new_column_name)
end
private
- def table_definition
+ def create_table_definition
TableDefinition.new(self)
end
+
+ def update_table_definition(table_name, base)
+ Table.new(table_name, base)
+ end
end
end
end
@@ -263,7 +263,7 @@ class ColumnDefinition < ActiveRecord::ConnectionAdapters::ColumnDefinition
attr_accessor :array
end
- class TableDefinition < ActiveRecord::ConnectionAdapters::TableDefinition
+ module ColumnMethods
def xml(*args)
options = args.extract_options!
column(args[0], 'xml', options)
@@ -325,6 +325,10 @@ def uuid(name, options = {})
def json(name, options = {})
column(name, 'json', options)
end
+ end
+
+ class TableDefinition < ActiveRecord::ConnectionAdapters::TableDefinition
+ include ColumnMethods
def column(name, type = nil, options = {})
super
@@ -344,6 +348,10 @@ def new_column_definition(base, name, type)
end
end
+ class Table < ActiveRecord::ConnectionAdapters::Table
+ include ColumnMethods
+ end
+
ADAPTER_NAME = 'PostgreSQL'
NATIVE_DATABASE_TYPES = {
@@ -884,9 +892,13 @@ def extract_table_ref_from_insert_sql(sql)
$1.strip if $1
end
- def table_definition
+ def create_table_definition
TableDefinition.new(self)
end
+
+ def update_table_definition(table_name, base)
+ Table.new(table_name, base)
+ end
end
end
end
@@ -65,6 +65,21 @@ def test_column
assert_equal :hstore, @column.type
end
+ def test_change_table_supports_hstore
+ @connection.transaction do
+ @connection.change_table('hstores') do |t|
+ t.hstore 'users', default: ''
+ end
+ Hstore.reset_column_information
+ column = Hstore.columns.find { |c| c.name == 'users' }
+ assert_equal :hstore, column.type
+
+ raise ActiveRecord::Rollback # reset the schema change
+ end
+ ensure
+ Hstore.reset_column_information
+ end
+
def test_type_cast_hstore
assert @column
@@ -31,6 +31,21 @@ def test_column
assert_equal :json, @column.type
end
+ def test_change_table_supports_json
+ @connection.transaction do
+ @connection.change_table('json_data_type') do |t|
+ t.json 'users', default: '{}'
+ end
+ JsonDataType.reset_column_information
+ column = JsonDataType.columns.find { |c| c.name == 'users' }
+ assert_equal :json, column.type
+
+ raise ActiveRecord::Rollback # reset the schema change
+ end
+ ensure
+ JsonDataType.reset_column_information
+ end
+
def test_type_cast_json
assert @column

0 comments on commit 8f6b70f

Please sign in to comment.