Skip to content

Commit d8a807a

Browse files
committed
feat: add project and and rework data storing
1 parent bcca2ca commit d8a807a

File tree

17 files changed

+185
-127
lines changed

17 files changed

+185
-127
lines changed

.vscode/settings.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
"editor.semanticHighlighting.enabled": false
1414
},
1515
"rust-analyzer.rustfmt.overrideCommand": ["leptosfmt", "--stdin", "--rustfmt"],
16+
"rust-analyzer.procMacro.attributes.enable": true,
1617
"editor.tokenColorCustomizations": {
1718
"[LaserWave High Contrast]": {
1819
"textMateRules": [

common/src/types/mod.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,7 @@
1+
use std::collections::BTreeMap;
2+
13
pub mod pgsql;
24

5+
pub type BTreeStore = BTreeMap<String, String>;
6+
pub type BTreeVecStore = BTreeMap<String, Vec<String>>;
7+

src-tauri/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ anyhow = "1.0.83"
2525
tracing = "0.1.40"
2626
tracing-subscriber = { version = "0.3.18", features = ["fmt"] }
2727
ahash = { version = "0.8.11", features = ["serde"] }
28+
bincode = "1.3.3"
2829

2930

3031

src-tauri/src/dbs/project.rs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,10 @@ use std::collections::BTreeMap;
33
use tauri::{Result, State};
44

55
use crate::AppState;
6+
use common::types::BTreeVecStore;
67

78
#[tauri::command(rename_all = "snake_case")]
8-
pub async fn project_db_select(app_state: State<'_, AppState>) -> Result<BTreeMap<String, String>> {
9+
pub async fn project_db_select(app_state: State<'_, AppState>) -> Result<BTreeVecStore> {
910
let project_db = app_state.project_db.lock().await;
1011
let db = project_db.clone().unwrap();
1112
let mut projects = BTreeMap::new();
@@ -20,7 +21,7 @@ pub async fn project_db_select(app_state: State<'_, AppState>) -> Result<BTreeMa
2021

2122
let project = (
2223
String::from_utf8(project.0.to_vec()).unwrap(),
23-
String::from_utf8(project.1.to_vec()).unwrap(),
24+
bincode::deserialize(&project.1).unwrap(),
2425
);
2526
projects.insert(project.0, project.1);
2627
}
@@ -30,11 +31,13 @@ pub async fn project_db_select(app_state: State<'_, AppState>) -> Result<BTreeMa
3031
#[tauri::command(rename_all = "snake_case")]
3132
pub async fn project_db_insert(
3233
project_id: &str,
33-
project_details: &str,
34+
project_details: Vec<String>,
3435
app_state: State<'_, AppState>,
3536
) -> Result<()> {
3637
let project_db = app_state.project_db.lock().await;
3738
let db = project_db.clone().unwrap();
39+
let project_details = bincode::serialize(&project_details).unwrap();
40+
// project_id - [driver, user, password, host, port]
3841
db.insert(project_id, project_details).unwrap();
3942
Ok(())
4043
}

src-tauri/src/drivers/pgsql.rs

Lines changed: 11 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ use crate::{utils::reflective_get, AppState};
1313
#[tauri::command(rename_all = "snake_case")]
1414
pub async fn pgsql_connector(
1515
project_id: &str,
16-
key: Option<&str>,
16+
key: Option<[&str; 4]>,
1717
app: AppHandle,
1818
) -> Result<ProjectConnectionStatus> {
1919
let app_state = app.state::<AppState>();
@@ -26,24 +26,21 @@ pub async fn pgsql_connector(
2626
}
2727

2828
let key = match key {
29-
Some(key) => key.to_string(),
29+
Some(key) => format!(
30+
"user={} password={} host={} port={}",
31+
key[0], key[1], key[2], key[3]
32+
),
3033
None => {
3134
let projects_db = app_state.project_db.lock().await;
3235
let projects_db = projects_db.as_ref().unwrap();
33-
let project_details = projects_db.get(project_id).unwrap().unwrap().to_vec();
34-
let project_details = String::from_utf8(project_details).unwrap();
35-
let project_details = project_details.split(":").collect::<Vec<&str>>();
36-
let project_details = project_details
37-
.into_iter()
38-
.skip(1)
39-
.map(|s| {
40-
let kv = s.split('=').collect::<Vec<&str>>();
41-
kv[1].to_owned()
42-
})
43-
.collect::<Vec<String>>();
36+
let project_details = projects_db.get(project_id).unwrap();
37+
let project_details = match project_details {
38+
Some(bytes) => bincode::deserialize::<Vec<String>>(&bytes).unwrap(),
39+
_ => Vec::new(),
40+
};
4441
let project_details = format!(
4542
"user={} password={} host={} port={}",
46-
project_details[0], project_details[1], project_details[2], project_details[3]
43+
project_details[1], project_details[2], project_details[3], project_details[4]
4744
);
4845
project_details
4946
}

src/app.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,10 @@ use crate::{
1010
performane::Performance,
1111
sidebar::index::Sidebar,
1212
store::{
13-
atoms::{QueryPerformanceAtom, QueryPerformanceContext, RunQueryAtom, RunQueryContext},
13+
atoms::{
14+
PgsqlConnectionDetailsAtom, PgsqlConnectionDetailsContext, QueryPerformanceAtom,
15+
QueryPerformanceContext, RunQueryAtom, RunQueryContext,
16+
},
1417
projects::ProjectsStore,
1518
queries::QueriesStore,
1619
tabs::TabsStore,
@@ -29,6 +32,9 @@ pub fn App() -> impl IntoView {
2932
RwSignal::new(VecDeque::<QueryPerformanceAtom>::new()),
3033
);
3134
provide_context::<RunQueryContext>(RwSignal::new(RunQueryAtom::default()));
35+
provide_context::<PgsqlConnectionDetailsContext>(RwSignal::new(
36+
PgsqlConnectionDetailsAtom::default(),
37+
));
3238
provide_context(TabsStore::default());
3339

3440
view! {

src/dashboard/query_editor.rs

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,7 @@ pub const MODE_ID: &str = "pgsql";
2323
#[component]
2424
pub fn QueryEditor(index: usize) -> impl IntoView {
2525
let tabs_store = expect_context::<TabsStore>();
26-
let active_project = move || match tabs_store.selected_projects.get().get(index) {
27-
Some(project) => Some(project.clone()),
28-
_ => None,
29-
};
26+
let active_project = move || tabs_store.selected_projects.get().get(index).cloned();
3027
let projects_store = expect_context::<ProjectsStore>();
3128
let project_driver = projects_store.select_driver_by_project(active_project().as_deref());
3229
let tabs_store_rc = Rc::new(RefCell::new(tabs_store));

src/databases/pgsql/driver.rs

Lines changed: 19 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,10 @@ use crate::{
1313
InvokePgsqlRunQueryArgs,
1414
},
1515
store::{
16-
atoms::{QueryPerformanceAtom, QueryPerformanceContext, RunQueryAtom, RunQueryContext},
16+
atoms::{
17+
PgsqlConnectionDetailsContext, QueryPerformanceAtom, QueryPerformanceContext, RunQueryAtom,
18+
RunQueryContext,
19+
},
1720
tabs::TabsStore,
1821
},
1922
};
@@ -48,12 +51,16 @@ impl<'a> Pgsql<'a> {
4851
self
4952
.status
5053
.update(|prev| *prev = ProjectConnectionStatus::Connecting);
51-
let connection_string = self.generate_connection_string();
5254
let status = invoke::<_, ProjectConnectionStatus>(
5355
Invoke::PgsqlConnector.as_ref(),
5456
&InvokePgsqlConnectorArgs {
5557
project_id: &self.project_id.get(),
56-
key: Some(&connection_string),
58+
key: Some([
59+
self.user.unwrap(),
60+
self.password.unwrap(),
61+
self.host.unwrap(),
62+
self.port.unwrap(),
63+
]),
5764
},
5865
)
5966
.await
@@ -158,15 +165,15 @@ impl<'a> Pgsql<'a> {
158165
self.port = Some(port);
159166
}
160167

161-
fn generate_connection_string(&self) -> String {
162-
let connection_string = format!(
163-
"user={} password={} host={} port={}",
164-
self.user.as_ref().unwrap(),
165-
self.password.as_ref().unwrap(),
166-
self.host.as_ref().unwrap(),
167-
self.port.as_ref().unwrap(),
168-
);
169-
connection_string
168+
pub fn edit_connection_details(&self) {
169+
let atom = expect_context::<PgsqlConnectionDetailsContext>();
170+
atom.update(|prev| {
171+
prev.project_id = self.project_id.get().clone();
172+
prev.user = self.user.unwrap().to_string();
173+
prev.password = self.password.unwrap().to_string();
174+
prev.host = self.host.unwrap().to_string();
175+
prev.port = self.port.unwrap().to_string();
176+
});
170177
}
171178
}
172179

src/databases/pgsql/index.rs

Lines changed: 21 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,10 @@ use leptos_icons::*;
55
use leptos_toaster::{Toast, ToastId, ToastVariant, Toasts};
66

77
use super::{driver::Pgsql, schema::Schema};
8-
use crate::store::{projects::ProjectsStore, tabs::TabsStore};
8+
use crate::{
9+
modals::add_pgsql_connection::AddPgsqlConnection,
10+
store::{projects::ProjectsStore, tabs::TabsStore},
11+
};
912
use common::enums::ProjectConnectionStatus;
1013

1114
#[component]
@@ -14,29 +17,18 @@ pub fn Pgsql(project_id: String) -> impl IntoView {
1417
let tabs_store = expect_context::<TabsStore>();
1518
let projects_store = expect_context::<ProjectsStore>();
1619
let project_details = projects_store.select_project_by_name(&project_id).unwrap();
17-
let connection_params = project_details
18-
.split(':')
19-
.map(String::from)
20-
.collect::<Vec<String>>();
21-
let connection_params = connection_params
22-
.into_iter()
23-
.skip(1)
24-
.map(|s| {
25-
let kv = s.split('=').collect::<Vec<&str>>();
26-
kv[1].to_owned()
27-
})
28-
.collect::<Vec<String>>();
29-
let connection_params = Box::leak(connection_params.into_boxed_slice());
20+
let project_details = Box::leak(Box::new(project_details));
3021
// [user, password, host, port]
3122
let mut pgsql = Pgsql::new(project_id.clone().to_string());
3223
{
3324
pgsql.load_connection_details(
34-
&connection_params[0],
35-
&connection_params[1],
36-
&connection_params[2],
37-
&connection_params[3],
25+
&project_details[1],
26+
&project_details[2],
27+
&project_details[3],
28+
&project_details[4],
3829
);
3930
}
31+
let show = create_rw_signal(false);
4032
let toast_context = expect_context::<Toasts>();
4133
let create_toast = move |variant: ToastVariant, title: String| {
4234
let toast_id = ToastId::new();
@@ -80,6 +72,7 @@ pub fn Pgsql(project_id: String) -> impl IntoView {
8072

8173
view! {
8274
<Provider value=pgsql>
75+
<AddPgsqlConnection show=show/>
8376
<div class="pl-1 text-xs">
8477
<div class="flex flex-row justify-between items-center">
8578
<button
@@ -131,6 +124,16 @@ pub fn Pgsql(project_id: String) -> impl IntoView {
131124

132125
<Icon icon=icondata::HiCircleStackOutlineLg width="12" height="12"/>
133126
</button>
127+
<button
128+
class="p-1 rounded-full hover:bg-gray-200"
129+
on:click=move |_| {
130+
pgsql.edit_connection_details();
131+
show.set(true);
132+
}
133+
>
134+
135+
<Icon icon=icondata::HiPencilSquareOutlineLg width="12" height="12"/>
136+
</button>
134137
<button
135138
class="p-1 rounded-full hover:bg-gray-200"
136139
on:click={

src/invoke.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ impl AsRef<str> for Invoke {
6262
#[derive(Serialize, Deserialize)]
6363
pub struct InvokePgsqlConnectorArgs<'a> {
6464
pub project_id: &'a str,
65-
pub key: Option<&'a str>,
65+
pub key: Option<[&'a str; 4]>,
6666
}
6767

6868
#[derive(Serialize, Deserialize)]
@@ -85,7 +85,7 @@ pub struct InvokePgsqlRunQueryArgs<'a> {
8585
#[derive(Serialize, Deserialize)]
8686
pub struct InvokeProjectDbInsertArgs<'a> {
8787
pub project_id: &'a str,
88-
pub project_details: &'a str,
88+
pub project_details: Vec<String>,
8989
}
9090

9191
#[derive(Serialize, Deserialize)]

0 commit comments

Comments
 (0)