Module: PgSaurus::ConnectionAdapters::PostgreSQLAdapter::ExtensionMethods

Included in:
PgSaurus::ConnectionAdapters::PostgreSQLAdapter
Defined in:
lib/pg_saurus/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_saurus/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



75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
# File 'lib/pg_saurus/connection_adapters/postgresql_adapter/extension_methods.rb', line 75

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

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

Execute SQL to load a postgresql extension module into the current database if it does not already exist. Then reload the type map.

Parameters:

  • extension_name (#to_s)

    Name of the extension module to load

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

Options Hash (options):

  • :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



64
65
66
67
# File 'lib/pg_saurus/connection_adapters/postgresql_adapter/extension_methods.rb', line 64

def enable_extension(extension_name, options = {})
  options[:if_not_exists] = true
  create_extension(extension_name, options).tap { reload_type_map }
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



113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
# File 'lib/pg_saurus/connection_adapters/postgresql_adapter/extension_methods.rb', line 113

def pg_extensions
  # Check postgresql version to not break on Postgresql < 9.1 during schema dump
  return {} if (::PgSaurus::Engine.pg_server_version <=> [9, 1]) < 0

  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_saurus/connection_adapters/postgresql_adapter/extension_methods.rb', line 28

def supports_extensions?
  true
end