class ActiveRecord::ConnectionAdapters::PostgreSQLAdapter - activerecord-4.2.3 Documentation

# class ActiveRecord::ConnectionAdapters::PostgreSQLAdapter

The PostgreSQL adapter works with the native C (bitbucket.org/ged/ruby-pg) driver.

Options:

- `:host` - Defaults to a Unix-domain socket in /tmp. On machines without Unix-domain sockets, the default is to connect to localhost.

- `:port` - Defaults to 5432.

- `:username` - Defaults to be the same as the operating system name of the user running the application.

- `:password` - Password to be used if the server demands password authentication.

- `:database` - Defaults to be the same as the user name.

- `:schema_search_path` - An optional schema search path for the connection given as a string of comma-separated schema names. This is backward-compatible with the `:schema_order` option.

- `:encoding` - An optional client encoding that is used in a `SET client_encoding TO <encoding>` call on the connection.

- `:min_messages` - An optional client min messages that is used in a `SET client_min_messages TO <min_messages>` call on the connection.

- `:variables` - An optional hash of additional parameters that will be used in `SET SESSION key = val` calls on the connection.

- `:insert_returning` - An optional boolean to control the use of `RETURNING` for `INSERT` statements defaults to true.

Any further options are used as connection parameters to libpq. See www.postgresql.org/docs/9.1/static/libpq-connect.html for the list of parameters.

In addition, default connection parameters of libpq can be set per environment variables. See www.postgresql.org/docs/9.1/static/libpq-envars.html .

### Constants

ADAPTER_NAME
FOREIGN_KEY_VIOLATION

  See www.postgresql.org/docs/9.1/static/errcodes-appendix.html

NATIVE_DATABASE_TYPES
UNIQUE_VIOLATION

### Public Class Methods

new(connection, logger, connection_parameters, config) click to toggle source

Initializes and connects a PostgreSQL adapter.

Calls superclass method ActiveRecord::ConnectionAdapters::QueryCache.new

    # File lib/active_record/connection_adapters/postgresql_adapter.rb, line 226
    def initialize(connection, logger, connection_parameters, config)
      super(connection, logger)

      @visitor = Arel::Visitors::PostgreSQL.new self
      if self.class.type_cast_config_to_boolean(config.fetch(:prepared_statements) { true })
        @prepared_statements = true
      else
        @prepared_statements = false
      end

      @connection_parameters, @config = connection_parameters, config

      # @local_tz is initialized as nil to avoid warnings when connect tries to use it
      @local_tz = nil
      @table_alias_length = nil

      connect
      @statements = StatementPool.new @connection,
                                      self.class.type_cast_config_to_integer(config.fetch(:statement_limit) { 1000 })

      if postgresql_version < 80200
        raise "Your version of PostgreSQL (#{postgresql_version}) is too old, please upgrade!"
      end

      @type_map = Type::HashLookupTypeMap.new
      initialize_type_map(type_map)
      @local_tz = execute('SHOW TIME ZONE', 'SCHEMA').first["TimeZone"]
      @use_insert_returning = @config.key?(:insert_returning) ? self.class.type_cast_config_to_boolean(@config[:insert_returning]) : true
    end

### Public Instance Methods

active?() click to toggle source

Is this connection alive and ready for queries?

    # File lib/active_record/connection_adapters/postgresql_adapter.rb, line 266
    def active?
      @connection.query 'SELECT 1'
      true
    rescue PGError
      false
    end

clear_cache!() click to toggle source

Clears the prepared statements cache.

    # File lib/active_record/connection_adapters/postgresql_adapter.rb, line 257
    def clear_cache!
      @statements.clear
    end

disable_extension(name) click to toggle source

    # File lib/active_record/connection_adapters/postgresql_adapter.rb, line 347
    def disable_extension(name)
      exec_query("DROP EXTENSION IF EXISTS \"#{name}\" CASCADE").tap {
        reload_type_map
      }
    end

disconnect!() click to toggle source

Disconnects from the database if already connected. Otherwise, this method does nothing.

