Class: DbSchema::Reader::Postgres::Table

Inherits:
Object
  • Object
show all
Defined in:
lib/db_schema/reader/postgres/table.rb

Constant Summary collapse

DEFAULT_VALUE =
/\A(
  ('(?<date>\d{4}-\d{2}-\d{2})'::date)
    |
  ('(?<time>\d{4}-\d{2}-\d{2}\s\d{2}:\d{2}:\d{2}([+-]\d{2})?)'::timestamp)
    |
  ('(?<string>.*)')
    |
  (?<float>\d+\.\d+)
    |
  (?<integer>\d+)
    |
  (?<boolean>true|false)
)/x
COLUMN_NAMES_QUERY =
<<-SQL.freeze
   SELECT c.column_name AS name,
  c.ordinal_position AS pos,
  c.column_default AS default,
  c.is_nullable AS null,
  c.data_type AS type,
  c.udt_name AS custom_type_name,
  c.character_maximum_length AS char_length,
  c.numeric_precision AS num_precision,
  c.numeric_scale AS num_scale,
  c.datetime_precision AS dt_precision,
  c.interval_type,
  e.data_type AS element_type,
  e.udt_name AS element_custom_type_name
     FROM information_schema.columns AS c
LEFT JOIN information_schema.element_types AS e
       ON e.object_catalog = c.table_catalog
      AND e.object_schema = c.table_schema
      AND e.object_name = c.table_name
      AND e.object_type = 'TABLE'
      AND e.collection_type_identifier = c.dtd_identifier
    WHERE c.table_schema = 'public'
      AND c.table_name = ?
SQL
CONSTRAINTS_QUERY =
<<-SQL.freeze
SELECT conname AS name,
       pg_get_expr(conbin, conrelid, true) AS condition
  FROM pg_constraint, pg_class
 WHERE conrelid = pg_class.oid
   AND relname = ?
   AND contype = 'c'
SQL
INDEXES_QUERY =
<<-SQL.freeze
   SELECT relname AS name,
  indkey AS column_positions,
  indisunique AS unique,
  indoption AS index_options,
  pg_get_expr(indpred, indrelid, true) AS condition,
  amname AS index_type,
  indexrelid AS index_oid
     FROM pg_class, pg_index
LEFT JOIN pg_opclass
       ON pg_opclass.oid = ANY(pg_index.indclass::int[])
LEFT JOIN pg_am
       ON pg_am.oid = pg_opclass.opcmethod
    WHERE pg_class.oid = pg_index.indexrelid
      AND pg_class.oid IN (
     SELECT indexrelid
       FROM pg_index, pg_class
      WHERE pg_class.relname = ?
AND pg_class.oid = pg_index.indrelid
AND indisprimary != 't'
)
  GROUP BY name, column_positions, indisunique, index_options, condition, index_type, index_oid
SQL
EXPRESSION_INDEXES_QUERY =
<<-SQL.freeze
    WITH index_ids AS (SELECT unnest(?) AS index_id),
 elements AS (SELECT unnest(?) AS element)
  SELECT index_id,
 array_agg(pg_get_indexdef(index_id, element, 't')) AS definitions
    FROM index_ids, elements
GROUP BY index_id;
SQL

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(connection, table_name) ⇒ Table

Returns a new instance of Table.



88
89
90
91
# File 'lib/db_schema/reader/postgres/table.rb', line 88

def initialize(connection, table_name)
  @connection = connection
  @table_name = table_name
end

Instance Attribute Details

#connectionObject (readonly)

Returns the value of attribute connection.



86
87
88
# File 'lib/db_schema/reader/postgres/table.rb', line 86

def connection
  @connection
end

#table_nameObject (readonly)

Returns the value of attribute table_name.



86
87
88
# File 'lib/db_schema/reader/postgres/table.rb', line 86

def table_name
  @table_name
end

Instance Method Details

#readObject



93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
# File 'lib/db_schema/reader/postgres/table.rb', line 93

def read
  primary_key_name = connection.primary_key(table_name)

  fields = columns_data.map do |column_data|
    build_field(column_data, primary_key: column_data[:name] == primary_key_name)
  end

  indexes = indexes_data.map do |index_data|
    Definitions::Index.new(index_data)
  end.sort_by(&:name)

  foreign_keys = connection.foreign_key_list(table_name).map do |foreign_key_data|
    build_foreign_key(foreign_key_data)
  end

  checks = connection[CONSTRAINTS_QUERY, table_name.to_s].map do |check_data|
    Definitions::CheckConstraint.new(
      name:      check_data[:name].to_sym,
      condition: check_data[:condition]
    )
  end

  Definitions::Table.new(
    table_name,
    fields:       fields,
    indexes:      indexes,
    checks:       checks,
    foreign_keys: foreign_keys
  )
end