Class: AsktiveRecord::Query

Inherits:
Object
  • Object
show all
Defined in:
lib/asktive_record/query.rb

Overview

The Query class encapsulates a natural language question, its corresponding SQL, and provides methods for sanitization, execution, and generating answers using LLMs.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(natural_question, raw_sql, model_class) ⇒ Query

Returns a new instance of Query.



13
14
15
16
17
18
19
20
21
# File 'lib/asktive_record/query.rb', line 13

def initialize(natural_question, raw_sql, model_class)
  @raw_sql = raw_sql
  @model_class = model_class
  @natural_question = natural_question
  @sanitized_sql = raw_sql # Initially, sanitized SQL is the same as raw SQL

  AsktiveRecord::Log.info("Received question: \"#{natural_question}\"")
  AsktiveRecord::Log.info("Generated SQL: #{raw_sql}")
end

Instance Attribute Details

#model_classObject (readonly)

Returns the value of attribute model_class.



10
11
12
# File 'lib/asktive_record/query.rb', line 10

def model_class
  @model_class
end

#natural_questionObject (readonly)

Returns the value of attribute natural_question.



10
11
12
# File 'lib/asktive_record/query.rb', line 10

def natural_question
  @natural_question
end

#raw_sqlObject (readonly)

Returns the value of attribute raw_sql.



10
11
12
# File 'lib/asktive_record/query.rb', line 10

def raw_sql
  @raw_sql
end

#sanitized_sqlObject

Returns the value of attribute sanitized_sql.



11
12
13
# File 'lib/asktive_record/query.rb', line 11

def sanitized_sql
  @sanitized_sql
end

Instance Method Details

#answerObject



34
35
36
37
38
39
# File 'lib/asktive_record/query.rb', line 34

def answer
  response = execute
  llm = AsktiveRecord::LlmService.new(AsktiveRecord.configuration)
  response_text = response.respond_to?(:inspect) ? response.inspect : response.to_s
  llm.answer(@natural_question, @sanitized_sql, response_text)
end

#executeObject



41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
# File 'lib/asktive_record/query.rb', line 41

def execute
  unless @sanitized_sql
    raise QueryExecutionError,
          "Cannot execute raw SQL. Call sanitize! first or work with sanitized_sql."
  end

  # Auto-sanitize before execution if not already done
  validate_before_execution!

  result = execute_query
  AsktiveRecord::Log.info("Query executed successfully.")
  AsktiveRecord::Log.debug("Query results: #{result.inspect}")
  result
rescue QueryExecutionError
  raise
rescue StandardError => e
  raise QueryExecutionError, "Failed to execute SQL query: #{e.message}"
end

#sanitize!(allow_only_select: true) ⇒ self

Sanitizes the SQL using the SqlSanitizer. Raises AsktiveRecord::SanitizationError if the query is unsafe.

Parameters:

  • allow_only_select (Boolean) (defaults to: true)

    restrict to SELECT-only (default: true)

Returns:

  • (self)

    for chaining



28
29
30
31
32
# File 'lib/asktive_record/query.rb', line 28

def sanitize!(allow_only_select: true)
  @sanitized_sql = SqlSanitizer.sanitize!(@sanitized_sql, allow_only_select: allow_only_select)
  AsktiveRecord::Log.info("Sanitized SQL: #{@sanitized_sql}")
  self # Return self for chaining
end

#to_sObject



60
61
62
# File 'lib/asktive_record/query.rb', line 60

def to_s
  @sanitized_sql || @raw_sql
end