2 Комити a83c080032 ... b6e2d6bd51

Аутор SHA1 Порука Датум
  biblius b6e2d6bd51 improved queries and added enable/disable пре 2 недеља
  biblius a83c080032 wip - improve queries пре 2 недеља

+ 38 - 31
src-tauri/src/cmd.rs

@@ -177,6 +177,20 @@ pub async fn expand_url(
     }
 }
 
+/// Used for updating disabled query params.
+#[tauri::command]
+pub async fn update_query_param_values(
+    state: tauri::State<'_, AppState>,
+    id: i64,
+    key: String,
+    value: String,
+) -> Result<(), String> {
+    db::update_query_param_values(&state.db, id, &key, &value)
+        .await
+        .map_err(|e| e.to_string())?;
+    Ok(())
+}
+
 #[tauri::command]
 pub async fn update_query_param_enabled(
     state: tauri::State<'_, AppState>,
@@ -190,37 +204,41 @@ pub async fn update_query_param_enabled(
                 .await
                 .map_err(|e| e.to_string())?;
 
-            log::debug!("Updating {qp:?}");
-
             if let Some(position) = qp.position {
-                dbg!(position, &url);
-
-                url.remove_query_param(position as usize);
+                let Some((removed, offset)) = url.remove_query_param(position as usize) else {
+                    return Err(format!("no query param at position {position}"));
+                };
 
-                db::update_request_url(&state.db, req_id, &url.to_string(), None, None)
+                let qp = db::update_query_param_enabled(&state.db, qp_id, None)
                     .await
                     .map_err(|e| e.to_string())?;
 
-                let qp = db::update_query_param_enabled(&state.db, qp_id, None)
+                // Update after deactivation because otherwise it will get deleted
+                db::update_query_param_position(
+                    &state.db,
+                    req_id,
+                    offset as i64,
+                    removed.position as i64,
+                )
+                .await
+                .map_err(|e| e.to_string())?;
+
+                db::update_request_url(&state.db, req_id, &url.to_string(), None, None)
                     .await
                     .map_err(|e| e.to_string())?;
 
-                log::debug!("Updated {qp:?}");
-
                 Ok((qp, url.to_string()))
             } else {
                 let position = url.add_qp_clear_trail(&qp.key, &qp.value);
 
-                db::update_request_url(&state.db, req_id, &url.to_string(), None, None)
+                let qp = db::update_query_param_enabled(&state.db, qp_id, Some(position as i64))
                     .await
                     .map_err(|e| e.to_string())?;
 
-                let qp = db::update_query_param_enabled(&state.db, qp_id, Some(position as i64))
+                db::update_request_url(&state.db, req_id, &url.to_string(), None, None)
                     .await
                     .map_err(|e| e.to_string())?;
 
-                log::debug!("Updated {qp:?}");
-
                 Ok((qp, url.to_string()))
             }
         }
@@ -254,7 +272,6 @@ pub async fn update_url(
         UrlUpdate::URL(url) => match RequestUrl::parse(&url) {
             Ok(mut url) => {
                 let mut path_update: Vec<RequestPathUpdate> = vec![];
-                let mut query_update: Vec<RequestQueryUpdate> = vec![];
 
                 for seg in url.path.iter_mut() {
                     let Segment::Dynamic(seg, position) = seg else {
@@ -270,13 +287,11 @@ pub async fn update_url(
                     });
                 }
 
-                for qp in url.query_params.iter() {
-                    query_update.push(RequestQueryUpdate {
-                        position: qp.position as i64,
-                        key: qp.key,
-                        value: qp.value,
-                    });
-                }
+                let query_update = url
+                    .query_params
+                    .iter()
+                    .map(RequestQueryUpdate::from)
+                    .collect();
 
                 db::update_request_url(
                     &state.db,
@@ -335,11 +350,7 @@ pub async fn update_url(
                 let query_update = url
                     .query_params
                     .iter()
-                    .map(|qp| RequestQueryUpdate {
-                        position: qp.position as i64,
-                        key: qp.key,
-                        value: qp.value,
-                    })
+                    .map(RequestQueryUpdate::from)
                     .collect();
 
                 db::update_request_url(
@@ -380,11 +391,7 @@ pub async fn update_url(
                 let query_update = url
                     .query_params
                     .iter()
-                    .map(|qp| RequestQueryUpdate {
-                        position: qp.position as i64,
-                        key: qp.key,
-                        value: qp.value,
-                    })
+                    .map(RequestQueryUpdate::from)
                     .collect();
 
                 db::update_request_url(

+ 43 - 66
src-tauri/src/db.rs

@@ -242,6 +242,24 @@ pub async fn get_query_param(db: &SqlitePool, qp_id: i64) -> AppResult<QueryPara
     .await?)
 }
 
+pub async fn update_query_param_values(
+    db: &SqlitePool,
+    id: i64,
+    key: &str,
+    value: &str,
+) -> AppResult<()> {
+    sqlx::query!(
+        "UPDATE request_query_params SET key = ?, value = ? WHERE id = ?",
+        key,
+        value,
+        id
+    )
+    .execute(db)
+    .await?;
+
+    Ok(())
+}
+
 pub async fn update_query_param_enabled(
     db: &SqlitePool,
     qp_id: i64,
@@ -257,6 +275,26 @@ pub async fn update_query_param_enabled(
     .await?)
 }
 
+pub async fn update_query_param_position(
+    db: &SqlitePool,
+    req_id: i64,
+    // Offset by amount
+    offset: i64,
+    // Start from position
+    position: i64,
+) -> AppResult<()> {
+    sqlx::query!(
+        "UPDATE request_query_params SET position = position + ? WHERE request_id = ? AND position > ?",
+        offset,
+        req_id,
+        position,
+    )
+    .execute(db)
+    .await?;
+
+    Ok(())
+}
+
 /// Return only the active request params.
 pub async fn get_request_url_params(
     db: &SqlitePool,
@@ -271,7 +309,7 @@ pub async fn get_request_url_params(
         FROM request_path_params WHERE request_id = ?
         UNION
         SELECT id, position, key AS "name", value, 1 AS type
-        FROM request_query_params WHERE request_id = ? AND position IS NOT NULL
+        FROM request_query_params WHERE request_id = ?
       "#,
         request_id,
         request_id
@@ -477,21 +515,7 @@ pub async fn get_workspace_request(db: SqlitePool, id: i64) -> AppResult<Workspa
     .fetch_all(&db)
     .await?;
 
-    let path_params = sqlx::query_as!(
-        PathParamRead,
-        "SELECT id, position, name, value FROM request_path_params WHERE request_id = ?",
-        entry.id
-    )
-    .fetch_all(&db)
-    .await?;
-
-    let query_params = sqlx::query_as!(
-        QueryParamRead,
-        "SELECT id, position, key, value FROM request_query_params WHERE request_id = ?",
-        entry.id
-    )
-    .fetch_all(&db)
-    .await?;
+    let (path_params, query_params) = get_request_url_params(&db, id).await?;
 
     Ok(WorkspaceRequest::from_entry(
         entry,
@@ -517,56 +541,9 @@ pub async fn get_workspace_entry(db: SqlitePool, id: i64) -> AppResult<Workspace
     .await?;
 
     match entry.r#type {
-        WorkspaceEntryType::Request => {
-            let params = sqlx::query_as!(
-                RequestParams,
-                r#"
-                  SELECT
-                   rp.request_id as id,
-                   method as 'method!',
-                   url as 'url!',
-                   ty as "ty: _",
-                   content as "content: _",
-                   rb.id as "body_id: _"
-                  FROM request_params rp
-                  LEFT JOIN request_bodies rb ON rp.request_id = rb.request_id
-                  WHERE rp.request_id = ? 
-                  LIMIT 1
-                "#,
-                id
-            )
-            .fetch_one(&db)
-            .await?;
-
-            let headers = sqlx::query_as!(
-                RequestHeader,
-                "SELECT id, name, value FROM request_headers WHERE request_id = ?",
-                entry.id
-            )
-            .fetch_all(&db)
-            .await?;
-
-            let path_params = sqlx::query_as!(
-                PathParamRead,
-                "SELECT id, position, name, value FROM request_path_params WHERE request_id = ?",
-                entry.id
-            )
-            .fetch_all(&db)
-            .await?;
-
-            let query_params = sqlx::query_as!(
-                QueryParamRead,
-                "SELECT id, position, key, value FROM request_query_params WHERE request_id = ?",
-                entry.id
-            )
-            .fetch_all(&db)
-            .await?;
-
-            let req =
-                WorkspaceRequest::from_entry(entry, params, headers, path_params, query_params);
-
-            Ok(WorkspaceEntry::new_req(req))
-        }
+        WorkspaceEntryType::Request => Ok(WorkspaceEntry::new_req(
+            get_workspace_request(db, id).await?,
+        )),
         WorkspaceEntryType::Collection => Ok(WorkspaceEntry::new_col(entry)),
     }
 }

+ 2 - 1
src-tauri/src/lib.rs

@@ -61,7 +61,8 @@ pub fn run() {
             cmd::update_auth,
             cmd::rename_auth,
             cmd::delete_auth,
-            cmd::update_query_param_enabled
+            cmd::update_query_param_enabled,
+            cmd::update_query_param_values
         ])
         .run(tauri::generate_context!())
         .expect("error while running tauri application");

+ 12 - 12
src-tauri/src/request.rs

@@ -1,14 +1,14 @@
 pub mod ctype;
 pub mod url;
 
-use std::{collections::HashMap, str::FromStr};
+use std::str::FromStr;
 
 use crate::{
     auth::{Auth, BasicAuth, OAuth},
     error::AppError,
     request::{
         ctype::ContentType,
-        url::{RequestUrl, RequestUrlOwned, Segment},
+        url::{QueryParam, RequestUrl, Segment},
     },
     workspace::WorkspaceEntryBase,
     AppResult,
@@ -419,16 +419,6 @@ pub struct QueryParamWrite {
     pub value: String,
 }
 
-impl QueryParamWrite {
-    pub fn new(position: i64, key: String, value: String) -> Self {
-        Self {
-            position,
-            key,
-            value,
-        }
-    }
-}
-
 #[derive(Debug, Deserialize)]
 pub struct RequestPathUpdate<'a> {
     pub position: i64,
@@ -445,6 +435,16 @@ pub struct RequestQueryUpdate<'a> {
     pub value: &'a str,
 }
 
+impl<'a> From<&'a QueryParam<'a>> for RequestQueryUpdate<'a> {
+    fn from(value: &'a QueryParam<'a>) -> Self {
+        Self {
+            position: value.position as i64,
+            key: value.key,
+            value: value.value,
+        }
+    }
+}
+
 #[derive(Debug, Serialize, FromRow)]
 pub struct RequestHeader {
     pub id: i64,

+ 14 - 4
src-tauri/src/request/url.rs

@@ -314,7 +314,7 @@ impl<'a> RequestUrl<'a> {
         }
     }
 
-    pub fn remove_query_param(&mut self, position: usize) -> Option<QueryParam<'a>> {
+    pub fn remove_query_param(&mut self, position: usize) -> Option<(QueryParam<'a>, i64)> {
         let Some(mut i) = self
             .query_params
             .iter()
@@ -327,14 +327,16 @@ impl<'a> RequestUrl<'a> {
         };
 
         let removed = self.query_params.remove(i);
+        let mut offset = 0i64;
 
         while let Some(qp) = self.query_params.get_mut(i) {
             // +1 for the &
             qp.position -= removed.total_len() + 1;
+            offset -= removed.total_len() as i64 + 1;
             i += 1;
         }
 
-        Some(removed)
+        Some((removed, offset))
     }
 }
 
@@ -418,6 +420,14 @@ impl<'a> Segment<'a> {
         }
     }
 
+    /// Return the segment name without any path separators or dynamic segment indicators.
+    pub fn name(&self) -> &str {
+        match self {
+            Segment::Static(s, _) => s,
+            Segment::Dynamic(s, _) => s,
+        }
+    }
+
     /// Return the full length of the path segment including its `/` and `:` in case of dynamic
     /// values.
     pub fn total_len(&self) -> usize {
@@ -930,7 +940,7 @@ mod tests {
 
         let qp = url.remove_query_param("http://localhost:4000?".len());
 
-        assert_eq!(first, qp.unwrap());
+        assert_eq!(first, qp.unwrap().0);
 
         assert_eq!("http://localhost:4000?".len(), url.query_params[0].position);
         assert_eq!(
@@ -960,7 +970,7 @@ mod tests {
 
         let qp = url.remove_query_param("http://localhost:4000?foo=69&".len());
 
-        assert_eq!(second, qp.unwrap());
+        assert_eq!(second, qp.unwrap().0);
 
         assert_eq!("http://localhost:4000?".len(), url.query_params[0].position);
         assert_eq!(

+ 15 - 6
src/lib/components/WorkspaceEntry.svelte

@@ -299,14 +299,20 @@
               {#if _state.entry?.query?.length > 0}
                 <div>
                   <h3 class="mb-2 text-sm font-medium">Query</h3>
-                  <div class="grid grid-cols-3 gap-2 text-sm">
+                  <div
+                    class="grid grid-cols-[5%_1fr_1fr] items-center justify-center gap-2 text-sm"
+                  >
                     {#each _state.entry.query as param}
-                      <Checkbox
-                        checked={param.position != null}
-                        onCheckedChange={() =>
-                          updateQueryParamEnabled(param.id)}
-                      />
+                      <div class="flex justify-center">
+                        <Checkbox
+                          checked={param.position != null}
+                          onCheckedChange={() => updateQueryParamEnabled(param)}
+                        />
+                      </div>
                       <Input
+                        class={param.position == null
+                          ? `text-muted-foreground opacity-75`
+                          : ""}
                         bind:value={param.key}
                         placeholder="key"
                         oninput={() =>
@@ -317,6 +323,9 @@
                           })}
                       />
                       <Input
+                        class={param.position == null
+                          ? `text-muted-foreground opacity-75`
+                          : ""}
                         bind:value={param.value}
                         placeholder="value"
                         oninput={() =>

+ 36 - 13
src/lib/state.svelte.ts

@@ -443,6 +443,14 @@ export async function updateUrl(up: UrlUpdate) {
       break;
     }
     case "Query": {
+      if (up.param.position == null) {
+        await invoke("update_query_param_values", {
+          id: up.param.id,
+          key: up.param.key,
+          value: up.param.value,
+        });
+        return;
+      }
       update = { Query: [up.url, up.param] };
       break;
     }
@@ -509,24 +517,39 @@ export async function updateUrl(up: UrlUpdate) {
   console.debug("updated", $state.snapshot(state.entry));
 }
 
-export async function updateQueryParamEnabled(qpId: number) {
-  const qpIdx = state.entry.query.findIndex((qp) => qp.id === qpId);
-
-  if (qpIdx === -1) {
-    console.warn("query param does not exist!", qpId);
-    return;
-  }
+export async function updateQueryParamEnabled(param: QueryParam) {
+  console.log(param);
+  console.log($state.snapshot(state.entry.query));
 
-  const [newQp, url] = await invoke<string>("update_query_param_enabled", {
-    reqId: state.entry.id,
-    qpId,
-    url: state.entry!!.url,
-  });
+  const [newQp, url] = await invoke<[QueryParam, string]>(
+    "update_query_param_enabled",
+    {
+      reqId: state.entry.id,
+      qpId: param.id,
+      url: state.entry!!.url,
+    },
+  );
 
   console.log("updated QP", newQp, url);
 
+  // Param was removed, offset all positions
+  if (newQp.position == null) {
+    for (const q of state.entry.query) {
+      if (q.position < param.position!!) {
+        continue;
+      }
+      // +1 for the &, +1 for the =
+      q.position -= newQp.key.length + newQp.value.length + 2;
+    }
+  }
+
   state.entry!!.url = url;
-  state.entry.query[qpIdx] = newQp;
+
+  param.key = newQp.key;
+  param.value = newQp.value;
+  param.position = newQp.position;
+
+  console.log($state.snapshot(state.entry.query));
 }
 
 export async function expandUrl() {