1use std::collections::{HashMap, HashSet};
16
17use risingwave_common::catalog::ColumnCatalog;
18use risingwave_common::id::JobId;
19use sea_orm::ConnectionTrait;
20
21use super::*;
22use crate::controller::utils::{
23 StreamingJobExtraInfo, get_database_resource_group, get_existing_job_resource_group,
24 get_streaming_job_extra_info as fetch_streaming_job_extra_info, get_table_columns,
25 load_streaming_jobs_by_ids,
26};
27
28impl CatalogController {
29 pub async fn get_secret_by_id(&self, secret_id: SecretId) -> MetaResult<PbSecret> {
30 let inner = self.inner.read().await;
31 let (secret, obj) = Secret::find_by_id(secret_id)
32 .find_also_related(Object)
33 .one(&inner.db)
34 .await?
35 .ok_or_else(|| MetaError::catalog_id_not_found("secret", secret_id))?;
36 Ok(ObjectModel(secret, obj.unwrap(), None).into())
37 }
38
39 pub async fn get_object_database_id(
40 &self,
41 object_id: impl Into<ObjectId>,
42 ) -> MetaResult<DatabaseId> {
43 let object_id = object_id.into();
44 let inner = self.inner.read().await;
45 let (database_id,): (Option<DatabaseId>,) = Object::find_by_id(object_id)
46 .select_only()
47 .select_column(object::Column::DatabaseId)
48 .into_tuple()
49 .one(&inner.db)
50 .await?
51 .ok_or_else(|| MetaError::catalog_id_not_found("object", object_id))?;
52 Ok(database_id.ok_or_else(|| anyhow!("object has no database id: {object_id}"))?)
53 }
54
55 pub async fn get_connection_by_id(
56 &self,
57 connection_id: ConnectionId,
58 ) -> MetaResult<PbConnection> {
59 let inner = self.inner.read().await;
60 let (conn, obj) = Connection::find_by_id(connection_id)
61 .find_also_related(Object)
62 .one(&inner.db)
63 .await?
64 .ok_or_else(|| MetaError::catalog_id_not_found("connection", connection_id))?;
65
66 Ok(ObjectModel(conn, obj.unwrap(), None).into())
67 }
68
69 pub async fn get_table_catalog_by_name(
70 &self,
71 database_id: DatabaseId,
72 schema_id: SchemaId,
73 name: &str,
74 ) -> MetaResult<Option<PbTable>> {
75 let inner = self.inner.read().await;
76 let table_obj = Table::find()
77 .find_also_related(Object)
78 .filter(
79 table::Column::Name
80 .eq(name)
81 .and(object::Column::DatabaseId.eq(database_id))
82 .and(object::Column::SchemaId.eq(schema_id)),
83 )
84 .one(&inner.db)
85 .await?;
86 if let Some((table, obj)) = table_obj {
87 let streaming_job = streaming_job::Entity::find_by_id(table.job_id())
88 .one(&inner.db)
89 .await?;
90 Ok(Some(ObjectModel(table, obj.unwrap(), streaming_job).into()))
91 } else {
92 Ok(None)
93 }
94 }
95
96 pub async fn get_table_by_name(
97 &self,
98 database_name: &str,
99 table_name: &str,
100 ) -> MetaResult<Option<PbTable>> {
101 let inner = self.inner.read().await;
102 let table_obj = Table::find()
103 .find_also_related(Object)
104 .join(JoinType::InnerJoin, object::Relation::Database2.def())
105 .filter(
106 table::Column::Name
107 .eq(table_name)
108 .and(database::Column::Name.eq(database_name)),
109 )
110 .one(&inner.db)
111 .await?;
112 if let Some((table, obj)) = table_obj {
113 let streaming_job = streaming_job::Entity::find_by_id(table.job_id())
114 .one(&inner.db)
115 .await?;
116 Ok(Some(ObjectModel(table, obj.unwrap(), streaming_job).into()))
117 } else {
118 Ok(None)
119 }
120 }
121
122 pub async fn get_table_associated_source_id(
123 &self,
124 table_id: TableId,
125 ) -> MetaResult<Option<SourceId>> {
126 let inner = self.inner.read().await;
127 Table::find_by_id(table_id)
128 .select_only()
129 .select_column(table::Column::OptionalAssociatedSourceId)
130 .into_tuple()
131 .one(&inner.db)
132 .await?
133 .ok_or_else(|| MetaError::catalog_id_not_found("table", table_id))
134 }
135
136 pub async fn get_table_by_associate_source_id(
137 &self,
138 associated_source_id: SourceId,
139 ) -> MetaResult<PbTable> {
140 let inner = self.inner.read().await;
141 let table_obj = Table::find()
142 .find_also_related(Object)
143 .filter(table::Column::OptionalAssociatedSourceId.eq(associated_source_id))
144 .one(&inner.db)
145 .await?
146 .ok_or_else(|| {
147 MetaError::catalog_id_not_found("table associated source", associated_source_id)
148 })?;
149 let (table, obj) = table_obj;
150 let streaming_job = streaming_job::Entity::find_by_id(table.job_id())
151 .one(&inner.db)
152 .await?;
153 Ok(ObjectModel(table, obj.unwrap(), streaming_job).into())
154 }
155
156 pub async fn get_table_by_id(&self, table_id: TableId) -> MetaResult<PbTable> {
157 let inner = self.inner.read().await;
158 let table_obj = Table::find_by_id(table_id)
159 .find_also_related(Object)
160 .one(&inner.db)
161 .await?;
162 if let Some((table, obj)) = table_obj {
163 let streaming_job = streaming_job::Entity::find_by_id(table.job_id())
164 .one(&inner.db)
165 .await?;
166 Ok(ObjectModel(table, obj.unwrap(), streaming_job).into())
167 } else {
168 Err(MetaError::catalog_id_not_found("table", table_id))
169 }
170 }
171
172 pub async fn get_user_created_table_by_ids(
173 &self,
174 job_ids: impl Iterator<Item = JobId>,
175 ) -> MetaResult<Vec<PbTable>> {
176 let inner = self.inner.read().await;
177 self.get_user_created_table_by_ids_in_txn(&inner.db, job_ids)
178 .await
179 }
180
181 pub async fn get_user_created_table_by_ids_in_txn<C>(
182 &self,
183 txn: &C,
184 job_ids: impl Iterator<Item = JobId>,
185 ) -> MetaResult<Vec<PbTable>>
186 where
187 C: ConnectionTrait,
188 {
189 let table_objs = Table::find()
190 .find_also_related(Object)
191 .filter(
192 table::Column::TableId
193 .is_in(job_ids.map(|job_id| job_id.as_mv_table_id()).collect_vec())
194 .and(table::Column::TableType.eq(TableType::Table)),
195 )
196 .all(txn)
197 .await?;
198 let streaming_jobs = streaming_job::Entity::find()
199 .filter(
200 streaming_job::Column::JobId.is_in(
201 table_objs
202 .iter()
203 .map(|(table, _)| table.job_id())
204 .collect_vec(),
205 ),
206 )
207 .all(txn)
208 .await?
209 .into_iter()
210 .map(|job| (job.job_id, job))
211 .collect::<HashMap<JobId, streaming_job::Model>>();
212 Ok(table_objs
213 .into_iter()
214 .map(|(table, obj)| {
215 let job_id = table.job_id();
216 let streaming_job = streaming_jobs.get(&job_id).cloned();
217 ObjectModel(table, obj.unwrap(), streaming_job).into()
218 })
219 .collect())
220 }
221
222 pub async fn get_table_by_ids(
223 &self,
224 table_ids: Vec<TableId>,
225 include_dropped_table: bool,
226 ) -> MetaResult<Vec<PbTable>> {
227 let inner = self.inner.read().await;
228 let table_objs = Table::find()
229 .find_also_related(Object)
230 .filter(table::Column::TableId.is_in(table_ids.clone()))
231 .all(&inner.db)
232 .await?;
233 let streaming_jobs = load_streaming_jobs_by_ids(
234 &inner.db,
235 table_objs.iter().map(|(table, _)| table.job_id()),
236 )
237 .await?;
238 let tables = table_objs.into_iter().map(|(table, obj)| {
239 let job_id = table.job_id();
240 let streaming_job = streaming_jobs.get(&job_id).cloned();
241 ObjectModel(table, obj.unwrap(), streaming_job).into()
242 });
243 let tables = if include_dropped_table {
244 tables
245 .chain(inner.dropped_tables.iter().filter_map(|(id, t)| {
246 if table_ids.contains(id) {
247 Some(t.clone())
248 } else {
249 None
250 }
251 }))
252 .collect()
253 } else {
254 tables.collect()
255 };
256 Ok(tables)
257 }
258
259 pub async fn get_table_columns(&self, id: TableId) -> MetaResult<Vec<ColumnCatalog>> {
260 let inner = self.inner.read().await;
261 Ok(get_table_columns(&inner.db, id)
262 .await?
263 .to_protobuf()
264 .into_iter()
265 .map(|col| col.into())
266 .collect())
267 }
268
269 pub async fn get_sink_by_id(&self, sink_id: SinkId) -> MetaResult<Option<PbSink>> {
270 let inner = self.inner.read().await;
271 inner.get_sink_by_id(sink_id).await
272 }
273
274 pub async fn get_sink_auto_refresh_schema_from(
275 &self,
276 table_id: TableId,
277 ) -> MetaResult<Vec<PbSink>> {
278 let inner = self.inner.read().await;
279 let sink_objs = Sink::find()
280 .find_also_related(Object)
281 .filter(sink::Column::AutoRefreshSchemaFromTable.eq(table_id))
282 .all(&inner.db)
283 .await?;
284 let streaming_jobs = load_streaming_jobs_by_ids(
285 &inner.db,
286 sink_objs.iter().map(|(sink, _)| sink.sink_id.as_job_id()),
287 )
288 .await?;
289 Ok(sink_objs
290 .into_iter()
291 .map(|(sink, obj)| {
292 let streaming_job = streaming_jobs.get(&sink.sink_id.as_job_id()).cloned();
293 ObjectModel(sink, obj.unwrap(), streaming_job).into()
294 })
295 .collect())
296 }
297
298 pub async fn get_sink_state_table_ids(&self, sink_id: SinkId) -> MetaResult<Vec<TableId>> {
299 let inner = self.inner.read().await;
300 let tables: Vec<I32Array> = Fragment::find()
301 .select_only()
302 .column(fragment::Column::StateTableIds)
303 .filter(fragment::Column::JobId.eq(sink_id))
304 .into_tuple()
305 .all(&inner.db)
306 .await?;
307 Ok(tables
308 .into_iter()
309 .flat_map(|ids| {
310 ids.into_inner()
311 .into_iter()
312 .map(|table_id| TableId::new(table_id as _))
313 })
314 .collect())
315 }
316
317 pub async fn get_subscription_by_id(
318 &self,
319 subscription_id: SubscriptionId,
320 ) -> MetaResult<PbSubscription> {
321 let inner = self.inner.read().await;
322 let subscription_objs = Subscription::find()
323 .find_also_related(Object)
324 .filter(subscription::Column::SubscriptionId.eq(subscription_id))
325 .all(&inner.db)
326 .await?;
327 let subscription: PbSubscription = subscription_objs
328 .into_iter()
329 .map(|(subscription, obj)| ObjectModel(subscription, obj.unwrap(), None).into())
330 .find_or_first(|_| true)
331 .ok_or_else(|| anyhow!("cannot find subscription with id {}", subscription_id))?;
332
333 Ok(subscription)
334 }
335
336 pub async fn get_mv_depended_subscriptions(
337 &self,
338 database_id: Option<DatabaseId>,
339 ) -> MetaResult<HashMap<TableId, HashMap<SubscriptionId, u64>>> {
340 let inner = self.inner.read().await;
341 let select = Subscription::find()
342 .select_only()
343 .select_column(subscription::Column::SubscriptionId)
344 .select_column(subscription::Column::DependentTableId)
345 .select_column(subscription::Column::RetentionSeconds);
346 let select = if let Some(database_id) = database_id {
347 select
348 .join(JoinType::InnerJoin, subscription::Relation::Object.def())
349 .filter(object::Column::DatabaseId.eq(database_id))
350 } else {
351 select
352 };
353 let subscription_objs: Vec<(SubscriptionId, TableId, i64)> =
354 select.into_tuple().all(&inner.db).await?;
355 let mut map: HashMap<_, HashMap<_, _>> = HashMap::new();
356 for (subscription_id, dependent_table_id, retention_seconds) in subscription_objs {
358 map.entry(dependent_table_id)
359 .or_default()
360 .insert(subscription_id, retention_seconds as _);
361 }
362 Ok(map)
363 }
364
365 pub async fn get_all_table_options(&self) -> MetaResult<HashMap<TableId, TableOption>> {
366 let inner = self.inner.read().await;
367 let table_options: Vec<(TableId, Option<i32>)> = Table::find()
368 .select_only()
369 .columns([table::Column::TableId, table::Column::RetentionSeconds])
370 .into_tuple::<(TableId, Option<i32>)>()
371 .all(&inner.db)
372 .await?;
373
374 Ok(table_options
375 .into_iter()
376 .map(|(id, retention_seconds)| {
377 (
378 id,
379 TableOption {
380 retention_seconds: retention_seconds.map(|i| i.try_into().unwrap()),
381 },
382 )
383 })
384 .collect())
385 }
386
387 pub async fn get_all_streaming_parallelisms(
388 &self,
389 ) -> MetaResult<HashMap<ObjectId, StreamingParallelism>> {
390 let inner = self.inner.read().await;
391
392 let job_parallelisms = StreamingJob::find()
393 .select_only()
394 .columns([
395 streaming_job::Column::JobId,
396 streaming_job::Column::Parallelism,
397 ])
398 .into_tuple::<(ObjectId, StreamingParallelism)>()
399 .all(&inner.db)
400 .await?;
401
402 Ok(job_parallelisms
403 .into_iter()
404 .collect::<HashMap<ObjectId, StreamingParallelism>>())
405 }
406
407 pub async fn get_table_name_type_mapping(
408 &self,
409 ) -> MetaResult<HashMap<TableId, (String, String)>> {
410 let inner = self.inner.read().await;
411 let table_name_types: Vec<(TableId, String, TableType)> = Table::find()
412 .select_only()
413 .columns([
414 table::Column::TableId,
415 table::Column::Name,
416 table::Column::TableType,
417 ])
418 .into_tuple()
419 .all(&inner.db)
420 .await?;
421 Ok(table_name_types
422 .into_iter()
423 .map(|(id, name, table_type)| {
424 (
425 id,
426 (name, PbTableType::from(table_type).as_str_name().to_owned()),
427 )
428 })
429 .collect())
430 }
431
432 pub async fn get_table_by_cdc_table_id(
433 &self,
434 cdc_table_id: &String,
435 ) -> MetaResult<Vec<PbTable>> {
436 let inner = self.inner.read().await;
437 let table_objs = Table::find()
438 .find_also_related(Object)
439 .filter(table::Column::CdcTableId.eq(cdc_table_id))
440 .all(&inner.db)
441 .await?;
442 let streaming_jobs = load_streaming_jobs_by_ids(
443 &inner.db,
444 table_objs.iter().map(|(table, _)| table.job_id()),
445 )
446 .await?;
447 Ok(table_objs
448 .into_iter()
449 .map(|(table, obj)| {
450 let job_id = table.job_id();
451 let streaming_job = streaming_jobs.get(&job_id).cloned();
452 ObjectModel(table, obj.unwrap(), streaming_job).into()
453 })
454 .collect())
455 }
456
457 pub async fn get_created_table_ids(&self) -> MetaResult<Vec<TableId>> {
458 let inner = self.inner.read().await;
459
460 let mut table_ids: Vec<TableId> = StreamingJob::find()
462 .select_only()
463 .column(streaming_job::Column::JobId)
464 .filter(streaming_job::Column::JobStatus.eq(JobStatus::Created))
465 .into_tuple()
466 .all(&inner.db)
467 .await?;
468
469 let internal_table_ids: Vec<TableId> = Table::find()
471 .select_only()
472 .column(table::Column::TableId)
473 .filter(table::Column::BelongsToJobId.is_in(table_ids.clone()))
474 .into_tuple()
475 .all(&inner.db)
476 .await?;
477 table_ids.extend(internal_table_ids);
478
479 Ok(table_ids)
480 }
481
482 pub async fn get_versioned_table_schemas(
485 &self,
486 ) -> MetaResult<HashMap<risingwave_common::catalog::TableId, Vec<i32>>> {
487 let res = self
488 .list_all_state_tables()
489 .await?
490 .into_iter()
491 .filter_map(|t| {
492 if t.version.is_some() {
493 let ret = (
494 t.id,
495 t.columns
496 .iter()
497 .map(|c| c.column_desc.as_ref().unwrap().column_id)
498 .collect_vec(),
499 );
500 return Some(ret);
501 }
502 None
503 })
504 .collect();
505 Ok(res)
506 }
507
508 pub async fn get_existing_job_resource_group(
509 &self,
510 streaming_job_id: JobId,
511 ) -> MetaResult<String> {
512 let inner = self.inner.read().await;
513 get_existing_job_resource_group(&inner.db, streaming_job_id).await
514 }
515
516 pub async fn get_database_resource_group(&self, database_id: DatabaseId) -> MetaResult<String> {
517 let inner = self.inner.read().await;
518 get_database_resource_group(&inner.db, database_id).await
519 }
520
521 pub async fn get_existing_job_resource_groups(
522 &self,
523 streaming_job_ids: Vec<JobId>,
524 ) -> MetaResult<HashMap<JobId, String>> {
525 let inner = self.inner.read().await;
526 let mut resource_groups = HashMap::new();
527 for job_id in streaming_job_ids {
528 let resource_group = get_existing_job_resource_group(&inner.db, job_id).await?;
529 resource_groups.insert(job_id, resource_group);
530 }
531
532 Ok(resource_groups)
533 }
534
535 pub async fn get_existing_job_database_resource_group(
536 &self,
537 streaming_job_id: JobId,
538 ) -> MetaResult<String> {
539 let inner = self.inner.read().await;
540 let database_id: DatabaseId = StreamingJob::find_by_id(streaming_job_id)
541 .select_only()
542 .join(JoinType::InnerJoin, streaming_job::Relation::Object.def())
543 .column(object::Column::DatabaseId)
544 .into_tuple()
545 .one(&inner.db)
546 .await?
547 .ok_or_else(|| MetaError::catalog_id_not_found("streaming job", streaming_job_id))?;
548
549 get_database_resource_group(&inner.db, database_id).await
550 }
551
552 pub async fn get_job_streaming_parallelisms(
553 &self,
554 streaming_job_id: JobId,
555 ) -> MetaResult<StreamingParallelism> {
556 let inner = self.inner.read().await;
557
558 let job_parallelism: StreamingParallelism = StreamingJob::find_by_id(streaming_job_id)
559 .select_only()
560 .column(streaming_job::Column::Parallelism)
561 .into_tuple()
562 .one(&inner.db)
563 .await?
564 .ok_or_else(|| MetaError::catalog_id_not_found("streaming job", streaming_job_id))?;
565
566 Ok(job_parallelism)
567 }
568
569 pub async fn get_job_parallelisms(
570 &self,
571 streaming_job_id: JobId,
572 ) -> MetaResult<
573 Option<(
574 StreamingParallelism,
575 Option<String>,
576 Option<StreamingParallelism>,
577 Option<String>,
578 )>,
579 > {
580 let inner = self.inner.read().await;
581
582 let parallelisms = StreamingJob::find_by_id(streaming_job_id)
583 .select_only()
584 .columns([
585 streaming_job::Column::Parallelism,
586 streaming_job::Column::AdaptiveParallelismStrategy,
587 streaming_job::Column::BackfillParallelism,
588 streaming_job::Column::BackfillAdaptiveParallelismStrategy,
589 ])
590 .into_tuple::<(
591 StreamingParallelism,
592 Option<String>,
593 Option<StreamingParallelism>,
594 Option<String>,
595 )>()
596 .one(&inner.db)
597 .await?;
598
599 Ok(parallelisms)
600 }
601
602 pub async fn get_fragment_streaming_job_id(
603 &self,
604 fragment_id: FragmentId,
605 ) -> MetaResult<JobId> {
606 let inner = self.inner.read().await;
607 let job_id: JobId = Fragment::find_by_id(fragment_id)
608 .select_only()
609 .column(fragment::Column::JobId)
610 .into_tuple()
611 .one(&inner.db)
612 .await?
613 .ok_or_else(|| MetaError::catalog_id_not_found("fragment", fragment_id))?;
614 Ok(job_id)
615 }
616
617 pub async fn list_streaming_job_with_database(
618 &self,
619 ) -> MetaResult<HashMap<DatabaseId, Vec<JobId>>> {
620 let inner = self.inner.read().await;
621 let database_objects: Vec<(DatabaseId, JobId)> = StreamingJob::find()
622 .select_only()
623 .column(object::Column::DatabaseId)
624 .column(streaming_job::Column::JobId)
625 .join(JoinType::LeftJoin, streaming_job::Relation::Object.def())
626 .into_tuple()
627 .all(&inner.db)
628 .await?;
629
630 Ok(database_objects.into_iter().into_group_map())
631 }
632
633 pub async fn list_table_objects(
635 &self,
636 ) -> MetaResult<Vec<(TableId, String, String, String, String, TableType)>> {
637 let inner = self.inner.read().await;
638 Ok(Object::find()
639 .select_only()
640 .join(JoinType::InnerJoin, object::Relation::Table.def())
641 .join(JoinType::InnerJoin, object::Relation::Database2.def())
642 .join(JoinType::InnerJoin, object::Relation::Schema2.def())
643 .column(object::Column::Oid)
644 .column(database::Column::Name)
645 .column(schema::Column::Name)
646 .column(table::Column::Name)
647 .column(database::Column::ResourceGroup)
648 .column(table::Column::TableType)
649 .into_tuple()
650 .all(&inner.db)
651 .await?)
652 }
653
654 pub async fn list_source_objects(
656 &self,
657 ) -> MetaResult<Vec<(TableId, String, String, String, String)>> {
658 let inner = self.inner.read().await;
659 Ok(Object::find()
660 .select_only()
661 .join(JoinType::InnerJoin, object::Relation::Source.def())
662 .join(JoinType::InnerJoin, object::Relation::Database2.def())
663 .join(JoinType::InnerJoin, object::Relation::Schema2.def())
664 .column(object::Column::Oid)
665 .column(database::Column::Name)
666 .column(schema::Column::Name)
667 .column(source::Column::Name)
668 .column(database::Column::ResourceGroup)
669 .into_tuple()
670 .all(&inner.db)
671 .await?)
672 }
673
674 pub async fn list_sink_objects(
676 &self,
677 ) -> MetaResult<Vec<(TableId, String, String, String, String)>> {
678 let inner = self.inner.read().await;
679 Ok(Object::find()
680 .select_only()
681 .join(JoinType::InnerJoin, object::Relation::Sink.def())
682 .join(JoinType::InnerJoin, object::Relation::Database2.def())
683 .join(JoinType::InnerJoin, object::Relation::Schema2.def())
684 .column(object::Column::Oid)
685 .column(database::Column::Name)
686 .column(schema::Column::Name)
687 .column(sink::Column::Name)
688 .column(database::Column::ResourceGroup)
689 .into_tuple()
690 .all(&inner.db)
691 .await?)
692 }
693
694 pub async fn list_relation_objects_by_ids(
696 &self,
697 ids: &HashSet<ObjectId>,
698 ) -> MetaResult<Vec<(ObjectId, String, String, String, String)>> {
699 if ids.is_empty() {
700 return Ok(vec![]);
701 }
702 let inner = self.inner.read().await;
703 let ids: Vec<_> = ids.iter().cloned().collect();
704
705 let tables: Vec<(ObjectId, String, String, String, TableType)> = Object::find()
706 .select_only()
707 .join(JoinType::InnerJoin, object::Relation::Table.def())
708 .join(JoinType::InnerJoin, object::Relation::Database2.def())
709 .join(JoinType::InnerJoin, object::Relation::Schema2.def())
710 .filter(object::Column::Oid.is_in(ids.clone()))
711 .column(object::Column::Oid)
712 .column(database::Column::Name)
713 .column(schema::Column::Name)
714 .column(table::Column::Name)
715 .column(table::Column::TableType)
716 .into_tuple()
717 .all(&inner.db)
718 .await?;
719
720 let sources: Vec<(ObjectId, String, String, String)> = Object::find()
721 .select_only()
722 .join(JoinType::InnerJoin, object::Relation::Source.def())
723 .join(JoinType::InnerJoin, object::Relation::Database2.def())
724 .join(JoinType::InnerJoin, object::Relation::Schema2.def())
725 .filter(object::Column::Oid.is_in(ids.clone()))
726 .column(object::Column::Oid)
727 .column(database::Column::Name)
728 .column(schema::Column::Name)
729 .column(source::Column::Name)
730 .into_tuple()
731 .all(&inner.db)
732 .await?;
733
734 let mut result = Vec::with_capacity(tables.len() + sources.len());
735 result.extend(
736 tables
737 .into_iter()
738 .map(|(id, db, schema, name, table_type)| {
739 let relation_type = PbTableType::from(table_type).as_str_name();
740 (id, db, schema, name, relation_type.to_owned())
741 }),
742 );
743 result.extend(
744 sources
745 .into_iter()
746 .map(|(id, db, schema, name)| (id, db, schema, name, "source".to_owned())),
747 );
748 Ok(result)
749 }
750
751 pub async fn get_streaming_job_status(&self, streaming_job_id: JobId) -> MetaResult<JobStatus> {
752 let inner = self.inner.read().await;
753 let status = StreamingJob::find_by_id(streaming_job_id)
754 .select_only()
755 .column(streaming_job::Column::JobStatus)
756 .into_tuple()
757 .one(&inner.db)
758 .await?
759 .ok_or_else(|| MetaError::catalog_id_not_found("streaming job", streaming_job_id))?;
760 Ok(status)
761 }
762
763 pub async fn get_streaming_job_extra_info(
764 &self,
765 job_ids: Vec<JobId>,
766 ) -> MetaResult<HashMap<JobId, StreamingJobExtraInfo>> {
767 let inner = self.inner.read().await;
768 let txn = inner.db.begin().await?;
769
770 self.get_streaming_job_extra_info_in_txn(&txn, job_ids)
771 .await
772 }
773
774 pub async fn get_streaming_job_extra_info_in_txn<C>(
775 &self,
776 txn: &C,
777 job_ids: Vec<JobId>,
778 ) -> MetaResult<HashMap<JobId, StreamingJobExtraInfo>>
779 where
780 C: ConnectionTrait,
781 {
782 fetch_streaming_job_extra_info(txn, job_ids).await
783 }
784}
785
786impl CatalogControllerInner {
787 pub(crate) async fn get_sink_by_id(&self, sink_id: SinkId) -> MetaResult<Option<PbSink>> {
788 let sink_objs = Sink::find_by_id(sink_id)
789 .find_also_related(Object)
790 .one(&self.db)
791 .await?;
792 if let Some((sink, obj)) = sink_objs {
793 let streaming_job = streaming_job::Entity::find_by_id(sink.sink_id.as_job_id())
794 .one(&self.db)
795 .await?;
796 Ok(Some(ObjectModel(sink, obj.unwrap(), streaming_job).into()))
797 } else {
798 Ok(None)
799 }
800 }
801}