sql_genius 0.9.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 +7 -0
- data/CHANGELOG.md +195 -0
- data/LICENSE.txt +65 -0
- data/README.md +178 -0
- data/Rakefile +8 -0
- data/app/controllers/concerns/sql_genius/ai_features.rb +332 -0
- data/app/controllers/concerns/sql_genius/database_analysis.rb +67 -0
- data/app/controllers/concerns/sql_genius/query_execution.rb +87 -0
- data/app/controllers/concerns/sql_genius/shared_view_helpers.rb +76 -0
- data/app/controllers/sql_genius/base_controller.rb +29 -0
- data/app/controllers/sql_genius/queries_controller.rb +94 -0
- data/app/views/layouts/sql_genius/application.html.erb +285 -0
- data/config/routes.rb +34 -0
- data/docs/guides/ai-features.md +115 -0
- data/docs/guides/getting-started-rails.md +118 -0
- data/docs/guides/ssh-tunnel-connections.md +151 -0
- data/docs/screenshots/ai_tools.png +0 -0
- data/docs/screenshots/dashboard.png +0 -0
- data/docs/screenshots/duplicate_indexes.png +0 -0
- data/docs/screenshots/query_explore.png +0 -0
- data/docs/screenshots/query_stats.png +0 -0
- data/docs/screenshots/server.png +0 -0
- data/docs/screenshots/table_sizes.png +0 -0
- data/lib/generators/sql_genius/install/install_generator.rb +19 -0
- data/lib/generators/sql_genius/install/templates/initializer.rb +56 -0
- data/lib/sql_genius/configuration.rb +114 -0
- data/lib/sql_genius/core/ai/client.rb +155 -0
- data/lib/sql_genius/core/ai/config.rb +47 -0
- data/lib/sql_genius/core/ai/connection_advisor.rb +96 -0
- data/lib/sql_genius/core/ai/describe_query.rb +41 -0
- data/lib/sql_genius/core/ai/dialect_hints.rb +35 -0
- data/lib/sql_genius/core/ai/index_advisor.rb +43 -0
- data/lib/sql_genius/core/ai/index_planner.rb +91 -0
- data/lib/sql_genius/core/ai/innodb_interpreter.rb +78 -0
- data/lib/sql_genius/core/ai/migration_risk.rb +51 -0
- data/lib/sql_genius/core/ai/optimization.rb +81 -0
- data/lib/sql_genius/core/ai/pattern_grouper.rb +94 -0
- data/lib/sql_genius/core/ai/rewrite_query.rb +51 -0
- data/lib/sql_genius/core/ai/schema_context_builder.rb +82 -0
- data/lib/sql_genius/core/ai/schema_review.rb +46 -0
- data/lib/sql_genius/core/ai/suggestion.rb +74 -0
- data/lib/sql_genius/core/ai/variable_reviewer.rb +113 -0
- data/lib/sql_genius/core/ai/workload_digest.rb +86 -0
- data/lib/sql_genius/core/analysis/columns.rb +63 -0
- data/lib/sql_genius/core/analysis/duplicate_indexes.rb +85 -0
- data/lib/sql_genius/core/analysis/query_history.rb +50 -0
- data/lib/sql_genius/core/analysis/query_stats.rb +76 -0
- data/lib/sql_genius/core/analysis/server_overview.rb +294 -0
- data/lib/sql_genius/core/analysis/stats_collector.rb +118 -0
- data/lib/sql_genius/core/analysis/stats_history.rb +42 -0
- data/lib/sql_genius/core/analysis/table_sizes.rb +52 -0
- data/lib/sql_genius/core/analysis/unused_indexes.rb +62 -0
- data/lib/sql_genius/core/column_definition.rb +30 -0
- data/lib/sql_genius/core/connection/active_record_adapter.rb +75 -0
- data/lib/sql_genius/core/connection/fake_adapter.rb +114 -0
- data/lib/sql_genius/core/connection.rb +37 -0
- data/lib/sql_genius/core/execution_result.rb +27 -0
- data/lib/sql_genius/core/index_definition.rb +23 -0
- data/lib/sql_genius/core/query_builders/mysql.rb +169 -0
- data/lib/sql_genius/core/query_builders/postgresql.rb +185 -0
- data/lib/sql_genius/core/query_builders.rb +27 -0
- data/lib/sql_genius/core/query_explainer.rb +113 -0
- data/lib/sql_genius/core/query_runner/config.rb +21 -0
- data/lib/sql_genius/core/query_runner.rb +123 -0
- data/lib/sql_genius/core/result.rb +43 -0
- data/lib/sql_genius/core/server_info.rb +54 -0
- data/lib/sql_genius/core/sql_validator.rb +149 -0
- data/lib/sql_genius/core/views/sql_genius/queries/_shared_results.html.erb +59 -0
- data/lib/sql_genius/core/views/sql_genius/queries/_tab_ai_tools.html.erb +43 -0
- data/lib/sql_genius/core/views/sql_genius/queries/_tab_dashboard.html.erb +97 -0
- data/lib/sql_genius/core/views/sql_genius/queries/_tab_duplicate_indexes.html.erb +35 -0
- data/lib/sql_genius/core/views/sql_genius/queries/_tab_query_explorer.html.erb +110 -0
- data/lib/sql_genius/core/views/sql_genius/queries/_tab_query_stats.html.erb +43 -0
- data/lib/sql_genius/core/views/sql_genius/queries/_tab_server.html.erb +59 -0
- data/lib/sql_genius/core/views/sql_genius/queries/_tab_slow_queries.html.erb +17 -0
- data/lib/sql_genius/core/views/sql_genius/queries/_tab_table_sizes.html.erb +33 -0
- data/lib/sql_genius/core/views/sql_genius/queries/_tab_unused_indexes.html.erb +54 -0
- data/lib/sql_genius/core/views/sql_genius/queries/dashboard.html.erb +1826 -0
- data/lib/sql_genius/core/views/sql_genius/queries/query_detail.html.erb +465 -0
- data/lib/sql_genius/core.rb +72 -0
- data/lib/sql_genius/engine.rb +31 -0
- data/lib/sql_genius/slow_query_monitor.rb +43 -0
- data/lib/sql_genius/version.rb +5 -0
- data/lib/sql_genius.rb +29 -0
- data/sql_genius.gemspec +47 -0
- metadata +171 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: f20a1a129d62d967470cbf11082c11772b3e2f8a8041a8d3de7edefd7e2f789c
|
|
4
|
+
data.tar.gz: ce514b35658ebfbebff2b7d7b11a29da096dfd8e01082c0c3aad3ed7e1081eae
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: 8effd028d592666cc4054f505c85969e2f908fd2775909f0cfcc48f91e5fbf726bdbdaf25b1d1ad0f62f4baa1f4db90a9c126feeb0442b7d000d183ef17b28f1
|
|
7
|
+
data.tar.gz: be54e67e85e4c12aa52264c46946328d94400513c308032d82dabbe29fe48e95e016adef010ea9602b58a66371fc065a929a0d0fb786e4e3ae4f4f9fb452e114
|
data/CHANGELOG.md
ADDED
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## 0.9.0
|
|
4
|
+
|
|
5
|
+
### Added
|
|
6
|
+
- **PostgreSQL support across the dashboard.** Analyses (table sizes, query stats, unused indexes, server overview, duplicate indexes, query history) and the query detail page now run against PostgreSQL in addition to MySQL/MariaDB. Dialect is detected automatically from the `ActiveRecord::Base.connection`.
|
|
7
|
+
- `SqlGenius::Core::QueryBuilders` — dialect-aware SQL generation layer with two builders (`Mysql` covering MySQL/MariaDB, `Postgresql`). Analyses delegate SQL generation through it.
|
|
8
|
+
- `SqlGenius::Core::Analysis::QueryHistory` — single-digest stats lookup used by the query detail page; reads `pg_stat_statements` on PG, `performance_schema.events_statements_summary_by_digest` on MySQL.
|
|
9
|
+
- `SqlGenius::Core::Analysis::DuplicateIndexes` now includes a `drop_sql` field per result (`ALTER TABLE ... DROP INDEX` on MySQL, `DROP INDEX IF EXISTS "..."` on PG). The dashboard JS uses this instead of assembling MySQL syntax client-side.
|
|
10
|
+
- `SqlGenius::Core::UnsupportedDialect` error class. `VariableReviewer`, `ConnectionAdvisor`, and `InnodbInterpreter` raise it on PG so the UI surfaces a clear "MySQL/MariaDB-only" message instead of a raw `PG::SyntaxError`. Controller-side `root_cause` and `anomaly_detection` short-circuit on PG with the same kind of error.
|
|
11
|
+
- `Core::ServerInfo` recognises `:postgresql` as a vendor; exposes `#postgresql?` and `#dialect`.
|
|
12
|
+
- `Core::QueryRunner` issues `SET statement_timeout = ms` (and resets to 0 in an `ensure` block) on PostgreSQL; recognises `canceling statement due to statement timeout` as a timeout error.
|
|
13
|
+
- `Core::SqlValidator` blocks PG system schemas (`pg_catalog`, `pg_toast`, `pg_temp`) and parses double-quoted identifiers.
|
|
14
|
+
|
|
15
|
+
### Changed
|
|
16
|
+
- The gem and public brand now use `sql_genius` / `SqlGenius`. The default mount path, install generator, initializer path, require paths, GitHub links, and RubyGems publishing workflow now use the new name.
|
|
17
|
+
- **`sql_genius-core` has been merged back into the main `sql_genius` gem.** The split was originally added to support a planned desktop app; with that path discontinued, the two gems become one. Host apps no longer need `gem "sql_genius-core"` in their Gemfile — it's gone, and the runtime dependency in `sql_genius.gemspec` is gone too. The `SqlGenius::Core::*` namespace is preserved, so all existing `require` paths and constant lookups continue to work unchanged.
|
|
18
|
+
- `ActiveRecordAdapter#server_version` is memoized — dialect detection runs `SELECT VERSION()` at most once per adapter instance.
|
|
19
|
+
- Tab header text in Tables / Query Stats / Unused Indexes no longer mentions `performance_schema` / `information_schema` by name.
|
|
20
|
+
|
|
21
|
+
### Removed
|
|
22
|
+
- The `sql_genius-desktop` gem stub. Desktop sidecar / macOS DMG packaging scripts (`packaging/macos/`) are removed; they only assembled the now-deleted gem.
|
|
23
|
+
- `SqlGenius::Core::VERSION` constant. Use `SqlGenius::VERSION`.
|
|
24
|
+
|
|
25
|
+
### Unused Indexes: PgHero-style context
|
|
26
|
+
- `GET /sql_genius/unused_indexes` now returns `{ indexes: [...], stats_reset_at, min_scans }` instead of a bare array. The Unused Indexes tab shows "Stats last reset N ago · threshold: scans ≤ M" above the table so an empty/fresh stats source doesn't read as "everything is unused."
|
|
27
|
+
- New `config.min_unused_index_scans` (default 0 — PgHero parity). Raise it (e.g. 50) to ignore indexes that are technically used but rarely enough to consider dropping.
|
|
28
|
+
- The PG query now sorts results by index byte size DESC (largest first — biggest wins). Each result hash carries a `size_bytes` field; the table shows a Size column. `pg_relation_size` is the source.
|
|
29
|
+
- Removed the `c.reltuples > 0` filter so indexes on empty tables show up too (matches PgHero — empty tables with indexes are still actionable noise).
|
|
30
|
+
|
|
31
|
+
### Notes
|
|
32
|
+
- PostgreSQL query stats require the `pg_stat_statements` extension to be installed and enabled (`shared_preload_libraries`).
|
|
33
|
+
- Slow query log capture remains MySQL-only.
|
|
34
|
+
|
|
35
|
+
## 0.8.1
|
|
36
|
+
|
|
37
|
+
### Fixed
|
|
38
|
+
- **Older MySQL compatibility** — the `DIGEST` column in `performance_schema.events_statements_summary_by_digest` is not present on all MySQL/MariaDB versions. `QueryStats` now checks for column existence before including it in the SELECT. Query links in the Query Stats tab gracefully degrade to plain text when the digest is unavailable.
|
|
39
|
+
|
|
40
|
+
## 0.8.0
|
|
41
|
+
|
|
42
|
+
### Added
|
|
43
|
+
- **6 new AI analysis features:**
|
|
44
|
+
- **Variable Config Reviewer** — reviews my.cnf settings against observed workload
|
|
45
|
+
- **Connection Pressure Advisor** — diagnoses connection pool health
|
|
46
|
+
- **Workload Digest** — executive summary of the entire query workload
|
|
47
|
+
- **InnoDB Health Interpreter** — plain English translation of `SHOW ENGINE INNODB STATUS`
|
|
48
|
+
- **Index Consolidation Planner** — holistic drop/merge/add index plan across tables
|
|
49
|
+
- **Slow Query Pattern Grouper** — groups slow queries by shared root cause
|
|
50
|
+
- AI buttons added to Server tab, Query Stats tab, and Indexes tabs
|
|
51
|
+
- `sql_genius` now declares runtime dependency on `sql_genius-core ~> 0.8.0`
|
|
52
|
+
|
|
53
|
+
## 0.7.2
|
|
54
|
+
|
|
55
|
+
### Added
|
|
56
|
+
- **Anthropic Messages API support** — `x-api-key` auth style with `anthropic-version` header, top-level `system` parameter, `content[0].text` response parsing.
|
|
57
|
+
- **Configurable `max_tokens`** — new field on `Core::Ai::Config` (default 4096), sent to both OpenAI and Anthropic APIs.
|
|
58
|
+
- **Copy response button** on all AI result sections (schema review, migration risk, optimization, describe query, rewrite, index advisor, root cause, anomaly detection).
|
|
59
|
+
- **Dark mode contrast fixes** for AI result sections — proper CSS classes with dark-mode variants replace hardcoded light-mode inline styles.
|
|
60
|
+
- **`capability?(:standalone_header)`** guard hides the dashboard header when rendered inside a layout that already provides one.
|
|
61
|
+
|
|
62
|
+
## 0.7.1
|
|
63
|
+
|
|
64
|
+
Lockstep version bump with `sql_genius-core 0.7.1` which fixes missing ERB templates in the gem package.
|
|
65
|
+
|
|
66
|
+
## 0.7.0
|
|
67
|
+
|
|
68
|
+
### Added
|
|
69
|
+
- **`capability?(name)` helper** in `SharedViewHelpers`. The Rails adapter returns `true` for all capabilities; the desktop sidecar uses it to hide Redis-backed features (slow_queries, anomaly_detection, root_cause) from the shared dashboard templates.
|
|
70
|
+
- **Query detail page** at `GET /queries/:digest` with syntax-highlighted SQL, Explain button, aggregate stats cards, and three inline SVG time-series charts (Total Time, Average Time, Calls).
|
|
71
|
+
- **`Core::Analysis::StatsHistory`** — thread-safe in-memory ring buffer for per-digest query stats snapshots (24hr retention at 60s intervals).
|
|
72
|
+
- **`Core::Analysis::StatsCollector`** — background thread that samples `performance_schema.events_statements_summary_by_digest` every 60s, computes deltas, and records to StatsHistory.
|
|
73
|
+
- **`DIGEST` hash** added to `Core::Analysis::QueryStats` return value for stable URL keys.
|
|
74
|
+
- **Stats collection config option** (`stats_collection`, default `true`) — controls whether the background collector starts on boot.
|
|
75
|
+
- **Query Stats tab linkification** — SQL cells in the Query Stats table are now clickable links to the query detail page.
|
|
76
|
+
- `sql_genius` now declares runtime dependency on `sql_genius-core ~> 0.7.0`.
|
|
77
|
+
|
|
78
|
+
## 0.6.0
|
|
79
|
+
|
|
80
|
+
### Changed
|
|
81
|
+
- **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 `sql_genius 0.5.0` (`gem "sql_genius", "~> 0.5.0"`) if you can't upgrade Rails yet.
|
|
82
|
+
- `sql_genius` now declares runtime dependency on `sql_genius-core ~> 0.6.0` (was `~> 0.5.0`).
|
|
83
|
+
|
|
84
|
+
### Fixed
|
|
85
|
+
- **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.
|
|
86
|
+
|
|
87
|
+
### Internal
|
|
88
|
+
- **`rails_connection` consolidated into `BaseController`.** Nine inline `SqlGenius::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.
|
|
89
|
+
- **`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.
|
|
90
|
+
- **`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.
|
|
91
|
+
- **`Core::Analysis::Columns` spec** covers the `default: false` branch (6th column outside `default_columns`).
|
|
92
|
+
- **`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.
|
|
93
|
+
- **Gemspec `source_code_uri` duplicate dropped** from both gemspecs (was equal to `homepage_uri` and triggered a RubyGems build warning on every release).
|
|
94
|
+
|
|
95
|
+
### Documentation
|
|
96
|
+
- README Compatibility table no longer lists Rails 5.2. The note explaining the drop and pinning instructions stays in place.
|
|
97
|
+
|
|
98
|
+
## 0.5.0
|
|
99
|
+
|
|
100
|
+
### Changed
|
|
101
|
+
- **ERB templates moved into `sql_genius-core`.** All 11 view files (`dashboard.html.erb` and 10 partials) have been extracted from `app/views/sql_genius/queries/` into `gems/sql_genius-core/lib/sql_genius/core/views/sql_genius/queries/`. The index template is renamed to `dashboard.html.erb`. The engine registers `SqlGenius::Core.views_path` before `:add_view_paths` so Rails finds templates in both view roots. Non-Rails adapters (Phase 2b `sql_genius-desktop` sidecar) can register this same path with their own view loader and implement `path_for`/`render_partial` to reuse the templates.
|
|
102
|
+
- **`QueriesController#index`** now sets `@framework_version_major` and `@framework_version_minor` instance variables (replacing direct `Rails::VERSION` references in the template) and explicitly renders `"sql_genius/queries/dashboard"`.
|
|
103
|
+
- **`SharedViewHelpers`** — new concern providing `path_for(name)` and `render_partial(name)` as the 2-method contract the shared templates depend on. `render_partial` delegates to `view_context.render(partial: "sql_genius/queries/#{name}")`.
|
|
104
|
+
- Extracted 5 AI prompt builders from the `AiFeatures` concern into `SqlGenius::Core::Ai::{DescribeQuery, SchemaReview, RewriteQuery, IndexAdvisor, MigrationRisk}` plus a shared `Core::Ai::SchemaContextBuilder` helper. `anomaly_detection` and `root_cause` remain in the Rails concern because they depend on the Redis-backed `SlowQueryMonitor`.
|
|
105
|
+
- Extracted `QueriesController#columns` logic into `SqlGenius::Core::Analysis::Columns` with a tagged-result struct. Retires the `masked_column?` helper added in the 0.4.1 hotfix.
|
|
106
|
+
- `SqlGenius::Core::Ai::Config` gains a `domain_context:` field. The Rails adapter defaults it to a Rails-specific string; `sql_genius-desktop` will default to empty.
|
|
107
|
+
- `sql_genius` now declares runtime dependency on `sql_genius-core ~> 0.5.0` (was `~> 0.4.0`).
|
|
108
|
+
|
|
109
|
+
### Added
|
|
110
|
+
- Integration test suite at `spec/dummy/` + `spec/rails_helper.rb` + `spec/requests/`. Boots a minimal Rails engine dummy app and dispatches real HTTP requests against the mounted engine via `Rack::Test`. Dedicated regression specs at `spec/regressions/` pin the two Phase 1b latent bugs (`Core::Connection::ActiveRecordAdapter` boot-order and `QueriesController#masked_column?` helper deletion) so they can never silently return.
|
|
111
|
+
- `CLAUDE.md` updated: the "no Rails boot in tests" rule is relaxed to a two-tier model (unit specs stub AR, integration specs boot Rails via `spec/dummy/`).
|
|
112
|
+
|
|
113
|
+
### Internal
|
|
114
|
+
- `SqlGenius::Core.views_path` — new public module method returning the absolute path to the shared ERB template directory.
|
|
115
|
+
|
|
116
|
+
## 0.4.1
|
|
117
|
+
|
|
118
|
+
### Fixed
|
|
119
|
+
- **`GET /columns` endpoint raised `NoMethodError: undefined method 'masked_column?'` at runtime** — a second Phase 1b regression (0.4.0 also shipped the `ActiveRecordAdapter` boot-order bug). When `SqlValidator::masked_column?` was promoted to a 2-arg class method during Phase 1b, the one remaining caller in `QueriesController#columns` was not updated. Clicking a table in the Query Explorer dropdown on 0.4.0 hits this route and triggers a 500. Fixed by reintroducing a private `masked_column?(name)` helper on `QueriesController` that delegates to `SqlGenius::Core::SqlValidator.masked_column?(name, sql_genius_config.masked_column_patterns)`. The call site on line 30 is untouched. Regression guard is deferred to Phase 2a's planned `spec/dummy/` Rails dummy app — the project's "no Rails boot in tests" policy blocks writing a controller-level unit spec for this without novel scaffolding. Empirically verified in-process: `masked_column?("password_hash") == true`, `masked_column?("email") == false`, `masked_column?("api_token") == true`.
|
|
120
|
+
|
|
121
|
+
## 0.4.0
|
|
122
|
+
|
|
123
|
+
### Fixed
|
|
124
|
+
- **Boot-order bug: `SqlGenius::Core::Connection::ActiveRecordAdapter` was not required by `lib/sql_genius.rb`** — shipped in Phase 1a but never wired into the production require chain. Invisible to CI because the adapter's spec file explicitly required it, and invisible in development because pre-Phase-1b concerns didn't reference it. Phase 1b's extracted delegators instantiate it in every action, so the missing require would have surfaced as `uninitialized constant` on every tab (tables, query stats, unused indexes, duplicate indexes, server overview, execute, explain, AI suggest, AI optimize) in any host app that installed 0.4.0 without the fix. `lib/sql_genius.rb` now explicitly requires the adapter after loading `sql_genius/core`, and `spec/spec_helper.rb` has a regression guard that aborts the spec suite at boot if the constant is not reachable via a plain `require "sql_genius"`.
|
|
125
|
+
|
|
126
|
+
### Changed
|
|
127
|
+
- **Internal refactor: extracted Rails-free core library into a new `sql_genius-core` gem.** The validator, AI services, value objects, database analyses, query runner, and query explainer now live in `sql_genius-core`; the `sql_genius` Rails engine delegates through a new `Core::Connection::ActiveRecordAdapter`. Public API, routes, config DSL, and JSON response shapes are unchanged — host apps see no difference after `bundle update`. See [the design spec](docs/superpowers/specs/2026-04-10-desktop-app-design.md) for the motivation: the new core gem is the foundation for a forthcoming `sql_genius-desktop` standalone app.
|
|
128
|
+
- `sql_genius` now declares a runtime dependency on `sql_genius-core ~> 0.4.0`. The two gems release in lockstep under matching version numbers (0.4.0 is the first paired release); the dependency resolves transitively, so host apps do not need to add `sql_genius-core` to their Gemfile.
|
|
129
|
+
- `SqlGenius::SqlValidator` moved to `SqlGenius::Core::SqlValidator`.
|
|
130
|
+
- `SqlGenius::AiClient`, `SqlGenius::AiSuggestionService`, `SqlGenius::AiOptimizationService` moved to `SqlGenius::Core::Ai::{Client, Suggestion, Optimization}` and now take an explicit `Core::Ai::Config` instead of reading `SqlGenius.configuration` at construction time.
|
|
131
|
+
- The 5 database analyses (`table_sizes`, `duplicate_indexes`, `query_stats`, `unused_indexes`, `server_overview`) moved from the `DatabaseAnalysis` controller concern into `SqlGenius::Core::Analysis::*` classes, each taking a `Core::Connection`. The concern shrunk from ~295 lines to 47 lines of thin delegating wrappers.
|
|
132
|
+
- `SqlGenius::Core::QueryRunner` now owns SQL validation, row-limit application, timeout-hint wrapping (MySQL / MariaDB flavors), execution, column masking, and timeout detection. The `execute` controller action delegates to it. Audit logging stays in the Rails adapter.
|
|
133
|
+
- `SqlGenius::Core::QueryExplainer` now owns the EXPLAIN path with optional validation-skipping for captured slow queries. The `explain` controller action delegates to it.
|
|
134
|
+
|
|
135
|
+
### Documentation
|
|
136
|
+
- Added README troubleshooting section covering `SSL_connect ... EC lib` / `unable to decode issuer public key` errors that hit Ruby 2.7 + OpenSSL 1.1.x users talking to Google Trust Services-backed hosts like Ollama Cloud. Recommends local Ollama (`http://localhost:11434`) as the fastest unblock, `SSL_CERT_FILE` pointing at a fresher CA bundle as an intermediate fix, and upgrading to Ruby 3.2+ as the durable fix.
|
|
137
|
+
- Added `docs/superpowers/specs/2026-04-10-desktop-app-design.md` — the full design spec for the eventual `sql_genius-desktop` standalone app.
|
|
138
|
+
|
|
139
|
+
## 0.3.2
|
|
140
|
+
|
|
141
|
+
### Fixed
|
|
142
|
+
- **Query Stats tab stuck on loading spinner** -- commented-out HTML controls in `_tab_query_stats.html.erb` left corresponding JavaScript (`el('qstats-sort').value` and two `addEventListener` calls) throwing `TypeError` on null elements, killing `loadQueryStats` before it could issue its fetch. The commented-out markup and the dead JavaScript have both been removed; client-side sortable column headers continue to provide sort UX.
|
|
143
|
+
|
|
144
|
+
## 0.3.1
|
|
145
|
+
|
|
146
|
+
### Added
|
|
147
|
+
- **Sortable columns** -- click any column header to sort ascending/descending on all data tables
|
|
148
|
+
- **Automated RubyGems publishing** -- GitHub Actions workflow publishes gem on tag push
|
|
149
|
+
|
|
150
|
+
### Fixed
|
|
151
|
+
- **Query stats noise** -- SQLGenius internal queries (information_schema, performance_schema, SHOW, etc.) are now excluded from the Query Stats tab
|
|
152
|
+
|
|
153
|
+
## 0.3.0
|
|
154
|
+
|
|
155
|
+
### Improved
|
|
156
|
+
- **SQL syntax highlighting** -- SQL code blocks in tables now feature a dark-themed syntax highlighter with distinct colors for keywords, functions, strings, numbers, operators, identifiers, and placeholders (Catppuccin Mocha palette)
|
|
157
|
+
- **Table visual hierarchy** -- redesigned table headers (uppercase, thicker bottom border, rounded top corners), improved row hover states (blue tint), cleaner alternating row colors, removed vertical cell borders
|
|
158
|
+
- **Numeric column formatting** -- right-aligned with monospace tabular-nums font for easy scanning; duration values color-coded green/amber/red by severity
|
|
159
|
+
- **Overall dashboard polish** -- more generous cell padding, improved inline `code` tag styling, added `mg-badge-success` variant
|
|
160
|
+
- **Tab persistence** -- active tab is remembered across page reloads via URL hash
|
|
161
|
+
|
|
162
|
+
### Fixed
|
|
163
|
+
- **Unused indexes SQL error on MySQL 8.0+** -- `reads` and `writes` are reserved words and now use backtick quoting
|
|
164
|
+
|
|
165
|
+
### Added
|
|
166
|
+
- **Dark theme** -- auto-detects system preference, manual toggle via sun/moon button, persisted in localStorage
|
|
167
|
+
- **Tables tab** -- renamed from "Table Sizes", now shows engine, collation, auto-increment, last updated, and accurate row counts via `COUNT(*)`
|
|
168
|
+
- **Optimize suggestions** -- tables with >10% fragmentation are flagged with an optimize badge
|
|
169
|
+
|
|
170
|
+
## 0.2.0
|
|
171
|
+
|
|
172
|
+
- **Dashboard-first redesign** -- new default landing page with server health, top slow queries, top expensive queries, and index alert badges
|
|
173
|
+
- **Query Explorer** -- merged Visual Builder and SQL Query into one tab with a mode toggle
|
|
174
|
+
- **Suggested migrations** -- duplicate and unused index tabs generate timestamped Rails migrations with copy-to-clipboard
|
|
175
|
+
- **Install generator** -- `rails generate sql_genius:install` creates initializer and mounts the engine
|
|
176
|
+
- **RuboCop** -- added rubocop-shopify and rubocop-rspec, enforced across the codebase
|
|
177
|
+
- **CI matrix** -- added Ruby 3.4, Rails 8.0 and 8.1; excluded incompatible Ruby 3.4 + Rails 6.1/7.0 combos
|
|
178
|
+
- **Smarter AI prompts** -- schema review now includes primary keys and Rails-aware context (no foreign key constraint recommendations, recommends indexes on FK columns instead)
|
|
179
|
+
- **SSL fix** -- explicit CA certificate file for AI API requests
|
|
180
|
+
- Tab reorder: Dashboard, Slow Queries, Query Stats, Server, Table Sizes, Unused Indexes, Duplicate Indexes, Query Explorer, AI Tools
|
|
181
|
+
- Dashboard links to Server tab for full details
|
|
182
|
+
- Clipboard fallback for non-HTTPS environments
|
|
183
|
+
- Gemspec description updated to lead with monitoring features
|
|
184
|
+
|
|
185
|
+
## 0.1.0
|
|
186
|
+
|
|
187
|
+
- Initial release
|
|
188
|
+
- Visual query builder with column selection, filters, and ordering
|
|
189
|
+
- Safe SQL execution (read-only, blocked tables, masked columns, row limits, timeouts)
|
|
190
|
+
- EXPLAIN analysis
|
|
191
|
+
- AI-powered query suggestions (optional)
|
|
192
|
+
- AI-powered query optimization from EXPLAIN output (optional)
|
|
193
|
+
- Slow query monitoring via Redis
|
|
194
|
+
- Audit logging
|
|
195
|
+
- MariaDB support
|
data/LICENSE.txt
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
SQLGenius Source-Available Non-Commercial License 1.0
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Antarr Byrd
|
|
4
|
+
|
|
5
|
+
1. Grant of rights
|
|
6
|
+
|
|
7
|
+
You may use, copy, modify, and distribute this software and any modified
|
|
8
|
+
version of it for non-commercial purposes only, subject to the terms of this
|
|
9
|
+
license.
|
|
10
|
+
|
|
11
|
+
2. Non-commercial use only
|
|
12
|
+
|
|
13
|
+
"Non-commercial" means a use that is not primarily intended for or directed
|
|
14
|
+
toward commercial advantage or monetary compensation.
|
|
15
|
+
|
|
16
|
+
Without prior written permission from the copyright holder, you may not use
|
|
17
|
+
this software:
|
|
18
|
+
|
|
19
|
+
- in connection with a business or other for-profit activity;
|
|
20
|
+
- for paid client work, consulting, or contract services;
|
|
21
|
+
- as part of a hosted or managed service, including SaaS;
|
|
22
|
+
- inside an internal business system or other revenue-supporting operation;
|
|
23
|
+
- as part of a commercial product, bundle, or offering that is sold,
|
|
24
|
+
licensed, or monetized; or
|
|
25
|
+
- in any other way primarily intended for commercial advantage or monetary
|
|
26
|
+
compensation.
|
|
27
|
+
|
|
28
|
+
3. Commercial licensing
|
|
29
|
+
|
|
30
|
+
Any commercial use requires prior written permission from the copyright
|
|
31
|
+
holder. Commercial licenses may require payment or another separately agreed
|
|
32
|
+
consideration. A donation by itself does not grant commercial rights unless
|
|
33
|
+
the copyright holder expressly says so in writing.
|
|
34
|
+
|
|
35
|
+
4. Redistribution
|
|
36
|
+
|
|
37
|
+
If you distribute this software or a modified version of it, you must:
|
|
38
|
+
|
|
39
|
+
- include this license text and the copyright notice with the distribution;
|
|
40
|
+
- clearly state that the software is licensed for non-commercial use only;
|
|
41
|
+
and
|
|
42
|
+
- clearly mark any material modifications you made.
|
|
43
|
+
|
|
44
|
+
You may not distribute this software under terms that grant recipients
|
|
45
|
+
commercial rights not granted by this license.
|
|
46
|
+
|
|
47
|
+
5. No trademark rights
|
|
48
|
+
|
|
49
|
+
This license does not grant any right to use the names, logos, or trademarks
|
|
50
|
+
of the copyright holder, except as necessary for reasonable attribution.
|
|
51
|
+
|
|
52
|
+
6. Termination
|
|
53
|
+
|
|
54
|
+
Any use of the software outside the scope of this license automatically
|
|
55
|
+
terminates your rights under it.
|
|
56
|
+
|
|
57
|
+
7. Disclaimer of warranty and limitation of liability
|
|
58
|
+
|
|
59
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
60
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
61
|
+
FITNESS FOR A PARTICULAR PURPOSE, AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
62
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES, OR OTHER
|
|
63
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT, OR OTHERWISE, ARISING FROM,
|
|
64
|
+
OUT OF, OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
65
|
+
THE SOFTWARE.
|
data/README.md
ADDED
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
# SQLGenius
|
|
2
|
+
|
|
3
|
+
An AI-powered SQL dashboard for Rails to help you inspect and optimize MySQL, MariaDB, and PostgreSQL databases.
|
|
4
|
+
|
|
5
|
+
## Screenshots
|
|
6
|
+
|
|
7
|
+
### Dashboard
|
|
8
|
+
|
|
9
|
+
At-a-glance server health, top slow queries, most expensive queries, and index alerts.
|
|
10
|
+
|
|
11
|
+

