Class: Automodel::SchemaInspector
- Inherits:
-
Object
- Object
- Automodel::SchemaInspector
- Defined in:
- lib/automodel/schema_inspector.rb
Overview
A utility object that issues the actual database inspection commands and returns the table, column, primary-key, and foreign-key data.
Class Method Summary collapse
- .known_adapters ⇒ Object
-
.register_adapter(adapter:, tables:, columns:, primary_key:, foreign_keys: nil) ⇒ Object
“Registers” an adapter with the Automodel::SchemaInspector.
Instance Method Summary collapse
-
#columns(table_name) ⇒ Array<ActiveRecord::ConnectionAdapters::Column>
Returns a list of columns for the given table.
-
#foreign_keys(table_name) ⇒ Array<ActiveRecord::ConnectionAdapters::ForeignKeyDefinition>
Returns a list of foreign keys for the given table.
-
#initialize(connection_handler) ⇒ SchemaInspector
constructor
A new instance of SchemaInspector.
- #known_adapters ⇒ Object
-
#primary_key(table_name) ⇒ String+
Returns the primary key for the given table.
-
#tables ⇒ Array<String>
Returns a list of table names in the target database.
Constructor Details
#initialize(connection_handler) ⇒ SchemaInspector
Returns a new instance of SchemaInspector
64 65 66 67 68 69 |
# File 'lib/automodel/schema_inspector.rb', line 64 def initialize(connection_handler) @connection = connection_handler.connection adapter = connection_handler.connection_pool.spec.config[:adapter] @registration = known_adapters[adapter.to_sym] || {} end |
Class Method Details
.known_adapters ⇒ Object
18 |
# File 'lib/automodel/schema_inspector.rb', line 18 def self.known_adapters; @known_adapters; end |
.register_adapter(adapter:, tables:, columns:, primary_key:, foreign_keys: nil) ⇒ Object
“Registers” an adapter with the Automodel::SchemaInspector. This allows for
alternate mechanisms of procuring lists of tables, columns, primary keys,
and/or foreign keys from an adapter that may not itself support
#tables
/#columns
/#primary_key
/#foreign_keys
.
50 51 52 53 54 55 56 57 58 |
# File 'lib/automodel/schema_inspector.rb', line 50 def self.register_adapter(adapter:, tables:, columns:, primary_key:, foreign_keys: nil) adapter = adapter.to_sym.downcase raise Automodel::AdapterAlreadyRegisteredError, adapter if known_adapters.key? adapter known_adapters[adapter] = { tables: tables, columns: columns, primary_key: primary_key, foreign_keys: foreign_keys } end |
Instance Method Details
#columns(table_name) ⇒ Array<ActiveRecord::ConnectionAdapters::Column>
Returns a list of columns for the given table.
If a matching Automodel::SchemaInspector registration is found for the
connection's adapter, and that registration specified a
:columns
Proc, the Proc is called. Otherwise, the standard
connection #columns
is returned.
101 102 103 104 105 106 107 108 109 110 |
# File 'lib/automodel/schema_inspector.rb', line 101 def columns(table_name) table_name = table_name.to_s @columns ||= {} @columns[table_name] ||= if @registration[:columns].present? @registration[:columns].call(@connection, table_name) else @connection.columns(table_name) end end |
#foreign_keys(table_name) ⇒ Array<ActiveRecord::ConnectionAdapters::ForeignKeyDefinition>
Returns a list of foreign keys for the given table.
If a matching Automodel::SchemaInspector registration is found for the
connection's adapter, and that registration specified a
:foreign_keys
Proc, the Proc is called. Otherwise, the
standard connection #foreign_keys
is attempted. If that call
to `#foreign_keys
raises a ::NoMethodError or
::NotImplementedError, a best-effort attempt is made to build a list of
foreign keys based on table and column names.
151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 |
# File 'lib/automodel/schema_inspector.rb', line 151 def foreign_keys(table_name) table_name = table_name.to_s @foreign_keys ||= {} @foreign_keys[table_name] ||= begin if @registration[:foreign_keys].present? @registration[:foreign_keys].call(@connection, table_name) else begin @connection.foreign_keys(table_name) rescue ::NoMethodError, ::NotImplementedError ## Not all ActiveRecord adapters support `#foreign_keys`. When this happens, we'll make ## a best-effort attempt to intuit relationships from the table and column names. ## columns(table_name).map do |column| id_pattern = %r{(?:_id|Id)$} next unless column.name =~ id_pattern target_table = column.name.sub(id_pattern, '') next unless target_table.in? tables target_column = primary_key(qualified_name(target_table, context: table_name)) next unless target_column.in? ['id', 'Id', 'ID', column.name] ActiveRecord::ConnectionAdapters::ForeignKeyDefinition.new( table_name.split('.').last, target_table, name: "FK_#{SecureRandom.uuid.delete('-')}", column: column.name, primary_key: target_column, on_update: nil, on_delete: nil ) end.compact end end end end |
#known_adapters ⇒ Object
19 |
# File 'lib/automodel/schema_inspector.rb', line 19 def known_adapters; self.class.known_adapters; end |
#primary_key(table_name) ⇒ String+
Returns the primary key for the given table.
If a matching Automodel::SchemaInspector registration is found for the
connection's adapter, and that registration specified a
:primary_key
Proc, the Proc is called. Otherwise, the standard
connection #primary_key
is returned.
125 126 127 128 129 130 131 132 133 134 |
# File 'lib/automodel/schema_inspector.rb', line 125 def primary_key(table_name) table_name = table_name.to_s @primary_keys ||= {} @primary_keys[table_name] ||= if @registration[:primary_key].present? @registration[:primary_key].call(@connection, table_name) else @connection.primary_key(table_name) end end |
#tables ⇒ Array<String>
Returns a list of table names in the target database.
If a matching Automodel::SchemaInspector registration is found for the
connection's adapter, and that registration specified a
:tables
Proc, the Proc is called. Otherwise, the standard
connection #tables
is returned.
80 81 82 83 84 85 86 |
# File 'lib/automodel/schema_inspector.rb', line 80 def tables @tables ||= if @registration[:tables].present? @registration[:tables].call(@connection) else @connection.tables end end |