Files

Class/Module Index [+]

Quicksearch

ArJdbc::PostgreSQL

Constants

ADAPTER_NAME

constants taken from postgresql_adapter in rails project

NATIVE_DATABASE_TYPES

Public Class Methods

arel2_visitors(config) click to toggle source
# File lib/arjdbc/postgresql/adapter.rb, line 172
def self.arel2_visitors(config)
  {
    'postgresql' => ::Arel::Visitors::PostgreSQL,
    'jdbcpostgresql' => ::Arel::Visitors::PostgreSQL,
    'pg' => ::Arel::Visitors::PostgreSQL
  }
end
column_selector() click to toggle source
# File lib/arjdbc/postgresql/adapter.rb, line 13
def self.column_selector
  [/postgre/, lambda {|cfg,col| col.extend(::ArJdbc::PostgreSQL::Column)}]
end
extended(mod) click to toggle source
# File lib/arjdbc/postgresql/adapter.rb, line 5
def self.extended(mod)
  (class << mod; self; end).class_eval do
    alias_chained_method :columns, :query_cache, :pg_columns
  end

  mod.configure_connection
end
jdbc_connection_class() click to toggle source
# File lib/arjdbc/postgresql/adapter.rb, line 17
def self.jdbc_connection_class
  ::ActiveRecord::ConnectionAdapters::PostgresJdbcConnection
end

Public Instance Methods

add_column(table_name, column_name, type, options = {}) click to toggle source

Adds a new column to the named table. See TableDefinition#column for details of the options you can use.

# File lib/arjdbc/postgresql/adapter.rb, line 740
def add_column(table_name, column_name, type, options = {})
  default = options[:default]
  notnull = options[:null] == false

  # Add the column.
  execute("ALTER TABLE #{quote_table_name(table_name)} ADD COLUMN #{quote_column_name(column_name)} #{type_to_sql(type, options[:limit], options[:precision], options[:scale])}")

  change_column_default(table_name, column_name, default) if options_include_default?(options)
  change_column_null(table_name, column_name, false, default) if notnull
end
add_order_by_for_association_limiting!(sql, options) click to toggle source

ORDER BY clause for the passed order option.

PostgreSQL does not allow arbitrary ordering when using DISTINCT ON, so we work around this by wrapping the sql as a sub-select and ordering in that query.

# File lib/arjdbc/postgresql/adapter.rb, line 630
def add_order_by_for_association_limiting!(sql, options)
  return sql if options[:order].blank?

  order = options[:order].split(',').collect { |s| s.strip }.reject(&:blank?)
  order.map! { |s| 'DESC' if s =~ /\bdesc$/ }
  order = order.zip((0...order.size).to_a).map { |s,i| "id_list.alias_#{i} #{s}" }.join(', ')

  sql.replace "SELECT * FROM (#{sql}) AS id_list ORDER BY #{order}"
end
all_schemas() click to toggle source
# File lib/arjdbc/postgresql/adapter.rb, line 544
def all_schemas
  select('select nspname from pg_namespace').map {|r| r["nspname"] }
end
change_column(table_name, column_name, type, options = {}) click to toggle source

Changes the column of a table.

# File lib/arjdbc/postgresql/adapter.rb, line 752
def change_column(table_name, column_name, type, options = {})
  quoted_table_name = quote_table_name(table_name)

  begin
    execute "ALTER TABLE #{quoted_table_name} ALTER COLUMN #{quote_column_name(column_name)} TYPE #{type_to_sql(type, options[:limit], options[:precision], options[:scale])}"
  rescue ActiveRecord::StatementInvalid => e
    raise e if postgresql_version > 80000
    # This is PostgreSQL 7.x, so we have to use a more arcane way of doing it.
    begin
      begin_db_transaction
      tmp_column_name = "#{column_name}_ar_tmp"
      add_column(table_name, tmp_column_name, type, options)
      execute "UPDATE #{quoted_table_name} SET #{quote_column_name(tmp_column_name)} = CAST(#{quote_column_name(column_name)} AS #{type_to_sql(type, options[:limit], options[:precision], options[:scale])})"
      remove_column(table_name, column_name)
      rename_column(table_name, tmp_column_name, column_name)
      commit_db_transaction
    rescue
      rollback_db_transaction
    end
  end

  change_column_default(table_name, column_name, options[:default]) if options_include_default?(options)
  change_column_null(table_name, column_name, options[:null], options[:default]) if options.key?(:null)