Calls superclass method ActiveRecord::ConnectionAdapters::AbstractAdapter#disconnect!

    # File lib/active_record/connection_adapters/postgresql_adapter.rb, line 292
    def disconnect!
      super
      @connection.close rescue nil
    end

enable_extension(name) click to toggle source

    # File lib/active_record/connection_adapters/postgresql_adapter.rb, line 341
    def enable_extension(name)
      exec_query("CREATE EXTENSION IF NOT EXISTS \"#{name}\"").tap {
        reload_type_map
      }
    end

extension_enabled?(name) click to toggle source

    # File lib/active_record/connection_adapters/postgresql_adapter.rb, line 353
    def extension_enabled?(name)
      if supports_extensions?
        res = exec_query "SELECT EXISTS(SELECT * FROM pg_available_extensions WHERE name = '#{name}' AND installed_version IS NOT NULL) as enabled",
          'SCHEMA'
        res.cast_values.first
      end
    end

extensions() click to toggle source
Calls superclass method ActiveRecord::ConnectionAdapters::AbstractAdapter#extensions

    # File lib/active_record/connection_adapters/postgresql_adapter.rb, line 361
    def extensions
      if supports_extensions?
        exec_query("SELECT extname from pg_extension", "SCHEMA").cast_values
      else
        super
      end
    end

index_algorithms() click to toggle source

    # File lib/active_record/connection_adapters/postgresql_adapter.rb, line 168
    def index_algorithms
      { concurrently: 'CONCURRENTLY' }
    end

migration_keys() click to toggle source

Adds `:array` as a valid migration key

Calls superclass method ActiveRecord::ConnectionAdapters::ColumnDumper#migration_keys

    # File lib/active_record/connection_adapters/postgresql_adapter.rb, line 138
    def migration_keys
      super + [:array]
    end

reconnect!() click to toggle source

Close then reopen the connection.

Calls superclass method ActiveRecord::ConnectionAdapters::AbstractAdapter#reconnect!

    # File lib/active_record/connection_adapters/postgresql_adapter.rb, line 274
    def reconnect!
      super
      @connection.reset
      configure_connection
    end

reset!() click to toggle source

    # File lib/active_record/connection_adapters/postgresql_adapter.rb, line 280
    def reset!
      clear_cache!
      reset_transaction
      unless @connection.transaction_status == ::PG::PQTRANS_IDLE
        @connection.query 'ROLLBACK'
      end
      @connection.query 'DISCARD ALL'
      configure_connection
    end

session_auth=(user) click to toggle source

Set the authorized user for this session

    # File lib/active_record/connection_adapters/postgresql_adapter.rb, line 375
    def session_auth=(user)
      clear_cache!
      exec_query "SET SESSION AUTHORIZATION #{user}"
    end

set_standard_conforming_strings() click to toggle source

Enable standard-conforming strings if available.

    # File lib/active_record/connection_adapters/postgresql_adapter.rb, line 312
    def set_standard_conforming_strings
      old, self.client_min_messages = client_min_messages, 'panic'
      execute('SET standard_conforming_strings = on', 'SCHEMA') rescue nil
    ensure
      self.client_min_messages = old
    end

supports_ddl_transactions?() click to toggle source

    # File lib/active_record/connection_adapters/postgresql_adapter.rb, line 319
    def supports_ddl_transactions?
      true
    end

supports_explain?() click to toggle source

    # File lib/active_record/connection_adapters/postgresql_adapter.rb, line 323
    def supports_explain?
      true
    end

supports_extensions?() click to toggle source

Returns true if pg > 9.1

    # File lib/active_record/connection_adapters/postgresql_adapter.rb, line 328
    def supports_extensions?
      postgresql_version >= 90100
    end

supports_foreign_keys?() click to toggle source

    # File lib/active_record/connection_adapters/postgresql_adapter.rb, line 160
    def supports_foreign_keys?
      true
    end

supports_index_sort_order?() click to toggle source

    # File lib/active_record/connection_adapters/postgresql_adapter.rb, line 148
    def supports_index_sort_order?
      true
    end

supports_materialized_views?() click to toggle source

    # File lib/active_record/connection_adapters/postgresql_adapter.rb, line 337
    def supports_materialized_views?
      postgresql_version >= 90300
    end

