standard_ledger 0.5.1 → 0.7.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.
@@ -1,60 +0,0 @@
1
- namespace :standard_ledger do
2
- # PostgreSQL-only: queries `pg_trigger` directly. The only mode that
3
- # registers a trigger today is `:trigger`, and the only adopter is
4
- # nutripod-web (Postgres). SQLite has no comparable per-statement
5
- # trigger introspection that makes sense for this gem's contract — if
6
- # a non-Postgres host adopts `:trigger` mode in the future, they'll
7
- # need to extend this task with a connection-adapter dispatch. The
8
- # task is loud about its Postgres assumption: a `pg_trigger` query
9
- # against a non-Postgres connection will raise, which is preferable
10
- # to silently passing.
11
- desc "Verify that every :trigger projection's trigger exists in the database (Postgres-only)"
12
- task doctor: :environment do
13
- require "standard_ledger"
14
-
15
- # Discover entry classes by walking ActiveRecord descendants for
16
- # ones that include `StandardLedger::Projector` and have at least
17
- # one `:trigger` projection registered. The host's eager loading
18
- # (Rails default in production / when explicitly invoked in dev)
19
- # ensures all entry classes are loaded before this iterates.
20
- entry_classes = ActiveRecord::Base.descendants.select { |klass|
21
- klass.respond_to?(:standard_ledger_projections) &&
22
- klass.standard_ledger_projections.any? { |d| d.mode == :trigger }
23
- }
24
-
25
- missing = []
26
- entry_classes.each do |klass|
27
- klass.standard_ledger_projections_for(:trigger).each do |definition|
28
- # `pg_trigger.tgname` is the trigger's name as known to Postgres,
29
- # but trigger names are scoped per-table — two tables can each
30
- # have a trigger called e.g. `update_counts`. Join `pg_trigger`
31
- # to `pg_class` and filter by the entry class's table name so the
32
- # doctor reports presence on the *correct* table, not "anywhere
33
- # in the schema". Use `klass.connection` (rather than
34
- # `ActiveRecord::Base.connection`) so multi-DB setups query the
35
- # connection that owns the entry class's table.
36
- result = klass.connection.exec_query(
37
- "SELECT 1 FROM pg_trigger t " \
38
- "JOIN pg_class c ON c.oid = t.tgrelid " \
39
- "WHERE t.tgname = $1 AND c.relname = $2 " \
40
- "LIMIT 1",
41
- "standard_ledger:doctor",
42
- [ definition.trigger_name, klass.table_name ]
43
- )
44
- if result.rows.empty?
45
- missing << " #{klass.name}##{definition.target_association}: trigger #{definition.trigger_name.inspect} not found"
46
- end
47
- end
48
- end
49
-
50
- if missing.empty?
51
- puts "All :trigger projections have their triggers present."
52
- else
53
- warn "Missing triggers detected:"
54
- missing.each { |line| warn line }
55
- warn ""
56
- warn "Run the migration that creates the trigger, or check that the trigger name in `projects_onto` matches the actual trigger name in the schema."
57
- exit 1
58
- end
59
- end
60
- end