mirror of
https://github.com/mountain-loop/yaak.git
synced 2026-04-23 01:08:28 +02:00
Ability to open workspace from directory, WorkspaceMeta, and many sync improvements
This commit is contained in:
@@ -165,7 +165,6 @@ pub struct Workspace {
|
||||
#[serde(default = "default_true")]
|
||||
pub setting_follow_redirects: bool,
|
||||
pub setting_request_timeout: i32,
|
||||
pub setting_sync_dir: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Iden)]
|
||||
@@ -181,7 +180,6 @@ pub enum WorkspaceIden {
|
||||
Name,
|
||||
SettingFollowRedirects,
|
||||
SettingRequestTimeout,
|
||||
SettingSyncDir,
|
||||
SettingValidateCertificates,
|
||||
}
|
||||
|
||||
@@ -198,7 +196,6 @@ impl<'s> TryFrom<&Row<'s>> for Workspace {
|
||||
description: r.get("description")?,
|
||||
setting_follow_redirects: r.get("setting_follow_redirects")?,
|
||||
setting_request_timeout: r.get("setting_request_timeout")?,
|
||||
setting_sync_dir: r.get("setting_sync_dir")?,
|
||||
setting_validate_certificates: r.get("setting_validate_certificates")?,
|
||||
})
|
||||
}
|
||||
@@ -216,6 +213,47 @@ impl Workspace {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, Default, TS)]
|
||||
#[serde(default, rename_all = "camelCase")]
|
||||
#[ts(export, export_to = "models.ts")]
|
||||
pub struct WorkspaceMeta {
|
||||
#[ts(type = "\"workspace_meta\"")]
|
||||
pub model: String,
|
||||
pub id: String,
|
||||
pub workspace_id: String,
|
||||
pub created_at: NaiveDateTime,
|
||||
pub updated_at: NaiveDateTime,
|
||||
pub setting_sync_dir: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Iden)]
|
||||
pub enum WorkspaceMetaIden {
|
||||
#[iden = "workspace_metas"]
|
||||
Table,
|
||||
Model,
|
||||
Id,
|
||||
WorkspaceId,
|
||||
CreatedAt,
|
||||
UpdatedAt,
|
||||
|
||||
SettingSyncDir,
|
||||
}
|
||||
|
||||
impl<'s> TryFrom<&Row<'s>> for WorkspaceMeta {
|
||||
type Error = rusqlite::Error;
|
||||
|
||||
fn try_from(r: &Row<'s>) -> Result<Self, Self::Error> {
|
||||
Ok(WorkspaceMeta {
|
||||
id: r.get("id")?,
|
||||
workspace_id: r.get("workspace_id")?,
|
||||
model: r.get("model")?,
|
||||
created_at: r.get("created_at")?,
|
||||
updated_at: r.get("updated_at")?,
|
||||
setting_sync_dir: r.get("setting_sync_dir")?,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, TS)]
|
||||
#[ts(export, export_to = "models.ts")]
|
||||
enum CookieDomain {
|
||||
@@ -933,6 +971,22 @@ pub struct SyncState {
|
||||
pub sync_dir: String,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, Default, TS)]
|
||||
#[serde(default, rename_all = "camelCase")]
|
||||
#[ts(export, export_to = "models.ts")]
|
||||
pub struct SyncHistory {
|
||||
#[ts(type = "\"sync_history\"")]
|
||||
pub model: String,
|
||||
pub id: String,
|
||||
pub workspace_id: String,
|
||||
pub created_at: NaiveDateTime,
|
||||
|
||||
pub states: Vec<SyncState>,
|
||||
pub checksum: String,
|
||||
pub rel_path: String,
|
||||
pub sync_dir: String,
|
||||
}
|
||||
|
||||
#[derive(Iden)]
|
||||
pub enum SyncStateIden {
|
||||
#[iden = "sync_states"]
|
||||
@@ -1030,6 +1084,7 @@ pub enum ModelType {
|
||||
TypeHttpResponse,
|
||||
TypePlugin,
|
||||
TypeWorkspace,
|
||||
TypeWorkspaceMeta,
|
||||
TypeSyncState,
|
||||
}
|
||||
|
||||
@@ -1046,6 +1101,7 @@ impl ModelType {
|
||||
ModelType::TypeHttpResponse => "rs",
|
||||
ModelType::TypePlugin => "pg",
|
||||
ModelType::TypeWorkspace => "wk",
|
||||
ModelType::TypeWorkspaceMeta => "wm",
|
||||
ModelType::TypeSyncState => "ss",
|
||||
}
|
||||
.to_string()
|
||||
@@ -1068,6 +1124,7 @@ pub enum AnyModel {
|
||||
Settings(Settings),
|
||||
KeyValue(KeyValue),
|
||||
Workspace(Workspace),
|
||||
WorkspaceMeta(WorkspaceMeta),
|
||||
}
|
||||
|
||||
impl<'de> Deserialize<'de> for AnyModel {
|
||||
|
||||
@@ -5,7 +5,8 @@ use crate::models::{
|
||||
GrpcConnection, GrpcConnectionIden, GrpcConnectionState, GrpcEvent, GrpcEventIden, GrpcRequest,
|
||||
GrpcRequestIden, HttpRequest, HttpRequestIden, HttpResponse, HttpResponseHeader,
|
||||
HttpResponseIden, HttpResponseState, KeyValue, KeyValueIden, ModelType, Plugin, PluginIden,
|
||||
Settings, SettingsIden, SyncState, SyncStateIden, Workspace, WorkspaceIden,
|
||||
Settings, SettingsIden, SyncState, SyncStateIden, Workspace, WorkspaceIden, WorkspaceMeta,
|
||||
WorkspaceMetaIden,
|
||||
};
|
||||
use crate::plugin::SqliteConnection;
|
||||
use chrono::NaiveDateTime;
|
||||
@@ -18,7 +19,7 @@ use sea_query::{Cond, Expr, OnConflict, Order, Query, SqliteQueryBuilder};
|
||||
use sea_query_rusqlite::RusqliteBinder;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::fs;
|
||||
use std::path::PathBuf;
|
||||
use std::path::{Path, PathBuf};
|
||||
use tauri::{AppHandle, Emitter, Listener, Manager, Runtime, WebviewWindow};
|
||||
use ts_rs::TS;
|
||||
|
||||
@@ -177,6 +178,18 @@ pub async fn list_workspaces<R: Runtime>(mgr: &impl Manager<R>) -> Result<Vec<Wo
|
||||
Ok(items.map(|v| v.unwrap()).collect())
|
||||
}
|
||||
|
||||
pub async fn list_workspace_metas<R: Runtime>(mgr: &impl Manager<R>) -> Result<Vec<WorkspaceMeta>> {
|
||||
let dbm = &*mgr.state::<SqliteConnection>();
|
||||
let db = dbm.0.lock().await.get().unwrap();
|
||||
let (sql, params) = Query::select()
|
||||
.from(WorkspaceMetaIden::Table)
|
||||
.column(Asterisk)
|
||||
.build_rusqlite(SqliteQueryBuilder);
|
||||
let mut stmt = db.prepare(sql.as_str())?;
|
||||
let items = stmt.query_map(&*params.as_params(), |row| row.try_into())?;
|
||||
Ok(items.map(|v| v.unwrap()).collect())
|
||||
}
|
||||
|
||||
pub async fn get_workspace<R: Runtime>(mgr: &impl Manager<R>, id: &str) -> Result<Workspace> {
|
||||
let dbm = &*mgr.state::<SqliteConnection>();
|
||||
let db = dbm.0.lock().await.get().unwrap();
|
||||
@@ -189,6 +202,54 @@ pub async fn get_workspace<R: Runtime>(mgr: &impl Manager<R>, id: &str) -> Resul
|
||||
Ok(stmt.query_row(&*params.as_params(), |row| row.try_into())?)
|
||||
}
|
||||
|
||||
pub async fn get_workspace_meta<R: Runtime>(
|
||||
mgr: &impl Manager<R>,
|
||||
workspace: &Workspace,
|
||||
) -> Result<Option<WorkspaceMeta>> {
|
||||
let dbm = &*mgr.state::<SqliteConnection>();
|
||||
let db = dbm.0.lock().await.get().unwrap();
|
||||
let (sql, params) = Query::select()
|
||||
.from(WorkspaceMetaIden::Table)
|
||||
.column(Asterisk)
|
||||
.cond_where(Expr::col(WorkspaceMetaIden::WorkspaceId).eq(&workspace.id))
|
||||
.build_rusqlite(SqliteQueryBuilder);
|
||||
let mut stmt = db.prepare(sql.as_str())?;
|
||||
Ok(stmt.query_row(&*params.as_params(), |row| row.try_into()).optional()?)
|
||||
}
|
||||
|
||||
pub async fn get_or_create_workspace_meta<R: Runtime>(
|
||||
window: &WebviewWindow<R>,
|
||||
workspace: &Workspace,
|
||||
update_source: &UpdateSource,
|
||||
) -> Result<WorkspaceMeta> {
|
||||
let workspace_meta = get_workspace_meta(window, workspace).await?;
|
||||
if let Some(m) = workspace_meta {
|
||||
return Ok(m);
|
||||
}
|
||||
|
||||
upsert_workspace_meta(
|
||||
window,
|
||||
WorkspaceMeta {
|
||||
workspace_id: workspace.to_owned().id,
|
||||
..Default::default()
|
||||
},
|
||||
update_source,
|
||||
)
|
||||
.await
|
||||
}
|
||||
|
||||
pub async fn exists_workspace<R: Runtime>(mgr: &impl Manager<R>, id: &str) -> Result<bool> {
|
||||
let dbm = &*mgr.state::<SqliteConnection>();
|
||||
let db = dbm.0.lock().await.get().unwrap();
|
||||
let (sql, params) = Query::select()
|
||||
.from(WorkspaceIden::Table)
|
||||
.column(Asterisk)
|
||||
.cond_where(Expr::col(WorkspaceIden::Id).eq(id))
|
||||
.build_rusqlite(SqliteQueryBuilder);
|
||||
let mut stmt = db.prepare(sql.as_str())?;
|
||||
Ok(stmt.exists(&*params.as_params())?)
|
||||
}
|
||||
|
||||
pub async fn upsert_workspace<R: Runtime>(
|
||||
window: &WebviewWindow<R>,
|
||||
workspace: Workspace,
|
||||
@@ -200,56 +261,96 @@ pub async fn upsert_workspace<R: Runtime>(
|
||||
};
|
||||
let trimmed_name = workspace.name.trim();
|
||||
|
||||
let m: Workspace = {
|
||||
let dbm = &*window.app_handle().state::<SqliteConnection>();
|
||||
let db = dbm.0.lock().await.get().unwrap();
|
||||
let dbm = &*window.app_handle().state::<SqliteConnection>();
|
||||
let db = dbm.0.lock().await.get().unwrap();
|
||||
|
||||
let (sql, params) = Query::insert()
|
||||
.into_table(WorkspaceIden::Table)
|
||||
.columns([
|
||||
WorkspaceIden::Id,
|
||||
WorkspaceIden::CreatedAt,
|
||||
WorkspaceIden::UpdatedAt,
|
||||
WorkspaceIden::Name,
|
||||
WorkspaceIden::Description,
|
||||
WorkspaceIden::SettingFollowRedirects,
|
||||
WorkspaceIden::SettingRequestTimeout,
|
||||
WorkspaceIden::SettingSyncDir,
|
||||
WorkspaceIden::SettingValidateCertificates,
|
||||
])
|
||||
.values_panic([
|
||||
id.as_str().into(),
|
||||
CurrentTimestamp.into(),
|
||||
CurrentTimestamp.into(),
|
||||
trimmed_name.into(),
|
||||
workspace.description.into(),
|
||||
workspace.setting_follow_redirects.into(),
|
||||
workspace.setting_request_timeout.into(),
|
||||
workspace.setting_sync_dir.into(),
|
||||
workspace.setting_validate_certificates.into(),
|
||||
])
|
||||
.on_conflict(
|
||||
OnConflict::column(GrpcRequestIden::Id)
|
||||
.update_columns([
|
||||
WorkspaceIden::UpdatedAt,
|
||||
WorkspaceIden::Name,
|
||||
WorkspaceIden::Description,
|
||||
WorkspaceIden::SettingRequestTimeout,
|
||||
WorkspaceIden::SettingFollowRedirects,
|
||||
WorkspaceIden::SettingRequestTimeout,
|
||||
WorkspaceIden::SettingSyncDir,
|
||||
WorkspaceIden::SettingValidateCertificates,
|
||||
])
|
||||
.to_owned(),
|
||||
)
|
||||
.returning_all()
|
||||
.build_rusqlite(SqliteQueryBuilder);
|
||||
let (sql, params) = Query::insert()
|
||||
.into_table(WorkspaceIden::Table)
|
||||
.columns([
|
||||
WorkspaceIden::Id,
|
||||
WorkspaceIden::CreatedAt,
|
||||
WorkspaceIden::UpdatedAt,
|
||||
WorkspaceIden::Name,
|
||||
WorkspaceIden::Description,
|
||||
WorkspaceIden::SettingFollowRedirects,
|
||||
WorkspaceIden::SettingRequestTimeout,
|
||||
WorkspaceIden::SettingValidateCertificates,
|
||||
])
|
||||
.values_panic([
|
||||
id.as_str().into(),
|
||||
CurrentTimestamp.into(),
|
||||
CurrentTimestamp.into(),
|
||||
trimmed_name.into(),
|
||||
workspace.description.into(),
|
||||
workspace.setting_follow_redirects.into(),
|
||||
workspace.setting_request_timeout.into(),
|
||||
workspace.setting_validate_certificates.into(),
|
||||
])
|
||||
.on_conflict(
|
||||
OnConflict::column(GrpcRequestIden::Id)
|
||||
.update_columns([
|
||||
WorkspaceIden::UpdatedAt,
|
||||
WorkspaceIden::Name,
|
||||
WorkspaceIden::Description,
|
||||
WorkspaceIden::SettingRequestTimeout,
|
||||
WorkspaceIden::SettingFollowRedirects,
|
||||
WorkspaceIden::SettingRequestTimeout,
|
||||
WorkspaceIden::SettingValidateCertificates,
|
||||
])
|
||||
.to_owned(),
|
||||
)
|
||||
.returning_all()
|
||||
.build_rusqlite(SqliteQueryBuilder);
|
||||
|
||||
let mut stmt = db.prepare(&sql)?;
|
||||
stmt.query_row(&*params.as_params(), |row| row.try_into())?
|
||||
};
|
||||
let mut stmt = db.prepare(&sql)?;
|
||||
let m: Workspace = stmt.query_row(&*params.as_params(), |row| row.try_into())?;
|
||||
emit_upserted_model(window, &AnyModel::Workspace(m.to_owned()), update_source);
|
||||
ensure_base_environment(window, &m.id).await?;
|
||||
Ok(m)
|
||||
}
|
||||
|
||||
pub async fn upsert_workspace_meta<R: Runtime>(
|
||||
window: &WebviewWindow<R>,
|
||||
workspace_meta: WorkspaceMeta,
|
||||
update_source: &UpdateSource,
|
||||
) -> Result<WorkspaceMeta> {
|
||||
let id = match workspace_meta.id.as_str() {
|
||||
"" => generate_model_id(ModelType::TypeWorkspaceMeta),
|
||||
_ => workspace_meta.id.to_string(),
|
||||
};
|
||||
|
||||
let dbm = &*window.app_handle().state::<SqliteConnection>();
|
||||
let db = dbm.0.lock().await.get().unwrap();
|
||||
|
||||
let (sql, params) = Query::insert()
|
||||
.into_table(WorkspaceMetaIden::Table)
|
||||
.columns([
|
||||
WorkspaceMetaIden::Id,
|
||||
WorkspaceMetaIden::WorkspaceId,
|
||||
WorkspaceMetaIden::CreatedAt,
|
||||
WorkspaceMetaIden::UpdatedAt,
|
||||
WorkspaceMetaIden::SettingSyncDir,
|
||||
])
|
||||
.values_panic([
|
||||
id.as_str().into(),
|
||||
workspace_meta.workspace_id.into(),
|
||||
CurrentTimestamp.into(),
|
||||
CurrentTimestamp.into(),
|
||||
workspace_meta.setting_sync_dir.into(),
|
||||
])
|
||||
.on_conflict(
|
||||
OnConflict::column(GrpcRequestIden::Id)
|
||||
.update_columns([
|
||||
WorkspaceMetaIden::UpdatedAt,
|
||||
WorkspaceMetaIden::SettingSyncDir,
|
||||
])
|
||||
.to_owned(),
|
||||
)
|
||||
.returning_all()
|
||||
.build_rusqlite(SqliteQueryBuilder);
|
||||
|
||||
let mut stmt = db.prepare(&sql)?;
|
||||
let m: WorkspaceMeta = stmt.query_row(&*params.as_params(), |row| row.try_into())?;
|
||||
emit_upserted_model(window, &AnyModel::WorkspaceMeta(m.to_owned()), update_source);
|
||||
Ok(m)
|
||||
}
|
||||
|
||||
@@ -1788,7 +1889,7 @@ pub async fn get_sync_state_for_model<R: Runtime>(
|
||||
pub async fn list_sync_states_for_workspace<R: Runtime>(
|
||||
mgr: &impl Manager<R>,
|
||||
workspace_id: &str,
|
||||
sync_dir: PathBuf,
|
||||
sync_dir: &Path,
|
||||
) -> Result<Vec<SyncState>> {
|
||||
let dbm = &*mgr.state::<SqliteConnection>();
|
||||
let db = dbm.0.lock().await.get().unwrap();
|
||||
|
||||
Reference in New Issue
Block a user