1
1
mirror of https://github.com/Fabio286/antares.git synced 2025-06-05 21:59:22 +02:00

Compare commits

..

25 Commits

Author SHA1 Message Date
e9b42c3edb chore(release): 0.7.22-beta.1 2024-02-12 18:31:01 +01:00
259d051a21 fix: some issues related to previous commit 2024-02-12 18:30:07 +01:00
876d5ea481 perf(MySQL): improvements in connection handling 2024-02-11 16:38:06 +01:00
da56905572 refactor: improved SET field edit 2024-02-07 17:37:19 +01:00
d698f2798a fix: unable to edit tables containing SET fields, fixes #755 2024-02-06 18:16:26 +01:00
9a41511c42 Merge pull request #758 from 64knl/feat/translation-spelling
feat: update dutch translation + fix spelling mistake
2024-02-06 16:45:29 +01:00
Rene
30ada13663 feat: update dutch translation + fix spelling mistake 2024-02-06 15:38:42 +01:00
14eeaccb07 chore(release): 0.7.22-beta.0 2024-02-04 14:40:24 +01:00
1a0c5da2f1 feat(UI): resizable textarea in new/edito note, closes #747 2024-02-04 14:38:15 +01:00
bb36e98beb perf(UI): improved notes, fixes #746 2024-01-20 10:11:49 +01:00
8928510fb5 refactor: use Record to type objects 2024-01-19 18:03:20 +01:00
eb5d3f14f1 chore(release): 0.7.21 2024-01-13 16:31:14 +01:00
33c127b090 Merge branch 'master' of https://github.com/antares-sql/antares 2024-01-13 16:30:23 +01:00
4e98dc21d8 Merge branch 'beta' of https://github.com/antares-sql/antares 2024-01-13 16:30:21 +01:00
20b27343cd feat(SQLite): enable schema reloat button on sidebar 2024-01-13 16:28:55 +01:00
3b9228a723 fix(SQLite): unable to change integer fields length to 0, fixes #732 2024-01-13 16:28:31 +01:00
ab0f91b448 chore: remove Twitter links 2024-01-11 14:09:34 +01:00
0b6307c738 chore(release): 0.7.21-beta.1 2024-01-06 19:04:36 +01:00
dbf38fd99c ci: update create-generated-sources.yml 2024-01-06 18:53:47 +01:00
169fcb13da build(deps): downgrade better-sqlite3 2024-01-06 18:17:58 +01:00
97ece32988 ci: action to generate generated-sources.json 2024-01-05 11:14:58 +01:00
c946c3fcda ci: update node version 2024-01-05 11:14:05 +01:00
cdd2a11f8e fix(PostgreSQL): unhandled error on connection lost, fixes #740 2023-12-29 14:42:12 +01:00
23946ff2ce fix(PostgreSQL): exception deleting a table with one or less tabs open 2023-12-28 10:44:11 +01:00
0f8d2cb4ef fix(PostgreSQL): error adding MONEY fields to a table 2023-12-28 10:13:28 +01:00
72 changed files with 325 additions and 207 deletions

View File

@@ -15,7 +15,7 @@ jobs:
- name: Install Node.js - name: Install Node.js
uses: actions/setup-node@v3 uses: actions/setup-node@v3
with: with:
node-version: 18 node-version: 20
- name: Install dependencies - name: Install dependencies
run: npm i run: npm i

View File

@@ -0,0 +1,50 @@
name: Create generated-rources.json
on:
workflow_dispatch: {}
jobs:
build:
runs-on: ubuntu-latest
steps:
# Install flatpak-node-generator
- name: Install Python
uses: actions/setup-python@v5
with:
python-version: '3.8'
- name: Install pipx
uses: CfirTsabari/actions-pipx@v1
- name: Install flatpak-node-generator
run: |
cd ../
git clone https://github.com/flatpak/flatpak-builder-tools.git
cd flatpak-builder-tools/node
pipx install .
# Install Antares
- name: Check out Git repository
uses: actions/checkout@v3
- name: Install Node.js
uses: actions/setup-node@v3
with:
node-version: 18
# - name: Delete old package-lock.json
# run: rm package-lock.json
- name: Install dependencies
run: npm i --lockfile-version 2
- name: Generate generated-sources.json
run: flatpak-node-generator npm -r package-lock.json --electron-node-headers
- name: Upload Artifact
uses: actions/upload-artifact@v3
with:
name: generated-sources
retention-days: 3
path: |
generated-sources.json

View File

@@ -20,7 +20,7 @@ jobs:
- name: Install Node.js - name: Install Node.js
uses: actions/setup-node@v3 uses: actions/setup-node@v3
with: with:
node-version: 16 node-version: 20
- name: Install dependencies - name: Install dependencies
run: npm i run: npm i

9
.vscode/launch.json vendored
View File

