Class: ODBCAdapter::Adapters::PostgreSQLODBCAdapter

Inherits:
ActiveRecord::ConnectionAdapters::ODBCAdapter show all
Defined in:
lib/odbc_adapter/adapters/postgresql_odbc_adapter.rb

Overview

Overrides specific to PostgreSQL. Mostly taken from ActiveRecord::ConnectionAdapters::PostgreSQLAdapter

Constant Summary collapse

BOOLEAN_TYPE =
'bool'.freeze
PRIMARY_KEY =
'SERIAL PRIMARY KEY'.freeze

Constants inherited from ActiveRecord::ConnectionAdapters::ODBCAdapter

ActiveRecord::ConnectionAdapters::ODBCAdapter::ADAPTER_NAME, ActiveRecord::ConnectionAdapters::ODBCAdapter::ERR_CONNECTION_FAILED_MESSAGE, ActiveRecord::ConnectionAdapters::ODBCAdapter::ERR_CONNECTION_FAILED_REGEX, ActiveRecord::ConnectionAdapters::ODBCAdapter::ERR_DUPLICATE_KEY_VALUE, ActiveRecord::ConnectionAdapters::ODBCAdapter::ERR_QUERY_TIMED_OUT, ActiveRecord::ConnectionAdapters::ODBCAdapter::ERR_QUERY_TIMED_OUT_MESSAGE

Constants included from DatabaseStatements

DatabaseStatements::SQL_NO_NULLS, DatabaseStatements::SQL_NULLABLE, DatabaseStatements::SQL_NULLABLE_UNKNOWN

Instance Attribute Summary

Attributes inherited from ActiveRecord::ConnectionAdapters::ODBCAdapter

#database_metadata

Instance Method Summary collapse

Methods inherited from ActiveRecord::ConnectionAdapters::ODBCAdapter

#active?, #adapter_name, #disconnect!, #initialize, #new_column, #reconnect!, #supports_migrations?

Methods included from SchemaStatements

#columns, #current_database, #foreign_keys, #index_name, #indexes, #primary_key, #tables, #views

Methods included from Quoting

#quote_column_name, #quoted_date

Methods included from DatabaseStatements

#begin_db_transaction, #commit_db_transaction, #exec_delete, #exec_query, #exec_rollback_db_transaction, #execute

Methods included from DatabaseLimits

#table_alias_length

Constructor Details

This class inherits a constructor from ActiveRecord::ConnectionAdapters::ODBCAdapter

Instance Method Details

#arel_visitorObject



16
17
18
# File 'lib/odbc_adapter/adapters/postgresql_odbc_adapter.rb', line 16

def arel_visitor
  Arel::Visitors::PostgreSQL.new(self)
end

#change_column(table_name, column_name, type, options = {}) ⇒ Object



117
118
119
120
# File 'lib/odbc_adapter/adapters/postgresql_odbc_adapter.rb', line 117

def change_column(table_name, column_name, type, options = {})
  execute("ALTER TABLE #{table_name} ALTER  #{column_name} TYPE #{type_to_sql(type, options[:limit], options[:precision], options[:scale])}")
  change_column_default(table_name, column_name, options[:default]) if options_include_default?(options)
end

#change_column_default(table_name, column_name, default) ⇒ Object



122
123
124
# File 'lib/odbc_adapter/adapters/postgresql_odbc_adapter.rb', line 122

def change_column_default(table_name, column_name, default)
  execute("ALTER TABLE #{table_name} ALTER COLUMN #{column_name} SET DEFAULT #{quote(default)}")
end

#create_database(name, options = {}) ⇒ Object

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'


81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
# File 'lib/odbc_adapter/adapters/postgresql_odbc_adapter.rb', line 81

def create_database(name, options = {})
  options = options.reverse_merge(encoding: 'utf8')

  option_string = options.symbolize_keys.sum do |key, value|
    case key
    when :owner
      " OWNER = \"#{value}\""
    when :template
      " TEMPLATE = \"#{value}\""
    when :encoding
      " ENCODING = '#{value}'"
    when :tablespace
      " TABLESPACE = \"#{value}\""
    when :connection_limit
      " CONNECTION LIMIT = #{value}"
    else
      ''
    end
  end

  execute("CREATE DATABASE #{quote_table_name(name)}#{option_string}")
end

#default_sequence_name(table_name, pk = nil) ⇒ Object

Returns the sequence name for a table’s primary key or some other specified key.



32
33
34
35
36
# File 'lib/odbc_adapter/adapters/postgresql_odbc_adapter.rb', line 32

def default_sequence_name(table_name, pk = nil)
  serial_sequence(table_name, pk || 'id').split('.').last
rescue ActiveRecord::StatementInvalid
  "#{table_name}_#{pk || 'id'}_seq"
end

#disable_referential_integrityObject



