diff --git a/apps/desktop/src/components/connection/ConnectionDialog.vue b/apps/desktop/src/components/connection/ConnectionDialog.vue
index 732a716bf8..e2939582da 100644
--- a/apps/desktop/src/components/connection/ConnectionDialog.vue
+++ b/apps/desktop/src/components/connection/ConnectionDialog.vue
@@ -2000,6 +2000,24 @@ async function createDuckDbFilePath() {
form.value.host = path;
}
+function ensureSqliteFileExtension(path: string): string {
+ return /\.(db|sqlite|sqlite3)$/i.test(path) ? path : `${path}.db`;
+}
+
+async function createSqliteFilePath() {
+ if (!isTauriRuntime()) return;
+ const { save } = await import("@tauri-apps/plugin-dialog");
+ const selected = await save({
+ title: t("connection.createSqliteFile"),
+ defaultPath: "database.db",
+ filters: [{ name: "SQLite", extensions: ["db", "sqlite", "sqlite3"] }],
+ });
+ if (!selected) return;
+
+ const path = ensureSqliteFileExtension(selected);
+ form.value.host = path;
+}
+
async function browseJdbcDriverPaths() {
if (!isTauriRuntime()) return;
const { open } = await import("@tauri-apps/plugin-dialog");
@@ -2371,6 +2389,14 @@ function openExternalUrl(url: string) {
{{ t("connection.memoryDatabasePathHint") }}
diff --git a/apps/desktop/src/i18n/locales/en.ts b/apps/desktop/src/i18n/locales/en.ts
index 463d691f8c..de2a1f6435 100644
--- a/apps/desktop/src/i18n/locales/en.ts
+++ b/apps/desktop/src/i18n/locales/en.ts
@@ -144,6 +144,7 @@
h2TcpMode: "TCP",
h2FilePathRequired: "H2 file path cannot be empty",
createDuckDbFile: "Create DuckDB file",
+ createSqliteFile: "Create SQLite database",
memoryDatabasePathHint: "Use :memory: to create an in-memory SQLite or DuckDB database.",
sqliteExtensions: "SQLite Extensions",
sqliteExtensionsPlaceholder: "/path/to/regexp.dylib\n/path/to/text.dylib|sqlite3_text_init",
diff --git a/apps/desktop/src/i18n/locales/es.ts b/apps/desktop/src/i18n/locales/es.ts
index 081c625f83..f476ac7db7 100644
--- a/apps/desktop/src/i18n/locales/es.ts
+++ b/apps/desktop/src/i18n/locales/es.ts
@@ -142,6 +142,7 @@
h2TcpMode: "TCP",
h2FilePathRequired: "La ruta del archivo H2 no puede estar vacía",
createDuckDbFile: "Crear archivo DuckDB",
+ createSqliteFile: "Crear base de datos SQLite",
user: "Usuario",
password: "Contraseña",
database: "Base de datos",
diff --git a/apps/desktop/src/i18n/locales/it.ts b/apps/desktop/src/i18n/locales/it.ts
index 5997a1b3c0..8d8049deb1 100644
--- a/apps/desktop/src/i18n/locales/it.ts
+++ b/apps/desktop/src/i18n/locales/it.ts
@@ -142,6 +142,7 @@
h2TcpMode: "TCP",
h2FilePathRequired: "Il percorso del file H2 non può essere vuoto",
createDuckDbFile: "Crea file DuckDB",
+ createSqliteFile: "Crea database SQLite",
memoryDatabasePathHint: "Usa :memory: per creare un database SQLite o DuckDB in memoria.",
sqliteExtensions: "Estensioni SQLite",
sqliteExtensionsPlaceholder: "/percorso/per/regexp.dylib\n/percorso/per/text.dylib|sqlite3_text_init",
diff --git a/apps/desktop/src/i18n/locales/ja.ts b/apps/desktop/src/i18n/locales/ja.ts
index e0ad7b6f73..836372a03e 100644
--- a/apps/desktop/src/i18n/locales/ja.ts
+++ b/apps/desktop/src/i18n/locales/ja.ts
@@ -143,6 +143,7 @@ export default {
h2TcpMode: "TCP",
h2FilePathRequired: "H2ファイルパスを指定してください",
createDuckDbFile: "DuckDBファイルを作成",
+ createSqliteFile: "SQLiteデータベースを作成",
memoryDatabasePathHint: "インメモリのSQLiteまたはDuckDBデータベースを作成するには :memory: を使用してください。",
sqliteExtensions: "SQLite拡張",
sqliteExtensionsPlaceholder: "/path/to/regexp.dylib\n/path/to/text.dylib|sqlite3_text_init",
diff --git a/apps/desktop/src/i18n/locales/pt-BR.ts b/apps/desktop/src/i18n/locales/pt-BR.ts
index bf2ccfd199..d30cbe2f6a 100644
--- a/apps/desktop/src/i18n/locales/pt-BR.ts
+++ b/apps/desktop/src/i18n/locales/pt-BR.ts
@@ -142,6 +142,7 @@
h2TcpMode: "TCP",
h2FilePathRequired: "O caminho do arquivo H2 não pode ficar vazio",
createDuckDbFile: "Criar arquivo DuckDB",
+ createSqliteFile: "Criar banco de dados SQLite",
memoryDatabasePathHint: "Use :memory: para criar um banco de dados SQLite ou DuckDB na memória.",
sqliteExtensions: "Extensões SQLite",
sqliteExtensionsPlaceholder: "/caminho/para/regexp.dylib\n/caminho/para/text.dylib|sqlite3_text_init",
diff --git a/apps/desktop/src/i18n/locales/zh-CN.ts b/apps/desktop/src/i18n/locales/zh-CN.ts
index f3aa9c8f7a..e1e99f5147 100644
--- a/apps/desktop/src/i18n/locales/zh-CN.ts
+++ b/apps/desktop/src/i18n/locales/zh-CN.ts
@@ -145,6 +145,7 @@
h2TcpMode: "TCP",
h2FilePathRequired: "H2 文件路径不能为空",
createDuckDbFile: "新建 DuckDB 文件",
+ createSqliteFile: "新建 SQLite 数据库",
memoryDatabasePathHint: "输入 :memory: 可创建 SQLite 或 DuckDB 内存数据库。",
sqliteExtensions: "SQLite 扩展库",
sqliteExtensionsPlaceholder: "/path/to/regexp.dylib\n/path/to/text.dylib|sqlite3_text_init",
diff --git a/apps/desktop/src/i18n/locales/zh-TW.ts b/apps/desktop/src/i18n/locales/zh-TW.ts
index 48e0afd4c4..d2f322be67 100644
--- a/apps/desktop/src/i18n/locales/zh-TW.ts
+++ b/apps/desktop/src/i18n/locales/zh-TW.ts
@@ -142,6 +142,7 @@
h2TcpMode: "TCP",
h2FilePathRequired: "H2 檔案路徑不能為空",
createDuckDbFile: "建立 DuckDB 檔案",
+ createSqliteFile: "建立 SQLite 資料庫",
memoryDatabasePathHint: "輸入 :memory: 可建立 SQLite 或 DuckDB 記憶體資料庫。",
sqliteExtensions: "SQLite 擴充庫",
sqliteExtensionsPlaceholder: "/path/to/regexp.dylib\n/path/to/text.dylib|sqlite3_text_init",
diff --git a/crates/dbx-core/src/connection.rs b/crates/dbx-core/src/connection.rs
index ec64f8933f..ab97c6d1f3 100644
--- a/crates/dbx-core/src/connection.rs
+++ b/crates/dbx-core/src/connection.rs
@@ -447,7 +447,11 @@ impl AppState {
})
.collect();
PoolKind::Sqlite(
- db::sqlite::connect_path_with_extensions(&expand_tilde(&db_config.host), extensions).await?,
+ db::sqlite::connect_path_create_if_missing_with_extensions(
+ &expand_tilde(&db_config.host),
+ extensions,
+ )
+ .await?,
)
}
DatabaseType::Rqlite => {
diff --git a/crates/dbx-core/src/db/sqlite.rs b/crates/dbx-core/src/db/sqlite.rs
index 6c05283533..500d2e461d 100644
--- a/crates/dbx-core/src/db/sqlite.rs
+++ b/crates/dbx-core/src/db/sqlite.rs
@@ -46,6 +46,13 @@ pub async fn connect_path_create_if_missing(path: &str) -> Result