|
|
12
|
+
|
|
13
|
+
### Query Stats
|
|
14
|
+
|
|
15
|
+
Top queries from `performance_schema` sorted by total time, with SQL syntax highlighting and color-coded durations.
|
|
16
|
+
|
|
17
|
+

|
|
18
|
+
|
|
19
|
+
### Server Dashboard
|
|
20
|
+
|
|
21
|
+
Server health: version, connections, InnoDB buffer pool, and query activity with AI-powered diagnostics.
|
|
22
|
+
|
|
23
|
+

|
|
24
|
+
|
|
25
|
+
### Tables
|
|
26
|
+
|
|
27
|
+
Row counts, data size, index size, engine, fragmentation, and optimize suggestions for every table.
|
|
28
|
+
|
|
29
|
+

|
|
30
|
+
|
|
31
|
+
### Duplicate Index Detection
|
|
32
|
+
|
|
33
|
+
Find redundant indexes whose columns are a left-prefix of another index, with ready-to-run `DROP INDEX` statements.
|
|
34
|
+
|
|
35
|
+

|
|
36
|
+
|
|
37
|
+
### Query Explorer
|
|
38
|
+
|
|
39
|
+
Build queries visually or write raw SQL. Optional AI assistant generates queries from plain English descriptions.
|
|
40
|
+
|
|
41
|
+

