mysql_genius 0.5.1 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 48fbc36b280f63255eebb38587db28d24e38150b53faaff13efeddb810de8c70
4
- data.tar.gz: a55a5115090bc136e99d854dc13c231670293a363f8d441951d98191c794d9e6
3
+ metadata.gz: a35fb751622eaa5cd7bc6fad555020fb5dbf2a9a2f50d50d27ee9b3da6440818
4
+ data.tar.gz: 1423b66748df1f05b0a9e9ff3868d35905953218443823e9cf2b0a554e88c4db
5
5
  SHA512:
6
- metadata.gz: 9d9de9d97d05814ff37b0ed88ee1846656ba3f1ff323f094ff776a3abb4be358d12204810e9068d2f6e99daea88d007f5a406f27681b7c1574a38395b0889c7e
7
- data.tar.gz: cb5c725008371288dff5e8a32a66851914a39de71f0b647ade81bde743e01f7fe5f7ae2664715da9602b7e024b5609c3df53f37c1817faa73e7a4d801a26f292
6
+ metadata.gz: 8fbd465309eb1068b2c78cc47e56e93ac98badd97f8df834a306cbda5c114f903f410c5a7e927c6e9079556d2a240e44521290a28b959e9af91805f13b1fe22d
7
+ data.tar.gz: 2f3fe565bd970da7f1a1ac0f331bc435a59cc5508b1094fdc91003ef01f5fd3fb7782618cc7d55e24e5aec243f597895b5d4bd1238e90b150d5d92ba2cf611ef
@@ -14,17 +14,8 @@ jobs:
14
14
  fail-fast: false
15
15
  matrix:
16
16
  ruby: ["2.7", "3.0", "3.1", "3.2", "3.3", "3.4"]
17
- rails: ["5.2", "6.0", "6.1", "7.0", "7.1", "7.2", "8.0", "8.1"]
17
+ rails: ["6.0", "6.1", "7.0", "7.1", "7.2", "8.0", "8.1"]
18
18
  exclude:
19
- # Rails 5.2 doesn't support Ruby 3.1+
20
- - ruby: "3.1"
21
- rails: "5.2"
22
- - ruby: "3.2"
23
- rails: "5.2"
24
- - ruby: "3.3"
25
- rails: "5.2"
26
- - ruby: "3.4"
27
- rails: "5.2"
28
19
  # Rails 6.0 doesn't support Ruby 3.2+
29
20
  - ruby: "3.2"
30
21
  rails: "6.0"
@@ -61,7 +52,7 @@ jobs:
61
52
  RAILS_VERSION: ${{ matrix.rails }}
62
53
 
63
54
  steps:
64
- - uses: actions/checkout@v4
55
+ - uses: actions/checkout@v5
65
56
 
66
57
  - name: Set up Ruby ${{ matrix.ruby }}
67
58
  uses: ruby/setup-ruby@v1
@@ -9,7 +9,7 @@ jobs:
9
9
  test:
10
10
  runs-on: ubuntu-latest
11
11
  steps:
12
- - uses: actions/checkout@v4
12
+ - uses: actions/checkout@v5
13
13
  - uses: ruby/setup-ruby@v1
14
14
  with:
15
15
  ruby-version: 3.3
@@ -25,7 +25,7 @@ jobs:
25
25
  needs: test
26
26
  runs-on: ubuntu-latest
27
27
  steps:
28
- - uses: actions/checkout@v4
28
+ - uses: actions/checkout@v5
29
29
  - uses: ruby/setup-ruby@v1
30
30
  with:
31
31
  ruby-version: 3.3
data/CHANGELOG.md CHANGED
@@ -1,9 +1,24 @@
1
1
  # Changelog
2
2
 
3
- ## 0.5.1
3
+ ## 0.6.0
4
+
5
+ ### Changed
6
+ - **Dropped Rails 5.2 support.** The gemspec floor is now Rails 6.0 (`activerecord`/`railties` constraint is `">= 6.0", "< 9"`). Rails 5.2 has been end-of-life since June 2022 and its incompatibilities with modern Rack (`ActionDispatch::Static#initialize` arity mismatch, `MiddlewareStack#operations` removal) started surfacing as CI failures once Phase 2a's integration specs booted Rails in test. Pin `mysql_genius 0.5.0` (`gem "mysql_genius", "~> 0.5.0"`) if you can't upgrade Rails yet.
7
+ - `mysql_genius` now declares runtime dependency on `mysql_genius-core ~> 0.6.0` (was `~> 0.5.0`).
4
8
 
5
9
  ### Fixed
