active?()
click to toggle source
Is this connection alive and ready for queries?
343: def active?
344: @connection.query 'SELECT 1'
345: true
346: rescue PGError
347: false
348: end
adapter_name()
click to toggle source
Returns ‘PostgreSQL’ as adapter name for identification
purposes.
238: def adapter_name
239: ADAPTER_NAME
240: end
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.
1020: def add_column(table_name, column_name, type, options = {})
1021: clear_cache!
1022: add_column_sql = "ALTER TABLE #{quote_table_name(table_name)} ADD COLUMN #{quote_column_name(column_name)} #{type_to_sql(type, options[:limit], options[:precision], options[:scale])}"
1023: add_column_options!(add_column_sql, options)
1024:
1025: execute add_column_sql
1026: end
begin_db_transaction()
click to toggle source
Begins a transaction.
700: def begin_db_transaction
701: execute "BEGIN"
702: end
change_column(table_name, column_name, type, options = {})
click to toggle source
Changes the column of a table.
1029: def change_column(table_name, column_name, type, options = {})
1030: clear_cache!
1031: quoted_table_name = quote_table_name(table_name)
1032:
1033: execute "ALTER TABLE #{quoted_table_name} ALTER COLUMN #{quote_column_name(column_name)} TYPE #{type_to_sql(type, options[:limit], options[:precision], options[:scale])}"
1034:
1035: change_column_default(table_name, column_name, options[:default]) if options_include_default?(options)
1036: change_column_null(table_name, column_name, options[:null], options[:default]) if options.key?(:null)
1037: end
change_column_default(table_name, column_name, default)
click to toggle source
Changes the default value of a table column.
1040: def change_column_default(table_name, column_name, default)
1041: clear_cache!
1042: execute "ALTER TABLE #{quote_table_name(table_name)} ALTER COLUMN #{quote_column_name(column_name)} SET DEFAULT #{quote(default)}"
1043: end
change_column_null(table_name, column_name, null, default = nil)
click to toggle source
1045: def change_column_null(table_name, column_name, null, default = nil)
1046: clear_cache!
1047: unless null || default.nil?
1048: execute("UPDATE #{quote_table_name(table_name)} SET #{quote_column_name(column_name)}=#{quote(default)} WHERE #{quote_column_name(column_name)} IS NULL")
1049: end
1050: execute("ALTER TABLE #{quote_table_name(table_name)} ALTER #{quote_column_name(column_name)} #{null ? 'DROP' : 'SET'} NOT NULL")
1051: end
clear_cache!()
click to toggle source
Clears the prepared statements cache.
338: def clear_cache!
339: @statements.clear
340: end
client_min_messages()
click to toggle source
Returns the current client message level.
898: def client_min_messages
899: query('SHOW client_min_messages', 'SCHEMA')[0][0]
900: end
client_min_messages=(level)
click to toggle source
Set the client message level.
903: def client_min_messages=(level)
904: execute("SET client_min_messages TO '#{level}'", 'SCHEMA')
905: end
columns(table_name, name = nil)
click to toggle source
Returns the list of all column definitions for a table.
855: def columns(table_name, name = nil)
856:
857: column_definitions(table_name).collect do |column_name, type, default, notnull|
858: PostgreSQLColumn.new(column_name, default, type, notnull == 'f')
859: end
860: end
commit_db_transaction()
click to toggle source
Commits a transaction.
705: def commit_db_transaction
706: execute "COMMIT"
707: end
create_database(name, options = {})
click to toggle source
Create a new PostgreSQL database. Options include :owner,
:template, :encoding, :tablespace, and
:connection_limit (note that MySQL uses :charset while
PostgreSQL uses :encoding).
Example:
create_database config[:database], config
create_database 'foo_development', :encoding => 'unicode'
746: def create_database(name, options = {})
747: options = options.reverse_merge(:encoding => "utf8")
748:
749: option_string = options.symbolize_keys.sum do |key, value|
750: case key
751: when :owner
752: " OWNER = \"#{value}\""
753: when :template
754: " TEMPLATE = \"#{value}\""
755: when :encoding
756: " ENCODING = '#{value}'"
757: when :tablespace
758: " TABLESPACE = \"#{value}\""
759: when :connection_limit
760: " CONNECTION LIMIT = #{value}"
761: else
762: ""
763: end
764: end
765:
766: execute "CREATE DATABASE #{quote_table_name(name)}#{option_string}"
767: end
create_savepoint()
click to toggle source
718: def create_savepoint
719: execute("SAVEPOINT #{current_savepoint_name}")
720: end
current_database()
click to toggle source
Returns the current database name.
863: def current_database
864: query('select current_database()', 'SCHEMA')[0][0]
865: end
current_schema()
click to toggle source
Returns the current schema name.
868: def current_schema
869: query('SELECT current_schema', 'SCHEMA')[0][0]
870: end
disconnect!()
click to toggle source
Disconnects from the database if already connected. Otherwise, this method
does nothing.
365: def disconnect!
366: clear_cache!
367: @connection.close rescue nil
368: end
encoding()
click to toggle source
Returns the current database encoding format.
873: def encoding
874: query( SELECT pg_encoding_to_char(pg_database.encoding) FROM pg_database WHERE pg_database.datname LIKE '#{current_database}', 'SCHEMA')[0][0]
875: end
escape_bytea(value)
click to toggle source
Escapes binary strings for bytea input to the database.
418: def escape_bytea(value)
419: @connection.escape_bytea(value) if value
420: end
exec_delete(sql, name = 'SQL', binds = [])
click to toggle source
671: def exec_delete(sql, name = 'SQL', binds = [])
672: log(sql, name, binds) do
673: result = binds.empty? ? exec_no_cache(sql, binds) :
674: exec_cache(sql, binds)
675: affected = result.cmd_tuples
676: result.clear
677: affected
678: end
679: end
exec_query(sql, name = 'SQL', binds = [])
click to toggle source
660: def exec_query(sql, name = 'SQL', binds = [])
661: log(sql, name, binds) do
662: result = binds.empty? ? exec_no_cache(sql, binds) :
663: exec_cache(sql, binds)
664:
665: ret = ActiveRecord::Result.new(result.fields, result_as_array(result))
666: result.clear
667: return ret
668: end
669: end
exec_update(sql, name = 'SQL', binds = [])
click to toggle source
execute(sql, name = nil)
click to toggle source
Executes an SQL statement, returning a PGresult object on success or
raising a PGError exception otherwise.
650: def execute(sql, name = nil)
651: log(sql, name) do
652: @connection.async_exec(sql)
653: end
654: end
explain(arel, binds = [])
click to toggle source
DATABASE STATEMENTS ======================================
534: def explain(arel, binds = [])
535: sql = "EXPLAIN #{to_sql(arel, binds)}"
536: ExplainPrettyPrinter.new.pp(exec_query(sql, 'EXPLAIN', binds))
537: end
index_name_length()
click to toggle source
1067: def index_name_length
1068: 63
1069: end
indexes(table_name, name = nil)
click to toggle source
Returns an array of indexes for the given table.
816: def indexes(table_name, name = nil)
817: result = query( SELECT distinct i.relname, d.indisunique, d.indkey, pg_get_indexdef(d.indexrelid), t.oid FROM pg_class t INNER JOIN pg_index d ON t.oid = d.indrelid INNER JOIN pg_class i ON d.indexrelid = i.oid WHERE i.relkind = 'i' AND d.indisprimary = 'f' AND t.relname = '#{table_name}' AND i.relnamespace IN (SELECT oid FROM pg_namespace WHERE nspname = ANY (current_schemas(false)) ) ORDER BY i.relname, 'SCHEMA')
818:
819:
820: result.map do |row|
821: index_name = row[0]
822: unique = row[1] == 't'
823: indkey = row[2].split(" ")
824: inddef = row[3]
825: oid = row[4]
826:
827: columns = Hash[query( SELECT a.attnum, a.attname FROM pg_attribute a WHERE a.attrelid = #{oid} AND a.attnum IN (#{indkey.join(",")}), "SCHEMA")]
828:
829: column_names = columns.values_at(*indkey).compact
830:
831:
832: desc_order_columns = inddef.scan(/(\w+) DESC/).flatten
833: orders = desc_order_columns.any? ? Hash[desc_order_columns.map {|order_column| [order_column, :desc]}] : {}
834:
835: column_names.empty? ? nil : IndexDefinition.new(table_name, index_name, unique, column_names, [], orders)
836: end.compact
837: end
insert_sql(sql, name = nil, pk = nil, id_value = nil, sequence_name = nil)
click to toggle source
Executes an INSERT query and returns the new record’s ID
583: def insert_sql(sql, name = nil, pk = nil, id_value = nil, sequence_name = nil)
584: unless pk
585:
586: table_ref = extract_table_ref_from_insert_sql(sql)
587: pk = primary_key(table_ref) if table_ref
588: end
589:
590: if pk
591: select_value("#{sql} RETURNING #{quote_column_name(pk)}")
592: else
593: super
594: end
595: end
outside_transaction?()
click to toggle source
714: def outside_transaction?
715: @connection.transaction_status == PGconn::PQTRANS_IDLE
716: end
primary_key(table)
click to toggle source
Returns just a table’s primary key
989: def primary_key(table)
990: row = exec_query( SELECT DISTINCT(attr.attname) FROM pg_attribute attr INNER JOIN pg_depend dep ON attr.attrelid = dep.refobjid AND attr.attnum = dep.refobjsubid INNER JOIN pg_constraint cons ON attr.attrelid = cons.conrelid AND attr.attnum = cons.conkey[1] WHERE cons.contype = 'p' AND dep.refobjid = '#{quote_table_name(table)}'::regclass, 'SCHEMA').rows.first
991:
992: row && row.first
993: end
quote_table_name(name)
click to toggle source
Checks the following cases:
483: def quote_table_name(name)
484: schema, name_part = extract_pg_identifier_from_name(name.to_s)
485:
486: unless name_part
487: quote_column_name(schema)
488: else
489: table_name, name_part = extract_pg_identifier_from_name(name_part)
490: "#{quote_column_name(schema)}.#{quote_column_name(table_name)}"
491: end
492: end
reconnect!()
click to toggle source
Close then reopen the connection.
351: def reconnect!
352: clear_cache!
353: @connection.reset
354: @open_transactions = 0
355: configure_connection
356: end
release_savepoint()
click to toggle source
726: def release_savepoint
727: execute("RELEASE SAVEPOINT #{current_savepoint_name}")
728: end
rename_column(table_name, column_name, new_column_name)
click to toggle source
Renames a column in a table.
1054: def rename_column(table_name, column_name, new_column_name)
1055: clear_cache!
1056: execute "ALTER TABLE #{quote_table_name(table_name)} RENAME COLUMN #{quote_column_name(column_name)} TO #{quote_column_name(new_column_name)}"
1057: end
rename_index(table_name, old_name, new_name)
click to toggle source
1063: def rename_index(table_name, old_name, new_name)
1064: execute "ALTER INDEX #{quote_column_name(old_name)} RENAME TO #{quote_table_name(new_name)}"
1065: end
rename_table(name, new_name)
click to toggle source
Renames a table. Also renames a table’s primary key sequence if the
sequence name matches the Active Record default.
Example:
rename_table('octopuses', 'octopi')
1008: def rename_table(name, new_name)
1009: clear_cache!
1010: execute "ALTER TABLE #{quote_table_name(name)} RENAME TO #{quote_table_name(new_name)}"
1011: pk, seq = pk_and_sequence_for(new_name)
1012: if seq == "#{name}_#{pk}_seq"
1013: new_seq = "#{new_name}_#{pk}_seq"
1014: execute "ALTER TABLE #{quote_table_name(seq)} RENAME TO #{quote_table_name(new_seq)}"
1015: end
1016: end
reset!()
click to toggle source
358: def reset!
359: clear_cache!
360: super
361: end
rollback_db_transaction()
click to toggle source
Aborts a transaction.
710: def rollback_db_transaction
711: execute "ROLLBACK"
712: end
rollback_to_savepoint()
click to toggle source
722: def rollback_to_savepoint
723: execute("ROLLBACK TO SAVEPOINT #{current_savepoint_name}")
724: end
schema_exists?(name)
click to toggle source
Returns true if schema exists.
807: def schema_exists?(name)
808: exec_query( SELECT COUNT(*) FROM pg_namespace WHERE nspname = '#{name}', 'SCHEMA').rows.first[0].to_i > 0
809: end
schema_search_path()
click to toggle source
Returns the active schema search path.
893: def schema_search_path
894: @schema_search_path ||= query('SHOW search_path', 'SCHEMA')[0][0]
895: 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.
885: def schema_search_path=(schema_csv)
886: if schema_csv
887: execute("SET search_path TO #{schema_csv}", 'SCHEMA')
888: @schema_search_path = schema_csv
889: end
890: end
select_rows(sql, name = nil)
click to toggle source
Executes a SELECT query and returns an array of rows. Each row is an array
of field values.
578: def select_rows(sql, name = nil)
579: select_raw(sql, name).last
580: end
serial_sequence(table, column)
click to toggle source
914: def serial_sequence(table, column)
915: result = exec_query( SELECT pg_get_serial_sequence('#{table}', '#{column}'), 'SCHEMA')
916: result.rows.first.first
917: end
session_auth=(user)
click to toggle source
Set the authorized user for this session
510: def session_auth=(user)
511: clear_cache!
512: exec_query "SET SESSION AUTHORIZATION #{user}"
513: end
sql_for_insert(sql, pk, id_value, sequence_name, binds)
click to toggle source
682: def sql_for_insert(sql, pk, id_value, sequence_name, binds)
683: unless pk
684:
685: table_ref = extract_table_ref_from_insert_sql(sql)
686: pk = primary_key(table_ref) if table_ref
687: end
688:
689: sql = "#{sql} RETURNING #{quote_column_name(pk)}" if pk
690:
691: [sql, binds]
692: end
substitute_at(column, index)
click to toggle source
656: def substitute_at(column, index)
657: Arel::Nodes::BindParam.new "$#{index + 1}"
658: end
supports_ddl_transactions?()
click to toggle source
396: def supports_ddl_transactions?
397: true
398: end
supports_explain?()
click to toggle source
Returns true.
406: def supports_explain?
407: true
408: end
supports_index_sort_order?()
click to toggle source
248: def supports_index_sort_order?
249: true
250: end
supports_insert_with_returning?()
click to toggle source
392: def supports_insert_with_returning?
393: true
394: end
supports_migrations?()
click to toggle source
Returns true, since this connection adapter supports migrations.
375: def supports_migrations?
376: true
377: end
supports_savepoints?()
click to toggle source
Returns true, since this connection adapter supports savepoints.
401: def supports_savepoints?
402: true
403: end
supports_statement_cache?()
click to toggle source
Returns true, since this connection adapter supports prepared
statement caching.
244: def supports_statement_cache?
245: true
246: end
table_alias_length()
click to toggle source
Returns the configured supported identifier length supported by PostgreSQL
411: def table_alias_length
412: @table_alias_length ||= query('SHOW max_identifier_length')[0][0].to_i
413: end
table_exists?(name)
click to toggle source
Returns true if table exists. If the schema is not specified as part of
name then it will only find tables within the current schema
search path (regardless of permissions to access tables in other schemas)
789: def table_exists?(name)
790: schema, table = Utils.extract_schema_and_table(name.to_s)
791: return false unless table
792:
793: binds = [[nil, table]]
794: binds << [nil, schema] if schema
795:
796: exec_query( SELECT COUNT(*) FROM pg_class c LEFT JOIN pg_namespace n ON n.oid = c.relnamespace WHERE c.relkind in ('v','r') AND c.relname = '#{table.gsub(/(^"|"$)/,'')}' AND n.nspname = #{schema ? "'#{schema}'" : 'ANY (current_schemas(false))'}, 'SCHEMA').rows.first[0].to_i > 0
797: end
tables(name = nil)
click to toggle source
Returns the list of all tables in the schema search path or a specified
schema.
778: def tables(name = nil)
779: query( SELECT tablename FROM pg_tables WHERE schemaname = ANY (current_schemas(false)), 'SCHEMA').map { |row| row[0] }
780: end
type_cast(value, column)
click to toggle source
458: def type_cast(value, column)
459: return super unless column
460:
461: case value
462: when String
463: return super unless 'bytea' == column.sql_type
464: { :value => value, :format => 1 }
465: else
466: super
467: end
468: end
type_to_sql(type, limit = nil, precision = nil, scale = nil)
click to toggle source
Maps logical Rails types to PostgreSQL-specific data types.
1072: def type_to_sql(type, limit = nil, precision = nil, scale = nil)
1073: case type.to_s
1074: when 'binary'
1075:
1076:
1077: case limit
1078: when nil, 0..0x3fffffff; super(type)
1079: else raise(ActiveRecordError, "No binary type has byte size #{limit}.")
1080: end
1081: when 'integer'
1082: return 'integer' unless limit
1083:
1084: case limit
1085: when 1, 2; 'smallint'
1086: when 3, 4; 'integer'
1087: when 5..8; 'bigint'
1088: else raise(ActiveRecordError, "No integer type has byte size #{limit}. Use a numeric with precision 0 instead.")
1089: end
1090: else
1091: super
1092: end
1093: end
unescape_bytea(value)
click to toggle source
Unescapes bytea output from a database to the binary string it represents.
NOTE: This is NOT an inverse of escape_bytea! This
is only to be used
on escaped binary output from database drive.
425: def unescape_bytea(value)
426: @connection.unescape_bytea(value) if value
427: end
update_sql(sql, name = nil)
click to toggle source
Executes an UPDATE query and returns the number of affected tuples.
695: def update_sql(sql, name = nil)
696: super.cmd_tuples
697: end