|
|
42
|
+
|
|
43
|
+
### AI Tools
|
|
44
|
+
|
|
45
|
+
Schema review, query optimization, index advisor, anomaly detection, root cause analysis, and migration risk assessment.
|
|
46
|
+
|
|
47
|
+

|
|
48
|
+
|
|
49
|
+
## Features
|
|
50
|
+
|
|
51
|
+
- **Dashboard** -- server health, slow queries, expensive queries, index alerts at a glance
|
|
52
|
+
- **Query Explorer** -- visual builder + raw SQL editor with AI assistant
|
|
53
|
+
- **SQL Syntax Highlighting** -- dark-themed code blocks with color-coded keywords, functions, strings
|
|
54
|
+
- **Safe SQL Execution** -- read-only enforcement, blocked tables, masked columns, row limits, timeouts
|
|
55
|
+
- **EXPLAIN Analysis** -- run EXPLAIN on any query and view the execution plan
|
|
56
|
+
- **9 AI Tools** -- suggestions, optimization, schema review, query rewrite, index advisor, anomaly detection, root cause analysis, migration risk ([details](https://github.com/antarr/sql_genius/wiki/AI-Features))
|
|
57
|
+
- **Slow Query Monitoring** -- captures slow queries via ActiveSupport notifications and Redis ([details](https://github.com/antarr/sql_genius/wiki/Slow-Query-Monitoring))
|
|
58
|
+
- **Index Analysis** -- duplicate index detection, unused index detection with DROP statements
|
|
59
|
+
- **Dark Theme** -- auto-detects system preference with manual toggle ([details](https://github.com/antarr/sql_genius/wiki/Dark-Theme))
|
|
60
|
+
- **MariaDB Support** -- automatically detects MariaDB and uses appropriate timeout syntax
|
|
61
|
+
- **PostgreSQL Support** -- core analyses (table sizes, query stats, unused indexes, server overview) work on PostgreSQL via `pg_stat_statements` and `pg_stat_user_indexes`; dialect detected automatically
|
|
62
|
+
- **Self-contained UI** -- no external CSS/JS dependencies, no jQuery, works with any Rails layout
|
|
63
|
+
|
|
64
|
+
## Quick Start
|
|
65
|
+
|
|
66
|
+
```ruby
|
|
67
|
+
# Gemfile
|
|
68
|
+
gem "sql_genius"
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
```bash
|
|
72
|
+
bundle install
|
|
73
|
+
rails generate sql_genius:install
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
Visit `/sql_genius` in your browser.
|
|
77
|
+
|
|
78
|
+
For detailed setup, see the [Installation guide](https://github.com/antarr/sql_genius/wiki/Installation).
|
|
79
|
+
|
|
80
|
+
## Configuration
|
|
81
|
+
|
|
82
|
+
```ruby
|
|
83
|
+
SqlGenius.configure do |config|
|
|
84
|
+
config.base_controller = "ApplicationController"
|
|
85
|
+
config.authenticate = ->(controller) { controller.current_user&.admin? }
|
|
86
|
+
config.blocked_tables += %w[oauth_tokens api_keys]
|
|
87
|
+
end
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
For full configuration options, see the [Configuration guide](https://github.com/antarr/sql_genius/wiki/Configuration).
|
|
91
|
+
|
|
92
|
+
## AI Features (optional)
|
|
93
|
+
|
|
94
|
+
Works with OpenAI, Azure OpenAI, Ollama Cloud, local Ollama, or any OpenAI-compatible API.
|
|
95
|
+
|
|
96
|
+
```ruby
|
|
97
|
+
SqlGenius.configure do |config|
|
|
98
|
+
config.ai_endpoint = "https://api.openai.com/v1/chat/completions"
|
|
99
|
+
config.ai_api_key = ENV["OPENAI_API_KEY"]
|
|
100
|
+
config.ai_model = "gpt-4o"
|
|
101
|
+
config.ai_auth_style = :bearer
|
|
102
|
+
end
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
For all provider examples, see the [AI Features guide](https://github.com/antarr/sql_genius/wiki/AI-Features).
|
|
106
|
+
|
|
107
|
+
### Troubleshooting TLS errors with Ollama Cloud
|
|
108
|
+
|
|
109
|
+
If you see `SSL_connect ... unable to decode issuer public key` or `SSL_connect ... EC lib` when using an AI feature, your Rails host's Ruby is linked against an older OpenSSL that can't verify modern ECDSA certificate chains (Ollama Cloud is served behind Google Trust Services, whose ECDSA roots trip up OpenSSL 1.1.x and earlier). This is not specific to `sql_genius` — it affects any Ruby HTTPS call to those hosts.
|
|
110
|
+
|
|
111
|
+
Three ways to fix it, in order of effort:
|
|
112
|
+
|
|
113
|
+
**Use a local Ollama instead.** Point the endpoint at `http://localhost:11434/v1/chat/completions`. Your Rails app talks plain HTTP to the local `ollama` binary, which handles the upstream TLS itself using its own modern cert handling. For cloud-backed models, run `ollama signin` once and use the `:cloud` model suffix (e.g., `gemma3:27b-cloud`).
|
|
114
|
+
|
|
115
|
+
```ruby
|
|
116
|
+
SqlGenius.configure do |config|
|
|
117
|
+
config.ai_endpoint = "http://localhost:11434/v1/chat/completions"
|
|
118
|
+
config.ai_api_key = "unused-but-required" # any non-empty string
|
|
119
|
+
config.ai_model = "gemma3:27b-cloud" # or any local model
|
|
120
|
+
config.ai_auth_style = :bearer
|
|
121
|
+
end
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
**Point Ruby at a fresher CA bundle.** Set `SSL_CERT_FILE` in the environment where Rails boots. On macOS with Homebrew:
|
|
125
|
+
|
|
126
|
+
```bash
|
|
127
|
+
SSL_CERT_FILE=/opt/homebrew/etc/openssl@3/cert.pem bin/rails s
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
This helps if the problem is a stale trust store, but does **not** help if the underlying OpenSSL itself is too old to parse the cert's key algorithm.
|
|
131
|
+
|
|
132
|
+
**Upgrade Ruby** to 3.2 or newer. Ruby 2.7 is end-of-life (March 2023); newer Rubies link against OpenSSL 3.x which handles modern ECDSA chains correctly. This is the durable fix and the one we recommend for any project still on 2.7.
|
|
133
|
+
|
|
134
|
+
## Compatibility
|
|
135
|
+
|
|
136
|
+
| Rails | Ruby |
|
|
137
|
+
|-------|------|
|
|
138
|
+
| 6.0 | 2.7, 3.0, 3.1 |
|
|
139
|
+
| 6.1 | 2.7, 3.0, 3.1, 3.2, 3.3 |
|
|
140
|
+
| 7.0 | 2.7, 3.0, 3.1, 3.2, 3.3 |
|
|
141
|
+
| 7.1 | 2.7, 3.0, 3.1, 3.2, 3.3, 3.4 |
|
|
142
|
+
| 7.2 | 3.1, 3.2, 3.3, 3.4 |
|
|
143
|
+
| 8.0 | 3.2, 3.3, 3.4 |
|
|
144
|
+
| 8.1 | 3.2, 3.3, 3.4 |
|
|
145
|
+
|
|
146
|
+
> **Rails 5.2:** dropped in `sql_genius 0.6.0`. `sql_genius 0.5.0` is the last version to support Rails 5.2 — pin it (`gem "sql_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.
|
|
147
|
+
|
|
148
|
+
## Documentation
|
|
149
|
+
|
|
150
|
+
Full documentation is available on the [Wiki](https://github.com/antarr/sql_genius/wiki).
|
|
151
|
+
|
|
152
|
+
## Licensing
|
|
153
|
+
|
|
154
|
+
SqlGenius is source-available.
|
|
155
|
+
|
|
156
|
+
- Free for personal, educational, hobby, nonprofit, and other non-commercial use
|
|
157
|
+
- Commercial use requires prior written permission from the copyright holder
|
|
158
|
+
- Commercial use includes internal business use, paid client work, SaaS/hosting, resale, and bundling with a paid product or service
|
|
159
|
+
- Voluntary donations are welcome for non-commercial users, but a donation alone does not grant commercial rights
|
|
160
|
+
|
|
161
|
+
For commercial licensing requests, contact Antarr Byrd at antarr.t.byrd@uth.tmc.edu.
|
|
162
|
+
|
|
163
|
+
## Development
|
|
164
|
+
|
|
165
|
+
```bash
|
|
166
|
+
git clone https://github.com/antarr/sql_genius.git
|
|
167
|
+
cd sql_genius
|
|
168
|
+
bin/setup
|
|
169
|
+
bundle exec rspec
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
## Contributing
|
|
173
|
+
|
|
174
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/antarr/sql_genius.
|
|
175
|
+
|
|
176
|
+
## License
|
|
177
|
+
|
|
178
|
+
This project is licensed under the terms of the [SQLGenius Source-Available Non-Commercial License](LICENSE.txt). It is not distributed under the MIT License or another OSI-approved open source license.
|