Class: QueryGuard::Migrations::TableRiskAnalyzer

Inherits:
Object
  • Object
show all
Defined in:
lib/query_guard/migrations/table_risk_analyzer.rb

Overview

Enhances risk analysis with table-size-aware context

When database metadata is available, escalates risk severity for operations on large tables.

For example:

  • add_index on 10M row table = CRITICAL (will lock for minutes)
  • add_index on 100K row table = ERROR (will lock briefly)

Works gracefully if database unavailable by falling back to static analysis.

Constant Summary collapse

ESCALATION_FACTORS =

Risk escalation factors based on table size

{
  low: 0,        # < 1M rows: no escalation
  medium: 1,     # 1M - 10M rows: escalate 1 level (error -> critical)
  high: 2,       # 10M - 100M rows: escalate 2 levels (warn -> critical)
  critical: 3    # > 100M rows: already critical
}.freeze

Instance Method Summary collapse

Constructor Details

#initialize(adapter = nil) ⇒ TableRiskAnalyzer

Initialize analyzer

Parameters:

  • adapter (DatabaseAdapter) (defaults to: nil) —

    Optional database adapter



28
29
30
# File 'lib/query_guard/migrations/table_risk_analyzer.rb', line 28

def initialize(adapter = nil)
  @adapter = adapter || NullDatabaseAdapter.new
end

Instance Method Details

#enhance_risks(migration_content, risks) ⇒ Array<Hash>

Enhance risks with table size information

Parameters:

  • migration_content (String) —

    Migration file content

  • risks (Array<Hash>) —

    Risks from MigrationRiskDetectors

Returns:

  • (Array<Hash>) —

    Risks with table metadata added



37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
# File 'lib/query_guard/migrations/table_risk_analyzer.rb', line 37

def enhance_risks(migration_content, risks)
  return risks unless @adapter.connected?

  # Extract affected tables from migration
  affected_tables = TableSizeResolver.affected_tables(migration_content)
  return risks if affected_tables.empty?

  # Build table metadata cache
   = {}
  affected_tables.each do |table_name|
    row_count = @adapter.estimate_table_rows(table_name)
    lock_risk = @adapter.estimate_lock_risk(table_name)

    [table_name] = {
      estimated_rows: row_count,
      lock_risk: lock_risk
    }
  end

  # Enhance each risk with table metadata
  risks.map do |risk|
    enhance_single_risk(risk, migration_content, )
  end
end