From b8d86518e7af87093ea1dc8e3c48a4ce8025d317 Mon Sep 17 00:00:00 2001 From: Nybkox Date: Tue, 8 Apr 2025 18:56:17 +0200 Subject: [PATCH] feat: add new duck db command --- app/src/mainMenuDefinition.js | 1 + packages/api/src/controllers/connections.js | 16 ++++++++++++ packages/api/testduck.db | Bin 2371584 -> 2371584 bytes packages/web/src/commands/stdCommands.ts | 27 +++++++++++++++++--- translations/en.json | 6 ++++- 5 files changed, 46 insertions(+), 4 deletions(-) diff --git a/app/src/mainMenuDefinition.js b/app/src/mainMenuDefinition.js index b74a94136..8e676db79 100644 --- a/app/src/mainMenuDefinition.js +++ b/app/src/mainMenuDefinition.js @@ -4,6 +4,7 @@ module.exports = ({ editMenu, isMac }) => [ submenu: [ { command: 'new.connection', hideDisabled: true }, { command: 'new.sqliteDatabase', hideDisabled: true }, + { command: 'new.duckdbDatabase', hideDisabled: true }, { divider: true }, { command: 'new.query', hideDisabled: true }, { command: 'new.queryDesign', hideDisabled: true }, diff --git a/packages/api/src/controllers/connections.js b/packages/api/src/controllers/connections.js index bf6b86544..8662f5e3e 100644 --- a/packages/api/src/controllers/connections.js +++ b/packages/api/src/controllers/connections.js @@ -435,6 +435,22 @@ module.exports = { return res; }, + newDuckdbDatabase_meta: true, + async newDuckdbDatabase({ file }) { + const duckdbDir = path.join(filesdir(), 'duckdb'); + if (!(await fs.exists(duckdbDir))) { + await fs.mkdir(duckdbDir); + } + const databaseFile = path.join(duckdbDir, `${file}.duckdb`); + const res = await this.save({ + engine: 'duckdb@dbgate-plugin-duckdb', + databaseFile, + singleDatabase: true, + defaultDatabase: `${file}.duckdb`, + }); + return res; + }, + dbloginWeb_meta: { raw: true, method: 'get', diff --git a/packages/api/testduck.db b/packages/api/testduck.db index 9b9f42b80c1d4d9e43b35563bbed9de7a252f6ad..90a8e2dd2acd8082b1e2e1f432d6bc13c88d5bfe 100644 GIT binary patch delta 3712 zcmdT`Yiv|S6rQ=ecOTuB-L~`%eb|;33hk6y%0q-ko<`fHKnO_OHr?BHwe6N}2^vCL zOc*f&-7;;L1eGR6A)+a8jaOr|HAbL3EJck0O^QE=Bq*)^A;HM?%x!nKyS9K4W7uSq zIp55kIrsa{H}|w%^Wrx6_t?xmn>H`H^=V70*byC%7s~0jYu5BDpPjn8^UL?k^(f?L z7?1L`Rk4w2QR}ve<$K1_5+|~-Sh6sodb_8^-5@o429OgO038EZM`ye-qQ=$iX>lAZ zjx(6+tF+PFEU~H1-6%=0I!RS)5voH-Rh=lhS*mq;TAHg`T<%8ZC`q&%u@mXeB0PZ5 zIfTdem6{zcr>epfhAIC*&<45zq=S{B)KKNB_fP5k1Cimbq)aR!ld9Grq@64{QLMdU z?X#s7n;n4{VN1Glnmy$lO;5mDt~uyITlkT zG%T>Rt`t_>d0otq&>jOsf576D?!B!*f*wdPjUVb9m@qzv&;>Lh9nVFC(bou%QT9+C zTl8SZsVdjHZTy!dp~F$~N8LLytL#iqotPmnAkm4UCU7`fJe{$wWOll1fpuC_v#VNi zGy%Wc8(l4|sxU(`g_OvIC#NnFD4Re@=(XCo2O0PRGPv1^qIl-&PQy*?weH+m^Cfi0 z94sN76UF&UD44m27f~WittzirxpsA#W5Sf980u)&RFex}a!x)JCcK(ZgUk&tJ3Q5O zyrj8LRJ9t7&y5=qB7<_mjw>Qr^TpuhlIo*c_WZvXZPz0zKQn*`;BQ@BUe@{`}%znHU= ztmEJ=L3wo_XcGAMNUZuy`5X77O51uwE<-ItCEBB6WQXze-`|yh} z9dlnbmks_SHK8*JRTF?vH39IeSu#9@ngt{GQ8PzXAwn9L2~!BEsAWPaFM@3m<6>roiHQpUcuB8-Z$?B|=oRs- zzacq*j0y^TiFfcSxuSiP6`adTZT&&VD9i1_COw}0cB##zc()3b+#@~_&w-~m2>$QC z4hQN#Wj);6$DwZtx&VOJBf@}N;lPk3Y{iF>nhQ88@-9HI;5;~V9rhRP(nt=M33x8R zVuT<5Uc~bNs2y`foO-6WCp*w&?Ed)D@D^27+E(DrW@YqwVMsGep1kDH8=Qqot<~5k zq_xR~hu-DLc_SvU-6TvEvdNg5AI?+}JUs(@qd$z=Gx3FE;itZ{y3r)GZDbZ6RQevRQ zNQsFOGbIs}SSX34B#M%0lvpXTQ4&o_3?;FYOs6D{l6XoIC`qIwiIQYWQYe{0$xKR8 QDM_OwostYn9-}1lFI);Dr2qf` delta 1785 zcmaKsZD<@t7{~XS-Mzi-^j_SzSe( zsEU)duWTNl`o7&>9bJ+}D{zWdHaq@mRT8Hq)$58tf- zzCE%nK@U7KLjTwvP?e07*R4ZMt)SNMsekf93e>ucG*(70q@whvZ8=crO!EnPE)`JY z8R=ZLWp6(W?4uQQ1zAR7T2@e(1T6WY+%DEDy4iUQJ#3x1{i5Ch*PUi;A++b+4x zb+<5I%UWZw2T>z&p0!dmsawAdJ`UoLu=!04lIEE=&~A45A^2M6W%eLuZ-HByIkAGg za+l=cE;iAH#(n&@ZCi(3?r9n6JSw=Sth(3fxTj~N8=-=G>-n_OaW9yW-mG53z4DB7 zI$rADf&yM^{I*}`CGA(7V(&P$1JSwcI}9H}o$~+v`cbtm&zwSHyA`eF+Jn4iZ?S27 z-Q!wcgCftC4xk2)H8VE|yq0G9{>HtoSZs0Qs=H0~kYv}I;1i8Mc|$gNrV$4&i#-O< zBP*LLQ25z9kW;nQ zyX%x-Jf@nbgK(42Ql%SHUJ-Z9G~+PKcguaEoXxEJDEuw6;RbkFH1aLABw1c&$6Mfc znHq_Ol8v`Cb1)4HTsIicdR(Bqf*8+u7_t5isNyD5Wcql(7mQm&5$o%NeI6e63$Xc7 zG^w%fLHJIbc^w#TmiLIe{OV!6HS2i9XJ}a%+a@rF&|T-E2JfeAwAd0Z4A;4YKi$F) zF;~Rr^|swDNw#h6O#BPtg$S7+2jnBx)ek(P7kUFMorS0@UYH4$8i|XgguhkICud-< z5br~ne`n@A#V2zitGR^tOFEWEoYV#3h;FvbIUqaM0vV>gyPhzc79E(6`UHh#nKk4K z9RE`9((TdMCYv+lmqLZ!z0)c$Xl6W!1jPOlxKmz{?J2|}aip&kQ1dDaHXsLI2nl@s z8q->kgD>C+5g)VL(aw7)|Iq}*P9%U{6_}%{8zuj+epy*;1{dC|atSML;pea`;;YC# zlrO0Tluu8~18fvz&Ciym<>f&&Bx2@Vll tMsPX76$DojTt#r0;0VFh1lJH;OK_CnI)Y;a*ApBkI6-id;0Fla@E;WXsa^m8 diff --git a/packages/web/src/commands/stdCommands.ts b/packages/web/src/commands/stdCommands.ts index 8b99b6584..2be460669 100644 --- a/packages/web/src/commands/stdCommands.ts +++ b/packages/web/src/commands/stdCommands.ts @@ -46,6 +46,7 @@ import { openImportExportTab } from '../utility/importExportTools'; import newTable from '../tableeditor/newTable'; import { isProApp } from '../utility/proTools'; import { openWebLink } from '../utility/simpleTools'; +import { _t } from '../translations'; // function themeCommand(theme: ThemeDefinition) { // return { @@ -389,12 +390,12 @@ registerCommand({ category: 'New', icon: 'img sqlite-database', name: 'SQLite database', - menuName: 'New SQLite database', + menuName: _t('command.new.sqliteDatabase', { defaultMessage: 'New SQLite database' }), onClick: () => { showModal(InputTextModal, { value: 'newdb', - label: 'New database name', - header: 'Create SQLite database', + label: _t('command.new.sqliteDatabase', { defaultMessage: 'New SQLite database' }), + header: _t('command.new.sqliteDatabase.header', { defaultMessage: 'Create SQLite database' }), onConfirm: async file => { const resp = await apiCall('connections/new-sqlite-database', { file }); const connection = resp; @@ -404,6 +405,26 @@ registerCommand({ }, }); +registerCommand({ + id: 'new.duckdbDatabase', + category: 'New', + icon: 'img sqlite-database', + name: 'DuckDB database', + menuName: _t('command.new.duckdbDatabase', { defaultMessage: 'New DuckDB database' }), + onClick: () => { + showModal(InputTextModal, { + value: 'newdb', + label: _t('command.new.duckdbDatabase', { defaultMessage: 'New DuckDB database' }), + header: _t('command.new.duckdbDatabase.header', { defaultMessage: 'Create DuckDB database' }), + onConfirm: async file => { + const resp = await apiCall('connections/new-duckdb-database', { file }); + const connection = resp; + switchCurrentDatabase({ connection, name: `${file}.duckdb` }); + }, + }); + }, +}); + registerCommand({ id: 'tabs.changelog', category: 'Tabs', diff --git a/translations/en.json b/translations/en.json index d47f7e144..3eadc7994 100644 --- a/translations/en.json +++ b/translations/en.json @@ -26,6 +26,10 @@ "command.datagrid.undo": "Undo", "command.datagrid.viewJsonDocument": "View row as JSON document", "command.datagrid.viewJsonValue": "View cell as JSON document", + "command.new.duckdbDatabase": "New DuckDB database", + "command.new.duckdbDatabase.header": "Create DuckDB database", + "command.new.sqliteDatabase": "New SQLite database", + "command.new.sqliteDatabase.header": "Create SQLite database", "command.tabs.addToFavorites": "Add current tab to favorites", "command.tabs.closeAll": "Close all tabs", "command.tabs.closeTab": "Close tab", @@ -51,7 +55,6 @@ "connection.newQuery": "New Query (server)", "connection.refresh": "Refresh", "connection.serverSummary": "Server summary", - "connection.sqlRestore": "Restore/import SQL dump", "connection.viewDetails": "View details", "error.driverNotFound": "Invalid database connection, driver not found", "importExport.sourceFiles": "Source files", @@ -61,6 +64,7 @@ "schema.delete": "Delete schema", "schema.resetToDefault": "Reset to default", "schema.schemaName": "Schema name", + "settings.behaviour.jsonPreviewWrap": "Wrap json in preview", "settings.localization": "Localization", "tab.administration": "Administration", "widget.databaseContent": "Database content",