From 4fd72ec9e7d6d81bede7778f6f30383c045e4fb6 Mon Sep 17 00:00:00 2001 From: Fabio Date: Tue, 4 Aug 2020 17:54:19 +0200 Subject: [PATCH] refactor: improvements to blob editor and code cleanup --- src/common/fieldTypes.js | 12 + src/common/libs/bufferToBase64.js | 7 + src/common/libs/formatBytes.js | 12 + .../libs/{utilities.js => mimeFromHex.js} | 26 +- src/common/libs/uidGen.js | 4 + src/main/libs/AntaresConnector.js | 2 +- src/main/models/Tables.js | 41 ++- src/renderer/components/BaseConfirmModal.vue | 11 +- .../components/ModalNewConnection.vue | 2 +- src/renderer/components/WorkspaceQueryTab.vue | 3 + .../components/WorkspaceQueryTable.vue | 2 +- .../components/WorkspaceQueryTableCell.vue | 245 +++++++++--------- src/renderer/components/WorkspaceTableTab.vue | 5 +- src/renderer/mixins/tableTabs.js | 16 +- src/renderer/scss/_transitions.scss | 28 ++ src/renderer/scss/main.scss | 9 + .../store/modules/notifications.store.js | 2 +- .../store/modules/workspaces.store.js | 2 +- 18 files changed, 255 insertions(+), 174 deletions(-) create mode 100644 src/common/fieldTypes.js create mode 100644 src/common/libs/bufferToBase64.js create mode 100644 src/common/libs/formatBytes.js rename src/common/libs/{utilities.js => mimeFromHex.js} (72%) create mode 100644 src/common/libs/uidGen.js diff --git a/src/common/fieldTypes.js b/src/common/fieldTypes.js new file mode 100644 index 00000000..f67139af --- /dev/null +++ b/src/common/fieldTypes.js @@ -0,0 +1,12 @@ +export const TEXT = ['char', 'varchar']; +export const LONG_TEXT = ['text', 'mediumtext', 'longtext']; + +export const NUMBER = ['int', 'tinyint', 'smallint', 'mediumint', 'bigint']; + +export const DATE = ['date']; +export const TIME = ['time']; +export const DATETIME = ['datetime', 'timestamp']; + +export const BLOB = ['blob', 'mediumblob', 'longblob']; + +export const BIT = ['bit']; diff --git a/src/common/libs/bufferToBase64.js b/src/common/libs/bufferToBase64.js new file mode 100644 index 00000000..8106dec3 --- /dev/null +++ b/src/common/libs/bufferToBase64.js @@ -0,0 +1,7 @@ +'use strict'; +export function bufferToBase64 (buf) { + const binstr = Array.prototype.map.call(buf, ch => { + return String.fromCharCode(ch); + }).join(''); + return btoa(binstr); +} diff --git a/src/common/libs/formatBytes.js b/src/common/libs/formatBytes.js new file mode 100644 index 00000000..e2f87942 --- /dev/null +++ b/src/common/libs/formatBytes.js @@ -0,0 +1,12 @@ +'use strict'; +export function formatBytes (bytes, decimals = 2) { + if (bytes === 0) return '0 Bytes'; + + const k = 1024; + const dm = decimals < 0 ? 0 : decimals; + const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB']; + + const i = Math.floor(Math.log(bytes) / Math.log(k)); + + return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + ' ' + sizes[i]; +} diff --git a/src/common/libs/utilities.js b/src/common/libs/mimeFromHex.js similarity index 72% rename from src/common/libs/utilities.js rename to src/common/libs/mimeFromHex.js index d9d50525..6d292de6 100644 --- a/src/common/libs/utilities.js +++ b/src/common/libs/mimeFromHex.js @@ -1,7 +1,4 @@ -export function uidGen () { - return Math.random().toString(36).substr(2, 9).toUpperCase(); -}; - +'use strict'; export function mimeFromHex (hex) { switch (hex.substring(0, 4)) { // 2 bytes case '424D': @@ -39,28 +36,11 @@ export function mimeFromHex (hex) { return { ext: 'bpg', mime: 'image/bpg' }; case '4D4D002A': return { ext: 'tif', mime: 'image/tiff' }; + case '00000100': + return { ext: 'ico', mime: 'image/x-icon' }; default: return { ext: '', mime: 'unknown ' + hex }; } } } }; - -export function formatBytes (bytes, decimals = 2) { - if (bytes === 0) return '0 Bytes'; - - const k = 1024; - const dm = decimals < 0 ? 0 : decimals; - const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB']; - - const i = Math.floor(Math.log(bytes) / Math.log(k)); - - return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + ' ' + sizes[i]; -} - -export function bufferToBase64 (buf) { - const binstr = Array.prototype.map.call(buf, ch => { - return String.fromCharCode(ch); - }).join(''); - return btoa(binstr); -} diff --git a/src/common/libs/uidGen.js b/src/common/libs/uidGen.js new file mode 100644 index 00000000..f109f023 --- /dev/null +++ b/src/common/libs/uidGen.js @@ -0,0 +1,4 @@ +'use strict'; +export function uidGen () { + return Math.random().toString(36).substr(2, 9).toUpperCase(); +}; diff --git a/src/main/libs/AntaresConnector.js b/src/main/libs/AntaresConnector.js index 3d0e0f3f..87e1b47d 100644 --- a/src/main/libs/AntaresConnector.js +++ b/src/main/libs/AntaresConnector.js @@ -248,7 +248,7 @@ export class AntaresConnector { * @memberof AntaresConnector */ async raw (sql) { - if (process.env.NODE_ENV === 'development') this._logger(sql); + if (process.env.NODE_ENV === 'development') this._logger(sql);// TODO: replace BLOB content with a placeholder switch (this._client) { // TODO: uniform fields with every client type, needed table name and fields array case 'maria': diff --git a/src/main/models/Tables.js b/src/main/models/Tables.js index 460bbb9a..89b2ff86 100644 --- a/src/main/models/Tables.js +++ b/src/main/models/Tables.js @@ -1,5 +1,6 @@ 'use strict'; import { sqlEscaper } from 'common/libs/sqlEscaper'; +import { TEXT, LONG_TEXT, NUMBER, BLOB } from 'common/fieldTypes'; import fs from 'fs'; export default class { @@ -14,38 +15,32 @@ export default class { static async updateTableCell (connection, params) { let escapedParam; - switch (params.type) { - case 'int': - case 'tinyint': - case 'smallint': - case 'mediumint': - case 'bigint': - escapedParam = params.content; - break; - case 'char': - case 'varchar': - case 'text': - case 'mediumtext': - case 'longtext': - escapedParam = `"${sqlEscaper(params.content)}"`; - break; - case 'blob': - case 'mediumblob': - case 'longblob': { + let reload = false; + + if (NUMBER.includes(params.type)) + escapedParam = params.content; + else if ([...TEXT, ...LONG_TEXT].includes(params.type)) + escapedParam = `"${sqlEscaper(params.content)}"`; + else if (BLOB.includes(params.type)) { + if (params.content) { const fileBlob = fs.readFileSync(params.content); escapedParam = `0x${fileBlob.toString('hex')}`; + reload = true; } - break; - default: - escapedParam = `"${sqlEscaper(params.content)}"`; - break; + else + escapedParam = '""'; } - return connection + else + escapedParam = `"${sqlEscaper(params.content)}"`; + + await connection .update({ [params.field]: `= ${escapedParam}` }) .schema(params.schema) .from(params.table) .where({ [params.primary]: `= ${params.id}` }) .run(); + + return { reload }; } static async deleteTableRows (connection, params) { diff --git a/src/renderer/components/BaseConfirmModal.vue b/src/renderer/components/BaseConfirmModal.vue index fe6df89a..e1776b89 100644 --- a/src/renderer/components/BaseConfirmModal.vue +++ b/src/renderer/components/BaseConfirmModal.vue @@ -29,13 +29,13 @@ class="btn btn-primary mr-2" @click="confirmModal" > - {{ $t('word.confirm') }} + {{ confirmText || $t('word.confirm') }} @@ -48,8 +48,11 @@ export default { props: { size: { type: String, - default: 'small' // small, medium, large - } + validator: prop => ['small', 'medium', 'large'].includes(prop), + default: 'small' + }, + confirmText: String, + cancelText: String }, computed: { hasHeader () { diff --git a/src/renderer/components/ModalNewConnection.vue b/src/renderer/components/ModalNewConnection.vue index 53dfc142..5dae624e 100644 --- a/src/renderer/components/ModalNewConnection.vue +++ b/src/renderer/components/ModalNewConnection.vue @@ -148,7 +148,7 @@