turbine_rb 0.1.1 → 0.1.2

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: da43639e3f731f3d00c53ed1e5dfd30b905d74549d3b5a8ce6c21604091c9dc2
4
- data.tar.gz: 57fcd45315e4eaa26eb21bcc78478ff7a07afce5ac04ec6eafe351104fd82a37
3
+ metadata.gz: 0adaff81024cca99dc5d4b043e98e3fe6a69f29d5d9ee2fd312c66ede6840f4c
4
+ data.tar.gz: c702105c5d3b5672bab440ac16beef7ff0c4497147b66cee1f9dad2cce31bbf6
5
5
  SHA512:
6
- metadata.gz: 397f59b0c96496fa4e2e84386f0d885040ba0878e68da94c8e871689753b004ca8618821d8c570a41bca61b5514d8509a8c185aab25fac89a9de267f39c6d904
7
- data.tar.gz: 745c1cb5eaf39a45e5eb460b27f0211e1f4e813d71018b26c2751a26806be85ad3f602de3496f5bc5a32d7cf153829f9a8621ac648e05864b02ae61f33501b8a
6
+ metadata.gz: 5ea6a41d9686349f4f02d90ac74b653a08ddf693feb12453e7a056a077982ae8dbdec792209acc2e24263e5e576762266a8d37ecebc0329815e028b26fdd5cc1
7
+ data.tar.gz: 3d473b1e102a17b9b247977bbccb5617bb4a7d861e6584035e00ab406032b83e31363ea769d525c15faccd2ce573cabd82ed2473c267ee770c164905aa50a31b
data/CHANGELOG.md CHANGED
@@ -1,4 +1,9 @@
1
+ ## [0.1.2] - 2022-12-02
2
+
3
+ - fix: add record interface to local run
4
+
1
5
  ## [0.1.1] - 2022-12-01
6
+
2
7
  - fix: dockerfile entrypoint
3
8
 
4
9
  ## [0.1.0] - 2022-11-30
@@ -6,48 +6,59 @@ require "turbine_rb"
6
6
 
7
7
  class MyApp
8
8
  def call(app)
9
+ # To configure resources for your production datastores
10
+ # on Meroxa, use the Dashboard, CLI, or Terraform Provider
11
+ # For more details refer to: http://docs.meroxa.com/
12
+ #
13
+ # Identify the upstream datastore with the `resource` function
14
+ # Replace `demopg` with the resource name configured on Meroxa
9
15
  database = app.resource(name: "demopg")
10
16
 
11
- # ELT pipeline example
12
- # records = database.records(collection: 'events')
13
- # database.write(records: records, collection: 'events_copy')
14
-
15
- # procedural API
16
- records = database.records(collection: "events")
17
+ # Specify which upstream records to pull
18
+ # with the `records` function
19
+ # Replace `collection_name` with a table, collection,
20
+ # or bucket name in your data store.
21
+ # If a configuration is needed for your source,
22
+ # you can pass it as a second argument to the `records` function. For example:
23
+ # database.records(collection: "collection_name", configs: {"incrementing.column.name" => "id"})
24
+ records = database.records(collection: "collection_name")
17
25
 
18
- # This register the secret to be available in the turbine application
19
- app.register_secrets("MY_ENV_TEST")
26
+ # Register secrets to be available in the function:
27
+ # app.register_secrets("MY_ENV_TEST")
20
28
 
21
- # you can also register several secrets at once
29
+ # Register several secrets at once:
22
30
  # app.register_secrets(["MY_ENV_TEST", "MY_OTHER_ENV_TEST"])
23
31
 
24
- # Passthrough just has to match the signature
32
+ # Specify the code to execute against `records` with the `process` function.
33
+ # Replace `Passthrough` with your desired function.
34
+ # Ensure desired function matches `Passthrough`'s' function signature.
25
35
  processed_records = app.process(records: records, process: Passthrough.new)
26
- database.write(records: processed_records, collection: "events_copy")
27
-
28
- # out_records = processed_records.join(records, key: "user_id", window: 1.day) # stream joins
29
36
 
30
- # chaining API
31
- # database.records(collection: "events").
32
- # process_with(process: Passthrough.new).
33
- # write_to(resource: database, collection: "events_copy")
37
+ # Specify where to write records using the `write` function.
38
+ # Replace `collection_archive` with whatever data organisation method
39
+ # is relevant to the datastore (e.g., table, bucket, collection, etc.)
40
+ # If additional connector configs are needed, provided another argument. For example:
41
+ # database.write(
42
+ # records: processed_records,
43
+ # collection: "collection_archive",
44
+ # configs: {"behavior.on.null.values": "ignore"})
45
+ database.write(records: processed_records, collection: "collection_archive")
34
46
  end
35
47
  end
36
48
 
37
- # might be useful to signal that this is a special Turbine call
38
49
  class Passthrough < TurbineRb::Process
39
50
  def call(records:)
40
51
  puts "got records: #{records}"
41
- # to get the value of unformatted records, use record .value getter method
52
+ # To get the value of unformatted records, use record .value getter method
42
53
  # records.map { |r| puts r.value }