supports_migrations?() click to toggle source

Returns true, since this connection adapter supports migrations.

    # File lib/active_record/connection_adapters/postgresql_adapter.rb, line 302
    def supports_migrations?
      true
    end

supports_partial_index?() click to toggle source

    # File lib/active_record/connection_adapters/postgresql_adapter.rb, line 152
    def supports_partial_index?
      true
    end

supports_ranges?() click to toggle source

Range datatypes weren't introduced until PostgreSQL 9.2

    # File lib/active_record/connection_adapters/postgresql_adapter.rb, line 333
    def supports_ranges?
      postgresql_version >= 90200
    end

supports_statement_cache?() click to toggle source

Returns `true`, since this connection adapter supports prepared statement caching.

    # File lib/active_record/connection_adapters/postgresql_adapter.rb, line 144
    def supports_statement_cache?
      true
    end

supports_transaction_isolation?() click to toggle source

    # File lib/active_record/connection_adapters/postgresql_adapter.rb, line 156
    def supports_transaction_isolation?
      true
    end

supports_views?() click to toggle source

    # File lib/active_record/connection_adapters/postgresql_adapter.rb, line 164
    def supports_views?
      true
    end

table_alias_length() click to toggle source

Returns the configured supported identifier length supported by PostgreSQL

    # File lib/active_record/connection_adapters/postgresql_adapter.rb, line 370
    def table_alias_length
      @table_alias_length ||= query('SHOW max_identifier_length', 'SCHEMA')[0][0].to_i
    end

truncate(table_name, name = nil) click to toggle source

    # File lib/active_record/connection_adapters/postgresql_adapter.rb, line 261
    def truncate(table_name, name = nil)
      exec_query "TRUNCATE TABLE #{quote_table_name(table_name)}", name, []
    end

use_insert_returning?() click to toggle source

    # File lib/active_record/connection_adapters/postgresql_adapter.rb, line 380
    def use_insert_returning?
      @use_insert_returning
    end

valid_type?(type) click to toggle source

    # File lib/active_record/connection_adapters/postgresql_adapter.rb, line 384
    def valid_type?(type)
      !native_database_types[type].nil?
    end

### Protected Instance Methods

postgresql_version() click to toggle source

Returns the version of the connected PostgreSQL server.

    # File lib/active_record/connection_adapters/postgresql_adapter.rb, line 410
    def postgresql_version
      @connection.server_version
    end

translate_exception(exception, message) click to toggle source
Calls superclass method ActiveRecord::ConnectionAdapters::AbstractAdapter#translate_exception

    # File lib/active_record/connection_adapters/postgresql_adapter.rb, line 418
    def translate_exception(exception, message)
      return exception unless exception.respond_to?(:result)

      case exception.result.try(:error_field, PGresult::PG_DIAG_SQLSTATE)
      when UNIQUE_VIOLATION
        RecordNotUnique.new(message, exception)
      when FOREIGN_KEY_VIOLATION
        InvalidForeignKey.new(message, exception)
      else
        super
      end
    end

### Private Instance Methods

configure_connection() click to toggle source

Configures the encoding, verbosity, schema search path, and time zone of the connection. This is called by connect and should not be called manually.

    # File lib/active_record/connection_adapters/postgresql_adapter.rb, line 673
    def configure_connection
      if @config[:encoding]
        @connection.set_client_encoding(@config[:encoding])
      end
      self.client_min_messages = @config[:min_messages] || 'warning'
      self.schema_search_path = @config[:schema_search_path] || @config[:schema_order]

      # Use standard-conforming strings if available so we don't have to do the E'...' dance.
      set_standard_conforming_strings

      # If using Active Record's time zone support configure the connection to return
      # TIMESTAMP WITH ZONE types in UTC.
      # (SET TIME ZONE does not use an equals sign like other SET variables)
      if ActiveRecord::Base.default_timezone == :utc
        execute("SET time zone 'UTC'", 'SCHEMA')
      elsif @local_tz
        execute("SET time zone '#{@local_tz}'", 'SCHEMA')
      end

      # SET statements from :variables config hash
      # http://www.postgresql.org/docs/8.3/static/sql-set.html
      variables = @config[:variables] || {}
      variables.map do |k, v|
        if v == ':default' || v == :default
          # Sets the value to the global or compile default
          execute("SET SESSION #{k} TO DEFAULT", 'SCHEMA')
        elsif !v.nil?
          execute("SET SESSION #{k} TO #{quote(v)}", 'SCHEMA')
        end
      end
    end

