sqlite_dashboard 1.0.0 → 1.0.2

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: 869bae55994f425455d02e3798d598d4d346a4d6bfa90f11898e0b4a1c36320f
4
- data.tar.gz: 030f4f2c91332a9ef73e65eb5a06be94f38c7063c65cf17b538680b1c72b155f
3
+ metadata.gz: 9b1922be7426fe6320e16ad206a78512a2d4c70ab16b5193def19470ce5db413
4
+ data.tar.gz: 2d32502f6e3eb01188b9bc9091bc80c3e5dc1bb2bbc10de717c9c3c74c4730e7
5
5
  SHA512:
6
- metadata.gz: a067bb74a549a6a34c9779ec167a7670c47505b76af208dfd7e2be02564d68bb9e0edda43ddab7c1b16e9ac43d13080d1f62045fee71d1cf1667fa79f00fd382
7
- data.tar.gz: 2bfb94bd33407f7f22503934b532fa93f263f40f40ca5ae2dbb1acfcd25e2e1e6b0dc6bc2aa84448e64fa38498b4bdf5bef03b6e8938f72fc3b12ca11849383e
6
+ metadata.gz: 50368ebf1eaff776214f1c2602a1372b4d33d3ea660674a001d982091383562fc0eb0084ff46dfa11bbe7c5e61c83f215b96f678c22817ae827a8304abb3bd81
7
+ data.tar.gz: 4342fdd6a7043c89053ef5b004ca1726d1a4380d0f0cd93a81eff40a6fe347d2e7cbecd45cee1f056a04bddd248dc5a06d771a39e3f751dd88663917cf6749a4
data/README.md CHANGED
@@ -5,18 +5,28 @@
5
5
 
6
6
  A beautiful, feature-rich SQLite database browser and query interface for Rails applications. Mount it as an engine in your Rails app to inspect and query your SQLite databases through a clean, modern interface.
7
7
 
