mirror of https://github.com/Fabio286/antares.git
Merge branch 'beta' of https://github.com/antares-sql/antares
This commit is contained in:
commit
b542a09c01
37
CHANGELOG.md
37
CHANGELOG.md
|
@ -2,6 +2,43 @@
|
|||
|
||||
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
|
||||
|
||||
### [0.7.22-beta.2](https://github.com/antares-sql/antares/compare/v0.7.22-beta.1...v0.7.22-beta.2) (2024-02-18)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **MySQL:** option to enable single connection mode ([d3f71e6](https://github.com/antares-sql/antares/commit/d3f71e65cef88838f03f95a4b34e197fb61878f8))
|
||||
|
||||
### [0.7.22-beta.1](https://github.com/antares-sql/antares/compare/v0.7.22-beta.0...v0.7.22-beta.1) (2024-02-12)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* update dutch translation + fix spelling mistake ([30ada13](https://github.com/antares-sql/antares/commit/30ada13663e88f89beb3dd7291010837059585d5))
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* some issues related to previous commit ([259d051](https://github.com/antares-sql/antares/commit/259d051a21e334496d3a52b662f1855ba9a9046d))
|
||||
* unable to edit tables containing SET fields, fixes [#755](https://github.com/antares-sql/antares/issues/755) ([d698f27](https://github.com/antares-sql/antares/commit/d698f2798a2423f86e6d786dd3ab80439b372a08))
|
||||
|
||||
|
||||
### Improvements
|
||||
|
||||
* **MySQL:** improvements in connection handling ([876d5ea](https://github.com/antares-sql/antares/commit/876d5ea48185334e9e2fc981c4282a9c42d22b10))
|
||||
|
||||
### [0.7.22-beta.0](https://github.com/antares-sql/antares/compare/v0.7.21...v0.7.22-beta.0) (2024-02-04)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **UI:** resizable textarea in new/edito note, closes [#747](https://github.com/antares-sql/antares/issues/747) ([1a0c5da](https://github.com/antares-sql/antares/commit/1a0c5da2f14b99d6f5581b2bf6e916d67d097245))
|
||||
|
||||
|
||||
### Improvements
|
||||
|
||||
* **UI:** improved notes, fixes [#746](https://github.com/antares-sql/antares/issues/746) ([bb36e98](https://github.com/antares-sql/antares/commit/bb36e98bebc5e1e55735e98d272428df2ab682e8))
|
||||
|
||||
### [0.7.21](https://github.com/antares-sql/antares/compare/v0.7.21-beta.1...v0.7.21) (2024-01-13)
|
||||
|
||||
|
||||
|
|
12
README.md
12
README.md
|
@ -71,17 +71,6 @@ On macOS you can run `.dmg` distribution following [this guide](https://support.
|
|||
[<img height='56' alt='Download on Flathub' src='https://dl.flathub.org/assets/badges/flathub-badge-en.svg'/>](https://flathub.org/apps/it.fabiodistasio.AntaresSQL) [![Get it from the Snap Store](https://snapcraft.io/static/images/badges/en/snap-store-black.svg)](https://snapcraft.io/antares) [![Get it from AUR](https://raw.githubusercontent.com/antares-sql/antares/master/docs/aur-badge.svg)](https://aur.archlinux.org/packages/antares-sql-bin) [<img src="https://developer.microsoft.com/store/badges/images/English_get-it-from-MS.png" style="height: 56px">](https://www.microsoft.com/p/antares-sql-client/9nhtb9sq51r1?cid=storebadge&ocid=badge&rtc=1&activetab=pivot:overviewtab)
|
||||
🚀 **[Other Downloads](https://github.com/antares-sql/antares/releases/latest)**
|
||||
|
||||
## Coming soon
|
||||
|
||||
This is a roadmap with major features will come in near future.
|
||||
|
||||
- Database tools.
|
||||
- Users management (add/edit/delete).
|
||||
- More context menu shortcuts.
|
||||
- More keyboard shortcuts.
|
||||
- Support for other databases.
|
||||
- Apple Silicon distribution
|
||||
|
||||
## Currently supported
|
||||
|
||||
### Databases
|
||||
|
@ -90,6 +79,7 @@ This is a roadmap with major features will come in near future.
|
|||
- [x] PostgreSQL
|
||||
- [x] SQLite
|
||||
- [x] Firebird SQL
|
||||
- [ ] DuckDB
|
||||
- [ ] SQL Server
|
||||
- [ ] More...
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load Diff
64
package.json
64
package.json
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"name": "antares",
|
||||
"productName": "Antares",
|
||||
"version": "0.7.21",
|
||||
"version": "0.7.22-beta.2",
|
||||
"description": "A modern, fast and productivity driven SQL client with a focus in UX.",
|
||||
"license": "MIT",
|
||||
"repository": "https://github.com/antares-sql/antares.git",
|
||||
|
@ -124,34 +124,56 @@
|
|||
"@jamescoyle/vue-icon": "~0.1.2",
|
||||
"@mdi/js": "~7.2.96",
|
||||
"@turf/helpers": "~6.5.0",
|
||||
"@vue/compiler-sfc": "~3.2.33",
|
||||
"@vueuse/core": "~10.4.1",
|
||||
"ace-builds": "~1.24.1",
|
||||
"better-sqlite3": "^8.0.1",
|
||||
"babel-loader": "~8.2.3",
|
||||
"better-sqlite3": "~9.4.1",
|
||||
"chalk": "~4.1.2",
|
||||
"cross-env": "~7.0.2",
|
||||
"css-loader": "~6.5.0",
|
||||
"electron-log": "~5.0.1",
|
||||
"electron-store": "~8.1.0",
|
||||
"electron-updater": "~4.6.5",
|
||||
"electron-window-state": "~5.0.3",
|
||||
"encoding": "~0.1.13",
|
||||
"file-loader": "~6.2.0",
|
||||
"floating-vue": "~2.0.0-beta.20",
|
||||
"html-webpack-plugin": "~5.5.0",
|
||||
"json2php": "~0.0.7",
|
||||
"leaflet": "~1.7.1",
|
||||
"marked": "~4.0.19",
|
||||
"moment": "~2.29.4",
|
||||
"mysql2": "~3.5.2",
|
||||
"marked": "~12.0.0",
|
||||
"mini-css-extract-plugin": "~2.4.5",
|
||||
"moment": "~2.30.1",
|
||||
"mysql2": "~3.9.1",
|
||||
"node-firebird": "~1.1.4",
|
||||
"pg": "~8.11.1",
|
||||
"node-loader": "~2.0.0",
|
||||
"pg": "~8.11.3",
|
||||
"pg-connection-string": "~2.5.0",
|
||||
"pg-query-stream": "~4.2.3",
|
||||
"pgsql-ast-parser": "~7.2.1",
|
||||
"pinia": "~2.1.6",
|
||||
"pinia": "~2.1.7",
|
||||
"postcss-html": "~1.5.0",
|
||||
"progress-webpack-plugin": "~1.0.12",
|
||||
"rimraf": "~3.0.2",
|
||||
"sass": "~1.42.1",
|
||||
"sass-loader": "~12.3.0",
|
||||
"source-map-support": "~0.5.20",
|
||||
"spectre.css": "~0.5.9",
|
||||
"sql-formatter": "~13.0.0",
|
||||
"sql-highlight": "~4.4.0",
|
||||
"style-loader": "~3.3.1",
|
||||
"tree-kill": "~1.2.2",
|
||||
"ts-loader": "~9.2.8",
|
||||
"typescript": "~4.6.3",
|
||||
"unzip-crx-3": "~0.2.0",
|
||||
"v-mask": "~2.3.0",
|
||||
"vue": "~3.3.4",
|
||||
"vue": "~3.4.19",
|
||||
"vue-i18n": "~9.2.2",
|
||||
"vuedraggable": "~4.1.0"
|
||||
"vue-loader": "~16.8.3",
|
||||
"vuedraggable": "~4.1.0",
|
||||
"webpack": "~5.72.0",
|
||||
"webpack-cli": "~4.9.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/eslint-parser": "~7.15.7",
|
||||
|
@ -166,13 +188,8 @@
|
|||
"@types/ssh2": "~1.11.6",
|
||||
"@typescript-eslint/eslint-plugin": "~5.18.0",
|
||||
"@typescript-eslint/parser": "~5.18.0",
|
||||
"@vue/compiler-sfc": "~3.2.33",
|
||||
"all-contributors-cli": "~6.20.0",
|
||||
"babel-loader": "~8.2.3",
|
||||
"chalk": "~4.1.2",
|
||||
"cross-env": "~7.0.2",
|
||||
"css-loader": "~6.5.0",
|
||||
"electron": "~22.3.27",
|
||||
"electron": "~26.6.9",
|
||||
"electron-builder": "~24.6.4",
|
||||
"eslint": "~7.32.0",
|
||||
"eslint-config-standard": "~16.0.3",
|
||||
|
@ -181,32 +198,15 @@
|
|||
"eslint-plugin-promise": "~5.2.0",
|
||||
"eslint-plugin-simple-import-sort": "~10.0.0",
|
||||
"eslint-plugin-vue": "~8.0.3",
|
||||
"file-loader": "~6.2.0",
|
||||
"html-webpack-plugin": "~5.5.0",
|
||||
"mini-css-extract-plugin": "~2.4.5",
|
||||
"node-loader": "~2.0.0",
|
||||
"playwright": "~1.28.1",
|
||||
"playwright-core": "~1.28.1",
|
||||
"postcss-html": "~1.5.0",
|
||||
"progress-webpack-plugin": "~1.0.12",
|
||||
"rimraf": "~3.0.2",
|
||||
"sass": "~1.42.1",
|
||||
"sass-loader": "~12.3.0",
|
||||
"standard-version": "~9.3.1",
|
||||
"style-loader": "~3.3.1",
|
||||
"stylelint": "^15.11.0",
|
||||
"stylelint-config-recommended-vue": "~1.5.0",
|
||||
"stylelint-config-standard": "~34.0.0",
|
||||
"stylelint-scss": "~5.3.0",
|
||||
"tree-kill": "~1.2.2",
|
||||
"ts-loader": "~9.2.8",
|
||||
"ts-node": "~10.9.1",
|
||||
"typescript": "~4.6.3",
|
||||
"unzip-crx-3": "~0.2.0",
|
||||
"vue-eslint-parser": "~8.3.0",
|
||||
"vue-loader": "~16.8.3",
|
||||
"webpack": "~5.72.0",
|
||||
"webpack-cli": "~4.9.1",
|
||||
"webpack-dev-server": "~4.11.1",
|
||||
"xvfb-maybe": "~0.2.1"
|
||||
}
|
||||
|
|
|
@ -19,6 +19,7 @@ export const defaults: Customizations = {
|
|||
sshConnection: false,
|
||||
fileConnection: false,
|
||||
cancelQueries: false,
|
||||
singleConnectionMode: false,
|
||||
// Tools
|
||||
processesList: false,
|
||||
usersManagement: false,
|
||||
|
|
|
@ -29,6 +29,7 @@ export const customizations: Customizations = {
|
|||
sslConnection: true,
|
||||
sshConnection: true,
|
||||
cancelQueries: true,
|
||||
singleConnectionMode: true,
|
||||
// Tools
|
||||
processesList: true,
|
||||
// Structure
|
||||
|
|
|
@ -52,6 +52,7 @@ export interface ConnectionParams {
|
|||
password: string;
|
||||
ask: boolean;
|
||||
readonly: boolean;
|
||||
singleConnectionMode: boolean;
|
||||
ssl: boolean;
|
||||
cert?: string;
|
||||
key?: string;
|
||||
|
@ -363,7 +364,7 @@ export interface QueryBuilderObject {
|
|||
offset: number;
|
||||
join: string[];
|
||||
update: string[];
|
||||
insert: {[key: string]: string | boolean | number }[];
|
||||
insert: Record<string, string | boolean | number>[];
|
||||
delete: boolean;
|
||||
}
|
||||
|
||||
|
|
|
@ -19,6 +19,7 @@ export interface Customizations {
|
|||
sshConnection?: boolean;
|
||||
fileConnection?: boolean;
|
||||
cancelQueries?: boolean;
|
||||
singleConnectionMode?: boolean;
|
||||
// Tools
|
||||
processesList?: boolean;
|
||||
usersManagement?: boolean;
|
||||
|
|
|
@ -13,7 +13,7 @@ export interface ExportOptions {
|
|||
includeContent: boolean;
|
||||
includeDropStatement: boolean;
|
||||
}[];
|
||||
includes: {[key: string]: boolean};
|
||||
includes: Record<string, boolean>;
|
||||
outputFormat: 'sql' | 'sql.zip';
|
||||
outputFile: string;
|
||||
sqlInsertAfter: number;
|
||||
|
|
|
@ -18,7 +18,7 @@ export interface TableDeleteParams {
|
|||
primary?: string;
|
||||
field: string;
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
rows: {[key: string]: any};
|
||||
rows: Record<string, any>;
|
||||
}
|
||||
|
||||
export type TableFilterOperator = '=' | '!=' | '>' | '<' | '>=' | '<=' | 'IN' | 'NOT IN' | 'LIKE' | 'NOT LIKE' | 'RLIKE' | 'NOT RLIKE' | 'BETWEEN' | 'IS NULL' | 'IS NOT NULL'
|
||||
|
@ -35,17 +35,16 @@ export interface InsertRowsParams {
|
|||
uid: string;
|
||||
schema: string;
|
||||
table: string;
|
||||
row: {[key: string]: {
|
||||
group: string;
|
||||
method: string;
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
params: any;
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
value: any;
|
||||
length: number;
|
||||
};
|
||||
};
|
||||
row: Record<string, {
|
||||
group: string;
|
||||
method: string;
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
params: any;
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
value: any;
|
||||
length: number;
|
||||
}>;
|
||||
repeat: number;
|
||||
fields: {[key: string]: string};
|
||||
fields: Record<string, string>;
|
||||
locale: UsableLocale;
|
||||
}
|
||||
|
|
|
@ -41,7 +41,7 @@ export const escapeAndQuote = (val: string, client: ClientCode) => {
|
|||
const { stringsWrapper: sw } = customizations[client];
|
||||
// eslint-disable-next-line no-control-regex
|
||||
const CHARS_TO_ESCAPE = /[\0\b\t\n\r\x1a"'\\]/g;
|
||||
const CHARS_ESCAPE_MAP: {[key: string]: string} = {
|
||||
const CHARS_ESCAPE_MAP: Record<string, string> = {
|
||||
'\0': '\\0',
|
||||
'\b': '\\b',
|
||||
'\t': '\\t',
|
||||
|
@ -153,9 +153,9 @@ export const valueToSqlString = (args: {
|
|||
};
|
||||
|
||||
export const jsonToSqlInsert = (args: {
|
||||
json: { [key: string]: any}[];
|
||||
json: Record<string, any>[];
|
||||
client: ClientCode;
|
||||
fields: { [key: string]: {type: string; datePrecision: number}};
|
||||
fields: Record<string, {type: string; datePrecision: number}>;
|
||||
table: string;
|
||||
options?: {sqlInsertAfter: number; sqlInsertDivider: 'bytes' | 'rows'};
|
||||
}) => {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
export const shortcutEvents: { [key: string]: { l18n: string; l18nParam?: string | number; context?: 'tab' }} = {
|
||||
export const shortcutEvents: Record<string, { l18n: string; l18nParam?: string | number; context?: 'tab' }> = {
|
||||
'run-or-reload': { l18n: 'application.runOrReload', context: 'tab' },
|
||||
'open-new-tab': { l18n: 'application.openNewTab', context: 'tab' },
|
||||
'close-tab': { l18n: 'application.closeTab', context: 'tab' },
|
||||
|
|
|
@ -6,7 +6,7 @@ import { SslOptions } from 'mysql2';
|
|||
import { ClientsFactory } from '../libs/ClientsFactory';
|
||||
import { validateSender } from '../libs/misc/validateSender';
|
||||
|
||||
export default (connections: {[key: string]: antares.Client}) => {
|
||||
export default (connections: Record<string, antares.Client>) => {
|
||||
ipcMain.handle('test-connection', async (event, conn: antares.ConnectionParams) => {
|
||||
if (!validateSender(event.senderFrame)) return { status: 'error', response: 'Unauthorized process' };
|
||||
|
||||
|
@ -146,7 +146,7 @@ export default (connections: {[key: string]: antares.Client}) => {
|
|||
uid: conn.uid,
|
||||
client: conn.client,
|
||||
params,
|
||||
poolSize: 5
|
||||
poolSize: conn.singleConnectionMode ? 0 : 5
|
||||
});
|
||||
|
||||
await connection.connect();
|
||||
|
|
|
@ -3,7 +3,7 @@ import { ipcMain } from 'electron';
|
|||
|
||||
import { validateSender } from '../libs/misc/validateSender';
|
||||
|
||||
export default (connections: {[key: string]: antares.Client}) => {
|
||||
export default (connections: Record<string, antares.Client>) => {
|
||||
ipcMain.handle('get-databases', async (event, uid) => {
|
||||
if (!validateSender(event.senderFrame)) return { status: 'error', response: 'Unauthorized process' };
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@ import { ipcMain } from 'electron';
|
|||
|
||||
import { validateSender } from '../libs/misc/validateSender';
|
||||
|
||||
export default (connections: {[key: string]: antares.Client}) => {
|
||||
export default (connections: Record<string, antares.Client>) => {
|
||||
ipcMain.handle('get-function-informations', async (event, params) => {
|
||||
if (!validateSender(event.senderFrame)) return { status: 'error', response: 'Unauthorized process' };
|
||||
|
||||
|
|
|
@ -13,7 +13,7 @@ import updates from './updates';
|
|||
import users from './users';
|
||||
import views from './views';
|
||||
|
||||
const connections: {[key: string]: antares.Client} = {};
|
||||
const connections: Record<string, antares.Client> = {};
|
||||
|
||||
export default () => {
|
||||
connection(connections);
|
||||
|
|
|
@ -3,7 +3,7 @@ import { ipcMain } from 'electron';
|
|||
|
||||
import { validateSender } from '../libs/misc/validateSender';
|
||||
|
||||
export default (connections: {[key: string]: antares.Client}) => {
|
||||
export default (connections: Record<string, antares.Client>) => {
|
||||
ipcMain.handle('get-routine-informations', async (event, params) => {
|
||||
if (!validateSender(event.senderFrame)) return { status: 'error', response: 'Unauthorized process' };
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@ import { ipcMain } from 'electron';
|
|||
|
||||
import { validateSender } from '../libs/misc/validateSender';
|
||||
|
||||
export default (connections: {[key: string]: antares.Client}) => {
|
||||
export default (connections: Record<string, antares.Client>) => {
|
||||
ipcMain.handle('get-scheduler-informations', async (event, params) => {
|
||||
if (!validateSender(event.senderFrame)) return { status: 'error', response: 'Unauthorized process' };
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@ import { Worker } from 'worker_threads';
|
|||
|
||||
import { validateSender } from '../libs/misc/validateSender';
|
||||
|
||||
export default (connections: {[key: string]: antares.Client}) => {
|
||||
export default (connections: Record<string, antares.Client>) => {
|
||||
let exporter: Worker = null;
|
||||
let importer: Worker = null;
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@ import * as moment from 'moment';
|
|||
|
||||
import { validateSender } from '../libs/misc/validateSender';
|
||||
|
||||
export default (connections: {[key: string]: antares.Client}) => {
|
||||
export default (connections: Record<string, antares.Client>) => {
|
||||
ipcMain.handle('get-table-columns', async (event, params) => {
|
||||
if (!validateSender(event.senderFrame)) return { status: 'error', response: 'Unauthorized process' };
|
||||
|
||||
|
@ -249,7 +249,7 @@ export default (connections: {[key: string]: antares.Client}) => {
|
|||
|
||||
if (params.primary) {
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
const idString = params.rows.map((row: {[key: string]: any}) => {
|
||||
const idString = params.rows.map((row: Record<string, any>) => {
|
||||
const fieldName = Object.keys(row)[0].includes('.') ? `${params.table}.${params.primary}` : params.primary;
|
||||
|
||||
return typeof row[fieldName] === 'string'
|
||||
|
@ -304,10 +304,10 @@ export default (connections: {[key: string]: antares.Client}) => {
|
|||
if (!validateSender(event.senderFrame)) return { status: 'error', response: 'Unauthorized process' };
|
||||
|
||||
try { // TODO: move to client classes
|
||||
const rows: {[key: string]: string | number | boolean | Date | Buffer}[] = [];
|
||||
const rows: Record<string, string | number | boolean | Date | Buffer>[] = [];
|
||||
|
||||
for (let i = 0; i < +params.repeat; i++) {
|
||||
const insertObj: {[key: string]: string | number | boolean | Date | Buffer} = {};
|
||||
const insertObj: Record<string, string | number | boolean | Date | Buffer> = {};
|
||||
|
||||
for (const key in params.row) {
|
||||
const type = params.fields[key];
|
||||
|
@ -367,7 +367,7 @@ export default (connections: {[key: string]: antares.Client}) => {
|
|||
insertObj[key] = escapedParam;
|
||||
}
|
||||
else { // Faker value
|
||||
const parsedParams: {[key: string]: string | number | boolean | Date | Buffer} = {};
|
||||
const parsedParams: Record<string, string | number | boolean | Date | Buffer> = {};
|
||||
let fakeValue;
|
||||
|
||||
if (params.locale)
|
||||
|
@ -437,12 +437,12 @@ export default (connections: {[key: string]: antares.Client}) => {
|
|||
if (description)
|
||||
query.select(`LEFT(${description}, 20) AS foreign_description`);
|
||||
|
||||
const results = await query.run<{[key: string]: string}>();
|
||||
const results = await query.run<Record<string, string>>();
|
||||
|
||||
const parsedResults: {[key: string]: string}[] = [];
|
||||
const parsedResults: Record<string, string>[] = [];
|
||||
|
||||
for (const row of results.rows) {
|
||||
const remappedRow: {[key: string]: string} = {};
|
||||
const remappedRow: Record<string, string> = {};
|
||||
|
||||
for (const key in row)
|
||||
remappedRow[key.toLowerCase()] = row[key];// Thanks Firebird -.-
|
||||
|
|
|
@ -3,7 +3,7 @@ import { ipcMain } from 'electron';
|
|||
|
||||
import { validateSender } from '../libs/misc/validateSender';
|
||||
|
||||
export default (connections: {[key: string]: antares.Client}) => {
|
||||
export default (connections: Record<string, antares.Client>) => {
|
||||
ipcMain.handle('get-trigger-informations', async (event, params) => {
|
||||
if (!validateSender(event.senderFrame)) return { status: 'error', response: 'Unauthorized process' };
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@ import { ipcMain } from 'electron';
|
|||
|
||||
import { validateSender } from '../libs/misc/validateSender';
|
||||
|
||||
export default (connections: {[key: string]: antares.Client}) => {
|
||||
export default (connections: Record<string, antares.Client>) => {
|
||||
ipcMain.handle('get-users', async (event, uid) => {
|
||||
if (!validateSender(event.senderFrame)) return { status: 'error', response: 'Unauthorized process' };
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@ import { ipcMain } from 'electron';
|
|||
|
||||
import { validateSender } from '../libs/misc/validateSender';
|
||||
|
||||
export default (connections: {[key: string]: antares.Client}) => {
|
||||
export default (connections: Record<string, antares.Client>) => {
|
||||
ipcMain.handle('get-view-informations', async (event, params) => {
|
||||
if (!validateSender(event.senderFrame)) return { status: 'error', response: 'Unauthorized process' };
|
||||
|
||||
|
|
|
@ -136,7 +136,7 @@ export abstract class BaseClient {
|
|||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
insert (arr: {[key: string]: any}[]) {
|
||||
insert (arr: Record<string, any>[]) {
|
||||
this._query.insert = [...this._query.insert, ...arr];
|
||||
return this;
|
||||
}
|
||||
|
|
|
@ -13,7 +13,7 @@ export class FirebirdSQLClient extends BaseClient {
|
|||
protected _connection?: firebird.Database | firebird.ConnectionPool;
|
||||
_params: firebird.Options;
|
||||
|
||||
private _types: {[key: number]: string} ={
|
||||
private _types: Record<number, string> ={
|
||||
452: 'CHAR', // Array of char
|
||||
448: 'VARCHAR',
|
||||
500: 'SMALLINT',
|
||||
|
|
|
@ -12,10 +12,11 @@ export class MySQLClient extends BaseClient {
|
|||
private _connectionsToCommit: Map<string, mysql.Connection | mysql.PoolConnection>;
|
||||
private _keepaliveTimer: NodeJS.Timer;
|
||||
private _keepaliveMs: number;
|
||||
private sqlMode?: string[];
|
||||
_connection?: mysql.Connection | mysql.Pool;
|
||||
_params: mysql.ConnectionOptions & {schema: string; ssl?: mysql.SslOptions; ssh?: SSHConfig; readonly: boolean};
|
||||
|
||||
private types: {[key: number]: string} = {
|
||||
private types: Record<number, string> = {
|
||||
0: 'DECIMAL',
|
||||
1: 'TINYINT',
|
||||
2: 'SMALLINT',
|
||||
|
@ -58,6 +59,10 @@ export class MySQLClient extends BaseClient {
|
|||
this._keepaliveMs = 10*60*1000;
|
||||
}
|
||||
|
||||
private get isPool () {
|
||||
return 'getConnection' in this._connection;
|
||||
}
|
||||
|
||||
private _getType (field: mysql.FieldPacket & { columnType?: number; columnLength?: number }) {
|
||||
let name = this.types[field.columnType];
|
||||
let length = field.columnLength;
|
||||
|
@ -181,9 +186,32 @@ export class MySQLClient extends BaseClient {
|
|||
|
||||
async connect () {
|
||||
if (!this._poolSize)
|
||||
this._connection = await this.getConnection();
|
||||
this._connection = await this.getSingleConnection();
|
||||
else
|
||||
this._connection = await this.getConnectionPool();
|
||||
|
||||
// ANSI_QUOTES check
|
||||
const [response] = await this._connection.query<mysql.RowDataPacket[]>('SHOW GLOBAL VARIABLES LIKE \'%sql_mode%\'');
|
||||
this.sqlMode = response[0]?.Value?.split(',');
|
||||
const hasAnsiQuotes = this.sqlMode.includes('ANSI') || this.sqlMode.includes('ANSI_QUOTES');
|
||||
|
||||
if (hasAnsiQuotes)
|
||||
await this._connection.query(`SET SESSION sql_mode = '${this.sqlMode.filter((m: string) => !['ANSI', 'ANSI_QUOTES'].includes(m)).join(',')}'`);
|
||||
|
||||
if (this._params.readonly)
|
||||
await this._connection.query('SET SESSION TRANSACTION READ ONLY');
|
||||
|
||||
if (this._poolSize) {
|
||||
const hasAnsiQuotes = this.sqlMode.includes('ANSI') || this.sqlMode.includes('ANSI_QUOTES');
|
||||
|
||||
this._connection.on('connection', conn => {
|
||||
if (this._params.readonly)
|
||||
conn.query('SET SESSION TRANSACTION READ ONLY');
|
||||
|
||||
if (hasAnsiQuotes)
|
||||
conn.query(`SET SESSION sql_mode = '${this.sqlMode.filter((m: string) => !['ANSI', 'ANSI_QUOTES'].includes(m)).join(',')}'`);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
destroy () {
|
||||
|
@ -196,7 +224,7 @@ export class MySQLClient extends BaseClient {
|
|||
}
|
||||
}
|
||||
|
||||
async getConnection () {
|
||||
async getSingleConnection () {
|
||||
const dbConfig = await this.getDbConfig();
|
||||
const connection = await mysql.createConnection({
|
||||
...dbConfig,
|
||||
|
@ -208,17 +236,6 @@ export class MySQLClient extends BaseClient {
|
|||
}
|
||||
});
|
||||
|
||||
// ANSI_QUOTES check
|
||||
const [response] = await connection.query<mysql.RowDataPacket[]>('SHOW GLOBAL VARIABLES LIKE \'%sql_mode%\'');
|
||||
const sqlMode: string[] = response[0]?.Value?.split(',');
|
||||
const hasAnsiQuotes = sqlMode.includes('ANSI') || sqlMode.includes('ANSI_QUOTES');
|
||||
|
||||
if (this._params.readonly)
|
||||
await connection.query('SET SESSION TRANSACTION READ ONLY');
|
||||
|
||||
if (hasAnsiQuotes)
|
||||
await connection.query(`SET SESSION sql_mode = '${sqlMode.filter((m: string) => !['ANSI', 'ANSI_QUOTES'].includes(m)).join(',')}'`);
|
||||
|
||||
return connection;
|
||||
}
|
||||
|
||||
|
@ -227,6 +244,7 @@ export class MySQLClient extends BaseClient {
|
|||
const connection = mysql.createPool({
|
||||
...dbConfig,
|
||||
connectionLimit: this._poolSize,
|
||||
enableKeepAlive: true,
|
||||
typeCast: (field, next) => {
|
||||
if (field.type === 'DATETIME')
|
||||
return field.string();
|
||||
|
@ -235,25 +253,6 @@ export class MySQLClient extends BaseClient {
|
|||
}
|
||||
});
|
||||
|
||||
// ANSI_QUOTES check
|
||||
const [res] = await connection.query<mysql.RowDataPacket[]>('SHOW GLOBAL VARIABLES LIKE \'%sql_mode%\'');
|
||||
const sqlMode: string[] = res[0]?.Value?.split(',');
|
||||
const hasAnsiQuotes = sqlMode.includes('ANSI') || sqlMode.includes('ANSI_QUOTES');
|
||||
|
||||
if (hasAnsiQuotes)
|
||||
await connection.query(`SET SESSION sql_mode = '${sqlMode.filter((m: string) => !['ANSI', 'ANSI_QUOTES'].includes(m)).join(',')}'`);
|
||||
|
||||
if (this._params.readonly)
|
||||
await connection.query('SET SESSION TRANSACTION READ ONLY');
|
||||
|
||||
connection.on('connection', conn => {
|
||||
if (this._params.readonly)
|
||||
conn.query('SET SESSION TRANSACTION READ ONLY');
|
||||
|
||||
if (hasAnsiQuotes)
|
||||
conn.query(`SET SESSION sql_mode = '${sqlMode.filter((m: string) => !['ANSI', 'ANSI_QUOTES'].includes(m)).join(',')}'`);
|
||||
});
|
||||
|
||||
this._keepaliveTimer = setInterval(async () => {
|
||||
await this.keepAlive();
|
||||
}, this._keepaliveMs);
|
||||
|
@ -261,6 +260,43 @@ export class MySQLClient extends BaseClient {
|
|||
return connection;
|
||||
}
|
||||
|
||||
async getConnection (args?: antares.QueryParams, retry?: boolean): Promise<mysql.Pool | mysql.PoolConnection | mysql.Connection> {
|
||||
let connection;
|
||||
|
||||
try {
|
||||
if (args && !args.autocommit && args.tabUid) { // autocommit OFF
|
||||
if (this._connectionsToCommit.has(args.tabUid))
|
||||
connection = this._connectionsToCommit.get(args.tabUid);
|
||||
else {
|
||||
connection = await this.getSingleConnection();
|
||||
await connection.query('SET SESSION autocommit=0');
|
||||
this._connectionsToCommit.set(args.tabUid, connection);
|
||||
}
|
||||
}
|
||||
else// autocommit ON
|
||||
connection = this.isPool ? await (this._connection as mysql.Pool).getConnection() : this._connection;
|
||||
|
||||
if (args && args.tabUid && this.isPool) {
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
this._runningConnections.set(args.tabUid, (connection as any).connection.connectionId);
|
||||
}
|
||||
|
||||
if (args && args.schema)
|
||||
await connection.query(`USE \`${args.schema}\``);
|
||||
|
||||
return connection;
|
||||
}
|
||||
catch (error) {
|
||||
if (error.code === 'ECONNRESET' && !retry) {
|
||||
this.destroy();
|
||||
await this.connect();
|
||||
return this.getConnection(args, true);
|
||||
}
|
||||
else
|
||||
throw new Error(error.message);
|
||||
}
|
||||
}
|
||||
|
||||
private async keepAlive () {
|
||||
try {
|
||||
const connection = await (this._connection as mysql.Pool).getConnection();
|
||||
|
@ -582,7 +618,7 @@ export class MySQLClient extends BaseClient {
|
|||
}
|
||||
})
|
||||
.filter(Boolean)
|
||||
.reduce((acc: {[key: string]: { name: string; type: string; length: string; default: string}}, curr) => {
|
||||
.reduce((acc: Record<string, { name: string; type: string; length: string; default: string}>, curr) => {
|
||||
acc[curr.name] = curr;
|
||||
return acc;
|
||||
}, {});
|
||||
|
@ -591,7 +627,7 @@ export class MySQLClient extends BaseClient {
|
|||
return rows.map((field) => {
|
||||
const numLengthMatch = field.COLUMN_TYPE.match(/int\(([^)]+)\)/);
|
||||
const numLength = numLengthMatch ? +numLengthMatch.pop() : field.NUMERIC_PRECISION || null;
|
||||
const enumValues = /(enum)/.test(field.COLUMN_TYPE)
|
||||
const enumValues = /(enum|set)/.test(field.COLUMN_TYPE)
|
||||
? field.COLUMN_TYPE.match(/\(([^)]+)\)/)[0].slice(1, -1)
|
||||
: null;
|
||||
|
||||
|
@ -1648,28 +1684,7 @@ export class MySQLClient extends BaseClient {
|
|||
.map(q => q.trim())
|
||||
: [sql];
|
||||
|
||||
let connection: mysql.Connection | mysql.Pool | mysql.PoolConnection;
|
||||
const isPool = 'getConnection' in this._connection;
|
||||
|
||||
if (!args.autocommit && args.tabUid) { // autocommit OFF
|
||||
if (this._connectionsToCommit.has(args.tabUid))
|
||||
connection = this._connectionsToCommit.get(args.tabUid);
|
||||
else {
|
||||
connection = await this.getConnection();
|
||||
await connection.query('SET SESSION autocommit=0');
|
||||
this._connectionsToCommit.set(args.tabUid, connection);
|
||||
}
|
||||
}
|
||||
else// autocommit ON
|
||||
connection = isPool ? await (this._connection as mysql.Pool).getConnection() : this._connection;
|
||||
|
||||
if (args.tabUid && isPool) {
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
this._runningConnections.set(args.tabUid, (connection as any).connection.connectionId);
|
||||
}
|
||||
|
||||
if (args.schema)
|
||||
await connection.query(`USE \`${args.schema}\``);
|
||||
const connection = await this.getConnection(args);
|
||||
|
||||
for (const query of queries) {
|
||||
if (!query) continue;
|
||||
|
@ -1729,7 +1744,7 @@ export class MySQLClient extends BaseClient {
|
|||
});
|
||||
}
|
||||
catch (err) {
|
||||
if (isPool && args.autocommit) {
|
||||
if (this.isPool && args.autocommit) {
|
||||
(connection as mysql.PoolConnection).release();
|
||||
this._runningConnections.delete(args.tabUid);
|
||||
}
|
||||
|
@ -1741,7 +1756,7 @@ export class MySQLClient extends BaseClient {
|
|||
keysArr = keysArr ? [...keysArr, ...response] : response;
|
||||
}
|
||||
catch (err) {
|
||||
if (isPool && args.autocommit) {
|
||||
if (this.isPool && args.autocommit) {
|
||||
(connection as mysql.PoolConnection).release();
|
||||
this._runningConnections.delete(args.tabUid);
|
||||
}
|
||||
|
@ -1759,7 +1774,7 @@ export class MySQLClient extends BaseClient {
|
|||
keys: keysArr
|
||||
});
|
||||
}).catch((err) => {
|
||||
if (isPool && args.autocommit) {
|
||||
if (this.isPool && args.autocommit) {
|
||||
(connection as mysql.PoolConnection).release();
|
||||
this._runningConnections.delete(args.tabUid);
|
||||
}
|
||||
|
@ -1776,7 +1791,7 @@ export class MySQLClient extends BaseClient {
|
|||
});
|
||||
}
|
||||
|
||||
if (isPool && args.autocommit) {
|
||||
if (this.isPool && args.autocommit) {
|
||||
(connection as mysql.PoolConnection).release();
|
||||
this._runningConnections.delete(args.tabUid);
|
||||
}
|
||||
|
|
|
@ -88,8 +88,8 @@ export class PostgreSQLClient extends BaseClient {
|
|||
private _keepaliveTimer: NodeJS.Timer;
|
||||
private _keepaliveMs: number;
|
||||
protected _connection?: pg.Client | pg.Pool;
|
||||
private types: {[key: string]: string} = {};
|
||||
private _arrayTypes: {[key: string]: string} = {
|
||||
private types: Record<string, string> = {};
|
||||
private _arrayTypes: Record<string, string> = {
|
||||
_int2: 'SMALLINT',
|
||||
_int4: 'INTEGER',
|
||||
_int8: 'BIGINT',
|
||||
|
@ -656,7 +656,7 @@ export class PostgreSQLClient extends BaseClient {
|
|||
let createSql = '';
|
||||
const sequences = [];
|
||||
const columnsSql = [];
|
||||
const arrayTypes: {[key: string]: string} = {
|
||||
const arrayTypes: Record<string, string> = {
|
||||
_int2: 'smallint',
|
||||
_int4: 'integer',
|
||||
_int8: 'bigint',
|
||||
|
|
|
@ -658,7 +658,7 @@ export class SQLiteClient extends BaseClient {
|
|||
let queryAllResult: any[];
|
||||
let affectedRows;
|
||||
let fields;
|
||||
const detectedTypes: {[key: string]: string} = {};
|
||||
const detectedTypes: Record<string, string> = {};
|
||||
|
||||
try {
|
||||
const stmt = connection.prepare(query);
|
||||
|
|
|
@ -354,7 +354,7 @@ CREATE TABLE \`${view.Name}\`(
|
|||
escapeAndQuote (val: string) {
|
||||
// eslint-disable-next-line no-control-regex
|
||||
const CHARS_TO_ESCAPE = /[\0\b\t\n\r\x1a"'\\]/g;
|
||||
const CHARS_ESCAPE_MAP: {[key: string]: string} = {
|
||||
const CHARS_ESCAPE_MAP: Record<string, string> = {
|
||||
'\0': '\\0',
|
||||
'\b': '\\b',
|
||||
'\t': '\\t',
|
||||
|
|
|
@ -59,7 +59,7 @@ SET row_security = off;\n\n\n`;
|
|||
let createSql = '';
|
||||
const sequences = [];
|
||||
const columnsSql = [];
|
||||
const arrayTypes: {[key: string]: string} = {
|
||||
const arrayTypes: Record<string, string> = {
|
||||
_int2: 'smallint',
|
||||
_int4: 'integer',
|
||||
_int8: 'bigint',
|
||||
|
@ -440,7 +440,7 @@ SET row_security = off;\n\n\n`;
|
|||
escapeAndQuote (val: string) {
|
||||
// eslint-disable-next-line no-control-regex
|
||||
const CHARS_TO_ESCAPE = /[\0\b\t\n\r\x1a"'\\]/g;
|
||||
const CHARS_ESCAPE_MAP: {[key: string]: string} = {
|
||||
const CHARS_ESCAPE_MAP: Record<string, string> = {
|
||||
'\0': '\\0',
|
||||
'\b': '\\b',
|
||||
'\t': '\\t',
|
||||
|
|
|
@ -56,8 +56,8 @@ const { t } = useI18n();
|
|||
|
||||
const props = defineProps({
|
||||
size: {
|
||||
type: String as PropType<'small' | 'medium' | '400' | 'large'>,
|
||||
validator: (prop: string) => ['small', 'medium', '400', 'large'].includes(prop),
|
||||
type: String as PropType<'small' | 'medium' | '400' | 'large' | 'resize'>,
|
||||
validator: (prop: string) => ['small', 'medium', '400', 'large', 'resize'].includes(prop),
|
||||
default: 'small'
|
||||
},
|
||||
hideFooter: {
|
||||
|
@ -88,6 +88,8 @@ const modalSizeClass = computed(() => {
|
|||
return 'modal-sm';
|
||||
if (props.size === '400')
|
||||
return 'modal-400';
|
||||
if (props.size === 'resize')
|
||||
return 'modal-resize';
|
||||
else if (props.size === 'large')
|
||||
return 'modal-lg';
|
||||
else return '';
|
||||
|
@ -120,6 +122,12 @@ onBeforeUnmount(() => {
|
|||
max-width: 400px;
|
||||
}
|
||||
|
||||
.modal-resize .modal-container {
|
||||
max-width: 95vw;
|
||||
max-height: 95vh;
|
||||
width: auto;
|
||||
}
|
||||
|
||||
.modal.modal-sm .modal-container {
|
||||
padding: 0;
|
||||
}
|
||||
|
|
|
@ -4,7 +4,11 @@
|
|||
:id="`editor-${id}`"
|
||||
class="editor"
|
||||
:class="editorClass"
|
||||
:style="{height: `${height}px`}"
|
||||
:style="{
|
||||
height: `${height}px`,
|
||||
width: width ? `${width}px` : null,
|
||||
resize: resizable ? 'both' : 'none'
|
||||
}"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
@ -17,7 +21,7 @@ import 'ace-builds/webpack-resolver';
|
|||
|
||||
import { uidGen } from 'common/libs/uidGen';
|
||||
import { storeToRefs } from 'pinia';
|
||||
import { onMounted, watch } from 'vue';
|
||||
import { PropType, onMounted, watch } from 'vue';
|
||||
|
||||
import { useSettingsStore } from '@/stores/settings';
|
||||
|
||||
|
@ -25,10 +29,12 @@ const props = defineProps({
|
|||
modelValue: String,
|
||||
mode: { type: String, default: 'text' },
|
||||
editorClass: { type: String, default: '' },
|
||||
resizable: { type: Boolean, default: false },
|
||||
autoFocus: { type: Boolean, default: false },
|
||||
readOnly: { type: Boolean, default: false },
|
||||
showLineNumbers: { type: Boolean, default: true },
|
||||
height: { type: Number, default: 200 }
|
||||
height: { type: Number, default: 200 },
|
||||
width: { type: [Number, Boolean] as PropType<number|false>, default: false }
|
||||
});
|
||||
const emit = defineEmits(['update:modelValue']);
|
||||
const settingsStore = useSettingsStore();
|
||||
|
@ -132,8 +138,10 @@ onMounted(() => {
|
|||
|
||||
<style lang="scss" scoped>
|
||||
.editor-wrapper {
|
||||
.editor {
|
||||
width: 100%;
|
||||
}
|
||||
.editor {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
max-width: 90vw;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -113,7 +113,7 @@ const selectedGroup: Ref<string> = ref('manual');
|
|||
const selectedMethod: Ref<string> = ref('');
|
||||
const selectedValue: Ref<string> = ref('');
|
||||
const debounceTimeout: Ref<NodeJS.Timeout> = ref(null);
|
||||
const methodParams: Ref<{[key: string]: string}> = ref({});
|
||||
const methodParams: Ref<Record<string, string>> = ref({});
|
||||
const enumArray: Ref<string[]> = ref(null);
|
||||
|
||||
const fakerGroups = computed(() => {
|
||||
|
|
|
@ -73,7 +73,7 @@ const props = defineProps({
|
|||
const emit = defineEmits(['confirm', 'close']);
|
||||
|
||||
const firstInput: Ref<HTMLInputElement[]> = ref(null);
|
||||
const values: Ref<{[key: string]: string}> = ref({});
|
||||
const values: Ref<Record<string, string>> = ref({});
|
||||
|
||||
const inParameters = computed(() => {
|
||||
return props.localRoutine.parameters.filter(param => param.context === 'IN');
|
||||
|
|
|
@ -327,7 +327,7 @@ const tables: Ref<{
|
|||
}[]> = ref([]);
|
||||
const options: Ref<Partial<ExportOptions>> = ref({
|
||||
schema: selectedSchema.value,
|
||||
includes: {} as {[key: string]: boolean},
|
||||
includes: {} as Record<string, boolean>,
|
||||
outputFormat: 'sql' as 'sql' | 'sql.zip',
|
||||
sqlInsertAfter: 250,
|
||||
sqlInsertDivider: 'bytes' as 'bytes' | 'rows'
|
||||
|
|
|
@ -142,7 +142,7 @@ const { getSelected: selectedWorkspace } = storeToRefs(workspacesStore);
|
|||
const { trapRef } = useFocusTrap({ disableAutofocus: true });
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
const localRow: Ref<{[key: string]: any}> = ref({});
|
||||
const localRow: Ref<Record<string, any>> = ref({});
|
||||
const fieldsToExclude = ref([]);
|
||||
const nInserts = ref(1);
|
||||
const isInserting = ref(false);
|
||||
|
@ -225,7 +225,7 @@ const insertRows = async () => {
|
|||
delete rowToInsert[key];
|
||||
});
|
||||
|
||||
const fieldTypes: {[key: string]: string} = {};
|
||||
const fieldTypes: Record<string, string> = {};
|
||||
props.fields.forEach(field => {
|
||||
fieldTypes[field.name] = field.type;
|
||||
});
|
||||
|
@ -290,7 +290,7 @@ onMounted(() => {
|
|||
}
|
||||
}, 50);
|
||||
|
||||
const rowObj: {[key: string]: unknown} = {};
|
||||
const rowObj: Record<string, unknown> = {};
|
||||
|
||||
if (!props.rowToDuplicate) {
|
||||
// Set default values
|
||||
|
|
|
@ -115,7 +115,7 @@
|
|||
<BaseIcon icon-name="mdiHistory" :size="48" />
|
||||
</div>
|
||||
<p class="empty-title h5">
|
||||
{{ t('database.thereIsNoQueriesYet') }}
|
||||
{{ t('database.thereAreNoQueriesYet') }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<template>
|
||||
<ConfirmModal
|
||||
size="medium"
|
||||
size="resize"
|
||||
:disable-autofocus="true"
|
||||
:close-on-confirm="!!localNote.note.length"
|
||||
:confirm-text="t('general.save')"
|
||||
|
@ -52,6 +52,10 @@
|
|||
v-model="localNote.note"
|
||||
:mode="editorMode"
|
||||
:show-line-numbers="false"
|
||||
:auto-focus="true"
|
||||
:height="400"
|
||||
:width="640"
|
||||
:resizable="true"
|
||||
/>
|
||||
</div>
|
||||
</form>
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<template>
|
||||
<ConfirmModal
|
||||
size="medium"
|
||||
size="resize"
|
||||
:disable-autofocus="true"
|
||||
:close-on-confirm="!!newNote.note.length"
|
||||
:confirm-text="t('general.save')"
|
||||
|
@ -52,6 +52,10 @@
|
|||
v-model="newNote.note"
|
||||
:mode="editorMode"
|
||||
:show-line-numbers="false"
|
||||
:auto-focus="true"
|
||||
:height="400"
|
||||
:width="640"
|
||||
:resizable="true"
|
||||
/>
|
||||
</div>
|
||||
</form>
|
||||
|
|
|
@ -67,7 +67,7 @@ const props = defineProps({
|
|||
|
||||
const emit = defineEmits(['select-row', 'contextmenu', 'stop-refresh']);
|
||||
|
||||
const isInlineEditor: Ref<{[key: string]: boolean}> = ref({});
|
||||
const isInlineEditor: Ref<Record<string, boolean>> = ref({});
|
||||
const isInfoModal = ref(false);
|
||||
const editorMode = ref('sql');
|
||||
|
||||
|
|
|
@ -256,9 +256,9 @@ const highlightWord = (string: string) => {
|
|||
|
||||
code, pre {
|
||||
max-width: 100%;
|
||||
width: 100%;
|
||||
display: inline-block;
|
||||
font-size: 100%;
|
||||
// color: $primary-color;
|
||||
opacity: 0.8;
|
||||
font-weight: 600;
|
||||
white-space: break-spaces;
|
||||
|
@ -342,6 +342,8 @@ const highlightWord = (string: string) => {
|
|||
<style lang="scss">
|
||||
.tile-paragraph {
|
||||
white-space: initial;
|
||||
word-break: break-word;
|
||||
user-select: text;
|
||||
|
||||
h1, h2, h3, h4, h5, h6, p, li {
|
||||
margin: 0;
|
||||
|
|
|
@ -32,7 +32,7 @@ const { removeNotification } = notificationsStore;
|
|||
const { notifications } = storeToRefs(notificationsStore);
|
||||
const { notificationsTimeout } = storeToRefs(settingsStore);
|
||||
|
||||
const timeouts: Ref<{[key: string]: NodeJS.Timeout}> = ref({});
|
||||
const timeouts: Ref<Record<string, NodeJS.Timeout>> = ref({});
|
||||
|
||||
const latestNotifications = computed(() => notifications.value.slice(0, 10));
|
||||
|
||||
|
|
|
@ -186,7 +186,7 @@ if (!connectionsArr.value.length)
|
|||
.settingbar-top-elements {
|
||||
overflow-x: hidden;
|
||||
overflow-y: overlay;
|
||||
// max-height: calc((100vh - 3.5rem) - #{$excluding-size});
|
||||
width: 100%;
|
||||
|
||||
&::-webkit-scrollbar {
|
||||
width: 3px;
|
||||
|
|
|
@ -695,7 +695,7 @@ const openAsPermanentTab = (tab: WorkspaceTab) => {
|
|||
routine: 'routine-props',
|
||||
procedure: 'routine-props',
|
||||
scheduler: 'scheduler-props'
|
||||
} as {[key: string]: string};
|
||||
} as Record<string, string>;
|
||||
|
||||
newTab({
|
||||
uid: props.connection.uid,
|
||||
|
|
|
@ -163,22 +163,30 @@
|
|||
>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="clientCustomizations.readOnlyMode" class="form-group columns">
|
||||
<div v-if="clientCustomizations.readOnlyMode" class="form-group columns mb-0">
|
||||
<div class="column col-5 col-sm-12" />
|
||||
<div class="column col-7 col-sm-12">
|
||||
<label class="form-checkbox form-inline">
|
||||
<label class="form-checkbox form-inline my-0">
|
||||
<input v-model="connection.readonly" type="checkbox"><i class="form-icon" /> {{ t('connection.readOnlyMode') }}
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="!clientCustomizations.fileConnection" class="form-group columns">
|
||||
<div v-if="!clientCustomizations.fileConnection" class="form-group columns mb-0">
|
||||
<div class="column col-5 col-sm-12" />
|
||||
<div class="column col-7 col-sm-12">
|
||||
<label class="form-checkbox form-inline">
|
||||
<label class="form-checkbox form-inline my-0">
|
||||
<input v-model="connection.ask" type="checkbox"><i class="form-icon" /> {{ t('connection.askCredentials') }}
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="clientCustomizations.singleConnectionMode" class="form-group columns mb-0">
|
||||
<div class="column col-5 col-sm-12" />
|
||||
<div class="column col-7 col-sm-12">
|
||||
<label class="form-checkbox form-inline my-0">
|
||||
<input v-model="connection.singleConnectionMode" type="checkbox"><i class="form-icon" /> {{ t('connection.singleConnection') }}
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</fieldset>
|
||||
</form>
|
||||
</div>
|
||||
|
@ -572,11 +580,11 @@ const pathSelection = (event: Event & {target: {files: {path: string}[]}}, name:
|
|||
const { files } = event.target;
|
||||
if (!files.length) return;
|
||||
|
||||
(connection.value as unknown as {[key: string]: string})[name] = files[0].path as string;
|
||||
(connection.value as unknown as Record<string, string>)[name] = files[0].path as string;
|
||||
};
|
||||
|
||||
const pathClear = (name: keyof ConnectionParams) => {
|
||||
(connection.value as unknown as {[key: string]: string})[name] = '';
|
||||
(connection.value as unknown as Record<string, string>)[name] = '';
|
||||
};
|
||||
|
||||
setDefaults();
|
||||
|
|
|
@ -165,22 +165,30 @@
|
|||
>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="clientCustomizations.readOnlyMode" class="form-group columns">
|
||||
<div v-if="clientCustomizations.readOnlyMode" class="form-group columns mb-0">
|
||||
<div class="column col-5 col-sm-12" />
|
||||
<div class="column col-7 col-sm-12">
|
||||
<label class="form-checkbox form-inline">
|
||||
<label class="form-checkbox form-inline my-0">
|
||||
<input v-model="localConnection.readonly" type="checkbox"><i class="form-icon" /> {{ t('connection.readOnlyMode') }}
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="!clientCustomizations.fileConnection" class="form-group columns">
|
||||
<div v-if="!clientCustomizations.fileConnection" class="form-group columns mb-0">
|
||||
<div class="column col-5 col-sm-12" />
|
||||
<div class="column col-7 col-sm-12">
|
||||
<label class="form-checkbox form-inline">
|
||||
<label class="form-checkbox form-inline my-0">
|
||||
<input v-model="localConnection.ask" type="checkbox"><i class="form-icon" /> {{ t('connection.askCredentials') }}
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="clientCustomizations.singleConnectionMode" class="form-group columns mb-0">
|
||||
<div class="column col-5 col-sm-12" />
|
||||
<div class="column col-7 col-sm-12">
|
||||
<label class="form-checkbox form-inline my-0">
|
||||
<input v-model="localConnection.singleConnectionMode" type="checkbox"><i class="form-icon" /> {{ t('connection.singleConnection') }}
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</fieldset>
|
||||
</form>
|
||||
</div>
|
||||
|
@ -569,11 +577,11 @@ const pathSelection = (event: Event & {target: {files: {path: string}[]}}, name:
|
|||
const { files } = event.target;
|
||||
if (!files.length) return;
|
||||
|
||||
(localConnection.value as unknown as {[key: string]: string})[name] = files[0].path;
|
||||
(localConnection.value as unknown as Record<string, string>)[name] = files[0].path;
|
||||
};
|
||||
|
||||
const pathClear = (name: keyof ConnectionParams) => {
|
||||
(localConnection.value as unknown as {[key: string]: string})[name] = '';
|
||||
(localConnection.value as unknown as Record<string, string>)[name] = '';
|
||||
};
|
||||
|
||||
localConnection.value = JSON.parse(JSON.stringify(props.connection));
|
||||
|
|
|
@ -382,7 +382,7 @@ const getFieldsData = async () => {
|
|||
if (status === 'success') {
|
||||
const indexesObj = response
|
||||
.filter((index: TableIndex) => index.type !== 'FOREIGN KEY')
|
||||
.reduce((acc: {[key: string]: TableIndex[]}, curr: TableIndex) => {
|
||||
.reduce((acc: Record<string, TableIndex[]>, curr: TableIndex) => {
|
||||
acc[curr.name] = acc[curr.name] || [];
|
||||
acc[curr.name].push(curr);
|
||||
return acc;
|
||||
|
|
|
@ -258,7 +258,7 @@ const indexesPanel: Ref<HTMLDivElement> = ref(null);
|
|||
const foreignProxy = ref([]);
|
||||
const selectedForeignID = ref('');
|
||||
const modalInnerHeight = ref(400);
|
||||
const refFields = ref({} as {[key: string]: TableField[]});
|
||||
const refFields = ref({} as Record<string, TableField[]>);
|
||||
|
||||
const foreignActions = computed(() => props.workspace.customizations.foreignActions);
|
||||
const selectedForeignObj = computed(() => foreignProxy.value.find(foreign => foreign._antares_id === selectedForeignID.value));
|
||||
|
|
|
@ -43,6 +43,7 @@
|
|||
autofocus
|
||||
class="editable-field form-input input-sm px-1"
|
||||
@blur="editOFF"
|
||||
@keyup.delete.stop
|
||||
>
|
||||
<BaseSelect
|
||||
v-else-if="inputProps.type === 'boolean'"
|
||||
|
@ -50,6 +51,7 @@
|
|||
:options="['true', 'false']"
|
||||
class="form-select small-select editable-field"
|
||||
@blur="editOFF"
|
||||
@keyup.delete.stop
|
||||
/>
|
||||
<BaseSelect
|
||||
v-else-if="enumArray"
|
||||
|
@ -58,6 +60,7 @@
|
|||
class="form-select small-select editable-field"
|
||||
dropdown-class="small-select"
|
||||
@blur="editOFF"
|
||||
@keyup.delete.stop
|
||||
/>
|
||||
<input
|
||||
v-else
|
||||
|
@ -67,6 +70,7 @@
|
|||
autofocus
|
||||
class="editable-field form-input input-sm px-1"
|
||||
@blur="editOFF"
|
||||
@keyup.delete.stop
|
||||
>
|
||||
</template>
|
||||
</template>
|
||||
|
@ -382,7 +386,7 @@ const isBaseSelectField = computed(() => {
|
|||
});
|
||||
|
||||
const enumArray = computed(() => {
|
||||
if (props.fields[editingField.value] && props.fields[editingField.value].enumValues)
|
||||
if (props.fields[editingField.value] && props.fields[editingField.value].enumValues && props.fields[editingField.value].type !== 'SET')
|
||||
return props.fields[editingField.value].enumValues.replaceAll('\'', '').split(',');
|
||||
return false;
|
||||
});
|
||||
|
|
|
@ -28,7 +28,7 @@ export function useFilters () {
|
|||
return `(${num})`;
|
||||
};
|
||||
|
||||
const parseKeys = (keys: {[key: number]: string}[]) => {
|
||||
const parseKeys = (keys: Record<number, string>[]) => {
|
||||
const isMacOS = process.platform === 'darwin';
|
||||
return (keys as string[]).map(k => (
|
||||
k.split('+')
|
||||
|
|
|
@ -232,7 +232,7 @@ export const caES = {
|
|||
newFunction: 'Nova funció',
|
||||
newScheduler: 'Nou planificador',
|
||||
newTriggerFunction: 'Nova funció de disparador',
|
||||
thereIsNoQueriesYet: 'Encara no hi ha consultes',
|
||||
thereAreNoQueriesYet: 'Encara no hi ha consultes',
|
||||
searchForQueries: 'Cerca consultes',
|
||||
killProcess: 'Mata procés',
|
||||
exportSchema: 'Exporta esquema',
|
||||
|
|
|
@ -233,7 +233,7 @@ export const csCZ = {
|
|||
newFunction: 'Nová funkce',
|
||||
newScheduler: 'Nový scheduler',
|
||||
newTriggerFunction: 'Nová trigger funkce',
|
||||
thereIsNoQueriesYet: 'Nejsou tu žádné dotazy',
|
||||
thereAreNoQueriesYet: 'Nejsou tu žádné dotazy',
|
||||
searchForQueries: 'Hledání dotazů',
|
||||
killProcess: 'Zabít proces',
|
||||
exportSchema: 'Exportovat schéma',
|
||||
|
|
|
@ -116,7 +116,8 @@ export const enUS = {
|
|||
readOnlyMode: 'Read-only mode',
|
||||
allConnections: 'All connections',
|
||||
searchForConnections: 'Search for connections',
|
||||
keepAliveInterval: 'Keep alive interval'
|
||||
keepAliveInterval: 'Keep alive interval',
|
||||
singleConnection: 'Single connection'
|
||||
},
|
||||
database: { // Database related terms
|
||||
schema: 'Schema',
|
||||
|
@ -251,7 +252,7 @@ export const enUS = {
|
|||
newFunction: 'New function',
|
||||
newScheduler: 'New scheduler',
|
||||
newTriggerFunction: 'New trigger function',
|
||||
thereIsNoQueriesYet: 'There is no queries yet',
|
||||
thereAreNoQueriesYet: 'There are no queries yet',
|
||||
searchForQueries: 'Search for queries',
|
||||
killProcess: 'Kill process',
|
||||
exportSchema: 'Export schema',
|
||||
|
|
|
@ -229,7 +229,7 @@ export const frFR = {
|
|||
newFunction: 'Nouvelle function',
|
||||
newScheduler: 'Nouveau déclencheur',
|
||||
newTriggerFunction: 'Nouvelle fonction de déclencheur',
|
||||
thereIsNoQueriesYet: 'Il n\'y a pas encore de requête',
|
||||
thereAreNoQueriesYet: 'Il n\'y a pas encore de requête',
|
||||
searchForQueries: 'Rechercher des requêtes',
|
||||
killProcess: 'Terminer un processus',
|
||||
exportSchema: 'Exporter un schéma',
|
||||
|
|
|
@ -227,7 +227,7 @@ export const idID = {
|
|||
newFunction: 'Fungsi baru',
|
||||
newScheduler: 'Penjadwal baru',
|
||||
newTriggerFunction: 'Fungsi pemicu baru',
|
||||
thereIsNoQueriesYet: 'Belum ada kueri',
|
||||
thereAreNoQueriesYet: 'Belum ada kueri',
|
||||
searchForQueries: 'Telusuri kueri',
|
||||
killProcess: 'Membunuh proses',
|
||||
exportSchema: 'Skema ekspor',
|
||||
|
|
|
@ -228,7 +228,7 @@ export const itIT = {
|
|||
newFunction: 'Nuova funzione',
|
||||
newScheduler: 'Nuovo scheduler',
|
||||
newTriggerFunction: 'Nuova funzione di trigger',
|
||||
thereIsNoQueriesYet: 'Non ci sono ancora query',
|
||||
thereAreNoQueriesYet: 'Non ci sono ancora query',
|
||||
searchForQueries: 'Cerca query',
|
||||
killProcess: 'Uccidi processo',
|
||||
exportSchema: 'Esporta schema',
|
||||
|
|
|
@ -198,7 +198,7 @@ export const jaJP = {
|
|||
newFunction: '新しい関数',
|
||||
newScheduler: '新規スケジューラ',
|
||||
newTriggerFunction: '新しいトリガー機能',
|
||||
thereIsNoQueriesYet: 'まだ問い合わせはありません',
|
||||
thereAreNoQueriesYet: 'まだ問い合わせはありません',
|
||||
searchForQueries: 'クエリの検索',
|
||||
killProcess: 'プロセスの停止'
|
||||
},
|
||||
|
|
|
@ -228,7 +228,7 @@ export const koKR = {
|
|||
newFunction: '새 함수',
|
||||
newScheduler: '새 스케줄러',
|
||||
newTriggerFunction: '새 트리거 함수',
|
||||
thereIsNoQueriesYet: '아직 쿼리가 없습니다',
|
||||
thereAreNoQueriesYet: '아직 쿼리가 없습니다',
|
||||
searchForQueries: '쿼리 검색',
|
||||
killProcess: '프로세스 종료',
|
||||
exportSchema: '스키마 내보내기',
|
||||
|
|
|
@ -100,7 +100,7 @@ export const nlNL = {
|
|||
readOnlyMode: 'Alleen lezen modus',
|
||||
untrustedConnection: 'Niet vertrouwde verbinding',
|
||||
allConnections: 'Alle verbindingen',
|
||||
searchForConnections: 'Search for connections'
|
||||
searchForConnections: 'Zoek naar verbindingen'
|
||||
},
|
||||
database: {
|
||||
schema: 'Schema',
|
||||
|
@ -233,8 +233,8 @@ export const nlNL = {
|
|||
newFunction: 'Nieuwe function',
|
||||
newScheduler: 'Nieuwe scheduler',
|
||||
newTriggerFunction: 'Nieuwe trigger function',
|
||||
thereIsNoQueriesYet: 'There is no queries yet',
|
||||
searchForQueries: 'Search for queries',
|
||||
thereAreNoQueriesYet: 'Er zijn nog geen queries',
|
||||
searchForQueries: 'Zoek naar queries',
|
||||
killProcess: 'Sluit proces af',
|
||||
exportSchema: 'Exporteer schema',
|
||||
importSchema: 'Importeer schema',
|
||||
|
|
|
@ -231,7 +231,7 @@ export const ptBR = {
|
|||
newFunction: 'Nova função',
|
||||
newScheduler: 'Novo agendento',
|
||||
newTriggerFunction: 'Novo gatinho de função',
|
||||
thereIsNoQueriesYet: 'Nenhuma consulta ainda',
|
||||
thereAreNoQueriesYet: 'Nenhuma consulta ainda',
|
||||
searchForQueries: 'Pesquisar por consultas',
|
||||
killProcess: 'Matar processo',
|
||||
exportSchema: 'Exportar banco de dados',
|
||||
|
|
|
@ -229,7 +229,7 @@ export const ruRU = {
|
|||
newFunction: 'Новая функция',
|
||||
newScheduler: 'Новый планировщик',
|
||||
newTriggerFunction: 'Новая функция триггера',
|
||||
thereIsNoQueriesYet: 'Запросы пока отсутствуют',
|
||||
thereAreNoQueriesYet: 'Запросы пока отсутствуют',
|
||||
searchForQueries: 'Поиск по запросам',
|
||||
killProcess: 'Убить процесс',
|
||||
exportSchema: 'Экспорт схемы',
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
export const localesNames: {[key: string]: string} = {
|
||||
export const localesNames: Record<string, string> = {
|
||||
'en-US': 'English',
|
||||
'it-IT': 'Italiano',
|
||||
'ar-SA': 'العربية',
|
||||
|
|
|
@ -238,7 +238,7 @@ export const ukUA = {
|
|||
newFunction: 'Нова функція',
|
||||
newScheduler: 'Новий планувальник',
|
||||
newTriggerFunction: 'Нова функція тригера',
|
||||
thereIsNoQueriesYet: 'Поки що немає запитів',
|
||||
thereAreNoQueriesYet: 'Поки що немає запитів',
|
||||
searchForQueries: 'Пошук запитів',
|
||||
killProcess: 'Завершити процес',
|
||||
exportSchema: 'Експорт схеми',
|
||||
|
|
|
@ -222,7 +222,7 @@ export const viVN = {
|
|||
newFunction: 'Chức năng mới',
|
||||
newScheduler: 'Bộ lập lịch mới',
|
||||
newTriggerFunction: 'Chức năng kích hoạt mới',
|
||||
thereIsNoQueriesYet: 'Không có truy vấn nào',
|
||||
thereAreNoQueriesYet: 'Không có truy vấn nào',
|
||||
searchForQueries: 'Tìm kiếm truy vấn',
|
||||
killProcess: 'Huỷ quá trình',
|
||||
exportSchema: 'Xuất lược đồ',
|
||||
|
|
|
@ -236,7 +236,7 @@ export const zhCN = {
|
|||
newFunction: '新函数',
|
||||
newScheduler: '新调度器',
|
||||
newTriggerFunction: '新触发器函数',
|
||||
thereIsNoQueriesYet: '目前还没有任何查询',
|
||||
thereAreNoQueriesYet: '目前还没有任何查询',
|
||||
searchForQueries: '搜索查询',
|
||||
killProcess: '终止进程',
|
||||
exportSchema: '导出模式(schema)',
|
||||
|
|
|
@ -64,7 +64,7 @@ export default class {
|
|||
primary?: string;
|
||||
field: string;
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
rows: {[key: string]: any};
|
||||
rows: Record<string, any>;
|
||||
}): Promise<IpcResponse> {
|
||||
return ipcRenderer.invoke('delete-table-rows', unproxify(params));
|
||||
}
|
||||
|
@ -73,9 +73,9 @@ export default class {
|
|||
uid: string;
|
||||
schema: string;
|
||||
table: string;
|
||||
row: {[key: string]: string | number | boolean | Date | Buffer};
|
||||
row: Record<string, string | number | boolean | Date | Buffer>;
|
||||
repeat: number;
|
||||
fields: {[key: string]: string};
|
||||
fields: Record<string, string>;
|
||||
locale: string;
|
||||
}): Promise<IpcResponse> {
|
||||
return ipcRenderer.invoke('insert-table-fake-rows', unproxify(params));
|
||||
|
|
|
@ -55,10 +55,9 @@ export const useApplicationStore = defineStore('application', {
|
|||
},
|
||||
showScratchpad (tag?: string) {
|
||||
this.isScratchpad = true;
|
||||
if (tag) {
|
||||
const { selectedTag } = storeToRefs(useScratchpadStore());
|
||||
selectedTag.value = tag;
|
||||
}
|
||||
if (!tag) tag = 'all';
|
||||
const { selectedTag } = storeToRefs(useScratchpadStore());
|
||||
selectedTag.value = tag;
|
||||
},
|
||||
hideScratchpad () {
|
||||
this.isScratchpad = false;
|
||||
|
|
|
@ -13,7 +13,7 @@ export interface HistoryRecord {
|
|||
|
||||
export const useHistoryStore = defineStore('history', {
|
||||
state: () => ({
|
||||
history: persistentStore.get('history', {}) as {[key: string]: HistoryRecord[]},
|
||||
history: persistentStore.get('history', {}) as Record<string, HistoryRecord[]>,
|
||||
favorites: persistentStore.get('favorites', {})
|
||||
}),
|
||||
getters: {
|
||||
|
|
|
@ -86,11 +86,11 @@ export interface Workspace {
|
|||
arch: string;
|
||||
os: string;
|
||||
};
|
||||
engines?: {[key: string]: string | boolean | number}[];
|
||||
engines?: Record<string, string | boolean | number>[];
|
||||
}
|
||||
|
||||
const persistentStore = new Store({ name: 'tabs' });
|
||||
const tabIndex: {[key: string]: number} = {};
|
||||
const tabIndex: Record<string, number> = {};
|
||||
|
||||
export const useWorkspacesStore = defineStore('workspaces', {
|
||||
state: () => ({
|
||||
|
|
Loading…
Reference in New Issue