mirror of
https://github.com/DeNNiiInc/dbgate.git
synced 2026-04-24 22:16:00 +00:00
create collection - generic operation
This commit is contained in:
@@ -182,6 +182,15 @@ module.exports = {
|
||||
return res;
|
||||
},
|
||||
|
||||
runOperation_meta: true,
|
||||
async runOperation({ conid, database, operation, useTransaction }, req) {
|
||||
testConnectionPermission(conid, req);
|
||||
logger.info({ conid, database, operation }, 'Processing operation');
|
||||
const opened = await this.ensureOpened(conid, database);
|
||||
const res = await this.sendRequest(opened, { msgtype: 'runOperation', operation, useTransaction });
|
||||
return res;
|
||||
},
|
||||
|
||||
collectionData_meta: true,
|
||||
async collectionData({ conid, database, options }, req) {
|
||||
testConnectionPermission(conid, req);
|
||||
|
||||
@@ -170,6 +170,18 @@ async function handleRunScript({ msgid, sql, useTransaction }, skipReadonlyCheck
|
||||
}
|
||||
}
|
||||
|
||||
async function handleRunOperation({ msgid, operation, useTransaction }, skipReadonlyCheck = false) {
|
||||
await waitConnected();
|
||||
const driver = requireEngineDriver(storedConnection);
|
||||
try {
|
||||
if (!skipReadonlyCheck) ensureExecuteCustomScript(driver);
|
||||
await driver.operation(systemConnection, operation, { useTransaction });
|
||||
process.send({ msgtype: 'response', msgid });
|
||||
} catch (err) {
|
||||
process.send({ msgtype: 'response', msgid, errorMessage: err.message });
|
||||
}
|
||||
}
|
||||
|
||||
async function handleQueryData({ msgid, sql }, skipReadonlyCheck = false) {
|
||||
await waitConnected();
|
||||
const driver = requireEngineDriver(storedConnection);
|
||||
@@ -311,6 +323,7 @@ const messageHandlers = {
|
||||
connect: handleConnect,
|
||||
queryData: handleQueryData,
|
||||
runScript: handleRunScript,
|
||||
runOperation: handleRunOperation,
|
||||
updateCollection: handleUpdateCollection,
|
||||
collectionData: handleCollectionData,
|
||||
loadKeys: handleLoadKeys,
|
||||
|
||||
@@ -81,6 +81,9 @@ export const driverBase = {
|
||||
runCommandOnDriver(pool, this, dmp => dmp.commitTransaction());
|
||||
}
|
||||
},
|
||||
async operation(pool, operation, options: RunScriptOptions) {
|
||||
throw new Error('Operation not defined in target driver');
|
||||
},
|
||||
getNewObjectTemplates() {
|
||||
if (this.databaseEngineTypes.includes('sql')) {
|
||||
return [{ label: 'New view', sql: 'CREATE VIEW myview\nAS\nSELECT * FROM table1' }];
|
||||
|
||||
1
packages/types/engines.d.ts
vendored
1
packages/types/engines.d.ts
vendored
@@ -142,6 +142,7 @@ export interface EngineDriver {
|
||||
dropDatabase(pool: any, name: string): Promise;
|
||||
getQuerySplitterOptions(usage: 'stream' | 'script' | 'editor'): any;
|
||||
script(pool: any, sql: string, options?: RunScriptOptions): Promise;
|
||||
operation(pool: any, operation: {}, options?: RunScriptOptions): Promise;
|
||||
getNewObjectTemplates(): NewObjectTemplate[];
|
||||
// direct call of pool method, only some methods could be supported, on only some drivers
|
||||
callMethod(pool, method, args);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<script lang="ts" context="module">
|
||||
import {copyTextToClipboard} from "../utility/clipboard";
|
||||
import { copyTextToClipboard } from '../utility/clipboard';
|
||||
|
||||
export const extractKey = props => props.name;
|
||||
|
||||
@@ -93,10 +93,18 @@
|
||||
const handleNewCollection = () => {
|
||||
showModal(InputTextModal, {
|
||||
value: '',
|
||||
label: 'New collection name',
|
||||
header: 'Create collection',
|
||||
label: 'New collection/container name',
|
||||
header: 'Create collection/container',
|
||||
onConfirm: async newCollection => {
|
||||
saveScriptToDatabase({ conid: connection._id, database: name }, `db.createCollection('${newCollection}')`);
|
||||
runOperationOnDatabase(
|
||||
{ conid: connection._id, database: name },
|
||||
{
|
||||
type: 'createCollection',
|
||||
collection: newCollection,
|
||||
}
|
||||
);
|
||||
|
||||
// saveScriptToDatabase({ conid: connection._id, database: name }, `db.createCollection('${newCollection}')`);
|
||||
},
|
||||
});
|
||||
};
|
||||
@@ -173,7 +181,7 @@
|
||||
|
||||
const handleCopyName = async () => {
|
||||
copyTextToClipboard(name);
|
||||
}
|
||||
};
|
||||
|
||||
const handleDisconnect = () => {
|
||||
disconnectDatabaseConnection(connection._id, name);
|
||||
@@ -286,7 +294,7 @@
|
||||
return [
|
||||
{ onClick: handleNewQuery, text: 'New query', isNewQuery: true },
|
||||
driver?.databaseEngineTypes?.includes('sql') && { onClick: handleNewTable, text: 'New table' },
|
||||
driver?.databaseEngineTypes?.includes('document') && { onClick: handleNewCollection, text: 'New collection' },
|
||||
driver?.databaseEngineTypes?.includes('document') && { onClick: handleNewCollection, text: 'New collection/container' },
|
||||
driver?.databaseEngineTypes?.includes('sql') && { onClick: handleQueryDesigner, text: 'Design query' },
|
||||
driver?.databaseEngineTypes?.includes('sql') && {
|
||||
onClick: handleNewPerspective,
|
||||
@@ -370,7 +378,7 @@
|
||||
import { openJsonDocument } from '../tabs/JsonTab.svelte';
|
||||
import { apiCall } from '../utility/api';
|
||||
import ErrorMessageModal from '../modals/ErrorMessageModal.svelte';
|
||||
import ConfirmSqlModal, { saveScriptToDatabase } from '../modals/ConfirmSqlModal.svelte';
|
||||
import ConfirmSqlModal, { runOperationOnDatabase, saveScriptToDatabase } from '../modals/ConfirmSqlModal.svelte';
|
||||
import { filterAppsForDatabase } from '../utility/appTools';
|
||||
import newQuery from '../query/newQuery';
|
||||
import { exportSqlDump } from '../utility/exportFileTools';
|
||||
|
||||
@@ -522,8 +522,8 @@
|
||||
copyTextToClipboard(data.pureName);
|
||||
} else if (menu.isRenameCollection) {
|
||||
showModal(InputTextModal, {
|
||||
label: 'New collection name',
|
||||
header: 'Rename collection',
|
||||
label: 'New collection/container name',
|
||||
header: 'Rename collection/container',
|
||||
value: data.pureName,
|
||||
onConfirm: async newName => {
|
||||
const dbid = _.pick(data, ['conid', 'database']);
|
||||
|
||||
@@ -39,6 +39,7 @@ import { isMac } from '../utility/common';
|
||||
import { doLogout, internalRedirectTo } from '../clientAuth';
|
||||
import { disconnectServerConnection } from '../appobj/ConnectionAppObject.svelte';
|
||||
import UploadErrorModal from '../modals/UploadErrorModal.svelte';
|
||||
import ErrorMessageModal from '../modals/ErrorMessageModal.svelte';
|
||||
|
||||
// function themeCommand(theme: ThemeDefinition) {
|
||||
// return {
|
||||
@@ -277,7 +278,7 @@ registerCommand({
|
||||
icon: 'icon table',
|
||||
name: 'Collection',
|
||||
toolbar: true,
|
||||
toolbarName: 'New collection',
|
||||
toolbarName: 'New collection/container',
|
||||
testEnabled: () => {
|
||||
const driver = findEngineDriver(get(currentDatabase)?.connection, getExtensions());
|
||||
return !!get(currentDatabase) && driver?.databaseEngineTypes?.includes('document');
|
||||
@@ -291,11 +292,25 @@ registerCommand({
|
||||
|
||||
showModal(InputTextModal, {
|
||||
value: '',
|
||||
label: 'New collection name',
|
||||
header: 'Create collection',
|
||||
label: 'New collection/container name',
|
||||
header: 'Create collection/container',
|
||||
onConfirm: async newCollection => {
|
||||
await apiCall('database-connections/run-script', { ...dbid, sql: `db.createCollection('${newCollection}')` });
|
||||
apiCall('database-connections/sync-model', dbid);
|
||||
// await apiCall('database-connections/run-script', { ...dbid, sql: `db.createCollection('${newCollection}')` });
|
||||
const resp = await apiCall('database-connections/run-operation', {
|
||||
...dbid,
|
||||
operation: {
|
||||
type: 'createCollection',
|
||||
collection: newCollection,
|
||||
},
|
||||
});
|
||||
|
||||
const { errorMessage } = resp || {};
|
||||
if (errorMessage) {
|
||||
showModal(ErrorMessageModal, { title: 'Error when executing operation', message: errorMessage });
|
||||
} else {
|
||||
showSnackbarSuccess('Saved to database');
|
||||
apiCall('database-connections/sync-model', dbid);
|
||||
}
|
||||
},
|
||||
});
|
||||
},
|
||||
|
||||
@@ -14,6 +14,22 @@
|
||||
if (syncModel) apiCall('database-connections/sync-model', { conid, database });
|
||||
}
|
||||
}
|
||||
|
||||
export async function runOperationOnDatabase({ conid, database }, operation, syncModel = true) {
|
||||
const resp = await apiCall('database-connections/run-operation', {
|
||||
conid,
|
||||
database,
|
||||
operation,
|
||||
});
|
||||
|
||||
const { errorMessage } = resp || {};
|
||||
if (errorMessage) {
|
||||
showModal(ErrorMessageModal, { title: 'Error when executing operation', message: errorMessage });
|
||||
} else {
|
||||
showSnackbarSuccess('Saved to database');
|
||||
if (syncModel) apiCall('database-connections/sync-model', { conid, database });
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<script>
|
||||
|
||||
@@ -99,6 +99,14 @@
|
||||
{/key}
|
||||
{/if}
|
||||
|
||||
{#if driver?.showConnectionField('endpoint', $values, showConnectionFieldArgs)}
|
||||
<FormTextField label="Endpoint" name="endpoint" disabled={isConnected} />
|
||||
{/if}
|
||||
|
||||
{#if driver?.showConnectionField('endpointKey', $values, showConnectionFieldArgs)}
|
||||
<FormTextField label="Key" name="endpointKey" disabled={isConnected} />
|
||||
{/if}
|
||||
|
||||
{#if driver?.showConnectionField('clientLibraryPath', $values, showConnectionFieldArgs)}
|
||||
<FormTextField label="Client library path" name="clientLibraryPath" disabled={isConnected} />
|
||||
{/if}
|
||||
|
||||
@@ -120,7 +120,7 @@
|
||||
{/if}
|
||||
{#if driver?.databaseEngineTypes?.includes('document')}
|
||||
<div class="m-1" />
|
||||
<InlineButton on:click={() => runCommand('new.collection')}>New collection</InlineButton>
|
||||
<InlineButton on:click={() => runCommand('new.collection')}>New collection/container</InlineButton>
|
||||
{/if}
|
||||
</WidgetsInnerContainer>
|
||||
{:else}
|
||||
|
||||
@@ -100,6 +100,16 @@ const driver = {
|
||||
const res = func(db, ObjectId.createFromHexString);
|
||||
if (isPromise(res)) await res;
|
||||
},
|
||||
async operation(pool, operation, options) {
|
||||
const { type } = operation;
|
||||
switch (type) {
|
||||
case 'createCollection':
|
||||
await this.script(pool, `db.createCollection('${operation.collection}')`);
|
||||
default:
|
||||
throw new Error(`Operation type ${type} not supported`);
|
||||
}
|
||||
// saveScriptToDatabase({ conid: connection._id, database: name }, `db.createCollection('${newCollection}')`);
|
||||
},
|
||||
async stream(pool, sql, options) {
|
||||
let func;
|
||||
try {
|
||||
|
||||
79
yarn.lock
79
yarn.lock
@@ -31,7 +31,7 @@
|
||||
dependencies:
|
||||
tslib "^2.6.2"
|
||||
|
||||
"@azure/core-auth@^1.3.0", "@azure/core-auth@^1.4.0", "@azure/core-auth@^1.5.0":
|
||||
"@azure/core-auth@^1.3.0", "@azure/core-auth@^1.4.0", "@azure/core-auth@^1.5.0", "@azure/core-auth@^1.7.1":
|
||||
version "1.7.2"
|
||||
resolved "https://registry.yarnpkg.com/@azure/core-auth/-/core-auth-1.7.2.tgz#558b7cb7dd12b00beec07ae5df5907d74df1ebd9"
|
||||
integrity sha512-Igm/S3fDYmnMq1uKS38Ae1/m37B3zigdlZw+kocwEhh5GjyKjPrXKO2J6rzpC1wAxrNil/jX9BJRqBshyjnF3g==
|
||||
@@ -93,7 +93,21 @@
|
||||
https-proxy-agent "^7.0.0"
|
||||
tslib "^2.6.2"
|
||||
|
||||
"@azure/core-tracing@^1.0.0", "@azure/core-tracing@^1.0.1":
|
||||
"@azure/core-rest-pipeline@^1.15.1":
|
||||
version "1.16.3"
|
||||
resolved "https://registry.yarnpkg.com/@azure/core-rest-pipeline/-/core-rest-pipeline-1.16.3.tgz#bde3bc3ebad7f885ddd9de6af5e5a8fc254b287e"
|
||||
integrity sha512-VxLk4AHLyqcHsfKe4MZ6IQ+D+ShuByy+RfStKfSjxJoL3WBWq17VNmrz8aT8etKzqc2nAeIyLxScjpzsS4fz8w==
|
||||
dependencies:
|
||||
"@azure/abort-controller" "^2.0.0"
|
||||
"@azure/core-auth" "^1.4.0"
|
||||
"@azure/core-tracing" "^1.0.1"
|
||||
"@azure/core-util" "^1.9.0"
|
||||
"@azure/logger" "^1.0.0"
|
||||
http-proxy-agent "^7.0.0"
|
||||
https-proxy-agent "^7.0.0"
|
||||
tslib "^2.6.2"
|
||||
|
||||
"@azure/core-tracing@^1.0.0", "@azure/core-tracing@^1.0.1", "@azure/core-tracing@^1.1.1":
|
||||
version "1.1.2"
|
||||
resolved "https://registry.yarnpkg.com/@azure/core-tracing/-/core-tracing-1.1.2.tgz#065dab4e093fb61899988a1cdbc827d9ad90b4ee"
|
||||
integrity sha512-dawW9ifvWAWmUm9/h+/UQ2jrdvjCJ7VJEuCJ6XVNudzcOwm53BFZH4Q845vjfgoUAM8ZxokvVNxNxAITc502YA==
|
||||
@@ -108,6 +122,30 @@
|
||||
"@azure/abort-controller" "^2.0.0"
|
||||
tslib "^2.6.2"
|
||||
|
||||
"@azure/core-util@^1.8.1":
|
||||
version "1.9.2"
|
||||
resolved "https://registry.yarnpkg.com/@azure/core-util/-/core-util-1.9.2.tgz#1dc37dc5b0dae34c578be62cf98905ba7c0cafe7"
|
||||
integrity sha512-l1Qrqhi4x1aekkV+OlcqsJa4AnAkj5p0JV8omgwjaV9OAbP41lvrMvs+CptfetKkeEaGRGSzby7sjPZEX7+kkQ==
|
||||
dependencies:
|
||||
"@azure/abort-controller" "^2.0.0"
|
||||
tslib "^2.6.2"
|
||||
|
||||
"@azure/cosmos@^4.1.0":
|
||||
version "4.1.0"
|
||||
resolved "https://registry.yarnpkg.com/@azure/cosmos/-/cosmos-4.1.0.tgz#97014d8110d94c4b47911350a018ad2d726493b0"
|
||||
integrity sha512-+m085WKIGkf6wyw4vT85FFXl9j3U35u+LFFVwmLqfPbolnQAtoX24cowXz+vseW4BWKyx6Lamb+Zz+jl69zn6g==
|
||||
dependencies:
|
||||
"@azure/abort-controller" "^2.0.0"
|
||||
"@azure/core-auth" "^1.7.1"
|
||||
"@azure/core-rest-pipeline" "^1.15.1"
|
||||
"@azure/core-tracing" "^1.1.1"
|
||||
"@azure/core-util" "^1.8.1"
|
||||
fast-json-stable-stringify "^2.1.0"
|
||||
jsbi "^4.3.0"
|
||||
priorityqueuejs "^2.0.0"
|
||||
semaphore "^1.1.0"
|
||||
tslib "^2.6.2"
|
||||
|
||||
"@azure/identity@^3.4.1":
|
||||
version "3.4.2"
|
||||
resolved "https://registry.yarnpkg.com/@azure/identity/-/identity-3.4.2.tgz#6b01724c9caac7cadab6b63c76584345bda8e2de"
|
||||
@@ -3207,6 +3245,26 @@ dbgate-query-splitter@^4.10.1:
|
||||
resolved "https://registry.yarnpkg.com/dbgate-query-splitter/-/dbgate-query-splitter-4.10.1.tgz#dc40d792de06f779a743cad054d5e786006b03a9"
|
||||
integrity sha512-KqrB7NLP1jXbx8rN7gSmYUVorm6ICeqOV+oR+jHaBLXqqhWepHsKr6JJlFEeb/LhoVjnTDY/cy5zhW1dMIQF6A==
|
||||
|
||||
dbgate-sqltree@^5.3.4:
|
||||
version "5.3.4"
|
||||
resolved "https://registry.yarnpkg.com/dbgate-sqltree/-/dbgate-sqltree-5.3.4.tgz#d91bbb1a3264dc8d88898fbb5427ee15aacc14a3"
|
||||
integrity sha512-pvfjuI51plcmwErxxDCl8ZLXb9VfDnT+NukEMExiytYrTg3dDF2j9xwsYR9MZ/UaOQjwEO4LZ2FBLg/B776CuA==
|
||||
dependencies:
|
||||
lodash "^4.17.21"
|
||||
|
||||
dbgate-tools@^5.0.0:
|
||||
version "5.3.4"
|
||||
resolved "https://registry.yarnpkg.com/dbgate-tools/-/dbgate-tools-5.3.4.tgz#168662ccd92e404a31fe3d5e29f732a91a0ea9b6"
|
||||
integrity sha512-EsZafhQIGx8AlUT5PIMXoS0LTCxtANuQnxFUMwL20DfW/CCJtwWALHwwi2Am+1/YbDeM9Uh3FhWPTiZh5fhLYA==
|
||||
dependencies:
|
||||
dbgate-query-splitter "^4.10.1"
|
||||
dbgate-sqltree "^5.3.4"
|
||||
debug "^4.3.4"
|
||||
json-stable-stringify "^1.0.1"
|
||||
lodash "^4.17.21"
|
||||
pinomin "^1.0.4"
|
||||
uuid "^3.4.0"
|
||||
|
||||
debug@2.6.9, debug@^2.2.0, debug@^2.3.3:
|
||||
version "2.6.9"
|
||||
resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f"
|
||||
@@ -4083,7 +4141,7 @@ fast-glob@^3.0.3:
|
||||
merge2 "^1.3.0"
|
||||
micromatch "^4.0.4"
|
||||
|
||||
fast-json-stable-stringify@2.x, fast-json-stable-stringify@^2.0.0:
|
||||
fast-json-stable-stringify@2.x, fast-json-stable-stringify@^2.0.0, fast-json-stable-stringify@^2.1.0:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633"
|
||||
integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==
|
||||
@@ -6644,6 +6702,11 @@ js-yaml@^4.1.0:
|
||||
dependencies:
|
||||
argparse "^2.0.1"
|
||||
|
||||
jsbi@^4.3.0:
|
||||
version "4.3.0"
|
||||
resolved "https://registry.yarnpkg.com/jsbi/-/jsbi-4.3.0.tgz#b54ee074fb6fcbc00619559305c8f7e912b04741"
|
||||
integrity sha512-SnZNcinB4RIcnEyZqFPdGPVgrg2AcnykiBy0sHVJQKHYeaLUvi3Exj+iaPpLnFVkDPZIV4U0yvgC9/R4uEAZ9g==
|
||||
|
||||
jsbn@1.1.0:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-1.1.0.tgz#b01307cb29b618a1ed26ec79e911f803c4da0040"
|
||||
@@ -8458,6 +8521,11 @@ printj@~1.1.0:
|
||||
resolved "https://registry.yarnpkg.com/printj/-/printj-1.1.2.tgz#d90deb2975a8b9f600fb3a1c94e3f4c53c78a222"
|
||||
integrity sha512-zA2SmoLaxZyArQTOPj5LXecR+RagfPSU5Kw1qP+jkWeNlrq+eJZyY2oS68SU1Z/7/myXM4lo9716laOFAVStCQ==
|
||||
|
||||
priorityqueuejs@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/priorityqueuejs/-/priorityqueuejs-2.0.0.tgz#96064040edd847ee9dd3013d8e16297399a6bd4f"
|
||||
integrity sha512-19BMarhgpq3x4ccvVi8k2QpJZcymo/iFUcrhPd4V96kYGovOdTsWwy7fxChYi4QY+m2EnGBWSX9Buakz+tWNQQ==
|
||||
|
||||
process-nextick-args@~1.0.6:
|
||||
version "1.0.7"
|
||||
resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-1.0.7.tgz#150e20b756590ad3f91093f25a4f2ad8bff30ba3"
|
||||
@@ -9167,6 +9235,11 @@ secure-json-parse@^2.4.0:
|
||||
resolved "https://registry.yarnpkg.com/secure-json-parse/-/secure-json-parse-2.7.0.tgz#5a5f9cd6ae47df23dba3151edd06855d47e09862"
|
||||
integrity sha512-6aU+Rwsezw7VR8/nyvKTx8QpWH9FrcYiXXlqC4z5d5XQBDRqtbfsRjnwGyqbi3gddNtWHuEk9OANUotL26qKUw==
|
||||
|
||||
semaphore@^1.1.0:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/semaphore/-/semaphore-1.1.0.tgz#aaad8b86b20fe8e9b32b16dc2ee682a8cd26a8aa"
|
||||
integrity sha512-O4OZEaNtkMd/K0i6js9SL+gqy0ZCBMgUvlSqHKi4IBdjhe7wB8pwztUk1BbZ1fmrvpwFrPbHzqd2w5pTcJH6LA==
|
||||
|
||||
semiver@^1.0.0:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/semiver/-/semiver-1.1.0.tgz#9c97fb02c21c7ce4fcf1b73e2c7a24324bdddd5f"
|
||||
|
||||
Reference in New Issue
Block a user