Class: Dbviewer::QueryParser

Inherits:
Object
  • Object
show all
Defined in:
lib/dbviewer/query_parser.rb

Overview

QueryParser handles parsing SQL queries and extracting useful information

Class Method Summary collapse

Class Method Details

.extract_tables(sql) ⇒ Object

Extract table names from an SQL query string



5
6
7
8
9
10
11
12
13
# File 'lib/dbviewer/query_parser.rb', line 5

def self.extract_tables(sql)
  return [] if sql.nil?

  # Convert to lowercase for case-insensitive matching
  sql = sql.downcase

  # Extract table names after FROM or JOIN
  sql.scan(/(?:from|join)\s+[`"']?(\w+)[`"']?/).flatten.uniq
end

.format_binds(binds) ⇒ Object

Format bind parameters for storage



56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
# File 'lib/dbviewer/query_parser.rb', line 56

def self.format_binds(binds)
  return [] unless binds.respond_to?(:map)

  binds.map do |bind|
    if bind.respond_to?(:value)
      bind.value
    elsif bind.is_a?(Array) && bind.size == 2
      bind.last
    else
      bind.to_s
    end
  end
rescue
  []
end

.from_dbviewer?(event) ⇒ Boolean

Check if the query is from the DBViewer library

Returns:

  • (Boolean)


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
# File 'lib/dbviewer/query_parser.rb', line 26

def self.from_dbviewer?(event)
  # Check if the SQL itself references DBViewer tables
  if event.payload[:sql].match(/\b(from|join|update|into)\s+["`']?dbviewer_/i)
    return true
  end

  # Check the caller information if available
  caller = event.payload[:caller]
  if caller.is_a?(String) && caller.include?("/dbviewer/")
    return true
  end

  # Check if query name indicates it's from DBViewer
  if event.payload[:name].is_a?(String) &&
     (event.payload[:name].include?("Dbviewer") || event.payload[:name].include?("DBViewer") || event.payload[:name] == "SQL")
    return true
  end

  # Check for common DBViewer operations
  sql = event.payload[:sql].downcase
  if sql.include?("table_structure") ||
     sql.include?("schema_migrations") ||
     sql.include?("database_analytics")
    return true
  end

  false
end

.normalize(sql) ⇒ Object

Normalize a SQL query to find similar patterns Replaces specific values with placeholders



17
18
19
20
21
22
23
# File 'lib/dbviewer/query_parser.rb', line 17

def self.normalize(sql)
  return "" if sql.nil?

  sql.gsub(/\b\d+\b/, "N")
     .gsub(/'[^']*'/, "'X'")
     .gsub(/"[^"]*"/, '"X"')
end

.should_skip_query?(event) ⇒ Boolean

Determine if a query should be skipped based on content

Returns:

  • (Boolean)


73
74
75
76
77
78
79
80
# File 'lib/dbviewer/query_parser.rb', line 73

def self.should_skip_query?(event)
  event.payload[:name] == "SCHEMA" ||
  event.payload[:sql].include?("SHOW TABLES") ||
  event.payload[:sql].include?("sqlite_master") ||
  event.payload[:sql].include?("information_schema") ||
  event.payload[:sql].include?("pg_catalog") ||
  from_dbviewer?(event)
end