turbine_rb 0.1.1 → 0.1.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: da43639e3f731f3d00c53ed1e5dfd30b905d74549d3b5a8ce6c21604091c9dc2
4
- data.tar.gz: 57fcd45315e4eaa26eb21bcc78478ff7a07afce5ac04ec6eafe351104fd82a37
3
+ metadata.gz: 400b81da43fa55a94e4d85544197b6cfca8eeeff18d7db8cfb351abacc07c518
4
+ data.tar.gz: 480a684b89b0a8ab8ec9cca5d1a314d144f6760b097a011db84aae006eb457b1
5
5
  SHA512:
6
- metadata.gz: 397f59b0c96496fa4e2e84386f0d885040ba0878e68da94c8e871689753b004ca8618821d8c570a41bca61b5514d8509a8c185aab25fac89a9de267f39c6d904
7
- data.tar.gz: 745c1cb5eaf39a45e5eb460b27f0211e1f4e813d71018b26c2751a26806be85ad3f602de3496f5bc5a32d7cf153829f9a8621ac648e05864b02ae61f33501b8a
6
+ metadata.gz: cc55f7f0ba4310bddd702d95d8feb9d7c5bf16fe7856eba58f6301af6d6a75504af8c615f53ac71edf7e30333594cdbc8a91707af1596c2508d7580c32ab0e8e
7
+ data.tar.gz: c59f54f06f4cc0538ff3c17607871f104fb1d43e9083cb4ec1da11b2cb2ebb4a7426c0b03135dc9dd0a1e4b2d3fda823307502dba1b08a1eba6e8049503bfbaa
data/CHANGELOG.md CHANGED
@@ -1,4 +1,13 @@
1
+ ## [0.1.3] - 2022-12-03
2
+
3
+ - fix: set new keys on unformatted json
4
+
5
+ ## [0.1.2] - 2022-12-02
6
+
7
+ - fix: add record interface to local run
8
+
1
9
  ## [0.1.1] - 2022-12-01
10
+
2
11
  - fix: dockerfile entrypoint
3
12
 
4
13
  ## [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,34 @@ 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"
41
+ @value = value unless value_hash?
42
+ return @value unless value_hash?
42
43
 
44
+ if json_schema?
43
45
  begin
44
- @value.send("#{payload_key}.#{key}")
46
+ @value.send(payload_key(key))
45
47
  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
48
+ set_schema_field(key, value)
55
49
  end
56
-
57
- @value.send("#{payload_key}.#{key}=", value)
58
50
  end
51
+
52
+ @value.send("#{payload_key(key)}=", value)
59
53
  end
60
54
 
61
55
  def unwrap!
@@ -87,6 +81,16 @@ module TurbineRb
87
81
  @value.is_a?(Hash)
88
82
  end
89
83
 
84
+ def payload_key(prop_key)
85
+ if cdc_format?
86
+ "payload.after.#{prop_key}"
87
+ elsif json_schema?
88
+ "payload.#{prop_key}"
89
+ else
90
+ prop_key
91
+ end
92
+ end
93
+
90
94
  def json_schema?
91
95
  value_hash? &&
92
96
  @value.key?("payload") &&
@@ -112,7 +116,24 @@ module TurbineRb
112
116
  "unsupported"
113
117
  end
114
118
  end
119
+
120
+ def set_schema_field(key, value)
121
+ schema = @value.send("schema.fields")
122
+ new_schema_field = { field: key, optional: true, type: type_of_value(value) }.to_dot
123
+
124
+ schema.find { |f| f.field == "after" }.fields.unshift(new_schema_field) if cdc_format?
125
+ schema.unshift(new_schema_field) if json_schema?
126
+ end
127
+
128
+ def serialize_value
129
+ if value_string?
130
+ @value
131
+ else
132
+ @value.to_json
133
+ end
134
+ end
115
135
  end
136
+ # rubocop:enable Metrics/ClassLength
116
137
 
117
138
  class Records < SimpleDelegator
118
139
  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.3"
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.3
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