end
change_column_default(table_name, column_name, default) click to toggle source

Changes the default value of a table column.

# File lib/arjdbc/postgresql/adapter.rb, line 778
def change_column_default(table_name, column_name, default)
  execute "ALTER TABLE #{quote_table_name(table_name)} ALTER COLUMN #{quote_column_name(column_name)} SET DEFAULT #{quote(default)}"
end
change_column_null(table_name, column_name, null, default = nil) click to toggle source
# File lib/arjdbc/postgresql/adapter.rb, line 782
def change_column_null(table_name, column_name, null, default = nil)
  unless null || default.nil?
    execute("UPDATE #{quote_table_name(table_name)} SET #{quote_column_name(column_name)}=#{quote(default)} WHERE #{quote_column_name(column_name)} IS NULL")
  end
  execute("ALTER TABLE #{quote_table_name(table_name)} ALTER #{quote_column_name(column_name)} #{null ? 'DROP' : 'SET'} NOT NULL")
end
client_min_messages() click to toggle source

Returns the current client message level.

# File lib/arjdbc/postgresql/adapter.rb, line 598
def client_min_messages
  exec_query('SHOW client_min_messages', 'SCHEMA')[0]['client_min_messages']
end
client_min_messages=(level) click to toggle source

Set the client message level.

# File lib/arjdbc/postgresql/adapter.rb, line 603
def client_min_messages=(level)
  execute("SET client_min_messages TO '#{level}'", 'SCHEMA')
end
configure_connection() click to toggle source
# File lib/arjdbc/postgresql/adapter.rb, line 21
def configure_connection
  self.standard_conforming_strings = true
end
create_database(name, options = {}) click to toggle source
# File lib/arjdbc/postgresql/adapter.rb, line 512
def create_database(name, options = {})
  options = options.with_indifferent_access
  create_query = "CREATE DATABASE \"#{name}\" ENCODING='#{options[:encoding] || 'utf8'}'"
  create_query += options.symbolize_keys.sum('') do |key, value|
    case key
      when :owner
        " OWNER = \"#{value}\""
      when :template
        " TEMPLATE = \"#{value}\""
      when :tablespace
        " TABLESPACE = \"#{value}\""
      when :connection_limit
        " CONNECTION LIMIT = #{value}"
      else
        ""
    end
  end
  execute create_query
end
create_savepoint() click to toggle source
# File lib/arjdbc/postgresql/adapter.rb, line 280
def create_savepoint
  execute("SAVEPOINT #{current_savepoint_name}")
end
create_schema(schema_name, pg_username) click to toggle source
# File lib/arjdbc/postgresql/adapter.rb, line 536
def create_schema(schema_name, pg_username)
  execute("CREATE SCHEMA \"#{schema_name}\" AUTHORIZATION \"#{pg_username}\"")
end
current_database() click to toggle source

current database name

# File lib/arjdbc/postgresql/adapter.rb, line 431
def current_database
  exec_query("select current_database() as database").
    first["database"]
end
current_schema() click to toggle source

Returns the current schema name.

# File lib/arjdbc/postgresql/adapter.rb, line 593
def current_schema
  exec_query('SELECT current_schema', 'SCHEMA')[0]["current_schema"]
end
default_sequence_name(table_name, pk = nil) click to toggle source
# File lib/arjdbc/postgresql/adapter.rb, line 298
def default_sequence_name(table_name, pk = nil)
  default_pk, default_seq = pk_and_sequence_for(table_name)
  default_seq || "#{table_name}_#{pk || default_pk || 'id'}_seq"
end
drop_database(name) click to toggle source
# File lib/arjdbc/postgresql/adapter.rb, line 532
def drop_database(name)
  execute "DROP DATABASE IF EXISTS \"#{name}\""
end
drop_schema(schema_name) click to toggle source
# File lib/arjdbc/postgresql/adapter.rb, line 540
def drop_schema(schema_name)
  execute("DROP SCHEMA \"#{schema_name}\"")
end
encoding() click to toggle source

current database encoding

# File lib/arjdbc/postgresql/adapter.rb, line 437
def encoding
  exec_query(        SELECT pg_encoding_to_char(pg_database.encoding) as encoding        FROM pg_database        WHERE pg_database.datname LIKE '#{current_database}').first["encoding"]
