pg_sql_triggers 1.0.1 → 1.1.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.
Files changed (37) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +83 -0
  3. data/COVERAGE.md +58 -0
  4. data/Goal.md +180 -138
  5. data/README.md +6 -0
  6. data/app/controllers/pg_sql_triggers/dashboard_controller.rb +4 -1
  7. data/app/controllers/pg_sql_triggers/generator_controller.rb +67 -5
  8. data/app/models/pg_sql_triggers/trigger_registry.rb +73 -10
  9. data/app/views/pg_sql_triggers/generator/new.html.erb +18 -0
  10. data/app/views/pg_sql_triggers/generator/preview.html.erb +233 -13
  11. data/app/views/pg_sql_triggers/shared/_confirmation_modal.html.erb +32 -0
  12. data/config/initializers/pg_sql_triggers.rb +69 -0
  13. data/db/migrate/20251222000001_create_pg_sql_triggers_tables.rb +2 -0
  14. data/db/migrate/20251229071916_add_timing_to_pg_sql_triggers_registry.rb +8 -0
  15. data/docs/api-reference.md +22 -4
  16. data/docs/usage-guide.md +73 -0
  17. data/docs/web-ui.md +14 -0
  18. data/lib/generators/pg_sql_triggers/templates/create_pg_sql_triggers_tables.rb +2 -0
  19. data/lib/generators/pg_sql_triggers/templates/initializer.rb +8 -0
  20. data/lib/pg_sql_triggers/drift/db_queries.rb +116 -0
  21. data/lib/pg_sql_triggers/drift/detector.rb +187 -0
  22. data/lib/pg_sql_triggers/drift/reporter.rb +179 -0
  23. data/lib/pg_sql_triggers/drift.rb +14 -11
  24. data/lib/pg_sql_triggers/dsl/trigger_definition.rb +15 -1
  25. data/lib/pg_sql_triggers/generator/form.rb +3 -1
  26. data/lib/pg_sql_triggers/generator/service.rb +81 -25
  27. data/lib/pg_sql_triggers/migrator/pre_apply_comparator.rb +344 -0
  28. data/lib/pg_sql_triggers/migrator/pre_apply_diff_reporter.rb +143 -0
  29. data/lib/pg_sql_triggers/migrator/safety_validator.rb +258 -0
  30. data/lib/pg_sql_triggers/migrator.rb +58 -0
  31. data/lib/pg_sql_triggers/registry/manager.rb +96 -9
  32. data/lib/pg_sql_triggers/testing/function_tester.rb +66 -24
  33. data/lib/pg_sql_triggers/testing/syntax_validator.rb +24 -1
  34. data/lib/pg_sql_triggers/version.rb +1 -1
  35. data/lib/pg_sql_triggers.rb +12 -0
  36. data/scripts/generate_coverage_report.rb +129 -0
  37. metadata +12 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3d6bd35c06d2081333452a1417048b31fc8399c67722f0d14c1a59e73abfaf7c
4
- data.tar.gz: 1cdee375336d7249e3587fb5368663d03eb8c9e0c4f7384802d1140932a03aa1
3
+ metadata.gz: e72011f4407b6d60e5002202eedccf7e34c03075faebdf24301f74521e817904
4
+ data.tar.gz: b9df169c3fecf2a3b5bb34bc6a8fd7c3cad9707ded4297276a9d73af3c57871c
5
5
  SHA512:
