The PostgreSQL adapter works both with the C-based (www.postgresql.jp/interfaces/ruby/) and the Ruby-base (available both as gem and from rubyforge.org/frs/?group_id=234&release_id=1145) drivers.
Options:
-
:host
-- Defaults to localhost -
:port
-- Defaults to 5432 -
:username
-- Defaults to nothing -
:password
-- Defaults to nothing -
:database
-- The name of the database. No default, must be provided. -
: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 using in a SET client_encoding TO <encoding> call on connection. -
:min_messages
-- An optional client min messages that is using in a SET client_min_messages TO <min_messages> call on connection. -
:allow_concurrency
-- If true, use async query methods so Ruby threads don't deadlock; otherwise, use blocking query methods.
- A
- D
- N
- P
- Q
- R
- S
- T
BYTEA_COLUMN_TYPE_OID | = | 17 |
NUMERIC_COLUMN_TYPE_OID | = | 1700 |
TIMESTAMPOID | = | 1114 |
TIMESTAMPTZOID | = | 1184 |
Source: show
# File rails/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb, line 55 def initialize(connection, logger, config = {}) super(connection, logger) @config = config @async = config[:allow_concurrency] configure_connection end
Is this connection alive and ready for queries?
Source: show
# File rails/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb, line 63 def active? if @connection.respond_to?(:status) @connection.status == PGconn::CONNECTION_OK else @connection.query 'SELECT 1' true end # postgres-pr raises a NoMethodError when querying if no conn is available rescue PGError, NoMethodError false end
Source: show
# File rails/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb, line 51 def adapter_name 'PostgreSQL' end
Source: show
# File rails/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb, line 316 def add_column(table_name, column_name, type, options = {}) default = options[:default] notnull = options[:null] == false # Add the column. execute("ALTER TABLE #{table_name} ADD COLUMN #{column_name} #{type_to_sql(type, options[:limit])}") # Set optional default. If not null, update nulls to the new default. if options_include_default?(options) change_column_default(table_name, column_name, default) if notnull execute("UPDATE #{table_name} SET #{column_name}=#{quote(default, options[:column])} WHERE #{column_name} IS NULL") end end if notnull execute("ALTER TABLE #{table_name} ALTER #{column_name} SET NOT NULL") end end
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.
Source: show
# File rails/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb, line 403 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 =~ %r\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
Source: show
# File rails/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb, line 243 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
Source: show
# File rails/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb, line 84 def disconnect! # Both postgres and postgres-pr respond to :close @connection.close rescue nil end
SELECT DISTINCT clause for a given set of columns and a given ORDER BY clause.
PostgreSQL requires the ORDER BY columns in the select list for distinct queries, and requires that the ORDER BY include the distinct column.
distinct("posts.id", "posts.created_at desc")
Source: show
# File rails/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb, line 384 def distinct(columns, order_by) return "DISTINCT #{columns}" if order_by.blank? # construct a clean list of column names from the ORDER BY clause, removing # any asc/desc modifiers order_columns = order_by.split(',').collect { |s| s.split.first } order_columns.delete_if &:blank? order_columns = order_columns.zip((0...order_columns.size).to_a).map { |s,i| "#{s} AS alias_#{i}" } # return a DISTINCT ON() clause that's distinct on the columns we want but includes # all the required columns for the ORDER BY to work properly sql = "DISTINCT ON (#{columns}) #{columns}, " sql << order_columns * ', ' end
Source: show
# File rails/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb, line 89 def native_database_types { :primary_key => "serial primary key", :string => { :name => "character varying", :limit => 255 }, :text => { :name => "text" }, :integer => { :name => "integer" }, :float => { :name => "float" }, :decimal => { :name => "decimal" }, :datetime => { :name => "timestamp" }, :timestamp => { :name => "timestamp" }, :time => { :name => "time" }, :date => { :name => "date" }, :binary => { :name => "bytea" }, :boolean => { :name => "boolean" } } end
Find a table’s primary key and sequence.
Source: show
# File rails/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb, line 267 def pk_and_sequence_for(table) # First try looking for a sequence with a dependency on the # given table's primary key. result = query(" SELECT attr.attname, name.nspname, seq.relname FROM pg_class seq, pg_attribute attr, pg_depend dep, pg_namespace name, pg_constraint cons WHERE seq.oid = dep.objid AND seq.relnamespace = name.oid AND seq.relkind = 'S' AND attr.attrelid = dep.refobjid AND attr.attnum = dep.refobjsubid AND attr.attrelid = cons.conrelid AND attr.attnum = cons.conkey[1] AND cons.contype = 'p' AND dep.refobjid = '#{table}'::regclass ", 'PK and serial sequence')[0] if result.nil? or result.empty? # If that fails, try parsing the primary key's default value. # Support the 7.x and 8.0 nextval('foo'::text) as well as # the 8.1+ nextval('foo'::regclass). # TODO: assumes sequence is in same schema as table. result = query(" SELECT attr.attname, name.nspname, split_part(def.adsrc, '''', 2) FROM pg_class t JOIN pg_namespace name ON (t.relnamespace = name.oid) JOIN pg_attribute attr ON (t.oid = attrelid) JOIN pg_attrdef def ON (adrelid = attrelid AND adnum = attnum) JOIN pg_constraint cons ON (conrelid = adrelid AND adnum = conkey[1]) WHERE t.oid = '#{table}'::regclass AND cons.contype = 'p' AND def.adsrc ~* 'nextval' ", 'PK and custom sequence')[0] end # check for existence of . in sequence name as in public.foo_sequence. if it does not exist, return unqualified sequence # We cannot qualify unqualified sequences, as rails doesn't qualify any table access, using the search path [result.first, result.last] rescue nil end
QUOTING ==================================================
Source: show
# File rails/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb, line 116 def quote(value, column = nil) if value.kind_of?(String) && column && column.type == :binary "'#{escape_bytea(value)}'" else super end end
Source: show
# File rails/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb, line 124 def quote_column_name(name) %Q("#{name}") end
Source: show
# File rails/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb, line 128 def quoted_date(value) value.strftime("%Y-%m-%d %H:%M:%S.#{sprintf("%06d", value.usec)}") end
Close then reopen the connection.
Source: show
# File rails/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb, line 76 def reconnect! # TODO: postgres-pr doesn't have PGconn#reset. if @connection.respond_to?(:reset) @connection.reset configure_connection end end
Source: show
# File rails/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb, line 312 def rename_table(name, new_name) execute "ALTER TABLE #{name} RENAME TO #{new_name}" end
Resets sequence to the max value of the table’s pk if present.
Source: show
# File rails/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb, line 249 def reset_pk_sequence!(table, pk = nil, sequence = nil) unless pk and sequence default_pk, default_sequence = pk_and_sequence_for(table) pk ||= default_pk sequence ||= default_sequence end if pk if sequence select_value " SELECT setval('#{sequence}', (SELECT COALESCE(MAX(#{pk})+(SELECT increment_by FROM #{sequence}), (SELECT min_value FROM #{sequence})) FROM #{table}), false) ", 'Reset sequence' else @logger.warn "#{table} has primary key #{pk} with no default sequence" if @logger end end end
Source: show
# File rails/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb, line 106 def supports_migrations? true end
Source: show
# File rails/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb, line 110 def table_alias_length 63 end