Class: SchemaSherlock::OptimizedScanner

Inherits:
Object
  • Object
show all
Defined in:
lib/schema_sherlock/optimized_scanner.rb

Constant Summary collapse

BOUNDARY_CHARS =

Pre-compiled patterns stored as constants to avoid recompilation

/[\s\(\)\[\]\{\},;:'"]/

Class Method Summary collapse

Class Method Details

.count_column_references(content, table_name, column_name) ⇒ Object

Use StringScanner for efficient single-pass scanning



10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
# File 'lib/schema_sherlock/optimized_scanner.rb', line 10

def count_column_references(content, table_name, column_name)
  # Convert to downcase once for case-insensitive matching
  content_lower = content.downcase
  column_lower = column_name.downcase
  association_name = column_name.gsub(/_id$/, '').downcase
  
  count = 0
  scanner = StringScanner.new(content_lower)
  
  # Single pass through the content
  while scanner.scan_until(/\./)
    
    # Check for .where patterns
    if scanner.match?(/where\s*\(/)
      scanner.skip(/where\s*\(\s*/)
      if match_column_reference(scanner, column_lower)
        count += 1
        next
      end
    end
    
    # Check for .find_by patterns
    if scanner.match?(/find_by\s*\(/)
      scanner.skip(/find_by\s*\(\s*/)
      if match_column_reference(scanner, column_lower)
        count += 1
        next
      end
    end
    
    # Check for .joins and .includes with association
    if scanner.match?(/joins\s*\(/)
      scanner.skip(/joins\s*\(\s*/)
      if match_association_reference(scanner, association_name)
        count += 1
        next
      end
    elsif scanner.match?(/includes\s*\(/)
      scanner.skip(/includes\s*\(\s*/)
      if match_association_reference(scanner, association_name)
        count += 1
        next
      end
    end
    
    # Check for direct column access
    if scanner.match?(/#{Regexp.escape(column_lower)}\b/)
      scanner.skip(/#{Regexp.escape(column_lower)}\b/)
      count += 1
    end
  end
  
  count
end

.count_column_references_native(content, table_name, column_name) ⇒ Object

Native string operations version - even faster for simple patterns



66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
# File 'lib/schema_sherlock/optimized_scanner.rb', line 66

def count_column_references_native(content, table_name, column_name)
  content_lower = content.downcase
  column_lower = column_name.downcase
  association_name = column_name.gsub(/_id$/, '').downcase
  
  count = 0
  
  # Use native string operations for simple patterns
  # Count .where( patterns
  count += count_pattern_native(content_lower, ".where(", column_lower)
  count += count_pattern_native(content_lower, ".where (", column_lower)
  count += count_pattern_native(content_lower, ".find_by(", column_lower)
  count += count_pattern_native(content_lower, ".find_by (", column_lower)
  
  # Count joins/includes
  count += count_pattern_native(content_lower, ".joins(", association_name)
  count += count_pattern_native(content_lower, ".joins (", association_name)
  count += count_pattern_native(content_lower, ".includes(", association_name)
  count += count_pattern_native(content_lower, ".includes (", association_name)
  
  # Count direct access - use boundary checking
  count += count_direct_access(content_lower, ".#{column_lower}")
  
  count
end