Module: PgPower::ConnectionAdapters::PostgreSQLAdapter::ExtensionMethods

Included in:
PgPower::ConnectionAdapters::PostgreSQLAdapter
Defined in:
lib/pg_power/connection_adapters/postgresql_adapter/extension_methods.rb

Overview

Provides methods to extend ActiveRecord::ConnectionAdapters::PostgreSQLAdapter to support extensions feature.

Constant Summary collapse

CREATE_EXTENSION_DEFAULTS =

Default options for #create_extension method.

{
    :if_not_exists => true,
    :schema_name   => nil,
    :version       => nil,
    :old_version   => nil
}
DROP_EXTENSION_DEFAULTS =

Default options for #drop_extension method.

{
    :if_exists => true,
    :mode      => :restrict
}
AVAILABLE_DROP_MODES =

The modes which determine postgresql behavior on DROP EXTENSION operation.

:restrict refuse to drop the extension if any objects depend on it :cascade automatically drop objects that depend on the extension

{
    :restrict => 'RESTRICT',
    :cascade  => 'CASCADE'
}

Instance Method Summary collapse

Instance Method Details

#create_extension(extension_name, options = {}) ⇒ Object

Execute SQL to load a postgresql extension module into the current database.

Options Hash (options):

  • :if_not_exists (Boolean)

    should the ‘IF NOT EXISTS’ clause be added

  • :schema_name (#to_s, nil)

    The name of the schema in which to install the extension’s objects

  • :version (#to_s, nil)

    The version of the extension to install

  • :old_version (#to_s, nil)

    Alternative installation script name that absorbs the existing objects into the extension, instead of creating new objects



41
42
43
44
45
46
47
48
49
50
51
52
53
# File 'lib/pg_power/connection_adapters/postgresql_adapter/extension_methods.rb', line 41

def create_extension(extension_name, options = {})
  options = CREATE_EXTENSION_DEFAULTS.merge(options.symbolize_keys)

  sql = ['CREATE EXTENSION']
  sql << 'IF NOT EXISTS'                   if options[:if_not_exists]
  sql << %Q{"#{extension_name.to_s}"}
  sql << "SCHEMA #{options[:schema_name]}" if options[:schema_name].present?
  sql << "VERSION '#{options[:version]}'"  if options[:version].present?
  sql << "FROM #{options[:old_version]}"   if options[:old_version].present?

  sql = sql.join(' ')
  execute(sql)
end

#drop_extension(extension_name, options = {}) ⇒ Object

Execute SQL to remove a postgresql extension module from the current database.

Options Hash (options):

  • :if_exists (Boolean)

    should the ‘IF EXISTS’ clause be added

  • :mode (Symbol)

    Operation mode. See AVAILABLE_DROP_MODES for details



61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
# File 'lib/pg_power/connection_adapters/postgresql_adapter/extension_methods.rb', line 61

def drop_extension(extension_name, options = {})
  options = DROP_EXTENSION_DEFAULTS.merge(options.symbolize_keys)

  sql = ['DROP EXTENSION']
  sql << 'IF EXISTS' if options[:if_exists]
  sql << %Q{"#{extension_name.to_s}"}

  mode = options[:mode]
  if mode.present?
    mode = mode.to_sym

    unless AVAILABLE_DROP_MODES.include?(mode)
      raise ArgumentError,
            "Expected one of #{AVAILABLE_DROP_MODES.keys.inspect} drop modes, " \
            "but #{mode} received"
    end

    sql << AVAILABLE_DROP_MODES[mode]
  end

  sql = sql.join(' ')
  execute(sql)
end

#pg_extensionsHash{String => Hash{Symbol => String}}

Note:

Since Rails 4 connection has method extensions that returns array of extensions. This method is slightly different, since it returns also additional options.

Query the pg_catalog for all extension modules loaded to the current database.

Please note all extensions which belong to pg_catalog schema are omitted

Example

extension # => {
  "fuzzystrmatch" => {:schema_name => "public", :version => "1.0" }
}


99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
# File 'lib/pg_power/connection_adapters/postgresql_adapter/extension_methods.rb', line 99

def pg_extensions
  # Check postgresql version to not break on Postgresql < 9.1 during schema dump
  pg_version_str = select_value('SELECT version()')
  return {} unless pg_version_str =~ /^PostgreSQL (\d+\.\d+.\d+)/ && ($1 >= '9.1')

  sql = <<-SQL
    SELECT pge.extname AS ext_name, pgn.nspname AS schema_name, pge.extversion AS ext_version
    FROM pg_extension pge
    INNER JOIN pg_namespace pgn on pge.extnamespace = pgn.oid
    WHERE pgn.nspname <> 'pg_catalog'
  SQL

  result = select_all(sql)
  formatted_result = result.map do |row|
    [
        row['ext_name'],
        {
            :schema_name => row['schema_name'],
            :version => row['ext_version']
        }
    ]
  end

  Hash[formatted_result]
end

#supports_extensions?Boolean



28
29
30
# File 'lib/pg_power/connection_adapters/postgresql_adapter/extension_methods.rb', line 28

def supports_extensions?
  true
end