module SQL module Postgres def supports_schema_transactions? true end def table(table_name) SQL::Postgres::Table.new(self, table_name) end def recreate_database execute 'DROP SCHEMA IF EXISTS test CASCADE' execute 'CREATE SCHEMA test' execute 'SET search_path TO test' end def supports_serial? true end def property_schema_statement(connection, schema) if supports_serial? && schema[:serial] statement = "#{schema[:quote_column_name]} SERIAL PRIMARY KEY" else statement = super statement << " DEFAULT nextval('#{schema[:sequence_name]}') NOT NULL" if schema.key?(:sequence_name) statement end statement end def table_options(_opts) '' end def change_column_type_statement(name, column) "ALTER TABLE #{quote_name(name)} ALTER COLUMN #{column.to_sql}" end def rename_column_type_statement(table_name, old_col, new_col) "ALTER TABLE #{quote_name(table_name)} RENAME COLUMN #{quote_name(old_col)} TO #{quote_name(new_col)}" end class Table < SQL::Table def initialize(adapter, table_name) super() @adapter = adapter @name = table_name @columns = [] adapter.query_table(table_name).each do |col_struct| @columns << SQL::Postgres::Column.new(col_struct) end query_column_constraints end def query_column_constraints @adapter.select( "SELECT * FROM information_schema.table_constraints WHERE table_name='#{@name}' AND table_schema=current_schema()" ).each do |table_constraint| @adapter.select( "SELECT * FROM information_schema.constraint_column_usage WHERE constraint_name='#{table_constraint.constraint_name}' " \ 'AND table_schema=current_schema()' ).each do |constrained_column| @columns.each do |column| next unless column.name == constrained_column.column_name case table_constraint.constraint_type when 'UNIQUE' then column.unique = true when 'PRIMARY KEY' then column.primary_key = true end end end end end end class Column < SQL::Column def initialize(col_struct) super() @name = col_struct.column_name @type = col_struct.data_type @default_value = col_struct.column_default @not_null = col_struct.is_nullable != 'YES' end end end end