query_console 0.1.0 → 0.2.1
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 +4 -4
- data/README.md +204 -28
- data/app/controllers/query_console/application_controller.rb +6 -3
- data/app/controllers/query_console/explain_controller.rb +47 -0
- data/app/controllers/query_console/queries_controller.rb +4 -1
- data/app/controllers/query_console/schema_controller.rb +32 -0
- data/app/javascript/query_console/controllers/editor_controller.js +182 -45
- data/app/services/query_console/audit_logger.rb +29 -3
- data/app/services/query_console/explain_runner.rb +137 -0
- data/app/services/query_console/runner.rb +56 -3
- data/app/services/query_console/schema_introspector.rb +244 -0
- data/app/services/query_console/sql_limiter.rb +10 -0
- data/app/services/query_console/sql_validator.rb +33 -6
- data/app/views/query_console/explain/_results.html.erb +89 -0
- data/app/views/query_console/queries/_results.html.erb +40 -4
- data/app/views/query_console/queries/new.html.erb +843 -328
- data/config/importmap.rb +8 -0
- data/config/routes.rb +5 -0
- data/lib/query_console/configuration.rb +21 -1
- data/lib/query_console/version.rb +1 -1
- metadata +16 -14
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 9ea5d214eb67f13c153578fce1f001109518b6935409774d9ae343de3ee87258
|
|
4
|
+
data.tar.gz: e7f2c6c7a528ababbef441b2d548cc635222701f5903cbdd1f06b9ecbefd3bc8
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 5780f01ddfc86f3f998ea7f67b449ff312c3e4e305a6a5c454593a9aec6d691879837171d0567d2db8def6b70503d77203eecf708e4878947463b9f0443ba5eb
|
|
7
|
+
data.tar.gz: 99f44e0e10f2c06cb428936bfeaf8757bef817353d535ef1088761c6df7ea6a546905ce12c076207a5252103ce7df37a487ff56846a7e89d92c9e37e376de813
|
data/README.md
CHANGED
|
@@ -1,18 +1,76 @@
|
|
|
1
1
|
# QueryConsole
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
[](https://badge.fury.io/rb/query_console)
|
|
4
|
+
[](MIT-LICENSE)
|
|
5
|
+
[](https://www.ruby-lang.org)
|
|
6
|
+
[](https://rubyonrails.org)
|
|
7
|
+
|
|
8
|
+
A Rails engine that provides a secure, mountable web interface for running SQL queries against your application's database. Read-only by default with optional DML support.
|
|
9
|
+
|
|
10
|
+

|
|
11
|
+
*Modern, responsive SQL query interface with schema explorer, query management, and real-time execution*
|
|
12
|
+
|
|
13
|
+
## Table of Contents
|
|
14
|
+
|
|
15
|
+
- [Features](#features)
|
|
16
|
+
- [Screenshots](#screenshots)
|
|
17
|
+
- [Security Features](#security-features)
|
|
18
|
+
- [Installation](#installation)
|
|
19
|
+
- [Configuration](#configuration)
|
|
20
|
+
- [Usage](#usage)
|
|
21
|
+
- [Security Considerations](#security-considerations)
|
|
22
|
+
- [Development](#development)
|
|
23
|
+
- [Troubleshooting](#troubleshooting)
|
|
24
|
+
- [Contributing](#contributing)
|
|
25
|
+
- [Changelog](#changelog)
|
|
4
26
|
|
|
5
27
|
## Features
|
|
6
28
|
|
|
7
|
-
|
|
29
|
+
### Security & Control
|
|
30
|
+
- 🔒 **Security First**: Read-only by default with multi-layer enforcement
|
|
8
31
|
- 🚦 **Environment Gating**: Disabled by default in production
|
|
9
32
|
- 🔑 **Flexible Authorization**: Integrate with your existing auth system
|
|
10
|
-
- 📊 **Modern UI**: Clean, responsive interface with query history
|
|
11
|
-
- 📝 **Audit Logging**: All queries logged with actor information
|
|
12
33
|
- ⚡ **Resource Protection**: Configurable row limits and query timeouts
|
|
13
|
-
-
|
|
14
|
-
-
|
|
15
|
-
|
|
34
|
+
- 📝 **Comprehensive Audit Logging**: All queries logged with actor information and metadata
|
|
35
|
+
- 🔐 **Optional DML Support**: Enable INSERT/UPDATE/DELETE with confirmation dialogs
|
|
36
|
+
|
|
37
|
+
### Query Execution
|
|
38
|
+
- 📊 **EXPLAIN Query Plans**: Analyze query execution plans for performance debugging
|
|
39
|
+
- ✅ **Smart Validation**: SQL validation with keyword blocking and statement isolation
|
|
40
|
+
- 🎯 **Accurate Results**: Proper row counts for both SELECT and DML operations
|
|
41
|
+
- ⏱️ **Query Timeout**: Configurable timeout to prevent long-running queries
|
|
42
|
+
|
|
43
|
+
### User Interface
|
|
44
|
+
- 📊 **Modern UI**: Clean, responsive interface with real-time updates
|
|
45
|
+
- 🗂️ **Schema Explorer**: Browse tables, columns, types with quick actions
|
|
46
|
+
- 💾 **Query Management**: Save, organize, import/export queries (client-side)
|
|
47
|
+
- 📜 **Query History**: Client-side history stored in browser localStorage
|
|
48
|
+
- 🎨 **Tabbed Navigation**: Switch between History, Schema, and Saved Queries seamlessly
|
|
49
|
+
- 🔍 **Quick Actions**: Generate queries from schema, copy names, insert WHERE clauses
|
|
50
|
+
- ⚡ **Hotwire-Powered**: Turbo Frames and Stimulus for smooth, SPA-like experience
|
|
51
|
+
- 🎨 **Zero Build Step**: CDN-hosted dependencies, no asset compilation needed
|
|
52
|
+
|
|
53
|
+
## Screenshots
|
|
54
|
+
|
|
55
|
+
### Query Execution with Results
|
|
56
|
+

|
|
57
|
+
*Execute SQL queries with real-time results, execution time, and row counts displayed in a clean, scrollable table*
|
|
58
|
+
|
|
59
|
+
### Schema Explorer
|
|
60
|
+

|
|
61
|
+
*Browse database tables, columns with data types, nullable status, and quick-action buttons (Insert, WHERE, Copy Table Name)*
|
|
62
|
+
|
|
63
|
+
### DML Operations with Safety Features
|
|
64
|
+

|
|
65
|
+
*DML operations show "Data Modified" banner, accurate "Rows Affected" count, and permanent change confirmation. A browser confirmation dialog appears before execution (not shown - browser native UI).*
|
|
66
|
+
|
|
67
|
+
### Query History
|
|
68
|
+

|
|
69
|
+
*Access recent queries with timestamps - click any query to load it into the editor instantly*
|
|
70
|
+
|
|
71
|
+
### Saved Queries Management
|
|
72
|
+

|
|
73
|
+
*Save important queries with names and tags, then load, export, or import them with one click*
|
|
16
74
|
|
|
17
75
|
## Security Features
|
|
18
76
|
|
|
@@ -20,12 +78,13 @@ QueryConsole implements multiple layers of security:
|
|
|
20
78
|
|
|
21
79
|
1. **Environment Gating**: Only enabled in configured environments (development by default)
|
|
22
80
|
2. **Authorization Hook**: Requires explicit authorization configuration
|
|
23
|
-
3. **
|
|
24
|
-
4. **
|
|
25
|
-
5. **
|
|
26
|
-
6. **
|
|
27
|
-
7. **
|
|
28
|
-
8. **
|
|
81
|
+
3. **Read-Only by Default**: Only SELECT and WITH (CTE) queries allowed by default
|
|
82
|
+
4. **Optional DML with Safeguards**: INSERT/UPDATE/DELETE available when explicitly enabled, with mandatory user confirmation dialogs
|
|
83
|
+
5. **Keyword Blocking**: Always blocks DDL operations (DROP, ALTER, CREATE, TRUNCATE, etc.)
|
|
84
|
+
6. **Statement Isolation**: Prevents multiple statement execution
|
|
85
|
+
7. **Row Limiting**: Automatic result limiting to prevent resource exhaustion
|
|
86
|
+
8. **Query Timeout**: Configurable timeout to prevent long-running queries
|
|
87
|
+
9. **Comprehensive Audit Trail**: All queries logged with actor, query type, and execution metadata
|
|
29
88
|
|
|
30
89
|
## Installation
|
|
31
90
|
|
|
@@ -70,6 +129,17 @@ QueryConsole.configure do |config|
|
|
|
70
129
|
# Optional: Adjust limits
|
|
71
130
|
# config.max_rows = 1000
|
|
72
131
|
# config.timeout_ms = 5000
|
|
132
|
+
|
|
133
|
+
# Advanced Features
|
|
134
|
+
# EXPLAIN feature (default: enabled)
|
|
135
|
+
# config.enable_explain = true
|
|
136
|
+
# config.enable_explain_analyze = false # Disabled by default for safety
|
|
137
|
+
|
|
138
|
+
# Schema Explorer (default: enabled)
|
|
139
|
+
# config.schema_explorer = true
|
|
140
|
+
# config.schema_cache_seconds = 60
|
|
141
|
+
# config.schema_table_denylist = ["schema_migrations", "ar_internal_metadata"]
|
|
142
|
+
# config.schema_allowlist = [] # Optional: whitelist specific tables
|
|
73
143
|
end
|
|
74
144
|
```
|
|
75
145
|
|
|
@@ -110,6 +180,93 @@ config.authorize = ->(_controller) { true }
|
|
|
110
180
|
| `timeout_ms` | `3000` | Query timeout in milliseconds |
|
|
111
181
|
| `forbidden_keywords` | See code | SQL keywords that are blocked |
|
|
112
182
|
| `allowed_starts_with` | `["select", "with"]` | Allowed query starting keywords |
|
|
183
|
+
| `enable_dml` | `false` | Enable DML queries (INSERT, UPDATE, DELETE) |
|
|
184
|
+
| `enable_explain` | `true` | Enable EXPLAIN query plans |
|
|
185
|
+
| `enable_explain_analyze` | `false` | Enable EXPLAIN ANALYZE (use with caution) |
|
|
186
|
+
| `schema_explorer` | `true` | Enable schema browser |
|
|
187
|
+
| `schema_cache_seconds` | `60` | Schema cache duration in seconds |
|
|
188
|
+
|
|
189
|
+
### DML (Data Manipulation Language) Support
|
|
190
|
+
|
|
191
|
+
By default, Query Console is **read-only**. To enable DML operations (INSERT, UPDATE, DELETE):
|
|
192
|
+
|
|
193
|
+
```ruby
|
|
194
|
+
QueryConsole.configure do |config|
|
|
195
|
+
config.enable_dml = true
|
|
196
|
+
|
|
197
|
+
# Recommended: Restrict to specific environments
|
|
198
|
+
config.enabled_environments = ["development", "staging"]
|
|
199
|
+
end
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
#### Important Security Notes
|
|
203
|
+
|
|
204
|
+
- **DML is disabled by default** for safety
|
|
205
|
+
- When enabled, INSERT, UPDATE, DELETE, and MERGE queries are permitted
|
|
206
|
+
- All DML operations are logged with actor information and query type
|
|
207
|
+
- No transaction support - queries auto-commit immediately
|
|
208
|
+
- Consider additional application-level authorization for production use
|
|
209
|
+
|
|
210
|
+
#### What's Still Blocked
|
|
211
|
+
|
|
212
|
+
Even with DML enabled, these operations remain **forbidden**:
|
|
213
|
+
- `DROP`, `ALTER`, `CREATE` (schema changes)
|
|
214
|
+
- `TRUNCATE` (bulk deletion)
|
|
215
|
+
- `GRANT`, `REVOKE` (permission changes)
|
|
216
|
+
- `EXECUTE`, `EXEC` (stored procedures)
|
|
217
|
+
- `TRANSACTION`, `COMMIT`, `ROLLBACK` (manual transaction control)
|
|
218
|
+
- System procedures (`sp_`, `xp_`)
|
|
219
|
+
|
|
220
|
+
#### UI Behavior with DML
|
|
221
|
+
|
|
222
|
+
When DML is enabled and a DML query is detected:
|
|
223
|
+
- **Before execution**: A confirmation dialog appears with a clear warning about permanent data modifications
|
|
224
|
+
- User must explicitly confirm to proceed (can click "Cancel" to abort)
|
|
225
|
+
- **After execution**: An informational banner shows: "ℹ️ Data Modified: This query has modified the database"
|
|
226
|
+
- **Rows Affected** count is displayed (e.g., "3 row(s) affected") showing how many rows were inserted/updated/deleted
|
|
227
|
+
- The security banner reflects DML status
|
|
228
|
+
- All changes are permanent and logged
|
|
229
|
+
|
|
230
|
+
#### Database Support
|
|
231
|
+
|
|
232
|
+
DML operations work on all supported databases:
|
|
233
|
+
- **SQLite**: INSERT, UPDATE, DELETE
|
|
234
|
+
- **PostgreSQL**: INSERT, UPDATE, DELETE, MERGE (via INSERT ... ON CONFLICT)
|
|
235
|
+
- **MySQL**: INSERT, UPDATE, DELETE, REPLACE
|
|
236
|
+
|
|
237
|
+
#### Enhanced Audit Logging
|
|
238
|
+
|
|
239
|
+
DML queries are logged with additional metadata:
|
|
240
|
+
|
|
241
|
+
```ruby
|
|
242
|
+
{
|
|
243
|
+
component: "query_console",
|
|
244
|
+
actor: "user@example.com",
|
|
245
|
+
sql: "UPDATE users SET active = true WHERE id = 123",
|
|
246
|
+
duration_ms: 12.5,
|
|
247
|
+
rows: 1,
|
|
248
|
+
status: "ok",
|
|
249
|
+
query_type: "UPDATE", # NEW: Query type classification
|
|
250
|
+
is_dml: true # NEW: DML flag
|
|
251
|
+
}
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
#### Example DML Queries
|
|
255
|
+
|
|
256
|
+
```sql
|
|
257
|
+
-- Insert a new record
|
|
258
|
+
INSERT INTO users (name, email) VALUES ('John Doe', 'john@example.com');
|
|
259
|
+
|
|
260
|
+
-- Update existing records
|
|
261
|
+
UPDATE users SET active = true WHERE id = 123;
|
|
262
|
+
|
|
263
|
+
-- Delete specific records
|
|
264
|
+
DELETE FROM sessions WHERE expires_at < NOW();
|
|
265
|
+
|
|
266
|
+
-- PostgreSQL upsert
|
|
267
|
+
INSERT INTO settings (key, value) VALUES ('theme', 'dark')
|
|
268
|
+
ON CONFLICT (key) DO UPDATE SET value = 'dark';
|
|
269
|
+
```
|
|
113
270
|
|
|
114
271
|
## Mounting
|
|
115
272
|
|
|
@@ -147,14 +304,17 @@ Then visit: `http://localhost:3000/query_console`
|
|
|
147
304
|
- `WITH active_users AS (SELECT * FROM users WHERE active = true) SELECT * FROM active_users`
|
|
148
305
|
- Queries with JOINs, ORDER BY, GROUP BY, etc.
|
|
149
306
|
|
|
150
|
-
❌ **Blocked
|
|
151
|
-
- `UPDATE users SET name = 'test'`
|
|
152
|
-
- `DELETE FROM users`
|
|
153
|
-
- `INSERT INTO users VALUES (...)`
|
|
154
|
-
- `DROP TABLE users`
|
|
155
|
-
- `
|
|
307
|
+
❌ **Blocked** (by default):
|
|
308
|
+
- `UPDATE users SET name = 'test'` (unless `enable_dml = true`)
|
|
309
|
+
- `DELETE FROM users` (unless `enable_dml = true`)
|
|
310
|
+
- `INSERT INTO users VALUES (...)` (unless `enable_dml = true`)
|
|
311
|
+
- `DROP TABLE users` (always blocked)
|
|
312
|
+
- `TRUNCATE TABLE users` (always blocked)
|
|
313
|
+
- `SELECT * FROM users; DELETE FROM users` (multiple statements always blocked)
|
|
156
314
|
- Any query containing forbidden keywords
|
|
157
315
|
|
|
316
|
+
**Note**: With `config.enable_dml = true`, INSERT, UPDATE, DELETE, and MERGE queries become allowed.
|
|
317
|
+
|
|
158
318
|
## Example Queries
|
|
159
319
|
|
|
160
320
|
```sql
|
|
@@ -371,12 +531,28 @@ Created by [Johnson Gnanasekar](https://github.com/JohnsonGnanasekar)
|
|
|
371
531
|
|
|
372
532
|
## Changelog
|
|
373
533
|
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
-
|
|
380
|
-
-
|
|
381
|
-
-
|
|
382
|
-
- Audit
|
|
534
|
+
See [CHANGELOG.md](CHANGELOG.md) for detailed version history.
|
|
535
|
+
|
|
536
|
+
### Recent Updates
|
|
537
|
+
|
|
538
|
+
#### Latest (DML Support)
|
|
539
|
+
- ✨ **Optional DML Support**: INSERT/UPDATE/DELETE with mandatory confirmation dialogs
|
|
540
|
+
- 🎯 **Accurate Row Counts**: Proper affected rows tracking for DML operations
|
|
541
|
+
- 🔒 **Enhanced Security**: Pre-execution confirmation with detailed warnings
|
|
542
|
+
- 📝 **Enhanced Audit Logging**: Query type classification and DML flags
|
|
543
|
+
- 🗃️ **Multi-Database Support**: SQLite, PostgreSQL, MySQL compatibility
|
|
544
|
+
|
|
545
|
+
#### v0.2.0 (January 2026)
|
|
546
|
+
- 📊 **EXPLAIN Plans**: Query execution plan analysis
|
|
547
|
+
- 🗂️ **Schema Explorer**: Interactive table/column browser with quick actions
|
|
548
|
+
- 💾 **Saved Queries**: Client-side query management with import/export
|
|
549
|
+
- 🎨 **Modern UI**: Tabbed navigation and collapsible sections
|
|
550
|
+
- 🔍 **Quick Actions**: Generate queries from schema explorer
|
|
551
|
+
|
|
552
|
+
#### v0.1.0 (Initial Release)
|
|
553
|
+
- 🔒 Read-only query console with security enforcement
|
|
554
|
+
- 🚦 Environment gating and authorization hooks
|
|
555
|
+
- ✅ SQL validation and row limiting
|
|
556
|
+
- ⏱️ Query timeout protection
|
|
557
|
+
- 📜 Client-side history with localStorage
|
|
558
|
+
- ✅ Comprehensive test suite and audit logging
|
|
@@ -15,7 +15,8 @@ module QueryConsole
|
|
|
15
15
|
config = QueryConsole.configuration
|
|
16
16
|
|
|
17
17
|
unless config.enabled_environments.map(&:to_s).include?(Rails.env.to_s)
|
|
18
|
-
|
|
18
|
+
render plain: "Not Found", status: :not_found
|
|
19
|
+
return false
|
|
19
20
|
end
|
|
20
21
|
end
|
|
21
22
|
|
|
@@ -25,13 +26,15 @@ module QueryConsole
|
|
|
25
26
|
# Default deny if no authorize hook is configured
|
|
26
27
|
if config.authorize.nil?
|
|
27
28
|
Rails.logger.warn("[QueryConsole] Access denied: No authorization hook configured")
|
|
28
|
-
|
|
29
|
+
render plain: "Not Found", status: :not_found
|
|
30
|
+
return false
|
|
29
31
|
end
|
|
30
32
|
|
|
31
33
|
# Call the authorization hook
|
|
32
34
|
unless config.authorize.call(self)
|
|
33
35
|
Rails.logger.warn("[QueryConsole] Access denied by authorization hook")
|
|
34
|
-
|
|
36
|
+
render plain: "Not Found", status: :not_found
|
|
37
|
+
return false
|
|
35
38
|
end
|
|
36
39
|
end
|
|
37
40
|
end
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
module QueryConsole
|
|
2
|
+
class ExplainController < ApplicationController
|
|
3
|
+
skip_forgery_protection only: [:create] # Allow Turbo Frame POST requests
|
|
4
|
+
|
|
5
|
+
def create
|
|
6
|
+
sql = params[:sql]
|
|
7
|
+
|
|
8
|
+
if sql.blank?
|
|
9
|
+
@result = ExplainRunner::ExplainResult.new(error: "Query cannot be empty")
|
|
10
|
+
respond_to do |format|
|
|
11
|
+
format.turbo_stream do
|
|
12
|
+
render turbo_stream: turbo_stream.replace(
|
|
13
|
+
"explain-results",
|
|
14
|
+
partial: "query_console/explain/results",
|
|
15
|
+
locals: { result: @result }
|
|
16
|
+
)
|
|
17
|
+
end
|
|
18
|
+
format.html { render "explain/_results", layout: false, locals: { result: @result } }
|
|
19
|
+
end
|
|
20
|
+
return
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
# Execute the EXPLAIN
|
|
24
|
+
runner = ExplainRunner.new(sql)
|
|
25
|
+
@result = runner.execute
|
|
26
|
+
|
|
27
|
+
# Log the EXPLAIN execution
|
|
28
|
+
AuditLogger.log_query(
|
|
29
|
+
sql: "EXPLAIN: #{sql}",
|
|
30
|
+
result: @result,
|
|
31
|
+
controller: self
|
|
32
|
+
)
|
|
33
|
+
|
|
34
|
+
# Respond with Turbo Stream or HTML
|
|
35
|
+
respond_to do |format|
|
|
36
|
+
format.turbo_stream do
|
|
37
|
+
render turbo_stream: turbo_stream.replace(
|
|
38
|
+
"explain-results",
|
|
39
|
+
partial: "query_console/explain/results",
|
|
40
|
+
locals: { result: @result }
|
|
41
|
+
)
|
|
42
|
+
end
|
|
43
|
+
format.html { render "query_console/explain/_results", layout: false, locals: { result: @result } }
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
module QueryConsole
|
|
2
2
|
class QueriesController < ApplicationController
|
|
3
|
+
skip_forgery_protection only: [:run] # Allow Turbo Frame POST requests
|
|
4
|
+
|
|
3
5
|
def new
|
|
4
6
|
# Render the main query editor page
|
|
5
7
|
end
|
|
@@ -19,6 +21,7 @@ module QueryConsole
|
|
|
19
21
|
# Execute the query
|
|
20
22
|
runner = Runner.new(sql)
|
|
21
23
|
@result = runner.execute
|
|
24
|
+
@is_dml = @result.dml?
|
|
22
25
|
|
|
23
26
|
# Log the query execution
|
|
24
27
|
AuditLogger.log_query(
|
|
@@ -33,7 +36,7 @@ module QueryConsole
|
|
|
33
36
|
render turbo_stream: turbo_stream.replace(
|
|
34
37
|
"query-results",
|
|
35
38
|
partial: "results",
|
|
36
|
-
locals: { result: @result }
|
|
39
|
+
locals: { result: @result, is_dml: @is_dml }
|
|
37
40
|
)
|
|
38
41
|
end
|
|
39
42
|
format.html { render :_results, layout: false }
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
module QueryConsole
|
|
2
|
+
class SchemaController < ApplicationController
|
|
3
|
+
def tables
|
|
4
|
+
unless QueryConsole.configuration.schema_explorer
|
|
5
|
+
render json: { error: "Schema explorer is disabled" }, status: :forbidden
|
|
6
|
+
return
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
introspector = SchemaIntrospector.new
|
|
10
|
+
@tables = introspector.tables
|
|
11
|
+
|
|
12
|
+
render json: @tables
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def show
|
|
16
|
+
unless QueryConsole.configuration.schema_explorer
|
|
17
|
+
render json: { error: "Schema explorer is disabled" }, status: :forbidden
|
|
18
|
+
return
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
introspector = SchemaIntrospector.new
|
|
22
|
+
@table = introspector.table_details(params[:name])
|
|
23
|
+
|
|
24
|
+
if @table.nil?
|
|
25
|
+
render json: { error: "Table not found or access denied" }, status: :not_found
|
|
26
|
+
return
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
render json: @table
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|