From 902c29ffa551bc3489fa1d9136ee926d135ea14f Mon Sep 17 00:00:00 2001 From: Fabio Di Stasio Date: Wed, 29 Jun 2022 10:48:21 +0200 Subject: [PATCH] feat(MySQL): option to disable foreign key checks when empty a table --- src/common/customizations/defaults.ts | 1 + src/common/customizations/mysql.ts | 1 + src/common/interfaces/customizations.ts | 11 +++---- src/main/libs/clients/MySQLClient.ts | 11 +++++-- src/renderer/components/BaseConfirmModal.vue | 8 +++-- .../WorkspaceExploreBarTableContext.vue | 30 ++++++++++++------- .../components/WorkspaceTabQueryTable.vue | 5 +++- .../components/WorkspaceTabQueryTableRow.vue | 1 + src/renderer/i18n/en-US.ts | 3 +- src/renderer/ipc-api/Tables.ts | 2 +- 10 files changed, 51 insertions(+), 22 deletions(-) diff --git a/src/common/customizations/defaults.ts b/src/common/customizations/defaults.ts index 794a72d4..26d81697 100644 --- a/src/common/customizations/defaults.ts +++ b/src/common/customizations/defaults.ts @@ -31,6 +31,7 @@ export const defaults: Customizations = { elementsWrapper: '', stringsWrapper: '"', tableAdd: false, + tableTruncateDisableFKCheck: false, viewAdd: false, triggerAdd: false, triggerFunctionAdd: false, diff --git a/src/common/customizations/mysql.ts b/src/common/customizations/mysql.ts index e5cd4526..339e00f2 100644 --- a/src/common/customizations/mysql.ts +++ b/src/common/customizations/mysql.ts @@ -28,6 +28,7 @@ export const customizations: Customizations = { elementsWrapper: '', stringsWrapper: '"', tableAdd: true, + tableTruncateDisableFKCheck: true, viewAdd: true, triggerAdd: true, routineAdd: true, diff --git a/src/common/interfaces/customizations.ts b/src/common/interfaces/customizations.ts index de5041e8..4a16ffbd 100644 --- a/src/common/interfaces/customizations.ts +++ b/src/common/interfaces/customizations.ts @@ -29,7 +29,13 @@ export interface Customizations { elementsWrapper: string; stringsWrapper: string; tableAdd?: boolean; + tableSettings?: boolean; + tableOptions?: boolean; + tableArray?: boolean; + tableRealCount?: boolean; + tableTruncateDisableFKCheck?: boolean; viewAdd?: boolean; + viewSettings?: boolean; triggerAdd?: boolean; triggerFunctionAdd?: boolean; routineAdd?: boolean; @@ -41,11 +47,6 @@ export interface Customizations { schemaExport?: boolean; exportByChunks?: boolean; schemaImport?: boolean; - tableSettings?: boolean; - tableOptions?: boolean; - tableArray?: boolean; - tableRealCount?: boolean; - viewSettings?: boolean; triggerSettings?: boolean; triggerFunctionSettings?: boolean; routineSettings?: boolean; diff --git a/src/main/libs/clients/MySQLClient.ts b/src/main/libs/clients/MySQLClient.ts index 36233b99..ba3226f0 100644 --- a/src/main/libs/clients/MySQLClient.ts +++ b/src/main/libs/clients/MySQLClient.ts @@ -912,8 +912,15 @@ export class MySQLClient extends AntaresCore { return await this.raw(sql); } - async truncateTable (params: { schema: string; table: string }) { - const sql = `TRUNCATE TABLE \`${params.schema}\`.\`${params.table}\``; + async truncateTable (params: { schema: string; table: string; force: boolean }) { + let sql = `TRUNCATE TABLE \`${params.schema}\`.\`${params.table}\`;`; + if (params.force) { + sql = ` + SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0; + ${sql} + SET FOREIGN_KEY_CHECKS=IFNULL(@OLD_FOREIGN_KEY_CHECKS, 1); + `; + } return await this.raw(sql); } diff --git a/src/renderer/components/BaseConfirmModal.vue b/src/renderer/components/BaseConfirmModal.vue index 7fd1f4a8..65da82c8 100644 --- a/src/renderer/components/BaseConfirmModal.vue +++ b/src/renderer/components/BaseConfirmModal.vue @@ -61,12 +61,16 @@ const props = defineProps({ default: false }, confirmText: String, - cancelText: String + cancelText: String, + disableAutofocus: { + type: Boolean, + default: false + } }); const emit = defineEmits(['confirm', 'hide']); const slots = useSlots(); -const { trapRef } = useFocusTrap({ disableAutofocus: true }); +const { trapRef } = useFocusTrap({ disableAutofocus: props.disableAutofocus }); const hasHeader = computed(() => !!slots.header); const hasBody = computed(() => !!slots.body); diff --git a/src/renderer/components/WorkspaceExploreBarTableContext.vue b/src/renderer/components/WorkspaceExploreBarTableContext.vue index 4f32ab9b..171134df 100644 --- a/src/renderer/components/WorkspaceExploreBarTableContext.vue +++ b/src/renderer/components/WorkspaceExploreBarTableContext.vue @@ -8,31 +8,31 @@ class="context-element" @click="openTableSettingTab" > - {{ $t('word.settings') }} + {{ t('word.settings') }}
- {{ $t('word.settings') }} + {{ t('word.settings') }}
- {{ $t('message.duplicateTable') }} + {{ t('message.duplicateTable') }}
- {{ $t('message.emptyTable') }} + {{ t('message.emptyTable') }}
- {{ $t('word.delete') }} + {{ t('word.delete') }}
@@ -59,12 +64,12 @@ @@ -79,6 +84,9 @@ import { useWorkspacesStore } from '@/stores/workspaces'; import BaseContextMenu from '@/components/BaseContextMenu.vue'; import ConfirmModal from '@/components/BaseConfirmModal.vue'; import Tables from '@/ipc-api/Tables'; +import { useI18n } from 'vue-i18n'; + +const { t } = useI18n(); const props = defineProps({ contextEvent: MouseEvent, @@ -103,6 +111,7 @@ const { const isDeleteModal = ref(false); const isEmptyModal = ref(false); +const forceTruncate = ref(false); const workspace = computed(() => getWorkspace(selectedWorkspace.value)); const customizations = computed(() => workspace.value && workspace.value.customizations ? workspace.value.customizations : null); @@ -178,7 +187,8 @@ const emptyTable = async () => { const { status, response } = await Tables.truncateTable({ uid: selectedWorkspace.value, table: props.selectedTable.name, - schema: props.selectedSchema + schema: props.selectedSchema, + force: forceTruncate.value }); if (status === 'success') diff --git a/src/renderer/components/WorkspaceTabQueryTable.vue b/src/renderer/components/WorkspaceTabQueryTable.vue index e9c47f71..f16daa05 100644 --- a/src/renderer/components/WorkspaceTabQueryTable.vue +++ b/src/renderer/components/WorkspaceTabQueryTable.vue @@ -457,8 +457,11 @@ const selectAllRows = (e: KeyboardEvent) => { const deselectRows = (e: Event) => { if (!isEditingRow.value) { - selectedRows.value = []; + if (!isDeleteConfirmModal.value) + selectedRows.value = []; + selectedField.value = null; + if (e.type === 'blur') hasFocus.value = false; } diff --git a/src/renderer/components/WorkspaceTabQueryTableRow.vue b/src/renderer/components/WorkspaceTabQueryTableRow.vue index f60951b1..7a6cf6ca 100644 --- a/src/renderer/components/WorkspaceTabQueryTableRow.vue +++ b/src/renderer/components/WorkspaceTabQueryTableRow.vue @@ -70,6 +70,7 @@ v-if="isTextareaEditor" :confirm-text="t('word.update')" size="medium" + :disable-autofocus="true" @confirm="editOFF" @hide="hideEditorModal" > diff --git a/src/renderer/i18n/en-US.ts b/src/renderer/i18n/en-US.ts index 2c4373f7..2fbc93f4 100644 --- a/src/renderer/i18n/en-US.ts +++ b/src/renderer/i18n/en-US.ts @@ -290,7 +290,8 @@ module.exports = { disableBlur: 'Disable blur', untrustedConnection: 'Untrusted connection', missingOrIncompleteTranslation: 'Missing or incomplete translation?', - findOutHowToContribute: 'Find out how to contribute' + findOutHowToContribute: 'Find out how to contribute', + disableFKChecks: 'Disable foreigh key checks' }, faker: { address: 'Address', diff --git a/src/renderer/ipc-api/Tables.ts b/src/renderer/ipc-api/Tables.ts index c058c7e4..f221602c 100644 --- a/src/renderer/ipc-api/Tables.ts +++ b/src/renderer/ipc-api/Tables.ts @@ -98,7 +98,7 @@ export default class { return ipcRenderer.invoke('duplicate-table', unproxify(params)); } - static truncateTable (params: { uid: string; schema: string; table: string }): Promise { + static truncateTable (params: { uid: string; schema: string; table: string; force: boolean }): Promise { return ipcRenderer.invoke('truncate-table', unproxify(params)); }