Skip to content

Commit 624ea8e

Browse files
refactorings
1 parent 2afc5e0 commit 624ea8e

File tree

9 files changed

+134
-104
lines changed

9 files changed

+134
-104
lines changed

crates/pg_completions/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ tree-sitter.workspace = true
1212
tree_sitter_sql.workspace = true
1313
pg_schema_cache.workspace = true
1414
pg_test_utils.workspace = true
15+
tower-lsp.workspace = true
1516

1617
sqlx.workspace = true
1718

crates/pg_completions/src/builder.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,26 @@
1-
use crate::{item::CompletionItem, CompletionResult};
1+
use crate::{item::CompletionItemWithRelevance, CompletionResult};
22

33
pub(crate) struct CompletionBuilder {
4-
items: Vec<CompletionItem>,
4+
items: Vec<CompletionItemWithRelevance>,
55
}
66

77
impl CompletionBuilder {
88
pub fn new() -> Self {
99
CompletionBuilder { items: vec![] }
1010
}
1111

12-
pub fn add_item(&mut self, item: CompletionItem) {
12+
pub fn add_item(&mut self, item: CompletionItemWithRelevance) {
1313
self.items.push(item)
1414
}
1515

1616
pub fn finish(mut self) -> CompletionResult {
1717
self.items.sort_by(|a, b| {
1818
b.score()
1919
.cmp(&a.score())
20-
.then_with(|| a.label.cmp(&b.label))
20+
.then_with(|| a.label().cmp(&b.label()))
2121
});
2222

23-
self.items.dedup_by(|a, b| a.label == b.label);
23+
self.items.dedup_by(|a, b| a.label() == b.label());
2424
self.items.truncate(crate::LIMIT);
2525

2626
let Self { items, .. } = self;

crates/pg_completions/src/complete.rs

Lines changed: 58 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
use text_size::TextSize;
22

33
use crate::{
4-
builder::CompletionBuilder, context::CompletionContext, item::CompletionItem, providers,
4+
builder::CompletionBuilder, context::CompletionContext, item::CompletionItemWithRelevance,
5+
providers,
56
};
67

78
pub const LIMIT: usize = 50;
@@ -16,7 +17,7 @@ pub struct CompletionParams<'a> {
1617

1718
#[derive(Debug, Default)]
1819
pub struct CompletionResult {
19-
pub items: Vec<CompletionItem>,
20+
pub items: Vec<CompletionItemWithRelevance>,
2021
}
2122

2223
pub fn complete(params: CompletionParams) -> CompletionResult {
@@ -45,48 +46,34 @@ mod tests {
4546
use crate::{complete, CompletionParams};
4647

4748
#[tokio::test]
48-
async fn test_complete() {
49-
let pool = get_new_test_db().await;
50-
51-
let input = "select id from c;";
52-
53-
let mut parser = tree_sitter::Parser::new();
54-
parser
55-
.set_language(tree_sitter_sql::language())
56-
.expect("Error loading sql language");
57-
58-
let tree = parser.parse(input, None).unwrap();
59-
60-
let schema_cache = SchemaCache::load(&pool).await;
61-
62-
let p = CompletionParams {
63-
position: 15.into(),
64-
schema: &schema_cache,
65-
text: input,
66-
tree: Some(&tree),
67-
};
68-
69-
let result = complete(p);
49+
async fn autocompletes_simple_table() {
50+
let test_db = get_new_test_db().await;
7051

71-
assert!(result.items.len() > 0);
72-
}
52+
let setup = r#"
53+
create table users (
54+
id serial primary key,
55+
name text,
56+
password text
57+
);
58+
"#;
7359

74-
#[tokio::test]
75-
async fn test_complete_two() {
76-
let pool = get_new_test_db().await;
60+
test_db
61+
.execute(setup)
62+
.await
63+
.expect("Failed to execute setup query");
7764

78-
let input = "select id, name, test1231234123, unknown from co;";
65+
let input = "select * from u";
7966

8067
let mut parser = tree_sitter::Parser::new();
8168
parser
8269
.set_language(tree_sitter_sql::language())
8370
.expect("Error loading sql language");
8471

8572
let tree = parser.parse(input, None).unwrap();
86-
let schema_cache = SchemaCache::load(&pool).await;
73+
let schema_cache = SchemaCache::load(&test_db).await;
8774

8875
let p = CompletionParams {
89-
position: 47.into(),
76+
position: ((input.len() - 1) as u32).into(),
9077
schema: &schema_cache,
9178
text: input,
9279
tree: Some(&tree),
@@ -95,52 +82,71 @@ mod tests {
9582
let result = complete(p);
9683

9784
assert!(result.items.len() > 0);
85+
86+
let best_match = &result.items[0];
87+
88+
assert_eq!(
89+
best_match.label, "users",
90+
"Does not return the expected table to autocomplete: {}",
91+
best_match.label
92+
)
9893
}
9994

100-
#[tokio::test]
101-
async fn test_complete_three() {
95+
async fn autocompletes_table_with_schema() {
10296
let test_db = get_new_test_db().await;
10397

10498
let setup = r#"
105-
create table users (
99+
create schema public;
100+
create schema private;
101+
102+
create table private.users (
106103
id serial primary key,
107104
name text,
108105
password text
109106
);
107+
108+
create table public.user_requests (
109+
id serial primary key,
110+
request text,
111+
send_at timestamp with time zone
112+
);
110113
"#;
111114

112115
test_db
113116
.execute(setup)
114117
.await
115118
.expect("Failed to execute setup query");
116119

117-
let input = "select * from u";
120+
let schema_cache = SchemaCache::load(&test_db).await;
118121

119122
let mut parser = tree_sitter::Parser::new();
120123
parser
121124
.set_language(tree_sitter_sql::language())
122125
.expect("Error loading sql language");
123126

124-
let tree = parser.parse(input, None).unwrap();
125-
let schema_cache = SchemaCache::load(&test_db).await;
127+
// testing the private schema
128+
{
129+
let input = "select * from private.u";
130+
let tree = parser.parse(input, None).unwrap();
126131

127-
let p = CompletionParams {
128-
position: ((input.len() - 1) as u32).into(),
129-
schema: &schema_cache,
130-
text: input,
131-
tree: Some(&tree),
132-
};
132+
let p = CompletionParams {
133+
position: ((input.len() - 1) as u32).into(),
134+
schema: &schema_cache,
135+
text: input,
136+
tree: Some(&tree),
137+
};
133138

134-
let result = complete(p);
139+
let result = complete(p);
135140

136-
assert!(result.items.len() > 0);
141+
assert!(result.items.len() > 0);
137142

138-
let best_match = &result.items[0];
143+
let best_match = &result.items[0];
139144

140-
assert_eq!(
141-
best_match.label, "users",
142-
"Does not return the expected table to autocomplete: {}",
143-
best_match.label
144-
)
145+
assert_eq!(
146+
best_match.label, "users",
147+
"Does not return the expected table to autocomplete: {}",
148+
best_match.label
149+
)
150+
}
145151
}
146152
}

crates/pg_completions/src/data.rs

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
use tower_lsp::lsp_types::{CompletionItem, CompletionItemKind, CompletionItemLabelDetails};
2+
3+
#[derive(Debug)]
4+
pub(crate) enum CompletionItemData<'a> {
5+
Table(&'a pg_schema_cache::Table),
6+
}
7+
8+
impl<'a> Into<CompletionItem> for CompletionItemData<'a> {
9+
fn into(self) -> CompletionItem {
10+
match self {
11+
Self::Table(tb) => CompletionItem {
12+
label: tb.name.clone(),
13+
label_details: Some(CompletionItemLabelDetails {
14+
description: Some(format!("Schema: {}", tb.schema)),
15+
detail: None,
16+
}),
17+
kind: Some(CompletionItemKind::CLASS),
18+
detail: None,
19+
documentation: None,
20+
deprecated: None,
21+
preselect: None,
22+
sort_text: None,
23+
filter_text: None,
24+
insert_text: None,
25+
insert_text_format: None,
26+
insert_text_mode: None,
27+
text_edit: None,
28+
additional_text_edits: None,
29+
commit_characters: None,
30+
data: None,
31+
tags: None,
32+
command: None,
33+
},
34+
}
35+
}
36+
}

crates/pg_completions/src/item.rs

Lines changed: 11 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,41 +1,26 @@
1-
use text_size::TextRange;
1+
use tower_lsp::lsp_types;
22

3-
use crate::relevance::CompletionRelevance;
3+
use crate::{data::CompletionItemData, relevance::CompletionRelevance};
44

55
#[derive(Debug)]
6-
pub enum CompletionItemData<'a> {
7-
Table(&'a pg_schema_cache::Table),
8-
}
9-
10-
impl<'a> CompletionItemData<'a> {
11-
pub fn label(&self) -> String {
12-
match self {
13-
CompletionItemData::Table(t) => t.name.clone(),
14-
}
15-
}
16-
}
17-
18-
#[derive(Debug)]
19-
pub struct CompletionItem {
20-
pub range: TextRange,
21-
pub label: String,
6+
pub struct CompletionItemWithRelevance {
7+
item: lsp_types::CompletionItem,
228
relevance: CompletionRelevance,
239
}
2410

25-
impl CompletionItem {
26-
pub(crate) fn new(
27-
range: TextRange,
28-
data: CompletionItemData,
29-
relevance: CompletionRelevance,
30-
) -> Self {
11+
impl CompletionItemWithRelevance {
12+
pub(crate) fn new(data: CompletionItemData, relevance: CompletionRelevance) -> Self {
3113
Self {
32-
range,
33-
label: data.label(),
14+
item: data.into(),
3415
relevance,
3516
}
3617
}
3718

3819
pub(crate) fn score(&self) -> i32 {
3920
self.relevance.score()
4021
}
22+
23+
pub(crate) fn label(&self) -> &str {
24+
&self.item.label
25+
}
4126
}

crates/pg_completions/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
mod builder;
22
mod complete;
33
mod context;
4+
mod data;
45
mod item;
56
mod providers;
67
mod relevance;
Lines changed: 6 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,14 @@
11
use pg_schema_cache::Table;
2-
use text_size::{TextRange, TextSize};
32

43
use crate::{
5-
builder::CompletionBuilder,
6-
context::CompletionContext,
7-
item::{CompletionItem, CompletionItemData},
8-
relevance::CompletionRelevance,
4+
builder::CompletionBuilder, context::CompletionContext, data::CompletionItemData,
5+
item::CompletionItemWithRelevance, relevance::CompletionRelevance,
96
};
107

118
pub fn complete_tables(ctx: &CompletionContext, builder: &mut CompletionBuilder) {
129
let available_tables = &ctx.schema_cache.tables;
1310

14-
let completion_items: Vec<CompletionItem> = available_tables
11+
let completion_items: Vec<CompletionItemWithRelevance> = available_tables
1512
.iter()
1613
.map(|table| to_completion_item(ctx, table))
1714
.collect();
@@ -21,18 +18,8 @@ pub fn complete_tables(ctx: &CompletionContext, builder: &mut CompletionBuilder)
2118
}
2219
}
2320

24-
fn to_completion_item(ctx: &CompletionContext, table: &Table) -> CompletionItem {
21+
fn to_completion_item(ctx: &CompletionContext, table: &Table) -> CompletionItemWithRelevance {
2522
let data = CompletionItemData::Table(table);
26-
27-
let start = ctx.position;
28-
let end = start + TextSize::from(table.name.len() as u32);
29-
let range = TextRange::new(start, end);
30-
31-
let mut relevance = CompletionRelevance::default();
32-
33-
relevance.set_is_catalog(&table.schema);
34-
relevance.set_matches_prefix(ctx, &table.name);
35-
relevance.set_matches_schema(ctx, &table.schema);
36-
37-
CompletionItem::new(range, data, relevance)
23+
let relevance = CompletionRelevance::from_data_and_ctx(&data, ctx);
24+
CompletionItemWithRelevance::new(data, relevance)
3825
}

crates/pg_completions/src/relevance.rs

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use crate::context::CompletionContext;
1+
use crate::{context::CompletionContext, data::CompletionItemData};
22

33
#[derive(Debug, Default)]
44
pub(crate) struct CompletionRelevance {
@@ -14,6 +14,20 @@ pub(crate) struct CompletionRelevance {
1414
}
1515

1616
impl CompletionRelevance {
17+
pub fn from_data_and_ctx(data: &CompletionItemData, ctx: &CompletionContext) -> Self {
18+
let mut relevance = CompletionRelevance::default();
19+
20+
match data {
21+
CompletionItemData::Table(tb) => {
22+
relevance.set_is_catalog(&tb.schema);
23+
relevance.set_matches_schema(ctx, &tb.schema);
24+
relevance.set_matches_prefix(ctx, &tb.name);
25+
}
26+
}
27+
28+
relevance
29+
}
30+
1731
pub fn score(&self) -> i32 {
1832
let mut score: i32 = 0;
1933

crates/pg_lsp/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ text-size = "1.1.1"
2323

2424
line_index.workspace = true
2525
sqlx.workspace = true
26+
tower-lsp.workspace = true
2627

2728
pg_hover.workspace = true
2829
pg_fs.workspace = true
@@ -35,7 +36,6 @@ pg_workspace.workspace = true
3536
pg_diagnostics.workspace = true
3637
tokio = { version = "1.40.0", features = ["io-std", "macros", "rt-multi-thread", "sync", "time"] }
3738
tokio-util = "0.7.12"
38-
tower-lsp = "0.20.0"
3939
tracing = "0.1.40"
4040
tracing-subscriber = "0.3.18"
4141

0 commit comments

Comments
 (0)