Class: QueryGuard::Migrations::MigrationAnalyzer
- Inherits:
-
Analyzers::Base
- Object
- Analyzers::Base
- QueryGuard::Migrations::MigrationAnalyzer
- Defined in:
- lib/query_guard/migrations/migration_analyzer.rb
Overview
Migration risk analyzer - scans Rails migration files for risky patterns. Searches for dangerous operations like:
- Index additions without algorithm: :concurrently
- Column removals/type changes
- Non-NULL additions without defaults
- Full-table updates
- Unsafe raw SQL
Optionally integrates with database metadata for table-size-aware risk estimation.
Example:
analyzer = MigrationAnalyzer.new
findings = analyzer.analyze_migration(migration_file_path)
With table size awareness:
connection = ActiveRecord::Base.connection
adapter = PostgreSQLAdapter.new(connection)
analyzer = MigrationAnalyzer.new(database_adapter: adapter)
findings = analyzer.analyze_migration(migration_file_path)
Instance Attribute Summary
Attributes inherited from Analyzers::Base
Instance Method Summary collapse
-
#analyze(context, config) ⇒ Array<Core::Finding>
Analyze method for integration with QueryGuard context This is called by registry when running full analysis.
-
#analyze_migration(file_path) ⇒ Array<Core::Finding>
Analyze a single migration file.
-
#analyze_migrations_directory(migrations_dir = "db/migrate") ⇒ Array<Core::Finding>
Analyze all migrations in a directory.
-
#initialize(database_adapter: nil) ⇒ MigrationAnalyzer
constructor
Initialize analyzer.
Methods inherited from Analyzers::Base
Constructor Details
#initialize(database_adapter: nil) ⇒ MigrationAnalyzer
Initialize analyzer
28 29 30 31 32 |
# File 'lib/query_guard/migrations/migration_analyzer.rb', line 28 def initialize(database_adapter: nil) super(:migration_risk) @database_adapter = database_adapter @table_risk_analyzer = TableRiskAnalyzer.new(database_adapter) end |
Instance Method Details
#analyze(context, config) ⇒ Array<Core::Finding>
Analyze method for integration with QueryGuard context This is called by registry when running full analysis
73 74 75 76 |
# File 'lib/query_guard/migrations/migration_analyzer.rb', line 73 def analyze(context, config) migrations_dir = config&.migrations_directory || "db/migrate" analyze_migrations_directory(migrations_dir) end |
#analyze_migration(file_path) ⇒ Array<Core::Finding>
Analyze a single migration file
38 39 40 41 42 43 44 45 46 47 48 49 50 |
# File 'lib/query_guard/migrations/migration_analyzer.rb', line 38 def analyze_migration(file_path) return [] unless File.exist?(file_path) content = File.read(file_path) migration_name = File.basename(file_path, ".rb") risks = MigrationRiskDetectors.detect_risks(content, migration_name) # Enhance risks with table metadata if adapter available risks = @table_risk_analyzer.enhance_risks(content, risks) risks_to_findings(risks, file_path) end |
#analyze_migrations_directory(migrations_dir = "db/migrate") ⇒ Array<Core::Finding>
Analyze all migrations in a directory
56 57 58 59 60 61 62 63 64 65 |
# File 'lib/query_guard/migrations/migration_analyzer.rb', line 56 def analyze_migrations_directory(migrations_dir = "db/migrate") findings = [] return findings unless Dir.exist?(migrations_dir) Dir.glob(File.join(migrations_dir, "*.rb")).each do |file_path| findings.concat(analyze_migration(file_path)) end findings end |