active?()
click to toggle source
Is this connection alive and ready for queries?
233: def active?
234: if @connection.respond_to?(:status)
235: @connection.status == PGconn::CONNECTION_OK
236: else
237:
238: @connection.query 'SELECT 1'
239: true
240: end
241:
242: rescue PGError, NoMethodError
243: false
244: end
adapter_name()
click to toggle source
Returns ‘PostgreSQL’ as adapter name for identification
purposes.
214: def adapter_name
215: ADAPTER_NAME
216: 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.
795: def add_column(table_name, column_name, type, options = {})
796: default = options[:default]
797: notnull = options[:null] == false
798:
799:
800: 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])}")
801:
802: change_column_default(table_name, column_name, default) if options_include_default?(options)
803: change_column_null(table_name, column_name, false, default) if notnull
804: end
begin_db_transaction()
click to toggle source
Begins a transaction.
511: def begin_db_transaction
512: execute "BEGIN"
513: end
change_column(table_name, column_name, type, options = {})
click to toggle source
Changes the column of a table.
807: def change_column(table_name, column_name, type, options = {})
808: quoted_table_name = quote_table_name(table_name)
809:
810: begin
811: execute "ALTER TABLE #{quoted_table_name} ALTER COLUMN #{quote_column_name(column_name)} TYPE #{type_to_sql(type, options[:limit], options[:precision], options[:scale])}"
812: rescue ActiveRecord::StatementInvalid => e
813: raise e if postgresql_version > 80000
814:
815: begin
816: begin_db_transaction
817: tmp_column_name = "#{column_name}_ar_tmp"
818: add_column(table_name, tmp_column_name, type, options)
819: 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])})"
820: remove_column(table_name, column_name)
821: rename_column(table_name, tmp_column_name, column_name)
822: commit_db_transaction
823: rescue
824: rollback_db_transaction
825: end
826: end
827:
828: change_column_default(table_name, column_name, options[:default]) if options_include_default?(options)
829: change_column_null(table_name, column_name, options[:null], options[:default]) if options.key?(:null)
830: end
change_column_default(table_name, column_name, default)
click to toggle source
Changes the default value of a table column.
833: def change_column_default(table_name, column_name, default)
834: execute "ALTER TABLE #{quote_table_name(table_name)} ALTER COLUMN #{quote_column_name(column_name)} SET DEFAULT #{quote(default)}"
835: end
change_column_null(table_name, column_name, null, default = nil)
click to toggle source
837: def change_column_null(table_name, column_name, null, default = nil)
838: unless null || default.nil?
839: execute("UPDATE #{quote_table_name(table_name)} SET #{quote_column_name(column_name)}=#{quote(default)} WHERE #{quote_column_name(column_name)} IS NULL")
840: end
841: execute("ALTER TABLE #{quote_table_name(table_name)} ALTER #{quote_column_name(column_name)} #{null ? 'DROP' : 'SET'} NOT NULL")
842: end
client_min_messages()
click to toggle source
Returns the current client message level.
698: def client_min_messages
699: query('SHOW client_min_messages')[0][0]
700: end
client_min_messages=(level)
click to toggle source
Set the client message level.
703: def client_min_messages=(level)
704: execute("SET client_min_messages TO '#{level}'")
705: end
columns(table_name, name = nil)
click to toggle source
Returns the list of all column definitions for a table.
660: def columns(table_name, name = nil)
661:
662: column_definitions(table_name).collect do |name, type, default, notnull|
663: PostgreSQLColumn.new(name, default, type, notnull == 'f')
664: end
665: end
commit_db_transaction()
click to toggle source
Commits a transaction.
516: def commit_db_transaction
517: execute "COMMIT"
518: end
create(sql, name = nil, pk = nil, id_value = nil, sequence_name = nil)
click to toggle source
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'
555: def create_database(name, options = {})
556: options = options.reverse_merge(:encoding => "utf8")
557:
558: option_string = options.symbolize_keys.sum do |key, value|
559: case key
560: when :owner
561: " OWNER = \"#{value}\""
562: when :template
563: " TEMPLATE = \"#{value}\""
564: when :encoding
565: " ENCODING = '#{value}'"
566: when :tablespace
567: " TABLESPACE = \"#{value}\""
568: when :connection_limit
569: " CONNECTION LIMIT = #{value}"
570: else
571: ""
572: end
573: end
574:
575: execute "CREATE DATABASE #{quote_table_name(name)}#{option_string}"
576: end
create_savepoint()
click to toggle source
529: def create_savepoint
530: execute("SAVEPOINT #{current_savepoint_name}")
531: end
current_database()
click to toggle source
Returns the current database name.
668: def current_database
669: query('select current_database()')[0][0]
670: end
disconnect!()
click to toggle source
Close the connection.
258: def disconnect!
259: @connection.close rescue nil
260: end
encoding()
click to toggle source
Returns the current database encoding format.
673: def encoding
674: query( SELECT pg_encoding_to_char(pg_database.encoding) FROM pg_database WHERE pg_database.datname LIKE '#{current_database}')[0][0]
675: end
escape_bytea(value)
click to toggle source
Escapes binary strings for bytea input to the database.
305: def escape_bytea(value)
306: @connection.escape_bytea(value) if value
307: end
execute(sql, name = nil)
click to toggle source
Executes an SQL statement, returning a PGresult object on success or
raising a PGError exception otherwise.
495: def execute(sql, name = nil)
496: log(sql, name) do
497: if @async
498: @connection.async_exec(sql)
499: else
500: @connection.exec(sql)
501: end
502: end
503: end
index_name_length()
click to toggle source
853: def index_name_length
854: 63
855: end
indexes(table_name, name = nil)
click to toggle source
Returns the list of all indexes for a table.
626: def indexes(table_name, name = nil)
627: schemas = schema_search_path.split(/,/).map { |p| quote(p) }.join(',')
628: result = query( SELECT distinct i.relname, d.indisunique, d.indkey, t.oid FROM pg_class t, pg_class i, pg_index d 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 IN (#{schemas}) ) ORDER BY i.relname, name)
629:
630:
631: result.map do |row|
632: index_name = row[0]
633: unique = row[1] == 't'
634: indkey = row[2].split(" ")
635: oid = row[3]
636:
637: columns = Hash[query( SELECT a.attnum, a.attname FROM pg_attribute a WHERE a.attrelid = #{oid} AND a.attnum IN (#{indkey.join(",")}), "Columns for index #{row[0]} on #{table_name}")]
638:
639: column_names = columns.values_at(*indkey).compact
640: column_names.empty? ? nil : IndexDefinition.new(table_name, index_name, unique, column_names)
641: end.compact
642: end
insert(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
407: def insert(sql, name = nil, pk = nil, id_value = nil, sequence_name = nil)
408:
409: table = sql.split(" ", 4)[2].gsub('"', '')
410:
411:
412: if supports_insert_with_returning?
413: pk, sequence_name = *pk_and_sequence_for(table) unless pk
414: if pk
415: id = select_value("#{sql} RETURNING #{quote_column_name(pk)}")
416: clear_query_cache
417: return id
418: end
419: end
420:
421:
422: if insert_id = super
423: insert_id
424: else
425:
426: unless pk || sequence_name
427: pk, sequence_name = *pk_and_sequence_for(table)
428: end
429:
430:
431:
432: if pk && sequence_name ||= default_sequence_name(table, pk)
433: last_insert_id(table, sequence_name)
434: end
435: end
436: end
outside_transaction?()
click to toggle source
525: def outside_transaction?
526: @connection.transaction_status == PGconn::PQTRANS_IDLE
527: end
primary_key(table)
click to toggle source
Returns just a table’s primary key
783: def primary_key(table)
784: pk_and_sequence = pk_and_sequence_for(table)
785: pk_and_sequence && pk_and_sequence.first
786: end
quote_table_name(name)
click to toggle source
Checks the following cases:
352: def quote_table_name(name)
353: schema, name_part = extract_pg_identifier_from_name(name.to_s)
354:
355: unless name_part
356: quote_column_name(schema)
357: else
358: table_name, name_part = extract_pg_identifier_from_name(name_part)
359: "#{quote_column_name(schema)}.#{quote_column_name(table_name)}"
360: end
361: end
reconnect!()
click to toggle source
Close then reopen the connection.
247: def reconnect!
248: if @connection.respond_to?(:reset)
249: @connection.reset
250: configure_connection
251: else
252: disconnect!
253: connect
254: end
255: end
release_savepoint()
click to toggle source
537: def release_savepoint
538: execute("RELEASE SAVEPOINT #{current_savepoint_name}")
539: end
rename_column(table_name, column_name, new_column_name)
click to toggle source
Renames a column in a table.
845: def rename_column(table_name, column_name, new_column_name)
846: execute "ALTER TABLE #{quote_table_name(table_name)} RENAME COLUMN #{quote_column_name(column_name)} TO #{quote_column_name(new_column_name)}"
847: end
rename_table(name, new_name)
click to toggle source
Renames a table.
789: def rename_table(name, new_name)
790: execute "ALTER TABLE #{quote_table_name(name)} RENAME TO #{quote_table_name(new_name)}"
791: end
rollback_db_transaction()
click to toggle source
Aborts a transaction.
521: def rollback_db_transaction
522: execute "ROLLBACK"
523: end
rollback_to_savepoint()
click to toggle source
533: def rollback_to_savepoint
534: execute("ROLLBACK TO SAVEPOINT #{current_savepoint_name}")
535: end
schema_search_path()
click to toggle source
Returns the active schema search path.
693: def schema_search_path
694: @schema_search_path ||= query('SHOW search_path')[0][0]
695: 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.
685: def schema_search_path=(schema_csv)
686: if schema_csv
687: execute "SET search_path TO #{schema_csv}"
688: @schema_search_path = schema_csv
689: end
690: 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.
402: def select_rows(sql, name = nil)
403: select_raw(sql, name).last
404: end
supports_ddl_transactions?()
click to toggle source
288: def supports_ddl_transactions?
289: true
290: end
supports_insert_with_returning?()
click to toggle source
284: def supports_insert_with_returning?
285: postgresql_version >= 80200
286: end
supports_migrations?()
click to toggle source
Does PostgreSQL support migrations?
267: def supports_migrations?
268: true
269: end
supports_savepoints?()
click to toggle source
292: def supports_savepoints?
293: true
294: 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.
298: def table_alias_length
299: @table_alias_length ||= (postgresql_version >= 80000 ? query('SHOW max_identifier_length')[0][0].to_i : 63)
300: end
table_exists?(name)
click to toggle source
603: def table_exists?(name)
604: name = name.to_s
605: schema, table = name.split('.', 2)
606:
607: unless table
608: table = schema
609: schema = nil
610: end
611:
612: if name =~ /^"/
613: table = name
614: schema = nil
615: end
616:
617: query( SELECT COUNT(*) FROM pg_tables WHERE tablename = '#{table.gsub(/(^"|"$)/,'')}' #{schema ? "AND schemaname = '#{schema}'" : ''}).first[0].to_i > 0
618: end
tables(name = nil)
click to toggle source
Returns the list of all tables in the schema search path or a specified
schema.
595: def tables(name = nil)
596: query( SELECT tablename FROM pg_tables WHERE schemaname = ANY (current_schemas(false)), name).map { |row| row[0] }
597: end
type_to_sql(type, limit = nil, precision = nil, scale = nil)
click to toggle source
Maps logical Rails types to PostgreSQL-specific data types.
858: def type_to_sql(type, limit = nil, precision = nil, scale = nil)
859: return super unless type.to_s == 'integer'
860: return 'integer' unless limit
861:
862: case limit
863: when 1, 2; 'smallint'
864: when 3, 4; 'integer'
865: when 5..8; 'bigint'
866: else raise(ActiveRecordError, "No integer type has byte size #{limit}. Use a numeric with precision 0 instead.")
867: end
868: 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.
312: def unescape_bytea(value)
313: @connection.unescape_bytea(value) if value
314: end
update_sql(sql, name = nil)
click to toggle source
Executes an UPDATE query and returns the number of affected tuples.
506: def update_sql(sql, name = nil)
507: super.cmd_tuples
508: end