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.

Parameters:

  • extension_name (#to_s)

    Name of the extension module to load

  • options (Hash) (defaults to: {})

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.

Parameters:

  • extension_name (#to_s)

    Name of the extension module to unload

  • options (Hash) (defaults to: {})

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" }
}

Returns:

  • (Hash{String => Hash{Symbol => String}})

    A list of loaded extensions with their options



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

Returns if adapter supports postgresql extension manipulation.

Returns:

  • (Boolean)

    if adapter supports postgresql extension manipulation



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

def supports_extensions?
  true
end