Class: QueryConsole::Runner

Inherits:
Object
  • Object
show all
Defined in:
app/services/query_console/runner.rb

Defined Under Namespace

Classes: QueryResult

Instance Method Summary collapse

Constructor Details

#initialize(sql, config = QueryConsole.configuration) ⇒ Runner

Returns a new instance of Runner.



36
37
38
39
# File 'app/services/query_console/runner.rb', line 36

def initialize(sql, config = QueryConsole.configuration)
  @sql = sql
  @config = config
end

Instance Method Details

#executeObject



41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
# File 'app/services/query_console/runner.rb', line 41

def execute
  start_time = Time.now

  # Step 1: Validate SQL
  validator = SqlValidator.new(@sql, @config)
  validation_result = validator.validate

  if validation_result.invalid?
    return QueryResult.new(error: validation_result.error)
  end

  sanitized_sql = validation_result.sanitized_sql
  is_dml = validation_result.dml?

  # Step 2: Apply row limit
  limiter = SqlLimiter.new(sanitized_sql, @config.max_rows, @config)
  limit_result = limiter.apply_limit
  final_sql = limit_result.sql
  truncated = limit_result.truncated?

  # Step 3: Execute query with timeout
  begin
    result, rows_affected = execute_with_timeout(final_sql, is_dml)
    execution_time = ((Time.now - start_time) * 1000).round(2)

    QueryResult.new(
      columns: result.columns,
      rows: result.rows,
      execution_time_ms: execution_time,
      row_count_shown: result.rows.length,
      truncated: truncated,
      is_dml: is_dml,
      rows_affected: rows_affected
    )
  rescue Timeout::Error
    QueryResult.new(
      error: "Query timeout: exceeded #{@config.timeout_ms}ms limit"
    )
  rescue StandardError => e
    QueryResult.new(
      error: "Query error: #{e.message}"
    )
  end
end