Add typed statements
This commit is contained in:
parent
64ac84fdf4
commit
4a00f0b062
14 changed files with 388 additions and 394 deletions
|
@ -15,24 +15,19 @@ pub(crate) const KVP_MIGRATION: Migration = Migration::new(
|
|||
|
||||
impl Db {
|
||||
pub fn read_kvp(&self, key: &str) -> Result<Option<String>> {
|
||||
self.0
|
||||
.prepare("SELECT value FROM kv_store WHERE key = (?)")?
|
||||
.with_bindings(key)?
|
||||
.maybe_row()
|
||||
self.select_row_bound("SELECT value FROM kv_store WHERE key = (?)")?(key)
|
||||
}
|
||||
|
||||
pub fn write_kvp(&self, key: &str, value: &str) -> Result<()> {
|
||||
self.0
|
||||
.prepare("INSERT OR REPLACE INTO kv_store(key, value) VALUES ((?), (?))")?
|
||||
.with_bindings((key, value))?
|
||||
.exec()
|
||||
self.exec_bound("INSERT OR REPLACE INTO kv_store(key, value) VALUES ((?), (?))")?((
|
||||
key, value,
|
||||
))?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn delete_kvp(&self, key: &str) -> Result<()> {
|
||||
self.0
|
||||
.prepare("DELETE FROM kv_store WHERE key = (?)")?
|
||||
.with_bindings(key)?
|
||||
.exec()
|
||||
self.exec_bound("DELETE FROM kv_store WHERE key = (?)")?(key)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -22,7 +22,7 @@ pub(crate) const WORKSPACES_MIGRATION: Migration = Migration::new(
|
|||
"}],
|
||||
);
|
||||
|
||||
use self::model::{SerializedWorkspace, WorkspaceId, WorkspaceRow};
|
||||
use self::model::{SerializedWorkspace, WorkspaceId};
|
||||
|
||||
use super::Db;
|
||||
|
||||
|
@ -40,21 +40,19 @@ impl Db {
|
|||
// and we've grabbed the most recent workspace
|
||||
let (workspace_id, dock_anchor, dock_visible) = iife!({
|
||||
if worktree_roots.len() == 0 {
|
||||
self.prepare(indoc! {"
|
||||
self.select_row(indoc! {"
|
||||
SELECT workspace_id, dock_anchor, dock_visible
|
||||
FROM workspaces
|
||||
ORDER BY timestamp DESC LIMIT 1"})?
|
||||
.maybe_row::<WorkspaceRow>()
|
||||
ORDER BY timestamp DESC LIMIT 1"})?()?
|
||||
} else {
|
||||
self.prepare(indoc! {"
|
||||
self.select_row_bound(indoc! {"
|
||||
SELECT workspace_id, dock_anchor, dock_visible
|
||||
FROM workspaces
|
||||
WHERE workspace_id = ?"})?
|
||||
.with_bindings(&workspace_id)?
|
||||
.maybe_row::<WorkspaceRow>()
|
||||
WHERE workspace_id = ?"})?(&workspace_id)?
|
||||
}
|
||||
.context("No workspaces found")
|
||||
})
|
||||
.log_err()
|
||||
.warn_on_err()
|
||||
.flatten()?;
|
||||
|
||||
Some(SerializedWorkspace {
|
||||
|
@ -85,23 +83,17 @@ impl Db {
|
|||
if let Some(old_roots) = old_roots {
|
||||
let old_id: WorkspaceId = old_roots.into();
|
||||
|
||||
self.prepare("DELETE FROM WORKSPACES WHERE workspace_id = ?")?
|
||||
.with_bindings(&old_id)?
|
||||
.exec()?;
|
||||
self.exec_bound("DELETE FROM WORKSPACES WHERE workspace_id = ?")?(&old_id)?;
|
||||
}
|
||||
|
||||
// Delete any previous workspaces with the same roots. This cascades to all
|
||||
// other tables that are based on the same roots set.
|
||||
// Insert new workspace into workspaces table if none were found
|
||||
self.prepare("DELETE FROM workspaces WHERE workspace_id = ?;")?
|
||||
.with_bindings(&workspace_id)?
|
||||
.exec()?;
|
||||
self.exec_bound("DELETE FROM workspaces WHERE workspace_id = ?;")?(&workspace_id)?;
|
||||
|
||||
self.prepare(
|
||||
self.exec_bound(
|
||||
"INSERT INTO workspaces(workspace_id, dock_anchor, dock_visible) VALUES (?, ?, ?)",
|
||||
)?
|
||||
.with_bindings((&workspace_id, workspace.dock_anchor, workspace.dock_visible))?
|
||||
.exec()?;
|
||||
)?((&workspace_id, workspace.dock_anchor, workspace.dock_visible))?;
|
||||
|
||||
// Save center pane group and dock pane
|
||||
self.save_pane_group(&workspace_id, &workspace.center_group, None)?;
|
||||
|
@ -126,11 +118,9 @@ impl Db {
|
|||
iife!({
|
||||
// TODO, upgrade anyhow: https://docs.rs/anyhow/1.0.66/anyhow/fn.Ok.html
|
||||
Ok::<_, anyhow::Error>(
|
||||
self.prepare(
|
||||
self.select_bound::<usize, WorkspaceId>(
|
||||
"SELECT workspace_id FROM workspaces ORDER BY timestamp DESC LIMIT ?",
|
||||
)?
|
||||
.with_bindings(limit)?
|
||||
.rows::<WorkspaceId>()?
|
||||
)?(limit)?
|
||||
.into_iter()
|
||||
.map(|id| id.paths())
|
||||
.collect::<Vec<Vec<PathBuf>>>(),
|
||||
|
|
|
@ -3,7 +3,7 @@ use indoc::indoc;
|
|||
use sqlez::migrations::Migration;
|
||||
|
||||
use crate::{
|
||||
model::{ItemId, PaneId, SerializedItem, SerializedItemKind, WorkspaceId},
|
||||
model::{PaneId, SerializedItem, SerializedItemKind, WorkspaceId},
|
||||
Db,
|
||||
};
|
||||
|
||||
|
@ -29,19 +29,16 @@ pub(crate) const ITEM_MIGRATIONS: Migration = Migration::new(
|
|||
|
||||
impl Db {
|
||||
pub(crate) fn get_items(&self, pane_id: PaneId) -> Result<Vec<SerializedItem>> {
|
||||
Ok(self
|
||||
.prepare(indoc! {"
|
||||
Ok(self.select_bound(indoc! {"
|
||||
SELECT item_id, kind FROM items
|
||||
WHERE pane_id = ?
|
||||
ORDER BY position"})?
|
||||
.with_bindings(pane_id)?
|
||||
.rows::<(ItemId, SerializedItemKind)>()?
|
||||
.into_iter()
|
||||
.map(|(item_id, kind)| match kind {
|
||||
SerializedItemKind::Terminal => SerializedItem::Terminal { item_id },
|
||||
_ => unimplemented!(),
|
||||
})
|
||||
.collect())
|
||||
ORDER BY position"})?(pane_id)?
|
||||
.into_iter()
|
||||
.map(|(item_id, kind)| match kind {
|
||||
SerializedItemKind::Terminal => SerializedItem::Terminal { item_id },
|
||||
_ => unimplemented!(),
|
||||
})
|
||||
.collect())
|
||||
}
|
||||
|
||||
pub(crate) fn save_items(
|
||||
|
@ -51,19 +48,14 @@ impl Db {
|
|||
items: &[SerializedItem],
|
||||
) -> Result<()> {
|
||||
let mut delete_old = self
|
||||
.prepare("DELETE FROM items WHERE workspace_id = ? AND pane_id = ? AND item_id = ?")
|
||||
.exec_bound("DELETE FROM items WHERE workspace_id = ? AND pane_id = ? AND item_id = ?")
|
||||
.context("Preparing deletion")?;
|
||||
let mut insert_new = self.prepare(
|
||||
let mut insert_new = self.exec_bound(
|
||||
"INSERT INTO items(item_id, workspace_id, pane_id, kind, position) VALUES (?, ?, ?, ?, ?)",
|
||||
).context("Preparing insertion")?;
|
||||
for (position, item) in items.iter().enumerate() {
|
||||
delete_old
|
||||
.with_bindings((workspace_id, pane_id, item.item_id()))?
|
||||
.exec()?;
|
||||
|
||||
insert_new
|
||||
.with_bindings((item.item_id(), workspace_id, pane_id, item.kind(), position))?
|
||||
.exec()?;
|
||||
delete_old((workspace_id, pane_id, item.item_id()))?;
|
||||
insert_new((item.item_id(), workspace_id, pane_id, item.kind(), position))?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
|
|
|
@ -80,8 +80,6 @@ impl Column for DockAnchor {
|
|||
}
|
||||
}
|
||||
|
||||
pub(crate) type WorkspaceRow = (WorkspaceId, DockAnchor, bool);
|
||||
|
||||
#[derive(Debug, PartialEq, Eq)]
|
||||
pub struct SerializedWorkspace {
|
||||
pub dock_anchor: DockAnchor,
|
||||
|
@ -240,23 +238,20 @@ mod tests {
|
|||
workspace_id BLOB,
|
||||
dock_anchor TEXT
|
||||
);"})
|
||||
.unwrap();
|
||||
.unwrap()()
|
||||
.unwrap();
|
||||
|
||||
let workspace_id: WorkspaceId = WorkspaceId::from(&["\test2", "\test1"]);
|
||||
|
||||
db.prepare("INSERT INTO workspace_id_test(workspace_id, dock_anchor) VALUES (?,?)")
|
||||
.unwrap()
|
||||
.with_bindings((&workspace_id, DockAnchor::Bottom))
|
||||
.unwrap()
|
||||
.exec()
|
||||
.unwrap();
|
||||
db.exec_bound("INSERT INTO workspace_id_test(workspace_id, dock_anchor) VALUES (?,?)")
|
||||
.unwrap()((&workspace_id, DockAnchor::Bottom))
|
||||
.unwrap();
|
||||
|
||||
assert_eq!(
|
||||
db.prepare("SELECT workspace_id, dock_anchor FROM workspace_id_test LIMIT 1")
|
||||
.unwrap()
|
||||
.row::<(WorkspaceId, DockAnchor)>()
|
||||
.unwrap(),
|
||||
(WorkspaceId::from(&["\test1", "\test2"]), DockAnchor::Bottom)
|
||||
db.select_row("SELECT workspace_id, dock_anchor FROM workspace_id_test LIMIT 1")
|
||||
.unwrap()()
|
||||
.unwrap(),
|
||||
Some((WorkspaceId::from(&["\test1", "\test2"]), DockAnchor::Bottom))
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use anyhow::{bail, Context, Result};
|
||||
use indoc::indoc;
|
||||
use sqlez::{migrations::Migration, statement::Statement};
|
||||
use sqlez::migrations::Migration;
|
||||
use util::unzip_option;
|
||||
|
||||
use crate::model::{Axis, GroupId, PaneId, SerializedPane};
|
||||
|
@ -39,38 +39,29 @@ impl Db {
|
|||
&self,
|
||||
workspace_id: &WorkspaceId,
|
||||
) -> Result<SerializedPaneGroup> {
|
||||
let mut query = self.prepare(indoc! {"
|
||||
SELECT group_id, axis, pane_id
|
||||
FROM (SELECT group_id, axis, NULL as pane_id, position, parent_group_id, workspace_id
|
||||
FROM pane_groups
|
||||
UNION
|
||||
SELECT NULL, NULL, pane_id, position, parent_group_id, workspace_id
|
||||
FROM panes
|
||||
-- Remove the dock panes from the union
|
||||
WHERE parent_group_id IS NOT NULL and position IS NOT NULL)
|
||||
WHERE parent_group_id IS ? AND workspace_id = ?
|
||||
ORDER BY position
|
||||
"})?;
|
||||
|
||||
self.get_pane_group_children(workspace_id, None, &mut query)?
|
||||
self.get_pane_group_children(workspace_id, None)?
|
||||
.into_iter()
|
||||
.next()
|
||||
.context("No center pane group")
|
||||
}
|
||||
|
||||
fn get_pane_group_children(
|
||||
fn get_pane_group_children<'a>(
|
||||
&self,
|
||||
workspace_id: &WorkspaceId,
|
||||
group_id: Option<GroupId>,
|
||||
query: &mut Statement,
|
||||
) -> Result<Vec<SerializedPaneGroup>> {
|
||||
let children = query.with_bindings((group_id, workspace_id))?.rows::<(
|
||||
Option<GroupId>,
|
||||
Option<Axis>,
|
||||
Option<PaneId>,
|
||||
)>()?;
|
||||
|
||||
children
|
||||
self.select_bound::<(Option<GroupId>, &WorkspaceId), (Option<GroupId>, Option<Axis>, Option<PaneId>)>(indoc! {"
|
||||
SELECT group_id, axis, pane_id
|
||||
FROM (SELECT group_id, axis, NULL as pane_id, position, parent_group_id, workspace_id
|
||||
FROM pane_groups
|
||||
UNION
|
||||
SELECT NULL, NULL, pane_id, position, parent_group_id, workspace_id
|
||||
FROM panes
|
||||
-- Remove the dock panes from the union
|
||||
WHERE parent_group_id IS NOT NULL and position IS NOT NULL)
|
||||
WHERE parent_group_id IS ? AND workspace_id = ?
|
||||
ORDER BY position
|
||||
"})?((group_id, workspace_id))?
|
||||
.into_iter()
|
||||
.map(|(group_id, axis, pane_id)| {
|
||||
if let Some((group_id, axis)) = group_id.zip(axis) {
|
||||
|
@ -79,7 +70,6 @@ impl Db {
|
|||
children: self.get_pane_group_children(
|
||||
workspace_id,
|
||||
Some(group_id),
|
||||
query,
|
||||
)?,
|
||||
})
|
||||
} else if let Some(pane_id) = pane_id {
|
||||
|
@ -107,9 +97,8 @@ impl Db {
|
|||
|
||||
match pane_group {
|
||||
SerializedPaneGroup::Group { axis, children } => {
|
||||
let parent_id = self.prepare("INSERT INTO pane_groups(workspace_id, parent_group_id, position, axis) VALUES (?, ?, ?, ?)")?
|
||||
.with_bindings((workspace_id, parent_id, position, *axis))?
|
||||
.insert()? as GroupId;
|
||||
let parent_id = self.insert_bound("INSERT INTO pane_groups(workspace_id, parent_group_id, position, axis) VALUES (?, ?, ?, ?)")?
|
||||
((workspace_id, parent_id, position, *axis))?;
|
||||
|
||||
for (position, group) in children.iter().enumerate() {
|
||||
self.save_pane_group(workspace_id, group, Some((parent_id, position)))?
|
||||
|
@ -121,12 +110,12 @@ impl Db {
|
|||
}
|
||||
|
||||
pub(crate) fn get_dock_pane(&self, workspace_id: &WorkspaceId) -> Result<SerializedPane> {
|
||||
let pane_id = self
|
||||
.prepare(indoc! {"
|
||||
let pane_id = self.select_row_bound(indoc! {"
|
||||
SELECT pane_id FROM panes
|
||||
WHERE workspace_id = ? AND parent_group_id IS NULL AND position IS NULL"})?
|
||||
.with_bindings(workspace_id)?
|
||||
.row::<PaneId>()?;
|
||||
WHERE workspace_id = ? AND parent_group_id IS NULL AND position IS NULL"})?(
|
||||
workspace_id,
|
||||
)?
|
||||
.context("No dock pane for workspace")?;
|
||||
|
||||
Ok(SerializedPane::new(
|
||||
self.get_items(pane_id).context("Reading items")?,
|
||||
|
@ -141,10 +130,9 @@ impl Db {
|
|||
) -> Result<()> {
|
||||
let (parent_id, order) = unzip_option(parent);
|
||||
|
||||
let pane_id = self
|
||||
.prepare("INSERT INTO panes(workspace_id, parent_group_id, position) VALUES (?, ?, ?)")?
|
||||
.with_bindings((workspace_id, parent_id, order))?
|
||||
.insert()? as PaneId;
|
||||
let pane_id = self.insert_bound(
|
||||
"INSERT INTO panes(workspace_id, parent_group_id, position) VALUES (?, ?, ?)",
|
||||
)?((workspace_id, parent_id, order))?;
|
||||
|
||||
self.save_items(workspace_id, pane_id, &pane.children)
|
||||
.context("Saving items")
|
||||
|
|
Binary file not shown.
Loading…
Add table
Add a link
Reference in a new issue