43
54
  #
44
- # to transform unformatted records, use record .value setter method
55
+ # To transform unformatted records, use record .value setter method
45
56
  # records.map { |r| r.value = "newdata" }
46
57
  #
47
- # to get the value of json formatted records, use record .get method
58
+ # To get the value of json formatted records, use record .get method
48
59
  # records.map { |r| puts r.get("message") }
49
60
  #
50
- # to transform json formatted records, use record .set methods
61
+ # To transform json formatted records, use record .set methods
51
62
  # records.map { |r| r.set('message', 'goodbye') }
52
63
  records
53
64
  end
@@ -27,7 +27,9 @@ module TurbineRb
27
27
 
28
28
  req = TurbineCore::ProcessCollectionRequest.new(collection: unwrapped_records, process: pr)
29
29
  @core_server.add_process_to_collection(req)
30
- records.pb_collection = process.call(records: records.pb_collection) unless @is_recording
30
+ records_interface = TurbineRb::Records.new(unwrapped_records.records)
31
+ processed_records = process.call(records: records_interface) unless @is_recording
32
+ records.pb_collection = processed_records.map(&:serialize_core_record) unless @is_recording
31
33
 
32
34
  records
33
35
  end
@@ -4,6 +4,7 @@ require "json"
4
4
  require "hash_dot"
5
5
 
6
6
  module TurbineRb
7
+ # rubocop:disable Metrics/ClassLength
7
8
  class Record
8
9
  attr_accessor :key, :value, :timestamp
9
10
 
@@ -21,41 +22,32 @@ module TurbineRb
21
22
  end
22
23
 
23
24
  def serialize
24
- Io::Meroxa::Funtime::Record.new(key: @key, value: @value.to_json, timestamp: @timestamp)
25
+ Io::Meroxa::Funtime::Record.new(key: @key, value: serialize_value, timestamp: @timestamp)
26
+ end
27
+
28
+ def serialize_core_record
29
+ TurbineCore::Record.new(key: @key, value: serialize_value, timestamp: @timestamp)
25
30
  end
26
31
 
27
32
  def get(key)
28
33
  if value_string? || value_array?
29
34
  @value
30
- elsif cdc_format?
31
- @value.send("payload.after.#{key}")
32
35
  else
33
- @value.send("payload.#{key}")
36
+ @value.send(payload_key(key))
34
37
  end
35
38
  end
36
39
 
37
40
  def set(key, value)
38
- if !value_hash?
39
- @value = value
40
- else
41
- payload_key = cdc_format? ? "payload.after" : "payload"
42
-
43
- begin
44
- @value.send("#{payload_key}.#{key}")
45
- rescue NoMethodError
46
- schema = @value.send("schema.fields")
47
- new_schema_field = { field: key, optional: true, type: "string" }.to_dot
48
-
49
- if cdc_format?
50
- schema_fields = schema.find { |f| f.field == "after" }
51
- schema_fields.fields.unshift(new_schema_field)
52
- else
53
- schema.unshift(new_schema_field)
54
- end
55
- end
56
-
57
- @value.send("#{payload_key}.#{key}=", value)
41
+ @value = value unless value_hash?
42
+ return unless value_hash?
43
+
44
+ begin
45
+ @value.send(payload_key(key))
46
+ rescue NoMethodError
47
+ set_schema_field(key, value)
58
48
  end
49
+
50
+ @value.send("#{payload_key(key)}=", value)
59
51
  end
60
52
 
61
53
  def unwrap!
@@ -87,6 +79,16 @@ module TurbineRb
87
79
  @value.is_a?(Hash)
88
80
  end
89
81
 
82
+ def payload_key(prop_key)
83
+ if cdc_format?
84
+ "payload.after.#{prop_key}"
85
+ elsif json_schema?
86
+ "payload.#{prop_key}"
87
+ else
88
+ prop_key
89
+ end
90
+ end
91
+
90
92
  def json_schema?
91
93
  value_hash? &&
92
94
  @value.key?("payload") &&
@@ -112,7 +114,24 @@ module TurbineRb
112
114
  "unsupported"
113
115
  end
114
116
  end
117
+
118
+ def set_schema_field(key, value)
119
+ schema = @value.send("schema.fields")
120
+ new_schema_field = { field: key, optional: true, type: type_of_value(value) }.to_dot
121
+
122
+ schema.find { |f| f.field == "after" }.fields.unshift(new_schema_field) if cdc_format?
123
+ schema.unshift(new_schema_field) if json_schema?
124
+ end
125
+
126
+ def serialize_value
127
+ if value_string?
128
+ @value
129
+ else
130
+ @value.to_json
131
+ end
132
+ end
115
133
  end
134
+ # rubocop:enable Metrics/ClassLength
116
135
 
117
136
  class Records < SimpleDelegator
118
137
  def initialize(pb_records)
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module TurbineRb
4
- VERSION = "0.1.1"
4
+ VERSION = "0.1.2"
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: turbine_rb
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.1.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Meroxa
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-12-01 00:00:00.000000000 Z
11
+ date: 2022-12-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: grpc