@@ -17,15 +17,6 @@
"sourceMaps": true, "sourceMaps": true,
"type": "chrome", "type": "chrome",
"webRoot": "${workspaceFolder}" "webRoot": "${workspaceFolder}"
},
{
"name": "Electron: Worker",
"cwd": "${workspaceFolder}",
"port": 9224,
"request": "attach",
"sourceMaps": true,
"type": "node",
"timeout": 1000000
} }
], ],
"compounds": [ "compounds": [

View File

@@ -2,6 +2,57 @@
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. 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.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)
### Features
* **SQLite:** enable schema reloat button on sidebar ([20b2734](https://github.com/antares-sql/antares/commit/20b27343cd95998bd83403b7556ea35fcad9fa1b))
### Bug Fixes
* **SQLite:** unable to change integer fields length to 0, fixes [#732](https://github.com/antares-sql/antares/issues/732) ([3b9228a](https://github.com/antares-sql/antares/commit/3b9228a7230dcd9f47f5794a83b60d28207bdce1))
### [0.7.21-beta.1](https://github.com/antares-sql/antares/compare/v0.7.21-beta.0...v0.7.21-beta.1) (2024-01-06)
### Bug Fixes
* **PostgreSQL:** error adding MONEY fields to a table ([0f8d2cb](https://github.com/antares-sql/antares/commit/0f8d2cb4ef5c327f96f788179be0b309689b4ce8))
* **PostgreSQL:** exception deleting a table with one or less tabs open ([23946ff](https://github.com/antares-sql/antares/commit/23946ff2cef6d63e1529e2c8c4357d7fdedc3284))
* **PostgreSQL:** unhandled error on connection lost, fixes [#740](https://github.com/antares-sql/antares/issues/740) ([cdd2a11](https://github.com/antares-sql/antares/commit/cdd2a11f8e33d6607337989723774d60c7c1a030))
### [0.7.21-beta.0](https://github.com/antares-sql/antares/compare/v0.7.20...v0.7.21-beta.0) (2023-12-25) ### [0.7.21-beta.0](https://github.com/antares-sql/antares/compare/v0.7.20...v0.7.21-beta.0) (2023-12-25)

View File

@@ -7,7 +7,7 @@
# Antares SQL Client # Antares SQL Client
![GitHub package.json version](https://img.shields.io/github/package-json/v/fabio286/antares) ![GitHub](https://img.shields.io/github/license/fabio286/antares) ![Test e2e](https://github.com/antares-sql/antares/actions/workflows/test-e2e-win.yml/badge.svg?branch=develop) ![Mastodon Follow](https://img.shields.io/mastodon/follow/%20110860460902482117?domain=https%3A%2F%2Ffosstodon.org&style=social) [![Twitter Follow](https://img.shields.io/twitter/follow/AntaresSQL?style=social)](https://twitter.com/AntaresSQL) [![Plant a Tree](https://raw.githubusercontent.com/Fabio286/treedom-badge/master/svg/plant-a-tree.svg)](https://www.treedom.net/en/user/fabio-di-stasio/event/antares-for-the-planet) ![GitHub package.json version](https://img.shields.io/github/package-json/v/fabio286/antares) ![GitHub](https://img.shields.io/github/license/fabio286/antares) ![Test e2e](https://github.com/antares-sql/antares/actions/workflows/test-e2e-win.yml/badge.svg?branch=develop) ![Mastodon Follow](https://img.shields.io/mastodon/follow/%20110860460902482117?domain=https%3A%2F%2Ffosstodon.org&style=social) [![Plant a Tree](https://raw.githubusercontent.com/Fabio286/treedom-badge/master/svg/plant-a-tree.svg)](https://www.treedom.net/en/user/fabio-di-stasio/event/antares-for-the-planet)
Antares is an SQL client based on [Electron.js](https://github.com/electron/electron) and [Vue.js](https://github.com/vuejs/vue) that aims to become a useful tool, especially for developers. Antares is an SQL client based on [Electron.js](https://github.com/electron/electron) and [Vue.js](https://github.com/vuejs/vue) that aims to become a useful tool, especially for developers.
Our target is to support as many databases as possible, and all major operating systems, including the ARM versions. Our target is to support as many databases as possible, and all major operating systems, including the ARM versions.
@@ -17,7 +17,7 @@ However, there are all the features necessary to have a pleasant database manage
We are actively working on it, hoping to provide new cool features, improvements and fixes as soon as possible. We are actively working on it, hoping to provide new cool features, improvements and fixes as soon as possible.
🔗 If you are curious to try Antares you can download and install the [latest release](https://github.com/Fabio286/antares/releases/latest). 🔗 If you are curious to try Antares you can download and install the [latest release](https://github.com/Fabio286/antares/releases/latest).
👁 To stay tuned for new releases follow Antares SQL on [Mastodon](https://fosstodon.org/@AntaresSQL) or [Twitter](https://twitter.com/AntaresSQL). 👁 To stay tuned for new releases follow Antares SQL on [Mastodon](https://fosstodon.org/@AntaresSQL).
🌟 Don't forget to **leave a star** if you appreciate this project. 🌟 Don't forget to **leave a star** if you appreciate this project.
🗳️ Polls: 🗳️ Polls:
@@ -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) [<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)** 🚀 **[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 ## Currently supported
### Databases ### Databases
@@ -90,6 +79,7 @@ This is a roadmap with major features will come in near future.
- [x] PostgreSQL - [x] PostgreSQL
- [x] SQLite - [x] SQLite
- [x] Firebird SQL - [x] Firebird SQL
- [ ] DuckDB
- [ ] SQL Server - [ ] SQL Server
- [ ] More... - [ ] More...

22
package-lock.json generated
View File

@@ -1,12 +1,12 @@
{ {
"name": "antares", "name": "antares",
"version": "0.7.21-beta.0", "version": "0.7.22-beta.1",
"lockfileVersion": 2, "lockfileVersion": 2,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "antares", "name": "antares",
"version": "0.7.21-beta.0", "version": "0.7.22-beta.1",
"hasInstallScript": true, "hasInstallScript": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
@@ -18,7 +18,7 @@
"@turf/helpers": "~6.5.0", "@turf/helpers": "~6.5.0",
"@vueuse/core": "~10.4.1", "@vueuse/core": "~10.4.1",
"ace-builds": "~1.24.1", "ace-builds": "~1.24.1",
"better-sqlite3": "~9.1.1", "better-sqlite3": "^8.0.1",
"electron-log": "~5.0.1", "electron-log": "~5.0.1",
"electron-store": "~8.1.0", "electron-store": "~8.1.0",
"electron-updater": "~4.6.5", "electron-updater": "~4.6.5",
@@ -4546,13 +4546,13 @@
} }
}, },
"node_modules/better-sqlite3": { "node_modules/better-sqlite3": {
"version": "9.1.1", "version": "8.0.1",
"resolved": "https://registry.npmjs.org/better-sqlite3/-/better-sqlite3-9.1.1.tgz", "resolved": "https://registry.npmjs.org/better-sqlite3/-/better-sqlite3-8.0.1.tgz",
"integrity": "sha512-FhW7bS7cXwkB2SFnPJrSGPmQerVSCzwBgmQ1cIRcYKxLsyiKjljzCbyEqqhYXo5TTBqt5BISiBj2YE2Sy2ynaA==", "integrity": "sha512-JhTZjpyapA1icCEjIZB4TSSgkGdFgpWZA2Wszg7Cf4JwJwKQmbvuNnJBeR+EYG/Z29OXvR4G//Rbg31BW/Z7Yg==",
"hasInstallScript": true, "hasInstallScript": true,
"dependencies": { "dependencies": {
"bindings": "^1.5.0", "bindings": "^1.5.0",
"prebuild-install": "^7.1.1" "prebuild-install": "^7.1.0"
} }
}, },
"node_modules/big-integer": { "node_modules/big-integer": {
@@ -20668,12 +20668,12 @@
} }
}, },
"better-sqlite3": { "better-sqlite3": {
"version": "9.1.1", "version": "8.0.1",
"resolved": "https://registry.npmjs.org/better-sqlite3/-/better-sqlite3-9.1.1.tgz", "resolved": "https://registry.npmjs.org/better-sqlite3/-/better-sqlite3-8.0.1.tgz",
"integrity": "sha512-FhW7bS7cXwkB2SFnPJrSGPmQerVSCzwBgmQ1cIRcYKxLsyiKjljzCbyEqqhYXo5TTBqt5BISiBj2YE2Sy2ynaA==", "integrity": "sha512-JhTZjpyapA1icCEjIZB4TSSgkGdFgpWZA2Wszg7Cf4JwJwKQmbvuNnJBeR+EYG/Z29OXvR4G//Rbg31BW/Z7Yg==",
"requires": { "requires": {
"bindings": "^1.5.0", "bindings": "^1.5.0",
"prebuild-install": "^7.1.1" "prebuild-install": "^7.1.0"
} }
}, },
"big-integer": { "big-integer": {

View File

@@ -1,7 +1,7 @@
{ {
"name": "antares", "name": "antares",
"productName": "Antares", "productName": "Antares",
"version": "0.7.21-beta.0", "version": "0.7.22-beta.1",
"description": "A modern, fast and productivity driven SQL client with a focus in UX.", "description": "A modern, fast and productivity driven SQL client with a focus in UX.",
"license": "MIT", "license": "MIT",
"repository": "https://github.com/antares-sql/antares.git", "repository": "https://github.com/antares-sql/antares.git",
@@ -126,7 +126,7 @@
"@turf/helpers": "~6.5.0", "@turf/helpers": "~6.5.0",
"@vueuse/core": "~10.4.1", "@vueuse/core": "~10.4.1",
"ace-builds": "~1.24.1", "ace-builds": "~1.24.1",
"better-sqlite3": "~9.1.1", "better-sqlite3": "^8.0.1",
"electron-log": "~5.0.1", "electron-log": "~5.0.1",
"electron-store": "~8.1.0", "electron-store": "~8.1.0",
"electron-updater": "~4.6.5", "electron-updater": "~4.6.5",

View File

@@ -66,7 +66,7 @@ export default [
group: 'monetary', group: 'monetary',
types: [ types: [
{ {
name: 'money', name: 'MONEY',
length: false, length: false,
unsigned: true unsigned: true
} }

View File

@@ -363,7 +363,7 @@ export interface QueryBuilderObject {
offset: number; offset: number;
join: string[]; join: string[];
update: string[]; update: string[];
insert: {[key: string]: string | boolean | number }[]; insert: Record<string, string | boolean | number>[];
delete: boolean; delete: boolean;
} }

View File

@@ -13,7 +13,7 @@ export interface ExportOptions {
includeContent: boolean; includeContent: boolean;
includeDropStatement: boolean; includeDropStatement: boolean;
}[]; }[];
includes: {[key: string]: boolean}; includes: Record<string, boolean>;
outputFormat: 'sql' | 'sql.zip'; outputFormat: 'sql' | 'sql.zip';
outputFile: string; outputFile: string;
sqlInsertAfter: number; sqlInsertAfter: number;

View File

@@ -18,7 +18,7 @@ export interface TableDeleteParams {
primary?: string; primary?: string;
field: string; field: string;
// eslint-disable-next-line @typescript-eslint/no-explicit-any // 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' export type TableFilterOperator = '=' | '!=' | '>' | '<' | '>=' | '<=' | 'IN' | 'NOT IN' | 'LIKE' | 'NOT LIKE' | 'RLIKE' | 'NOT RLIKE' | 'BETWEEN' | 'IS NULL' | 'IS NOT NULL'
@@ -35,7 +35,7 @@ export interface InsertRowsParams {
uid: string; uid: string;
schema: string; schema: string;
table: string; table: string;
row: {[key: string]: { row: Record<string, {
group: string; group: string;
method: string; method: string;
// eslint-disable-next-line @typescript-eslint/no-explicit-any // eslint-disable-next-line @typescript-eslint/no-explicit-any
@@ -43,9 +43,8 @@ export interface InsertRowsParams {
// eslint-disable-next-line @typescript-eslint/no-explicit-any // eslint-disable-next-line @typescript-eslint/no-explicit-any
value: any; value: any;
length: number; length: number;
}; }>;
};
repeat: number; repeat: number;
fields: {[key: string]: string}; fields: Record<string, string>;
locale: UsableLocale; locale: UsableLocale;
} }

View File

@@ -41,7 +41,7 @@ export const escapeAndQuote = (val: string, client: ClientCode) => {
const { stringsWrapper: sw } = customizations[client]; const { stringsWrapper: sw } = customizations[client];
// eslint-disable-next-line no-control-regex // eslint-disable-next-line no-control-regex
const CHARS_TO_ESCAPE = /[\0\b\t\n\r\x1a"'\\]/g; 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', '\0': '\\0',
'\b': '\\b', '\b': '\\b',
'\t': '\\t', '\t': '\\t',
@@ -153,9 +153,9 @@ export const valueToSqlString = (args: {
}; };
export const jsonToSqlInsert = (args: { export const jsonToSqlInsert = (args: {
json: { [key: string]: any}[]; json: Record<string, any>[];
client: ClientCode; client: ClientCode;
fields: { [key: string]: {type: string; datePrecision: number}}; fields: Record<string, {type: string; datePrecision: number}>;
table: string; table: string;
options?: {sqlInsertAfter: number; sqlInsertDivider: 'bytes' | 'rows'}; options?: {sqlInsertAfter: number; sqlInsertDivider: 'bytes' | 'rows'};
}) => { }) => {

View File

@@ -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' }, 'run-or-reload': { l18n: 'application.runOrReload', context: 'tab' },
'open-new-tab': { l18n: 'application.openNewTab', context: 'tab' }, 'open-new-tab': { l18n: 'application.openNewTab', context: 'tab' },
'close-tab': { l18n: 'application.closeTab', context: 'tab' }, 'close-tab': { l18n: 'application.closeTab', context: 'tab' },

View File

@@ -6,7 +6,7 @@ import { SslOptions } from 'mysql2';
import { ClientsFactory } from '../libs/ClientsFactory'; import { ClientsFactory } from '../libs/ClientsFactory';
import { validateSender } from '../libs/misc/validateSender'; 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) => { ipcMain.handle('test-connection', async (event, conn: antares.ConnectionParams) => {
if (!validateSender(event.senderFrame)) return { status: 'error', response: 'Unauthorized process' }; if (!validateSender(event.senderFrame)) return { status: 'error', response: 'Unauthorized process' };

View File

@@ -3,7 +3,7 @@ import { ipcMain } from 'electron';
import { validateSender } from '../libs/misc/validateSender'; 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) => { ipcMain.handle('get-databases', async (event, uid) => {
if (!validateSender(event.senderFrame)) return { status: 'error', response: 'Unauthorized process' }; if (!validateSender(event.senderFrame)) return { status: 'error', response: 'Unauthorized process' };

View File

@@ -3,7 +3,7 @@ import { ipcMain } from 'electron';
import { validateSender } from '../libs/misc/validateSender'; 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) => { ipcMain.handle('get-function-informations', async (event, params) => {
if (!validateSender(event.senderFrame)) return { status: 'error', response: 'Unauthorized process' }; if (!validateSender(event.senderFrame)) return { status: 'error', response: 'Unauthorized process' };

View File

@@ -13,7 +13,7 @@ import updates from './updates';
import users from './users'; import users from './users';
import views from './views'; import views from './views';
const connections: {[key: string]: antares.Client} = {}; const connections: Record<string, antares.Client> = {};
export default () => { export default () => {
connection(connections); connection(connections);

View File

@@ -3,7 +3,7 @@ import { ipcMain } from 'electron';
import { validateSender } from '../libs/misc/validateSender'; 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) => { ipcMain.handle('get-routine-informations', async (event, params) => {
if (!validateSender(event.senderFrame)) return { status: 'error', response: 'Unauthorized process' }; if (!validateSender(event.senderFrame)) return { status: 'error', response: 'Unauthorized process' };

View File

@@ -3,7 +3,7 @@ import { ipcMain } from 'electron';
import { validateSender } from '../libs/misc/validateSender'; 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) => { ipcMain.handle('get-scheduler-informations', async (event, params) => {
if (!validateSender(event.senderFrame)) return { status: 'error', response: 'Unauthorized process' }; if (!validateSender(event.senderFrame)) return { status: 'error', response: 'Unauthorized process' };

View File

@@ -6,7 +6,7 @@ import { Worker } from 'worker_threads';
import { validateSender } from '../libs/misc/validateSender'; 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 exporter: Worker = null;
let importer: Worker = null; let importer: Worker = null;

View File

@@ -10,7 +10,7 @@ import * as moment from 'moment';
import { validateSender } from '../libs/misc/validateSender'; 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) => { ipcMain.handle('get-table-columns', async (event, params) => {
if (!validateSender(event.senderFrame)) return { status: 'error', response: 'Unauthorized process' }; if (!validateSender(event.senderFrame)) return { status: 'error', response: 'Unauthorized process' };
@@ -249,7 +249,7 @@ export default (connections: {[key: string]: antares.Client}) => {
if (params.primary) { if (params.primary) {
// eslint-disable-next-line @typescript-eslint/no-explicit-any // 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; const fieldName = Object.keys(row)[0].includes('.') ? `${params.table}.${params.primary}` : params.primary;
return typeof row[fieldName] === 'string' 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' }; if (!validateSender(event.senderFrame)) return { status: 'error', response: 'Unauthorized process' };
try { // TODO: move to client classes 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++) { 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) { for (const key in params.row) {
const type = params.fields[key]; const type = params.fields[key];
@@ -367,7 +367,7 @@ export default (connections: {[key: string]: antares.Client}) => {
insertObj[key] = escapedParam; insertObj[key] = escapedParam;
} }
else { // Faker value else { // Faker value
const parsedParams: {[key: string]: string | number | boolean | Date | Buffer} = {}; const parsedParams: Record<string, string | number | boolean | Date | Buffer> = {};
let fakeValue; let fakeValue;
if (params.locale) if (params.locale)
@@ -437,12 +437,12 @@ export default (connections: {[key: string]: antares.Client}) => {
if (description) if (description)
query.select(`LEFT(${description}, 20) AS foreign_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) { for (const row of results.rows) {
const remappedRow: {[key: string]: string} = {}; const remappedRow: Record<string, string> = {};
for (const key in row) for (const key in row)
remappedRow[key.toLowerCase()] = row[key];// Thanks Firebird -.- remappedRow[key.toLowerCase()] = row[key];// Thanks Firebird -.-

View File

@@ -3,7 +3,7 @@ import { ipcMain } from 'electron';
import { validateSender } from '../libs/misc/validateSender'; 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) => { ipcMain.handle('get-trigger-informations', async (event, params) => {
if (!validateSender(event.senderFrame)) return { status: 'error', response: 'Unauthorized process' }; if (!validateSender(event.senderFrame)) return { status: 'error', response: 'Unauthorized process' };

View File

@@ -3,7 +3,7 @@ import { ipcMain } from 'electron';
import { validateSender } from '../libs/misc/validateSender'; 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) => { ipcMain.handle('get-users', async (event, uid) => {
if (!validateSender(event.senderFrame)) return { status: 'error', response: 'Unauthorized process' }; if (!validateSender(event.senderFrame)) return { status: 'error', response: 'Unauthorized process' };

View File

@@ -3,7 +3,7 @@ import { ipcMain } from 'electron';
import { validateSender } from '../libs/misc/validateSender'; 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) => { ipcMain.handle('get-view-informations', async (event, params) => {
if (!validateSender(event.senderFrame)) return { status: 'error', response: 'Unauthorized process' }; if (!validateSender(event.senderFrame)) return { status: 'error', response: 'Unauthorized process' };

View File

@@ -136,7 +136,7 @@ export abstract class BaseClient {
} }
// eslint-disable-next-line @typescript-eslint/no-explicit-any // 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]; this._query.insert = [...this._query.insert, ...arr];
return this; return this;
} }

View File

@@ -13,7 +13,7 @@ export class FirebirdSQLClient extends BaseClient {
protected _connection?: firebird.Database | firebird.ConnectionPool; protected _connection?: firebird.Database | firebird.ConnectionPool;
_params: firebird.Options; _params: firebird.Options;
private _types: {[key: number]: string} ={ private _types: Record<number, string> ={
452: 'CHAR', // Array of char 452: 'CHAR', // Array of char
448: 'VARCHAR', 448: 'VARCHAR',
500: 'SMALLINT', 500: 'SMALLINT',

View File

@@ -12,10 +12,11 @@ export class MySQLClient extends BaseClient {
private _connectionsToCommit: Map<string, mysql.Connection | mysql.PoolConnection>; private _connectionsToCommit: Map<string, mysql.Connection | mysql.PoolConnection>;
private _keepaliveTimer: NodeJS.Timer; private _keepaliveTimer: NodeJS.Timer;
private _keepaliveMs: number; private _keepaliveMs: number;
private sqlMode?: string[];
_connection?: mysql.Connection | mysql.Pool; _connection?: mysql.Connection | mysql.Pool;
_params: mysql.ConnectionOptions & {schema: string; ssl?: mysql.SslOptions; ssh?: SSHConfig; readonly: boolean}; _params: mysql.ConnectionOptions & {schema: string; ssl?: mysql.SslOptions; ssh?: SSHConfig; readonly: boolean};
private types: {[key: number]: string} = { private types: Record<number, string> = {
0: 'DECIMAL', 0: 'DECIMAL',
1: 'TINYINT', 1: 'TINYINT',
2: 'SMALLINT', 2: 'SMALLINT',
@@ -58,6 +59,10 @@ export class MySQLClient extends BaseClient {
this._keepaliveMs = 10*60*1000; this._keepaliveMs = 10*60*1000;
} }
private get isPool () {
return 'getConnection' in this._connection;
}
private _getType (field: mysql.FieldPacket & { columnType?: number; columnLength?: number }) { private _getType (field: mysql.FieldPacket & { columnType?: number; columnLength?: number }) {
let name = this.types[field.columnType]; let name = this.types[field.columnType];
let length = field.columnLength; let length = field.columnLength;
@@ -181,9 +186,32 @@ export class MySQLClient extends BaseClient {
async connect () { async connect () {
if (!this._poolSize) if (!this._poolSize)
this._connection = await this.getConnection(); this._connection = await this.getSingleConnection();
else else
this._connection = await this.getConnectionPool(); 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 () { destroy () {
@@ -196,7 +224,7 @@ export class MySQLClient extends BaseClient {
} }
} }
async getConnection () { async getSingleConnection () {
const dbConfig = await this.getDbConfig(); const dbConfig = await this.getDbConfig();
const connection = await mysql.createConnection({ const connection = await mysql.createConnection({
...dbConfig, ...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; return connection;
} }
@@ -227,6 +244,7 @@ export class MySQLClient extends BaseClient {
const connection = mysql.createPool({ const connection = mysql.createPool({
...dbConfig, ...dbConfig,
connectionLimit: this._poolSize, connectionLimit: this._poolSize,
enableKeepAlive: true,
typeCast: (field, next) => { typeCast: (field, next) => {
if (field.type === 'DATETIME') if (field.type === 'DATETIME')
return field.string(); 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 () => { this._keepaliveTimer = setInterval(async () => {
await this.keepAlive(); await this.keepAlive();
}, this._keepaliveMs); }, this._keepaliveMs);
@@ -261,6 +260,43 @@ export class MySQLClient extends BaseClient {
return connection; 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 () { private async keepAlive () {
try { try {
const connection = await (this._connection as mysql.Pool).getConnection(); const connection = await (this._connection as mysql.Pool).getConnection();
@@ -582,7 +618,7 @@ export class MySQLClient extends BaseClient {
} }
}) })
.filter(Boolean) .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; acc[curr.name] = curr;
return acc; return acc;
}, {}); }, {});
@@ -591,7 +627,7 @@ export class MySQLClient extends BaseClient {
return rows.map((field) => { return rows.map((field) => {
const numLengthMatch = field.COLUMN_TYPE.match(/int\(([^)]+)\)/); const numLengthMatch = field.COLUMN_TYPE.match(/int\(([^)]+)\)/);
const numLength = numLengthMatch ? +numLengthMatch.pop() : field.NUMERIC_PRECISION || null; 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) ? field.COLUMN_TYPE.match(/\(([^)]+)\)/)[0].slice(1, -1)
: null; : null;
@@ -1648,28 +1684,7 @@ export class MySQLClient extends BaseClient {
.map(q => q.trim()) .map(q => q.trim())
: [sql]; : [sql];
let connection: mysql.Connection | mysql.Pool | mysql.PoolConnection; const connection = await this.getConnection(args);
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}\``);
for (const query of queries) { for (const query of queries) {
if (!query) continue; if (!query) continue;
@@ -1729,7 +1744,7 @@ export class MySQLClient extends BaseClient {
}); });
} }
catch (err) { catch (err) {
if (isPool && args.autocommit) { if (this.isPool && args.autocommit) {
(connection as mysql.PoolConnection).release(); (connection as mysql.PoolConnection).release();
this._runningConnections.delete(args.tabUid); this._runningConnections.delete(args.tabUid);
} }
@@ -1741,7 +1756,7 @@ export class MySQLClient extends BaseClient {
keysArr = keysArr ? [...keysArr, ...response] : response; keysArr = keysArr ? [...keysArr, ...response] : response;
} }
catch (err) { catch (err) {
if (isPool && args.autocommit) { if (this.isPool && args.autocommit) {
(connection as mysql.PoolConnection).release(); (connection as mysql.PoolConnection).release();
this._runningConnections.delete(args.tabUid); this._runningConnections.delete(args.tabUid);
} }
@@ -1759,7 +1774,7 @@ export class MySQLClient extends BaseClient {
keys: keysArr keys: keysArr
}); });
}).catch((err) => { }).catch((err) => {
if (isPool && args.autocommit) { if (this.isPool && args.autocommit) {
(connection as mysql.PoolConnection).release(); (connection as mysql.PoolConnection).release();
this._runningConnections.delete(args.tabUid); 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(); (connection as mysql.PoolConnection).release();
this._runningConnections.delete(args.tabUid); this._runningConnections.delete(args.tabUid);
} }

View File

@@ -88,8 +88,8 @@ export class PostgreSQLClient extends BaseClient {
private _keepaliveTimer: NodeJS.Timer; private _keepaliveTimer: NodeJS.Timer;
private _keepaliveMs: number; private _keepaliveMs: number;
protected _connection?: pg.Client | pg.Pool; protected _connection?: pg.Client | pg.Pool;
private types: {[key: string]: string} = {}; private types: Record<string, string> = {};
private _arrayTypes: {[key: string]: string} = { private _arrayTypes: Record<string, string> = {
_int2: 'SMALLINT', _int2: 'SMALLINT',
_int4: 'INTEGER', _int4: 'INTEGER',
_int8: 'BIGINT', _int8: 'BIGINT',
@@ -232,6 +232,10 @@ export class PostgreSQLClient extends BaseClient {
await this.keepAlive(); await this.keepAlive();
}, this._keepaliveMs); }, this._keepaliveMs);
connection.on('error', err => { // Intercepts errors and converts to rejections
Promise.reject(err);
});
return connection; return connection;
} }
@@ -652,7 +656,7 @@ export class PostgreSQLClient extends BaseClient {
let createSql = ''; let createSql = '';
const sequences = []; const sequences = [];
const columnsSql = []; const columnsSql = [];
const arrayTypes: {[key: string]: string} = { const arrayTypes: Record<string, string> = {
_int2: 'smallint', _int2: 'smallint',
_int4: 'integer', _int4: 'integer',
_int8: 'bigint', _int8: 'bigint',

View File

@@ -166,7 +166,7 @@ export class SQLiteClient extends BaseClient {
type: type.trim(), type: type.trim(),
schema: schema, schema: schema,
table: table, table: table,
numPrecision: [...NUMBER, ...FLOAT].includes(type) ? length : null, numLength: [...NUMBER, ...FLOAT].includes(type) ? length : null,
datePrecision: null, datePrecision: null,
charLength: ![...NUMBER, ...FLOAT].includes(type) ? length : null, charLength: ![...NUMBER, ...FLOAT].includes(type) ? length : null,
nullable: !field.notnull, nullable: !field.notnull,
@@ -658,7 +658,7 @@ export class SQLiteClient extends BaseClient {
let queryAllResult: any[]; let queryAllResult: any[];
let affectedRows; let affectedRows;
let fields; let fields;
const detectedTypes: {[key: string]: string} = {}; const detectedTypes: Record<string, string> = {};
try { try {
const stmt = connection.prepare(query); const stmt = connection.prepare(query);

View File

@@ -354,7 +354,7 @@ CREATE TABLE \`${view.Name}\`(
escapeAndQuote (val: string) { escapeAndQuote (val: string) {
// eslint-disable-next-line no-control-regex // eslint-disable-next-line no-control-regex
const CHARS_TO_ESCAPE = /[\0\b\t\n\r\x1a"'\\]/g; 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', '\0': '\\0',
'\b': '\\b', '\b': '\\b',
'\t': '\\t', '\t': '\\t',

View File

@@ -59,7 +59,7 @@ SET row_security = off;\n\n\n`;
let createSql = ''; let createSql = '';
const sequences = []; const sequences = [];
const columnsSql = []; const columnsSql = [];
const arrayTypes: {[key: string]: string} = { const arrayTypes: Record<string, string> = {
_int2: 'smallint', _int2: 'smallint',
_int4: 'integer', _int4: 'integer',
_int8: 'bigint', _int8: 'bigint',
@@ -440,7 +440,7 @@ SET row_security = off;\n\n\n`;
escapeAndQuote (val: string) { escapeAndQuote (val: string) {
// eslint-disable-next-line no-control-regex // eslint-disable-next-line no-control-regex
const CHARS_TO_ESCAPE = /[\0\b\t\n\r\x1a"'\\]/g; 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', '\0': '\\0',
'\b': '\\b', '\b': '\\b',
'\t': '\\t', '\t': '\\t',

View File

@@ -56,8 +56,8 @@ const { t } = useI18n();
const props = defineProps({ const props = defineProps({
size: { size: {
type: String as PropType<'small' | 'medium' | '400' | 'large'>, type: String as PropType<'small' | 'medium' | '400' | 'large' | 'resize'>,
validator: (prop: string) => ['small', 'medium', '400', 'large'].includes(prop), validator: (prop: string) => ['small', 'medium', '400', 'large', 'resize'].includes(prop),
default: 'small' default: 'small'
}, },
hideFooter: { hideFooter: {
@@ -88,6 +88,8 @@ const modalSizeClass = computed(() => {
return 'modal-sm'; return 'modal-sm';
if (props.size === '400') if (props.size === '400')
return 'modal-400'; return 'modal-400';
if (props.size === 'resize')
return 'modal-resize';
else if (props.size === 'large') else if (props.size === 'large')
return 'modal-lg'; return 'modal-lg';
else return ''; else return '';
@@ -120,6 +122,12 @@ onBeforeUnmount(() => {
max-width: 400px; max-width: 400px;
} }
.modal-resize .modal-container {
max-width: 95vw;
max-height: 95vh;
width: auto;
}
.modal.modal-sm .modal-container { .modal.modal-sm .modal-container {
padding: 0; padding: 0;
} }

View File

@@ -4,7 +4,11 @@
:id="`editor-${id}`" :id="`editor-${id}`"
class="editor" class="editor"
:class="editorClass" :class="editorClass"
:style="{height: `${height}px`}" :style="{
height: `${height}px`,
width: width ? `${width}px` : null,
resize: resizable ? 'both' : 'none'
}"
/> />
</div> </div>
</template> </template>
@@ -17,7 +21,7 @@ import 'ace-builds/webpack-resolver';
import { uidGen } from 'common/libs/uidGen'; import { uidGen } from 'common/libs/uidGen';
import { storeToRefs } from 'pinia'; import { storeToRefs } from 'pinia';
import { onMounted, watch } from 'vue'; import { PropType, onMounted, watch } from 'vue';
import { useSettingsStore } from '@/stores/settings'; import { useSettingsStore } from '@/stores/settings';
@@ -25,10 +29,12 @@ const props = defineProps({
modelValue: String, modelValue: String,
mode: { type: String, default: 'text' }, mode: { type: String, default: 'text' },
editorClass: { type: String, default: '' }, editorClass: { type: String, default: '' },
resizable: { type: Boolean, default: false },
autoFocus: { type: Boolean, default: false }, autoFocus: { type: Boolean, default: false },
readOnly: { type: Boolean, default: false }, readOnly: { type: Boolean, default: false },
showLineNumbers: { type: Boolean, default: true }, 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 emit = defineEmits(['update:modelValue']);
const settingsStore = useSettingsStore(); const settingsStore = useSettingsStore();
@@ -134,6 +140,8 @@ onMounted(() => {
.editor-wrapper { .editor-wrapper {
.editor { .editor {
width: 100%; width: 100%;
height: 100%;
max-width: 90vw;
} }
} }
</style> </style>

View File

@@ -113,7 +113,7 @@ const selectedGroup: Ref<string> = ref('manual');
const selectedMethod: Ref<string> = ref(''); const selectedMethod: Ref<string> = ref('');
const selectedValue: Ref<string> = ref(''); const selectedValue: Ref<string> = ref('');
const debounceTimeout: Ref<NodeJS.Timeout> = ref(null); 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 enumArray: Ref<string[]> = ref(null);
const fakerGroups = computed(() => { const fakerGroups = computed(() => {

View File

@@ -73,7 +73,7 @@ const props = defineProps({
const emit = defineEmits(['confirm', 'close']); const emit = defineEmits(['confirm', 'close']);
const firstInput: Ref<HTMLInputElement[]> = ref(null); const firstInput: Ref<HTMLInputElement[]> = ref(null);
const values: Ref<{[key: string]: string}> = ref({}); const values: Ref<Record<string, string>> = ref({});
const inParameters = computed(() => { const inParameters = computed(() => {
return props.localRoutine.parameters.filter(param => param.context === 'IN'); return props.localRoutine.parameters.filter(param => param.context === 'IN');

View File

@@ -327,7 +327,7 @@ const tables: Ref<{
}[]> = ref([]); }[]> = ref([]);
const options: Ref<Partial<ExportOptions>> = ref({ const options: Ref<Partial<ExportOptions>> = ref({
schema: selectedSchema.value, schema: selectedSchema.value,
includes: {} as {[key: string]: boolean}, includes: {} as Record<string, boolean>,
outputFormat: 'sql' as 'sql' | 'sql.zip', outputFormat: 'sql' as 'sql' | 'sql.zip',
sqlInsertAfter: 250, sqlInsertAfter: 250,
sqlInsertDivider: 'bytes' as 'bytes' | 'rows' sqlInsertDivider: 'bytes' as 'bytes' | 'rows'

View File

@@ -142,7 +142,7 @@ const { getSelected: selectedWorkspace } = storeToRefs(workspacesStore);
const { trapRef } = useFocusTrap({ disableAutofocus: true }); const { trapRef } = useFocusTrap({ disableAutofocus: true });
// eslint-disable-next-line @typescript-eslint/no-explicit-any // 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 fieldsToExclude = ref([]);
const nInserts = ref(1); const nInserts = ref(1);
const isInserting = ref(false); const isInserting = ref(false);
@@ -225,7 +225,7 @@ const insertRows = async () => {
delete rowToInsert[key]; delete rowToInsert[key];
}); });
const fieldTypes: {[key: string]: string} = {}; const fieldTypes: Record<string, string> = {};
props.fields.forEach(field => { props.fields.forEach(field => {
fieldTypes[field.name] = field.type; fieldTypes[field.name] = field.type;
}); });
@@ -290,7 +290,7 @@ onMounted(() => {
} }
}, 50); }, 50);
const rowObj: {[key: string]: unknown} = {}; const rowObj: Record<string, unknown> = {};
if (!props.rowToDuplicate) { if (!props.rowToDuplicate) {
// Set default values // Set default values

View File

@@ -115,7 +115,7 @@
<BaseIcon icon-name="mdiHistory" :size="48" /> <BaseIcon icon-name="mdiHistory" :size="48" />
</div> </div>
<p class="empty-title h5"> <p class="empty-title h5">
{{ t('database.thereIsNoQueriesYet') }} {{ t('database.thereAreNoQueriesYet') }}
</p> </p>
</div> </div>
</div> </div>

View File

@@ -1,6 +1,6 @@
<template> <template>
<ConfirmModal <ConfirmModal
size="medium" size="resize"
:disable-autofocus="true" :disable-autofocus="true"
:close-on-confirm="!!localNote.note.length" :close-on-confirm="!!localNote.note.length"
:confirm-text="t('general.save')" :confirm-text="t('general.save')"
@@ -52,6 +52,10 @@
v-model="localNote.note" v-model="localNote.note"
:mode="editorMode" :mode="editorMode"
:show-line-numbers="false" :show-line-numbers="false"
:auto-focus="true"
:height="400"
:width="640"
:resizable="true"
/> />
</div> </div>
</form> </form>

View File

@@ -1,6 +1,6 @@
<template> <template>
<ConfirmModal <ConfirmModal
size="medium" size="resize"
:disable-autofocus="true" :disable-autofocus="true"
:close-on-confirm="!!newNote.note.length" :close-on-confirm="!!newNote.note.length"
:confirm-text="t('general.save')" :confirm-text="t('general.save')"
@@ -52,6 +52,10 @@
v-model="newNote.note" v-model="newNote.note"
:mode="editorMode" :mode="editorMode"
:show-line-numbers="false" :show-line-numbers="false"
:auto-focus="true"
:height="400"
:width="640"
:resizable="true"
/> />
</div> </div>
</form> </form>

View File

@@ -67,7 +67,7 @@ const props = defineProps({
const emit = defineEmits(['select-row', 'contextmenu', 'stop-refresh']); 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 isInfoModal = ref(false);
const editorMode = ref('sql'); const editorMode = ref('sql');

View File

@@ -409,14 +409,6 @@
class="d-inline mr-1" class="d-inline mr-1"
:size="16" :size="16"
/> Mastodon</a> <a /> Mastodon</a> <a
class="c-hand"
:style="'align-items: center; display: inline-flex;'"
@click="openOutside('https://twitter.com/AntaresSQL')"
><BaseIcon
icon-name="mdiTwitter"
class="d-inline mr-1"
:size="16"
/> Twitter</a> <a
class="c-hand" class="c-hand"
:style="'align-items: center; display: inline-flex;'" :style="'align-items: center; display: inline-flex;'"
@click="openOutside('https://antares-sql.app/')" @click="openOutside('https://antares-sql.app/')"

View File

@@ -256,9 +256,9 @@ const highlightWord = (string: string) => {
code, pre { code, pre {
max-width: 100%; max-width: 100%;
width: 100%;
display: inline-block; display: inline-block;
font-size: 100%; font-size: 100%;
// color: $primary-color;
opacity: 0.8; opacity: 0.8;
font-weight: 600; font-weight: 600;
white-space: break-spaces; white-space: break-spaces;
@@ -342,6 +342,8 @@ const highlightWord = (string: string) => {
<style lang="scss"> <style lang="scss">
.tile-paragraph { .tile-paragraph {
white-space: initial; white-space: initial;
word-break: break-word;
user-select: text;
h1, h2, h3, h4, h5, h6, p, li { h1, h2, h3, h4, h5, h6, p, li {
margin: 0; margin: 0;

View File

@@ -32,7 +32,7 @@ const { removeNotification } = notificationsStore;
const { notifications } = storeToRefs(notificationsStore); const { notifications } = storeToRefs(notificationsStore);
const { notificationsTimeout } = storeToRefs(settingsStore); 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)); const latestNotifications = computed(() => notifications.value.slice(0, 10));

View File

@@ -695,7 +695,7 @@ const openAsPermanentTab = (tab: WorkspaceTab) => {
routine: 'routine-props', routine: 'routine-props',
procedure: 'routine-props', procedure: 'routine-props',
scheduler: 'scheduler-props' scheduler: 'scheduler-props'
} as {[key: string]: string}; } as Record<string, string>;
newTab({ newTab({
uid: props.connection.uid, uid: props.connection.uid,

View File

@@ -572,11 +572,11 @@ const pathSelection = (event: Event & {target: {files: {path: string}[]}}, name:
const { files } = event.target; const { files } = event.target;
if (!files.length) return; 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) => { const pathClear = (name: keyof ConnectionParams) => {
(connection.value as unknown as {[key: string]: string})[name] = ''; (connection.value as unknown as Record<string, string>)[name] = '';
}; };
setDefaults(); setDefaults();

View File

@@ -569,11 +569,11 @@ const pathSelection = (event: Event & {target: {files: {path: string}[]}}, name:
const { files } = event.target; const { files } = event.target;
if (!files.length) return; 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) => { 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)); localConnection.value = JSON.parse(JSON.stringify(props.connection));

View File

@@ -34,7 +34,6 @@
</div> </div>
<div :title="t('general.refresh')"> <div :title="t('general.refresh')">
<BaseIcon <BaseIcon
v-if="customizations.schemas"
icon-name="mdiRefresh" icon-name="mdiRefresh"
:size="18" :size="18"
class="c-hand mr-2" class="c-hand mr-2"

View File

@@ -382,7 +382,7 @@ const getFieldsData = async () => {
if (status === 'success') { if (status === 'success') {
const indexesObj = response const indexesObj = response
.filter((index: TableIndex) => index.type !== 'FOREIGN KEY') .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] = acc[curr.name] || [];
acc[curr.name].push(curr); acc[curr.name].push(curr);
return acc; return acc;

View File

@@ -258,7 +258,7 @@ const indexesPanel: Ref<HTMLDivElement> = ref(null);
const foreignProxy = ref([]); const foreignProxy = ref([]);
const selectedForeignID = ref(''); const selectedForeignID = ref('');
const modalInnerHeight = ref(400); 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 foreignActions = computed(() => props.workspace.customizations.foreignActions);
const selectedForeignObj = computed(() => foreignProxy.value.find(foreign => foreign._antares_id === selectedForeignID.value)); const selectedForeignObj = computed(() => foreignProxy.value.find(foreign => foreign._antares_id === selectedForeignID.value));

View File

@@ -382,7 +382,7 @@ const isBaseSelectField = computed(() => {
}); });
const enumArray = 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 props.fields[editingField.value].enumValues.replaceAll('\'', '').split(',');
return false; return false;
}); });

View File

@@ -28,7 +28,7 @@ export function useFilters () {
return `(${num})`; return `(${num})`;
}; };
const parseKeys = (keys: {[key: number]: string}[]) => { const parseKeys = (keys: Record<number, string>[]) => {
const isMacOS = process.platform === 'darwin'; const isMacOS = process.platform === 'darwin';
return (keys as string[]).map(k => ( return (keys as string[]).map(k => (
k.split('+') k.split('+')

View File

@@ -232,7 +232,7 @@ export const caES = {
newFunction: 'Nova funció', newFunction: 'Nova funció',
newScheduler: 'Nou planificador', newScheduler: 'Nou planificador',
newTriggerFunction: 'Nova funció de disparador', newTriggerFunction: 'Nova funció de disparador',
thereIsNoQueriesYet: 'Encara no hi ha consultes', thereAreNoQueriesYet: 'Encara no hi ha consultes',
searchForQueries: 'Cerca consultes', searchForQueries: 'Cerca consultes',
killProcess: 'Mata procés', killProcess: 'Mata procés',
exportSchema: 'Exporta esquema', exportSchema: 'Exporta esquema',

View File

@@ -233,7 +233,7 @@ export const csCZ = {
newFunction: 'Nová funkce', newFunction: 'Nová funkce',
newScheduler: 'Nový scheduler', newScheduler: 'Nový scheduler',
newTriggerFunction: 'Nová trigger funkce', newTriggerFunction: 'Nová trigger funkce',
thereIsNoQueriesYet: 'Nejsou tu žádné dotazy', thereAreNoQueriesYet: 'Nejsou tu žádné dotazy',
searchForQueries: 'Hledání dotazů', searchForQueries: 'Hledání dotazů',
killProcess: 'Zabít proces', killProcess: 'Zabít proces',
exportSchema: 'Exportovat schéma', exportSchema: 'Exportovat schéma',

View File

@@ -251,7 +251,7 @@ export const enUS = {
newFunction: 'New function', newFunction: 'New function',
newScheduler: 'New scheduler', newScheduler: 'New scheduler',
newTriggerFunction: 'New trigger function', newTriggerFunction: 'New trigger function',
thereIsNoQueriesYet: 'There is no queries yet', thereAreNoQueriesYet: 'There are no queries yet',
searchForQueries: 'Search for queries', searchForQueries: 'Search for queries',
killProcess: 'Kill process', killProcess: 'Kill process',
exportSchema: 'Export schema', exportSchema: 'Export schema',

View File

@@ -229,7 +229,7 @@ export const frFR = {
newFunction: 'Nouvelle function', newFunction: 'Nouvelle function',
newScheduler: 'Nouveau déclencheur', newScheduler: 'Nouveau déclencheur',
newTriggerFunction: 'Nouvelle fonction de 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', searchForQueries: 'Rechercher des requêtes',
killProcess: 'Terminer un processus', killProcess: 'Terminer un processus',
exportSchema: 'Exporter un schéma', exportSchema: 'Exporter un schéma',

View File

@@ -227,7 +227,7 @@ export const idID = {
newFunction: 'Fungsi baru', newFunction: 'Fungsi baru',
newScheduler: 'Penjadwal baru', newScheduler: 'Penjadwal baru',
newTriggerFunction: 'Fungsi pemicu baru', newTriggerFunction: 'Fungsi pemicu baru',
thereIsNoQueriesYet: 'Belum ada kueri', thereAreNoQueriesYet: 'Belum ada kueri',
searchForQueries: 'Telusuri kueri', searchForQueries: 'Telusuri kueri',
killProcess: 'Membunuh proses', killProcess: 'Membunuh proses',
exportSchema: 'Skema ekspor', exportSchema: 'Skema ekspor',

View File

@@ -228,7 +228,7 @@ export const itIT = {
newFunction: 'Nuova funzione', newFunction: 'Nuova funzione',
newScheduler: 'Nuovo scheduler', newScheduler: 'Nuovo scheduler',
newTriggerFunction: 'Nuova funzione di trigger', newTriggerFunction: 'Nuova funzione di trigger',
thereIsNoQueriesYet: 'Non ci sono ancora query', thereAreNoQueriesYet: 'Non ci sono ancora query',
searchForQueries: 'Cerca query', searchForQueries: 'Cerca query',
killProcess: 'Uccidi processo', killProcess: 'Uccidi processo',
exportSchema: 'Esporta schema', exportSchema: 'Esporta schema',

View File

@@ -198,7 +198,7 @@ export const jaJP = {
newFunction: '新しい関数', newFunction: '新しい関数',
newScheduler: '新規スケジューラ', newScheduler: '新規スケジューラ',
newTriggerFunction: '新しいトリガー機能', newTriggerFunction: '新しいトリガー機能',
thereIsNoQueriesYet: 'まだ問い合わせはありません', thereAreNoQueriesYet: 'まだ問い合わせはありません',
searchForQueries: 'クエリの検索', searchForQueries: 'クエリの検索',
killProcess: 'プロセスの停止' killProcess: 'プロセスの停止'
}, },

View File

@@ -228,7 +228,7 @@ export const koKR = {
newFunction: '새 함수', newFunction: '새 함수',
newScheduler: '새 스케줄러', newScheduler: '새 스케줄러',
newTriggerFunction: '새 트리거 함수', newTriggerFunction: '새 트리거 함수',
thereIsNoQueriesYet: '아직 쿼리가 없습니다', thereAreNoQueriesYet: '아직 쿼리가 없습니다',
searchForQueries: '쿼리 검색', searchForQueries: '쿼리 검색',
killProcess: '프로세스 종료', killProcess: '프로세스 종료',
exportSchema: '스키마 내보내기', exportSchema: '스키마 내보내기',

View File

@@ -100,7 +100,7 @@ export const nlNL = {
readOnlyMode: 'Alleen lezen modus', readOnlyMode: 'Alleen lezen modus',
untrustedConnection: 'Niet vertrouwde verbinding', untrustedConnection: 'Niet vertrouwde verbinding',
allConnections: 'Alle verbindingen', allConnections: 'Alle verbindingen',
searchForConnections: 'Search for connections' searchForConnections: 'Zoek naar verbindingen'
}, },
database: { database: {
schema: 'Schema', schema: 'Schema',
@@ -233,8 +233,8 @@ export const nlNL = {
newFunction: 'Nieuwe function', newFunction: 'Nieuwe function',
newScheduler: 'Nieuwe scheduler', newScheduler: 'Nieuwe scheduler',
newTriggerFunction: 'Nieuwe trigger function', newTriggerFunction: 'Nieuwe trigger function',
thereIsNoQueriesYet: 'There is no queries yet', thereAreNoQueriesYet: 'Er zijn nog geen queries',
searchForQueries: 'Search for queries', searchForQueries: 'Zoek naar queries',
killProcess: 'Sluit proces af', killProcess: 'Sluit proces af',
exportSchema: 'Exporteer schema', exportSchema: 'Exporteer schema',
importSchema: 'Importeer schema', importSchema: 'Importeer schema',

View File

@@ -231,7 +231,7 @@ export const ptBR = {
newFunction: 'Nova função', newFunction: 'Nova função',
newScheduler: 'Novo agendento', newScheduler: 'Novo agendento',
newTriggerFunction: 'Novo gatinho de função', newTriggerFunction: 'Novo gatinho de função',
thereIsNoQueriesYet: 'Nenhuma consulta ainda', thereAreNoQueriesYet: 'Nenhuma consulta ainda',
searchForQueries: 'Pesquisar por consultas', searchForQueries: 'Pesquisar por consultas',
killProcess: 'Matar processo', killProcess: 'Matar processo',
exportSchema: 'Exportar banco de dados', exportSchema: 'Exportar banco de dados',

View File

@@ -229,7 +229,7 @@ export const ruRU = {
newFunction: 'Новая функция', newFunction: 'Новая функция',
newScheduler: 'Новый планировщик', newScheduler: 'Новый планировщик',
newTriggerFunction: 'Новая функция триггера', newTriggerFunction: 'Новая функция триггера',
thereIsNoQueriesYet: 'Запросы пока отсутствуют', thereAreNoQueriesYet: 'Запросы пока отсутствуют',
searchForQueries: 'Поиск по запросам', searchForQueries: 'Поиск по запросам',
killProcess: 'Убить процесс', killProcess: 'Убить процесс',
exportSchema: 'Экспорт схемы', exportSchema: 'Экспорт схемы',

View File

@@ -1,4 +1,4 @@
export const localesNames: {[key: string]: string} = { export const localesNames: Record<string, string> = {
'en-US': 'English', 'en-US': 'English',
'it-IT': 'Italiano', 'it-IT': 'Italiano',
'ar-SA': 'العربية', 'ar-SA': 'العربية',

View File

@@ -238,7 +238,7 @@ export const ukUA = {
newFunction: 'Нова функція', newFunction: 'Нова функція',
newScheduler: 'Новий планувальник', newScheduler: 'Новий планувальник',
newTriggerFunction: 'Нова функція тригера', newTriggerFunction: 'Нова функція тригера',
thereIsNoQueriesYet: 'Поки що немає запитів', thereAreNoQueriesYet: 'Поки що немає запитів',
searchForQueries: 'Пошук запитів', searchForQueries: 'Пошук запитів',
killProcess: 'Завершити процес', killProcess: 'Завершити процес',
exportSchema: 'Експорт схеми', exportSchema: 'Експорт схеми',

View File

@@ -222,7 +222,7 @@ export const viVN = {
newFunction: 'Chức năng mới', newFunction: 'Chức năng mới',
newScheduler: 'Bộ lập lịch mới', newScheduler: 'Bộ lập lịch mới',
newTriggerFunction: 'Chức năng kích hoạt 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', searchForQueries: 'Tìm kiếm truy vấn',
killProcess: 'Huỷ quá trình', killProcess: 'Huỷ quá trình',
exportSchema: 'Xuất lược đồ', exportSchema: 'Xuất lược đồ',

View File

@@ -236,7 +236,7 @@ export const zhCN = {
newFunction: '新函数', newFunction: '新函数',
newScheduler: '新调度器', newScheduler: '新调度器',
newTriggerFunction: '新触发器函数', newTriggerFunction: '新触发器函数',
thereIsNoQueriesYet: '目前还没有任何查询', thereAreNoQueriesYet: '目前还没有任何查询',
searchForQueries: '搜索查询', searchForQueries: '搜索查询',
killProcess: '终止进程', killProcess: '终止进程',
exportSchema: '导出模式(schema)', exportSchema: '导出模式(schema)',

View File

@@ -64,7 +64,7 @@ export default class {
primary?: string; primary?: string;
field: string; field: string;
// eslint-disable-next-line @typescript-eslint/no-explicit-any // eslint-disable-next-line @typescript-eslint/no-explicit-any
rows: {[key: string]: any}; rows: Record<string, any>;
}): Promise<IpcResponse> { }): Promise<IpcResponse> {
return ipcRenderer.invoke('delete-table-rows', unproxify(params)); return ipcRenderer.invoke('delete-table-rows', unproxify(params));
} }
@@ -73,9 +73,9 @@ export default class {
uid: string; uid: string;
schema: string; schema: string;
table: string; table: string;
row: {[key: string]: string | number | boolean | Date | Buffer}; row: Record<string, string | number | boolean | Date | Buffer>;
repeat: number; repeat: number;
fields: {[key: string]: string}; fields: Record<string, string>;
locale: string; locale: string;
}): Promise<IpcResponse> { }): Promise<IpcResponse> {
return ipcRenderer.invoke('insert-table-fake-rows', unproxify(params)); return ipcRenderer.invoke('insert-table-fake-rows', unproxify(params));

View File

@@ -13,7 +13,7 @@ export interface HistoryRecord {
export const useHistoryStore = defineStore('history', { export const useHistoryStore = defineStore('history', {
state: () => ({ state: () => ({
history: persistentStore.get('history', {}) as {[key: string]: HistoryRecord[]}, history: persistentStore.get('history', {}) as Record<string, HistoryRecord[]>,
favorites: persistentStore.get('favorites', {}) favorites: persistentStore.get('favorites', {})
}), }),
getters: { getters: {

View File

@@ -86,11 +86,11 @@ export interface Workspace {
arch: string; arch: string;
os: string; os: string;
}; };
engines?: {[key: string]: string | boolean | number}[]; engines?: Record<string, string | boolean | number>[];
} }
const persistentStore = new Store({ name: 'tabs' }); const persistentStore = new Store({ name: 'tabs' });
const tabIndex: {[key: string]: number} = {}; const tabIndex: Record<string, number> = {};
export const useWorkspacesStore = defineStore('workspaces', { export const useWorkspacesStore = defineStore('workspaces', {
state: () => ({ state: () => ({
@@ -680,6 +680,7 @@ export const useWorkspacesStore = defineStore('workspaces', {
if (!isSelectedExistent && workspace.tabs.length) { if (!isSelectedExistent && workspace.tabs.length) {
if (workspace.customizations.database) { if (workspace.customizations.database) {
const databaseTabs = workspace.tabs.filter(tab => tab.type === 'query' || tab.database === workspace.database); const databaseTabs = workspace.tabs.filter(tab => tab.type === 'query' || tab.database === workspace.database);
if (databaseTabs.length)
this.selectTab({ uid, tab: databaseTabs[databaseTabs.length - 1].uid }); this.selectTab({ uid, tab: databaseTabs[databaseTabs.length - 1].uid });
} }
else else