8
- ![SQLite Dashboard Screenshot](https://via.placeholder.com/800x400)
8
+ ## Screenshots
9
+
10
+ ### Database Selection
11
+ ![Database Dashboard](screenshots/dashboard.png)
12
+
13
+ ### Query Interface & Results
14
+ ![Query Details](screenshots/details.png)
9
15
 
10
16
  ## Features
11
17
 
12
- - 🎨 **Modern UI** with Bootstrap 5 and responsive design
18
+ - 🎨 **Modern UI** with dark sidebar theme and responsive design
13
19
  - 🔍 **Multiple Database Support** - Configure and switch between multiple SQLite databases
20
+ - 🗄️ **Auto-Detection** - Automatically discovers SQLite databases from `config/database.yml`
14
21
  - ✨ **SQL Syntax Highlighting** - CodeMirror editor with SQL syntax highlighting and autocomplete
15
- - 📊 **Interactive Query Results** - Paginated, sortable results with horizontal scrolling
22
+ - 📊 **Interactive Query Results** - Client-side pagination with customizable rows per page
23
+ - 💾 **Export Functionality** - Export results to CSV or JSON with custom formatting options
16
24
  - 🎯 **Quick Table Browse** - Click any table name to instantly query it
17
25
  - ⚡ **Fast & Lightweight** - No build tools required, works with Rails importmap
18
- - 🔐 **Safe for Development** - Read-only access to prevent accidental data modification
26
+ - 🔒 **Read-Only Mode** - Prevents accidental data modification (configurable)
27
+ - 🚫 **Security Controls** - DROP and ALTER operations always forbidden
19
28
  - ⌨️ **Keyboard Shortcuts** - `Ctrl/Cmd + Enter` to execute queries
29
+ - 📱 **Fully Responsive** - Works beautifully on desktop and mobile devices
20
30
 
21
31
  ## Installation
22
32
 
@@ -29,10 +39,32 @@ gem 'sqlite_dashboard'
29
39
  And then execute:
30
40
 
31
41
  ```bash
32
- $ bundle install
42
+ bundle install
43
+ ```
44
+
45
+ ## Quick Start (Recommended)
46
+
47
+ The easiest way to install SQLite Dashboard is using the built-in generator:
48
+
49
+ ```bash
50
+ rails generate sqlite_dashboard:install
51
+ ```
52
+
53
+ This will:
54
+ - ✅ Create an initializer at `config/initializers/sqlite_dashboard.rb`
55
+ - ✅ Mount the engine in your routes at `/sqlite_dashboard`
56
+ - ✅ Auto-detect your SQLite databases
57
+ - ✅ Display helpful setup instructions
58
+
59
+ Then start your Rails server and visit:
60
+
33
61
  ```
62
+ http://localhost:3000/sqlite_dashboard
63
+ ```
64
+
65
+ ## Manual Configuration
34
66
 
35
- ## Configuration
67
+ If you prefer to set up manually:
36
68
 
37
69
  ### Step 1: Mount the Engine
38
70
 
@@ -52,19 +84,23 @@ Create an initializer `config/initializers/sqlite_dashboard.rb`:
52
84
 
53
85
  ```ruby
54
86
  SqliteDashboard.configure do |config|
87
+ # Option 1: Explicitly define databases
55
88
  config.db_files = [
56
89
  {
57
90
  name: "Development",
58
- path: Rails.root.join("storage", "development.sqlite3").to_s
91
+ path: Rails.root.join("db", "development.sqlite3").to_s
59
92
  },
60
93
  {
61
94
  name: "Test",
62
- path: Rails.root.join("storage", "test.sqlite3").to_s
95
+ path: Rails.root.join("db", "test.sqlite3").to_s
63
96
  }
64
97
  ]
65
98
 
66
- # Or add databases dynamically:
67
- # config.add_database("Custom DB", "/path/to/database.sqlite3")
99
+ # Option 2: Or leave empty to auto-detect from database.yml
100
+ # (Automatically loads SQLite databases for current environment)
101
+
102
+ # Security: Control write operations (default: false)
103
+ config.allow_dml = false # Read-only mode
68
104
  end
69
105
  ```
70
106
 
@@ -95,6 +131,21 @@ http://localhost:3000/sqlite_dashboard
95
131
  - Adjust rows per page (10, 25, 50, 100, 500)
96
132
  - Navigate through pages with First, Previous, Next, Last buttons
97
133
  - See current position (e.g., "Showing 1 to 25 of 150 rows")
134
+ - Client-side pagination for instant navigation
135
+
136
+ ### Export Query Results
137
+
138
+ **CSV Export:**
139
+ - Choose separator: comma, semicolon, tab, or pipe
140
+ - Option to include/exclude headers as first row
141
+ - Exports all query results (not just paginated view)
142
+
143
+ **JSON Export:**
144
+ - Two format options:
145
+ - Array of objects: `[{"col1": "val1", "col2": "val2"}, ...]`
146
+ - Object with columns & rows: `{"columns": [...], "rows": [...]}`
147
+ - Pretty print option for formatted/readable JSON
148
+ - Timestamped filenames for easy organization
98
149
 
99
150
  ### Keyboard Shortcuts
100
151
 
@@ -106,7 +157,26 @@ http://localhost:3000/sqlite_dashboard
106
157
 
107
158
  ⚠️ **Warning**: This gem provides direct SQL access to your databases.
108
159
 
109
- ### Recommended Security Measures:
160
+ ### Built-in Security Features
161
+
162
+ 1. **Read-Only Mode by Default** - DML operations are disabled by default:
163
+
164
+ ```ruby
165
+ # config/initializers/sqlite_dashboard.rb
166
+ SqliteDashboard.configure do |config|
167
+ config.allow_dml = false # Default: prevents INSERT, UPDATE, DELETE, CREATE, TRUNCATE
168
+ end
169
+ ```
170
+
171
+ 2. **Always Forbidden Operations** - DROP and ALTER are always blocked, even when `allow_dml = true`:
172
+
173
+ ```ruby
174
+ # These are NEVER allowed for safety:
175
+ # - DROP TABLE/INDEX/VIEW
176
+ # - ALTER TABLE
177
+ ```
178
+
179
+ ### Recommended Security Measures
110
180
 
111
181
  1. **Development Only** - Only mount in development environment:
112
182
 
@@ -117,7 +187,7 @@ if Rails.env.development?
117
187
  end
118
188
  ```
119
189
 
120
- 2. **Authentication** - Add authentication with Devise or similar:
190
+ 2. **Authentication with Devise** - Add authentication for production use:
121
191
 
122
192
  ```ruby
123
193
  # config/routes.rb
@@ -126,25 +196,23 @@ authenticate :user, ->(user) { user.admin? } do
126
196
  end
127
197
  ```
128
198
 
129
- 3. **Basic Auth** - Quick protection with HTTP Basic Auth:
199
+ 3. **HTTP Basic Auth** - Quick protection with HTTP Basic Auth:
130
200
 
131
201
  ```ruby
132
- # config/initializers/sqlite_dashboard.rb
202
+ # config/initializers/sqlite_dashboard.rb or config/application.rb
133
203
  SqliteDashboard::Engine.middleware.use Rack::Auth::Basic do |username, password|
134
- username == ENV['DASHBOARD_USER'] && password == ENV['DASHBOARD_PASS']
204
+ ActiveSupport::SecurityUtils.secure_compare(username, ENV['DASHBOARD_USER']) &
205
+ ActiveSupport::SecurityUtils.secure_compare(password, ENV['DASHBOARD_PASS'])
135
206
  end
136
207
  ```
137
208
 
138
- 4. **Read-Only Mode** - Configure read-only database connections:
209
+ 4. **Enable DML Only When Needed** - Only allow write operations in trusted environments:
139
210
 
140
211
  ```ruby
141
- config.db_files = [
142
- {
143
- name: "Production (Read-Only)",
144
- path: Rails.root.join("db/production.sqlite3").to_s,
145
- readonly: true # Coming in v2.0
146
- }
147
- ]
212
+ SqliteDashboard.configure do |config|
213
+ # Use environment variables or Rails.env checks
214
+ config.allow_dml = Rails.env.development? || Rails.env.test?
215
+ end
148
216
  ```
149
217
 
150
218
  ## Customization
@@ -329,13 +397,24 @@ Bug reports and pull requests are welcome on GitHub at https://github.com/yourus
329
397
 
330
398
  ## Roadmap
331
399
 
332
- - [x] **v1.1** - Export results to CSV/JSON
333
- - [ ] **v1.2** - Query history and saved queries
334
- - [ ] **v1.3** - Database schema visualization
335
- - [ ] **v2.0** - Read-only mode enforcement
336
- - [ ] **v2.1** - Dark mode theme
337
- - [ ] **v2.2** - Multi-query execution
338
- - [ ] **v2.3** - Query performance analytics
400
+ ### Completed
401
+ - [x] **v1.0** - Core SQLite browser with modern UI
402
+ - [x] **v1.0** - SQL syntax highlighting with CodeMirror
403
+ - [x] **v1.0** - Client-side pagination
404
+ - [x] **v1.0** - Auto-detection from database.yml
405
+ - [x] **v1.0** - CSV & JSON export with options
406
+ - [x] **v1.0** - Read-only mode with DML controls
407
+ - [x] **v1.0** - Dark sidebar theme
408
+ - [x] **v1.0** - Rails generator for easy installation
409
+
410
+ ### Planned 🚀
411
+ - [ ] **v1.1** - Query history and saved queries
412
+ - [ ] **v1.2** - Database schema visualization
413
+ - [ ] **v1.3** - Table relationships diagram
414
+ - [ ] **v1.4** - Query performance analytics
415
+ - [ ] **v2.0** - Multi-query execution
416
+ - [ ] **v2.1** - Full dark mode theme toggle
417
+ - [ ] **v2.2** - SQL query builder UI
339
418
 
340
419
  ## License
341
420
 
@@ -343,7 +422,7 @@ The gem is available as open source under the terms of the [MIT License](https:/
343
422
 
344
423
  ## Credits
345
424
 
346
- Created by [Your Name](https://github.com/yourusername)
425
+ Created by [Giovanni Panasiti](https://github.com/giovapanasiti)
347
426
 
348
427
  Special thanks to:
349
428
  - [CodeMirror](https://codemirror.net/) for the SQL editor
@@ -352,9 +431,7 @@ Special thanks to:
352
431
 
353
432
  ## Support
354
433
 
355
- - 🐛 [Report bugs](https://github.com/yourusername/sqlite_dashboard/issues)
356
- - 💡 [Request features](https://github.com/yourusername/sqlite_dashboard/issues)
357
- - 📧 [Email support](mailto:your.email@example.com)
434
+ - 📧 [Email support](mailto:giova.panasiti@hey.com)
358
435
 
359
436
  ---
360
437
 
@@ -5,15 +5,22 @@ require 'json'
5
5
  module SqliteDashboard
6
6
  class DatabasesController < ApplicationController
7
7
  before_action :set_database, only: [:show, :execute_query, :export_csv, :export_json, :tables, :table_schema]
8
+ before_action :set_saved_query, only: [:destroy_saved_query]
8
9
 
9
10
  def index
10
11
  @databases = SqliteDashboard.configuration.databases
12
+ @saved_queries = SavedQuery.recent.limit(10)
11
13
  end
12
14
 
13
15
  def show
14
16
  @tables = fetch_tables
15
17
  end
16
18
 
19
+ def worksheet
20
+ @databases = SqliteDashboard.configuration.databases
21
+ @saved_queries = SavedQuery.recent.limit(20)
22
+ end
23
+
17
24
  def execute_query
18
25
  @query = params[:query]
19
26
 
@@ -166,8 +173,52 @@ module SqliteDashboard
166
173
  end
167
174
  end
168
175
 
176
+ # Saved Queries actions
177
+ def saved_queries
178
+ @saved_queries = SavedQuery.recent
179
+ database_name = params[:database_name]
180
+ @saved_queries = @saved_queries.for_database(database_name) if database_name.present?
181
+
182
+ render json: @saved_queries
183
+ end
184
+
185
+ def create_saved_query
186
+ @saved_query = SavedQuery.new(saved_query_params)
187
+
188
+ if @saved_query.save
189
+ render json: @saved_query, status: :created
190
+ else
191
+ render json: { error: @saved_query.errors.full_messages.join(", ") }, status: :unprocessable_entity
192
+ end
193
+ end
194
+
195
+ def show_saved_query
196
+ @saved_query = SavedQuery.find(params[:id])
197
+ render json: @saved_query
198
+ rescue ActiveRecord::RecordNotFound
199
+ render json: { error: "Saved query not found" }, status: :not_found
200
+ end
201
+
202
+ def destroy_saved_query
203
+ if @saved_query.destroy
204
+ render json: { message: "Query deleted successfully" }
205
+ else
206
+ render json: { error: "Failed to delete query" }, status: :unprocessable_entity
207
+ end
208
+ end
209
+
169
210
  private
170
211
 
212
+ def set_saved_query
213
+ @saved_query = SavedQuery.find(params[:id])
214
+ rescue ActiveRecord::RecordNotFound
215
+ render json: { error: "Saved query not found" }, status: :not_found
216
+ end
217
+
218
+ def saved_query_params
219
+ params.require(:saved_query).permit(:name, :query, :database_name, :description)
220
+ end
221
+
171
222
  def set_database
172
223
  @database = SqliteDashboard.configuration.databases.find { |db| db[:id] == params[:id].to_i }
173
224
  redirect_to databases_path, alert: "Database not found" unless @database