Class: ValidateQuery

Inherits:
Object
  • Object
show all
Defined in:
lib/rails_pg_extras_mcp/validate_query.rb

Constant Summary collapse

InvalidQueryError =
Class.new(StandardError)
DENYLIST =
%w[
  delete
  insert
  update
  truncate
  drop
  alter
  create
  grant
  begin
  commit
  explain
  analyze
].freeze

Instance Method Summary collapse

Constructor Details

#initialize(sql_query) ⇒ ValidateQuery

Returns a new instance of ValidateQuery.



23
24
25
# File 'lib/rails_pg_extras_mcp/validate_query.rb', line 23

def initialize(sql_query)
  @sql_query = sql_query.to_s.strip
end

Instance Method Details

#callObject

Raises:



27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
# File 'lib/rails_pg_extras_mcp/validate_query.rb', line 27

def call
  raise InvalidQueryError, "Query is empty" if @sql_query.empty?

  if DENYLIST.any? { |word| @sql_query.downcase.include?(word) }
    raise InvalidQueryError, "Query contains denied keyword. Denylist: #{DENYLIST.join(', ')}"
  end

  begin
    tree = PgQuery.parse(@sql_query)
  rescue PgQuery::ParseError => e
    raise InvalidQueryError, "Invalid SQL syntax: #{e.message}"
  end

  if tree.tree.stmts.size > 1
    raise InvalidQueryError, "Multiple SQL statements are not allowed"
  end

  unless tree.tree.stmts.all? { |stmt| stmt.stmt.select_stmt }
    raise InvalidQueryError, "Only SELECT statements are allowed"
  end

  true
end