Good start to multi-window

This commit is contained in:
Gregory Schier
2023-03-28 18:29:40 -07:00
parent 4f501abb72
commit 4c22215ca5
20 changed files with 771 additions and 517 deletions

View File

@@ -18,14 +18,16 @@ use reqwest::redirect::Policy;
use sqlx::{Pool, Sqlite};
use sqlx::migrate::Migrator;
use sqlx::sqlite::SqlitePoolOptions;
use sqlx::types::Json;
use tauri::{AppHandle, Menu, MenuItem, State, Submenu, Wry};
use sqlx::types::{Json};
use tauri::{AppHandle, Menu, MenuItem, State, Submenu, TitleBarStyle, Window, Wry};
use tauri::{CustomMenuItem, Manager, SystemTray, SystemTrayEvent, SystemTrayMenu, WindowEvent};
use tauri::regex::Regex;
use tokio::sync::Mutex;
use window_ext::WindowExt;
use crate::models::generate_id;
mod models;
mod runtime;
mod window_ext;
@@ -60,18 +62,18 @@ async fn migrate_db(
#[tauri::command]
async fn send_ephemeral_request(
request: models::HttpRequest,
app_handle: AppHandle<Wry>,
window: Window<Wry>,
db_instance: State<'_, Mutex<Pool<Sqlite>>>,
) -> Result<models::HttpResponse, String> {
let pool = &*db_instance.lock().await;
let response = models::HttpResponse::default();
return actually_send_ephemeral_request(request, response, app_handle, pool).await;
return actually_send_ephemeral_request(request, response, window, pool).await;
}
async fn actually_send_ephemeral_request(
request: models::HttpRequest,
mut response: models::HttpResponse,
app_handle: AppHandle<Wry>,
window: Window<Wry>,
pool: &Pool<Sqlite>,
) -> Result<models::HttpResponse, String> {
let start = std::time::Instant::now();
@@ -131,8 +133,8 @@ async fn actually_send_ephemeral_request(
headers.insert(header_name, header_value);
}
let m =
Method::from_bytes(request.method.to_uppercase().as_bytes()).expect("Failed to create method");
let m = Method::from_bytes(request.method.to_uppercase().as_bytes())
.expect("Failed to create method");
let builder = client.request(m, url_string.to_string()).headers(headers);
let sendable_req_result = match (request.body, request.body_type) {
@@ -143,13 +145,13 @@ async fn actually_send_ephemeral_request(
let sendable_req = match sendable_req_result {
Ok(r) => r,
Err(e) => {
return response_err(response, e.to_string(), app_handle, pool).await;
return response_err(response, e.to_string(), window, pool).await;
}
};
let resp = client.execute(sendable_req).await;
let p = app_handle
let p = window.app_handle()
.path_resolver()
.resolve_resource("plugins/plugin.ts")
.expect("failed to resolve resource");
@@ -172,19 +174,19 @@ async fn actually_send_ephemeral_request(
response.url = v.url().to_string();
response.body = v.text().await.expect("Failed to get body");
response.elapsed = start.elapsed().as_millis() as i64;
response = models::update_response_if_id(response, pool)
response = models::update_response_if_id(response, window.label(), pool)
.await
.expect("Failed to update response");
app_handle.emit_all("updated_response", &response).unwrap();
window.app_handle().emit_all("updated_response", &response).unwrap();
Ok(response)
}
Err(e) => response_err(response, e.to_string(), app_handle, pool).await,
Err(e) => response_err(response, e.to_string(), window, pool).await,
}
}
#[tauri::command]
async fn send_request(
app_handle: AppHandle<Wry>,
window: Window<Wry>,
db_instance: State<'_, Mutex<Pool<Sqlite>>>,
request_id: &str,
) -> Result<(), String> {
@@ -194,26 +196,26 @@ async fn send_request(
.await
.expect("Failed to get request");
let response = models::create_response(&req.id, 0, "", 0, None, "", vec![], pool)
let response = models::create_response(&req.id, 0, "", 0, None, "", vec![], window.label(), pool)
.await
.expect("Failed to create response");
app_handle.emit_all("updated_response", &response).unwrap();
window.app_handle().emit_all("updated_response", &response).unwrap();
actually_send_ephemeral_request(req, response, app_handle, pool).await?;
actually_send_ephemeral_request(req, response, window, pool).await?;
Ok(())
}
async fn response_err(
mut response: models::HttpResponse,
error: String,
app_handle: AppHandle<Wry>,
window: Window<Wry>,
pool: &Pool<Sqlite>,
) -> Result<models::HttpResponse, String> {
response.error = Some(error.clone());
response = models::update_response_if_id(response, pool)
response = models::update_response_if_id(response, window.label(), pool)
.await
.expect("Failed to update response");
app_handle.emit_all("updated_response", &response).unwrap();
window.app_handle().emit_all("updated_response", &response).unwrap();
Ok(response)
}
@@ -237,10 +239,9 @@ async fn set_key_value(
db_instance: State<'_, Mutex<Pool<Sqlite>>>,
) -> Result<(), String> {
let pool = &*db_instance.lock().await;
let created_key_value =
models::set_key_value(namespace, key, value, pool)
.await
.expect("Failed to create key value");
let created_key_value = models::set_key_value(namespace, key, value, pool)
.await
.expect("Failed to create key value");
app_handle
.emit_all("updated_key_value", &created_key_value)
@@ -252,14 +253,16 @@ async fn set_key_value(
#[tauri::command]
async fn create_workspace(
name: &str,
app_handle: AppHandle<Wry>,
window: Window<Wry>,
db_instance: State<'_, Mutex<Pool<Sqlite>>>,
) -> Result<String, String> {
let pool = &*db_instance.lock().await;
let created_workspace =
models::create_workspace(name, "", pool).await.expect("Failed to create workspace");
let created_workspace = models::create_workspace(name, "", window.label(), pool)
.await
.expect("Failed to create workspace");
app_handle
window
.app_handle()
.emit_all("updated_workspace", &created_workspace)
.unwrap();
@@ -271,17 +274,30 @@ async fn create_request(
workspace_id: &str,
name: &str,
sort_priority: f64,
app_handle: AppHandle<Wry>,
window: Window<Wry>,
db_instance: State<'_, Mutex<Pool<Sqlite>>>,
) -> Result<String, String> {
let pool = &*db_instance.lock().await;
let headers = Vec::new();
let created_request =
models::upsert_request(None, workspace_id, name, "GET", None, None, "", headers, sort_priority, pool)
.await
.expect("Failed to create request");
let created_request = models::upsert_request(
None,
workspace_id,
name,
"GET",
None,
None,
HashMap::new(),
None,
"",
headers,
sort_priority,
window.label(),
pool,
)
.await
.expect("Failed to create request");
app_handle
window.app_handle()
.emit_all("updated_request", &created_request)
.unwrap();
@@ -291,21 +307,21 @@ async fn create_request(
#[tauri::command]
async fn duplicate_request(
id: &str,
app_handle: AppHandle<Wry>,
window: Window<Wry>,
db_instance: State<'_, Mutex<Pool<Sqlite>>>,
) -> Result<String, String> {
let pool = &*db_instance.lock().await;
let request = models::duplicate_request(id, pool).await.expect("Failed to duplicate request");
app_handle
.emit_all("updated_request", &request)
.unwrap();
let request = models::duplicate_request(id, window.label(), pool)
.await
.expect("Failed to duplicate request");
window.app_handle().emit_all("updated_request", &request).unwrap();
Ok(request.id)
}
#[tauri::command]
async fn update_request(
request: models::HttpRequest,
app_handle: AppHandle<Wry>,
window: Window<Wry>,
db_instance: State<'_, Mutex<Pool<Sqlite>>>,
) -> Result<(), String> {
let pool = &*db_instance.lock().await;
@@ -320,6 +336,7 @@ async fn update_request(
None => None,
};
// TODO: Figure out how to make this better
let updated_request = models::upsert_request(
Some(request.id.as_str()),
request.workspace_id.as_str(),
@@ -327,15 +344,18 @@ async fn update_request(
request.method.as_str(),
body,
request.body_type,
request.authentication.0,
request.authentication_type,
request.url.as_str(),
request.headers.0,
request.sort_priority,
window.label(),
pool,
)
.await
.expect("Failed to update request");
app_handle
window.app_handle()
.emit_all("updated_request", updated_request)
.unwrap();
@@ -373,7 +393,9 @@ async fn get_request(
db_instance: State<'_, Mutex<Pool<Sqlite>>>,
) -> Result<models::HttpRequest, String> {
let pool = &*db_instance.lock().await;
models::get_request(id, pool).await.map_err(|e| e.to_string())
models::get_request(id, pool)
.await
.map_err(|e| e.to_string())
}
#[tauri::command]
@@ -415,15 +437,17 @@ async fn delete_all_responses(
#[tauri::command]
async fn workspaces(
db_instance: State<'_, Mutex<Pool<Sqlite>>>,
window: Window<Wry>,
) -> Result<Vec<models::Workspace>, String> {
let pool = &*db_instance.lock().await;
let workspaces = models::find_workspaces(pool)
.await
.expect("Failed to find workspaces");
if workspaces.is_empty() {
let workspace = models::create_workspace("My Project", "This is the default workspace", pool)
.await
.expect("Failed to create workspace");
let workspace =
models::create_workspace("My Project", "This is the default workspace", window.label(), pool)
.await
.expect("Failed to create workspace");
Ok(vec![workspace])
} else {
Ok(workspaces)
@@ -454,36 +478,16 @@ fn main() {
let tray_menu = SystemTrayMenu::new().add_item(quit);
let system_tray = SystemTray::new().with_menu(tray_menu);
let default_menu = Menu::os_default("Yaak".to_string().as_str());
let mut test_menu = Menu::new()
.add_item(CustomMenuItem::new("send_request".to_string(), "Send Request").accelerator("CmdOrCtrl+r"))
.add_item(CustomMenuItem::new("zoom_reset".to_string(), "Zoom to Actual Size").accelerator("CmdOrCtrl+0"))
.add_item(CustomMenuItem::new("zoom_in".to_string(), "Zoom In").accelerator("CmdOrCtrl+Plus"))
.add_item(CustomMenuItem::new("zoom_out".to_string(), "Zoom Out").accelerator("CmdOrCtrl+-"))
.add_item(CustomMenuItem::new("toggle_sidebar".to_string(), "Toggle Sidebar").accelerator("CmdOrCtrl+b"));
if is_dev() {
test_menu = test_menu
.add_native_item(MenuItem::Separator)
.add_item(CustomMenuItem::new("refresh".to_string(), "Refresh").accelerator("CmdOrCtrl + Shift + r"))
.add_item(CustomMenuItem::new("toggle_devtools".to_string(), "Open Devtools").accelerator("CmdOrCtrl + Option + i"));
}
let submenu = Submenu::new("Test Menu", test_menu);
let menu = default_menu.add_submenu(submenu);
tauri::Builder::default()
.menu(menu)
.system_tray(system_tray)
.setup(|app| {
let win = app.get_window("main").unwrap();
#[cfg(target_os = "macos")]
win.position_traffic_lights();
Ok(())
})
.setup(|app| {
let handle = app.handle();
std::thread::spawn(move || {
let win = create_window(handle);
if let Err(e) = win.show() {
println!("Failed to show window {}", e)
}
});
let dir = match is_dev() {
true => current_dir().unwrap(),
false => app.path_resolver().app_data_dir().unwrap(),
@@ -521,40 +525,6 @@ fn main() {
};
}
})
.on_menu_event(|event| {
match event.menu_item_id() {
"quit" => std::process::exit(0),
"close" => event.window().close().unwrap(),
"zoom_reset" => event.window().emit("zoom", 0).unwrap(),
"zoom_in" => event.window().emit("zoom", 1).unwrap(),
"zoom_out" => event.window().emit("zoom", -1).unwrap(),
"toggle_sidebar" => event.window().emit("toggle_sidebar", true).unwrap(),
"refresh" => event.window().emit("refresh", true).unwrap(),
"send_request" => event.window().emit("send_request", true).unwrap(),
"toggle_devtools" => {
if event.window().is_devtools_open() {
event.window().close_devtools();
} else {
event.window().open_devtools();
}
}
_ => {}
};
})
.on_window_event(|e| {
let apply_offset = || {
let win = e.window();
#[cfg(target_os = "macos")]
win.position_traffic_lights();
};
match e.event() {
WindowEvent::Resized(..) => apply_offset(),
WindowEvent::ThemeChanged(..) => apply_offset(),
_ => {}
}
})
.invoke_handler(tauri::generate_handler![
greet,
workspaces,
@@ -582,3 +552,102 @@ fn is_dev() -> bool {
let env = option_env!("YAAK_ENV");
env.unwrap_or("production") != "production"
}
fn create_window(handle: AppHandle<Wry>) -> Window<Wry> {
let default_menu = Menu::os_default("Yaak".to_string().as_str());
let mut test_menu = Menu::new()
.add_item(
CustomMenuItem::new("send_request".to_string(), "Send Request")
.accelerator("CmdOrCtrl+r"),
)
.add_item(
CustomMenuItem::new("zoom_reset".to_string(), "Zoom to Actual Size")
.accelerator("CmdOrCtrl+0"),
)
.add_item(
CustomMenuItem::new("zoom_in".to_string(), "Zoom In").accelerator("CmdOrCtrl+Plus"),
)
.add_item(
CustomMenuItem::new("zoom_out".to_string(), "Zoom Out").accelerator("CmdOrCtrl+-"),
)
.add_item(
CustomMenuItem::new("toggle_sidebar".to_string(), "Toggle Sidebar")
.accelerator("CmdOrCtrl+b"),
);
if is_dev() {
test_menu = test_menu
.add_native_item(MenuItem::Separator)
.add_item(
CustomMenuItem::new("refresh".to_string(), "Refresh")
.accelerator("CmdOrCtrl + Shift + r"),
)
.add_item(
CustomMenuItem::new("toggle_devtools".to_string(), "Open Devtools")
.accelerator("CmdOrCtrl + Option + i"),
)
.add_item(CustomMenuItem::new("new_window".to_string(), "New Window"));
}
let submenu = Submenu::new("Test Menu", test_menu);
let menu = default_menu.add_submenu(submenu);
let window_id = generate_id("win");
let win = tauri::WindowBuilder::new(
&handle,
window_id,
tauri::WindowUrl::App("workspaces".into()),
)
.menu(menu)
.fullscreen(false)
.resizable(true)
.inner_size(1100.0, 600.0)
.hidden_title(true)
.title("Yaak")
.title_bar_style(TitleBarStyle::Overlay)
.build()
.expect("failed to build window");
let win2 = win.clone();
win.on_menu_event(move |event| {
match event.menu_item_id() {
"quit" => std::process::exit(0),
"close" => win2.close().unwrap(),
"zoom_reset" => win2.emit("zoom", 0).unwrap(),
"zoom_in" => win2.emit("zoom", 1).unwrap(),
"zoom_out" => win2.emit("zoom", -1).unwrap(),
"toggle_sidebar" => win2.emit("toggle_sidebar", true).unwrap(),
"refresh" => win2.emit("refresh", true).unwrap(),
"send_request" => win2.emit("send_request", true).unwrap(),
"new_window" => {
create_window(handle.clone()).show().unwrap();
}
"toggle_devtools" => {
if win2.is_devtools_open() {
win2.close_devtools();
} else {
win2.open_devtools();
}
}
_ => {}
};
});
let win3 = win.clone();
win.on_window_event(move |e| {
let apply_offset = || {
#[cfg(target_os = "macos")]
win3.position_traffic_lights();
};
match e {
WindowEvent::Resized(..) => apply_offset(),
WindowEvent::ThemeChanged(..) => apply_offset(),
_ => {}
}
});
#[cfg(target_os = "macos")]
win.position_traffic_lights();
win
}

View File

@@ -1,7 +1,8 @@
use std::collections::HashMap;
use rand::distributions::{Alphanumeric, DistString};
use serde::{Deserialize, Serialize};
use sqlx::types::chrono::NaiveDateTime;
use sqlx::types::Json;
use sqlx::types::{Json, JsonValue};
use sqlx::{Pool, Sqlite};
#[derive(sqlx::FromRow, Debug, Clone, Serialize, Deserialize)]
@@ -11,6 +12,7 @@ pub struct Workspace {
pub model: String,
pub created_at: NaiveDateTime,
pub updated_at: NaiveDateTime,
pub updated_by: String,
pub name: String,
pub description: String,
}
@@ -31,6 +33,7 @@ pub struct HttpRequest {
pub model: String,
pub created_at: NaiveDateTime,
pub updated_at: NaiveDateTime,
pub updated_by: String,
pub sort_priority: f64,
pub workspace_id: String,
pub name: String,
@@ -38,6 +41,8 @@ pub struct HttpRequest {
pub method: String,
pub body: Option<String>,
pub body_type: Option<String>,
pub authentication: Json<HashMap<String, JsonValue>>,
pub authentication_type: Option<String>,
pub headers: Json<Vec<HttpRequestHeader>>,
}
@@ -57,6 +62,7 @@ pub struct HttpResponse {
pub request_id: String,
pub created_at: NaiveDateTime,
pub updated_at: NaiveDateTime,
pub updated_by: String,
pub error: Option<String>,
pub url: String,
pub elapsed: i64,
@@ -72,6 +78,7 @@ pub struct KeyValue {
pub model: String,
pub created_at: NaiveDateTime,
pub updated_at: NaiveDateTime,
pub updated_by: String,
pub namespace: String,
pub key: String,
pub value: String,
@@ -94,9 +101,9 @@ pub async fn set_key_value(
key,
value,
)
.execute(pool)
.await
.expect("Failed to insert key value");
.execute(pool)
.await
.expect("Failed to insert key value");
get_key_value(namespace, key, pool).await
}
@@ -105,23 +112,23 @@ pub async fn get_key_value(namespace: &str, key: &str, pool: &Pool<Sqlite>) -> O
sqlx::query_as!(
KeyValue,
r#"
SELECT model, created_at, updated_at, namespace, key, value
SELECT model, created_at, updated_at, updated_by, namespace, key, value
FROM key_values
WHERE namespace = ? AND key = ?
"#,
namespace,
key,
)
.fetch_one(pool)
.await
.ok()
.fetch_one(pool)
.await
.ok()
}
pub async fn find_workspaces(pool: &Pool<Sqlite>) -> Result<Vec<Workspace>, sqlx::Error> {
sqlx::query_as!(
Workspace,
r#"
SELECT id, model, created_at, updated_at, name, description
SELECT id, model, created_at, updated_at, updated_by, name, description
FROM workspaces
"#,
)
@@ -133,7 +140,7 @@ pub async fn get_workspace(id: &str, pool: &Pool<Sqlite>) -> Result<Workspace, s
sqlx::query_as!(
Workspace,
r#"
SELECT id, model, created_at, updated_at, name, description
SELECT id, model, created_at, updated_at, updated_by, name, description
FROM workspaces WHERE id = ?
"#,
id,
@@ -153,25 +160,27 @@ pub async fn delete_workspace(id: &str, pool: &Pool<Sqlite>) -> Result<Workspace
"#,
id,
)
.execute(pool)
.await;
.execute(pool)
.await;
Ok(workspace)
}
pub async fn create_workspace(
name: &str,
description: &str,
updated_by: &str,
pool: &Pool<Sqlite>,
) -> Result<Workspace, sqlx::Error> {
let id = generate_id("wk");
sqlx::query!(
r#"
INSERT INTO workspaces (id, name, description)
VALUES (?, ?, ?)
INSERT INTO workspaces (id, updated_by, name, description)
VALUES (?, ?, ?, ?)
"#,
id,
name,
description,
updated_by,
)
.execute(pool)
.await
@@ -180,11 +189,10 @@ pub async fn create_workspace(
get_workspace(&id, pool).await
}
pub async fn duplicate_request(
id: &str,
pool: &Pool<Sqlite>,
) -> Result<HttpRequest, sqlx::Error> {
let existing = get_request(id, pool).await.expect("Failed to get request to duplicate");
pub async fn duplicate_request(id: &str, updated_by: &str, pool: &Pool<Sqlite>) -> Result<HttpRequest, sqlx::Error> {
let existing = get_request(id, pool)
.await
.expect("Failed to get request to duplicate");
// TODO: Figure out how to make this better
let b2;
let body = match existing.body {
@@ -194,6 +202,7 @@ pub async fn duplicate_request(
}
None => None,
};
upsert_request(
None,
existing.workspace_id.as_str(),
@@ -201,14 +210,17 @@ pub async fn duplicate_request(
existing.method.as_str(),
body,
existing.body_type,
existing.authentication.0,
existing.authentication_type,
existing.url.as_str(),
existing.headers.0,
existing.sort_priority,
updated_by,
pool,
).await
)
.await
}
pub async fn upsert_request(
id: Option<&str>,
workspace_id: &str,
@@ -216,9 +228,12 @@ pub async fn upsert_request(
method: &str,
body: Option<&str>,
body_type: Option<String>,
authentication: HashMap<String, JsonValue>,
authentication_type: Option<String>,
url: &str,
headers: Vec<HttpRequestHeader>,
sort_priority: f64,
updated_by: &str,
pool: &Pool<Sqlite>,
) -> Result<HttpRequest, sqlx::Error> {
let generated_id;
@@ -230,6 +245,7 @@ pub async fn upsert_request(
}
};
let headers_json = Json(headers);
let auth_json = Json(authentication);
sqlx::query!(
r#"
INSERT INTO http_requests (
@@ -240,10 +256,13 @@ pub async fn upsert_request(
method,
body,
body_type,
authentication,
authentication_type,
headers,
sort_priority
sort_priority,
updated_by
)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
ON CONFLICT (id) DO UPDATE SET
updated_at = CURRENT_TIMESTAMP,
name = excluded.name,
@@ -251,8 +270,11 @@ pub async fn upsert_request(
headers = excluded.headers,
body = excluded.body,
body_type = excluded.body_type,
authentication = excluded.authentication,
authentication_type = excluded.authentication_type,
url = excluded.url,
sort_priority = excluded.sort_priority
sort_priority = excluded.sort_priority,
updated_by = excluded.updated_by
"#,
id,
workspace_id,
@@ -261,8 +283,11 @@ pub async fn upsert_request(
method,
body,
body_type,
auth_json,
authentication_type,
headers_json,
sort_priority,
updated_by,
)
.execute(pool)
.await
@@ -288,7 +313,10 @@ pub async fn find_requests(
method,
body,
body_type,
authentication AS "authentication!: Json<HashMap<String, JsonValue>>",
authentication_type,
sort_priority,
updated_by,
headers AS "headers!: sqlx::types::Json<Vec<HttpRequestHeader>>"
FROM http_requests
WHERE workspace_id = ?
@@ -314,7 +342,10 @@ pub async fn get_request(id: &str, pool: &Pool<Sqlite>) -> Result<HttpRequest, s
method,
body,
body_type,
authentication AS "authentication!: Json<HashMap<String, JsonValue>>",
authentication_type,
sort_priority,
updated_by,
headers AS "headers!: sqlx::types::Json<Vec<HttpRequestHeader>>"
FROM http_requests
WHERE id = ?
@@ -350,6 +381,7 @@ pub async fn create_response(
status_reason: Option<&str>,
body: &str,
headers: Vec<HttpResponseHeader>,
updated_by: &str,
pool: &Pool<Sqlite>,
) -> Result<HttpResponse, sqlx::Error> {
let req = get_request(request_id, pool)
@@ -359,8 +391,19 @@ pub async fn create_response(
let headers_json = Json(headers);
sqlx::query!(
r#"
INSERT INTO http_responses (id, request_id, workspace_id, elapsed, url, status, status_reason, body, headers)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?);
INSERT INTO http_responses (
id,
request_id,
workspace_id,
elapsed,
url,
status,
status_reason,
body,
headers,
updated_by
)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?);
"#,
id,
request_id,
@@ -371,6 +414,7 @@ pub async fn create_response(
status_reason,
body,
headers_json,
updated_by,
)
.execute(pool)
.await
@@ -381,23 +425,25 @@ pub async fn create_response(
pub async fn update_response_if_id(
response: HttpResponse,
updated_by: &str,
pool: &Pool<Sqlite>,
) -> Result<HttpResponse, sqlx::Error> {
if response.id == "" {
return Ok(response);
}
return update_response(response, pool).await;
return update_response(response, updated_by, pool).await;
}
pub async fn update_response(
response: HttpResponse,
updated_by: &str,
pool: &Pool<Sqlite>,
) -> Result<HttpResponse, sqlx::Error> {
let headers_json = Json(response.headers);
sqlx::query!(
r#"
UPDATE http_responses SET (elapsed, url, status, status_reason, body, error, headers, updated_at) =
(?, ?, ?, ?, ?, ?, ?, CURRENT_TIMESTAMP) WHERE id = ?;
UPDATE http_responses SET (elapsed, url, status, status_reason, body, error, headers, updated_by, updated_at) =
(?, ?, ?, ?, ?, ?, ?, ?, CURRENT_TIMESTAMP) WHERE id = ?;
"#,
response.elapsed,
response.url,
@@ -406,6 +452,7 @@ pub async fn update_response(
response.body,
response.error,
headers_json,
updated_by,
response.id,
)
.execute(pool)
@@ -418,7 +465,7 @@ pub async fn get_response(id: &str, pool: &Pool<Sqlite>) -> Result<HttpResponse,
sqlx::query_as_unchecked!(
HttpResponse,
r#"
SELECT id, model, workspace_id, request_id, updated_at, created_at,
SELECT id, model, workspace_id, request_id, updated_at, updated_by, created_at,
status, status_reason, body, elapsed, url, error,
headers AS "headers!: sqlx::types::Json<Vec<HttpResponseHeader>>"
FROM http_responses
@@ -437,7 +484,7 @@ pub async fn find_responses(
sqlx::query_as!(
HttpResponse,
r#"
SELECT id, model, workspace_id, request_id, updated_at,
SELECT id, model, workspace_id, request_id, updated_at, updated_by,
created_at, status, status_reason, body, elapsed, url, error,
headers AS "headers!: sqlx::types::Json<Vec<HttpResponseHeader>>"
FROM http_responses