1use gpui::Axis;
2use indoc::indoc;
3use sqlez::{connection::Connection, migrations::Migration};
4use util::{iife, ResultExt};
5
6use super::{
7 model::{PaneGroupId, PaneId, SerializedDockPane, SerializedPaneGroup, WorkspaceId},
8 Db,
9};
10
11pub(crate) const PANE_MIGRATIONS: Migration = Migration::new(
12 "pane",
13 &[indoc! {"
14 CREATE TABLE pane_groups(
15 group_id INTEGER PRIMARY KEY,
16 workspace_id BLOB NOT NULL,
17 parent_group INTEGER, -- NULL indicates that this is a root node
18 axis TEXT NOT NULL, -- Enum: 'Vertical' / 'Horizontal'
19 FOREIGN KEY(workspace_id) REFERENCES workspaces(workspace_id) ON DELETE CASCADE,
20 FOREIGN KEY(parent_group) REFERENCES pane_groups(group_id) ON DELETE CASCADE
21 PRIMARY KEY(group_id, workspace_id)
22 ) STRICT;
23
24 CREATE TABLE panes(
25 pane_id INTEGER PRIMARY KEY,
26 workspace_id BLOB NOT NULL,
27 group_id INTEGER, -- If null, this is a dock pane
28 idx INTEGER NOT NULL,
29 FOREIGN KEY(workspace_id) REFERENCES workspaces(workspace_id) ON DELETE CASCADE,
30 FOREIGN KEY(group_id) REFERENCES pane_groups(group_id) ON DELETE CASCADE
31 PRIMARY KEY(pane_id, workspace_id)
32 ) STRICT;
33
34 CREATE TABLE items(
35 item_id INTEGER NOT NULL, -- This is the item's view id, so this is not unique
36 pane_id INTEGER NOT NULL,
37 workspace_id BLOB NOT NULL,
38 kind TEXT NOT NULL,
39 FOREIGN KEY(workspace_id) REFERENCES workspaces(workspace_id) ON DELETE CASCADE
40 FOREIGN KEY(pane_id) REFERENCES panes(pane_id) ON DELETE CASCADE
41 PRIMARY KEY(item_id, workspace_id)
42 ) STRICT;
43 "}],
44);
45
46impl Db {
47 pub(crate) fn get_center_group(&self, _workspace: WorkspaceId) -> SerializedPaneGroup {
48 unimplemented!()
49 }
50
51 pub fn get_pane_group(&self, _pane_group_id: PaneGroupId) -> SerializedPaneGroup {
52 unimplemented!()
53 // let axis = self.get_pane_group_axis(pane_group_id);
54 // let mut children: Vec<(usize, PaneGroupChild)> = Vec::new();
55 // for child_row in self.get_pane_group_children(pane_group_id) {
56 // if let Some(child_pane_id) = child_row.child_pane_id {
57 // children.push((
58 // child_row.index,
59 // PaneGroupChild::Pane(self.get_pane(PaneId {
60 // workspace_id: pane_group_id.workspace_id,
61 // pane_id: child_pane_id,
62 // })),
63 // ));
64 // } else if let Some(child_group_id) = child_row.child_group_id {
65 // children.push((
66 // child_row.index,
67 // PaneGroupChild::Group(self.get_pane_group(PaneGroupId {
68 // workspace_id: pane_group_id.workspace_id,
69 // group_id: child_group_id,
70 // })),
71 // ));
72 // }
73 // }
74 // children.sort_by_key(|(index, _)| *index);
75
76 // SerializedPaneGroup {
77 // group_id: pane_group_id,
78 // axis,
79 // children: children.into_iter().map(|(_, child)| child).collect(),
80 // }
81 }
82
83 // fn _get_pane_group_children(
84 // &self,
85 // _pane_group_id: PaneGroupId,
86 // ) -> impl Iterator<Item = PaneGroupChildRow> {
87 // Vec::new().into_iter()
88 // }
89
90 pub(crate) fn save_center_group(
91 _workspace: &WorkspaceId,
92 _center_pane_group: &SerializedPaneGroup,
93 _connection: &Connection,
94 ) {
95 // Delete the center pane group for this workspace and any of its children
96 // Generate new pane group IDs as we go through
97 // insert them
98 }
99
100 pub fn _get_pane(&self, _pane_id: PaneId) -> SerializedPane {
101 unimplemented!();
102 }
103
104 pub(crate) fn get_dock_pane(&self, workspace: WorkspaceId) -> Option<SerializedDockPane> {
105 iife!({
106 self.prepare("SELECT anchor_position, visible FROM dock_panes WHERE workspace_id = ?")?
107 .with_bindings(workspace)?
108 .maybe_row::<SerializedDockPane>()
109 })
110 .log_err()
111 .flatten()
112 }
113
114 pub(crate) fn save_dock_pane(
115 workspace: &WorkspaceId,
116 dock_pane: &SerializedDockPane,
117 connection: &Connection,
118 ) {
119 // iife!({
120 // self.prepare(
121 // "INSERT INTO dock_panes (workspace_id, anchor_position, visible) VALUES (?, ?, ?);",
122 // )?
123 // .with_bindings(dock_pane.to_row(workspace))?
124 // .insert()
125 // })
126 // .log_err();
127 }
128}
129
130#[cfg(test)]
131mod tests {
132
133 // use crate::{items::ItemId, pane::SerializedPane, Db, DockAnchor};
134
135 // use super::{PaneGroupChild, SerializedDockPane, SerializedPaneGroup};
136
137 // #[test]
138 // fn test_basic_dock_pane() {
139 // let db = Db::open_in_memory("basic_dock_pane");
140
141 // let workspace = db.workspace_for_roots(&["/tmp"]);
142
143 // let dock_pane = SerializedDockPane {
144 // anchor_position: DockAnchor::Expanded,
145 // visible: true,
146 // };
147
148 // db.save_dock_pane(&workspace.workspace_id, &dock_pane);
149
150 // let new_workspace = db.workspace_for_roots(&["/tmp"]);
151
152 // assert_eq!(new_workspace.dock_pane.unwrap(), dock_pane);
153 // }
154
155 // #[test]
156 // fn test_dock_simple_split() {
157 // let db = Db::open_in_memory("simple_split");
158
159 // let workspace = db.workspace_for_roots(&["/tmp"]);
160
161 // // Pane group -> Pane -> 10 , 20
162 // let center_pane = SerializedPaneGroup {
163 // axis: gpui::Axis::Horizontal,
164 // children: vec![PaneGroupChild::Pane(SerializedPane {
165 // items: vec![ItemId { item_id: 10 }, ItemId { item_id: 20 }],
166 // })],
167 // };
168
169 // db.save_pane_splits(&workspace.workspace_id, ¢er_pane);
170
171 // // let new_workspace = db.workspace_for_roots(&["/tmp"]);
172
173 // // assert_eq!(new_workspace.center_group, center_pane);
174 // }
175}