paper_trail_diff 0.13.1 → 0.14.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 +287 -0
- data/QUICKSTART.md +9 -6
- data/README.md +84 -9
- data/docs/architecture.md +32 -9
- data/docs/performance.md +106 -13
- data/docs/reference.md +242 -29
- data/docs/testing.md +34 -11
- data/lib/paper_trail_diff/activity_belongs_to_event_applier.rb +19 -9
- data/lib/paper_trail_diff/activity_collection_event_applier.rb +11 -1
- data/lib/paper_trail_diff/activity_collection_record_updater.rb +16 -2
- data/lib/paper_trail_diff/activity_event_record_resolver.rb +20 -1
- data/lib/paper_trail_diff/activity_event_route_finder.rb +2 -1
- data/lib/paper_trail_diff/activity_event_snapshot_refresher.rb +1 -1
- data/lib/paper_trail_diff/activity_range.rb +14 -2
- data/lib/paper_trail_diff/activity_relationship.rb +12 -0
- data/lib/paper_trail_diff/activity_root_snapshot_refresher.rb +5 -2
- data/lib/paper_trail_diff/activity_target_candidate_loader.rb +131 -0
- data/lib/paper_trail_diff/activity_timeline_builder.rb +30 -24
- data/lib/paper_trail_diff/activity_version_collector.rb +31 -20
- data/lib/paper_trail_diff/association_activity_edge.rb +236 -0
- data/lib/paper_trail_diff/association_activity_selection.rb +197 -0
- data/lib/paper_trail_diff/association_discovery.rb +8 -13
- data/lib/paper_trail_diff/association_traversal.rb +169 -45
- data/lib/paper_trail_diff/batch_safety.rb +23 -15
- data/lib/paper_trail_diff/batched_root_versions.rb +21 -39
- data/lib/paper_trail_diff/comparison_batch.rb +37 -10
- data/lib/paper_trail_diff/deleted_analysis_batch.rb +34 -16
- data/lib/paper_trail_diff/diagnostics.rb +26 -8
- data/lib/paper_trail_diff/direct_record_state_loader.rb +10 -1
- data/lib/paper_trail_diff/errors.rb +2 -1
- data/lib/paper_trail_diff/habtm_transaction_owners.rb +68 -0
- data/lib/paper_trail_diff/historical_association_reifier.rb +32 -2
- data/lib/paper_trail_diff/historical_snapshot_store.rb +6 -9
- data/lib/paper_trail_diff/live_endpoint_batch_loader.rb +35 -2
- data/lib/paper_trail_diff/live_graph_collector.rb +1 -1
- data/lib/paper_trail_diff/paper_trail_adapter.rb +22 -6
- data/lib/paper_trail_diff/preloaded_endpoint_batch_loader.rb +1 -1
- data/lib/paper_trail_diff/prepared_activity_index.rb +110 -36
- data/lib/paper_trail_diff/prepared_edge_loader.rb +29 -45
- data/lib/paper_trail_diff/prepared_history.rb +63 -54
- data/lib/paper_trail_diff/prepared_history_loader.rb +33 -43
- data/lib/paper_trail_diff/prepared_record_index.rb +26 -0
- data/lib/paper_trail_diff/prepared_snapshot_builder.rb +1 -1
- data/lib/paper_trail_diff/prepared_state_association_reader.rb +119 -29
- data/lib/paper_trail_diff/recorded_changes.rb +83 -0
- data/lib/paper_trail_diff/recorded_class.rb +53 -0
- data/lib/paper_trail_diff/scope_condition.rb +331 -0
- data/lib/paper_trail_diff/scope_ranking.rb +196 -0
- data/lib/paper_trail_diff/scoped_analysis_builder.rb +4 -3
- data/lib/paper_trail_diff/scoped_root_selection.rb +93 -43
- data/lib/paper_trail_diff/snapshot_normalizer.rb +10 -3
- data/lib/paper_trail_diff/support.rb +9 -4
- data/lib/paper_trail_diff/time_activity_timeline_builder.rb +0 -1
- data/lib/paper_trail_diff/time_range.rb +9 -12
- data/lib/paper_trail_diff/time_version_range.rb +5 -5
- data/lib/paper_trail_diff/version.rb +1 -1
- data/lib/paper_trail_diff/version_association_candidate_scope.rb +13 -3
- data/lib/paper_trail_diff/version_range.rb +8 -15
- data/lib/paper_trail_diff/version_scope_filter.rb +11 -3
- data/lib/paper_trail_diff.rb +31 -2
- data/sig/generated/paper_trail_diff/activity_belongs_to_event_applier.rbs +10 -2
- data/sig/generated/paper_trail_diff/activity_collection_event_applier.rbs +5 -0
- data/sig/generated/paper_trail_diff/activity_collection_record_updater.rbs +5 -0
- data/sig/generated/paper_trail_diff/activity_event_record_resolver.rbs +7 -0
- data/sig/generated/paper_trail_diff/activity_range.rbs +6 -2
- data/sig/generated/paper_trail_diff/activity_relationship.rbs +3 -0
- data/sig/generated/paper_trail_diff/activity_root_snapshot_refresher.rbs +2 -0
- data/sig/generated/paper_trail_diff/activity_target_candidate_loader.rbs +79 -0
- data/sig/generated/paper_trail_diff/activity_timeline_builder.rbs +11 -5
- data/sig/generated/paper_trail_diff/activity_version_collector.rbs +10 -4
- data/sig/generated/paper_trail_diff/association_activity_edge.rbs +148 -0
- data/sig/generated/paper_trail_diff/association_activity_selection.rbs +112 -0
- data/sig/generated/paper_trail_diff/association_discovery.rbs +3 -5
- data/sig/generated/paper_trail_diff/association_traversal.rbs +84 -9
- data/sig/generated/paper_trail_diff/batch_safety.rbs +10 -4
- data/sig/generated/paper_trail_diff/batched_root_versions.rbs +2 -8
- data/sig/generated/paper_trail_diff/comparison_batch.rbs +22 -4
- data/sig/generated/paper_trail_diff/deleted_analysis_batch.rbs +16 -4
- data/sig/generated/paper_trail_diff/diagnostics.rbs +7 -2
- data/sig/generated/paper_trail_diff/direct_record_state_loader.rbs +6 -0
- data/sig/generated/paper_trail_diff/errors.rbs +2 -1
- data/sig/generated/paper_trail_diff/habtm_transaction_owners.rbs +40 -0
- data/sig/generated/paper_trail_diff/historical_association_reifier.rbs +13 -0
- data/sig/generated/paper_trail_diff/historical_snapshot_store.rbs +3 -2
- data/sig/generated/paper_trail_diff/live_endpoint_batch_loader.rbs +17 -0
- data/sig/generated/paper_trail_diff/paper_trail_adapter.rbs +5 -0
- data/sig/generated/paper_trail_diff/prepared_activity_index.rbs +52 -10
- data/sig/generated/paper_trail_diff/prepared_edge_loader.rbs +4 -12
- data/sig/generated/paper_trail_diff/prepared_history.rbs +33 -22
- data/sig/generated/paper_trail_diff/prepared_history_loader.rbs +15 -13
- data/sig/generated/paper_trail_diff/prepared_record_index.rbs +15 -0
- data/sig/generated/paper_trail_diff/prepared_state_association_reader.rbs +56 -11
- data/sig/generated/paper_trail_diff/recorded_changes.rbs +47 -0
- data/sig/generated/paper_trail_diff/recorded_class.rbs +22 -0
- data/sig/generated/paper_trail_diff/scope_condition.rbs +185 -0
- data/sig/generated/paper_trail_diff/scope_ranking.rbs +117 -0
- data/sig/generated/paper_trail_diff/scoped_analysis_builder.rbs +2 -2
- data/sig/generated/paper_trail_diff/scoped_root_selection.rbs +41 -7
- data/sig/generated/paper_trail_diff/snapshot_normalizer.rbs +6 -0
- data/sig/generated/paper_trail_diff/support.rbs +5 -2
- data/sig/generated/paper_trail_diff/time_range.rbs +4 -0
- data/sig/generated/paper_trail_diff/time_version_range.rbs +4 -4
- data/sig/generated/paper_trail_diff/version_association_candidate_scope.rbs +7 -0
- data/sig/generated/paper_trail_diff/version_range.rbs +4 -2
- data/sig/generated/paper_trail_diff/version_scope_filter.rbs +4 -0
- data/sig/generated/paper_trail_diff.rbs +21 -2
- metadata +20 -4
|
@@ -12,15 +12,42 @@ module PaperTrailDiff
|
|
|
12
12
|
# : (untyped, Array[untyped]) -> Array[untyped]
|
|
13
13
|
def versions: (untyped, Array[untyped]) -> Array[untyped]
|
|
14
14
|
|
|
15
|
+
# Children are found by key across the whole table, so an association to
|
|
16
|
+
# an STI subclass finds the rows of its siblings too. Only a row that was
|
|
17
|
+
# of the class at some point belongs to it, and of that row only the
|
|
18
|
+
# versions it had the class before or after.
|
|
19
|
+
# : (untyped, Array[untyped]) -> Array[untyped]
|
|
20
|
+
def member_ids: (untyped, Array[untyped]) -> Array[untyped]
|
|
21
|
+
|
|
22
|
+
# : (untyped, Array[untyped], ActivityRange) -> Array[untyped]
|
|
23
|
+
def member_versions: (untyped, Array[untyped], ActivityRange) -> Array[untyped]
|
|
24
|
+
|
|
25
|
+
# The versions of a through's join rows that are on its path. Under
|
|
26
|
+
# `source_type:`, a row is on it only while its type column names that
|
|
27
|
+
# class, so only the versions it had that type before or after count. A
|
|
28
|
+
# version saved before the type column existed has no type to read.
|
|
29
|
+
# : (Hash[Symbol, untyped], untyped) -> Array[untyped]
|
|
30
|
+
def join_versions: (Hash[Symbol, untyped], untyped) -> Array[untyped]
|
|
31
|
+
|
|
15
32
|
# : (untyped, Array[untyped], untyped, ActivityRange) -> Array[untyped]
|
|
16
33
|
def child_ids: (untyped, Array[untyped], untyped, ActivityRange) -> Array[untyped]
|
|
17
34
|
|
|
18
|
-
#
|
|
19
|
-
|
|
35
|
+
# The `belongs_to` targets each owner pointed at in the range: at its start
|
|
36
|
+
# and after each change inside it, plus the live row at a current end.
|
|
37
|
+
# : (untyped, Array[untyped], untyped, ActivityRange) -> Array[ActivityTargetCandidateLoader::Row]
|
|
38
|
+
def target_rows: (untyped, Array[untyped], untyped, ActivityRange) -> Array[ActivityTargetCandidateLoader::Row]
|
|
39
|
+
|
|
40
|
+
# : (untyped, untyped) -> bool
|
|
41
|
+
def loaded?: (untyped, untyped) -> bool
|
|
42
|
+
|
|
43
|
+
# PT-AT records HABTM membership once per transaction, under the
|
|
44
|
+
# association's name, so the rows are keyed by transaction id.
|
|
45
|
+
# : (untyped, Array[untyped], untyped) -> Array[untyped]
|
|
46
|
+
def habtm_rows: (untyped, Array[untyped], untyped) -> Array[untyped]
|
|
20
47
|
|
|
21
48
|
private
|
|
22
49
|
|
|
23
|
-
@children: Hash[
|
|
50
|
+
@children: Hash[untyped, untyped]
|
|
24
51
|
|
|
25
52
|
@nodes: Hash[String, Array[untyped]]
|
|
26
53
|
|
|
@@ -30,7 +57,12 @@ module PaperTrailDiff
|
|
|
30
57
|
|
|
31
58
|
@roots: Hash[Array[String], Array[untyped]]
|
|
32
59
|
|
|
33
|
-
@rows: Hash[
|
|
60
|
+
@rows: Hash[untyped, Hash[String, Array[untyped]]]
|
|
61
|
+
|
|
62
|
+
@targets: Hash[untyped, untyped]
|
|
63
|
+
|
|
64
|
+
# : (untyped, Array[untyped]) -> bool
|
|
65
|
+
def member_class?: (untyped, Array[untyped]) -> bool
|
|
34
66
|
|
|
35
67
|
# : (untyped, Array[untyped], untyped, ActivityRange) -> Array[untyped]
|
|
36
68
|
def historical_ids: (untyped, Array[untyped], untyped, ActivityRange) -> Array[untyped]
|
|
@@ -41,16 +73,26 @@ module PaperTrailDiff
|
|
|
41
73
|
# : (untyped, untyped) -> untyped
|
|
42
74
|
def child_rows: (untyped, untyped) -> untyped
|
|
43
75
|
|
|
76
|
+
# : (Hash[String, Array[ActivityTargetCandidateLoader::Row]], Array[untyped]) -> Array[ActivityTargetCandidateLoader::Row]
|
|
77
|
+
def rows_for: (Hash[String, Array[ActivityTargetCandidateLoader::Row]], Array[untyped]) -> Array[ActivityTargetCandidateLoader::Row]
|
|
78
|
+
|
|
79
|
+
# : (untyped, Array[ActivityTargetCandidateLoader::Row], ActivityRange) -> Array[ActivityTargetCandidateLoader::Row]
|
|
80
|
+
def eligible_rows: (untyped, Array[ActivityTargetCandidateLoader::Row], ActivityRange) -> Array[ActivityTargetCandidateLoader::Row]
|
|
81
|
+
|
|
82
|
+
# : (untyped, untyped) -> untyped
|
|
83
|
+
def target_candidates: (untyped, untyped) -> untyped
|
|
84
|
+
|
|
44
85
|
# Mirrors VersionAssociationCandidateScope's before-window rule. The loaded
|
|
45
86
|
# series includes changes to other owners too, so an old membership cannot
|
|
46
87
|
# survive a later pre-window reassignment just because that owner is absent.
|
|
47
|
-
# : (untyped,
|
|
48
|
-
def
|
|
88
|
+
# : (untyped, untyped, untyped, String?, ActivityRange) -> bool
|
|
89
|
+
def eligible_version?: (untyped, untyped, untyped, String?, ActivityRange) -> bool
|
|
49
90
|
|
|
50
|
-
# : (untyped, untyped
|
|
51
|
-
def
|
|
91
|
+
# : (untyped, untyped) -> Hash[String, Array[untyped]]
|
|
92
|
+
def load_habtm_rows: (untyped, untyped) -> Hash[String, Array[untyped]]
|
|
52
93
|
|
|
53
|
-
#
|
|
54
|
-
|
|
94
|
+
# A version without a transaction id names no rows, so it can stay in.
|
|
95
|
+
# : (Array[untyped]) -> Array[untyped]
|
|
96
|
+
def transaction_ids: (Array[untyped]) -> Array[untyped]
|
|
55
97
|
end
|
|
56
98
|
end
|
|
@@ -3,11 +3,10 @@
|
|
|
3
3
|
module PaperTrailDiff
|
|
4
4
|
# Loads every historical identity that can participate in one association edge.
|
|
5
5
|
class PreparedEdgeLoader
|
|
6
|
-
EDGE_LOADERS: untyped
|
|
7
|
-
|
|
8
6
|
# : (PreparedRecordIndex, Array[untyped], ?start_at: untyped) -> void
|
|
9
7
|
def initialize: (PreparedRecordIndex, Array[untyped], ?start_at: untyped) -> void
|
|
10
8
|
|
|
9
|
+
# HABTM alone also returns each root transaction's members.
|
|
11
10
|
# : (untyped, Array[untyped], untyped) -> [Hash[String, Hash[Symbol, untyped]], Hash[String, Array[untyped]]?]
|
|
12
11
|
def call: (untyped, Array[untyped], untyped) -> [ Hash[String, Hash[Symbol, untyped]], Hash[String, Array[untyped]]? ]
|
|
13
12
|
|
|
@@ -19,21 +18,14 @@ module PaperTrailDiff
|
|
|
19
18
|
|
|
20
19
|
@transaction_ids: Array[untyped]
|
|
21
20
|
|
|
22
|
-
# : (untyped, Array[untyped], untyped) -> [Hash[String, Hash[Symbol, untyped]], nil]
|
|
23
|
-
def belongs_to_edge: (untyped, Array[untyped], untyped) -> [ Hash[String, Hash[Symbol, untyped]], nil ]
|
|
24
|
-
|
|
25
|
-
# : (untyped, Array[untyped], untyped) -> [Hash[String, Hash[Symbol, untyped]], nil]
|
|
26
|
-
def child_edge: (untyped, Array[untyped], untyped) -> [ Hash[String, Hash[Symbol, untyped]], nil ]
|
|
27
|
-
|
|
28
|
-
# : (untyped, Array[untyped], untyped) -> [Hash[String, Hash[Symbol, untyped]], Hash[String, Array[untyped]]]
|
|
29
|
-
def habtm_edge: (untyped, Array[untyped], untyped) -> [ Hash[String, Hash[Symbol, untyped]], Hash[String, Array[untyped]] ]
|
|
30
|
-
|
|
31
21
|
# : (untyped, Array[untyped], untyped) -> Hash[String, Hash[Symbol, untyped]]
|
|
32
22
|
def belongs_to_groups: (untyped, Array[untyped], untyped) -> Hash[String, Hash[Symbol, untyped]]
|
|
33
23
|
|
|
34
24
|
# : (untyped, Array[untyped], untyped) -> Hash[String, Hash[Symbol, untyped]]
|
|
35
25
|
def child_groups: (untyped, Array[untyped], untyped) -> Hash[String, Hash[Symbol, untyped]]
|
|
36
26
|
|
|
27
|
+
# A transaction more than one owner recorded members in is left out, so
|
|
28
|
+
# its read falls back to HistoricalAssociationReifier, which raises.
|
|
37
29
|
# : (untyped, untyped) -> [Hash[String, Hash[Symbol, untyped]], Hash[String, Array[untyped]]]
|
|
38
30
|
def habtm_groups: (untyped, untyped) -> [ Hash[String, Hash[Symbol, untyped]], Hash[String, Array[untyped]] ]
|
|
39
31
|
|
|
@@ -64,7 +56,7 @@ module PaperTrailDiff
|
|
|
64
56
|
# : (untyped, Array[untyped], ?owners: Hash[String, Array[untyped]]?) -> Hash[String, Hash[Symbol, untyped]]
|
|
65
57
|
def group_for: (untyped, Array[untyped], ?owners: Hash[String, Array[untyped]]?) -> Hash[String, Hash[Symbol, untyped]]
|
|
66
58
|
|
|
67
|
-
#
|
|
59
|
+
# A set rather than a scan, so that a wide edge stays linear in its width.
|
|
68
60
|
# : (Array[Array[untyped]]) -> Hash[String, Array[untyped]]
|
|
69
61
|
def group_ids_by_owner: (Array[Array[untyped]]) -> Hash[String, Array[untyped]]
|
|
70
62
|
|
|
@@ -10,8 +10,9 @@ module PaperTrailDiff
|
|
|
10
10
|
# : (PreparedRecordIndex, ?activity_index: PreparedActivityIndex?) -> void
|
|
11
11
|
def initialize: (PreparedRecordIndex, ?activity_index: PreparedActivityIndex?) -> void
|
|
12
12
|
|
|
13
|
-
#
|
|
14
|
-
|
|
13
|
+
# Returns every group the edge now holds.
|
|
14
|
+
# : (untyped, untyped, Hash[String, Hash[Symbol, untyped]]) -> Hash[String, Hash[Symbol, untyped]]
|
|
15
|
+
def merge_edge: (untyped, untyped, Hash[String, Hash[Symbol, untyped]]) -> Hash[String, Hash[Symbol, untyped]]
|
|
15
16
|
|
|
16
17
|
# : (untyped, untyped) -> Hash[String, Hash[Symbol, untyped]]
|
|
17
18
|
def edge: (untyped, untyped) -> Hash[String, Hash[Symbol, untyped]]
|
|
@@ -31,11 +32,15 @@ module PaperTrailDiff
|
|
|
31
32
|
# : (PreparedRecordState, untyped, untyped) -> [bool, Array[PreparedRecordState]]
|
|
32
33
|
def snapshot_states: (PreparedRecordState, untyped, untyped) -> [ bool, Array[PreparedRecordState] ]
|
|
33
34
|
|
|
34
|
-
#
|
|
35
|
-
|
|
35
|
+
# Unranked, as a part of a has_many through is read, it returns every row
|
|
36
|
+
# the part's conditions admit, a record reached twice appearing twice.
|
|
37
|
+
# : (untyped, untyped, untyped, habtm_boundary: untyped, ?ranked: bool) -> [bool, Array[untyped]]
|
|
38
|
+
def resolve: (untyped, untyped, untyped, habtm_boundary: untyped, ?ranked: bool) -> [ bool, Array[untyped] ]
|
|
36
39
|
|
|
37
40
|
private
|
|
38
41
|
|
|
42
|
+
@conditions: ScopeCondition::Cache
|
|
43
|
+
|
|
39
44
|
@edges: Hash[Array[String], Hash[String, Hash[Symbol, untyped]]]
|
|
40
45
|
|
|
41
46
|
@habtm: Hash[Array[String], Hash[String, Array[untyped]]]
|
|
@@ -46,35 +51,41 @@ module PaperTrailDiff
|
|
|
46
51
|
|
|
47
52
|
@unsupported: Hash[Array[String], bool]
|
|
48
53
|
|
|
49
|
-
#
|
|
50
|
-
|
|
54
|
+
# A polymorphic target's class is known only once a record names it, so
|
|
55
|
+
# belongs_to_records reads its scope for each record instead.
|
|
56
|
+
# : (untyped, untyped, bool) -> bool
|
|
57
|
+
def supported?: (untyped, untyped, bool) -> bool
|
|
51
58
|
|
|
52
|
-
# : (untyped, untyped, untyped, untyped) -> Array[untyped]?
|
|
53
|
-
def direct_records: (untyped, untyped, untyped, untyped) -> Array[untyped]?
|
|
59
|
+
# : (untyped, untyped, untyped, untyped, bool) -> Array[untyped]?
|
|
60
|
+
def direct_records: (untyped, untyped, untyped, untyped, bool) -> Array[untyped]?
|
|
54
61
|
|
|
55
|
-
# : (untyped, untyped, untyped, untyped) -> Array[untyped]?
|
|
56
|
-
def resolve_belongs_to: (untyped, untyped, untyped, untyped) -> Array[untyped]?
|
|
62
|
+
# : (untyped, untyped, untyped, untyped, bool) -> Array[untyped]?
|
|
63
|
+
def resolve_belongs_to: (untyped, untyped, untyped, untyped, bool) -> Array[untyped]?
|
|
57
64
|
|
|
58
|
-
# : (untyped, untyped, untyped, untyped) -> Array[untyped]
|
|
59
|
-
def resolve_children: (untyped, untyped, untyped, untyped) -> Array[untyped]
|
|
65
|
+
# : (untyped, untyped, untyped, untyped, bool) -> Array[untyped]
|
|
66
|
+
def resolve_children: (untyped, untyped, untyped, untyped, bool) -> Array[untyped]
|
|
60
67
|
|
|
61
|
-
# : (untyped, untyped, untyped) -> Array[untyped]?
|
|
62
|
-
def belongs_to_records: (untyped, untyped, untyped) -> Array[untyped]?
|
|
68
|
+
# : (untyped, untyped, untyped, bool) -> Array[untyped]?
|
|
69
|
+
def belongs_to_records: (untyped, untyped, untyped, bool) -> Array[untyped]?
|
|
63
70
|
|
|
64
|
-
# : (untyped, untyped, untyped) -> Array[untyped]
|
|
65
|
-
def child_records: (untyped, untyped, untyped) -> Array[untyped]
|
|
71
|
+
# : (untyped, untyped, untyped, bool) -> Array[untyped]
|
|
72
|
+
def child_records: (untyped, untyped, untyped, bool) -> Array[untyped]
|
|
66
73
|
|
|
67
74
|
# : (Hash[Symbol, untyped], untyped) -> Array[untyped]
|
|
68
75
|
def child_ids_for: (Hash[Symbol, untyped], untyped) -> Array[untyped]
|
|
69
76
|
|
|
70
|
-
# : (untyped, untyped, untyped, untyped) -> Array[untyped]?
|
|
71
|
-
def habtm_records: (untyped, untyped, untyped, untyped) -> Array[untyped]?
|
|
77
|
+
# : (untyped, untyped, untyped, untyped, bool) -> Array[untyped]?
|
|
78
|
+
def habtm_records: (untyped, untyped, untyped, untyped, bool) -> Array[untyped]?
|
|
72
79
|
|
|
73
|
-
#
|
|
74
|
-
|
|
80
|
+
# A has_many through reads its parts unranked, as its query does. Its own
|
|
81
|
+
# scope applies to each row, and a ranked read then keeps a record reached
|
|
82
|
+
# twice as one member.
|
|
83
|
+
# : (untyped, untyped, untyped, untyped, bool) -> Array[untyped]?
|
|
84
|
+
def through_records: (untyped, untyped, untyped, untyped, bool) -> Array[untyped]?
|
|
75
85
|
|
|
76
|
-
#
|
|
77
|
-
|
|
86
|
+
# The source records of each join record, once for each join.
|
|
87
|
+
# : (untyped, untyped, ^(untyped, untyped) -> [bool, Array[untyped]]) -> Array[untyped]?
|
|
88
|
+
def through_rows: (untyped, untyped, ^(untyped, untyped) -> [ bool, Array[untyped] ]) -> Array[untyped]?
|
|
78
89
|
|
|
79
90
|
# : (untyped, untyped, untyped) -> bool
|
|
80
91
|
def member_of?: (untyped, untyped, untyped) -> bool
|
|
@@ -3,19 +3,22 @@
|
|
|
3
3
|
module PaperTrailDiff
|
|
4
4
|
# Expands the explicit association tree into a request-scoped PreparedHistory.
|
|
5
5
|
class PreparedHistoryLoader
|
|
6
|
-
#
|
|
7
|
-
|
|
6
|
+
# Without `end_at`, the activity range closes on the last root version.
|
|
7
|
+
# : (untyped, root_ids: Array[untyped], root_versions: Array[untyped], tree: AssociationTree, traversal: AssociationTraversal, start_at: untyped, end_at: untyped, live_records: Array[untyped]) -> void
|
|
8
|
+
def initialize: (untyped, root_ids: Array[untyped], root_versions: Array[untyped], tree: AssociationTree, traversal: AssociationTraversal, start_at: untyped, end_at: untyped, live_records: Array[untyped]) -> void
|
|
8
9
|
|
|
9
10
|
# : () -> PreparedHistory
|
|
10
11
|
def call: () -> PreparedHistory
|
|
11
12
|
|
|
12
13
|
private
|
|
13
14
|
|
|
15
|
+
@activity: PreparedActivityIndex
|
|
16
|
+
|
|
14
17
|
@edges: PreparedEdgeLoader
|
|
15
18
|
|
|
16
19
|
@history: PreparedHistory
|
|
17
20
|
|
|
18
|
-
@prepared: Hash[
|
|
21
|
+
@prepared: Hash[untyped, Array[String]]
|
|
19
22
|
|
|
20
23
|
@record: untyped
|
|
21
24
|
|
|
@@ -35,24 +38,26 @@ module PaperTrailDiff
|
|
|
35
38
|
# : (untyped, Array[untyped], untyped) -> Hash[String, Hash[Symbol, untyped]]
|
|
36
39
|
def prepare_reflection: (untyped, Array[untyped], untyped) -> Hash[String, Hash[Symbol, untyped]]
|
|
37
40
|
|
|
41
|
+
# Either part can itself be a through, which has no key of its own to
|
|
42
|
+
# read, so each part is prepared as what it is. Like an edge, it returns
|
|
43
|
+
# every group it holds, not only those of these owners.
|
|
38
44
|
# : (untyped, Array[untyped], untyped) -> Hash[String, Hash[Symbol, untyped]]
|
|
39
45
|
def prepare_through: (untyped, Array[untyped], untyped) -> Hash[String, Hash[Symbol, untyped]]
|
|
40
46
|
|
|
41
47
|
# : (untyped, Array[untyped], untyped) -> Hash[String, Hash[Symbol, untyped]]
|
|
42
48
|
def prepare_edge: (untyped, Array[untyped], untyped) -> Hash[String, Hash[Symbol, untyped]]
|
|
43
49
|
|
|
44
|
-
#
|
|
45
|
-
|
|
50
|
+
# A reflection belongs to the class that declares it, so it alone names
|
|
51
|
+
# the edge; a subclass that inherits it reads the same records.
|
|
52
|
+
# : (Array[untyped], untyped) -> Array[untyped]
|
|
53
|
+
def unprepared_ids: (Array[untyped], untyped) -> Array[untyped]
|
|
46
54
|
|
|
47
|
-
# : (
|
|
48
|
-
def mark_prepared: (
|
|
55
|
+
# : (Array[untyped], untyped) -> void
|
|
56
|
+
def mark_prepared: (Array[untyped], untyped) -> void
|
|
49
57
|
|
|
50
58
|
# : (untyped, untyped, Hash[String, Hash[Symbol, untyped]]) -> void
|
|
51
59
|
def mark_unsupported: (untyped, untyped, Hash[String, Hash[Symbol, untyped]]) -> void
|
|
52
60
|
|
|
53
|
-
# : (untyped) -> bool
|
|
54
|
-
def deferred_macro?: (untyped) -> bool
|
|
55
|
-
|
|
56
61
|
# : (Hash[String, Hash[Symbol, untyped]]) -> void
|
|
57
62
|
def load_groups: (Hash[String, Hash[Symbol, untyped]]) -> void
|
|
58
63
|
|
|
@@ -62,9 +67,6 @@ module PaperTrailDiff
|
|
|
62
67
|
# : (untyped) -> bool
|
|
63
68
|
def versioned?: (untyped) -> bool
|
|
64
69
|
|
|
65
|
-
# : (untyped, untyped) -> Array[String]
|
|
66
|
-
def edge_key: (untyped, untyped) -> Array[String]
|
|
67
|
-
|
|
68
70
|
# : (Hash[String, Hash[Symbol, untyped]], Hash[String, Hash[Symbol, untyped]]) -> Hash[String, Hash[Symbol, untyped]]
|
|
69
71
|
def merge_groups: (Hash[String, Hash[Symbol, untyped]], Hash[String, Hash[Symbol, untyped]]) -> Hash[String, Hash[Symbol, untyped]]
|
|
70
72
|
end
|
|
@@ -81,6 +81,15 @@ module PaperTrailDiff
|
|
|
81
81
|
# : () -> Array[PreparedRecordState]
|
|
82
82
|
def states: () -> Array[PreparedRecordState]
|
|
83
83
|
|
|
84
|
+
# The classes the record had at any point, or either side of one version.
|
|
85
|
+
# : (?untyped) -> Array[untyped]
|
|
86
|
+
def model_classes: (?untyped) -> Array[untyped]
|
|
87
|
+
|
|
88
|
+
# The states either side of one version; a create has none before it and a
|
|
89
|
+
# destroy none after.
|
|
90
|
+
# : (untyped) -> Array[PreparedRecordState]
|
|
91
|
+
def states_around: (untyped) -> Array[PreparedRecordState]
|
|
92
|
+
|
|
84
93
|
# : (untyped) -> [Hash[untyped, untyped], Hash[untyped, untyped]]?
|
|
85
94
|
def transition: (untyped) -> [ Hash[untyped, untyped], Hash[untyped, untyped] ]?
|
|
86
95
|
|
|
@@ -153,6 +162,12 @@ module PaperTrailDiff
|
|
|
153
162
|
# : (untyped, untyped) -> Array[untyped]
|
|
154
163
|
def versions_for_id: (untyped, untyped) -> Array[untyped]
|
|
155
164
|
|
|
165
|
+
# : (untyped, untyped, ?untyped) -> Array[untyped]
|
|
166
|
+
def model_classes: (untyped, untyped, ?untyped) -> Array[untyped]
|
|
167
|
+
|
|
168
|
+
# : (untyped, untyped, untyped) -> Array[PreparedRecordState]
|
|
169
|
+
def states_around: (untyped, untyped, untyped) -> Array[PreparedRecordState]
|
|
170
|
+
|
|
156
171
|
# : (untyped, untyped) -> bool
|
|
157
172
|
def loaded?: (untyped, untyped) -> bool
|
|
158
173
|
|
|
@@ -1,31 +1,76 @@
|
|
|
1
1
|
# Generated from lib/paper_trail_diff/prepared_state_association_reader.rb with RBS::Inline
|
|
2
2
|
|
|
3
3
|
module PaperTrailDiff
|
|
4
|
-
# Reads plain
|
|
4
|
+
# Reads plain edges without creating AR records for their members: direct
|
|
5
|
+
# edges, polymorphic `belongs_to`, and `has_many :through` built from them.
|
|
5
6
|
class PreparedStateAssociationReader
|
|
6
|
-
# : (PreparedRecordIndex, untyped) -> void
|
|
7
|
-
def initialize: (PreparedRecordIndex, untyped) -> void
|
|
7
|
+
# : (PreparedRecordIndex, untyped, ScopeCondition::Cache) -> void
|
|
8
|
+
def initialize: (PreparedRecordIndex, untyped, ScopeCondition::Cache) -> void
|
|
8
9
|
|
|
9
|
-
#
|
|
10
|
-
|
|
10
|
+
# Unranked, as a part of a has_many through is read, it returns every row
|
|
11
|
+
# the part's conditions admit, a record reached twice appearing twice.
|
|
12
|
+
# : (PreparedRecordState, untyped, untyped, ?ranked: bool) -> [bool, Array[PreparedRecordState]]
|
|
13
|
+
def call: (PreparedRecordState, untyped, untyped, ?ranked: bool) -> [ bool, Array[PreparedRecordState] ]
|
|
11
14
|
|
|
12
15
|
private
|
|
13
16
|
|
|
17
|
+
@conditions: ScopeCondition::Cache
|
|
18
|
+
|
|
14
19
|
@edges: untyped
|
|
15
20
|
|
|
16
21
|
@records: PreparedRecordIndex
|
|
17
22
|
|
|
18
|
-
#
|
|
19
|
-
|
|
23
|
+
# A polymorphic target's class is known only once a record names it, so
|
|
24
|
+
# `target` reads its scope for each record instead.
|
|
25
|
+
# : (untyped, bool) -> bool
|
|
26
|
+
def supported?: (untyped, bool) -> bool
|
|
27
|
+
|
|
28
|
+
# : (PreparedRecordState, untyped, bool, ?untyped) -> bool
|
|
29
|
+
def in_scope?: (PreparedRecordState, untyped, bool, ?untyped) -> bool
|
|
30
|
+
|
|
31
|
+
# A type that names no class, or a class whose scope cannot be read as
|
|
32
|
+
# conditions, is left to the record path, which raises for the first and
|
|
33
|
+
# reads the second through its association.
|
|
34
|
+
# : (PreparedRecordState, untyped, untyped, bool) -> [bool, Array[PreparedRecordState]]
|
|
35
|
+
def target: (PreparedRecordState, untyped, untyped, bool) -> [ bool, Array[PreparedRecordState] ]
|
|
36
|
+
|
|
37
|
+
# : (PreparedRecordState, untyped) -> untyped
|
|
38
|
+
def target_class: (PreparedRecordState, untyped) -> untyped
|
|
39
|
+
|
|
40
|
+
# The members of each join record the owner had at the boundary, as
|
|
41
|
+
# PreparedHistory#through_records reads them from records. Under
|
|
42
|
+
# `source_type:`, only join records of that type count. A has_many
|
|
43
|
+
# through reads its parts unranked, as its query does.
|
|
44
|
+
# : (PreparedRecordState, untyped, untyped, bool) -> [bool, Array[PreparedRecordState]]
|
|
45
|
+
def through: (PreparedRecordState, untyped, untyped, bool) -> [ bool, Array[PreparedRecordState] ]
|
|
20
46
|
|
|
21
|
-
#
|
|
22
|
-
|
|
47
|
+
# The through's own scope applies after its parts' scopes, to each row,
|
|
48
|
+
# and a ranked read then keeps a record reached twice as one member.
|
|
49
|
+
# : (untyped, Array[PreparedRecordState], bool) -> Array[PreparedRecordState]
|
|
50
|
+
def through_members: (untyped, Array[PreparedRecordState], bool) -> Array[PreparedRecordState]
|
|
51
|
+
|
|
52
|
+
# A has_one keeps the first of its records.
|
|
53
|
+
# : (untyped, Array[PreparedRecordState]) -> Array[PreparedRecordState]
|
|
54
|
+
def first_if_one: (untyped, Array[PreparedRecordState]) -> Array[PreparedRecordState]
|
|
55
|
+
|
|
56
|
+
# : (untyped, PreparedRecordState) -> bool
|
|
57
|
+
def typed_join?: (untyped, PreparedRecordState) -> bool
|
|
58
|
+
|
|
59
|
+
# A record reached through two join records is one member.
|
|
60
|
+
# : (PreparedRecordState) -> Array[untyped]
|
|
61
|
+
def identity: (PreparedRecordState) -> Array[untyped]
|
|
62
|
+
|
|
63
|
+
# : (PreparedRecordState, untyped, untyped, bool) -> [bool, Array[PreparedRecordState]]
|
|
64
|
+
def children: (PreparedRecordState, untyped, untyped, bool) -> [ bool, Array[PreparedRecordState] ]
|
|
23
65
|
|
|
24
66
|
# : (untyped, PreparedRecordState) -> Array[untyped]
|
|
25
67
|
def ids_for: (untyped, PreparedRecordState) -> Array[untyped]
|
|
26
68
|
|
|
27
|
-
# : (PreparedRecordState, PreparedRecordState, untyped) -> bool
|
|
28
|
-
def member?: (PreparedRecordState, PreparedRecordState, untyped) -> bool
|
|
69
|
+
# : (PreparedRecordState, PreparedRecordState, untyped, bool) -> bool
|
|
70
|
+
def member?: (PreparedRecordState, PreparedRecordState, untyped, bool) -> bool
|
|
71
|
+
|
|
72
|
+
# : (PreparedRecordState) -> String
|
|
73
|
+
def owner_id: (PreparedRecordState) -> String
|
|
29
74
|
|
|
30
75
|
# : (PreparedRecordState, untyped, untyped) -> bool
|
|
31
76
|
def matching_type?: (PreparedRecordState, untyped, untyped) -> bool
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# Generated from lib/paper_trail_diff/recorded_changes.rb with RBS::Inline
|
|
2
|
+
|
|
3
|
+
module PaperTrailDiff
|
|
4
|
+
# The changes PaperTrail wrote with one version, typed by the version's model.
|
|
5
|
+
#
|
|
6
|
+
# A step's diff compares reconstructed states, so it also holds whatever was
|
|
7
|
+
# saved without a version before the next one was read. This is the other
|
|
8
|
+
# account of the same event: only what PaperTrail recorded for it. Comparing
|
|
9
|
+
# the two is how a caller tells an unrecorded write from the event's own edit.
|
|
10
|
+
#
|
|
11
|
+
# PaperTrail's `version.changeset` finds the model through `version.item`,
|
|
12
|
+
# which is a query per version and nothing at all once the record is deleted.
|
|
13
|
+
# The version already names its model, so neither is needed here.
|
|
14
|
+
class RecordedChanges
|
|
15
|
+
IGNORE_NAMES_REQUIRED: ::String
|
|
16
|
+
|
|
17
|
+
# : (untyped, ignore: untyped) -> Hash[String, ValueChange]?
|
|
18
|
+
def self.call: (untyped, ignore: untyped) -> Hash[String, ValueChange]?
|
|
19
|
+
|
|
20
|
+
# : (untyped, ignore: untyped) -> void
|
|
21
|
+
def initialize: (untyped, ignore: untyped) -> void
|
|
22
|
+
|
|
23
|
+
# : () -> Hash[String, ValueChange]?
|
|
24
|
+
def call: () -> Hash[String, ValueChange]?
|
|
25
|
+
|
|
26
|
+
private
|
|
27
|
+
|
|
28
|
+
@ignore: untyped
|
|
29
|
+
|
|
30
|
+
@version: untyped
|
|
31
|
+
|
|
32
|
+
# Validated before anything is read, so a bad option fails the same way
|
|
33
|
+
# whether or not this version happened to record changes. Subclasses of
|
|
34
|
+
# Array and String pass, as in other methods' `ignore:`; Symbol has none.
|
|
35
|
+
# : () -> Array[String]
|
|
36
|
+
def ignored_names: () -> Array[String]
|
|
37
|
+
|
|
38
|
+
# Without the column, or with it left empty for this version, nothing was
|
|
39
|
+
# recorded. That is not the same answer as a recorded empty changeset.
|
|
40
|
+
# : () -> bool
|
|
41
|
+
def recorded?: () -> bool
|
|
42
|
+
|
|
43
|
+
# Primary keys identify the record rather than describe it, as in a diff.
|
|
44
|
+
# : (untyped, Array[String]) -> Hash[String, ValueChange]
|
|
45
|
+
def value_changes: (untyped, Array[String]) -> Hash[String, ValueChange]
|
|
46
|
+
end
|
|
47
|
+
end
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# Generated from lib/paper_trail_diff/recorded_class.rb with RBS::Inline
|
|
2
|
+
|
|
3
|
+
module PaperTrailDiff
|
|
4
|
+
# The class a record had at one version, which decides the associations it
|
|
5
|
+
# can have. Without an `item_subtype` column PaperTrail stores only the base
|
|
6
|
+
# class, so an STI subclass is read from the stored inheritance column: the
|
|
7
|
+
# state before the change, or for a create, the value it was created with.
|
|
8
|
+
# A version that stored neither stays on the base class.
|
|
9
|
+
module RecordedClass
|
|
10
|
+
# : (untyped) -> untyped
|
|
11
|
+
def self?.for: (untyped) -> untyped
|
|
12
|
+
|
|
13
|
+
# : (untyped) -> bool
|
|
14
|
+
def self?.sti_base?: (untyped) -> bool
|
|
15
|
+
|
|
16
|
+
# : (untyped, untyped) -> untyped
|
|
17
|
+
def self?.stored_type: (untyped, untyped) -> untyped
|
|
18
|
+
|
|
19
|
+
# : (StandardError) -> bool
|
|
20
|
+
def self?.subclass_not_found?: (StandardError) -> bool
|
|
21
|
+
end
|
|
22
|
+
end
|