omni_orchestrator/schemas/v1/db/queries/
deployment.rs1use anyhow::Context;
3use sqlx::{MySql, Pool};
4
5use libomni::types::db::v1 as types;
6use types::deployment::Deployment;
7
8pub async fn list_deployments(pool: &Pool<MySql>, page: i64, per_page: i64) -> anyhow::Result<Vec<Deployment>> {
10 println!("Attempting to fetch deployments from database...");
11
12 let result = sqlx::query_as::<_, Deployment>(
13 r#"
14 SELECT *
15 FROM deployments
16 ORDER BY created_at DESC
17 LIMIT ? OFFSET ?
18 "#,
19 )
20 .bind(per_page)
21 .bind(page * per_page)
22 .fetch_all(pool)
23 .await;
24
25 match result {
26 Ok(deployments) => {
27 println!("Successfully fetched {} deployments", deployments.len());
28 Ok(deployments)
29 }
30 Err(e) => {
31 eprintln!("Error fetching deployments: {:#?}", e);
32 Err(anyhow::Error::new(e).context("Failed to fetch deployments"))
33 }
34 }
35}
36
37pub async fn count_deployments(pool: &Pool<MySql>) -> anyhow::Result<i64> {
39 let count = sqlx::query_scalar::<_, i64>("SELECT COUNT(*) FROM deployments")
40 .fetch_one(pool)
41 .await
42 .context("Failed to count deployments")?;
43
44 Ok(count)
45}
46
47pub async fn get_deployment_by_id(pool: &Pool<MySql>, id: i64) -> anyhow::Result<Deployment> {
49 let deployment = sqlx::query_as::<_, Deployment>("SELECT * FROM deployments WHERE id = ?")
50 .bind(id)
51 .fetch_one(pool)
52 .await
53 .context("Failed to fetch deployment")?;
54
55 Ok(deployment)
56}
57
58pub async fn list_deployments_by_app(
60 pool: &Pool<MySql>,
61 app_id: i64,
62 page: i64,
63 per_page: i64
64) -> anyhow::Result<Vec<Deployment>> {
65 let deployments = sqlx::query_as::<_, Deployment>(
66 "SELECT * FROM deployments WHERE app_id = ? ORDER BY created_at DESC LIMIT ? OFFSET ?"
67 )
68 .bind(app_id)
69 .bind(per_page)
70 .bind(page * per_page)
71 .fetch_all(pool)
72 .await
73 .context("Failed to fetch app deployments")?;
74
75 Ok(deployments)
76}
77
78pub async fn count_deployments_by_app(pool: &Pool<MySql>, app_id: i64) -> anyhow::Result<i64> {
80 let count = sqlx::query_scalar::<_, i64>(
81 "SELECT COUNT(*) FROM deployments WHERE app_id = ?"
82 )
83 .bind(app_id)
84 .fetch_one(pool)
85 .await
86 .context("Failed to count deployments by app_id")?;
87
88 Ok(count)
89}
90
91pub async fn create_deployment(
93 pool: &Pool<MySql>,
94 app_id: i64,
95 build_id: i64,
96 version: &str,
97 deployment_strategy: &str,
98 previous_deployment_id: Option<i64>,
99 canary_percentage: Option<i64>,
100 environment_variables: Option<serde_json::Value>,
101 annotations: Option<serde_json::Value>,
102 labels: Option<serde_json::Value>,
103 created_by: Option<i64>,
104) -> anyhow::Result<Deployment> {
105 let mut tx = pool.begin().await?;
107
108 let deployment = sqlx::query_as::<_, Deployment>(
110 r#"INSERT INTO deployments (
111 app_id, build_id, version, status, deployment_strategy,
112 previous_deployment_id, canary_percentage, environment_variables,
113 annotations, labels, created_at, created_by
114 ) VALUES (?, ?, ?, 'pending', ?, ?, ?, ?, ?, ?, CURRENT_TIMESTAMP, ?)"#,
115 )
116 .bind(app_id)
117 .bind(build_id)
118 .bind(version)
119 .bind(deployment_strategy)
120 .bind(previous_deployment_id)
121 .bind(canary_percentage)
122 .bind(environment_variables)
123 .bind(annotations)
124 .bind(labels)
125 .bind(created_by)
126 .fetch_one(&mut *tx)
127 .await
128 .context("Failed to create deployment")?;
129
130 tx.commit().await?;
132
133 Ok(deployment)
135}
136
137pub async fn update_deployment_status(
139 pool: &Pool<MySql>,
140 id: i64,
141 status: &str,
142 error_message: Option<&str>,
143) -> anyhow::Result<Deployment> {
144 let mut tx = pool.begin().await?;
145
146 let deployment = match status {
148 "in_progress" => {
149 sqlx::query_as::<_, Deployment>(
150 "UPDATE deployments SET status = ?, started_at = CURRENT_TIMESTAMP WHERE id = ?"
151 )
152 .bind(status)
153 .bind(id)
154 .fetch_one(&mut *tx)
155 .await
156 },
157 "deployed" | "failed" | "canceled" => {
158 sqlx::query_as::<_, Deployment>(
159 "UPDATE deployments SET status = ?, completed_at = CURRENT_TIMESTAMP,
160 deployment_duration = TIMESTAMPDIFF(SECOND, started_at, CURRENT_TIMESTAMP),
161 error_message = ? WHERE id = ?"
162 )
163 .bind(status)
164 .bind(error_message)
165 .bind(id)
166 .fetch_one(&mut *tx)
167 .await
168 },
169 _ => {
170 sqlx::query_as::<_, Deployment>(
171 "UPDATE deployments SET status = ? WHERE id = ?"
172 )
173 .bind(status)
174 .bind(id)
175 .fetch_one(&mut *tx)
176 .await
177 }
178 }.context("Failed to update deployment status")?;
179
180 tx.commit().await?;
181 Ok(deployment)
182}
183
184pub async fn delete_deployment(pool: &Pool<MySql>, id: i64) -> anyhow::Result<()> {
186 let mut tx = pool.begin().await?;
187
188 sqlx::query("DELETE FROM deployments WHERE id = ?")
189 .bind(id)
190 .execute(&mut *tx)
191 .await
192 .context("Failed to delete deployment")?;
193
194 tx.commit().await?;
195 Ok(())
196}