connect() click to toggle source

Connects to a PostgreSQL server and sets up the adapter depending on the connected server's characteristics.

    # File lib/active_record/connection_adapters/postgresql_adapter.rb, line 654
    def connect
      @connection = PGconn.connect(@connection_parameters)

      # Money type has a fixed precision of 10 in PostgreSQL 8.2 and below, and as of
      # PostgreSQL 8.3 it has a fixed precision of 19. PostgreSQLColumn.extract_precision
      # should know about this but can't detect it there, so deal with it here.
      OID::Money.precision = (postgresql_version >= 80300) ? 19 : 10

      configure_connection
    rescue ::PG::Error => error
      if error.message.include?("does not exist")
        raise ActiveRecord::NoDatabaseError.new(error.message, error)
      else
        raise
      end
    end

exec_cache(sql, name, binds) click to toggle source

    # File lib/active_record/connection_adapters/postgresql_adapter.rb, line 599
    def exec_cache(sql, name, binds)
      stmt_key = prepare_statement(sql)
      type_casted_binds = binds.map { |col, val|
        [col, type_cast(val, col)]
      }

      log(sql, name, type_casted_binds, stmt_key) do
        @connection.exec_prepared(stmt_key, type_casted_binds.map { |_, val| val })
      end
    rescue ActiveRecord::StatementInvalid => e
      pgerror = e.original_exception

      # Get the PG code for the failure.  Annoyingly, the code for
      # prepared statements whose return value may have changed is
      # FEATURE_NOT_SUPPORTED.  Check here for more details:
      # http://git.postgresql.org/gitweb/?p=postgresql.git;a=blob;f=src/backend/utils/cache/plancache.c#l573
      begin
        code = pgerror.result.result_error_field(PGresult::PG_DIAG_SQLSTATE)
      rescue
        raise e
      end
      if FEATURE_NOT_SUPPORTED == code
        @statements.delete sql_key(sql)
        retry
      else
        raise e
      end
    end

exec_no_cache(sql, name, binds) click to toggle source

    # File lib/active_record/connection_adapters/postgresql_adapter.rb, line 595
    def exec_no_cache(sql, name, binds)
      log(sql, name, binds) { @connection.async_exec(sql, []) }
    end

execute_and_clear(sql, name, binds) { |result| ... } click to toggle source

    # File lib/active_record/connection_adapters/postgresql_adapter.rb, line 587
    def execute_and_clear(sql, name, binds)
      result = without_prepared_statement?(binds) ? exec_no_cache(sql, name, binds) :
                                                    exec_cache(sql, name, binds)
      ret = yield result
      result.clear
      ret
    end

last_insert_id_value(sequence_name) click to toggle source

    # File lib/active_record/connection_adapters/postgresql_adapter.rb, line 710
    def last_insert_id_value(sequence_name)
      last_insert_id_result(sequence_name).rows.first.first
    end

prepare_statement(sql) click to toggle source

Prepare the statement if it hasn't been prepared, return the statement key.

    # File lib/active_record/connection_adapters/postgresql_adapter.rb, line 636
    def prepare_statement(sql)
      sql_key = sql_key(sql)
      unless @statements.key? sql_key
        nextkey = @statements.next_key
        begin
          @connection.prepare nextkey, sql
        rescue => e
          raise translate_exception_class(e, sql)
        end
        # Clear the queue
        @connection.get_last_result
        @statements[sql_key] = nextkey
      end
      @statements[sql_key]
    end

sql_key(sql) click to toggle source

Returns the statement identifier for the client side cache of statements

    # File lib/active_record/connection_adapters/postgresql_adapter.rb, line 630
    def sql_key(sql)
      "#{schema_search_path}-#{sql}"
    end