6
- - **ERB templates missing from `mysql_genius-core` gem package.** The gemspec glob only matched `*.rb` files, excluding the shared ERB templates. The dashboard crashed with `MissingTemplate` error when installed from RubyGems. Fixed by changing the glob to `*.{rb,erb}`.
10
+ - **CI matrix: Ruby 3.x + Rails 5.2/6.0/6.1 compatibility.** `spec/rails_helper.rb` and `spec/dummy/config/application.rb` now explicitly `require "logger"` before loading Rails. Works around a `Logger::Severity` reference inside `ActiveSupport::LoggerThreadSafeLevel` that fails on Ruby 3.x + older Rails because Logger is no longer autoloaded in modern Ruby. Only affects the test suite; no runtime impact on host apps.
11
+
12
+ ### Internal
13
+ - **`rails_connection` consolidated into `BaseController`.** Nine inline `MysqlGenius::Core::Connection::ActiveRecordAdapter.new(ActiveRecord::Base.connection)` call sites in the three controller concerns, plus two separate private helper definitions in `QueriesController` and `AiFeatures`, collapse to one private method on `BaseController`. Shared across all concerns via Ruby's standard method lookup.
14
+ - **`ai_domain_context` helper inlined and deleted.** Its two remaining callers (`anomaly_detection` and `root_cause`) now compute a local `domain_ctx` string before building their message array.
15
+ - **`fake_result(columns:, rows:, to_a:)` test helper extracted** into `spec/support/fake_connection.rb` alongside `fake_column`. Four duplicated `instance_double("ActiveRecord::Result", columns:, rows:, to_a:)` call sites in request specs refactored.
16
+ - **`Core::Analysis::Columns` spec** covers the `default: false` branch (6th column outside `default_columns`).
17
+ - **`actions/checkout@v4` bumped to `@v5`** in both `.github/workflows/ci.yml` and `.github/workflows/publish.yml`. Prepares for GitHub's June 2026 Node 20 deprecation.
18
+ - **Gemspec `source_code_uri` duplicate dropped** from both gemspecs (was equal to `homepage_uri` and triggered a RubyGems build warning on every release).
19
+
20
+ ### Documentation
21
+ - README Compatibility table no longer lists Rails 5.2. The note explaining the drop and pinning instructions stays in place.
7
22
 
8
23
  ## 0.5.0
9
24
 
data/README.md CHANGED
@@ -134,7 +134,6 @@ This helps if the problem is a stale trust store, but does **not** help if the u
134
134
 
135
135
  | Rails | Ruby |
136
136
  |-------|------|
137
- | 5.2 | 2.7, 3.0 |
138
137
  | 6.0 | 2.7, 3.0, 3.1 |
139
138
  | 6.1 | 2.7, 3.0, 3.1, 3.2, 3.3 |
140
139
  | 7.0 | 2.7, 3.0, 3.1, 3.2, 3.3 |
@@ -143,6 +142,8 @@ This helps if the problem is a stale trust store, but does **not** help if the u
143
142
  | 8.0 | 3.2, 3.3, 3.4 |
144
143
  | 8.1 | 3.2, 3.3, 3.4 |
145
144
 
145
+ > **Rails 5.2:** dropped in `mysql_genius 0.6.0`. `mysql_genius 0.5.0` is the last version to support Rails 5.2 — pin it (`gem "mysql_genius", "~> 0.5.0"`) if you can't upgrade Rails yet. Rails 5.2 has been end-of-life since June 2022, and its incompatibilities with modern Rack (`ActionDispatch::Static#initialize` arity mismatch, `MiddlewareStack#operations` removal) surfaced as CI failures once Phase 2a's integration specs booted Rails in test.
146
+
146
147
  ## Documentation
147
148
 
