systemprompt_database/repository/service/
listing.rs1use systemprompt_identifiers::{InstanceId, ServiceName};
7use systemprompt_manifest::services::{ServiceModule, ServiceStatus};
8
9use super::model::{ServiceConfig, ServiceRow, into_configs};
10use super::repo::ServiceRepository;
11use crate::error::DatabaseResult;
12
13impl ServiceRepository {
14 pub async fn list_all_agent_service_names(&self) -> DatabaseResult<Vec<ServiceName>> {
15 let rows = sqlx::query!(
16 r#"SELECT name FROM services WHERE instance_id = $1 AND module_name = 'agent'"#,
17 self.instance_id.as_str()
18 )
19 .fetch_all(&*self.pool)
20 .await?;
21 Ok(rows.into_iter().map(|r| ServiceName::new(r.name)).collect())
22 }
23
24 pub async fn list_mcp_services(&self) -> DatabaseResult<Vec<ServiceConfig>> {
25 self.list_services_by_type(ServiceModule::Mcp).await
26 }
27
28 pub async fn list_all_running_services(&self) -> DatabaseResult<Vec<ServiceConfig>> {
29 let rows = sqlx::query_as!(
30 ServiceRow,
31 r#"
32 SELECT instance_id as "instance_id: InstanceId", name, module_name, status, pid, port, binary_mtime,
33 heartbeat_at::text as "heartbeat_at!",
34 created_at::text as "created_at!", updated_at::text as "updated_at!"
35 FROM services
36 WHERE instance_id = $1 AND status = $2
37 ORDER BY name
38 "#,
39 self.instance_id.as_str(),
40 ServiceStatus::Running.as_str()
41 )
42 .fetch_all(&*self.pool)
43 .await?;
44 into_configs(rows)
45 }
46
47 pub async fn list_running_services_by_module(
48 &self,
49 module_name: ServiceModule,
50 ) -> DatabaseResult<Vec<ServiceConfig>> {
51 let rows = sqlx::query_as!(
52 ServiceRow,
53 r#"
54 SELECT instance_id as "instance_id: InstanceId", name, module_name, status, pid, port, binary_mtime,
55 heartbeat_at::text as "heartbeat_at!",
56 created_at::text as "created_at!", updated_at::text as "updated_at!"
57 FROM services
58 WHERE instance_id = $1 AND module_name = $2 AND status = $3
59 ORDER BY name
60 "#,
61 self.instance_id.as_str(),
62 module_name.as_str(),
63 ServiceStatus::Running.as_str()
64 )
65 .fetch_all(&*self.pool)
66 .await?;
67 into_configs(rows)
68 }
69
70 pub async fn count_running_services(
71 &self,
72 module_name: ServiceModule,
73 ) -> DatabaseResult<usize> {
74 let row = sqlx::query!(
75 r#"SELECT COUNT(*) as "count!" FROM services
76 WHERE instance_id = $1 AND module_name = $2 AND status = $3"#,
77 self.instance_id.as_str(),
78 module_name.as_str(),
79 ServiceStatus::Running.as_str()
80 )
81 .fetch_one(&*self.pool)
82 .await?;
83 Ok(usize::try_from(row.count).unwrap_or(0))
84 }
85
86 pub async fn list_running_services_with_pid(&self) -> DatabaseResult<Vec<ServiceConfig>> {
87 self.list_all_running_services().await
88 }
89
90 pub async fn list_services_by_type(
91 &self,
92 module_name: ServiceModule,
93 ) -> DatabaseResult<Vec<ServiceConfig>> {
94 let rows = sqlx::query_as!(
95 ServiceRow,
96 r#"
97 SELECT instance_id as "instance_id: InstanceId", name, module_name, status, pid, port, binary_mtime,
98 heartbeat_at::text as "heartbeat_at!",
99 created_at::text as "created_at!", updated_at::text as "updated_at!"
100 FROM services
101 WHERE instance_id = $1 AND module_name = $2
102 ORDER BY name
103 "#,
104 self.instance_id.as_str(),
105 module_name.as_str()
106 )
107 .fetch_all(&*self.pool)
108 .await?;
109 into_configs(rows)
110 }
111}