Skip to content

Commit

Permalink
Add Enum type to postgresql adapter's oids to prevent unknown OID war…
Browse files Browse the repository at this point in the history
…nings.
  • Loading branch information
kommen committed Mar 4, 2014
1 parent ffcc617 commit 5c55aaf
Show file tree
Hide file tree
Showing 4 changed files with 45 additions and 0 deletions.
5 changes: 5 additions & 0 deletions activerecord/CHANGELOG.md
@@ -1,3 +1,8 @@
* Dynamically register PostgreSQL enum OIDs. This prevents "unknown OID"
warnings on enum columns.

*Dieter Komendera*

* `includes` is able to detect the right preloading strategy when string
joins are involved.

Expand Down
Expand Up @@ -229,6 +229,12 @@ def infinity(options = {})
end
end

class Enum < Type
def type_cast(value)
value.to_s
end
end

class Hstore < Type
def type_cast_for_write(value)
ConnectionAdapters::PostgreSQLColumn.hstore_to_string value
Expand Down
Expand Up @@ -801,6 +801,12 @@ def initialize_type_map(type_map)
leaves, nodes = nodes.partition { |row| row['typelem'] == '0' }
arrays, nodes = nodes.partition { |row| row['typinput'] == 'array_in' }

# populate the enum types
enums, leaves = leaves.partition { |row| row['typinput'] == 'enum_in' }
enums.each do |row|
type_map[row['oid'].to_i] = OID::Enum.new
end

# populate the base types
leaves.find_all { |row| OID.registered_type? row['typname'] }.each do |row|
type_map[row['oid'].to_i] = OID::NAMES[row['typname']]
Expand Down
28 changes: 28 additions & 0 deletions activerecord/test/cases/adapters/postgresql/enum_test.rb
Expand Up @@ -23,6 +23,8 @@ def setup
t.column :current_mood, :mood
end
end
# reload type map after creating the enum type
@connection.send(:reload_type_map)
end

def test_enum_mapping
Expand All @@ -35,4 +37,30 @@ def test_enum_mapping

assert_equal "happy", enum.reload.current_mood
end

def test_invalid_enum_update
@connection.execute "INSERT INTO postgresql_enums VALUES (1, 'sad');"
enum = PostgresqlEnum.first
enum.current_mood = "angry"

assert_raise ActiveRecord::StatementInvalid do
enum.save
end
end

def test_no_oid_warning
@connection.execute "INSERT INTO postgresql_enums VALUES (1, 'sad');"
stderr_output = capture(:stderr) {
enum = PostgresqlEnum.first
}

assert stderr_output.blank?
end

def test_enum_type_cast
enum = PostgresqlEnum.new
enum.current_mood = :happy

assert_equal "happy", enum.current_mood
end
end

0 comments on commit 5c55aaf

Please sign in to comment.