Module: Torque::PostgreSQL::Adapter::DatabaseStatements

Included in:
Torque::PostgreSQL::Adapter
Defined in:
lib/torque/postgresql/adapter/database_statements.rb

Constant Summary collapse

EXTENDED_DATABASE_TYPES =
%i(enum enum_set interval)

Instance Method Summary collapse

Instance Method Details

#column_definitions(table_name) ⇒ Object

Get the list of columns, and their definition, but only from the actual table, does not include columns that comes from inherited table



141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
# File 'lib/torque/postgresql/adapter/database_statements.rb', line 141

def column_definitions(table_name) # :nodoc:
  local_condition = 'AND a.attislocal IS TRUE' if @_dump_mode
  query(<<-SQL, 'SCHEMA')
      SELECT a.attname, format_type(a.atttypid, a.atttypmod),
             pg_get_expr(d.adbin, d.adrelid), a.attnotnull, a.atttypid, a.atttypmod,
     (SELECT c.collname FROM pg_collation c, pg_type t
       WHERE c.oid = a.attcollation AND t.oid = a.atttypid AND a.attcollation <> t.typcollation),
             col_description(a.attrelid, a.attnum) AS comment
        FROM pg_attribute a
   LEFT JOIN pg_attrdef d ON a.attrelid = d.adrelid AND a.attnum = d.adnum
       WHERE a.attrelid = '#{quote_table_name(table_name)}'::regclass
         AND a.attnum > 0
         AND a.attisdropped IS FALSE
         #{local_condition}
       ORDER BY a.attnum
  SQL
end

#configure_connectionObject

Configure the interval format



30
31
32
33
# File 'lib/torque/postgresql/adapter/database_statements.rb', line 30

def configure_connection
  super
  execute("SET SESSION IntervalStyle TO 'iso_8601'", 'SCHEMA')
end

#dump_mode!Object

Switch between dump mode or not



9
10
11
# File 'lib/torque/postgresql/adapter/database_statements.rb', line 9

def dump_mode!
  @_dump_mode = !!!@_dump_mode
end

#extended_typesObject

Get the list of extended types



19
20
21
# File 'lib/torque/postgresql/adapter/database_statements.rb', line 19

def extended_types
  EXTENDED_DATABASE_TYPES
end

#extract_value_from_default(default) ⇒ Object

Extracts the value from a PostgreSQL column default definition.



160
161
162
163
164
165
166
167
168
169
170
171
# File 'lib/torque/postgresql/adapter/database_statements.rb', line 160

def extract_value_from_default(default)
  case default
    # Array elements
  when /\AARRAY\[(.*)\]\z/
    # TODO: Improve this since it's not the most safe approach
    eval(default.gsub(/ARRAY|::\w+(\[\])?/, ''))
  else
    super
  end
rescue SyntaxError
  # If somethin goes wrong with the eval, just return nil
end

#inherited_tablesObject

Get the list of inherited tables associated with their parent tables



123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
# File 'lib/torque/postgresql/adapter/database_statements.rb', line 123

def inherited_tables
  tables = query(<<-SQL, 'SCHEMA')
    SELECT child.relname             AS table_name,
           array_agg(parent.relname) AS inheritances
    FROM pg_inherits
    JOIN pg_class parent ON pg_inherits.inhparent = parent.oid
    JOIN pg_class child  ON pg_inherits.inhrelid  = child.oid
    GROUP BY child.relname, pg_inherits.inhrelid
    ORDER BY pg_inherits.inhrelid
  SQL

  tables.map do |(table, refs)|
    [table, Coder.decode(refs)]
  end.to_h
end

#initialize_type_map(m = type_map) ⇒ Object

Change some of the types being mapped



36
37
38
39
40
41
42
43
# File 'lib/torque/postgresql/adapter/database_statements.rb', line 36

def initialize_type_map(m = type_map)
  super
  m.register_type 'box',      OID::Box.new
  m.register_type 'circle',   OID::Circle.new
  m.register_type 'interval', OID::Interval.new
  m.register_type 'line',     OID::Line.new
  m.register_type 'segment',  OID::Segment.new
end

#load_additional_types(type_map, oids = nil) ⇒ Object



47
48
49
50
# File 'lib/torque/postgresql/adapter/database_statements.rb', line 47

def load_additional_types(oids = nil)
  super
  torque_load_additional_types(oids)
end

#torque_load_additional_types(oids = nil) ⇒ Object

Add the composite types to be loaded too.



59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
# File 'lib/torque/postgresql/adapter/database_statements.rb', line 59

def torque_load_additional_types(oids = nil)
  filter = "AND     a.typelem::integer IN (%s)" % oids.join(", ") if oids

  query = <<-SQL
    SELECT      a.typelem AS oid, t.typname, t.typelem,
                t.typdelim, t.typbasetype, t.typtype,
                t.typarray
    FROM        pg_type t
    INNER JOIN  pg_type a ON (a.oid = t.typarray)
    LEFT JOIN   pg_catalog.pg_namespace n ON n.oid = t.typnamespace
    WHERE       n.nspname NOT IN ('pg_catalog', 'information_schema')
    AND     t.typtype IN ( 'e' )
    #{filter}
    AND     NOT EXISTS(
              SELECT 1 FROM pg_catalog.pg_type el
                WHERE el.oid = t.typelem AND el.typarray = t.oid
              )
    AND     (t.typrelid = 0 OR (
              SELECT c.relkind = 'c' FROM pg_catalog.pg_class c
                WHERE c.oid = t.typrelid
              ))
  SQL

  execute_and_clear(query, 'SCHEMA', []) do |records|
    records.each do |row|
      case row['typtype']
      when 'e' then OID::Enum.create(row, type_map)
      end
    end
  end
end

#type_exists?(name) ⇒ Boolean Also known as: data_type_exists?

Returns true if type exists.

Returns:

  • (Boolean)


24
25
26
# File 'lib/torque/postgresql/adapter/database_statements.rb', line 24

def type_exists?(name)
  user_defined_types.key? name.to_s
end

#user_defined_types(*categories) ⇒ Object

Gets a list of user defined types. You can even choose the category filter



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
# File 'lib/torque/postgresql/adapter/database_statements.rb', line 93

def user_defined_types(*categories)
  category_condition = categories.present? \
    ? "AND t.typtype IN ('#{categories.join("', '")}')" \
    : "AND t.typtype NOT IN ('b', 'd')"

  select_all(<<-SQL, 'SCHEMA').rows.to_h
    SELECT t.typname AS name,
           CASE t.typtype
             WHEN 'e' THEN 'enum'
             END     AS type
    FROM pg_type t
           LEFT JOIN pg_catalog.pg_namespace n ON n.oid = t.typnamespace
    WHERE n.nspname NOT IN ('pg_catalog', 'information_schema')
      #{category_condition}
      AND NOT EXISTS(
        SELECT 1
        FROM pg_catalog.pg_type el
        WHERE el.oid = t.typelem
          AND el.typarray = t.oid
      )
      AND (t.typrelid = 0 OR (
      SELECT c.relkind = 'c'
      FROM pg_catalog.pg_class c
      WHERE c.oid = t.typrelid
    ))
    ORDER BY t.typtype DESC
  SQL
end

#valid_type?(type) ⇒ Boolean

Check if a given type is valid.

Returns:

  • (Boolean)


14
15
16
# File 'lib/torque/postgresql/adapter/database_statements.rb', line 14

def valid_type?(type)
  super || extended_types.include?(type)
end