6
- metadata.gz: a8669ed888d53bb3557767ecaa238a24d2ada5c890ac969da51d9c73a70b0aaebde2f7e7ca27c1cceeb66bcccbe540f4b3a6ed8195c12ca0278996cef07e8cac
7
- data.tar.gz: afacafb601e656ede4dd244022e6a3ecb492c49099add20c3198d11d0e93f82ab8f513f2e66549a9b110d573b7c3cb3797c6506a9db710289028d3984b61a99a
6
+ metadata.gz: 7868c6518becf693b0d34e28c18423220e8fb29ef6a5bf331123e6f0bec08735d1de582f49064b3140106f1906f1d4430fb569dcea1953c2204e5355552b4e89
7
+ data.tar.gz: c6d7c92d4588482fe526d7e747d646e5abfcd542d094942348186719bf9b5240d85752e5a3485abe4d72fd21037d013bd155da8e8ddd388d5c36d4dfe88d5fd8
data/CHANGELOG.md CHANGED
@@ -5,6 +5,89 @@ All notable changes to this project will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [Unreleased]
9
+
10
+ ## [1.1.0] - 2025-12-29
11
+
12
+ ### Added
13
+ - Trigger timing support (BEFORE/AFTER) in generator and registry
14
+ - Added `timing` field to generator form with "before" and "after" options
15
+ - Added `timing` column to `pg_sql_triggers_registry` table (defaults to "before")
16
+ - Timing is now included in DSL generation, migration generation, and registry storage
17
+ - Timing is included in checksum calculation for drift detection
18
+ - Preview page now displays trigger timing and condition information
19
+ - Comprehensive test coverage for both "before" and "after" timing scenarios
20
+ - Enhanced preview page UI for better testing and editing
21
+ - Timing and condition fields are now editable directly in the preview page
22
+ - Real-time DSL preview updates when timing or condition changes
23
+ - Improved visual layout with clear distinction between editable and read-only fields
24
+ - Better user experience for testing different timing and condition combinations before generating files
25
+ - JavaScript-powered dynamic preview that updates automatically as you type
26
+
27
+ ### Performance
28
+ - Optimized `Registry::Manager.register` to prevent N+1 queries when loading multiple trigger files
29
+ - Added request-level caching for registry lookups to avoid redundant database queries
30
+ - Added `preload_triggers` method for batch loading triggers into cache
31
+ - Cache is automatically populated during registration and can be manually cleared
32
+ - Significantly reduces database queries when multiple trigger files are loaded during request processing
33
+
34
+ ### Added
35
+ - Safety validation for trigger migrations (prevents unsafe DROP + CREATE operations)
36
+ - `Migrator::SafetyValidator` class that detects unsafe DROP + CREATE patterns in migrations
37
+ - Blocks migrations that would drop existing database objects (triggers/functions) and recreate them without validation
38
+ - Only flags as unsafe if the object actually exists in the database
39
+ - Configuration option `allow_unsafe_migrations` (default: false) for global override
40
+ - Environment variable `ALLOW_UNSAFE_MIGRATIONS=true` for per-migration override
41
+ - Provides clear error messages explaining unsafe operations and how to proceed if override is needed
42
+ - New error class `PgSqlTriggers::UnsafeMigrationError` for safety validation failures
43
+ - Pre-apply comparison for trigger migrations (diff expected vs actual)
44
+ - `Migrator::PreApplyComparator` class that extracts expected SQL from migrations and compares with database state
45
+ - `Migrator::PreApplyDiffReporter` class for formatting comparison results into human-readable diff reports
46
+ - Automatic pre-apply comparison before executing migrations to show what will change
47
+ - Comparison reports show new objects (will be created), modified objects (will be overwritten), and unchanged objects
48
+ - Detailed diff output for functions and triggers including expected vs actual SQL
49
+ - Summary output in verbose mode or when called from console
50
+ - Non-blocking: shows differences but doesn't prevent migration execution (warns only)
51
+ - Complete drift detection system implementation
52
+ - `Drift::Detector` class with all 6 drift states (IN_SYNC, DRIFTED, DISABLED, DROPPED, UNKNOWN, MANUAL_OVERRIDE)
53
+ - `Drift::Reporter` class for formatting drift reports and summaries
54
+ - `Drift::DbQueries` helper module for PostgreSQL system catalog queries
55
+ - Dashboard integration: drift count now calculated from actual detection results
56
+ - Console API: `PgSqlTriggers::Registry.diff` now fully functional with drift detection
57
+ - Comprehensive test coverage for all drift detection components (>90% coverage)
58
+
59
+ ### Added
60
+ - Comprehensive test coverage for generator components (>90% coverage)
61
+ - Added extensive test cases for `Generator::Service` covering all edge cases:
62
+ - Function name quoting (special characters vs simple patterns)
63
+ - Multiple environments handling
64
+ - Condition escaping with quotes
65
+ - Single and multiple event combinations
66
+ - All event types (insert, update, delete, truncate)
67
+ - Blank events and environments filtering
68
+ - Migration number generation edge cases (no existing migrations, timestamp collisions, multiple migrations)
69
+ - Standalone gem context (without Rails)
70
+ - Error handling and logging
71
+ - Checksum calculation with nil values
72
+ - Added test coverage for generator classes:
73
+ - `TriggerMigrationGenerator` - migration number generation, file naming, template usage
74
+ - `MigrationGenerator` (Trigger::Generators) - migration number generation, file naming, class name generation
75
+ - `InstallGenerator` - initializer creation, migration copying, route mounting, readme display
76
+
77
+ ### Fixed
78
+ - Fixed form data persistence when navigating between preview and edit pages
79
+ - Form data (including edits to condition, timing, and function_body) is now preserved when clicking "Back to Edit" from preview page
80
+ - Implemented session-based storage to maintain form state across page navigation
81
+ - All form fields are restored when returning to edit page: trigger_name, table_name, function_name, function_body, events, version, enabled, timing, condition, and environments
82
+ - Session data is automatically cleared after successful trigger creation
83
+ - Comprehensive test coverage added for session persistence functionality
84
+ - Fixed checksum calculation consistency across all code paths (field-concatenation algorithm)
85
+ - Fixed `Registry::Manager.diff` method to use drift detection
86
+ - Fixed dashboard controller to display actual drifted trigger count
87
+ - Fixed SQL parameter handling in `DbQueries.execute_query` method
88
+ - Fixed generator service to properly handle function body whitespace stripping
89
+ - Fixed generator service to handle standalone gem context (without Rails.root)
90
+
8
91
  ## [1.0.1] - 2025-12-28
