Module: PgCanary::SchemaIntrospection
- Defined in:
- lib/pg_canary/schema_introspection.rb
Overview
Index and column metadata for the rules, read through ActiveRecord's schema cache — caching, invalidation and thread safety ride on Rails. The catalog queries ActiveRecord issues are named "SCHEMA", which the Subscriber already ignores, so they are never analyzed themselves.
Defined Under Namespace
Classes: IndexInfo
Class Method Summary collapse
- .column_type(connection, table, column) ⇒ Object
-
.column_types(connection, table) ⇒ Object
=> { column_name => sql_type } e.g.
-
.index_info(definition) ⇒ Object
ActiveRecord returns plain-column indexes with an Array of column names, and expression indexes with the expressions as one SQL String.
-
.indexes(connection, table) ⇒ Object
=> [IndexInfo] — includes the primary key, which ActiveRecord's #indexes omits.
Class Method Details
.column_type(connection, table, column) ⇒ Object
42 43 44 |
# File 'lib/pg_canary/schema_introspection.rb', line 42 def column_type(connection, table, column) column_types(connection, table)[column] end |
.column_types(connection, table) ⇒ Object
=> { column_name => sql_type } e.g. { "id" => "bigint", "tags" => "text" }
47 48 49 50 51 52 53 54 55 56 57 58 59 |
# File 'lib/pg_canary/schema_introspection.rb', line 47 def column_types(connection, table) cache = connection.schema_cache return {} unless cache.data_source_exists?(table) cache.columns(table).to_h do |column| type = column.sql_type type = "#{type}[]" if column.respond_to?(:array?) && column.array? [column.name, type] end rescue StandardError => e PgCanary.internal_error(e) {} end |
.index_info(definition) ⇒ Object
ActiveRecord returns plain-column indexes with an Array of column names, and expression indexes with the expressions as one SQL String.
63 64 65 66 67 68 69 70 |
# File 'lib/pg_canary/schema_introspection.rb', line 63 def index_info(definition) expressions = definition.columns.is_a?(String) ? definition.columns : nil columns = expressions ? [] : Array(definition.columns) opclasses = definition.opclasses opclasses = columns.to_h { |c| [c, opclasses.to_s] } unless opclasses.is_a?(Hash) IndexInfo.new(name: definition.name, using: definition.using.to_s, columns: columns, opclasses: opclasses, expressions: expressions) end |
.indexes(connection, table) ⇒ Object
=> [IndexInfo] — includes the primary key, which ActiveRecord's #indexes omits.
26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
# File 'lib/pg_canary/schema_introspection.rb', line 26 def indexes(connection, table) cache = connection.schema_cache return [] unless cache.data_source_exists?(table) list = cache.indexes(table).map { |definition| index_info(definition) } primary_key = Array(cache.primary_keys(table)) if primary_key.any? list << IndexInfo.new(name: "#{table}_pkey", using: "btree", columns: primary_key, opclasses: {}, expressions: nil) end list rescue StandardError => e PgCanary.internal_error(e) [] end |