Permalink
Browse files

add API to pg for enabling / disabling hstore

  • Loading branch information...
1 parent ba6cae4 commit 439ac72013fc1b819e711d66642b0b5b563fd72e @tenderlove tenderlove committed Jan 29, 2013
@@ -171,6 +171,12 @@ def supports_transaction_isolation?
false
end
+ # Does this adapter support database extensions? As of this writing
+ # only postgresql does.
+ def supports_extensions?
+ false
+ end
+
# QUOTING ==================================================
# Returns a bind substitution value given a +column+ and list of current
@@ -575,11 +575,30 @@ def supports_explain?
true
end
+ # Returns true.
@tenderlove

tenderlove Jan 29, 2013

Owner

whoops! heh.

+ def supports_extensions?
+ postgresql_version >= 90200
+ end
+
# Range datatypes weren't introduced until PostgreSQL 9.2
def supports_ranges?
postgresql_version >= 90200
end
+ def enable_extension(name)
+ exec_query "CREATE EXTENSION IF NOT EXISTS #{name}"
+ end
+
+ def disable_extension(name)
+ exec_query "DROP EXTENSION IF EXISTS #{name} CASCADE"
+ end
+
+ def extension_enabled?(name)
+ res = exec_query "SELECT EXISTS(SELECT * FROM pg_available_extensions WHERE name = '#{name}' AND installed_version IS NOT NULL)",
+ 'SCHEMA'
+ res.column_types['exists'].type_cast res.rows.first.first
+ end
+
# Returns the configured supported identifier length supported by PostgreSQL
def table_alias_length
@table_alias_length ||= query('SHOW max_identifier_length', 'SCHEMA')[0][0].to_i
@@ -11,22 +11,44 @@ class Hstore < ActiveRecord::Base
def setup
@connection = ActiveRecord::Base.connection
- begin
- @connection.transaction do
- @connection.create_table('hstores') do |t|
- t.hstore 'tags', :default => ''
- end
- end
- rescue ActiveRecord::StatementInvalid
+ unless @connection.extension_enabled?('hstore')
+ @connection.enable_extension 'hstore'
return skip "do not test on PG without hstore"
end
+
+ @connection.transaction do
+ @connection.create_table('hstores') do |t|
+ t.hstore 'tags', :default => ''
+ end
+ end
@column = Hstore.columns.find { |c| c.name == 'tags' }
end
def teardown
@connection.execute 'drop table if exists hstores'
end
+ def test_hstore_enabled
+ assert @connection.extension_enabled?('hstore')
+ end
+
+ def test_disable_hstore
+ if @connection.extension_enabled?('hstore')
+ @connection.disable_extension 'hstore'
+ assert_not @connection.extension_enabled?('hstore')
+ end
+ end
+
+ def test_enable_hstore
+ if @connection.extension_enabled?('hstore')
+ @connection.disable_extension 'hstore'
+ end
+
+ assert_not @connection.extension_enabled?('hstore')
+ @connection.enable_extension 'hstore'
+ assert @connection.extension_enabled?('hstore')
+ end
+
def test_column
assert_equal :hstore, @column.type
end

3 comments on commit 439ac72

Owner

rafaelfranca replied Jan 29, 2013

This will not work. When you enable the extension in the connection it indeed create the extension but it doesn't change the OID::TYPE_MAP, so the hstrore OID will not be found.

The tests didn't fail because they are all skipped. You can see the errors when you apply this patch: https://gist.github.com/4665250

I'm trying to fix it but to update the OID::TYPE_MAP I need to create the hstore extension before connect to the database

I think we're safely assuming that contrib package is always installed for postgres? Perhaps this needs to be stated somewhere better for the linux folks (even though for me this is never a problem since I use homebrew, but came across this on a colleague's machine)?

Contributor

MacksMind replied Mar 16, 2013

Calling disable_extension 'hstore' breaks test_schema_dump_includes_hstores_shorthand_definition in test/cases/schema_dumper_test.rb if test/cases/adapters/postgresql/hstore_test.rb runs first.

As in: ARCONN=postgresql bundle exec ruby -I.:test -e "%w{test/cases/adapters/postgresql/hstore_test.rb test/cases/schema_dumper_test.rb}.each { |f| require f }"

Please sign in to comment.