better_structure_sql 0.1.0 → 0.2.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 +4 -4
- data/CHANGELOG.md +41 -0
- data/README.md +240 -31
- data/lib/better_structure_sql/adapters/base_adapter.rb +18 -0
- data/lib/better_structure_sql/adapters/mysql_adapter.rb +199 -4
- data/lib/better_structure_sql/adapters/postgresql_adapter.rb +321 -37
- data/lib/better_structure_sql/adapters/sqlite_adapter.rb +218 -59
- data/lib/better_structure_sql/configuration.rb +12 -10
- data/lib/better_structure_sql/dumper.rb +230 -102
- data/lib/better_structure_sql/errors.rb +24 -0
- data/lib/better_structure_sql/file_writer.rb +2 -1
- data/lib/better_structure_sql/generators/base.rb +38 -0
- data/lib/better_structure_sql/generators/comment_generator.rb +118 -0
- data/lib/better_structure_sql/generators/domain_generator.rb +2 -1
- data/lib/better_structure_sql/generators/index_generator.rb +3 -1
- data/lib/better_structure_sql/generators/table_generator.rb +45 -20
- data/lib/better_structure_sql/generators/type_generator.rb +5 -3
- data/lib/better_structure_sql/schema_loader.rb +3 -3
- data/lib/better_structure_sql/schema_version.rb +17 -1
- data/lib/better_structure_sql/schema_versions.rb +223 -20
- data/lib/better_structure_sql/store_result.rb +46 -0
- data/lib/better_structure_sql/version.rb +1 -1
- data/lib/better_structure_sql.rb +4 -1
- data/lib/generators/better_structure_sql/templates/README +1 -1
- data/lib/generators/better_structure_sql/templates/migration.rb.erb +2 -0
- data/lib/tasks/better_structure_sql.rake +35 -18
- metadata +4 -2
- data/lib/generators/better_structure_sql/templates/add_metadata_migration.rb.erb +0 -25
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 067320c86a8a8e2064c41dd5ac93acd1d89652213a61f9efed61a2b946c44660
|
|
4
|
+
data.tar.gz: f31e6dc7cb21647d8836f8f81da99097ed1c536db1b0adb7af33cf511ee401d1
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 581f226ac09dd57a6ab5f058615bcd1aba7e5eaca5abb01c62e3431b6c72ec7c9fe47422cf5e1bc8e5a336df4e64de386dbf7841cd4a2f6fafcd76feb50b575f
|
|
7
|
+
data.tar.gz: cd77d7dd9898c14ea6cfad1fa528de9b1cfb83d15d4d98253a9229ac7fb6fe84ad1b884cd9bfda7d815fd3cb87260ba559e3c7f44f33ee14a60661dce2e732cb
|
data/CHANGELOG.md
CHANGED
|
@@ -13,6 +13,47 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
13
13
|
|
|
14
14
|
### Fixed
|
|
15
15
|
|
|
16
|
+
## [0.2.0] - 2025-11-20
|
|
17
|
+
|
|
18
|
+
### Added
|
|
19
|
+
- **Database comments support** - COMMENT ON statements for PostgreSQL and MySQL
|
|
20
|
+
- Comments on tables, columns, indexes, views, functions, and triggers
|
|
21
|
+
- CommentGenerator for generating COMMENT ON SQL statements
|
|
22
|
+
- CommentIntrospector for querying pg_description and information_schema
|
|
23
|
+
- Configurable via `include_comments` option (enabled by default)
|
|
24
|
+
- 10_comments directory in multi-file output with load order after triggers
|
|
25
|
+
- Full test coverage for PostgreSQL and MySQL comment introspection
|
|
26
|
+
- **Hash-based schema version deduplication** - Automatic duplicate detection using MD5 content hashing
|
|
27
|
+
- `content_hash` column (VARCHAR 32) stores MD5 hexdigest of schema content
|
|
28
|
+
- Automatic skip when schema unchanged between storage attempts
|
|
29
|
+
- StoreResult value object for skip/store state communication
|
|
30
|
+
- Filesystem cleanup: delete multi-file directories after ZIP storage
|
|
31
|
+
- Enhanced rake task output showing skip reason or stored confirmation with hash
|
|
32
|
+
- `db:schema:versions` task now displays first 8 characters of content hash
|
|
33
|
+
- Content size and line count automatic tracking
|
|
34
|
+
- Streaming file reads (4MB chunks) for memory-efficient hash calculation
|
|
35
|
+
- Integration with retention management (cleanup only on actual storage)
|
|
36
|
+
- 29 new tests for deduplication workflow (all 355 tests passing)
|
|
37
|
+
|
|
38
|
+
### Changed
|
|
39
|
+
- **BREAKING**: Schema versions table requires `content_hash` column
|
|
40
|
+
- Run `rails generate better_structure_sql:migration` to add column
|
|
41
|
+
- Existing versions backfilled with calculated MD5 hash during migration
|
|
42
|
+
- `SchemaVersions.store_current` now returns `StoreResult` instead of `SchemaVersion`
|
|
43
|
+
- Use `result.stored?` or `result.skipped?` to check operation type
|
|
44
|
+
- Access version via `result.version` when stored
|
|
45
|
+
- `SchemaVersions.store` now requires `content_hash:` parameter
|
|
46
|
+
- `SchemaVersion.latest` changed from scope to class method (returns record, not Relation)
|
|
47
|
+
- Multi-file directories automatically cleaned up after ZIP archive creation
|
|
48
|
+
- Integration apps configured to use multi-file schema dumps by default
|
|
49
|
+
- Migration numbering scheme changed to support comments directory (20 directories)
|
|
50
|
+
|
|
51
|
+
### Fixed
|
|
52
|
+
- MySQL compatibility: Removed IF NOT EXISTS from index and type creation
|
|
53
|
+
- Hash calculation now excludes manifest.json to avoid circular dependencies
|
|
54
|
+
- FileWriter properly maps comments directory to correct load order
|
|
55
|
+
- CodeBlock component supports both code prop and children for flexibility
|
|
56
|
+
|
|
16
57
|
## [0.1.0] - 2025-11-20
|
|
17
58
|
|
|
18
59
|
### Added
|
data/README.md
CHANGED
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
|
|
17
17
|
</div>
|
|
18
18
|
|
|
19
|
-
> **⚠️ Beta Notice**:
|
|
19
|
+
> **⚠️ Beta Notice**: Version 0.2.0 is feature-complete and production-ready for **PostgreSQL**. Multi-database support (MySQL, SQLite) is implemented but considered experimental. APIs are stable but may see minor refinements before v1.0. We welcome feedback and contributions!
|
|
20
20
|
|
|
21
21
|
## ✨ Why BetterStructureSql?
|
|
22
22
|
|
|
@@ -67,7 +67,7 @@ Rails' database dump tools (`pg_dump`, `mysqldump`, etc.) create noisy `structur
|
|
|
67
67
|
| **Materialized Views** | ✅ | ❌ | ❌ |
|
|
68
68
|
| **Functions** | ✅ plpgsql, sql | ✅ Stored procedures | ❌ |
|
|
69
69
|
| **Triggers** | ✅ BEFORE/AFTER/INSTEAD OF | ✅ BEFORE/AFTER | ✅ BEFORE/AFTER |
|
|
70
|
-
| **Partitioned Tables** |
|
|
70
|
+
| **Partitioned Tables** | 🚧 Planned | ❌ | ❌ |
|
|
71
71
|
| **Domains** | ✅ | ❌ | ❌ |
|
|
72
72
|
|
|
73
73
|
### Getting Started by Database
|
|
@@ -95,15 +95,16 @@ Rails' database dump tools (`pg_dump`, `mysqldump`, etc.) create noisy `structur
|
|
|
95
95
|
- Custom types and enums (PostgreSQL, MySQL SET/ENUM)
|
|
96
96
|
|
|
97
97
|
### Multi-File Schema Output (Optional)
|
|
98
|
-
- **Massive schema support** -
|
|
98
|
+
- **Massive schema support** - Designed to handle tens of thousands of database objects
|
|
99
99
|
- **Directory-based output** - Split schema across organized, numbered directories
|
|
100
|
-
- **Smart chunking** - 500 LOC per file with intelligent overflow handling
|
|
100
|
+
- **Smart chunking** - 500 LOC per file (configurable) with intelligent overflow handling
|
|
101
101
|
- **Better git diffs** - See only changed files, not entire schema
|
|
102
102
|
- **ZIP downloads** - Download complete directory structure as archive
|
|
103
|
-
- **Easy navigation** - Find tables quickly in `
|
|
103
|
+
- **Easy navigation** - Find tables quickly in `05_tables/`, triggers in `09_triggers/`, etc.
|
|
104
104
|
|
|
105
105
|
### Schema Versioning (Optional)
|
|
106
106
|
- Store schema versions in database with metadata
|
|
107
|
+
- **Hash-based deduplication** - Automatically skip storing when schema unchanged
|
|
107
108
|
- Track database type and version, format type (SQL/Ruby), creation timestamp
|
|
108
109
|
- ZIP archive storage for multi-file schemas
|
|
109
110
|
- Configurable retention policy (keep last N versions)
|
|
@@ -141,9 +142,11 @@ Rails' database dump tools (`pg_dump`, `mysqldump`, etc.) create noisy `structur
|
|
|
141
142
|
```ruby
|
|
142
143
|
# Gemfile
|
|
143
144
|
gem 'better_structure_sql'
|
|
144
|
-
gem 'pg' # or 'mysql2' or 'sqlite3'
|
|
145
|
+
gem 'pg' # For PostgreSQL (or 'mysql2' for MySQL, or 'sqlite3' for SQLite)
|
|
145
146
|
```
|
|
146
147
|
|
|
148
|
+
**Database adapter is auto-detected** from your `ActiveRecord::Base.connection.adapter_name`. No manual configuration needed!
|
|
149
|
+
|
|
147
150
|
```bash
|
|
148
151
|
bundle install
|
|
149
152
|
rails generate better_structure_sql:install
|
|
@@ -152,6 +155,128 @@ rails db:schema:dump_better
|
|
|
152
155
|
|
|
153
156
|
**🎉 Your `db/structure.sql` is now clean and maintainable!**
|
|
154
157
|
|
|
158
|
+
## 📦 Schema Versioning with Deduplication
|
|
159
|
+
|
|
160
|
+
BetterStructureSql automatically tracks schema evolution by storing versions in your database. Hash-based deduplication ensures only meaningful schema changes are recorded.
|
|
161
|
+
|
|
162
|
+
### How It Works
|
|
163
|
+
|
|
164
|
+
When you run `rails db:schema:store`, the gem:
|
|
165
|
+
|
|
166
|
+
1. **Reads** your current schema files (single or multi-file)
|
|
167
|
+
2. **Calculates** MD5 hash of the complete schema content
|
|
168
|
+
3. **Compares** with the most recent stored version's hash
|
|
169
|
+
4. **Skips storage** if hash matches (no changes detected) ✨
|
|
170
|
+
5. **Creates new version** if hash differs (schema changed)
|
|
171
|
+
|
|
172
|
+
### Quick Example
|
|
173
|
+
|
|
174
|
+
```bash
|
|
175
|
+
# After migrations, dump and store schema
|
|
176
|
+
rails db:migrate
|
|
177
|
+
rails db:schema:dump_better
|
|
178
|
+
rails db:schema:store
|
|
179
|
+
|
|
180
|
+
# First run (no previous version)
|
|
181
|
+
# =>
|
|
182
|
+
# Stored schema version #1
|
|
183
|
+
# Format: sql
|
|
184
|
+
# Mode: single_file
|
|
185
|
+
# PostgreSQL: 15.4
|
|
186
|
+
# Size: 45.2 KB
|
|
187
|
+
# Hash: a3f5c9d2e8b1f4a6c7e9d3f1b5a8c2e4
|
|
188
|
+
# Total versions: 1
|
|
189
|
+
|
|
190
|
+
# Second run (no schema changes)
|
|
191
|
+
# =>
|
|
192
|
+
# No schema changes detected
|
|
193
|
+
# Current schema matches version #1
|
|
194
|
+
# Hash: a3f5c9d2e8b1f4a6c7e9d3f1b5a8c2e4
|
|
195
|
+
# No new version stored
|
|
196
|
+
# Total versions: 1
|
|
197
|
+
|
|
198
|
+
# After adding a table
|
|
199
|
+
rails db:migrate # Adds new table
|
|
200
|
+
rails db:schema:dump_better
|
|
201
|
+
rails db:schema:store
|
|
202
|
+
|
|
203
|
+
# =>
|
|
204
|
+
# Stored schema version #2
|
|
205
|
+
# Format: sql
|
|
206
|
+
# Mode: single_file
|
|
207
|
+
# PostgreSQL: 15.4
|
|
208
|
+
# Size: 48.7 KB
|
|
209
|
+
# Hash: b7e2d1c4f9a6c3e5d8b2f1a4c9e7d3b6
|
|
210
|
+
# Total versions: 2
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
### Production Workflow
|
|
214
|
+
|
|
215
|
+
Perfect for deployment automation:
|
|
216
|
+
|
|
217
|
+
```ruby
|
|
218
|
+
# config/deploy.rb or GitHub Actions
|
|
219
|
+
namespace :deploy do
|
|
220
|
+
task :update_schema do
|
|
221
|
+
# Run migrations (may be zero)
|
|
222
|
+
# Rails automatically dumps schema after migrations
|
|
223
|
+
execute :rake, 'db:migrate'
|
|
224
|
+
|
|
225
|
+
# Store schema version only if changed (automatic deduplication)
|
|
226
|
+
execute :rake, 'db:schema:store'
|
|
227
|
+
end
|
|
228
|
+
end
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
**Benefits in Production:**
|
|
232
|
+
- ✅ Deploys without migrations don't create duplicate versions
|
|
233
|
+
- ✅ Developers see clean schema evolution timeline
|
|
234
|
+
- ✅ Storage efficient (no duplicate content)
|
|
235
|
+
- ✅ Clear audit trail of actual schema changes
|
|
236
|
+
|
|
237
|
+
### Viewing Stored Versions
|
|
238
|
+
|
|
239
|
+
```bash
|
|
240
|
+
# List all versions with hashes
|
|
241
|
+
rails db:schema:versions
|
|
242
|
+
|
|
243
|
+
Schema Versions (3 total)
|
|
244
|
+
|
|
245
|
+
ID | Format | Mode | Files | PostgreSQL | Hash | Created | Size
|
|
246
|
+
-----|--------|-------------|-------|------------|----------|---------------------|-------
|
|
247
|
+
3 | sql | multi_file | 47 | 15.4 | a3f5c9d2 | 2025-01-20 14:30:15 | 125 KB
|
|
248
|
+
2 | sql | single_file | - | 15.4 | b7e2d1c4 | 2025-01-19 10:15:42 | 98 KB
|
|
249
|
+
1 | sql | single_file | - | 15.3 | c9f8a3b2 | 2025-01-18 08:45:30 | 85 KB
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
### Configuration
|
|
253
|
+
|
|
254
|
+
```ruby
|
|
255
|
+
# config/initializers/better_structure_sql.rb
|
|
256
|
+
BetterStructureSql.configure do |config|
|
|
257
|
+
# Enable schema versioning
|
|
258
|
+
config.enable_schema_versions = true
|
|
259
|
+
|
|
260
|
+
# Retain 10 most recent unique versions (0 = unlimited)
|
|
261
|
+
config.schema_versions_limit = 10
|
|
262
|
+
end
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
### Web UI Access
|
|
266
|
+
|
|
267
|
+
Developers can view stored schema versions via the web UI without database access:
|
|
268
|
+
|
|
269
|
+
```ruby
|
|
270
|
+
# config/routes.rb
|
|
271
|
+
authenticate :user, ->(user) { user.admin? } do
|
|
272
|
+
mount BetterStructureSql::Engine, at: '/schema_versions'
|
|
273
|
+
end
|
|
274
|
+
```
|
|
275
|
+
|
|
276
|
+
Navigate to `/schema_versions` to browse versions, view formatted schema, and download raw SQL files.
|
|
277
|
+
|
|
278
|
+
📖 See [Schema Versioning Documentation](docs/schema_versions.md) for complete details.
|
|
279
|
+
|
|
155
280
|
## Docker Development Environment 🐳
|
|
156
281
|
|
|
157
282
|
Get started with a fully configured development environment in seconds:
|
|
@@ -284,14 +409,21 @@ BetterStructureSql.configure do |config|
|
|
|
284
409
|
config.enable_schema_versions = true
|
|
285
410
|
config.schema_versions_limit = 10 # Keep last 10 versions (0 = unlimited)
|
|
286
411
|
|
|
287
|
-
# Customize output
|
|
412
|
+
# Customize output (feature toggles)
|
|
288
413
|
config.include_extensions = true
|
|
289
414
|
config.include_functions = true
|
|
290
415
|
config.include_triggers = true
|
|
291
416
|
config.include_views = true
|
|
292
|
-
|
|
293
|
-
#
|
|
417
|
+
config.include_materialized_views = true # PostgreSQL only
|
|
418
|
+
config.include_domains = true # PostgreSQL only
|
|
419
|
+
config.include_sequences = true # PostgreSQL only
|
|
420
|
+
config.include_custom_types = true # PostgreSQL ENUM, MySQL ENUM/SET
|
|
421
|
+
# config.include_rules = false # Not yet implemented
|
|
422
|
+
# config.include_comments = false # Not yet implemented
|
|
423
|
+
|
|
424
|
+
# Search path and schema filtering
|
|
294
425
|
config.search_path = '"$user", public'
|
|
426
|
+
config.schemas = ['public'] # Which schemas to dump
|
|
295
427
|
end
|
|
296
428
|
```
|
|
297
429
|
|
|
@@ -314,11 +446,20 @@ BetterStructureSql.configure do |config|
|
|
|
314
446
|
config.enable_schema_versions = true
|
|
315
447
|
config.schema_versions_limit = 10
|
|
316
448
|
|
|
317
|
-
# Feature toggles
|
|
449
|
+
# Feature toggles (same as single-file mode)
|
|
318
450
|
config.include_extensions = true
|
|
319
451
|
config.include_functions = true
|
|
320
452
|
config.include_triggers = true
|
|
321
453
|
config.include_views = true
|
|
454
|
+
config.include_materialized_views = true
|
|
455
|
+
config.include_domains = true
|
|
456
|
+
config.include_sequences = true
|
|
457
|
+
config.include_custom_types = true
|
|
458
|
+
|
|
459
|
+
# Formatting options
|
|
460
|
+
config.indent_size = 2 # SQL indentation (default: 2)
|
|
461
|
+
config.add_section_spacing = true # Add blank lines between sections
|
|
462
|
+
config.sort_tables = true # Sort tables alphabetically
|
|
322
463
|
end
|
|
323
464
|
```
|
|
324
465
|
|
|
@@ -330,34 +471,67 @@ When using `config.output_path = 'db/schema'`, your schema is organized by type
|
|
|
330
471
|
db/schema/
|
|
331
472
|
├── _header.sql # SET statements and search path
|
|
332
473
|
├── _manifest.json # Metadata and load order
|
|
333
|
-
├──
|
|
474
|
+
├── 01_extensions/
|
|
334
475
|
│ └── 000001.sql
|
|
335
|
-
├──
|
|
476
|
+
├── 02_types/
|
|
336
477
|
│ └── 000001.sql
|
|
337
|
-
├──
|
|
478
|
+
├── 03_functions/
|
|
338
479
|
│ └── 000001.sql
|
|
339
|
-
├──
|
|
480
|
+
├── 04_sequences/
|
|
481
|
+
│ └── 000001.sql
|
|
482
|
+
├── 05_tables/
|
|
340
483
|
│ ├── 000001.sql # ~500 lines per file
|
|
341
484
|
│ ├── 000002.sql
|
|
342
485
|
│ └── 000003.sql
|
|
343
|
-
├──
|
|
486
|
+
├── 06_indexes/
|
|
487
|
+
│ └── 000001.sql
|
|
488
|
+
├── 07_foreign_keys/
|
|
344
489
|
│ └── 000001.sql
|
|
345
|
-
├──
|
|
490
|
+
├── 08_views/
|
|
346
491
|
│ └── 000001.sql
|
|
347
|
-
├──
|
|
492
|
+
├── 09_triggers/
|
|
348
493
|
│ └── 000001.sql
|
|
349
|
-
├──
|
|
494
|
+
├── 10_comments/
|
|
350
495
|
│ └── 000001.sql
|
|
351
|
-
└──
|
|
496
|
+
└── 20_migrations/
|
|
352
497
|
└── 000001.sql
|
|
353
498
|
```
|
|
354
499
|
|
|
355
500
|
**Benefits for Large Schemas**:
|
|
356
501
|
- ✅ Memory efficient - incremental file writing
|
|
357
502
|
- ✅ Git friendly - only changed files in diffs
|
|
358
|
-
- ✅ Easy navigation - find specific tables
|
|
503
|
+
- ✅ Easy navigation - find specific tables in `05_tables/`, triggers in `09_triggers/`, etc.
|
|
359
504
|
- ✅ ZIP downloads - complete directory as single archive
|
|
360
505
|
- ✅ Scalable - handles 50,000+ database objects
|
|
506
|
+
- ✅ AI-friendly - 500-line chunks work better with LLM context windows
|
|
507
|
+
|
|
508
|
+
**Manifest File (_manifest.json)**:
|
|
509
|
+
|
|
510
|
+
The manifest tracks metadata and provides load order information:
|
|
511
|
+
|
|
512
|
+
```json
|
|
513
|
+
{
|
|
514
|
+
"version": "1.0",
|
|
515
|
+
"total_files": 11,
|
|
516
|
+
"total_lines": 2345,
|
|
517
|
+
"max_lines_per_file": 500,
|
|
518
|
+
"directories": {
|
|
519
|
+
"01_extensions": { "files": 1, "lines": 3 },
|
|
520
|
+
"02_types": { "files": 1, "lines": 13 },
|
|
521
|
+
"03_functions": { "files": 1, "lines": 332 },
|
|
522
|
+
"04_sequences": { "files": 1, "lines": 289 },
|
|
523
|
+
"05_tables": { "files": 2, "lines": 979 },
|
|
524
|
+
"06_indexes": { "files": 1, "lines": 397 },
|
|
525
|
+
"07_foreign_keys": { "files": 1, "lines": 67 },
|
|
526
|
+
"08_views": { "files": 1, "lines": 217 },
|
|
527
|
+
"09_triggers": { "files": 1, "lines": 35 },
|
|
528
|
+
"10_comments": { "files": 1, "lines": 9 },
|
|
529
|
+
"20_migrations": { "files": 1, "lines": 13 }
|
|
530
|
+
}
|
|
531
|
+
}
|
|
532
|
+
```
|
|
533
|
+
|
|
534
|
+
This example shows a real schema with 2,345 lines split across 11 files. The `05_tables` directory has 2 files because the tables exceed the 500-line limit.
|
|
361
535
|
|
|
362
536
|
## 📝 Usage & Rake Tasks
|
|
363
537
|
|
|
@@ -394,15 +568,17 @@ rails db:schema:versions
|
|
|
394
568
|
|
|
395
569
|
Output example:
|
|
396
570
|
```
|
|
397
|
-
Total versions:
|
|
571
|
+
Total versions: 3
|
|
398
572
|
|
|
399
573
|
ID Format Mode Files PostgreSQL Created Size
|
|
400
574
|
-----------------------------------------------------------------------------------------------
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
575
|
+
3 sql multi_file 12 15.3 2025-01-15 10:30:22 56.42 KB
|
|
576
|
+
2 sql single_file 1 15.3 2025-01-14 15:20:10 45.21 KB
|
|
577
|
+
1 sql single_file 1 15.2 2025-01-13 09:45:33 44.03 KB
|
|
404
578
|
```
|
|
405
579
|
|
|
580
|
+
The multi-file mode example shows 12 files across 10 directories (extensions, types, functions, sequences, tables, indexes, foreign_keys, views, triggers, migrations) stored as a ZIP archive.
|
|
581
|
+
|
|
406
582
|
**Restore from Version**
|
|
407
583
|
```bash
|
|
408
584
|
# Restore database from a specific version
|
|
@@ -436,10 +612,12 @@ end
|
|
|
436
612
|
```
|
|
437
613
|
|
|
438
614
|
Access at `http://localhost:3000/schema_versions` to:
|
|
439
|
-
- View list of
|
|
440
|
-
- Browse formatted schema content with syntax highlighting
|
|
441
|
-
- Download raw SQL/Ruby schema files
|
|
615
|
+
- View list of up to 100 most recent schema versions (pagination-ready)
|
|
616
|
+
- Browse formatted schema content with syntax highlighting (for files <200KB)
|
|
617
|
+
- Download raw SQL/Ruby schema files as text
|
|
442
618
|
- Download ZIP archives for multi-file schemas
|
|
619
|
+
- View manifest metadata for multi-file schemas
|
|
620
|
+
- Stream large files efficiently (>2MB) without memory issues
|
|
443
621
|
- Compare database versions and formats
|
|
444
622
|
|
|
445
623
|
**Authentication Examples**:
|
|
@@ -503,10 +681,13 @@ fi
|
|
|
503
681
|
|-----------|---------|-------|
|
|
504
682
|
| **Ruby** | 2.7+ | Tested up to Ruby 3.4.7 |
|
|
505
683
|
| **Rails** | 7.0+ | Works with Rails 8.1.1+ |
|
|
506
|
-
| **
|
|
507
|
-
|
|
|
508
|
-
| `
|
|
509
|
-
| `
|
|
684
|
+
| **rubyzip** | ≥ 2.0.0 | Required for ZIP archive support |
|
|
685
|
+
| **Database Adapter** | | |
|
|
686
|
+
| `pg` | ≥ 1.0 | **Required dependency**. Works with PostgreSQL 12+ |
|
|
687
|
+
| `mysql2` | ≥ 0.5 | Optional. For MySQL 8.0+ (experimental) |
|
|
688
|
+
| `sqlite3` | ≥ 1.4 | Optional. For SQLite 3.35+ (experimental) |
|
|
689
|
+
|
|
690
|
+
**Note**: The gem currently requires the `pg` gem as a dependency. Multi-database support (MySQL, SQLite) is implemented but requires manual gem installation. Future versions may make database adapters optional.
|
|
510
691
|
|
|
511
692
|
## Migration Guides
|
|
512
693
|
|
|
@@ -533,6 +714,34 @@ BetterStructureSql supports **both** `schema.rb` and `structure.sql` formats, al
|
|
|
533
714
|
|
|
534
715
|
---
|
|
535
716
|
|
|
717
|
+
## 📊 Project Stats
|
|
718
|
+
|
|
719
|
+
**Codebase Metrics** (as of v0.1.0):
|
|
720
|
+
- **47 Ruby files** in `lib/` (~5,296 total lines)
|
|
721
|
+
- **25 test files** in `spec/` (~3,022 lines)
|
|
722
|
+
- **8 adapter files** (PostgreSQL, MySQL, SQLite, Registry, Configs)
|
|
723
|
+
- **13 SQL generators** (Tables, Indexes, Functions, Triggers, Views, etc.)
|
|
724
|
+
- **9 introspection modules** (Extensions, Types, Tables, Indexes, Foreign Keys, etc.)
|
|
725
|
+
- **3 integration apps** (PostgreSQL, MySQL, SQLite) with Docker support
|
|
726
|
+
- **React documentation site** deployed to GitHub Pages
|
|
727
|
+
|
|
728
|
+
**Test Coverage**: Comprehensive RSpec test suite with unit and integration tests across all major components.
|
|
729
|
+
|
|
730
|
+
**Real-World Example**: The integration app generates a multi-file schema with:
|
|
731
|
+
- 11 SQL files across 10 directories
|
|
732
|
+
- 2,345 total lines of SQL
|
|
733
|
+
- Complete PostgreSQL feature coverage (extensions, types, functions, triggers, materialized views)
|
|
734
|
+
|
|
735
|
+
**Production Status**:
|
|
736
|
+
- ✅ **PostgreSQL**: Fully implemented and tested (primary focus)
|
|
737
|
+
- ✅ **Multi-file output**: Complete with ZIP storage and streaming
|
|
738
|
+
- ✅ **Schema versioning**: Full CRUD with web UI
|
|
739
|
+
- ✅ **Rails integration**: Drop-in replacement for default tasks
|
|
740
|
+
- 🧪 **MySQL**: Adapter implemented, integration app available (experimental)
|
|
741
|
+
- 🧪 **SQLite**: Adapter implemented, basic testing (experimental)
|
|
742
|
+
|
|
743
|
+
---
|
|
744
|
+
|
|
536
745
|
## 🤝 Contributing
|
|
537
746
|
|
|
538
747
|
We welcome contributions! Bug reports and pull requests are welcome on [GitHub](https://github.com/sebyx07/better_structure_sql).
|
|
@@ -112,6 +112,17 @@ module BetterStructureSql
|
|
|
112
112
|
raise NotImplementedError, "#{self.class} must implement #fetch_triggers"
|
|
113
113
|
end
|
|
114
114
|
|
|
115
|
+
# Fetch comments on database objects
|
|
116
|
+
#
|
|
117
|
+
# @param connection [ActiveRecord::ConnectionAdapters::AbstractAdapter] Database connection
|
|
118
|
+
# @return [Hash] Hash with object types as keys (:tables, :columns, :indexes, etc.)
|
|
119
|
+
# Each value is a hash mapping object identifier to comment text
|
|
120
|
+
# Example: { tables: { 'users' => 'User accounts', ... }, columns: { 'users.email' => 'Email address', ... } }
|
|
121
|
+
# @raise [NotImplementedError] If not implemented by subclass
|
|
122
|
+
def fetch_comments(connection)
|
|
123
|
+
raise NotImplementedError, "#{self.class} must implement #fetch_comments"
|
|
124
|
+
end
|
|
125
|
+
|
|
115
126
|
# Capability methods - indicate feature support
|
|
116
127
|
|
|
117
128
|
# Indicates whether this database supports extensions (like PostgreSQL extensions)
|
|
@@ -163,6 +174,13 @@ module BetterStructureSql
|
|
|
163
174
|
false
|
|
164
175
|
end
|
|
165
176
|
|
|
177
|
+
# Indicates whether this database supports comments on database objects
|
|
178
|
+
#
|
|
179
|
+
# @return [Boolean] True if comments are supported, false otherwise
|
|
180
|
+
def supports_comments?
|
|
181
|
+
false
|
|
182
|
+
end
|
|
183
|
+
|
|
166
184
|
# Version detection
|
|
167
185
|
|
|
168
186
|
# Detect the database version
|