risingwave_meta_model/
sink.rs

1// Copyright 2024 RisingWave Labs
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15use risingwave_pb::catalog::{PbSink, PbSinkType};
16use sea_orm::ActiveValue::Set;
17use sea_orm::entity::prelude::*;
18use serde::{Deserialize, Serialize};
19
20use crate::{
21    ColumnCatalogArray, ColumnOrderArray, ConnectionId, I32Array, Property, SecretRef,
22    SinkFormatDesc, SinkId, TableId,
23};
24
25#[derive(Clone, Debug, PartialEq, Eq, EnumIter, DeriveActiveEnum, Serialize, Deserialize)]
26#[sea_orm(rs_type = "String", db_type = "string(None)")]
27pub enum SinkType {
28    #[sea_orm(string_value = "APPEND_ONLY")]
29    AppendOnly,
30    #[sea_orm(string_value = "UPSERT")]
31    Upsert,
32    #[sea_orm(string_value = "RETRACT")]
33    Retract,
34}
35
36impl From<SinkType> for PbSinkType {
37    fn from(sink_type: SinkType) -> Self {
38        match sink_type {
39            SinkType::AppendOnly => Self::AppendOnly,
40            SinkType::Upsert => Self::Upsert,
41            SinkType::Retract => Self::Retract,
42        }
43    }
44}
45
46impl From<PbSinkType> for SinkType {
47    fn from(sink_type: PbSinkType) -> Self {
48        match sink_type {
49            // `ForceAppendOnly` is now denoted by `AppendOnly` + `ignore_delete`.
50            PbSinkType::AppendOnly | PbSinkType::ForceAppendOnly => Self::AppendOnly,
51            PbSinkType::Upsert => Self::Upsert,
52            PbSinkType::Retract => Self::Retract,
53            PbSinkType::Unspecified => unreachable!("Unspecified sink type"),
54        }
55    }
56}
57
58#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, Serialize, Deserialize)]
59#[sea_orm(table_name = "sink")]
60pub struct Model {
61    #[sea_orm(primary_key, auto_increment = false)]
62    pub sink_id: SinkId,
63    pub name: String,
64    pub columns: ColumnCatalogArray,
65    pub plan_pk: ColumnOrderArray,
66    pub distribution_key: I32Array,
67    pub downstream_pk: I32Array,
68    pub sink_type: SinkType,
69    pub ignore_delete: bool,
70    pub properties: Property,
71    pub definition: String,
72    pub connection_id: Option<ConnectionId>,
73    pub db_name: String,
74    pub sink_from_name: String,
75    pub sink_format_desc: Option<SinkFormatDesc>,
76    pub target_table: Option<TableId>,
77    // `secret_ref` stores the mapping info mapping from property name to secret id and type.
78    pub secret_ref: Option<SecretRef>,
79    pub original_target_columns: Option<ColumnCatalogArray>,
80    pub auto_refresh_schema_from_table: Option<TableId>,
81}
82
83#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
84pub enum Relation {
85    #[sea_orm(
86        belongs_to = "super::connection::Entity",
87        from = "Column::ConnectionId",
88        to = "super::connection::Column::ConnectionId",
89        on_update = "NoAction",
90        on_delete = "NoAction"
91    )]
92    Connection,
93    #[sea_orm(
94        belongs_to = "super::object::Entity",
95        from = "Column::SinkId",
96        to = "super::object::Column::Oid",
97        on_update = "NoAction",
98        on_delete = "Cascade"
99    )]
100    Object,
101}
102
103impl Related<super::connection::Entity> for Entity {
104    fn to() -> RelationDef {
105        Relation::Connection.def()
106    }
107}
108
109impl Related<super::object::Entity> for Entity {
110    fn to() -> RelationDef {
111        Relation::Object.def()
112    }
113}
114
115impl ActiveModelBehavior for ActiveModel {}
116
117impl From<PbSink> for ActiveModel {
118    fn from(pb_sink: PbSink) -> Self {
119        let sink_type = pb_sink.sink_type();
120        let ignore_delete = pb_sink.ignore_delete();
121
122        Self {
123            sink_id: Set(pb_sink.id),
124            name: Set(pb_sink.name),
125            columns: Set(pb_sink.columns.into()),
126            plan_pk: Set(pb_sink.plan_pk.into()),
127            distribution_key: Set(pb_sink.distribution_key.into()),
128            downstream_pk: Set(pb_sink.downstream_pk.into()),
129            sink_type: Set(sink_type.into()),
130            ignore_delete: Set(ignore_delete),
131            properties: Set(pb_sink.properties.into()),
132            definition: Set(pb_sink.definition),
133            connection_id: Set(pb_sink.connection_id),
134            db_name: Set(pb_sink.db_name),
135            sink_from_name: Set(pb_sink.sink_from_name),
136            sink_format_desc: Set(pb_sink.format_desc.as_ref().map(|x| x.into())),
137            target_table: Set(pb_sink.target_table),
138            secret_ref: Set(Some(SecretRef::from(pb_sink.secret_refs))),
139            original_target_columns: Set(Some(pb_sink.original_target_columns.into())),
140            auto_refresh_schema_from_table: Set(pb_sink.auto_refresh_schema_from_table),
141        }
142    }
143}