Skip to main content

risingwave_meta_model/
object.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::common::PbObjectType;
16use sea_orm::entity::prelude::*;
17use serde::{Deserialize, Serialize};
18
19use crate::{DatabaseId, ObjectId, SchemaId, UserId};
20
21#[derive(
22    Clone, Debug, Hash, PartialEq, Eq, Copy, EnumIter, DeriveActiveEnum, Serialize, Deserialize,
23)]
24#[sea_orm(rs_type = "String", db_type = "string(None)")]
25pub enum ObjectType {
26    #[sea_orm(string_value = "DATABASE")]
27    Database,
28    #[sea_orm(string_value = "SCHEMA")]
29    Schema,
30    #[sea_orm(string_value = "TABLE")]
31    Table,
32    #[sea_orm(string_value = "SOURCE")]
33    Source,
34    #[sea_orm(string_value = "SINK")]
35    Sink,
36    #[sea_orm(string_value = "VIEW")]
37    View,
38    #[sea_orm(string_value = "INDEX")]
39    Index,
40    #[sea_orm(string_value = "FUNCTION")]
41    Function,
42    #[sea_orm(string_value = "CONNECTION")]
43    Connection,
44    #[sea_orm(string_value = "SUBSCRIPTION")]
45    Subscription,
46    #[sea_orm(string_value = "SECRET")]
47    Secret,
48}
49
50impl ObjectType {
51    pub fn as_str(&self) -> &'static str {
52        match self {
53            ObjectType::Database => "database",
54            ObjectType::Schema => "schema",
55            ObjectType::Table => "table",
56            ObjectType::Source => "source",
57            ObjectType::Sink => "sink",
58            ObjectType::View => "view",
59            ObjectType::Index => "index",
60            ObjectType::Function => "function",
61            ObjectType::Connection => "connection",
62            ObjectType::Subscription => "subscription",
63            ObjectType::Secret => "secret",
64        }
65    }
66}
67
68impl From<PbObjectType> for ObjectType {
69    fn from(pb_object_type: PbObjectType) -> Self {
70        match pb_object_type {
71            PbObjectType::Database => ObjectType::Database,
72            PbObjectType::Schema => ObjectType::Schema,
73            PbObjectType::Table | PbObjectType::Mview => ObjectType::Table,
74            PbObjectType::Source => ObjectType::Source,
75            PbObjectType::Sink => ObjectType::Sink,
76            PbObjectType::View => ObjectType::View,
77            PbObjectType::Index => ObjectType::Index,
78            PbObjectType::Function => ObjectType::Function,
79            PbObjectType::Connection => ObjectType::Connection,
80            PbObjectType::Subscription => ObjectType::Subscription,
81            PbObjectType::Secret => ObjectType::Secret,
82            PbObjectType::Unspecified => {
83                unreachable!("Unspecified object type")
84            }
85        }
86    }
87}
88
89#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, Serialize, Deserialize)]
90#[sea_orm(table_name = "object")]
91pub struct Model {
92    #[sea_orm(primary_key)]
93    pub oid: ObjectId,
94    pub obj_type: ObjectType,
95    pub owner_id: UserId,
96    pub schema_id: Option<SchemaId>,
97    pub database_id: Option<DatabaseId>,
98    /// The parent object this object belongs to. The self foreign key uses `ON DELETE CASCADE`.
99    ///
100    /// This is distinct from `object_dependency`, which records semantic references used for
101    /// dependency checks and `DROP ... CASCADE`. The belong-to rules are:
102    ///
103    /// - database: no parent;
104    /// - schema: its database;
105    /// - named schema objects, including indexes and subscriptions: their schema;
106    /// - associated sources: the relation they belong to;
107    /// - internal tables: their streaming job;
108    /// - implicit Iceberg sinks and sources: their Iceberg table.
109    ///
110    /// New objects derive `database_id` and `schema_id` from this parent in
111    /// `CatalogController::create_object`.
112    ///
113    /// Object-type validation and cycle prevention remain application responsibilities.
114    pub belong_to_oid: Option<ObjectId>,
115    pub initialized_at: DateTime,
116    pub created_at: DateTime,
117    pub initialized_at_cluster_version: Option<String>,
118    pub created_at_cluster_version: Option<String>,
119}
120
121#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
122pub enum Relation {
123    #[sea_orm(has_many = "super::connection::Entity")]
124    Connection,
125    #[sea_orm(has_many = "super::database::Entity")]
126    Database,
127    #[sea_orm(has_many = "super::fragment::Entity")]
128    Fragment,
129    #[sea_orm(has_many = "super::function::Entity")]
130    Function,
131    #[sea_orm(has_many = "super::index::Entity")]
132    Index,
133    #[sea_orm(
134        belongs_to = "Entity",
135        from = "Column::DatabaseId",
136        to = "Column::Oid",
137        on_update = "NoAction",
138        on_delete = "Cascade"
139    )]
140    SelfRef2,
141    #[sea_orm(
142        belongs_to = "Entity",
143        from = "Column::SchemaId",
144        to = "Column::Oid",
145        on_update = "NoAction",
146        on_delete = "Cascade"
147    )]
148    SelfRef1,
149    #[sea_orm(
150        belongs_to = "Entity",
151        from = "Column::BelongToOid",
152        to = "Column::Oid",
153        on_update = "NoAction",
154        on_delete = "Cascade"
155    )]
156    SelfRef3,
157    #[sea_orm(
158        belongs_to = "super::database::Entity",
159        from = "Column::DatabaseId",
160        to = "super::database::Column::DatabaseId",
161        on_update = "NoAction",
162        on_delete = "NoAction"
163    )]
164    Database2,
165    #[sea_orm(has_many = "super::schema::Entity")]
166    Schema,
167    #[sea_orm(has_many = "super::sink::Entity")]
168    Sink,
169    #[sea_orm(has_many = "super::subscription::Entity")]
170    Subscription,
171    #[sea_orm(has_many = "super::source::Entity")]
172    Source,
173    #[sea_orm(has_many = "super::table::Entity")]
174    Table,
175    #[sea_orm(has_many = "super::streaming_job::Entity")]
176    StreamingJob,
177    #[sea_orm(
178        belongs_to = "super::user::Entity",
179        from = "Column::OwnerId",
180        to = "super::user::Column::UserId",
181        on_update = "NoAction",
182        on_delete = "Cascade"
183    )]
184    User,
185    #[sea_orm(has_many = "super::user_privilege::Entity")]
186    UserPrivilege,
187    #[sea_orm(has_many = "super::view::Entity")]
188    View,
189    #[sea_orm(
190        belongs_to = "super::schema::Entity",
191        from = "Column::SchemaId",
192        to = "super::schema::Column::SchemaId",
193        on_update = "NoAction",
194        on_delete = "NoAction"
195    )]
196    Schema2,
197}
198
199impl Related<super::connection::Entity> for Entity {
200    fn to() -> RelationDef {
201        Relation::Connection.def()
202    }
203}
204
205impl Related<super::database::Entity> for Entity {
206    fn to() -> RelationDef {
207        Relation::Database.def()
208    }
209}
210
211impl Related<super::fragment::Entity> for Entity {
212    fn to() -> RelationDef {
213        Relation::Fragment.def()
214    }
215}
216
217impl Related<super::function::Entity> for Entity {
218    fn to() -> RelationDef {
219        Relation::Function.def()
220    }
221}
222
223impl Related<super::index::Entity> for Entity {
224    fn to() -> RelationDef {
225        Relation::Index.def()
226    }
227}
228
229impl Related<super::schema::Entity> for Entity {
230    fn to() -> RelationDef {
231        Relation::Schema.def()
232    }
233}
234
235impl Related<super::sink::Entity> for Entity {
236    fn to() -> RelationDef {
237        Relation::Sink.def()
238    }
239}
240
241impl Related<super::subscription::Entity> for Entity {
242    fn to() -> RelationDef {
243        Relation::Subscription.def()
244    }
245}
246
247impl Related<super::source::Entity> for Entity {
248    fn to() -> RelationDef {
249        Relation::Source.def()
250    }
251}
252
253impl Related<super::table::Entity> for Entity {
254    fn to() -> RelationDef {
255        Relation::Table.def()
256    }
257}
258
259impl Related<super::streaming_job::Entity> for Entity {
260    fn to() -> RelationDef {
261        Relation::StreamingJob.def()
262    }
263}
264
265impl Related<super::user::Entity> for Entity {
266    fn to() -> RelationDef {
267        Relation::User.def()
268    }
269}
270
271impl Related<super::user_privilege::Entity> for Entity {
272    fn to() -> RelationDef {
273        Relation::UserPrivilege.def()
274    }
275}
276
277impl Related<super::view::Entity> for Entity {
278    fn to() -> RelationDef {
279        Relation::View.def()
280    }
281}
282
283impl ActiveModelBehavior for ActiveModel {}