9
92
 
10
93
  - Production kill switch for safety (blocks destructive operations in production by default)
data/COVERAGE.md ADDED
@@ -0,0 +1,58 @@
1
+ # Code Coverage Report
2
+
3
+ **Total Coverage: 95.4%**
4
+
5
+ Covered: 1678 / 1759 lines
6
+
7
+ ---
8
+
9
+ ## File Coverage
10
+
11
+ | File | Coverage | Covered Lines | Missed Lines | Total Lines |
12
+ |------|----------|---------------|--------------|-------------|
13
+ | `lib/pg_sql_triggers/testing/dry_run.rb` | 100.0% ✅ | 24 | 0 | 24 |
14
+ | `lib/pg_sql_triggers/testing.rb` | 100.0% ✅ | 6 | 0 | 6 |
15
+ | `lib/pg_sql_triggers/registry/validator.rb` | 100.0% ✅ | 5 | 0 | 5 |
16
+ | `lib/pg_sql_triggers/registry.rb` | 100.0% ✅ | 18 | 0 | 18 |
17
+ | `lib/pg_sql_triggers/permissions/checker.rb` | 100.0% ✅ | 15 | 0 | 15 |
18
+ | `lib/pg_sql_triggers/permissions.rb` | 100.0% ✅ | 11 | 0 | 11 |
19
+ | `lib/pg_sql_triggers/migrator/safety_validator.rb` | 100.0% ✅ | 110 | 0 | 110 |
20
+ | `lib/pg_sql_triggers/migrator/pre_apply_diff_reporter.rb` | 100.0% ✅ | 75 | 0 | 75 |
21
+ | `lib/pg_sql_triggers/migrator/pre_apply_comparator.rb` | 100.0% ✅ | 123 | 0 | 123 |
22
+ | `lib/pg_sql_triggers/migration.rb` | 100.0% ✅ | 4 | 0 | 4 |
23
+ | `lib/generators/trigger/migration_generator.rb` | 100.0% ✅ | 27 | 0 | 27 |
24
+ | `lib/generators/pg_sql_triggers/install_generator.rb` | 100.0% ✅ | 18 | 0 | 18 |
25
+ | `lib/pg_sql_triggers/generator/service.rb` | 100.0% ✅ | 93 | 0 | 93 |
26
+ | `lib/pg_sql_triggers/generator/form.rb` | 100.0% ✅ | 36 | 0 | 36 |
27
+ | `lib/pg_sql_triggers/generator.rb` | 100.0% ✅ | 4 | 0 | 4 |
28
+ | `lib/pg_sql_triggers/dsl/trigger_definition.rb` | 100.0% ✅ | 37 | 0 | 37 |
29
+ | `lib/pg_sql_triggers.rb` | 100.0% ✅ | 45 | 0 | 45 |
30
+ | `config/initializers/pg_sql_triggers.rb` | 100.0% ✅ | 10 | 0 | 10 |
31
+ | `app/models/pg_sql_triggers/application_record.rb` | 100.0% ✅ | 3 | 0 | 3 |
32
+ | `app/controllers/pg_sql_triggers/application_controller.rb` | 100.0% ✅ | 28 | 0 | 28 |
33
+ | `app/controllers/pg_sql_triggers/dashboard_controller.rb` | 100.0% ✅ | 25 | 0 | 25 |
34
+ | `app/controllers/pg_sql_triggers/migrations_controller.rb` | 100.0% ✅ | 63 | 0 | 63 |
35
+ | `lib/pg_sql_triggers/dsl.rb` | 100.0% ✅ | 9 | 0 | 9 |
36
+ | `lib/pg_sql_triggers/drift.rb` | 100.0% ✅ | 13 | 0 | 13 |
37
+ | `lib/pg_sql_triggers/drift/db_queries.rb` | 100.0% ✅ | 24 | 0 | 24 |
38
+ | `lib/pg_sql_triggers/drift/detector.rb` | 98.48% ✅ | 65 | 1 | 66 |
39
+ | `lib/pg_sql_triggers/registry/manager.rb` | 96.36% ✅ | 53 | 2 | 55 |
40
+ | `lib/generators/pg_sql_triggers/trigger_migration_generator.rb` | 96.3% ✅ | 26 | 1 | 27 |
41
+ | `lib/pg_sql_triggers/sql/kill_switch.rb` | 96.0% ✅ | 96 | 4 | 100 |
42
+ | `lib/pg_sql_triggers/migrator.rb` | 95.42% ✅ | 125 | 6 | 131 |
43
+ | `app/controllers/pg_sql_triggers/generator_controller.rb` | 94.68% ✅ | 89 | 5 | 94 |
44
+ | `app/controllers/pg_sql_triggers/tables_controller.rb` | 94.44% ✅ | 17 | 1 | 18 |
45
+ | `lib/pg_sql_triggers/drift/reporter.rb` | 94.12% ✅ | 96 | 6 | 102 |
46
+ | `lib/pg_sql_triggers/engine.rb` | 92.86% ✅ | 13 | 1 | 14 |
47
+ | `lib/pg_sql_triggers/database_introspection.rb` | 92.86% ✅ | 65 | 5 | 70 |
48
+ | `lib/pg_sql_triggers/testing/safe_executor.rb` | 91.89% ✅ | 34 | 3 | 37 |
49
+ | `lib/pg_sql_triggers/sql.rb` | 90.91% ✅ | 10 | 1 | 11 |
50
+ | `lib/pg_sql_triggers/testing/syntax_validator.rb` | 89.66% ⚠️ | 52 | 6 | 58 |
51
+ | `app/models/pg_sql_triggers/trigger_registry.rb` | 84.62% ⚠️ | 55 | 10 | 65 |
52
+ | `lib/pg_sql_triggers/testing/function_tester.rb` | 79.1% ⚠️ | 53 | 14 | 67 |
53
+ | `config/routes.rb` | 16.67% ❌ | 3 | 15 | 18 |
54
+
55
+ ---
56
+
57
+ *Report generated automatically from SimpleCov results*
58
+ *To regenerate: Run `bundle exec rspec` and then `ruby scripts/generate_coverage_report.rb`*