66
67
68
69
70
71
# File 'lib/odbc_adapter/adapters/postgresql_odbc_adapter.rb', line 66

def disable_referential_integrity
  execute(tables.map { |name| "ALTER TABLE #{quote_table_name(name)} DISABLE TRIGGER ALL" }.join(';'))
  yield
ensure
  execute(tables.map { |name| "ALTER TABLE #{quote_table_name(name)} ENABLE TRIGGER ALL" }.join(';'))
end

#distinct(columns, orders) ⇒ Object

Returns a 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")


146
147
148
149
150
151
152
153
154
155
156
# File 'lib/odbc_adapter/adapters/postgresql_odbc_adapter.rb', line 146

def distinct(columns, orders)
  return "DISTINCT #{columns}" if orders.empty?

  # Construct a clean list of column names from the ORDER BY clause,
  # removing any ASC/DESC modifiers
  order_columns = orders.map { |s| s.gsub(/\s+(ASC|DESC)\s*(NULLS\s+(FIRST|LAST)\s*)?/i, '') }
  order_columns.reject!(&:blank?)
  order_columns = order_columns.zip((0...order_columns.size).to_a).map { |s, i| "#{s} AS alias_#{i}" }

  "DISTINCT #{columns}, #{order_columns * ', '}"
end

#drop_database(name) ⇒ Object

Drops a PostgreSQL database.

Example:

drop_database 'rails_development'


108
109
110
# File 'lib/odbc_adapter/adapters/postgresql_odbc_adapter.rb', line 108

def drop_database(name)
  execute "DROP DATABASE IF EXISTS #{quote_table_name(name)}"
end

#native_database_typesObject

Override to handle booleans appropriately



12
13
14
# File 'lib/odbc_adapter/adapters/postgresql_odbc_adapter.rb', line 12

def native_database_types
  @native_database_types ||= super.merge(boolean: { name: 'bool' })
end

#quote_string(string) ⇒ Object

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



62
63
64
# File 'lib/odbc_adapter/adapters/postgresql_odbc_adapter.rb', line 62

def quote_string(string)
  string.gsub(/\\/, '\&\&').gsub(/'/, "''")
end

#remove_index!(_table_name, index_name) ⇒ Object



130
131
132
# File 'lib/odbc_adapter/adapters/postgresql_odbc_adapter.rb', line 130

def remove_index!(_table_name, index_name)
  execute("DROP INDEX #{quote_table_name(index_name)}")
end

#rename_column(table_name, column_name, new_column_name) ⇒ Object



126
127
128
# File 'lib/odbc_adapter/adapters/postgresql_odbc_adapter.rb', line 126

def rename_column(table_name, column_name, new_column_name)
  execute("ALTER TABLE #{table_name} RENAME #{column_name} TO #{new_column_name}")
end

#rename_index(_table_name, old_name, new_name) ⇒ Object



134
135
136
# File 'lib/odbc_adapter/adapters/postgresql_odbc_adapter.rb', line 134

def rename_index(_table_name, old_name, new_name)
  execute("ALTER INDEX #{quote_column_name(old_name)} RENAME TO #{quote_table_name(new_name)}")
end

#rename_table(name, new_name) ⇒ Object

Renames a table.



113
114
115
# File 'lib/odbc_adapter/adapters/postgresql_odbc_adapter.rb', line 113

def rename_table(name, new_name)
  execute("ALTER TABLE #{quote_table_name(name)} RENAME TO #{quote_table_name(new_name)}")
end

#sql_for_insert(sql, pk, _id_value, _sequence_name, binds) ⇒ Object



38
39
40
41
42
43
44
45
46
# File 'lib/odbc_adapter/adapters/postgresql_odbc_adapter.rb', line 38

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

#table_filtered?(schema_name, table_type) ⇒ Boolean

Filter for ODBCAdapter#tables Omits table from #tables if table_filter returns true

Returns:

  • (Boolean)


22
23
24
# File 'lib/odbc_adapter/adapters/postgresql_odbc_adapter.rb', line 22

def table_filtered?(schema_name, table_type)
  %w[information_schema pg_catalog].include?(schema_name) || table_type !~ /TABLE/i
end

#truncate(table_name, name = nil) ⇒ Object



26
27
28
# File 'lib/odbc_adapter/adapters/postgresql_odbc_adapter.rb', line 26

def truncate(table_name, name = nil)
  exec_query("TRUNCATE TABLE #{quote_table_name(table_name)}", name)
end

#type_cast(value, column) ⇒ Object



48
49
50
51
52
53
54
55
56
57
58
# File 'lib/odbc_adapter/adapters/postgresql_odbc_adapter.rb', line 48

def type_cast(value, column)
  return super unless column

  case value
  when String
    return super unless 'bytea' == column.native_type
    { value: value, format: 1 }
  else
    super
  end
end