cdc-core 0.0.0 → 0.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +29 -1
- data/LICENSE.txt +2 -1
- data/README.md +145 -22
- data/lib/cdc/core/change_event.rb +116 -0
- data/lib/cdc/core/column_change.rb +55 -0
- data/lib/cdc/core/composite_processor.rb +71 -0
- data/lib/cdc/core/errors.rb +14 -0
- data/lib/cdc/core/event_metadata.rb +78 -0
- data/lib/cdc/core/filter.rb +77 -0
- data/lib/cdc/core/operation.rb +51 -0
- data/lib/cdc/core/pipeline.rb +66 -0
- data/lib/cdc/core/processor.rb +43 -0
- data/lib/cdc/core/processor_result.rb +63 -0
- data/lib/cdc/core/transaction_envelope.rb +58 -0
- data/lib/cdc/core/version.rb +3 -2
- data/lib/cdc/core.rb +20 -4
- data/lib/cdc_core.rb +7 -0
- data/sig/cdc/core/change_event.rbs +226 -0
- data/sig/cdc/core/column_change.rbs +56 -0
- data/sig/cdc/core/composite_processor.rbs +53 -0
- data/sig/cdc/core/errors.rbs +15 -0
- data/sig/cdc/core/event_metadata.rbs +51 -0
- data/sig/cdc/core/filter.rbs +68 -0
- data/sig/cdc/core/operation.rbs +44 -0
- data/sig/cdc/core/pipeline.rbs +55 -0
- data/sig/cdc/core/processor.rbs +35 -0
- data/sig/cdc/core/processor_result.rbs +81 -0
- data/sig/cdc/core/transaction_envelope.rbs +79 -0
- data/sig/cdc/core/version.rbs +6 -0
- data/sig/cdc/core.rbs +8 -3
- data/sig/cdc_core.rbs +0 -0
- metadata +34 -7
- data/CODE_OF_CONDUCT.md +0 -10
- data/Rakefile +0 -12
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
module CDC
|
|
2
|
+
module Core
|
|
3
|
+
# Immutable metadata container for CDC domain objects.
|
|
4
|
+
#
|
|
5
|
+
# Metadata keys are normalized to frozen strings. Nested hashes and arrays
|
|
6
|
+
# are recursively converted into Ractor-shareable objects. Values that Ruby
|
|
7
|
+
# cannot make shareable are stored as frozen #inspect strings.
|
|
8
|
+
class EventMetadata
|
|
9
|
+
@data: untyped
|
|
10
|
+
|
|
11
|
+
# @return [Hash{String=>Object}] normalized metadata
|
|
12
|
+
attr_reader data: untyped
|
|
13
|
+
|
|
14
|
+
# Build metadata from a hash-like structure.
|
|
15
|
+
#
|
|
16
|
+
# @param data [Hash] metadata values
|
|
17
|
+
def initialize: (?::Hash[untyped, untyped] data) -> void
|
|
18
|
+
|
|
19
|
+
# Fetch a metadata value by string or symbol key.
|
|
20
|
+
#
|
|
21
|
+
# @param key [String, Symbol] metadata key
|
|
22
|
+
# @return [Object, nil]
|
|
23
|
+
def []: (untyped key) -> untyped
|
|
24
|
+
|
|
25
|
+
# Return the normalized Ractor-shareable hash.
|
|
26
|
+
#
|
|
27
|
+
# @return [Hash{String=>Object}]
|
|
28
|
+
def to_h: () -> untyped
|
|
29
|
+
|
|
30
|
+
private
|
|
31
|
+
|
|
32
|
+
# Recursively normalize and freeze a hash.
|
|
33
|
+
#
|
|
34
|
+
# @param hash [Hash]
|
|
35
|
+
# @return [Hash{String=>Object}]
|
|
36
|
+
def deep_shareable_hash: (untyped hash) -> untyped
|
|
37
|
+
|
|
38
|
+
# Normalize metadata keys to frozen strings.
|
|
39
|
+
#
|
|
40
|
+
# @param key [Object]
|
|
41
|
+
# @return [String]
|
|
42
|
+
def normalize_key: (untyped key) -> untyped
|
|
43
|
+
|
|
44
|
+
# Normalize a metadata value into a shareable representation.
|
|
45
|
+
#
|
|
46
|
+
# @param value [Object]
|
|
47
|
+
# @return [Object]
|
|
48
|
+
def normalize_value: (untyped value) -> untyped
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
module CDC
|
|
2
|
+
module Core
|
|
3
|
+
# Predicate object used to decide whether a pipeline should process an event.
|
|
4
|
+
#
|
|
5
|
+
# Filters are composable with #& and #|. A filter only matches when its
|
|
6
|
+
# predicate returns true exactly, keeping accidental truthy values from
|
|
7
|
+
# silently passing events through a pipeline.
|
|
8
|
+
class Filter
|
|
9
|
+
@predicate: untyped
|
|
10
|
+
|
|
11
|
+
# Match every event.
|
|
12
|
+
#
|
|
13
|
+
# @return [Filter]
|
|
14
|
+
def self.all: () -> untyped
|
|
15
|
+
|
|
16
|
+
# Match events from a schema.
|
|
17
|
+
#
|
|
18
|
+
# @param name [#to_s] schema name
|
|
19
|
+
# @return [Filter]
|
|
20
|
+
def self.schema: (untyped name) -> untyped
|
|
21
|
+
|
|
22
|
+
# Match events from a table regardless of schema.
|
|
23
|
+
#
|
|
24
|
+
# @param name [#to_s] table name
|
|
25
|
+
# @return [Filter]
|
|
26
|
+
def self.table: (untyped name) -> untyped
|
|
27
|
+
|
|
28
|
+
# Match events from a fully qualified schema.table name.
|
|
29
|
+
#
|
|
30
|
+
# @param name [#to_s] qualified table name
|
|
31
|
+
# @return [Filter]
|
|
32
|
+
def self.qualified_table: (untyped name) -> untyped
|
|
33
|
+
|
|
34
|
+
# Match events by operation.
|
|
35
|
+
#
|
|
36
|
+
# @param operation [#to_sym] CDC operation
|
|
37
|
+
# @return [Filter]
|
|
38
|
+
def self.operation: (untyped operation) -> untyped
|
|
39
|
+
|
|
40
|
+
# Build a custom filter.
|
|
41
|
+
#
|
|
42
|
+
# @yieldparam event [ChangeEvent] event being tested
|
|
43
|
+
# @yieldreturn [Boolean] true to match the event
|
|
44
|
+
# @raise [ArgumentError] when no predicate block is provided
|
|
45
|
+
def initialize: () ?{ (?) -> untyped } -> void
|
|
46
|
+
|
|
47
|
+
# Whether this filter matches an event.
|
|
48
|
+
#
|
|
49
|
+
# @param event [ChangeEvent] event to test
|
|
50
|
+
# @return [Boolean]
|
|
51
|
+
def match?: (untyped event) -> untyped
|
|
52
|
+
|
|
53
|
+
alias =~ match?
|
|
54
|
+
|
|
55
|
+
# Compose this filter with another filter using logical AND.
|
|
56
|
+
#
|
|
57
|
+
# @param other [Filter] other filter
|
|
58
|
+
# @return [Filter]
|
|
59
|
+
def &: (untyped other) -> untyped
|
|
60
|
+
|
|
61
|
+
# Compose this filter with another filter using logical OR.
|
|
62
|
+
#
|
|
63
|
+
# @param other [Filter] other filter
|
|
64
|
+
# @return [Filter]
|
|
65
|
+
def |: (untyped other) -> untyped
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
end
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
module CDC
|
|
2
|
+
module Core
|
|
3
|
+
# Canonical CDC operation names.
|
|
4
|
+
#
|
|
5
|
+
# Operations are represented as symbols to keep event objects small,
|
|
6
|
+
# immutable, and easy to compare. Use .normalize when accepting user input
|
|
7
|
+
# and .supported? when validating optional values.
|
|
8
|
+
module Operation
|
|
9
|
+
# Insert row operation.
|
|
10
|
+
INSERT: :insert
|
|
11
|
+
|
|
12
|
+
# Update row operation.
|
|
13
|
+
UPDATE: :update
|
|
14
|
+
|
|
15
|
+
# Delete row operation.
|
|
16
|
+
DELETE: :delete
|
|
17
|
+
|
|
18
|
+
# Truncate table operation.
|
|
19
|
+
TRUNCATE: :truncate
|
|
20
|
+
|
|
21
|
+
# Logical replication message operation.
|
|
22
|
+
MESSAGE: :message
|
|
23
|
+
|
|
24
|
+
# All operation names currently recognized by cdc-core.
|
|
25
|
+
SUPPORTED: untyped
|
|
26
|
+
|
|
27
|
+
# Minimal row-change operations used by the initial runtime surface.
|
|
28
|
+
MVP: untyped
|
|
29
|
+
|
|
30
|
+
# Convert an operation-like value into a supported operation symbol.
|
|
31
|
+
#
|
|
32
|
+
# @param operation [#to_sym] value to normalize
|
|
33
|
+
# @return [Symbol] one of SUPPORTED
|
|
34
|
+
# @raise [InvalidOperationError] when the operation is not supported
|
|
35
|
+
def self?.normalize: (untyped operation) -> untyped
|
|
36
|
+
|
|
37
|
+
# Check whether an operation-like value is supported.
|
|
38
|
+
#
|
|
39
|
+
# @param operation [#to_sym] value to check
|
|
40
|
+
# @return [Boolean] true when the value normalizes to a supported operation
|
|
41
|
+
def self?.supported?: (untyped operation) -> untyped
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
module CDC
|
|
2
|
+
module Core
|
|
3
|
+
# Connects filters with a processor to form an event-processing unit.
|
|
4
|
+
#
|
|
5
|
+
# A Pipeline first evaluates all filters. Matching events are handed to the
|
|
6
|
+
# processor, while filtered events produce skipped results. Processor errors
|
|
7
|
+
# are captured as failure results instead of escaping to the caller.
|
|
8
|
+
class Pipeline
|
|
9
|
+
@processor: untyped
|
|
10
|
+
|
|
11
|
+
@filters: untyped
|
|
12
|
+
|
|
13
|
+
# @return [#process] processor invoked for matching events
|
|
14
|
+
# @return [Array<Filter>] filters that must all match before processing
|
|
15
|
+
attr_reader processor: untyped
|
|
16
|
+
|
|
17
|
+
# @return [#process] processor invoked for matching events
|
|
18
|
+
# @return [Array<Filter>] filters that must all match before processing
|
|
19
|
+
attr_reader filters: untyped
|
|
20
|
+
|
|
21
|
+
# Build a pipeline.
|
|
22
|
+
#
|
|
23
|
+
# @param processor [#process] processor for matching events
|
|
24
|
+
# @param filters [Array<Filter>] filters applied before processing
|
|
25
|
+
def initialize: (processor: untyped, ?filters: untyped) -> void
|
|
26
|
+
|
|
27
|
+
# Process one event through the pipeline.
|
|
28
|
+
#
|
|
29
|
+
# @param event [ChangeEvent] event to process
|
|
30
|
+
# @return [ProcessorResult]
|
|
31
|
+
def process: (untyped event) -> untyped
|
|
32
|
+
|
|
33
|
+
# Process many events in order.
|
|
34
|
+
#
|
|
35
|
+
# @param events [Enumerable<ChangeEvent>] events to process
|
|
36
|
+
# @return [Array<ProcessorResult>]
|
|
37
|
+
def process_many: (untyped events) -> untyped
|
|
38
|
+
|
|
39
|
+
private
|
|
40
|
+
|
|
41
|
+
# Check whether every filter matches an event.
|
|
42
|
+
#
|
|
43
|
+
# @param event [ChangeEvent]
|
|
44
|
+
# @return [Boolean]
|
|
45
|
+
def matches?: (untyped event) -> untyped
|
|
46
|
+
|
|
47
|
+
# Normalize raw processor output into a ProcessorResult.
|
|
48
|
+
#
|
|
49
|
+
# @param result [Object] raw processor result
|
|
50
|
+
# @param event [ChangeEvent] processed event
|
|
51
|
+
# @return [ProcessorResult]
|
|
52
|
+
def normalize_result: (untyped result, untyped event) -> untyped
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
module CDC
|
|
2
|
+
module Core
|
|
3
|
+
# Base class for CDC event processors.
|
|
4
|
+
#
|
|
5
|
+
# Subclasses implement #process and may opt into Ractor-safe execution by
|
|
6
|
+
# calling .ractor_safe!. cdc-core itself does not schedule Ractors; it only
|
|
7
|
+
# records processor capabilities for runtime layers such as cdc-ractor.
|
|
8
|
+
class Processor
|
|
9
|
+
self.@ractor_safe: untyped
|
|
10
|
+
|
|
11
|
+
# Mark this processor class as safe to execute in Ractor-aware runtimes.
|
|
12
|
+
#
|
|
13
|
+
# @return [true]
|
|
14
|
+
def self.ractor_safe!: () -> untyped
|
|
15
|
+
|
|
16
|
+
# Whether this processor class has declared Ractor safety.
|
|
17
|
+
#
|
|
18
|
+
# @return [Boolean]
|
|
19
|
+
def self.ractor_safe?: () -> untyped
|
|
20
|
+
|
|
21
|
+
# Whether this processor instance is Ractor-safe.
|
|
22
|
+
#
|
|
23
|
+
# @return [Boolean]
|
|
24
|
+
def ractor_safe?: () -> untyped
|
|
25
|
+
|
|
26
|
+
# Process one event.
|
|
27
|
+
#
|
|
28
|
+
# Subclasses must override this method.
|
|
29
|
+
#
|
|
30
|
+
# @param _event [ChangeEvent] event to process
|
|
31
|
+
# @raise [NotImplementedError] when not implemented by a subclass
|
|
32
|
+
def process: (untyped _event) -> untyped
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
module CDC
|
|
2
|
+
module Core
|
|
3
|
+
# Result returned by processors and pipelines.
|
|
4
|
+
#
|
|
5
|
+
# ProcessorResult standardizes processor outcomes so callers can distinguish
|
|
6
|
+
# successful processing, skipped events, and failures without relying on
|
|
7
|
+
# processor-specific return values.
|
|
8
|
+
class ProcessorResult
|
|
9
|
+
@status: untyped
|
|
10
|
+
|
|
11
|
+
@event: untyped
|
|
12
|
+
|
|
13
|
+
@error: untyped
|
|
14
|
+
|
|
15
|
+
@metadata: untyped
|
|
16
|
+
|
|
17
|
+
# @return [Symbol] result status
|
|
18
|
+
# @return [ChangeEvent, nil] event associated with the result
|
|
19
|
+
# @return [Exception, nil] failure error, when status is :failure
|
|
20
|
+
# @return [EventMetadata] result metadata
|
|
21
|
+
attr_reader status: untyped
|
|
22
|
+
|
|
23
|
+
# @return [Symbol] result status
|
|
24
|
+
# @return [ChangeEvent, nil] event associated with the result
|
|
25
|
+
# @return [Exception, nil] failure error, when status is :failure
|
|
26
|
+
# @return [EventMetadata] result metadata
|
|
27
|
+
attr_reader event: untyped
|
|
28
|
+
|
|
29
|
+
# @return [Symbol] result status
|
|
30
|
+
# @return [ChangeEvent, nil] event associated with the result
|
|
31
|
+
# @return [Exception, nil] failure error, when status is :failure
|
|
32
|
+
# @return [EventMetadata] result metadata
|
|
33
|
+
attr_reader error: untyped
|
|
34
|
+
|
|
35
|
+
# @return [Symbol] result status
|
|
36
|
+
# @return [ChangeEvent, nil] event associated with the result
|
|
37
|
+
# @return [Exception, nil] failure error, when status is :failure
|
|
38
|
+
# @return [EventMetadata] result metadata
|
|
39
|
+
attr_reader metadata: untyped
|
|
40
|
+
|
|
41
|
+
# Build a successful result.
|
|
42
|
+
#
|
|
43
|
+
# @param event [ChangeEvent, nil] processed event
|
|
44
|
+
# @param metadata [Hash, EventMetadata] result metadata
|
|
45
|
+
# @return [ProcessorResult]
|
|
46
|
+
def self.success: (?untyped? event, ?metadata: ::Hash[untyped, untyped]) -> untyped
|
|
47
|
+
|
|
48
|
+
# Build a failure result.
|
|
49
|
+
#
|
|
50
|
+
# @param error [Exception] processor error
|
|
51
|
+
# @param event [ChangeEvent, nil] event being processed
|
|
52
|
+
# @param metadata [Hash, EventMetadata] result metadata
|
|
53
|
+
# @return [ProcessorResult]
|
|
54
|
+
def self.failure: (untyped error, ?event: untyped?, ?metadata: ::Hash[untyped, untyped]) -> untyped
|
|
55
|
+
|
|
56
|
+
# Build a skipped result.
|
|
57
|
+
#
|
|
58
|
+
# @param event [ChangeEvent, nil] skipped event
|
|
59
|
+
# @param metadata [Hash, EventMetadata] result metadata
|
|
60
|
+
# @return [ProcessorResult]
|
|
61
|
+
def self.skipped: (?untyped? event, ?metadata: ::Hash[untyped, untyped]) -> untyped
|
|
62
|
+
|
|
63
|
+
# Build a processor result with an explicit status.
|
|
64
|
+
#
|
|
65
|
+
# @param status [#to_sym] result status
|
|
66
|
+
# @param event [ChangeEvent, nil] associated event
|
|
67
|
+
# @param error [Exception, nil] associated failure
|
|
68
|
+
# @param metadata [Hash, EventMetadata] result metadata
|
|
69
|
+
def initialize: (untyped status, ?event: untyped?, ?error: untyped?, ?metadata: ::Hash[untyped, untyped]) -> void
|
|
70
|
+
|
|
71
|
+
# @return [Boolean] true when status is :success
|
|
72
|
+
def success?: () -> untyped
|
|
73
|
+
|
|
74
|
+
# @return [Boolean] true when status is :failure
|
|
75
|
+
def failure?: () -> untyped
|
|
76
|
+
|
|
77
|
+
# @return [Boolean] true when status is :skipped
|
|
78
|
+
def skipped?: () -> untyped
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
end
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
module CDC
|
|
2
|
+
module Core
|
|
3
|
+
# Immutable group of change events committed in one transaction.
|
|
4
|
+
#
|
|
5
|
+
# TransactionEnvelope is useful when a downstream processor needs transaction
|
|
6
|
+
# boundaries instead of isolated row-level events. The contained events and
|
|
7
|
+
# metadata are Ractor-shareable when construction succeeds.
|
|
8
|
+
class TransactionEnvelope
|
|
9
|
+
@transaction_id: untyped
|
|
10
|
+
|
|
11
|
+
@events: untyped
|
|
12
|
+
|
|
13
|
+
@commit_lsn: untyped
|
|
14
|
+
|
|
15
|
+
@committed_at: untyped
|
|
16
|
+
|
|
17
|
+
@metadata: untyped
|
|
18
|
+
|
|
19
|
+
# @return [Object] transaction identifier
|
|
20
|
+
# @return [Array<ChangeEvent>] events committed by the transaction
|
|
21
|
+
# @return [String, nil] commit log sequence number
|
|
22
|
+
# @return [Time, nil] commit timestamp
|
|
23
|
+
# @return [EventMetadata] transaction metadata
|
|
24
|
+
attr_reader transaction_id: untyped
|
|
25
|
+
|
|
26
|
+
# @return [Object] transaction identifier
|
|
27
|
+
# @return [Array<ChangeEvent>] events committed by the transaction
|
|
28
|
+
# @return [String, nil] commit log sequence number
|
|
29
|
+
# @return [Time, nil] commit timestamp
|
|
30
|
+
# @return [EventMetadata] transaction metadata
|
|
31
|
+
attr_reader events: untyped
|
|
32
|
+
|
|
33
|
+
# @return [Object] transaction identifier
|
|
34
|
+
# @return [Array<ChangeEvent>] events committed by the transaction
|
|
35
|
+
# @return [String, nil] commit log sequence number
|
|
36
|
+
# @return [Time, nil] commit timestamp
|
|
37
|
+
# @return [EventMetadata] transaction metadata
|
|
38
|
+
attr_reader commit_lsn: untyped
|
|
39
|
+
|
|
40
|
+
# @return [Object] transaction identifier
|
|
41
|
+
# @return [Array<ChangeEvent>] events committed by the transaction
|
|
42
|
+
# @return [String, nil] commit log sequence number
|
|
43
|
+
# @return [Time, nil] commit timestamp
|
|
44
|
+
# @return [EventMetadata] transaction metadata
|
|
45
|
+
attr_reader committed_at: untyped
|
|
46
|
+
|
|
47
|
+
# @return [Object] transaction identifier
|
|
48
|
+
# @return [Array<ChangeEvent>] events committed by the transaction
|
|
49
|
+
# @return [String, nil] commit log sequence number
|
|
50
|
+
# @return [Time, nil] commit timestamp
|
|
51
|
+
# @return [EventMetadata] transaction metadata
|
|
52
|
+
attr_reader metadata: untyped
|
|
53
|
+
|
|
54
|
+
# Build a transaction envelope.
|
|
55
|
+
#
|
|
56
|
+
# @param transaction_id [Object] upstream transaction identifier
|
|
57
|
+
# @param events [Array<ChangeEvent>] committed events
|
|
58
|
+
# @param commit_lsn [#to_s, nil] commit log sequence number
|
|
59
|
+
# @param committed_at [Time, nil] commit timestamp
|
|
60
|
+
# @param metadata [Hash, EventMetadata] transaction metadata
|
|
61
|
+
def initialize: (transaction_id: untyped, events: untyped, ?commit_lsn: untyped?, ?committed_at: untyped?, ?metadata: ::Hash[untyped, untyped]) -> void
|
|
62
|
+
|
|
63
|
+
# Whether the envelope has no events.
|
|
64
|
+
#
|
|
65
|
+
# @return [Boolean]
|
|
66
|
+
def empty?: () -> untyped
|
|
67
|
+
|
|
68
|
+
# Number of events in the envelope.
|
|
69
|
+
#
|
|
70
|
+
# @return [Integer]
|
|
71
|
+
def size: () -> untyped
|
|
72
|
+
|
|
73
|
+
# Convert the transaction envelope into a Ractor-shareable hash.
|
|
74
|
+
#
|
|
75
|
+
# @return [Hash{String=>Object,nil}]
|
|
76
|
+
def to_h: () -> untyped
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
end
|
data/sig/cdc/core.rbs
CHANGED
|
@@ -1,6 +1,11 @@
|
|
|
1
|
-
|
|
1
|
+
# Top-level namespace for Change Data Capture libraries.
|
|
2
|
+
module CDC
|
|
3
|
+
# Database-agnostic Change Data Capture domain primitives.
|
|
4
|
+
#
|
|
5
|
+
# CDC::Core intentionally contains only lightweight runtime abstractions:
|
|
6
|
+
# events, metadata, processors, filters, pipelines, and processor results.
|
|
7
|
+
# Transport, PostgreSQL protocol parsing, and value decoding live in sibling
|
|
8
|
+
# gems so this layer can remain independently useful.
|
|
2
9
|
module Core
|
|
3
|
-
VERSION: String
|
|
4
|
-
# See the writing guide of rbs: https://github.com/ruby/rbs#guides
|
|
5
10
|
end
|
|
6
11
|
end
|
data/sig/cdc_core.rbs
ADDED
|
File without changes
|
metadata
CHANGED
|
@@ -1,15 +1,18 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: cdc-core
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.1.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Ken C. Demanawa
|
|
8
|
-
bindir:
|
|
8
|
+
bindir: bin
|
|
9
9
|
cert_chain: []
|
|
10
10
|
date: 1980-01-02 00:00:00.000000000 Z
|
|
11
11
|
dependencies: []
|
|
12
|
-
description:
|
|
12
|
+
description: 'CDC Core provides immutable, Ractor-safe Change Data Capture domain
|
|
13
|
+
objects, processor contracts, filters, and pipeline primitives.
|
|
14
|
+
|
|
15
|
+
'
|
|
13
16
|
email:
|
|
14
17
|
- kenneth.c.demanawa@gmail.com
|
|
15
18
|
executables: []
|
|
@@ -17,13 +20,36 @@ extensions: []
|
|
|
17
20
|
extra_rdoc_files: []
|
|
18
21
|
files:
|
|
19
22
|
- CHANGELOG.md
|
|
20
|
-
- CODE_OF_CONDUCT.md
|
|
21
23
|
- LICENSE.txt
|
|
22
24
|
- README.md
|
|
23
|
-
- Rakefile
|
|
24
25
|
- lib/cdc/core.rb
|
|
26
|
+
- lib/cdc/core/change_event.rb
|
|
27
|
+
- lib/cdc/core/column_change.rb
|
|
28
|
+
- lib/cdc/core/composite_processor.rb
|
|
29
|
+
- lib/cdc/core/errors.rb
|
|
30
|
+
- lib/cdc/core/event_metadata.rb
|
|
31
|
+
- lib/cdc/core/filter.rb
|
|
32
|
+
- lib/cdc/core/operation.rb
|
|
33
|
+
- lib/cdc/core/pipeline.rb
|
|
34
|
+
- lib/cdc/core/processor.rb
|
|
35
|
+
- lib/cdc/core/processor_result.rb
|
|
36
|
+
- lib/cdc/core/transaction_envelope.rb
|
|
25
37
|
- lib/cdc/core/version.rb
|
|
38
|
+
- lib/cdc_core.rb
|
|
26
39
|
- sig/cdc/core.rbs
|
|
40
|
+
- sig/cdc/core/change_event.rbs
|
|
41
|
+
- sig/cdc/core/column_change.rbs
|
|
42
|
+
- sig/cdc/core/composite_processor.rbs
|
|
43
|
+
- sig/cdc/core/errors.rbs
|
|
44
|
+
- sig/cdc/core/event_metadata.rbs
|
|
45
|
+
- sig/cdc/core/filter.rbs
|
|
46
|
+
- sig/cdc/core/operation.rbs
|
|
47
|
+
- sig/cdc/core/pipeline.rbs
|
|
48
|
+
- sig/cdc/core/processor.rbs
|
|
49
|
+
- sig/cdc/core/processor_result.rbs
|
|
50
|
+
- sig/cdc/core/transaction_envelope.rbs
|
|
51
|
+
- sig/cdc/core/version.rbs
|
|
52
|
+
- sig/cdc_core.rbs
|
|
27
53
|
homepage: https://github.com/kanutocd/cdc-core
|
|
28
54
|
licenses:
|
|
29
55
|
- MIT
|
|
@@ -31,6 +57,7 @@ metadata:
|
|
|
31
57
|
homepage_uri: https://github.com/kanutocd/cdc-core
|
|
32
58
|
source_code_uri: https://github.com/kanutocd/cdc-core
|
|
33
59
|
changelog_uri: https://github.com/kanutocd/cdc-core/blob/main/CHANGELOG.md
|
|
60
|
+
documentation_uri: https://kanutocd.github.io/cdc-core/
|
|
34
61
|
rubygems_mfa_required: 'true'
|
|
35
62
|
rdoc_options: []
|
|
36
63
|
require_paths:
|
|
@@ -46,7 +73,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
46
73
|
- !ruby/object:Gem::Version
|
|
47
74
|
version: '0'
|
|
48
75
|
requirements: []
|
|
49
|
-
rubygems_version:
|
|
76
|
+
rubygems_version: 3.6.9
|
|
50
77
|
specification_version: 4
|
|
51
|
-
summary:
|
|
78
|
+
summary: Database-agnostic Change Data Capture domain primitives for Ruby.
|
|
52
79
|
test_files: []
|
data/CODE_OF_CONDUCT.md
DELETED
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
# Code of Conduct
|
|
2
|
-
|
|
3
|
-
"cdc-core" follows [The Ruby Community Conduct Guideline](https://www.ruby-lang.org/en/conduct) in all "collaborative space", which is defined as community communications channels (such as mailing lists, submitted patches, commit comments, etc.):
|
|
4
|
-
|
|
5
|
-
* Participants will be tolerant of opposing views.
|
|
6
|
-
* Participants must ensure that their language and actions are free of personal attacks and disparaging personal remarks.
|
|
7
|
-
* When interpreting the words and actions of others, participants should always assume good intentions.
|
|
8
|
-
* Behaviour which can be reasonably considered harassment will not be tolerated.
|
|
9
|
-
|
|
10
|
-
If you have any concerns about behaviour within this project, please contact us at ["kenneth.c.demanawa@gmail.com"](mailto:"kenneth.c.demanawa@gmail.com").
|