1
0
mirror of synced 2026-01-03 06:02:23 -05:00
Files
airbyte/airbyte-integrations/connectors/source-mongodb/lib/airbyte_protocol.rb
Yury Koleda b1061e32d9 🎉 Add MongoDB Source
Signed-off-by: fut <fut.wrk@gmail.com>
2021-03-08 14:27:14 -08:00

463 lines
12 KiB
Ruby

# The file was generated in several steps.
#
# 1. Convert airbyte_protocol.yaml to JSON
# 2. Use https://app.quicktype.io/?l=ruby to generate code. Parameters:
# Type strictness: Coercible
# Plain types only: Disabled
# 3. Fix module `Types` according to https://dry-rb.org/gems/dry-types/master/built-in-types/
# 4. Replace all instance variable calls to just method calls (remove all characters)
# 4. Add `.compact` call to resulting object in every `to_dynamic` method
#
#
#
# This code may look unusually verbose for Ruby (and it is), but
# it performs some subtle and complex validation of JSON data.
#
# To parse this JSON, add 'dry-struct' and 'dry-types' gems, then do:
#
# airbyte = Airbyte.from_json! "{…}"
# puts airbyte.configured_airbyte_catalog&.streams.first.stream.supported_sync_modes&.first
#
# If from_json! succeeds, the value returned matches the schema.
require 'json'
require 'dry-types'
require 'dry-struct'
module Types
include Dry::Types()
Int = Coercible::Integer
Bool = Strict::Bool
Hash = Coercible::Hash
String = Coercible::String
Type = Coercible::String.enum("CATALOG", "CONNECTION_STATUS", "LOG", "RECORD", "SPEC", "STATE")
SyncMode = Coercible::String.enum("full_refresh", "incremental")
Status = Coercible::String.enum("FAILED", "SUCCEEDED")
Level = Coercible::String.enum("DEBUG", "ERROR", "FATAL", "INFO", "TRACE", "WARN")
end
# Message type
module Type
Catalog = "CATALOG"
ConnectionStatus = "CONNECTION_STATUS"
Log = "LOG"
Record = "RECORD"
Spec = "SPEC"
State = "STATE"
end
module SyncMode
FullRefresh = "full_refresh"
Incremental = "incremental"
end
class AirbyteStream < Dry::Struct
# Path to the field that will be used to determine if a record is new or modified since the
# last sync. If not provided by the source, the end user will have to specify the
# comparable themselves.
attribute :default_cursor_field, Types.Array(Types::String).optional
# Stream schema using Json Schema specs.
attribute :json_schema, Types::Hash.meta(of: Types::Any)
# Stream's name.
attribute :airbyte_stream_name, Types::String
# If the source defines the cursor field, then it does any other cursor field inputs will
# be ignored. If it does not either the user_provided one is used or as a backup the
# default one is used.
attribute :source_defined_cursor, Types::Bool.optional
attribute :supported_sync_modes, Types.Array(Types::SyncMode).optional
def self.from_dynamic!(d)
d = Types::Hash[d]
new(
default_cursor_field: d["default_cursor_field"],
json_schema: Types::Hash[d.fetch("json_schema")].map { |k, v| [k, Types::Any[v]] }.to_h,
airbyte_stream_name: d.fetch("name"),
source_defined_cursor: d["source_defined_cursor"],
supported_sync_modes: d["supported_sync_modes"],
)
end
def self.from_json!(json)
from_dynamic!(JSON.parse(json))
end
def to_dynamic
{
"default_cursor_field" => default_cursor_field,
"json_schema" => json_schema,
"name" => airbyte_stream_name,
"source_defined_cursor" => source_defined_cursor,
"supported_sync_modes" => supported_sync_modes,
}.compact
end
def to_json(options = nil)
JSON.generate(to_dynamic, options)
end
end
# log message: any kind of logging you want the platform to know about.
#
# Airbyte stream schema catalog
class AirbyteCatalog < Dry::Struct
attribute :streams, Types.Array(AirbyteStream)
def self.from_dynamic!(d)
d = Types::Hash[d]
new(
streams: d.fetch("streams").map { |x| AirbyteStream.from_dynamic!(x) },
)
end
def self.from_json!(json)
from_dynamic!(JSON.parse(json))
end
def to_dynamic
{
"streams" => streams.map { |x| x.to_dynamic },
}.compact
end
def to_json(options = nil)
JSON.generate(to_dynamic, options)
end
end
module Status
Failed = "FAILED"
Succeeded = "SUCCEEDED"
end
# Airbyte connection status
class AirbyteConnectionStatus < Dry::Struct
attribute :message, Types::String.optional
attribute :status, Types::Status
def self.from_dynamic!(d)
d = Types::Hash[d]
new(
message: d["message"],
status: d.fetch("status"),
)
end
def self.from_json!(json)
from_dynamic!(JSON.parse(json))
end
def to_dynamic
{
"message" => message,
"status" => status,
}.compact
end
def to_json(options = nil)
JSON.generate(to_dynamic, options)
end
end
# the type of logging
module Level
Debug = "DEBUG"
Error = "ERROR"
Fatal = "FATAL"
Info = "INFO"
Trace = "TRACE"
Warn = "WARN"
end
# log message: any kind of logging you want the platform to know about.
class AirbyteLogMessage < Dry::Struct
# the type of logging
attribute :level, Types::Level
# the log message
attribute :message, Types::String
def self.from_dynamic!(d)
d = Types::Hash[d]
new(
level: d.fetch("level"),
message: d.fetch("message"),
)
end
def self.from_json!(json)
from_dynamic!(JSON.parse(json))
end
def to_dynamic
{
"level" => level,
"message" => message,
}.compact
end
def to_json(options = nil)
JSON.generate(to_dynamic, options)
end
end
# record message: the record
class AirbyteRecordMessage < Dry::Struct
# the record data
attribute :data, Types::Hash.meta(of: Types::Any)
# when the data was emitted from the source. epoch in millisecond.
attribute :emitted_at, Types::Int
# the name of the stream for this record
attribute :stream, Types::String
def self.from_dynamic!(d)
d = Types::Hash[d]
new(
data: Types::Hash[d.fetch("data")].map { |k, v| [k, Types::Any[v]] }.to_h,
emitted_at: d.fetch("emitted_at"),
stream: d.fetch("stream"),
)
end
def self.from_json!(json)
from_dynamic!(JSON.parse(json))
end
def to_dynamic
{
"data" => data,
"emitted_at" => emitted_at,
"stream" => stream,
}.compact
end
def to_json(options = nil)
JSON.generate(to_dynamic, options)
end
end
# Specification of a connector (source/destination)
class ConnectorSpecification < Dry::Struct
attribute :changelog_url, Types::String.optional
# ConnectorDefinition specific blob. Must be a valid JSON string.
attribute :connection_specification, Types::Hash.meta(of: Types::Any)
attribute :documentation_url, Types::String.optional
# If the connector supports incremental mode or not.
attribute :supports_incremental, Types::Bool.optional
def self.from_dynamic!(d)
d = Types::Hash[d]
new(
changelog_url: d["changelogUrl"],
connection_specification: Types::Hash[d.fetch("connectionSpecification")].map { |k, v| [k, Types::Any[v]] }.to_h,
documentation_url: d["documentationUrl"],
supports_incremental: d["supportsIncremental"],
)
end
def self.from_json!(json)
from_dynamic!(JSON.parse(json))
end
def to_dynamic
{
"changelogUrl" => changelog_url,
"connectionSpecification" => connection_specification,
"documentationUrl" => documentation_url,
"supportsIncremental" => supports_incremental,
}.compact
end
def to_json(options = nil)
JSON.generate(to_dynamic, options)
end
end
# schema message: the state. Must be the last message produced. The platform uses this
# information
class AirbyteStateMessage < Dry::Struct
# the state data
attribute :data, Types::Hash.meta(of: Types::Any)
def self.from_dynamic!(d)
d = Types::Hash[d]
new(
data: Types::Hash[d.fetch("data")].map { |k, v| [k, Types::Any[v]] }.to_h,
)
end
def self.from_json!(json)
from_dynamic!(JSON.parse(json))
end
def to_dynamic
{
"data" => data,
}.compact
end
def to_json(options = nil)
JSON.generate(to_dynamic, options)
end
end
class AirbyteMessage < Dry::Struct
# log message: any kind of logging you want the platform to know about.
attribute :catalog, AirbyteCatalog.optional
attribute :connection_status, AirbyteConnectionStatus.optional
# log message: any kind of logging you want the platform to know about.
attribute :log, AirbyteLogMessage.optional
# record message: the record
attribute :record, AirbyteRecordMessage.optional
attribute :spec, ConnectorSpecification.optional
# schema message: the state. Must be the last message produced. The platform uses this
# information
attribute :state, AirbyteStateMessage.optional
# Message type
attribute :airbyte_message_type, Types::Type
def self.from_dynamic!(d)
d = Types::Hash[d]
new(
catalog: d["catalog"] ? AirbyteCatalog.from_dynamic!(d["catalog"]) : nil,
connection_status: d["connectionStatus"] ? AirbyteConnectionStatus.from_dynamic!(d["connectionStatus"]) : nil,
log: d["log"] ? AirbyteLogMessage.from_dynamic!(d["log"]) : nil,
record: d["record"] ? AirbyteRecordMessage.from_dynamic!(d["record"]) : nil,
spec: d["spec"] ? ConnectorSpecification.from_dynamic!(d["spec"]) : nil,
state: d["state"] ? AirbyteStateMessage.from_dynamic!(d["state"]) : nil,
airbyte_message_type: d.fetch("type"),
)
end
def self.from_json!(json)
from_dynamic!(JSON.parse(json))
end
def to_dynamic
{
"catalog" => catalog&.to_dynamic,
"connectionStatus" => connection_status&.to_dynamic,
"log" => log&.to_dynamic,
"record" => record&.to_dynamic,
"spec" => spec&.to_dynamic,
"state" => state&.to_dynamic,
"type" => airbyte_message_type,
}.compact
end
def to_json(options = nil)
JSON.generate(to_dynamic, options)
end
end
class ConfiguredAirbyteStream < Dry::Struct
# Path to the field that will be used to determine if a record is new or modified since the
# last sync. This field is REQUIRED if `sync_mode` is `incremental`. Otherwise it is
# ignored.
attribute :cursor_field, Types.Array(Types::String).optional
attribute :stream, AirbyteStream
attribute :sync_mode, Types::SyncMode.optional
def self.from_dynamic!(d)
d = Types::Hash[d]
new(
cursor_field: d["cursor_field"],
stream: AirbyteStream.from_dynamic!(d.fetch("stream")),
sync_mode: d["sync_mode"],
)
end
def self.from_json!(json)
from_dynamic!(JSON.parse(json))
end
def to_dynamic
{
"cursor_field" => cursor_field,
"stream" => stream.to_dynamic,
"sync_mode" => sync_mode,
}.compact
end
def to_json(options = nil)
JSON.generate(to_dynamic, options)
end
end
# Airbyte stream schema catalog
class ConfiguredAirbyteCatalog < Dry::Struct
attribute :streams, Types.Array(ConfiguredAirbyteStream)
def self.from_dynamic!(d)
d = Types::Hash[d]
new(
streams: d.fetch("streams").map { |x| ConfiguredAirbyteStream.from_dynamic!(x) },
)
end
def self.from_json!(json)
from_dynamic!(JSON.parse(json))
end
def to_dynamic
{
"streams" => streams.map { |x| x.to_dynamic },
}.compact
end
def to_json(options = nil)
JSON.generate(to_dynamic, options)
end
end
# AirbyteProtocol structs
class Airbyte < Dry::Struct
attribute :airbyte_message, AirbyteMessage.optional
attribute :configured_airbyte_catalog, ConfiguredAirbyteCatalog.optional
def self.from_dynamic!(d)
d = Types::Hash[d]
new(
airbyte_message: d["airbyte_message"] ? AirbyteMessage.from_dynamic!(d["airbyte_message"]) : nil,
configured_airbyte_catalog: d["configured_airbyte_catalog"] ? ConfiguredAirbyteCatalog.from_dynamic!(d["configured_airbyte_catalog"]) : nil,
)
end
def self.from_json!(json)
from_dynamic!(JSON.parse(json))
end
def to_dynamic
{
"airbyte_message" => airbyte_message&.to_dynamic,
"configured_airbyte_catalog" => configured_airbyte_catalog&.to_dynamic,
}.compact
end
def to_json(options = nil)
JSON.generate(to_dynamic, options)
end
end