148
149
  Full documentation is available on the [Wiki](https://github.com/antarr/mysql_genius/wiki).
@@ -12,8 +12,7 @@ module MysqlGenius
12
12
  prompt = params[:prompt].to_s.strip
13
13
  return render(json: { error: "Please describe what you want to query." }, status: :unprocessable_entity) if prompt.blank?
14
14
 
15
- connection = MysqlGenius::Core::Connection::ActiveRecordAdapter.new(ActiveRecord::Base.connection)
16
- service = MysqlGenius::Core::Ai::Suggestion.new(connection, ai_client, ai_config_for_core)
15
+ service = MysqlGenius::Core::Ai::Suggestion.new(rails_connection, ai_client, ai_config_for_core)
17
16
  result = service.call(prompt, queryable_tables)
18
17
  sql = sanitize_ai_sql(result["sql"].to_s)
19
18
  render(json: { sql: sql, explanation: result["explanation"] })
@@ -33,8 +32,7 @@ module MysqlGenius
33
32
  return render(json: { error: "SQL and EXPLAIN output are required." }, status: :unprocessable_entity)
34
33
  end
35
34
 
36
- connection = MysqlGenius::Core::Connection::ActiveRecordAdapter.new(ActiveRecord::Base.connection)
37
- service = MysqlGenius::Core::Ai::Optimization.new(connection, ai_client, ai_config_for_core)
35
+ service = MysqlGenius::Core::Ai::Optimization.new(rails_connection, ai_client, ai_config_for_core)
38
36
  result = service.call(sql, explain_rows, queryable_tables)
39
37
  render(json: result)
40
38
  rescue StandardError => e
@@ -125,6 +123,7 @@ module MysqlGenius
125
123
 
126
124
  slow_summary = slow_data.first(50).map { |q| "#{q["duration_ms"]}ms @ #{q["timestamp"]}: #{q["sql"].to_s.truncate(150)}" }.join("\n")
127
125
  stats_summary = stats.map { |q| "calls=#{q[:calls]} avg=#{q[:avg_ms]}ms total=#{q[:total_ms]}ms exam=#{q[:rows_examined]} sent=#{q[:rows_sent]}: #{q[:sql]}" }.join("\n")
126
+ domain_ctx = mysql_genius_config.ai_system_context.present? ? "\nDomain context:\n#{mysql_genius_config.ai_system_context}" : ""
128
127
 
129
128
  messages = [
130
129
  { role: "system", content: <<~PROMPT },
@@ -134,7 +133,7 @@ module MysqlGenius
134
133
  3. Full table scans (rows_examined >> rows_sent)
135
134
  4. Sudden new query patterns that may indicate code changes
136
135
  5. Queries creating excessive temp tables or sorts
137
- #{ai_domain_context}
136
+ #{domain_ctx}
138
137
 
139
138
  Respond with JSON: {"report": "markdown-formatted health report organized by severity. For each finding, explain the issue, affected query, and recommended fix."}
140
139
  PROMPT
@@ -196,6 +195,8 @@ module MysqlGenius
196
195
  slow_summary = slows.map { |q| "#{q["duration_ms"]}ms: #{q["sql"].to_s.truncate(150)}" }.join("\n")
197
196
  end
198
197
 
198
+ domain_ctx = mysql_genius_config.ai_system_context.present? ? "\nDomain context:\n#{mysql_genius_config.ai_system_context}" : ""
199
+
199
200
  messages = [
200
201
  { role: "system", content: <<~PROMPT },
201
202
  You are a MySQL incident responder. The user is asking "why is the database slow right now?" Analyze the provided data and give a root cause diagnosis. Consider:
@@ -206,7 +207,7 @@ module MysqlGenius
206
207
  - Disk I/O saturation
207
208
  - Replication lag
208
209
  - Unusual query patterns
209
- #{ai_domain_context}
210
+ #{domain_ctx}
210
211
 
211
212
  Respond with JSON: {"diagnosis": "markdown-formatted root cause analysis. Start with a 1-2 sentence summary, then detailed findings. Include specific actionable steps to resolve the issue."}
212
213
  PROMPT
@@ -257,15 +258,5 @@ module MysqlGenius
257
258
  def ai_not_configured
258
259
  render(json: { error: "AI features are not configured." }, status: :not_found)
259
260
  end
260
-
261
- def rails_connection
262
- MysqlGenius::Core::Connection::ActiveRecordAdapter.new(ActiveRecord::Base.connection)
263
- end
264
-
265
- def ai_domain_context
266
- cfg = mysql_genius_config
267
- ctx = cfg.ai_system_context
268
- ctx.present? ? "\nDomain context:\n#{ctx}" : ""
269
- end
270
261
  end
271
262
  end
@@ -5,40 +5,35 @@ module MysqlGenius
5
5
  extend ActiveSupport::Concern
6
6
 
7
7
  def duplicate_indexes
8
- connection = MysqlGenius::Core::Connection::ActiveRecordAdapter.new(ActiveRecord::Base.connection)
9
8
  duplicates = MysqlGenius::Core::Analysis::DuplicateIndexes
10
- .new(connection, blocked_tables: mysql_genius_config.blocked_tables)
9
+ .new(rails_connection, blocked_tables: mysql_genius_config.blocked_tables)
11
10
  .call
12
11
  render(json: duplicates)
13
12
  end
14
13
 
15
14
  def table_sizes
16
- connection = MysqlGenius::Core::Connection::ActiveRecordAdapter.new(ActiveRecord::Base.connection)
17
- tables = MysqlGenius::Core::Analysis::TableSizes.new(connection).call
15
+ tables = MysqlGenius::Core::Analysis::TableSizes.new(rails_connection).call
18
16
  render(json: tables)
19
17
  end
20
18
 
21
19
  def query_stats
22
- connection = MysqlGenius::Core::Connection::ActiveRecordAdapter.new(ActiveRecord::Base.connection)
23
20
  sort = params[:sort].to_s
24
21
  limit = params.fetch(:limit, MysqlGenius::Core::Analysis::QueryStats::MAX_LIMIT).to_i
25
- queries = MysqlGenius::Core::Analysis::QueryStats.new(connection).call(sort: sort, limit: limit)
22
+ queries = MysqlGenius::Core::Analysis::QueryStats.new(rails_connection).call(sort: sort, limit: limit)
26
23
  render(json: queries)
27
24
  rescue ActiveRecord::StatementInvalid => e
28
25
  render(json: { error: "Query statistics require performance_schema to be enabled. #{e.message.split(":").last.strip}" }, status: :unprocessable_entity)
29
26
  end
30
27
 
31
28
  def unused_indexes
32
- connection = MysqlGenius::Core::Connection::ActiveRecordAdapter.new(ActiveRecord::Base.connection)
33
- indexes = MysqlGenius::Core::Analysis::UnusedIndexes.new(connection).call
29
+ indexes = MysqlGenius::Core::Analysis::UnusedIndexes.new(rails_connection).call
34
30
  render(json: indexes)
35
31
  rescue ActiveRecord::StatementInvalid => e
36
32
  render(json: { error: "Unused index detection requires performance_schema. #{e.message.split(":").last.strip}" }, status: :unprocessable_entity)
37
33
  end
38
34
 
39
35
  def server_overview
40
- connection = MysqlGenius::Core::Connection::ActiveRecordAdapter.new(ActiveRecord::Base.connection)
41
- overview = MysqlGenius::Core::Analysis::ServerOverview.new(connection).call
36
+ overview = MysqlGenius::Core::Analysis::ServerOverview.new(rails_connection).call
42
37
  render(json: overview)
43
38
  rescue => e
44
39
  render(json: { error: "Failed to load server overview: #{e.message}" }, status: :unprocessable_entity)
@@ -12,13 +12,12 @@ module MysqlGenius
12
12
  mysql_genius_config.default_row_limit
13
13
  end
14
14
 
15
- connection = MysqlGenius::Core::Connection::ActiveRecordAdapter.new(ActiveRecord::Base.connection)
16
15
  runner_config = MysqlGenius::Core::QueryRunner::Config.new(
17
16
  blocked_tables: mysql_genius_config.blocked_tables,
18
17
  masked_column_patterns: mysql_genius_config.masked_column_patterns,
19
18
  query_timeout_ms: mysql_genius_config.query_timeout_ms,
20
19
  )
21
- runner = MysqlGenius::Core::QueryRunner.new(connection, runner_config)
20
+ runner = MysqlGenius::Core::QueryRunner.new(rails_connection, runner_config)
22
21
 
23
22
  begin
24
23
  result = runner.run(sql, row_limit: row_limit)
@@ -48,13 +47,12 @@ module MysqlGenius
48
47
  sql = params[:sql].to_s.strip
49
48
  skip_validation = params[:from_slow_query] == "true"
50
49
 
51
- connection = MysqlGenius::Core::Connection::ActiveRecordAdapter.new(ActiveRecord::Base.connection)
52
50
  runner_config = MysqlGenius::Core::QueryRunner::Config.new(
53
51
  blocked_tables: mysql_genius_config.blocked_tables,
54
52
  masked_column_patterns: mysql_genius_config.masked_column_patterns,
55
53
  query_timeout_ms: mysql_genius_config.query_timeout_ms,
56
54
  )
57
- explainer = MysqlGenius::Core::QueryExplainer.new(connection, runner_config)
55
+ explainer = MysqlGenius::Core::QueryExplainer.new(rails_connection, runner_config)
58
56
 
59
57
  result = explainer.explain(sql, skip_validation: skip_validation)
60
58
  render(json: { columns: result.columns, rows: result.rows })
@@ -16,5 +16,14 @@ module MysqlGenius
16
16
  def mysql_genius_config
17
17
  MysqlGenius.configuration
18
18
  end
19
+
20
+ # Wraps ActiveRecord::Base.connection in a Core::Connection::ActiveRecordAdapter.
21
+ # Every controller action that delegates to a Core::* service calls this
22
+ # instead of instantiating the adapter inline. Shared across all concerns
23
+ # (QueryExecution, DatabaseAnalysis, AiFeatures) via BaseController's
24
+ # private method lookup.
25
+ def rails_connection
26
+ MysqlGenius::Core::Connection::ActiveRecordAdapter.new(ActiveRecord::Base.connection)
27
+ end
19
28
  end
20
29
  end
@@ -59,9 +59,5 @@ module MysqlGenius
59
59
  def queryable_tables
60
60
  ActiveRecord::Base.connection.tables - mysql_genius_config.blocked_tables
61
61
  end
62
-
63
- def rails_connection
64
- MysqlGenius::Core::Connection::ActiveRecordAdapter.new(ActiveRecord::Base.connection)
65
- end
66
62
  end
67
63
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module MysqlGenius
4
- VERSION = "0.5.1"
4
+ VERSION = "0.6.0"
5
5
  end
data/mysql_genius.gemspec CHANGED
@@ -20,7 +20,6 @@ Gem::Specification.new do |spec|
20
20
  spec.required_ruby_version = ">= 2.6.0"
21
21
 
22
22
  spec.metadata["homepage_uri"] = spec.homepage
23
- spec.metadata["source_code_uri"] = spec.homepage
24
23
  spec.metadata["changelog_uri"] = "#{spec.homepage}/blob/main/CHANGELOG.md"
25
24
 
26
25
  spec.files = Dir.chdir(File.expand_path("..", __FILE__)) do
@@ -30,7 +29,7 @@ Gem::Specification.new do |spec|
30
29
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
31
30
  spec.require_paths = ["lib"]
32
31
 
33
- spec.add_dependency("activerecord", ">= 5.2", "< 9")
34
- spec.add_dependency("mysql_genius-core", "~> 0.5.0")
35
- spec.add_dependency("railties", ">= 5.2", "< 9")
32
+ spec.add_dependency("activerecord", ">= 6.0", "< 9")
33
+ spec.add_dependency("mysql_genius-core", "~> 0.6.0")
34
+ spec.add_dependency("railties", ">= 6.0", "< 9")
36
35
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mysql_genius
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.1
4
+ version: 0.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Antarr Byrd
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2026-04-13 00:00:00.000000000 Z
11
+ date: 2026-04-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord
@@ -16,7 +16,7 @@ dependencies:
16
16
  requirements:
17
17
  - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: '5.2'
19
+ version: '6.0'
20
20
  - - "<"
21
21
  - !ruby/object:Gem::Version
22
22
  version: '9'
@@ -26,7 +26,7 @@ dependencies:
26
26
  requirements:
27
27
  - - ">="
28
28
  - !ruby/object:Gem::Version
29
- version: '5.2'
29
+ version: '6.0'
30
30
  - - "<"
31
31
  - !ruby/object:Gem::Version
32
32
  version: '9'
@@ -36,21 +36,21 @@ dependencies:
36
36
  requirements:
37
37
  - - "~>"
38
38
  - !ruby/object:Gem::Version
39
- version: 0.5.0
39
+ version: 0.6.0
40
40
  type: :runtime
41
41
  prerelease: false
42
42
  version_requirements: !ruby/object:Gem::Requirement
43
43
  requirements:
44
44
  - - "~>"
45
45
  - !ruby/object:Gem::Version
46
- version: 0.5.0
46
+ version: 0.6.0
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: railties
49
49
  requirement: !ruby/object:Gem::Requirement
50
50
  requirements:
51
51
  - - ">="
52
52
  - !ruby/object:Gem::Version
53
- version: '5.2'
53
+ version: '6.0'
54
54
  - - "<"
55
55
  - !ruby/object:Gem::Version
56
56
  version: '9'
@@ -60,7 +60,7 @@ dependencies:
60
60
  requirements:
61
61
  - - ">="
62
62
  - !ruby/object:Gem::Version
63
- version: '5.2'
63
+ version: '6.0'
64
64
  - - "<"
65
65
  - !ruby/object:Gem::Version
66
66
  version: '9'
@@ -116,7 +116,6 @@ licenses:
116
116
  - MIT
117
117
  metadata:
118
118
  homepage_uri: https://github.com/antarr/mysql_genius
119
- source_code_uri: https://github.com/antarr/mysql_genius
120
119
  changelog_uri: https://github.com/antarr/mysql_genius/blob/main/CHANGELOG.md
121
120
  post_install_message:
122
121
  rdoc_options: []