end
escape_bytea(string) click to toggle source
# File lib/arjdbc/postgresql/adapter.rb, line 687
def escape_bytea(string)
  if string
    if supports_hex_escaped_bytea?
      "\\\\x#{string.unpack("H*")[0]}"
    else
      result = ''
      string.each_byte { |c| result << sprintf('\\%03o', c) }
      result
    end
  end
end
extract_schema_and_table(name) click to toggle source

Extracts the table and schema name from name

# File lib/arjdbc/postgresql/adapter.rb, line 843
def extract_schema_and_table(name)
  schema, table = name.split('.', 2)

  unless table # A table was provided without a schema
    table  = schema
    schema = nil
  end

  if name =~ /^"/ # Handle quoted table names
    table  = name
    schema = nil
  end
  [schema, table]
end
index_name_length() click to toggle source
# File lib/arjdbc/postgresql/adapter.rb, line 797
def index_name_length
  63
end
indexes(table_name, name = nil) click to toggle source

Based on postgresql_adapter.rb

# File lib/arjdbc/postgresql/adapter.rb, line 456
def indexes(table_name, name = nil)
  schemas = schema_search_path.split(/,/).map { |p| quote(p) }.join(',')
  result = select_rows(        SELECT i.relname, d.indisunique, a.attname, a.attnum, d.indkey          FROM pg_class t, pg_class i, pg_index d, pg_attribute a,          generate_series(0,#{multi_column_index_limit - 1}) AS s(i)         WHERE i.relkind = 'i'           AND d.indexrelid = i.oid           AND d.indisprimary = 'f'           AND t.oid = d.indrelid           AND t.relname = '#{table_name}'           AND i.relnamespace IN (SELECT oid FROM pg_namespace WHERE nspname = ANY (current_schemas(false)) )           AND a.attrelid = t.oid           AND d.indkey[s.i]=a.attnum        ORDER BY i.relname, name)

  current_index = nil
  indexes = []

  insertion_order = []
  index_order = nil

  result.each do |row|
    if current_index != row[0]

      (index_order = row[4].split(' ')).each_with_index{ |v, i| index_order[i] = v.to_i }
      indexes << ::ActiveRecord::ConnectionAdapters::IndexDefinition.new(table_name, row[0], row[1] == "t", [])
      current_index = row[0]
    end
    insertion_order = row[3]
    ind = index_order.index(insertion_order)
    indexes.last.columns[ind] = row[2]
  end

  indexes
end
insert_sql(sql, name = nil, pk = nil, id_value = nil, sequence_name = nil, binds = []) click to toggle source

Insert logic for pre-AR-3.1 adapters

# File lib/arjdbc/postgresql/adapter.rb, line 372
def insert_sql(sql, name = nil, pk = nil, id_value = nil, sequence_name = nil, binds = [])
  # Extract the table from the insert sql. Yuck.
  table = sql.split(" ", 4)[2].gsub('"', '')

  # Try an insert with 'returning id' if available (PG >= 8.2)
  if supports_insert_with_returning? && id_value.nil?
    pk, sequence_name = *pk_and_sequence_for(table) unless pk
    if pk
      sql = to_sql(sql, binds)
      return select_value("#{sql} RETURNING #{quote_column_name(pk)}")
    end
  end

  # Otherwise, plain insert
  execute(sql, name, binds)

  # Don't need to look up id_value if we already have it.
  # (and can't in case of non-sequence PK)
  unless id_value
    # If neither pk nor sequence name is given, look them up.
    unless pk || sequence_name
      pk, sequence_name = *pk_and_sequence_for(table)
    end

    # If a pk is given, fallback to default sequence name.
    # Don't fetch last insert id for a table without a pk.
    if pk && sequence_name ||= default_sequence_name(table, pk)
      id_value = last_insert_id(table, sequence_name)
    end
  end
  id_value
end
last_insert_id(table, sequence_name) click to toggle source
# File lib/arjdbc/postgresql/adapter.rb, line 503
def last_insert_id(table, sequence_name)
  Integer(select_value("SELECT currval('#{sequence_name}')"))
end
last_inserted_id(result) click to toggle source

take id from result of insert query

# File lib/arjdbc/postgresql/adapter.rb, line 495
def last_inserted_id(result)
  if result.is_a? Fixnum
    result
  else
    result.first.first[1]
  end
end
multi_column_index_limit() click to toggle source

Gets the maximum number columns postgres has, default 32

# File lib/arjdbc/postgresql/adapter.rb, line 451
def multi_column_index_limit
  defined?(@multi_column_index_limit) && @multi_column_index_limit || 32
end
multi_column_index_limit=(limit) click to toggle source

Sets the maximum number columns postgres has, default 32

# File lib/arjdbc/postgresql/adapter.rb, line 446
def multi_column_index_limit=(limit)
  @multi_column_index_limit = limit
end
native_database_types() click to toggle source
# File lib/arjdbc/postgresql/adapter.rb, line 209
def native_database_types
  NATIVE_DATABASE_TYPES
end
pg_columns(table_name, name=nil) click to toggle source
# File lib/arjdbc/postgresql/adapter.rb, line 422
def pg_columns(table_name, name=nil)
  column_definitions(table_name).map do |row|
    ::ActiveRecord::ConnectionAdapters::PostgreSQLColumn.new(
      row["column_name"], row["column_default"], row["column_type"],
      row["column_not_null"] == "f")
  end
end
postgresql_version() click to toggle source
# File lib/arjdbc/postgresql/adapter.rb, line 180
def postgresql_version
  @postgresql_version ||=
    begin
      value = select_value('SELECT version()')
      if value =~ /PostgreSQL (\d+)\.(\d+)\.(\d+)/
        ($1.to_i * 10000) + ($2.to_i * 100) + $3.to_i
      else
        0
      end
    end
end
primary_key(table) click to toggle source
# File lib/arjdbc/postgresql/adapter.rb, line 417
def primary_key(table)
  pk_and_sequence = pk_and_sequence_for(table)
  pk_and_sequence && pk_and_sequence.first
end
quote_column_name(name) click to toggle source
# File lib/arjdbc/postgresql/adapter.rb, line 710
def quote_column_name(name)
  %("#{name.to_s.gsub("\"", "\"\"")}")
end
quote_string(string) click to toggle source

Quotes a string, escaping any ' (single quote) and \ (backslash) characters.

# File lib/arjdbc/postgresql/adapter.rb, line 679
def quote_string(string)
  quoted = string.gsub("'", "''")
  unless standard_conforming_strings?
    quoted.gsub!(/\\/, '\&\&')
  end
  quoted
end
quote_table_name(name) click to toggle source
# File lib/arjdbc/postgresql/adapter.rb, line 699
def quote_table_name(name)
  schema, name_part = extract_pg_identifier_from_name(name.to_s)
    
  unless name_part
    quote_column_name(schema)
  else
    table_name, name_part = extract_pg_identifier_from_name(name_part)
    "#{quote_column_name(schema)}.#{quote_column_name(table_name)}"
  end
end
recreate_database(name, options = {}) click to toggle source
# File lib/arjdbc/postgresql/adapter.rb, line 507
def recreate_database(name, options = {})
  drop_database(name)
  create_database(name, options)
end
release_savepoint() click to toggle source
# File lib/arjdbc/postgresql/adapter.rb, line 288
def release_savepoint
  execute("RELEASE SAVEPOINT #{current_savepoint_name}")
end
rename_table(name, new_name) click to toggle source
# File lib/arjdbc/postgresql/adapter.rb, line 729
def rename_table(name, new_name)
  execute "ALTER TABLE #{name} RENAME TO #{new_name}"
  pk, seq = pk_and_sequence_for(new_name)
  if seq == "#{name}_#{pk}_seq"
    new_seq = "#{new_name}_#{pk}_seq"
    execute "ALTER TABLE #{quote_table_name(seq)} RENAME TO #{quote_table_name(new_seq)}"
  end
end
rollback_to_savepoint() click to toggle source
# File lib/arjdbc/postgresql/adapter.rb, line 284
def rollback_to_savepoint
  execute("ROLLBACK TO SAVEPOINT #{current_savepoint_name}")
end
schema_search_path() click to toggle source

Returns the active schema search path.

# File lib/arjdbc/postgresql/adapter.rb, line 588
def schema_search_path
  @schema_search_path ||= exec_query('SHOW search_path', 'SCHEMA')[0]['search_path']
end
schema_search_path=(schema_csv) click to toggle source

Sets the schema search path to a string of comma-separated schema names. Names beginning with $ have to be quoted (e.g. $user => '$user'). See: www.postgresql.org/docs/current/static/ddl-schemas.html

This should be not be called manually but set in database.yml.

# File lib/arjdbc/postgresql/adapter.rb, line 580
def schema_search_path=(schema_csv)
  if schema_csv
    execute "SET search_path TO #{schema_csv}"
    @schema_search_path = schema_csv
  end
end
sql_for_insert(sql, pk, id_value, sequence_name, binds) click to toggle source

taken from rails postgresql_adapter.rb

# File lib/arjdbc/postgresql/adapter.rb, line 406
def sql_for_insert(sql, pk, id_value, sequence_name, binds)
  unless pk
    table_ref = extract_table_ref_from_insert_sql(sql)
    pk = primary_key(table_ref) if table_ref
  end

  sql = "#{sql} RETURNING #{quote_column_name(pk)}" if pk

  [sql, binds]
end
standard_conforming_strings=(enable) click to toggle source

Enable standard-conforming strings if available.

# File lib/arjdbc/postgresql/adapter.rb, line 214
def standard_conforming_strings=(enable)
  client_min_messages = self.client_min_messages
  begin
    self.client_min_messages = 'panic'
    value = enable ? "on" : "off"
    execute("SET standard_conforming_strings = #{value}", 'SCHEMA')
    @standard_conforming_strings = ( value == "on" )
  rescue
    @standard_conforming_strings = :unsupported
  ensure
    self.client_min_messages = client_min_messages
  end
end
structure_dump() click to toggle source
# File lib/arjdbc/postgresql/adapter.rb, line 548
def structure_dump
  database = @config[:database]
  if database.nil?
    if @config[:url] =~ /\/([^\/]*)$/
      database = $1
    else
      raise "Could not figure out what database this url is for #{@config["url"]}"
    end
  end

  ENV['PGHOST']     = @config[:host] if @config[:host]
  ENV['PGPORT']     = @config[:port].to_s if @config[:port]
  ENV['PGPASSWORD'] = @config[:password].to_s if @config[:password]
  search_path = "--schema=#{@config[:schema_search_path]}" if @config[:schema_search_path]

  @connection.connection.close
  begin
    definition = `pg_dump -i -U "#{@config[:username]}" -s -x -O #{search_path} #{database}`
    raise "Error dumping database" if $?.exitstatus == 1

    # need to patch away any references to SQL_ASCII as it breaks the JDBC driver
    definition.gsub(/SQL_ASCII/, 'UNICODE')
  ensure
    reconnect!
  end
end
table_alias_length() click to toggle source

Returns the configured supported identifier length supported by PostgreSQL, or report the default of 63 on PostgreSQL 7.x.

# File lib/arjdbc/postgresql/adapter.rb, line 294
def table_alias_length
  @table_alias_length ||= (postgresql_version >= 80000 ? select_one('SHOW max_identifier_length')['max_identifier_length'].to_i : 63)
end
table_exists?(name) click to toggle source
# File lib/arjdbc/postgresql/adapter.rb, line 827
def table_exists?(name)
  schema, table = extract_schema_and_table(name.to_s)
  return false unless table # Abstract classes is having nil table name

  binds = [[nil, table.gsub(/(^"|"$)/,'')]]
  binds << [nil, schema] if schema

  exec_query(          SELECT COUNT(*) as table_count          FROM pg_tables          WHERE tablename = ?          AND schemaname = #{schema ? "?" : "ANY (current_schemas(false))"}, 'SCHEMA', binds).first["table_count"] > 0
end
tables(name = nil) click to toggle source
# File lib/arjdbc/postgresql/adapter.rb, line 819
def tables(name = nil)
  exec_query(          SELECT tablename          FROM pg_tables          WHERE schemaname = ANY (current_schemas(false)), 'SCHEMA').map { |row| row["tablename"] }
end
type_to_sql(type, limit = nil, precision = nil, scale = nil) click to toggle source

Maps logical Rails types to PostgreSQL-specific data types.

# File lib/arjdbc/postgresql/adapter.rb, line 802
def type_to_sql(type, limit = nil, precision = nil, scale = nil)
  case type.to_sym
  when :integer
    return 'integer' unless limit
    case limit.to_i
      when 1, 2; 'smallint'
      when 3, 4; 'integer'
      when 5..8; 'bigint'
      else raise(ActiveRecordError, "No integer type has byte size #{limit}. Use a numeric with precision 0 instead.")
    end
  when :binary
    super(type, nil, nil, nil)
  else
    super
  end
end

[Validate]

Generated with the Darkfish Rdoc Generator 2.