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