diff --git a/crates/pgt_cli/src/cli_options.rs b/crates/pgt_cli/src/cli_options.rs index d1bfaee9..5c41c7fc 100644 --- a/crates/pgt_cli/src/cli_options.rs +++ b/crates/pgt_cli/src/cli_options.rs @@ -18,10 +18,6 @@ pub struct CliOptions { #[bpaf(long("use-server"), switch, fallback(false))] pub use_server: bool, - /// Skip connecting to the database and only run checks that don't require a database connection. - #[bpaf(long("skip-db"), switch, fallback(false))] - pub skip_db: bool, - /// Print additional diagnostics, and some diagnostics show more information. Also, print out what files were processed and which ones were modified. #[bpaf(long("verbose"), switch, fallback(false))] pub verbose: bool, diff --git a/crates/pgt_cli/src/commands/mod.rs b/crates/pgt_cli/src/commands/mod.rs index b166a033..ebd16e3d 100644 --- a/crates/pgt_cli/src/commands/mod.rs +++ b/crates/pgt_cli/src/commands/mod.rs @@ -307,7 +307,6 @@ pub(crate) trait CommandRunner: Sized { configuration, vcs_base_path, gitignore_matches, - skip_db: cli_options.skip_db, })?; let execution = self.get_execution(cli_options, console, workspace)?; diff --git a/crates/pgt_configuration/src/database.rs b/crates/pgt_configuration/src/database.rs index 209f86dc..39efb8d1 100644 --- a/crates/pgt_configuration/src/database.rs +++ b/crates/pgt_configuration/src/database.rs @@ -10,6 +10,8 @@ use serde::{Deserialize, Serialize}; #[partial(serde(rename_all = "camelCase", default, deny_unknown_fields))] pub struct DatabaseConfiguration { /// The host of the database. + /// Required if you want database-related features. + /// All else falls back to sensible defaults. #[partial(bpaf(long("host")))] pub host: String, @@ -35,11 +37,17 @@ pub struct DatabaseConfiguration { /// The connection timeout in seconds. #[partial(bpaf(long("conn_timeout_secs"), fallback(Some(10)), debug_fallback))] pub conn_timeout_secs: u16, + + /// Actively disable all database-related features. + #[partial(bpaf(long("disable-db"), switch, fallback(Some(false))))] + #[partial(cfg_attr(feature = "schema", schemars(skip)))] + pub disable_connection: bool, } impl Default for DatabaseConfiguration { fn default() -> Self { Self { + disable_connection: false, host: "127.0.0.1".to_string(), port: 5432, username: "postgres".to_string(), diff --git a/crates/pgt_configuration/src/lib.rs b/crates/pgt_configuration/src/lib.rs index f262450d..fcf0b5c6 100644 --- a/crates/pgt_configuration/src/lib.rs +++ b/crates/pgt_configuration/src/lib.rs @@ -110,8 +110,9 @@ impl PartialConfiguration { username: Some("postgres".to_string()), password: Some("postgres".to_string()), database: Some("postgres".to_string()), - conn_timeout_secs: Some(10), allow_statement_executions_against: Default::default(), + conn_timeout_secs: Some(10), + disable_connection: Some(false), }), } } diff --git a/crates/pgt_lsp/src/session.rs b/crates/pgt_lsp/src/session.rs index 64adf16a..db17dfd1 100644 --- a/crates/pgt_lsp/src/session.rs +++ b/crates/pgt_lsp/src/session.rs @@ -449,7 +449,6 @@ impl Session { configuration: fs_configuration, vcs_base_path, gitignore_matches, - skip_db: false, }); if let Err(error) = result { diff --git a/crates/pgt_lsp/tests/server.rs b/crates/pgt_lsp/tests/server.rs index 8e40c097..581ea1fe 100644 --- a/crates/pgt_lsp/tests/server.rs +++ b/crates/pgt_lsp/tests/server.rs @@ -773,14 +773,15 @@ async fn test_execute_statement() -> Result<()> { .to_string(); let host = test_db.connect_options().get_host().to_string(); - let conf = PartialConfiguration { + let mut conf = PartialConfiguration::init(); + conf.merge_with(PartialConfiguration { db: Some(PartialDatabaseConfiguration { database: Some(database), host: Some(host), ..Default::default() }), ..Default::default() - }; + }); fs.insert( url!("postgrestools.jsonc").to_file_path().unwrap(), diff --git a/crates/pgt_workspace/src/settings.rs b/crates/pgt_workspace/src/settings.rs index d4ea462a..f9275aa9 100644 --- a/crates/pgt_workspace/src/settings.rs +++ b/crates/pgt_workspace/src/settings.rs @@ -268,6 +268,7 @@ impl Default for LinterSettings { /// Database settings for the entire workspace #[derive(Debug)] pub struct DatabaseSettings { + pub enable_connection: bool, pub host: String, pub port: u16, pub username: String, @@ -280,6 +281,7 @@ pub struct DatabaseSettings { impl Default for DatabaseSettings { fn default() -> Self { Self { + enable_connection: false, host: "127.0.0.1".to_string(), port: 5432, username: "postgres".to_string(), @@ -295,6 +297,13 @@ impl From for DatabaseSettings { fn from(value: PartialDatabaseConfiguration) -> Self { let d = DatabaseSettings::default(); + // "host" is the minimum required setting for database features + // to be enabled. + let enable_connection = value + .host + .as_ref() + .is_some_and(|_| value.disable_connection.is_none_or(|disabled| !disabled)); + let database = value.database.unwrap_or(d.database); let host = value.host.unwrap_or(d.host); @@ -312,6 +321,8 @@ impl From for DatabaseSettings { .unwrap_or(false); Self { + enable_connection, + port: value.port.unwrap_or(d.port), username: value.username.unwrap_or(d.username), password: value.password.unwrap_or(d.password), diff --git a/crates/pgt_workspace/src/workspace.rs b/crates/pgt_workspace/src/workspace.rs index 54f7200b..873dd83e 100644 --- a/crates/pgt_workspace/src/workspace.rs +++ b/crates/pgt_workspace/src/workspace.rs @@ -73,7 +73,6 @@ pub struct UpdateSettingsParams { pub vcs_base_path: Option, pub gitignore_matches: Vec, pub workspace_directory: Option, - pub skip_db: bool, } #[derive(Debug, serde::Serialize, serde::Deserialize)] diff --git a/crates/pgt_workspace/src/workspace/server.rs b/crates/pgt_workspace/src/workspace/server.rs index 3bf540cc..3c14f352 100644 --- a/crates/pgt_workspace/src/workspace/server.rs +++ b/crates/pgt_workspace/src/workspace/server.rs @@ -168,12 +168,10 @@ impl Workspace for WorkspaceServer { tracing::info!("Updated settings in workspace"); - if !params.skip_db { - self.connection - .write() - .unwrap() - .set_conn_settings(&self.settings().as_ref().db); - } + self.connection + .write() + .unwrap() + .set_conn_settings(&self.settings().as_ref().db); tracing::info!("Updated Db connection settings"); diff --git a/crates/pgt_workspace/src/workspace/server/db_connection.rs b/crates/pgt_workspace/src/workspace/server/db_connection.rs index d1be3131..d002c0a2 100644 --- a/crates/pgt_workspace/src/workspace/server/db_connection.rs +++ b/crates/pgt_workspace/src/workspace/server/db_connection.rs @@ -16,6 +16,11 @@ impl DbConnection { } pub(crate) fn set_conn_settings(&mut self, settings: &DatabaseSettings) { + if !settings.enable_connection { + tracing::info!("Database connection disabled."); + return; + } + let config = PgConnectOptions::new() .host(&settings.host) .port(settings.port) diff --git a/docs/schemas/0.0.0/schema.json b/docs/schemas/0.0.0/schema.json index 086adf3d..faba3b5c 100644 --- a/docs/schemas/0.0.0/schema.json +++ b/docs/schemas/0.0.0/schema.json @@ -100,7 +100,7 @@ ] }, "host": { - "description": "The host of the database.", + "description": "The host of the database. Required if you want database-related features. All else falls back to sensible defaults.", "type": [ "string", "null" diff --git a/docs/schemas/latest/schema.json b/docs/schemas/latest/schema.json index 086adf3d..faba3b5c 100644 --- a/docs/schemas/latest/schema.json +++ b/docs/schemas/latest/schema.json @@ -100,7 +100,7 @@ ] }, "host": { - "description": "The host of the database.", + "description": "The host of the database. Required if you want database-related features. All else falls back to sensible defaults.", "type": [ "string", "null" diff --git a/justfile b/justfile index 2495ae84..a55207ae 100644 --- a/justfile +++ b/justfile @@ -100,6 +100,8 @@ serve-docs: uv run mkdocs serve # When you finished coding, run this command. Note that you should have already committed your changes. +# If you haven't run `sqlx prepare` at least once, you need to run `docker compose up` +# to lint the queries. ready: git diff --exit-code --quiet cargo run -p xtask_codegen -- configuration diff --git a/packages/@postgrestools/backend-jsonrpc/src/workspace.ts b/packages/@postgrestools/backend-jsonrpc/src/workspace.ts index 5c9a1ac4..a35dad81 100644 --- a/packages/@postgrestools/backend-jsonrpc/src/workspace.ts +++ b/packages/@postgrestools/backend-jsonrpc/src/workspace.ts @@ -179,21 +179,36 @@ export interface GetCompletionsParams { */ position: TextSize; } -export interface CompletionResult { +export interface CompletionsResult { items: CompletionItem[]; } export interface CompletionItem { + completion_text?: CompletionText; description: string; kind: CompletionItemKind; label: string; preselected: boolean; - score: number; + /** + * String used for sorting by LSP clients. + */ + sort_text: string; +} +/** + * The text that the editor should fill in. If `None`, the `label` should be used. Tables, for example, might have different completion_texts: + +label: "users", description: "Schema: auth", completion_text: "auth.users". + */ +export interface CompletionText { + /** + * A `range` is required because some editors replace the current token, others naively insert the text. Having a range where start == end makes it an insertion. + */ + range: TextRange; + text: string; } -export type CompletionItemKind = "table" | "function" | "column"; +export type CompletionItemKind = "table" | "function" | "column" | "schema"; export interface UpdateSettingsParams { configuration: PartialConfiguration; gitignore_matches: string[]; - skip_db: boolean; vcs_base_path?: string; workspace_directory?: string; } @@ -240,7 +255,7 @@ export interface PartialDatabaseConfiguration { */ database?: string; /** - * The host of the database. + * The host of the database. Required if you want database-related features. All else falls back to sensible defaults. */ host?: string; /** @@ -414,7 +429,7 @@ export interface Workspace { pullDiagnostics( params: PullDiagnosticsParams, ): Promise; - getCompletions(params: GetCompletionsParams): Promise; + getCompletions(params: GetCompletionsParams): Promise; updateSettings(params: UpdateSettingsParams): Promise; openFile(params: OpenFileParams): Promise; changeFile(params: ChangeFileParams): Promise;