mirror of
https://github.com/Fabio286/antares.git
synced 2025-06-05 21:59:22 +02:00
Compare commits
59 Commits
v0.7.31-be
...
dependabot
Author | SHA1 | Date | |
---|---|---|---|
|
67e849bc66 | ||
eb706c3e51 | |||
971df3a989 | |||
3129bf4baa | |||
c6d67cef01 | |||
1d7053ce03 | |||
41e797f9e2 | |||
704f70819b | |||
49a3589536 | |||
49ada059bc | |||
8003d3eb1e | |||
48cfa67889 | |||
9cda38e9d1 | |||
72f8d4249f | |||
0f93d70417 | |||
580bef76ba | |||
7595e89223 | |||
7af44d4a2c | |||
0479e5307c | |||
d03c1b90ce | |||
d34e56a517 | |||
0f35814ca0 | |||
96ae09feca | |||
e3b30359bf | |||
f3c3284fd1 | |||
27387f18a1 | |||
8e54f7b801 | |||
70aae2f194 | |||
592d7b3517 | |||
2b743a2c79 | |||
|
e493db5112 | ||
|
d3d7ab38c0 | ||
7a66c11868 | |||
8544bb5378 | |||
6709a75298 | |||
f25f6659d5 | |||
8d0ff4953e | |||
|
fbe28f0ff0 | ||
0d8bcf5cd6 | |||
|
47ac729d2f | ||
|
450c4c47f3 | ||
|
110dcd335a | ||
|
0029967619 | ||
34848e8dc3 | |||
c32add76e8 | |||
|
507dc7d55b | ||
4a2b5926f4 | |||
ed90b12a7b | |||
|
00ce76a12e | ||
|
77b3a8a354 | ||
d3ae45ec94 | |||
ad4478a822 | |||
|
ba5dd9ff15 | ||
|
5aab824fe9 | ||
87ab58c50f | |||
|
39a30e48dd | ||
46165d2f4f | |||
|
d0e56e4eb6 | ||
|
c803c072d1 |
@@ -338,6 +338,33 @@
|
|||||||
"contributions": [
|
"contributions": [
|
||||||
"platform"
|
"platform"
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"login": "r4f4dev",
|
||||||
|
"name": "r4f4dev",
|
||||||
|
"avatar_url": "https://avatars.githubusercontent.com/u/65920592?v=4",
|
||||||
|
"profile": "https://github.com/r4f4dev",
|
||||||
|
"contributions": [
|
||||||
|
"translation"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"login": "salvymc",
|
||||||
|
"name": "Salvatore Forino",
|
||||||
|
"avatar_url": "https://avatars.githubusercontent.com/u/10051897?v=4",
|
||||||
|
"profile": "https://github.com/salvymc",
|
||||||
|
"contributions": [
|
||||||
|
"code"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"login": "JoseGonzalez84",
|
||||||
|
"name": "José González",
|
||||||
|
"avatar_url": "https://avatars.githubusercontent.com/u/16820141?v=4",
|
||||||
|
"profile": "https://gadev.com.es/",
|
||||||
|
"contributions": [
|
||||||
|
"translation"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"contributorsPerLine": 7,
|
"contributorsPerLine": 7,
|
||||||
|
32
.github/workflows/create-artifact-windows-appx.yml
vendored
Normal file
32
.github/workflows/create-artifact-windows-appx.yml
vendored
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
name: Create artifact [WINDOWS APPX]
|
||||||
|
|
||||||
|
on:
|
||||||
|
workflow_dispatch: {}
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
runs-on: windows-2022
|
||||||
|
steps:
|
||||||
|
- name: Check out Git repository
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Install Node.js
|
||||||
|
uses: actions/setup-node@v4
|
||||||
|
with:
|
||||||
|
node-version: 20
|
||||||
|
|
||||||
|
- name: Install dependencies
|
||||||
|
run: npm i
|
||||||
|
|
||||||
|
- name: "Build"
|
||||||
|
run: npm run build:appx
|
||||||
|
|
||||||
|
- name: Upload Artifact
|
||||||
|
uses: actions/upload-artifact@v4
|
||||||
|
with:
|
||||||
|
name: windows-build
|
||||||
|
retention-days: 3
|
||||||
|
path: |
|
||||||
|
build
|
||||||
|
!build/*-unpacked
|
||||||
|
!build/.icon-ico
|
88
CHANGELOG.md
88
CHANGELOG.md
@@ -2,6 +2,94 @@
|
|||||||
|
|
||||||
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.33](https://github.com/antares-sql/antares/compare/v0.7.32...v0.7.33) (2025-02-14)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* issue with some SSH connections, fixes [#947](https://github.com/antares-sql/antares/issues/947) ([3129bf4](https://github.com/antares-sql/antares/commit/3129bf4baa5e72b1d79df986605fd5fad1dce291))
|
||||||
|
|
||||||
|
### [0.7.32](https://github.com/antares-sql/antares/compare/v0.7.31...v0.7.32) (2025-02-14)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* black background with light theme, fixes [#945](https://github.com/antares-sql/antares/issues/945) ([1d7053c](https://github.com/antares-sql/antares/commit/1d7053ce032efec8377d9500f2e24618f6381ab4))
|
||||||
|
* enhance SVG support in connection customization, fixes [#939](https://github.com/antares-sql/antares/issues/939) ([49a3589](https://github.com/antares-sql/antares/commit/49a3589536d2e75a14125be7b874e29b60fb56c4))
|
||||||
|
* improve error handling in SSH connection ([704f708](https://github.com/antares-sql/antares/commit/704f70819b21a42194d8f68cf9b58ba337f1ada7))
|
||||||
|
* **PostgreSQL:** error with materialized view tabs ([41e797f](https://github.com/antares-sql/antares/commit/41e797f9e27db66370d3ae7750c057f708af76f9))
|
||||||
|
|
||||||
|
### [0.7.31](https://github.com/antares-sql/antares/compare/v0.7.31-beta.5...v0.7.31) (2025-02-11)
|
||||||
|
|
||||||
|
### [0.7.31-beta.5](https://github.com/antares-sql/antares/compare/v0.7.31-beta.4...v0.7.31-beta.5) (2025-02-09)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **devtoolsInstaller:** improve file path handling and increase chromium version ([7595e89](https://github.com/antares-sql/antares/commit/7595e892238d2a93c454e9c1f236915fb458eed1))
|
||||||
|
* improve BLOB primary fields management, fixes [#938](https://github.com/antares-sql/antares/issues/938) ([72f8d42](https://github.com/antares-sql/antares/commit/72f8d4249f7f587d3e92b46cf7709ddab42107d4))
|
||||||
|
* **Linux:** restored AppImage auto updates ([0479e53](https://github.com/antares-sql/antares/commit/0479e5307c9a9d5f791e1c61fa772d331f6f7f1f))
|
||||||
|
* replace 'this.addNotification' with 'addNotification' in useResultTables.ts ([580bef7](https://github.com/antares-sql/antares/commit/580bef76ba390fc85df0892265f31392b80301bd))
|
||||||
|
* unable to delete rows from context menu ([0f93d70](https://github.com/antares-sql/antares/commit/0f93d70417871f02f9f64f203f6654fa1bf2004b))
|
||||||
|
|
||||||
|
|
||||||
|
### Improvements
|
||||||
|
|
||||||
|
* improve button styles of notes ([48cfa67](https://github.com/antares-sql/antares/commit/48cfa67889bd83228c109b7966c4acea4e542fc6))
|
||||||
|
* **MySQL:** long loading in table settings when no checks present ([9cda38e](https://github.com/antares-sql/antares/commit/9cda38e9d10e3000473863560d8be8f426a5ed17))
|
||||||
|
|
||||||
|
### [0.7.31-beta.4](https://github.com/antares-sql/antares/compare/v0.7.31-beta.3...v0.7.31-beta.4) (2025-01-31)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **Linux:** missing window management icons ([d34e56a](https://github.com/antares-sql/antares/commit/d34e56a517784dea16a7a53bc2249072a3b96596))
|
||||||
|
|
||||||
|
### [0.7.31-beta.3](https://github.com/antares-sql/antares/compare/v0.7.31-beta.2...v0.7.31-beta.3) (2025-01-31)
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* implement a better query splitter for SQL queries, fixes [#926](https://github.com/antares-sql/antares/issues/926) ([96ae09f](https://github.com/antares-sql/antares/commit/96ae09fecad0c1fc8926d5dcf64cc779abe5ed49))
|
||||||
|
* **Linux:** update title bar for better Linux experience ([8e54f7b](https://github.com/antares-sql/antares/commit/8e54f7b80135768a33934bc9336239dee38401a5))
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **MySQL:** adjust utf8mb3 encoding to resolve compatibility issue, fixes [#646](https://github.com/antares-sql/antares/issues/646) ([27387f1](https://github.com/antares-sql/antares/commit/27387f18a107fc6c09afec5f85134496ce764355))
|
||||||
|
|
||||||
|
### [0.7.31-beta.2](https://github.com/antares-sql/antares/compare/v0.7.31-beta.1...v0.7.31-beta.2) (2025-01-30)
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* add developer tools and refresh buttons to console in development mode ([592d7b3](https://github.com/antares-sql/antares/commit/592d7b35170f8437ebc15221c97985e889fccb40))
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* fail to fill cell to datetime column(Postgre) fixes [#924](https://github.com/antares-sql/antares/issues/924) ([d3d7ab3](https://github.com/antares-sql/antares/commit/d3d7ab38c029fc5ec23767c6c86c49a96e4e329c))
|
||||||
|
* reorder condition when format the update data ([e493db5](https://github.com/antares-sql/antares/commit/e493db5112478ff121e4e77f69c21747c5d2e032))
|
||||||
|
|
||||||
|
### [0.7.31-beta.1](https://github.com/antares-sql/antares/compare/v0.7.31-beta.0...v0.7.31-beta.1) (2025-01-22)
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* zoom in/out and fullscreen shortcuts ([47ac729](https://github.com/antares-sql/antares/commit/47ac729d2f5cced2c503358f7d45a1795f232a20))
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* cannot update column value with composite primary key and JSON column, fixes [#916](https://github.com/antares-sql/antares/issues/916) ([0029967](https://github.com/antares-sql/antares/commit/002996761997444ff689bf2384dae64ccb9ef8f7))
|
||||||
|
* fail to duplicate JSON row ([507dc7d](https://github.com/antares-sql/antares/commit/507dc7d55b342240bf18fd58e6bc71709e8e33a0))
|
||||||
|
* saved connections lost opening a second window after first app run ([4a2b592](https://github.com/antares-sql/antares/commit/4a2b5926f4783d0b9b1e28485e9293a25ddd31f3))
|
||||||
|
|
||||||
|
|
||||||
|
### Improvements
|
||||||
|
|
||||||
|
* **translation:** update spanish translation ([d3ae45e](https://github.com/antares-sql/antares/commit/d3ae45ec94b3538e84ac3013b285034caea695cf))
|
||||||
|
|
||||||
### [0.7.31-beta.0](https://github.com/antares-sql/antares/compare/v0.7.30...v0.7.31-beta.0) (2025-01-06)
|
### [0.7.31-beta.0](https://github.com/antares-sql/antares/compare/v0.7.30...v0.7.31-beta.0) (2025-01-06)
|
||||||
|
|
||||||
|
|
||||||
|
@@ -159,6 +159,9 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d
|
|||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/carvalhods"><img src="https://avatars.githubusercontent.com/u/6569255?v=4?s=100" width="100px;" alt="David Carvalho"/><br /><sub><b>David Carvalho</b></sub></a><br /><a href="#platform-carvalhods" title="Packaging/porting to new platform">📦</a></td>
|
<td align="center" valign="top" width="14.28%"><a href="https://github.com/carvalhods"><img src="https://avatars.githubusercontent.com/u/6569255?v=4?s=100" width="100px;" alt="David Carvalho"/><br /><sub><b>David Carvalho</b></sub></a><br /><a href="#platform-carvalhods" title="Packaging/porting to new platform">📦</a></td>
|
||||||
|
<td align="center" valign="top" width="14.28%"><a href="https://github.com/r4f4dev"><img src="https://avatars.githubusercontent.com/u/65920592?v=4?s=100" width="100px;" alt="r4f4dev"/><br /><sub><b>r4f4dev</b></sub></a><br /><a href="#translation-r4f4dev" title="Translation">🌍</a></td>
|
||||||
|
<td align="center" valign="top" width="14.28%"><a href="https://github.com/salvymc"><img src="https://avatars.githubusercontent.com/u/10051897?v=4?s=100" width="100px;" alt="Salvatore Forino"/><br /><sub><b>Salvatore Forino</b></sub></a><br /><a href="https://github.com/antares-sql/antares/commits?author=salvymc" title="Code">💻</a></td>
|
||||||
|
<td align="center" valign="top" width="14.28%"><a href="https://gadev.com.es/"><img src="https://avatars.githubusercontent.com/u/16820141?v=4?s=100" width="100px;" alt="José González"/><br /><sub><b>José González</b></sub></a><br /><a href="#translation-JoseGonzalez84" title="Translation">🌍</a></td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
684
package-lock.json
generated
684
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "antares",
|
"name": "antares",
|
||||||
"productName": "Antares",
|
"productName": "Antares",
|
||||||
"version": "0.7.31-beta.0",
|
"version": "0.7.33",
|
||||||
"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",
|
||||||
@@ -131,6 +131,7 @@
|
|||||||
"babel-loader": "~8.2.3",
|
"babel-loader": "~8.2.3",
|
||||||
"better-sqlite3": "~10.0.0",
|
"better-sqlite3": "~10.0.0",
|
||||||
"chalk": "~4.1.2",
|
"chalk": "~4.1.2",
|
||||||
|
"ciaplu": "^2.2.0",
|
||||||
"cpu-features": "^0.0.10",
|
"cpu-features": "^0.0.10",
|
||||||
"cross-env": "~7.0.2",
|
"cross-env": "~7.0.2",
|
||||||
"css-loader": "~6.5.0",
|
"css-loader": "~6.5.0",
|
||||||
@@ -173,7 +174,7 @@
|
|||||||
"vue-i18n": "~9.13.1",
|
"vue-i18n": "~9.13.1",
|
||||||
"vue-loader": "~16.8.3",
|
"vue-loader": "~16.8.3",
|
||||||
"vuedraggable": "~4.1.0",
|
"vuedraggable": "~4.1.0",
|
||||||
"webpack": "^5.91.0",
|
"webpack": "^5.98.0",
|
||||||
"webpack-cli": "~4.9.1"
|
"webpack-cli": "~4.9.1"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||||
// @ts-nocheck
|
// @ts-check
|
||||||
const fs = require('fs');
|
const fs = require('fs');
|
||||||
const path = require('path');
|
const path = require('path');
|
||||||
const https = require('https');
|
const https = require('https');
|
||||||
@@ -7,13 +7,18 @@ const unzip = require('unzip-crx-3');
|
|||||||
const { antares } = require('../package.json');
|
const { antares } = require('../package.json');
|
||||||
|
|
||||||
const extensionID = antares.devtoolsId;
|
const extensionID = antares.devtoolsId;
|
||||||
|
const chromiumVersion = '124';
|
||||||
const destFolder = path.resolve(__dirname, `../misc/${extensionID}`);
|
const destFolder = path.resolve(__dirname, `../misc/${extensionID}`);
|
||||||
const filePath = path.resolve(__dirname, `${destFolder}${extensionID}.crx`);
|
const filePath = path.resolve(__dirname, `${destFolder}/${extensionID}.crx`);
|
||||||
const fileUrl = `https://clients2.google.com/service/update2/crx?response=redirect&acceptformat=crx2,crx3&x=id%3D${extensionID}%26uc&prodversion=32`;
|
const fileUrl = `https://clients2.google.com/service/update2/crx?response=redirect&acceptformat=crx2,crx3&x=id%3D${extensionID}%26uc&prodversion=${chromiumVersion}`;
|
||||||
|
|
||||||
|
if (!fs.existsSync(destFolder))
|
||||||
|
fs.mkdirSync(destFolder, { recursive: true });
|
||||||
|
|
||||||
const fileStream = fs.createWriteStream(filePath);
|
const fileStream = fs.createWriteStream(filePath);
|
||||||
|
|
||||||
const downloadFile = url => {
|
const downloadFile = url => {
|
||||||
return new Promise((resolve, reject) => {
|
return /** @type {Promise<void>} */(new Promise((resolve, reject) => {
|
||||||
const request = https.get(url);
|
const request = https.get(url);
|
||||||
|
|
||||||
request.on('response', response => {
|
request.on('response', response => {
|
||||||
@@ -33,7 +38,7 @@ const downloadFile = url => {
|
|||||||
});
|
});
|
||||||
request.on('error', reject);
|
request.on('error', reject);
|
||||||
request.end();
|
request.end();
|
||||||
});
|
}));
|
||||||
};
|
};
|
||||||
|
|
||||||
(async () => {
|
(async () => {
|
||||||
|
@@ -34,6 +34,7 @@ export interface ClientParams {
|
|||||||
| { databasePath: string; readonly: boolean };
|
| { databasePath: string; readonly: boolean };
|
||||||
poolSize?: number;
|
poolSize?: number;
|
||||||
logger?: () => void;
|
logger?: () => void;
|
||||||
|
querySplitter?: (sql: string, clieng?: string) => string[];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -1,3 +1,5 @@
|
|||||||
|
import { match } from 'ciaplu';
|
||||||
|
|
||||||
function isJSON (str: string) {
|
function isJSON (str: string) {
|
||||||
try {
|
try {
|
||||||
if (!['{', '['].includes(str.trim()[0]))
|
if (!['{', '['].includes(str.trim()[0]))
|
||||||
@@ -176,17 +178,13 @@ function isMD (str: string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function langDetector (str: string) {
|
export function langDetector (str: string) {
|
||||||
if (!str || !str.trim().length)
|
return match(str)
|
||||||
return 'text';
|
.when(() => !str || !str.trim().length, () => 'text')
|
||||||
if (isJSON(str))
|
.when(isJSON, () => 'json')
|
||||||
return 'json';
|
.when(isHTML, () => 'html')
|
||||||
if (isHTML(str))
|
.when(isSVG, () => 'svg')
|
||||||
return 'html';
|
.when(isXML, () => 'xml')
|
||||||
if (isSVG(str))
|
.when(isMD, () => 'markdown')
|
||||||
return 'svg';
|
.otherwise(() => 'text')
|
||||||
if (isXML(str))
|
.return();
|
||||||
return 'xml';
|
|
||||||
if (isMD(str))
|
|
||||||
return 'markdown';
|
|
||||||
return 'text';
|
|
||||||
}
|
}
|
||||||
|
@@ -1,45 +1,25 @@
|
|||||||
|
import { match } from 'ciaplu';
|
||||||
|
|
||||||
export function mimeFromHex (hex: string) {
|
export function mimeFromHex (hex: string) {
|
||||||
switch (hex.substring(0, 4)) { // 2 bytes
|
return match(hex.substring(0, 4)) // 2 bytes
|
||||||
case '424D':
|
.with('424D', () => ({ ext: 'bmp', mime: 'image/bmp' }))
|
||||||
return { ext: 'bmp', mime: 'image/bmp' };
|
.with('1F8B', () => ({ ext: 'tar.gz', mime: 'application/gzip' }))
|
||||||
case '1F8B':
|
.with('0B77', () => ({ ext: 'ac3', mime: 'audio/vnd.dolby.dd-raw' }))
|
||||||
return { ext: 'tar.gz', mime: 'application/gzip' };
|
.with('7801', () => ({ ext: 'dmg', mime: 'application/x-apple-diskimage' }))
|
||||||
case '0B77':
|
.with('4D5A', () => ({ ext: 'exe', mime: 'application/x-msdownload' }))
|
||||||
return { ext: 'ac3', mime: 'audio/vnd.dolby.dd-raw' };
|
.when((val) => ['1FA0', '1F9D'].includes(val), () => ({ ext: 'Z', mime: 'application/x-compress' }))
|
||||||
case '7801':
|
.extracting(() => hex.substring(0, 6)) // 3 bytes
|
||||||
return { ext: 'dmg', mime: 'application/x-apple-diskimage' };
|
.with('FFD8FF', () => ({ ext: 'jpg', mime: 'image/jpeg' }))
|
||||||
case '4D5A':
|
.with('4949BC', () => ({ ext: 'jxr', mime: 'image/vnd.ms-photo' }))
|
||||||
return { ext: 'exe', mime: 'application/x-msdownload' };
|
.with('425A68', () => ({ ext: 'bz2', mime: 'application/x-bzip2' }))
|
||||||
case '1FA0':
|
.extracting(() => hex) // 4 bytes
|
||||||
case '1F9D':
|
.with('89504E47', () => ({ ext: 'png', mime: 'image/png' }))
|
||||||
return { ext: 'Z', mime: 'application/x-compress' };
|
.with('47494638', () => ({ ext: 'gif', mime: 'image/gif' }))
|
||||||
default:
|
.with('25504446', () => ({ ext: 'pdf', mime: 'application/pdf' }))
|
||||||
switch (hex.substring(0, 6)) { // 3 bytes
|
.with('504B0304', () => ({ ext: 'zip', mime: 'application/zip' }))
|
||||||
case 'FFD8FF':
|
.with('425047FB', () => ({ ext: 'bpg', mime: 'image/bpg' }))
|
||||||
return { ext: 'jpg', mime: 'image/jpeg' };
|
.with('4D4D002A', () => ({ ext: 'tif', mime: 'image/tiff' }))
|
||||||
case '4949BC':
|
.with('00000100', () => ({ ext: 'ico', mime: 'image/x-icon' }))
|
||||||
return { ext: 'jxr', mime: 'image/vnd.ms-photo' };
|
.otherwise(() => ({ ext: '', mime: 'unknown ' + hex }))
|
||||||
case '425A68':
|
.return();
|
||||||
return { ext: 'bz2', mime: 'application/x-bzip2' };
|
|
||||||
default:
|
|
||||||
switch (hex) { // 4 bites
|
|
||||||
case '89504E47':
|
|
||||||
return { ext: 'png', mime: 'image/png' };
|
|
||||||
case '47494638':
|
|
||||||
return { ext: 'gif', mime: 'image/gif' };
|
|
||||||
case '25504446':
|
|
||||||
return { ext: 'pdf', mime: 'application/pdf' };
|
|
||||||
case '504B0304':
|
|
||||||
return { ext: 'zip', mime: 'application/zip' };
|
|
||||||
case '425047FB':
|
|
||||||
return { ext: 'bpg', mime: 'image/bpg' };
|
|
||||||
case '4D4D002A':
|
|
||||||
return { ext: 'tif', mime: 'image/tiff' };
|
|
||||||
case '00000100':
|
|
||||||
return { ext: 'ico', mime: 'image/x-icon' };
|
|
||||||
default:
|
|
||||||
return { ext: '', mime: 'unknown ' + hex };
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
86
src/common/libs/querySplitter.ts
Normal file
86
src/common/libs/querySplitter.ts
Normal file
@@ -0,0 +1,86 @@
|
|||||||
|
import { ClientCode } from 'common/interfaces/antares';
|
||||||
|
|
||||||
|
export const querySplitter =(sql: string, dbType: ClientCode): string[] => {
|
||||||
|
const queries: string[] = [];
|
||||||
|
let currentQuery = '';
|
||||||
|
let insideBlock = false;
|
||||||
|
let insideString = false;
|
||||||
|
let stringDelimiter: string | null = null;
|
||||||
|
let insideDollarTag = false;
|
||||||
|
let dollarTagDelimiter: string | null = null;
|
||||||
|
|
||||||
|
// Regex patterns for BEGIN-END blocks, dollar tags in PostgreSQL, and semicolons
|
||||||
|
const beginRegex = /\bBEGIN\b/i;
|
||||||
|
const endRegex = /\bEND\b;/i;
|
||||||
|
const dollarTagRegex = /\$(\w+)?\$/; // Matches $tag$ or $$
|
||||||
|
|
||||||
|
// Split on semicolons, keeping semicolons attached to the lines
|
||||||
|
const lines = sql.split(/(?<=;)/);
|
||||||
|
|
||||||
|
for (let line of lines) {
|
||||||
|
line = line.trim();
|
||||||
|
|
||||||
|
if (!line) continue;
|
||||||
|
|
||||||
|
for (let i = 0; i < line.length; i++) {
|
||||||
|
const char = line[i];
|
||||||
|
|
||||||
|
// Handle string boundaries
|
||||||
|
if ((char === '\'' || char === '"') && (!insideString || char === stringDelimiter)) {
|
||||||
|
if (!insideString) {
|
||||||
|
insideString = true;
|
||||||
|
stringDelimiter = char;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
insideString = false;
|
||||||
|
stringDelimiter = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
currentQuery += char;
|
||||||
|
|
||||||
|
if (dbType === 'pg') {
|
||||||
|
// Handle dollar-quoted blocks in PostgreSQL
|
||||||
|
if (!insideString && line.slice(i).match(dollarTagRegex)) {
|
||||||
|
const match = line.slice(i).match(dollarTagRegex);
|
||||||
|
if (match) {
|
||||||
|
const tag = match[0];
|
||||||
|
if (!insideDollarTag) {
|
||||||
|
insideDollarTag = true;
|
||||||
|
dollarTagDelimiter = tag;
|
||||||
|
currentQuery += tag;
|
||||||
|
i += tag.length - 1;
|
||||||
|
}
|
||||||
|
else if (dollarTagDelimiter === tag) {
|
||||||
|
insideDollarTag = false;
|
||||||
|
dollarTagDelimiter = null;
|
||||||
|
currentQuery += tag;
|
||||||
|
i += tag.length - 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check BEGIN-END blocks
|
||||||
|
if (!insideString && !insideDollarTag) {
|
||||||
|
if (beginRegex.test(line))
|
||||||
|
insideBlock = true;
|
||||||
|
|
||||||
|
if (insideBlock && endRegex.test(line))
|
||||||
|
insideBlock = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Append the query if we encounter a semicolon outside a BEGIN-END block, outside a string, and outside dollar tags
|
||||||
|
if (!insideBlock && !insideString && !insideDollarTag && /;\s*$/.test(line)) {
|
||||||
|
queries.push(currentQuery.trim());
|
||||||
|
currentQuery = '';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add any remaining query
|
||||||
|
if (currentQuery.trim())
|
||||||
|
queries.push(currentQuery.trim());
|
||||||
|
|
||||||
|
return queries;
|
||||||
|
};
|
@@ -2,6 +2,7 @@
|
|||||||
/* eslint-disable no-useless-escape */
|
/* eslint-disable no-useless-escape */
|
||||||
import { lineString, point, polygon } from '@turf/helpers';
|
import { lineString, point, polygon } from '@turf/helpers';
|
||||||
import { BIT, BLOB, DATE, DATETIME, FLOAT, IS_MULTI_SPATIAL, NUMBER, SPATIAL, TEXT_SEARCH } from 'common/fieldTypes';
|
import { BIT, BLOB, DATE, DATETIME, FLOAT, IS_MULTI_SPATIAL, NUMBER, SPATIAL, TEXT_SEARCH } from 'common/fieldTypes';
|
||||||
|
import * as antares from 'common/interfaces/antares';
|
||||||
import * as moment from 'moment';
|
import * as moment from 'moment';
|
||||||
|
|
||||||
import customizations from '../customizations';
|
import customizations from '../customizations';
|
||||||
@@ -209,3 +210,20 @@ export const jsonToSqlInsert = (args: {
|
|||||||
|
|
||||||
return insertsString;
|
return insertsString;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const formatJsonForSqlWhere = (jsonValue: object, clientType: antares.ClientCode) => {
|
||||||
|
const formattedValue = JSON.stringify(jsonValue);
|
||||||
|
|
||||||
|
switch (clientType) {
|
||||||
|
case 'mysql':
|
||||||
|
return ` = CAST('${formattedValue}' AS JSON)`;
|
||||||
|
case 'maria':
|
||||||
|
return ` = '${formattedValue}'`;
|
||||||
|
case 'pg':
|
||||||
|
return `::text = '${formattedValue}'`;
|
||||||
|
case 'firebird':
|
||||||
|
case 'sqlite':
|
||||||
|
default:
|
||||||
|
return ` = '${formattedValue}'`;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
@@ -1,29 +1,34 @@
|
|||||||
export const shortcutEvents: Record<string, { l18n: string; l18nParam?: string | number; context?: 'tab' }> = {
|
export const shortcutEvents: Record<string, { i18n: string; i18nParam?: string | number; context?: 'tab' | 'main' }> = {
|
||||||
'run-or-reload': { l18n: 'application.runOrReload', context: 'tab' },
|
'run-or-reload': { i18n: 'application.runOrReload', context: 'tab' },
|
||||||
'open-new-tab': { l18n: 'application.openNewTab', context: 'tab' },
|
'open-new-tab': { i18n: 'application.openNewTab', context: 'tab' },
|
||||||
'close-tab': { l18n: 'application.closeTab', context: 'tab' },
|
'close-tab': { i18n: 'application.closeTab', context: 'tab' },
|
||||||
'format-query': { l18n: 'database.formatQuery', context: 'tab' },
|
'format-query': { i18n: 'database.formatQuery', context: 'tab' },
|
||||||
'kill-query': { l18n: 'database.killQuery', context: 'tab' },
|
'kill-query': { i18n: 'database.killQuery', context: 'tab' },
|
||||||
'query-history': { l18n: 'database.queryHistory', context: 'tab' },
|
'query-history': { i18n: 'database.queryHistory', context: 'tab' },
|
||||||
'clear-query': { l18n: 'database.clearQuery', context: 'tab' },
|
'clear-query': { i18n: 'database.clearQuery', context: 'tab' },
|
||||||
// 'save-file': { l18n: 'application.saveFile', context: 'tab' },
|
// 'save-file': { i18n: 'application.saveFile', context: 'tab' },
|
||||||
'open-file': { l18n: 'application.openFile', context: 'tab' },
|
'open-file': { i18n: 'application.openFile', context: 'tab' },
|
||||||
'save-file-as': { l18n: 'application.saveFileAs', context: 'tab' },
|
'save-file-as': { i18n: 'application.saveFileAs', context: 'tab' },
|
||||||
'next-tab': { l18n: 'application.nextTab' },
|
'next-tab': { i18n: 'application.nextTab' },
|
||||||
'prev-tab': { l18n: 'application.previousTab' },
|
'prev-tab': { i18n: 'application.previousTab' },
|
||||||
'open-all-connections': { l18n: 'application.openAllConnections' },
|
'open-all-connections': { i18n: 'application.openAllConnections' },
|
||||||
'open-filter': { l18n: 'application.openFilter' },
|
'open-filter': { i18n: 'application.openFilter' },
|
||||||
'next-page': { l18n: 'application.nextResultsPage' },
|
'next-page': { i18n: 'application.nextResultsPage' },
|
||||||
'prev-page': { l18n: 'application.previousResultsPage' },
|
'prev-page': { i18n: 'application.previousResultsPage' },
|
||||||
'toggle-console': { l18n: 'application.toggleConsole' },
|
'toggle-console': { i18n: 'application.toggleConsole' },
|
||||||
'save-content': { l18n: 'application.saveContent' },
|
'save-content': { i18n: 'application.saveContent' },
|
||||||
'create-connection': { l18n: 'connection.createNewConnection' },
|
'create-connection': { i18n: 'connection.createNewConnection' },
|
||||||
'open-settings': { l18n: 'application.openSettings' },
|
'open-settings': { i18n: 'application.openSettings' },
|
||||||
'open-scratchpad': { l18n: 'application.openNotes' }
|
'open-scratchpad': { i18n: 'application.openNotes' },
|
||||||
|
setFullScreen: { i18n: 'application.fullScreen', context: 'main' },
|
||||||
|
setZoomIn: { i18n: 'application.zoomIn', context: 'main' },
|
||||||
|
setZoomOut: { i18n: 'application.zoomOut', context: 'main' },
|
||||||
|
setZoomReset: { i18n: 'application.zoomReset', context: 'main' }
|
||||||
};
|
};
|
||||||
|
|
||||||
interface ShortcutRecord {
|
interface ShortcutRecord {
|
||||||
event: string;
|
event: string;
|
||||||
|
isFunction?: boolean;
|
||||||
keys: Electron.Accelerator[] | string[];
|
keys: Electron.Accelerator[] | string[];
|
||||||
/** Needed for default shortcuts */
|
/** Needed for default shortcuts */
|
||||||
os: NodeJS.Platform[];
|
os: NodeJS.Platform[];
|
||||||
@@ -38,6 +43,30 @@ const shortcuts: ShortcutRecord[] = [
|
|||||||
keys: ['F5'],
|
keys: ['F5'],
|
||||||
os: ['darwin', 'linux', 'win32']
|
os: ['darwin', 'linux', 'win32']
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
event: 'setFullScreen',
|
||||||
|
isFunction: true,
|
||||||
|
keys: ['F11'],
|
||||||
|
os: ['darwin', 'linux', 'win32']
|
||||||
|
},
|
||||||
|
{
|
||||||
|
event: 'setZoomIn',
|
||||||
|
isFunction: true,
|
||||||
|
keys: ['CommandOrControl+='],
|
||||||
|
os: ['darwin', 'linux', 'win32']
|
||||||
|
},
|
||||||
|
{
|
||||||
|
event: 'setZoomOut',
|
||||||
|
isFunction: true,
|
||||||
|
keys: ['CommandOrControl+-'],
|
||||||
|
os: ['darwin', 'linux', 'win32']
|
||||||
|
},
|
||||||
|
{
|
||||||
|
event: 'setZoomReset',
|
||||||
|
isFunction: true,
|
||||||
|
keys: ['CommandOrControl+0'],
|
||||||
|
os: ['darwin', 'linux', 'win32']
|
||||||
|
},
|
||||||
{
|
{
|
||||||
event: 'save-content',
|
event: 'save-content',
|
||||||
keys: ['CommandOrControl+S'],
|
keys: ['CommandOrControl+S'],
|
||||||
@@ -142,8 +171,8 @@ const shortcuts: ShortcutRecord[] = [
|
|||||||
|
|
||||||
for (let i = 1; i <= 9; i++) {
|
for (let i = 1; i <= 9; i++) {
|
||||||
shortcutEvents[`select-tab-${i}`] = {
|
shortcutEvents[`select-tab-${i}`] = {
|
||||||
l18n: 'application.selectTabNumber',
|
i18n: 'application.selectTabNumber',
|
||||||
l18nParam: i
|
i18nParam: i
|
||||||
};
|
};
|
||||||
|
|
||||||
shortcuts.push({
|
shortcuts.push({
|
||||||
|
@@ -64,9 +64,9 @@ export default (connections: Record<string, antares.Client>) => {
|
|||||||
username: conn.sshUser,
|
username: conn.sshUser,
|
||||||
password: conn.sshPass,
|
password: conn.sshPass,
|
||||||
port: conn.sshPort ? conn.sshPort : 22,
|
port: conn.sshPort ? conn.sshPort : 22,
|
||||||
privateKey: conn.sshKey ? fs.readFileSync(conn.sshKey).toString() : null,
|
privateKey: conn.sshKey ? fs.readFileSync(conn.sshKey).toString() : undefined,
|
||||||
passphrase: conn.sshPassphrase,
|
passphrase: conn.sshPassphrase,
|
||||||
keepaliveInterval: conn.sshKeepAliveInterval ? conn.sshKeepAliveInterval*1000 : null
|
keepaliveInterval: conn.sshKeepAliveInterval ? conn.sshKeepAliveInterval*1000 : undefined
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -90,11 +90,12 @@ export default (connections: Record<string, antares.Client>) => {
|
|||||||
|
|
||||||
return { status: 'success' };
|
return { status: 'success' };
|
||||||
}
|
}
|
||||||
catch (err) {
|
catch (error) {
|
||||||
clearInterval(abortChecker);
|
clearInterval(abortChecker);
|
||||||
|
if (error instanceof AggregateError)
|
||||||
if (!isLocalAborted)
|
throw new Error(error.errors.reduce((acc, curr) => acc +' | '+ curr.message, ''));
|
||||||
return { status: 'error', response: err.toString() };
|
else if (!isLocalAborted)
|
||||||
|
return { status: 'error', response: error.toString() };
|
||||||
else
|
else
|
||||||
return { status: 'abort', response: 'Connection aborted' };
|
return { status: 'abort', response: 'Connection aborted' };
|
||||||
}
|
}
|
||||||
|
@@ -3,7 +3,7 @@ import { ARRAY, BIT, BLOB, BOOLEAN, DATE, DATETIME, FLOAT, LONG_TEXT, NUMBER, TE
|
|||||||
import * as antares from 'common/interfaces/antares';
|
import * as antares from 'common/interfaces/antares';
|
||||||
import { InsertRowsParams } from 'common/interfaces/tableApis';
|
import { InsertRowsParams } from 'common/interfaces/tableApis';
|
||||||
import { fakerCustom } from 'common/libs/fakerCustom';
|
import { fakerCustom } from 'common/libs/fakerCustom';
|
||||||
import { sqlEscaper } from 'common/libs/sqlUtils';
|
import { formatJsonForSqlWhere, sqlEscaper } from 'common/libs/sqlUtils';
|
||||||
import { ipcMain } from 'electron';
|
import { ipcMain } from 'electron';
|
||||||
import * as fs from 'fs';
|
import * as fs from 'fs';
|
||||||
import * as moment from 'moment';
|
import * as moment from 'moment';
|
||||||
@@ -233,9 +233,10 @@ export default (connections: Record<string, antares.Client>) => {
|
|||||||
|
|
||||||
for (const key in orgRow) {
|
for (const key in orgRow) {
|
||||||
if (typeof orgRow[key] === 'string')
|
if (typeof orgRow[key] === 'string')
|
||||||
orgRow[key] = `'${orgRow[key]}'`;
|
orgRow[key] = ` = '${orgRow[key]}'`;
|
||||||
|
else if (typeof orgRow[key] === 'object' && orgRow[key] !== null)
|
||||||
if (orgRow[key] === null)
|
orgRow[key] = formatJsonForSqlWhere(orgRow[key], connections[params.uid]._client);
|
||||||
|
else if (orgRow[key] === null)
|
||||||
orgRow[key] = `IS ${orgRow[key]}`;
|
orgRow[key] = `IS ${orgRow[key]}`;
|
||||||
else
|
else
|
||||||
orgRow[key] = `= ${orgRow[key]}`;
|
orgRow[key] = `= ${orgRow[key]}`;
|
||||||
|
@@ -81,7 +81,15 @@ export class ShortcutRegister {
|
|||||||
accelerator: key,
|
accelerator: key,
|
||||||
visible: isMenuVisible,
|
visible: isMenuVisible,
|
||||||
click: () => {
|
click: () => {
|
||||||
this._mainWindow.webContents.send(shortcut.event);
|
if (shortcut.isFunction) {
|
||||||
|
if (shortcut.event in this) {
|
||||||
|
type exporterMethods = 'setFullScreen' | 'setZoomIn' | 'setZoomOut' | 'setZoomReset';
|
||||||
|
this[shortcut.event as exporterMethods]();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
this._mainWindow.webContents.send(shortcut.event);
|
||||||
|
|
||||||
if (isDevelopment) console.log('LOCAL EVENT:', shortcut);
|
if (isDevelopment) console.log('LOCAL EVENT:', shortcut);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -121,6 +129,24 @@ export class ShortcutRegister {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
setFullScreen () {
|
||||||
|
this._mainWindow.setFullScreen(!this._mainWindow.isFullScreen());
|
||||||
|
}
|
||||||
|
|
||||||
|
setZoomIn () {
|
||||||
|
const currentZoom = this._mainWindow.webContents.getZoomLevel();
|
||||||
|
this._mainWindow.webContents.setZoomLevel(currentZoom + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
setZoomOut () {
|
||||||
|
const currentZoom = this._mainWindow.webContents.getZoomLevel();
|
||||||
|
this._mainWindow.webContents.setZoomLevel(currentZoom - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
setZoomReset () {
|
||||||
|
this._mainWindow.webContents.setZoomLevel(0);
|
||||||
|
}
|
||||||
|
|
||||||
reload () {
|
reload () {
|
||||||
this.unregister();
|
this.unregister();
|
||||||
this.init();
|
this.init();
|
||||||
|
@@ -2,27 +2,9 @@ import * as antares from 'common/interfaces/antares';
|
|||||||
import mysql from 'mysql2/promise';
|
import mysql from 'mysql2/promise';
|
||||||
import * as pg from 'pg';
|
import * as pg from 'pg';
|
||||||
import SSH2Promise = require('@fabio286/ssh2-promise');
|
import SSH2Promise = require('@fabio286/ssh2-promise');
|
||||||
|
import { querySplitter } from 'common/libs/querySplitter';
|
||||||
|
|
||||||
export type LoggerLevel = 'query' | 'error'
|
import { ipcLogger, LoggerLevel } from '../misc/ipcLogger';
|
||||||
|
|
||||||
const ipcLogger = ({ content, cUid, level }: {content: string; cUid: string; level: LoggerLevel}) => {
|
|
||||||
if (level === 'error') {
|
|
||||||
if (process.type !== undefined) {
|
|
||||||
const mainWindow = require('electron').webContents.fromId(1);
|
|
||||||
mainWindow.send('non-blocking-exception', { cUid, message: content, date: new Date() });
|
|
||||||
}
|
|
||||||
if (process.env.NODE_ENV === 'development' && process.type === 'browser') console.log(content);
|
|
||||||
}
|
|
||||||
else if (level === 'query') {
|
|
||||||
// Remove comments, newlines and multiple spaces
|
|
||||||
const escapedSql = content.replace(/(\/\*(.|[\r\n])*?\*\/)|(--(.*|[\r\n]))/gm, '').replace(/\s\s+/g, ' ');
|
|
||||||
if (process.type !== undefined) {
|
|
||||||
const mainWindow = require('electron').webContents.fromId(1);
|
|
||||||
mainWindow.send('query-log', { cUid, sql: escapedSql, date: new Date() });
|
|
||||||
}
|
|
||||||
if (process.env.NODE_ENV === 'development' && process.type === 'browser') console.log(escapedSql);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* As Simple As Possible Query Builder Core
|
* As Simple As Possible Query Builder Core
|
||||||
@@ -34,6 +16,7 @@ export abstract class BaseClient {
|
|||||||
protected _poolSize: number;
|
protected _poolSize: number;
|
||||||
protected _ssh?: SSH2Promise;
|
protected _ssh?: SSH2Promise;
|
||||||
protected _logger: (args: {content: string; cUid: string; level: LoggerLevel}) => void;
|
protected _logger: (args: {content: string; cUid: string; level: LoggerLevel}) => void;
|
||||||
|
protected _querySplitter: (sql: string, client: antares.ClientCode) => string[];
|
||||||
protected _queryDefaults: antares.QueryBuilderObject;
|
protected _queryDefaults: antares.QueryBuilderObject;
|
||||||
protected _query: antares.QueryBuilderObject;
|
protected _query: antares.QueryBuilderObject;
|
||||||
|
|
||||||
@@ -43,6 +26,7 @@ export abstract class BaseClient {
|
|||||||
this._params = args.params;
|
this._params = args.params;
|
||||||
this._poolSize = args.poolSize || undefined;
|
this._poolSize = args.poolSize || undefined;
|
||||||
this._logger = args.logger || ipcLogger;
|
this._logger = args.logger || ipcLogger;
|
||||||
|
this._querySplitter = args.querySplitter || querySplitter;
|
||||||
|
|
||||||
this._queryDefaults = {
|
this._queryDefaults = {
|
||||||
schema: '',
|
schema: '',
|
||||||
|
@@ -245,10 +245,10 @@ export class FirebirdSQLClient extends BaseClient {
|
|||||||
name: db.name,
|
name: db.name,
|
||||||
size: schemaSize,
|
size: schemaSize,
|
||||||
tables: remappedTables,
|
tables: remappedTables,
|
||||||
functions: [],
|
functions: [] as null[],
|
||||||
procedures: remappedProcedures,
|
procedures: remappedProcedures,
|
||||||
triggers: remappedTriggers,
|
triggers: remappedTriggers,
|
||||||
schedulers: []
|
schedulers: [] as null[]
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -337,7 +337,7 @@ export class FirebirdSQLClient extends BaseClient {
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
name: field.FIELD_NAME.trim(),
|
name: field.FIELD_NAME.trim(),
|
||||||
key: null,
|
key: null as null,
|
||||||
type: fieldType,
|
type: fieldType,
|
||||||
schema: schema,
|
schema: schema,
|
||||||
table: table,
|
table: table,
|
||||||
@@ -346,14 +346,14 @@ export class FirebirdSQLClient extends BaseClient {
|
|||||||
datePrecision: field.FIELD_NAME.trim() === 'TIMESTAMP' ? 4 : null,
|
datePrecision: field.FIELD_NAME.trim() === 'TIMESTAMP' ? 4 : null,
|
||||||
charLength: ![...NUMBER, ...FLOAT].includes(fieldType) ? field.FIELD_LENGTH : null,
|
charLength: ![...NUMBER, ...FLOAT].includes(fieldType) ? field.FIELD_LENGTH : null,
|
||||||
nullable: !field.NOT_NULL,
|
nullable: !field.NOT_NULL,
|
||||||
unsigned: null,
|
unsigned: null as null,
|
||||||
zerofill: null,
|
zerofill: null as null,
|
||||||
order: field.FIELD_POSITION+1,
|
order: field.FIELD_POSITION+1,
|
||||||
default: defaultValue,
|
default: defaultValue,
|
||||||
charset: field.CHARSET,
|
charset: field.CHARSET,
|
||||||
collation: null,
|
collation: null as null,
|
||||||
autoIncrement: false,
|
autoIncrement: false,
|
||||||
onUpdate: null,
|
onUpdate: null as null,
|
||||||
comment: field.DESCRIPTION?.trim()
|
comment: field.DESCRIPTION?.trim()
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
@@ -457,7 +457,7 @@ export class FirebirdSQLClient extends BaseClient {
|
|||||||
table: table,
|
table: table,
|
||||||
field: field.FKCOLUMN_NAME.trim(),
|
field: field.FKCOLUMN_NAME.trim(),
|
||||||
position: field.KEY_SEQ,
|
position: field.KEY_SEQ,
|
||||||
constraintPosition: null,
|
constraintPosition: null as null,
|
||||||
constraintName: field.FK_NAME.trim(),
|
constraintName: field.FK_NAME.trim(),
|
||||||
refSchema: schema,
|
refSchema: schema,
|
||||||
refTable: field.PKTABLE_NAME.trim(),
|
refTable: field.PKTABLE_NAME.trim(),
|
||||||
@@ -1041,9 +1041,7 @@ export class FirebirdSQLClient extends BaseClient {
|
|||||||
const resultsArr = [];
|
const resultsArr = [];
|
||||||
let paramsArr = [];
|
let paramsArr = [];
|
||||||
const queries = args.split
|
const queries = args.split
|
||||||
? sql.split(/((?:[^;'"]*(?:"(?:\\.|[^"])*"|'(?:\\.|[^'])*')[^;'"]*)+)|;/gm)
|
? this._querySplitter(sql, 'firebird')
|
||||||
.filter(Boolean)
|
|
||||||
.map(q => q.trim())
|
|
||||||
: [sql];
|
: [sql];
|
||||||
|
|
||||||
let connection: firebird.Database | firebird.Transaction;
|
let connection: firebird.Database | firebird.Transaction;
|
||||||
|
@@ -4,7 +4,9 @@ import dataTypes from 'common/data-types/mysql';
|
|||||||
import * as antares from 'common/interfaces/antares';
|
import * as antares from 'common/interfaces/antares';
|
||||||
import * as mysql from 'mysql2/promise';
|
import * as mysql from 'mysql2/promise';
|
||||||
|
|
||||||
|
import * as EncodingToCharset from '../../../../node_modules/mysql2/lib/constants/encoding_charset.js';
|
||||||
import { BaseClient } from './BaseClient';
|
import { BaseClient } from './BaseClient';
|
||||||
|
EncodingToCharset.utf8mb3 = 192; // To fix https://github.com/sidorares/node-mysql2/issues/1398 until not included in mysql2
|
||||||
|
|
||||||
export class MySQLClient extends BaseClient {
|
export class MySQLClient extends BaseClient {
|
||||||
private _schema?: string;
|
private _schema?: string;
|
||||||
@@ -171,13 +173,13 @@ export class MySQLClient extends BaseClient {
|
|||||||
remotePort: this._params.port
|
remotePort: this._params.port
|
||||||
});
|
});
|
||||||
|
|
||||||
dbConfig.host = (this._ssh.config as SSHConfig[] & { host: string }).host;
|
dbConfig.host = undefined;
|
||||||
dbConfig.port = tunnel.localPort;
|
dbConfig.port = tunnel.localPort;
|
||||||
}
|
}
|
||||||
catch (err) {
|
catch (err) {
|
||||||
if (this._ssh) {
|
if (this._ssh) {
|
||||||
this._ssh.close();
|
|
||||||
this._ssh.closeTunnel();
|
this._ssh.closeTunnel();
|
||||||
|
this._ssh.close();
|
||||||
}
|
}
|
||||||
throw err;
|
throw err;
|
||||||
}
|
}
|
||||||
@@ -225,8 +227,8 @@ export class MySQLClient extends BaseClient {
|
|||||||
clearInterval(this._keepaliveTimer);
|
clearInterval(this._keepaliveTimer);
|
||||||
this._keepaliveTimer = undefined;
|
this._keepaliveTimer = undefined;
|
||||||
if (this._ssh) {
|
if (this._ssh) {
|
||||||
this._ssh.close();
|
|
||||||
this._ssh.closeTunnel();
|
this._ssh.closeTunnel();
|
||||||
|
this._ssh.close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -300,6 +302,8 @@ export class MySQLClient extends BaseClient {
|
|||||||
await this.connect();
|
await this.connect();
|
||||||
return this.getConnection(args, true);
|
return this.getConnection(args, true);
|
||||||
}
|
}
|
||||||
|
else if (error instanceof AggregateError)
|
||||||
|
throw new Error(error.errors.reduce((acc, curr) => acc +' | '+ curr.message, ''));
|
||||||
else
|
else
|
||||||
throw new Error(error.message);
|
throw new Error(error.message);
|
||||||
}
|
}
|
||||||
@@ -1753,9 +1757,7 @@ export class MySQLClient extends BaseClient {
|
|||||||
const resultsArr: antares.QueryResult[] = [];
|
const resultsArr: antares.QueryResult[] = [];
|
||||||
let paramsArr = [];
|
let paramsArr = [];
|
||||||
const queries = args.split
|
const queries = args.split
|
||||||
? sql.split(/((?:[^;'"]*(?:"(?:\\.|[^"])*"|'(?:\\.|[^'])*')[^;'"]*)+)|;/gm)
|
? this._querySplitter(sql, 'mysql')
|
||||||
.filter(Boolean)
|
|
||||||
.map(q => q.trim())
|
|
||||||
: [sql];
|
: [sql];
|
||||||
|
|
||||||
const connection = await this.getConnection(args);
|
const connection = await this.getConnection(args);
|
||||||
|
@@ -179,7 +179,7 @@ export class PostgreSQLClient extends BaseClient {
|
|||||||
remotePort: this._params.port
|
remotePort: this._params.port
|
||||||
});
|
});
|
||||||
|
|
||||||
dbConfig.host = (this._ssh.config as SSHConfig[] & { host: string }).host;
|
dbConfig.host = undefined;
|
||||||
dbConfig.port = tunnel.localPort;
|
dbConfig.port = tunnel.localPort;
|
||||||
}
|
}
|
||||||
catch (err) {
|
catch (err) {
|
||||||
@@ -348,7 +348,7 @@ export class PostgreSQLClient extends BaseClient {
|
|||||||
matviewowner AS owner,
|
matviewowner AS owner,
|
||||||
ispopulated AS is_populated,
|
ispopulated AS is_populated,
|
||||||
definition,
|
definition,
|
||||||
'materializedview' AS table_type
|
'materializedView' AS table_type
|
||||||
FROM pg_matviews
|
FROM pg_matviews
|
||||||
WHERE schemaname = '${db.database}'
|
WHERE schemaname = '${db.database}'
|
||||||
ORDER BY schema_name,
|
ORDER BY schema_name,
|
||||||
@@ -408,8 +408,8 @@ export class PostgreSQLClient extends BaseClient {
|
|||||||
name: table.table_name,
|
name: table.table_name,
|
||||||
type: table.table_type === 'VIEW'
|
type: table.table_type === 'VIEW'
|
||||||
? 'view'
|
? 'view'
|
||||||
: table.table_type === 'materializedview'
|
: table.table_type === 'materializedView'
|
||||||
? 'materializedview'
|
? 'materializedView'
|
||||||
: 'table',
|
: 'table',
|
||||||
rows: table.reltuples,
|
rows: table.reltuples,
|
||||||
size: tableSize,
|
size: tableSize,
|
||||||
@@ -466,7 +466,7 @@ export class PostgreSQLClient extends BaseClient {
|
|||||||
procedures: remappedProcedures,
|
procedures: remappedProcedures,
|
||||||
triggers: remappedTriggers,
|
triggers: remappedTriggers,
|
||||||
triggerFunctions: remappedTriggerFunctions,
|
triggerFunctions: remappedTriggerFunctions,
|
||||||
schedulers: []
|
schedulers: [] as null[]
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@@ -532,7 +532,7 @@ export class PostgreSQLClient extends BaseClient {
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
name: field.column_name,
|
name: field.column_name,
|
||||||
key: null,
|
key: null as null,
|
||||||
type: type.toUpperCase(),
|
type: type.toUpperCase(),
|
||||||
isArray,
|
isArray,
|
||||||
schema: field.table_schema,
|
schema: field.table_schema,
|
||||||
@@ -542,14 +542,14 @@ export class PostgreSQLClient extends BaseClient {
|
|||||||
datePrecision: field.datetime_precision,
|
datePrecision: field.datetime_precision,
|
||||||
charLength: field.character_maximum_length,
|
charLength: field.character_maximum_length,
|
||||||
nullable: field.is_nullable.includes('YES'),
|
nullable: field.is_nullable.includes('YES'),
|
||||||
unsigned: null,
|
unsigned: null as null,
|
||||||
zerofill: null,
|
zerofill: null as null,
|
||||||
order: field.ordinal_position,
|
order: field.ordinal_position,
|
||||||
default: field.column_default,
|
default: field.column_default,
|
||||||
charset: field.character_set_name,
|
charset: field.character_set_name,
|
||||||
collation: field.collation_name,
|
collation: field.collation_name,
|
||||||
autoIncrement: false,
|
autoIncrement: false,
|
||||||
onUpdate: null,
|
onUpdate: null as null,
|
||||||
comment: field.column_comment
|
comment: field.column_comment
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
@@ -1252,9 +1252,9 @@ export class PostgreSQLClient extends BaseClient {
|
|||||||
return results.rows.map(async row => {
|
return results.rows.map(async row => {
|
||||||
if (!row.pg_get_functiondef) {
|
if (!row.pg_get_functiondef) {
|
||||||
return {
|
return {
|
||||||
definer: null,
|
definer: null as null,
|
||||||
sql: '',
|
sql: '',
|
||||||
parameters: [],
|
parameters: [] as null[],
|
||||||
name: routine,
|
name: routine,
|
||||||
comment: '',
|
comment: '',
|
||||||
security: 'DEFINER',
|
security: 'DEFINER',
|
||||||
@@ -1303,8 +1303,8 @@ export class PostgreSQLClient extends BaseClient {
|
|||||||
name: routine,
|
name: routine,
|
||||||
comment: '',
|
comment: '',
|
||||||
security: row.pg_get_functiondef.includes('SECURITY DEFINER') ? 'DEFINER' : 'INVOKER',
|
security: row.pg_get_functiondef.includes('SECURITY DEFINER') ? 'DEFINER' : 'INVOKER',
|
||||||
deterministic: null,
|
deterministic: null as null,
|
||||||
dataAccess: null,
|
dataAccess: null as null,
|
||||||
language: row.pg_get_functiondef.match(/(?<=LANGUAGE )(.*)(?<=[\S+\n\r\s])/gm)[0]
|
language: row.pg_get_functiondef.match(/(?<=LANGUAGE )(.*)(?<=[\S+\n\r\s])/gm)[0]
|
||||||
};
|
};
|
||||||
})[0];
|
})[0];
|
||||||
@@ -1368,9 +1368,9 @@ export class PostgreSQLClient extends BaseClient {
|
|||||||
return results.rows.map(async row => {
|
return results.rows.map(async row => {
|
||||||
if (!row.pg_get_functiondef) {
|
if (!row.pg_get_functiondef) {
|
||||||
return {
|
return {
|
||||||
definer: null,
|
definer: null as null,
|
||||||
sql: '',
|
sql: '',
|
||||||
parameters: [],
|
parameters: [] as null[],
|
||||||
name: func,
|
name: func,
|
||||||
comment: '',
|
comment: '',
|
||||||
security: 'DEFINER',
|
security: 'DEFINER',
|
||||||
@@ -1418,8 +1418,8 @@ export class PostgreSQLClient extends BaseClient {
|
|||||||
name: func,
|
name: func,
|
||||||
comment: '',
|
comment: '',
|
||||||
security: row.pg_get_functiondef.includes('SECURITY DEFINER') ? 'DEFINER' : 'INVOKER',
|
security: row.pg_get_functiondef.includes('SECURITY DEFINER') ? 'DEFINER' : 'INVOKER',
|
||||||
deterministic: null,
|
deterministic: null as null,
|
||||||
dataAccess: null,
|
dataAccess: null as null,
|
||||||
language: row.pg_get_functiondef.match(/(?<=LANGUAGE )(.*)(?<=[\S+\n\r\s])/gm)[0],
|
language: row.pg_get_functiondef.match(/(?<=LANGUAGE )(.*)(?<=[\S+\n\r\s])/gm)[0],
|
||||||
returns: row.pg_get_functiondef.match(/(?<=RETURNS )(.*)(?<=[\S+\n\r\s])/gm)[0].replace('SETOF ', '').toUpperCase()
|
returns: row.pg_get_functiondef.match(/(?<=RETURNS )(.*)(?<=[\S+\n\r\s])/gm)[0].replace('SETOF ', '').toUpperCase()
|
||||||
};
|
};
|
||||||
@@ -1665,9 +1665,7 @@ export class PostgreSQLClient extends BaseClient {
|
|||||||
const resultsArr: antares.QueryResult[] = [];
|
const resultsArr: antares.QueryResult[] = [];
|
||||||
let paramsArr = [];
|
let paramsArr = [];
|
||||||
const queries = args.split
|
const queries = args.split
|
||||||
? sql.split(/(?!\B'[^']*);(?![^']*'\B)/gm)
|
? this._querySplitter(sql, 'pg')
|
||||||
.filter(Boolean)
|
|
||||||
.map(q => q.trim())
|
|
||||||
: [sql];
|
: [sql];
|
||||||
|
|
||||||
let connection: pg.Client | pg.PoolClient;
|
let connection: pg.Client | pg.PoolClient;
|
||||||
|
@@ -124,10 +124,10 @@ export class SQLiteClient extends BaseClient {
|
|||||||
name: db.name,
|
name: db.name,
|
||||||
size: schemaSize,
|
size: schemaSize,
|
||||||
tables: remappedTables,
|
tables: remappedTables,
|
||||||
functions: [],
|
functions: [] as null[],
|
||||||
procedures: [],
|
procedures: [] as null[],
|
||||||
triggers: remappedTriggers,
|
triggers: remappedTriggers,
|
||||||
schedulers: []
|
schedulers: [] as null[]
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@@ -166,22 +166,22 @@ export class SQLiteClient extends BaseClient {
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
name: field.name,
|
name: field.name,
|
||||||
key: null,
|
key: null as null,
|
||||||
type: type.trim(),
|
type: type.trim(),
|
||||||
schema: schema,
|
schema: schema,
|
||||||
table: table,
|
table: table,
|
||||||
numLength: [...NUMBER, ...FLOAT].includes(type) ? length : null,
|
numLength: [...NUMBER, ...FLOAT].includes(type) ? length : null,
|
||||||
datePrecision: null,
|
datePrecision: null as null,
|
||||||
charLength: ![...NUMBER, ...FLOAT].includes(type) ? length : null,
|
charLength: ![...NUMBER, ...FLOAT].includes(type) ? length : null,
|
||||||
nullable: !field.notnull,
|
nullable: !field.notnull,
|
||||||
unsigned: null,
|
unsigned: null as null,
|
||||||
zerofill: null,
|
zerofill: null as null,
|
||||||
order: typeof field.cid === 'string' ? +field.cid + 1 : field.cid + 1,
|
order: typeof field.cid === 'string' ? +field.cid + 1 : field.cid + 1,
|
||||||
default: field.dflt_value,
|
default: field.dflt_value,
|
||||||
charset: null,
|
charset: null as null,
|
||||||
collation: null,
|
collation: null as null,
|
||||||
autoIncrement: false,
|
autoIncrement: false,
|
||||||
onUpdate: null,
|
onUpdate: null as null,
|
||||||
comment: ''
|
comment: ''
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
@@ -267,7 +267,7 @@ export class SQLiteClient extends BaseClient {
|
|||||||
table: table,
|
table: table,
|
||||||
field: field.from,
|
field: field.from,
|
||||||
position: field.id + 1,
|
position: field.id + 1,
|
||||||
constraintPosition: null,
|
constraintPosition: null as null,
|
||||||
constraintName: field.id,
|
constraintName: field.id,
|
||||||
refSchema: schema,
|
refSchema: schema,
|
||||||
refTable: field.table,
|
refTable: field.table,
|
||||||
@@ -629,9 +629,7 @@ export class SQLiteClient extends BaseClient {
|
|||||||
const resultsArr = [];
|
const resultsArr = [];
|
||||||
let paramsArr = [];
|
let paramsArr = [];
|
||||||
const queries = args.split
|
const queries = args.split
|
||||||
? sql.split(/((?:[^;'"]*(?:"(?:\\.|[^"])*"|'(?:\\.|[^'])*')[^;'"]*)+)|;/gm)
|
? this._querySplitter(sql, 'sqlite')
|
||||||
.filter(Boolean)
|
|
||||||
.map(q => q.trim())
|
|
||||||
: [sql];
|
: [sql];
|
||||||
|
|
||||||
let connection: sqlite.Database;
|
let connection: sqlite.Database;
|
||||||
|
20
src/main/libs/misc/ipcLogger.ts
Normal file
20
src/main/libs/misc/ipcLogger.ts
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
export type LoggerLevel = 'query' | 'error'
|
||||||
|
|
||||||
|
export const ipcLogger = ({ content, cUid, level }: {content: string; cUid: string; level: LoggerLevel}) => {
|
||||||
|
if (level === 'error') {
|
||||||
|
if (process.type !== undefined) {
|
||||||
|
const mainWindow = require('electron').webContents.fromId(1);
|
||||||
|
mainWindow.send('non-blocking-exception', { cUid, message: content, date: new Date() });
|
||||||
|
}
|
||||||
|
if (process.env.NODE_ENV === 'development' && process.type === 'browser') console.log(content);
|
||||||
|
}
|
||||||
|
else if (level === 'query') {
|
||||||
|
// Remove comments, newlines and multiple spaces
|
||||||
|
const escapedSql = content.replace(/(\/\*(.|[\r\n])*?\*\/)|(--(.*|[\r\n]))/gm, '').replace(/\s\s+/g, ' ');
|
||||||
|
if (process.type !== undefined) {
|
||||||
|
const mainWindow = require('electron').webContents.fromId(1);
|
||||||
|
mainWindow.send('query-log', { cUid, sql: escapedSql, date: new Date() });
|
||||||
|
}
|
||||||
|
if (process.env.NODE_ENV === 'development' && process.type === 'browser') console.log(escapedSql);
|
||||||
|
}
|
||||||
|
};
|
@@ -43,7 +43,8 @@ async function createMainWindow () {
|
|||||||
spellcheck: false
|
spellcheck: false
|
||||||
},
|
},
|
||||||
autoHideMenuBar: true,
|
autoHideMenuBar: true,
|
||||||
titleBarStyle: isLinux ? 'default' :'hidden',
|
frame: !isLinux,
|
||||||
|
titleBarStyle: 'hidden',
|
||||||
titleBarOverlay: isWindows
|
titleBarOverlay: isWindows
|
||||||
? {
|
? {
|
||||||
color: appTheme === 'dark' ? '#3f3f3f' : '#fff',
|
color: appTheme === 'dark' ? '#3f3f3f' : '#fff',
|
||||||
@@ -127,15 +128,25 @@ app.on('ready', async () => {
|
|||||||
if (isWindows)
|
if (isWindows)
|
||||||
mainWindow.show();
|
mainWindow.show();
|
||||||
|
|
||||||
if (isDevelopment && !isWindows)// Because on Windows you can open devtools from title-bar
|
// if (isDevelopment && !isWindows)
|
||||||
mainWindow.webContents.openDevTools();
|
// mainWindow.webContents.openDevTools();
|
||||||
|
|
||||||
process.on('uncaughtException', error => {
|
process.on('uncaughtException', error => {
|
||||||
mainWindow.webContents.send('unhandled-exception', error);
|
if (error instanceof AggregateError) {
|
||||||
|
for (const e of error.errors)
|
||||||
|
mainWindow.webContents.send('unhandled-exception', e);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
mainWindow.webContents.send('unhandled-exception', error);
|
||||||
});
|
});
|
||||||
|
|
||||||
process.on('unhandledRejection', error => {
|
process.on('unhandledRejection', error => {
|
||||||
mainWindow.webContents.send('unhandled-exception', error);
|
if (error instanceof AggregateError) {
|
||||||
|
for (const e of error.errors)
|
||||||
|
mainWindow.webContents.send('unhandled-exception', e);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
mainWindow.webContents.send('unhandled-exception', error);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@@ -39,11 +39,11 @@ const props = defineProps({
|
|||||||
default: () => 'mdi'
|
default: () => 'mdi'
|
||||||
},
|
},
|
||||||
flip: {
|
flip: {
|
||||||
type: String as PropType<'horizontal' | 'vertical' | 'both'>,
|
type: String as PropType<'horizontal' | 'vertical' | 'both' | null>,
|
||||||
default: () => null
|
default: () => null
|
||||||
},
|
},
|
||||||
rotate: {
|
rotate: {
|
||||||
type: Number,
|
type: Number as PropType<number | null>,
|
||||||
default: () => null
|
default: () => null
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -55,8 +55,7 @@ const iconPath = computed(() => {
|
|||||||
const base64 = getIconByUid(props.iconName)?.base64;
|
const base64 = getIconByUid(props.iconName)?.base64;
|
||||||
const svgString = Buffer
|
const svgString = Buffer
|
||||||
.from(base64, 'base64')
|
.from(base64, 'base64')
|
||||||
.toString('utf-8')
|
.toString('utf-8');
|
||||||
.replaceAll(/width="[^"]*"|height="[^"]*"/g, '');
|
|
||||||
|
|
||||||
return svgString;
|
return svgString;
|
||||||
}
|
}
|
||||||
|
@@ -21,7 +21,23 @@
|
|||||||
<a class="tab-link" @click="selectedTab = 'debug'">{{ t('application.debugConsole') }}</a>
|
<a class="tab-link" @click="selectedTab = 'debug'">{{ t('application.debugConsole') }}</a>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
<button class="btn btn-clear mr-1" @click="resizeConsole(0)" />
|
<div class="d-flex">
|
||||||
|
<div
|
||||||
|
v-if="isDevelopment"
|
||||||
|
class="c-hand mr-2"
|
||||||
|
@click="openDevTools()"
|
||||||
|
>
|
||||||
|
<BaseIcon icon-name="mdiBugPlayOutline" :size="22" />
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
v-if="isDevelopment"
|
||||||
|
class="c-hand mr-2"
|
||||||
|
@click="reload()"
|
||||||
|
>
|
||||||
|
<BaseIcon icon-name="mdiRefresh" :size="22" />
|
||||||
|
</div>
|
||||||
|
<button class="btn btn-clear mr-1" @click="resizeConsole(0)" />
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
v-show="selectedTab === 'query'"
|
v-show="selectedTab === 'query'"
|
||||||
@@ -71,6 +87,7 @@
|
|||||||
</BaseContextMenu>
|
</BaseContextMenu>
|
||||||
</template>
|
</template>
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
|
import { getCurrentWindow } from '@electron/remote';
|
||||||
import * as moment from 'moment';
|
import * as moment from 'moment';
|
||||||
import { storeToRefs } from 'pinia';
|
import { storeToRefs } from 'pinia';
|
||||||
import { highlight } from 'sql-highlight';
|
import { highlight } from 'sql-highlight';
|
||||||
@@ -112,6 +129,8 @@ const isHover = ref(false);
|
|||||||
const isContext = ref(false);
|
const isContext = ref(false);
|
||||||
const contextContent: Ref<string> = ref(null);
|
const contextContent: Ref<string> = ref(null);
|
||||||
const contextEvent: Ref<MouseEvent> = ref(null);
|
const contextEvent: Ref<MouseEvent> = ref(null);
|
||||||
|
const w = ref(getCurrentWindow());
|
||||||
|
const isDevelopment = ref(process.env.NODE_ENV === 'development');
|
||||||
|
|
||||||
const resize = (e: MouseEvent) => {
|
const resize = (e: MouseEvent) => {
|
||||||
const el = queryConsole.value;
|
const el = queryConsole.value;
|
||||||
@@ -142,6 +161,14 @@ const copyLog = () => {
|
|||||||
isContext.value = false;
|
isContext.value = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const openDevTools = () => {
|
||||||
|
w.value.webContents.openDevTools();
|
||||||
|
};
|
||||||
|
|
||||||
|
const reload = () => {
|
||||||
|
w.value.reload();
|
||||||
|
};
|
||||||
|
|
||||||
watch(workspaceQueryLogs, async () => {
|
watch(workspaceQueryLogs, async () => {
|
||||||
if (!isHover.value) {
|
if (!isHover.value) {
|
||||||
await nextTick();
|
await nextTick();
|
||||||
|
@@ -127,7 +127,7 @@ const fakerGroups = computed(() => {
|
|||||||
localType.value = 'datetime';
|
localType.value = 'datetime';
|
||||||
else if (TIME.includes(props.type))
|
else if (TIME.includes(props.type))
|
||||||
localType.value = 'time';
|
localType.value = 'time';
|
||||||
else if (UUID.includes(props.type))
|
else if (UUID.includes(props.type) || (BLOB.includes(props.type) && props.field.key === 'pri'))
|
||||||
localType.value = 'uuid';
|
localType.value = 'uuid';
|
||||||
else
|
else
|
||||||
localType.value = 'none';
|
localType.value = 'none';
|
||||||
@@ -177,7 +177,7 @@ const inputProps = () => {
|
|||||||
return { type: 'text', mask: datetimeMask };
|
return { type: 'text', mask: datetimeMask };
|
||||||
}
|
}
|
||||||
|
|
||||||
if (BLOB.includes(props.type))
|
if (BLOB.includes(props.type) && props.field.key !== 'pri')
|
||||||
return { type: 'file', mask: false };
|
return { type: 'file', mask: false };
|
||||||
|
|
||||||
if (BIT.includes(props.type))
|
if (BIT.includes(props.type))
|
||||||
|
@@ -131,8 +131,10 @@ import Application from '@/ipc-api/Application';
|
|||||||
import { camelize } from '@/libs/camelize';
|
import { camelize } from '@/libs/camelize';
|
||||||
import { unproxify } from '@/libs/unproxify';
|
import { unproxify } from '@/libs/unproxify';
|
||||||
import { SidebarElement, useConnectionsStore } from '@/stores/connections';
|
import { SidebarElement, useConnectionsStore } from '@/stores/connections';
|
||||||
|
import { useNotificationsStore } from '@/stores/notifications';
|
||||||
|
|
||||||
const connectionsStore = useConnectionsStore();
|
const connectionsStore = useConnectionsStore();
|
||||||
|
const { addNotification } = useNotificationsStore();
|
||||||
|
|
||||||
const { addIcon, removeIcon, updateConnectionOrder, getConnectionName } = connectionsStore;
|
const { addIcon, removeIcon, updateConnectionOrder, getConnectionName } = connectionsStore;
|
||||||
const { customIcons } = storeToRefs(connectionsStore);
|
const { customIcons } = storeToRefs(connectionsStore);
|
||||||
@@ -225,12 +227,56 @@ const removeIconHandler = () => {
|
|||||||
isContext.value = false;
|
isContext.value = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const adjustSVGContent = (svgContent: string) => {
|
||||||
|
try {
|
||||||
|
const parser = new DOMParser();
|
||||||
|
const doc = parser.parseFromString(svgContent, 'image/svg+xml');
|
||||||
|
|
||||||
|
const parseError = doc.querySelector('parsererror');
|
||||||
|
if (parseError) {
|
||||||
|
addNotification({ status: 'error', message: parseError.textContent });
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
const svg = doc.documentElement;
|
||||||
|
if (svg.tagName.toLowerCase() !== 'svg') {
|
||||||
|
addNotification({ status: 'error', message: t('application.invalidFIle') });
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!svg.hasAttribute('viewBox')) {
|
||||||
|
const width = svg.getAttribute('width') || '36';
|
||||||
|
const height = svg.getAttribute('height') || '36';
|
||||||
|
svg.setAttribute('viewBox', `0 0 ${width} ${height}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
svg.removeAttribute('width');
|
||||||
|
svg.removeAttribute('height');
|
||||||
|
|
||||||
|
const serializer = new XMLSerializer();
|
||||||
|
return serializer.serializeToString(svg);
|
||||||
|
}
|
||||||
|
catch (error) {
|
||||||
|
addNotification({ status: 'error', message: error.stack });
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const openFile = async () => {
|
const openFile = async () => {
|
||||||
const result = await Application.showOpenDialog({ properties: ['openFile'], filters: [{ name: '"SVG"', extensions: ['svg'] }] });
|
const result = await Application.showOpenDialog({
|
||||||
|
properties: ['openFile'],
|
||||||
|
filters: [{ name: '"SVG"', extensions: ['svg'] }]
|
||||||
|
});
|
||||||
|
|
||||||
if (result && !result.canceled) {
|
if (result && !result.canceled) {
|
||||||
const file = result.filePaths[0];
|
const file = result.filePaths[0];
|
||||||
const content = await Application.readFile({ filePath: file, encoding: 'base64url' });
|
let content = await Application.readFile({ filePath: file, encoding: 'utf-8' });
|
||||||
addIcon(content);
|
|
||||||
|
content = adjustSVGContent(content);
|
||||||
|
|
||||||
|
const base64Content = Buffer.from(content).toString('base64');
|
||||||
|
|
||||||
|
addIcon(base64Content);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -339,6 +339,8 @@ onMounted(() => {
|
|||||||
for (const field of props.fields) {
|
for (const field of props.fields) {
|
||||||
if (typeof props.rowToDuplicate[field.name] !== 'object')
|
if (typeof props.rowToDuplicate[field.name] !== 'object')
|
||||||
rowObj[field.name] = { value: props.rowToDuplicate[field.name] };
|
rowObj[field.name] = { value: props.rowToDuplicate[field.name] };
|
||||||
|
else if (field.type === 'JSON')
|
||||||
|
rowObj[field.name] = { value: JSON.stringify(props.rowToDuplicate[field.name]) };
|
||||||
|
|
||||||
if (field.autoIncrement || !!field.onUpdate)// Disable by default auto increment or "on update" fields
|
if (field.autoIncrement || !!field.onUpdate)// Disable by default auto increment or "on update" fields
|
||||||
fieldsToExclude.value = [...fieldsToExclude.value, field.name];
|
fieldsToExclude.value = [...fieldsToExclude.value, field.name];
|
||||||
|
@@ -42,7 +42,7 @@
|
|||||||
tabindex="0"
|
tabindex="0"
|
||||||
>
|
>
|
||||||
<div class="td py-1">
|
<div class="td py-1">
|
||||||
{{ t(shortcutEvents[shortcut.event].l18n, {param: shortcutEvents[shortcut.event].l18nParam}) }}
|
{{ t(shortcutEvents[shortcut.event].i18n, {param: shortcutEvents[shortcut.event].i18nParam}) }}
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="td py-1"
|
class="td py-1"
|
||||||
@@ -167,7 +167,7 @@
|
|||||||
</template>
|
</template>
|
||||||
<template #body>
|
<template #body>
|
||||||
<div class="mb-2">
|
<div class="mb-2">
|
||||||
{{ t('general.deleteConfirm') }} <b>{{ t(shortcutEvents[shortcutToDelete.event].l18n, {param: shortcutEvents[shortcutToDelete.event].l18nParam}) }} (<span v-html="parseKeys(shortcutToDelete.keys)" />)</b>?
|
{{ t('general.deleteConfirm') }} <b>{{ t(shortcutEvents[shortcutToDelete.event].i18n, {param: shortcutEvents[shortcutToDelete.event].i18nParam}) }} (<span v-html="parseKeys(shortcutToDelete.keys)" />)</b>?
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</ConfirmModal>
|
</ConfirmModal>
|
||||||
@@ -233,7 +233,7 @@ const { shortcuts } = storeToRefs(settingsStore);
|
|||||||
const eventOptions = computed(() => {
|
const eventOptions = computed(() => {
|
||||||
return Object.keys(shortcutEvents)
|
return Object.keys(shortcutEvents)
|
||||||
.map(key => {
|
.map(key => {
|
||||||
return { value: key, label: t(shortcutEvents[key].l18n, { param: shortcutEvents[key].l18nParam }) };
|
return { value: key, label: t(shortcutEvents[key].i18n, { param: shortcutEvents[key].i18nParam }) };
|
||||||
})
|
})
|
||||||
.sort((a, b) => {
|
.sort((a, b) => {
|
||||||
if (a.label < b.label) return -1;
|
if (a.label < b.label) return -1;
|
||||||
|
@@ -47,65 +47,50 @@
|
|||||||
<div class="tile-history-buttons">
|
<div class="tile-history-buttons">
|
||||||
<button
|
<button
|
||||||
v-if="note.type === 'todo' && !note.isArchived"
|
v-if="note.type === 'todo' && !note.isArchived"
|
||||||
class="btn btn-link pl-1"
|
class="btn btn-dark tooltip tooltip-left"
|
||||||
|
:data-tooltip="t('general.archive')"
|
||||||
@click.stop="$emit('archive-note', note.uid)"
|
@click.stop="$emit('archive-note', note.uid)"
|
||||||
>
|
>
|
||||||
<BaseIcon
|
<BaseIcon icon-name="mdiCheck" :size="22" />
|
||||||
icon-name="mdiCheck"
|
|
||||||
class="pr-1"
|
|
||||||
:size="22"
|
|
||||||
/> {{ t('general.archive') }}
|
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
v-if="note.type === 'todo' && note.isArchived"
|
v-if="note.type === 'todo' && note.isArchived"
|
||||||
class="btn btn-link pl-1"
|
class="btn btn-dark tooltip tooltip-left"
|
||||||
|
:data-tooltip="t('general.undo')"
|
||||||
@click.stop="$emit('restore-note', note.uid)"
|
@click.stop="$emit('restore-note', note.uid)"
|
||||||
>
|
>
|
||||||
<BaseIcon
|
<BaseIcon icon-name="mdiRestore" :size="22" />
|
||||||
icon-name="mdiRestore"
|
|
||||||
class="pr-1"
|
|
||||||
:size="22"
|
|
||||||
/> {{ t('general.undo') }}
|
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
v-if="note.type === 'query'"
|
v-if="note.type === 'query'"
|
||||||
class="btn btn-link pl-1"
|
class="btn btn-dark tooltip tooltip-left"
|
||||||
|
:data-tooltip="t('general.select')"
|
||||||
@click.stop="$emit('select-query', note.note)"
|
@click.stop="$emit('select-query', note.note)"
|
||||||
>
|
>
|
||||||
<BaseIcon
|
<BaseIcon icon-name="mdiOpenInApp" :size="22" />
|
||||||
icon-name="mdiOpenInApp"
|
|
||||||
class="pr-1"
|
|
||||||
:size="22"
|
|
||||||
/> {{ t('general.select') }}
|
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
v-if="note.type === 'query'"
|
v-if="note.type === 'query'"
|
||||||
class="btn btn-link pl-1"
|
class="btn btn-dark tooltip tooltip-left"
|
||||||
|
:data-tooltip="t('general.copy')"
|
||||||
@click.stop="copyText(note.note)"
|
@click.stop="copyText(note.note)"
|
||||||
>
|
>
|
||||||
<BaseIcon
|
<BaseIcon icon-name="mdiContentCopy" :size="18" />
|
||||||
icon-name="mdiContentCopy"
|
|
||||||
class="pr-1"
|
|
||||||
:size="22"
|
|
||||||
/> {{ t('general.copy') }}
|
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
v-if=" !note.isArchived"
|
v-if=" !note.isArchived"
|
||||||
class="btn btn-link pl-1"
|
class="btn btn-dark tooltip tooltip-left"
|
||||||
|
:data-tooltip="t('general.edit')"
|
||||||
@click.stop="$emit('edit-note')"
|
@click.stop="$emit('edit-note')"
|
||||||
>
|
>
|
||||||
<BaseIcon
|
<BaseIcon icon-name="mdiPencil" :size="22" />
|
||||||
icon-name="mdiPencil"
|
|
||||||
class="pr-1"
|
|
||||||
:size="22"
|
|
||||||
/> {{ t('general.edit') }}
|
|
||||||
</button>
|
</button>
|
||||||
<button class="btn btn-link pl-1" @click.stop="$emit('delete-note', note.uid)">
|
<button
|
||||||
<BaseIcon
|
class="btn btn-dark tooltip tooltip-left"
|
||||||
icon-name="mdiDeleteForever"
|
:data-tooltip="t('general.delete')"
|
||||||
class="pr-1"
|
@click.stop="$emit('delete-note', note.uid)"
|
||||||
:size="22"
|
>
|
||||||
/> {{ t('general.delete') }}
|
<BaseIcon icon-name="mdiDeleteForever" :size="22" />
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -278,11 +263,14 @@ const highlightWord = (string: string) => {
|
|||||||
|
|
||||||
button {
|
button {
|
||||||
font-size: 0.7rem;
|
font-size: 0.7rem;
|
||||||
height: 1rem;
|
|
||||||
line-height: 1rem;
|
line-height: 1rem;
|
||||||
display: inline-flex;
|
display: inline-flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
|
margin: 0 5px;
|
||||||
|
padding: 0;
|
||||||
|
height: 24px;
|
||||||
|
width: 24px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,6 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<div
|
<div
|
||||||
v-if="!isLinux"
|
|
||||||
id="titlebar"
|
id="titlebar"
|
||||||
@dblclick="toggleFullScreen"
|
@dblclick="toggleFullScreen"
|
||||||
>
|
>
|
||||||
@@ -21,16 +20,27 @@
|
|||||||
class="titlebar-element"
|
class="titlebar-element"
|
||||||
@click="openDevTools"
|
@click="openDevTools"
|
||||||
>
|
>
|
||||||
<BaseIcon icon-name="mdiBugPlayOutline" :size="24" />
|
<BaseIcon icon-name="mdiBugPlayOutline" :size="18" />
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
v-if="isDevelopment"
|
v-if="isDevelopment"
|
||||||
class="titlebar-element"
|
class="titlebar-element"
|
||||||
@click="reload"
|
@click="reload"
|
||||||
>
|
>
|
||||||
<BaseIcon icon-name="mdiRefresh" :size="24" />
|
<BaseIcon icon-name="mdiRefresh" :size="18" />
|
||||||
</div>
|
</div>
|
||||||
<div v-if="isWindows" :style="'width: 140px;'" />
|
<div v-if="isWindows" :style="'width: 140px;'" />
|
||||||
|
<div v-if="isLinux" class="d-flex">
|
||||||
|
<div class="titlebar-element" @click="minimize">
|
||||||
|
<BaseIcon icon-name="mdiWindowMinimize" :size="18" />
|
||||||
|
</div>
|
||||||
|
<div class="titlebar-element" @click="toggleFullScreen">
|
||||||
|
<BaseIcon :icon-name="isMaximized ? 'mdiWindowRestore' : 'mdiWindowMaximize'" :size="18" />
|
||||||
|
</div>
|
||||||
|
<div class="titlebar-element" @click="closeApp">
|
||||||
|
<BaseIcon icon-name="mdiClose" :size="18" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@@ -74,6 +84,18 @@ const windowTitle = computed(() => {
|
|||||||
return [connectionName, ...breadcrumbs].join(' • ');
|
return [connectionName, ...breadcrumbs].join(' • ');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const openDevTools = () => {
|
||||||
|
w.value.webContents.openDevTools();
|
||||||
|
};
|
||||||
|
|
||||||
|
const reload = () => {
|
||||||
|
w.value.reload();
|
||||||
|
};
|
||||||
|
|
||||||
|
const minimize = () => {
|
||||||
|
w.value.minimize();
|
||||||
|
};
|
||||||
|
|
||||||
const toggleFullScreen = () => {
|
const toggleFullScreen = () => {
|
||||||
if (isMaximized.value)
|
if (isMaximized.value)
|
||||||
w.value.unmaximize();
|
w.value.unmaximize();
|
||||||
@@ -81,12 +103,8 @@ const toggleFullScreen = () => {
|
|||||||
w.value.maximize();
|
w.value.maximize();
|
||||||
};
|
};
|
||||||
|
|
||||||
const openDevTools = () => {
|
const closeApp = () => {
|
||||||
w.value.webContents.openDevTools();
|
ipcRenderer.send('close-app');
|
||||||
};
|
|
||||||
|
|
||||||
const reload = () => {
|
|
||||||
w.value.reload();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const onResize = () => {
|
const onResize = () => {
|
||||||
|
@@ -64,7 +64,7 @@
|
|||||||
>
|
>
|
||||||
<BaseIcon
|
<BaseIcon
|
||||||
class="mt-1 mr-1"
|
class="mt-1 mr-1"
|
||||||
:icon-name="['view', 'materializedview'].includes(element.elementType) ? 'mdiTableEye' : 'mdiTable'"
|
:icon-name="['view', 'materializedView'].includes(element.elementType) ? 'mdiTableEye' : 'mdiTable'"
|
||||||
:size="18"
|
:size="18"
|
||||||
/>
|
/>
|
||||||
<span :title="`${t('general.data').toUpperCase()}: ${t(`database.${element.elementType}`)}`">
|
<span :title="`${t('general.data').toUpperCase()}: ${t(`database.${element.elementType}`)}`">
|
||||||
@@ -81,7 +81,7 @@
|
|||||||
<a v-else-if="element.type === 'data'" class="tab-link">
|
<a v-else-if="element.type === 'data'" class="tab-link">
|
||||||
<BaseIcon
|
<BaseIcon
|
||||||
class="mt-1 mr-1"
|
class="mt-1 mr-1"
|
||||||
:icon-name="['view', 'materializedview'].includes(element.elementType) ? 'mdiTableEye' : 'mdiTable'"
|
:icon-name="['view', 'materializedView'].includes(element.elementType) ? 'mdiTableEye' : 'mdiTable'"
|
||||||
:size="18"
|
:size="18"
|
||||||
/>
|
/>
|
||||||
<span :title="`${t('general.data').toUpperCase()}: ${t(`database.${element.elementType}`)}`">
|
<span :title="`${t('general.data').toUpperCase()}: ${t(`database.${element.elementType}`)}`">
|
||||||
|
@@ -143,7 +143,7 @@
|
|||||||
:selected-schema="selectedSchema"
|
:selected-schema="selectedSchema"
|
||||||
:context-event="miscContextEvent"
|
:context-event="miscContextEvent"
|
||||||
@open-create-view-tab="openCreateElementTab('view')"
|
@open-create-view-tab="openCreateElementTab('view')"
|
||||||
@open-create-materializedview-tab="openCreateElementTab('materialized-view')"
|
@open-create-materializedView-tab="openCreateElementTab('materialized-view')"
|
||||||
@open-create-trigger-tab="openCreateElementTab('trigger')"
|
@open-create-trigger-tab="openCreateElementTab('trigger')"
|
||||||
@open-create-trigger-function-tab="openCreateElementTab('trigger-function')"
|
@open-create-trigger-function-tab="openCreateElementTab('trigger-function')"
|
||||||
@open-create-routine-tab="openCreateElementTab('routine')"
|
@open-create-routine-tab="openCreateElementTab('routine')"
|
||||||
|
@@ -16,9 +16,9 @@
|
|||||||
/> {{ t('database.createNewView') }}</span>
|
/> {{ t('database.createNewView') }}</span>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
v-if="props.selectedMisc === 'materializedview'"
|
v-if="props.selectedMisc === 'materializedView'"
|
||||||
class="context-element"
|
class="context-element"
|
||||||
@click="emit('open-create-materializedview-tab')"
|
@click="emit('open-create-materializedView-tab')"
|
||||||
>
|
>
|
||||||
<span class="d-flex">
|
<span class="d-flex">
|
||||||
<BaseIcon
|
<BaseIcon
|
||||||
@@ -106,7 +106,7 @@ const props = defineProps({
|
|||||||
|
|
||||||
const emit = defineEmits([
|
const emit = defineEmits([
|
||||||
'open-create-view-tab',
|
'open-create-view-tab',
|
||||||
'open-create-materializedview-tab',
|
'open-create-materializedView-tab',
|
||||||
'open-create-trigger-tab',
|
'open-create-trigger-tab',
|
||||||
'open-create-routine-tab',
|
'open-create-routine-tab',
|
||||||
'open-create-function-tab',
|
'open-create-function-tab',
|
||||||
|
@@ -121,7 +121,7 @@
|
|||||||
<summary
|
<summary
|
||||||
class="accordion-header misc-name"
|
class="accordion-header misc-name"
|
||||||
:class="{'text-bold': breadcrumbs.schema === database.name && breadcrumbs.trigger}"
|
:class="{'text-bold': breadcrumbs.schema === database.name && breadcrumbs.trigger}"
|
||||||
@contextmenu.prevent="showMiscFolderContext($event, 'materializedview')"
|
@contextmenu.prevent="showMiscFolderContext($event, 'materializedView')"
|
||||||
>
|
>
|
||||||
<BaseIcon
|
<BaseIcon
|
||||||
class="misc-icon mr-1"
|
class="misc-icon mr-1"
|
||||||
@@ -133,7 +133,7 @@
|
|||||||
icon-name="mdiFolderOpen"
|
icon-name="mdiFolderOpen"
|
||||||
:size="18"
|
:size="18"
|
||||||
/>
|
/>
|
||||||
{{ t('database.materializedview', 2) }}
|
{{ t('database.materializedView', 2) }}
|
||||||
</summary>
|
</summary>
|
||||||
<div class="accordion-body">
|
<div class="accordion-body">
|
||||||
<div>
|
<div>
|
||||||
@@ -477,8 +477,12 @@ const searchTerm = computed(() => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
const filteredTables = computed(() => {
|
const filteredTables = computed(() => {
|
||||||
if (props.searchMethod === 'elements')
|
if (props.searchMethod === 'elements') {
|
||||||
return props.database.tables.filter(table => table.name.search(searchTerm.value) >= 0 && table.type === 'table');
|
const searchTermLower = searchTerm.value.toLowerCase();
|
||||||
|
return props.database.tables.filter(table =>
|
||||||
|
table.name.toLowerCase().includes(searchTermLower) && table.type === 'table'
|
||||||
|
);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
return props.database.tables;
|
return props.database.tables;
|
||||||
});
|
});
|
||||||
@@ -492,9 +496,9 @@ const filteredViews = computed(() => {
|
|||||||
|
|
||||||
const filteredMatViews = computed(() => {
|
const filteredMatViews = computed(() => {
|
||||||
if (props.searchMethod === 'elements')
|
if (props.searchMethod === 'elements')
|
||||||
return props.database.tables.filter(table => table.name.search(searchTerm.value) >= 0 && table.type === 'materializedview');
|
return props.database.tables.filter(table => table.name.search(searchTerm.value) >= 0 && table.type === 'materializedView');
|
||||||
else
|
else
|
||||||
return props.database.tables.filter(table => table.type === 'materializedview');
|
return props.database.tables.filter(table => table.type === 'materializedView');
|
||||||
});
|
});
|
||||||
|
|
||||||
const filteredTriggers = computed(() => {
|
const filteredTriggers = computed(() => {
|
||||||
|
@@ -50,7 +50,7 @@
|
|||||||
class="text-light mt-1 mr-1"
|
class="text-light mt-1 mr-1"
|
||||||
icon-name="mdiTableEye"
|
icon-name="mdiTableEye"
|
||||||
:size="18"
|
:size="18"
|
||||||
/> {{ t('database.materializedview') }}</span>
|
/> {{ t('database.materializedView') }}</span>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
v-if="workspace.customizations.triggerAdd"
|
v-if="workspace.customizations.triggerAdd"
|
||||||
|
@@ -48,7 +48,7 @@
|
|||||||
/> {{ t('application.settings') }}</span>
|
/> {{ t('application.settings') }}</span>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
v-if="selectedTable && selectedTable.type === 'materializedview' && customizations.materializedViewSettings"
|
v-if="selectedTable && selectedTable.type === 'materializedView' && customizations.materializedViewSettings"
|
||||||
class="context-element"
|
class="context-element"
|
||||||
@click="openMaterializedViewSettingTab"
|
@click="openMaterializedViewSettingTab"
|
||||||
>
|
>
|
||||||
|
@@ -195,7 +195,7 @@ const saveChanges = async () => {
|
|||||||
uid: props.connection.uid,
|
uid: props.connection.uid,
|
||||||
schema: props.schema,
|
schema: props.schema,
|
||||||
elementName: localView.value.name,
|
elementName: localView.value.name,
|
||||||
elementType: 'materializedview',
|
elementType: 'materializedView',
|
||||||
type: 'materialized-view-props'
|
type: 'materialized-view-props'
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@@ -227,7 +227,7 @@ const saveChanges = async () => {
|
|||||||
schema: props.schema,
|
schema: props.schema,
|
||||||
elementName: oldName,
|
elementName: oldName,
|
||||||
elementNewName: localView.value.name,
|
elementNewName: localView.value.name,
|
||||||
elementType: 'materializedview'
|
elementType: 'materializedView'
|
||||||
});
|
});
|
||||||
|
|
||||||
changeBreadcrumbs({ schema: props.schema, view: localView.value.name });
|
changeBreadcrumbs({ schema: props.schema, view: localView.value.name });
|
||||||
|
@@ -458,6 +458,8 @@ const getFieldsData = async () => {
|
|||||||
addNotification({ status: 'error', message: err.stack });
|
addNotification({ status: 'error', message: err.stack });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
isLoading.value = false;
|
||||||
|
|
||||||
if (workspace.value.customizations.tableCheck) {
|
if (workspace.value.customizations.tableCheck) {
|
||||||
try { // Table checks
|
try { // Table checks
|
||||||
const { status, response } = await Tables.getTableChecks(params);
|
const { status, response } = await Tables.getTableChecks(params);
|
||||||
@@ -478,8 +480,6 @@ const getFieldsData = async () => {
|
|||||||
addNotification({ status: 'error', message: err.stack });
|
addNotification({ status: 'error', message: err.stack });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
isLoading.value = false;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const saveChanges = async () => {
|
const saveChanges = async () => {
|
||||||
|
@@ -7,7 +7,7 @@
|
|||||||
:key="i"
|
:key="i"
|
||||||
class="mb-4"
|
class="mb-4"
|
||||||
>
|
>
|
||||||
{{ t(shortcutEvents[shortcut.event].l18n, {param: shortcutEvents[shortcut.event].l18nParam}) }}
|
{{ t(shortcutEvents[shortcut.event].i18n, {param: shortcutEvents[shortcut.event].i18nParam}) }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="column col-16">
|
<div class="column col-16">
|
||||||
|
@@ -538,7 +538,7 @@ const closeContext = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const showDeleteConfirmModal = (e: any) => {
|
const showDeleteConfirmModal = (e: any) => {
|
||||||
if (e.code !== 'Delete') return;
|
if (e && e.code !== 'Delete') return;
|
||||||
if (e && e.path && ['INPUT', 'TEXTAREA', 'SELECT'].includes(e.path[0].tagName))
|
if (e && e.path && ['INPUT', 'TEXTAREA', 'SELECT'].includes(e.path[0].tagName))
|
||||||
return;
|
return;
|
||||||
if (selectedRows.value.length === 0) return;
|
if (selectedRows.value.length === 0) return;
|
||||||
@@ -563,6 +563,7 @@ const deleteSelected = () => {
|
|||||||
table: getTable(resultsetIndex.value),
|
table: getTable(resultsetIndex.value),
|
||||||
rows
|
rows
|
||||||
};
|
};
|
||||||
|
console.log(params);
|
||||||
emit('delete-selected', params);
|
emit('delete-selected', params);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -696,15 +697,15 @@ const fillCell = (event: { name: string; group: string; type: string }) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fakeValue = (fakerCustom as any)[event.group][event.name]();
|
fakeValue = (fakerCustom as any)[event.group][event.name]();
|
||||||
if (['string', 'number'].includes(typeof fakeValue)) {
|
const isDateType = [...DATE, ...DATETIME].includes(selectedCell.value.type);
|
||||||
|
if (isDateType)
|
||||||
|
fakeValue = moment(fakeValue).format(`YYYY-MM-DD HH:mm:ss${datePrecision}`);
|
||||||
|
else if (['string', 'number'].includes(typeof fakeValue)) {
|
||||||
if (typeof fakeValue === 'number')
|
if (typeof fakeValue === 'number')
|
||||||
fakeValue = String(fakeValue);
|
fakeValue = String(fakeValue);
|
||||||
|
|
||||||
if (selectedCell.value.length)
|
if (selectedCell.value.length)
|
||||||
fakeValue = fakeValue.substring(0, selectedCell.value.length < 1024 ? Number(selectedCell.value.length) : 1024);
|
fakeValue = fakeValue.substring(0, selectedCell.value.length < 1024 ? Number(selectedCell.value.length) : 1024);
|
||||||
}
|
}
|
||||||
else if ([...DATE, ...DATETIME].includes(selectedCell.value.type))
|
|
||||||
fakeValue = moment(fakeValue).format(`YYYY-MM-DD HH:mm:ss${datePrecision}`);
|
|
||||||
else if (TIME.includes(selectedCell.value.type))
|
else if (TIME.includes(selectedCell.value.type))
|
||||||
fakeValue = moment(fakeValue).format(`HH:mm:ss${datePrecision}`);
|
fakeValue = moment(fakeValue).format(`HH:mm:ss${datePrecision}`);
|
||||||
|
|
||||||
|
@@ -440,7 +440,7 @@ const editON = async (field: string) => {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (BLOB.includes(type)) {
|
if (BLOB.includes(type) && props.fields[field].key !== 'pri') {
|
||||||
isBlobEditor.value = true;
|
isBlobEditor.value = true;
|
||||||
editingContent.value = content || '';
|
editingContent.value = content || '';
|
||||||
fileToUpload.value = null;
|
fileToUpload.value = null;
|
||||||
@@ -458,9 +458,12 @@ const editON = async (field: string) => {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
emit('start-editing', field);
|
emit('start-editing', field);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
else if (BLOB.includes(type) && props.fields[field].key === 'pri')// Disable edit on BLOB primary until we are sure it's not problematic
|
||||||
|
return;
|
||||||
|
|
||||||
// Inline editable fields
|
// Inline editable fields
|
||||||
editingContent.value = originalContent.value;
|
editingContent.value = originalContent.value;
|
||||||
|
@@ -56,10 +56,10 @@ export function useResultTables (uid: string, reloadTable: () => void) {
|
|||||||
if (status === 'success')
|
if (status === 'success')
|
||||||
reloadTable();
|
reloadTable();
|
||||||
else
|
else
|
||||||
this.addNotification({ status: 'error', message: response });
|
addNotification({ status: 'error', message: response });
|
||||||
}
|
}
|
||||||
catch (err) {
|
catch (err) {
|
||||||
this.addNotification({ status: 'error', message: err.stack });
|
addNotification({ status: 'error', message: err.stack });
|
||||||
isQuering.value = false;
|
isQuering.value = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -141,7 +141,7 @@ export const csCZ = {
|
|||||||
total: 'Celkem',
|
total: 'Celkem',
|
||||||
table: 'Tabulka | Tabulky',
|
table: 'Tabulka | Tabulky',
|
||||||
view: 'Pohled | Pohledy',
|
view: 'Pohled | Pohledy',
|
||||||
materializedview: 'Materializovaný pohled',
|
materializedView: 'Materializovaný pohled',
|
||||||
definer: 'Definér',
|
definer: 'Definér',
|
||||||
algorithm: 'Algoritmus',
|
algorithm: 'Algoritmus',
|
||||||
trigger: 'Trigger | Triggery',
|
trigger: 'Trigger | Triggery',
|
||||||
|
@@ -141,7 +141,7 @@ export const enUS = {
|
|||||||
total: 'Total',
|
total: 'Total',
|
||||||
table: 'Table | Tables',
|
table: 'Table | Tables',
|
||||||
view: 'View | Views',
|
view: 'View | Views',
|
||||||
materializedview: 'Materialized view | Materialized views',
|
materializedView: 'Materialized view | Materialized views',
|
||||||
definer: 'Definer',
|
definer: 'Definer',
|
||||||
algorithm: 'Algorithm',
|
algorithm: 'Algorithm',
|
||||||
trigger: 'Trigger | Triggers',
|
trigger: 'Trigger | Triggers',
|
||||||
@@ -401,6 +401,7 @@ export const enUS = {
|
|||||||
ignoreDuplicates: 'Ignore duplicates',
|
ignoreDuplicates: 'Ignore duplicates',
|
||||||
wrongImportPassword: 'Wrong import password',
|
wrongImportPassword: 'Wrong import password',
|
||||||
wrongFileFormat: 'Wrong file format',
|
wrongFileFormat: 'Wrong file format',
|
||||||
|
invalidFile: 'Invalid file',
|
||||||
dataImportSuccess: 'Data successfully imported',
|
dataImportSuccess: 'Data successfully imported',
|
||||||
note: 'Note | Notes',
|
note: 'Note | Notes',
|
||||||
thereAreNoNotesYet: 'There are no notes yet',
|
thereAreNoNotesYet: 'There are no notes yet',
|
||||||
@@ -416,7 +417,11 @@ export const enUS = {
|
|||||||
openNotes: 'Open notes',
|
openNotes: 'Open notes',
|
||||||
debugConsole: 'Debug console', // <- console tab name
|
debugConsole: 'Debug console', // <- console tab name
|
||||||
executedQueries: 'Executed queries', // <- console tab name
|
executedQueries: 'Executed queries', // <- console tab name
|
||||||
sizeLimitError: 'Maximum size of {size} exceeded'
|
sizeLimitError: 'Maximum size of {size} exceeded',
|
||||||
|
fullScreen: 'Full screen',
|
||||||
|
zoomIn: 'Zoom in',
|
||||||
|
zoomOut: 'Zoom out',
|
||||||
|
zoomReset: 'Reset zoom'
|
||||||
},
|
},
|
||||||
faker: { // Faker.js methods, used in random generated content
|
faker: { // Faker.js methods, used in random generated content
|
||||||
address: 'Address',
|
address: 'Address',
|
||||||
|
@@ -1,5 +1,14 @@
|
|||||||
|
/**
|
||||||
|
* [TRANSLATION UPDATE HELPER]
|
||||||
|
* - Open a terminal in antares folder and run `npm run translation:check short-code` replacing short-code with the one you are updating.
|
||||||
|
* - The command will output which terms are missing or not translated from english.
|
||||||
|
* - Open antares folder with your editor of choice.
|
||||||
|
* - Go to antares/src/renderer/i18n/ and open the locale file you want to translate.
|
||||||
|
* - Add and translate missing terms and consider whether to translate untranslated terms.
|
||||||
|
*/
|
||||||
|
|
||||||
export const esES = {
|
export const esES = {
|
||||||
general: {
|
general: { // General purpose terms
|
||||||
edit: 'Editar',
|
edit: 'Editar',
|
||||||
save: 'Guardar',
|
save: 'Guardar',
|
||||||
close: 'Cerrar',
|
close: 'Cerrar',
|
||||||
@@ -8,6 +17,7 @@ export const esES = {
|
|||||||
cancel: 'Cancelar',
|
cancel: 'Cancelar',
|
||||||
send: 'Enviar',
|
send: 'Enviar',
|
||||||
refresh: 'Refrescar',
|
refresh: 'Refrescar',
|
||||||
|
autoRefresh: 'Auto refresco',
|
||||||
version: 'Versión',
|
version: 'Versión',
|
||||||
donate: 'Donar',
|
donate: 'Donar',
|
||||||
run: 'Ejecutar',
|
run: 'Ejecutar',
|
||||||
@@ -18,12 +28,62 @@ export const esES = {
|
|||||||
add: 'Añadir',
|
add: 'Añadir',
|
||||||
data: 'Datos',
|
data: 'Datos',
|
||||||
properties: 'Propiedades',
|
properties: 'Propiedades',
|
||||||
|
name: 'Nombre',
|
||||||
|
clear: 'Limpiar',
|
||||||
|
options: 'Opciones',
|
||||||
insert: 'Insertar',
|
insert: 'Insertar',
|
||||||
|
discard: 'Descartar',
|
||||||
|
stay: 'Mantener',
|
||||||
|
author: 'Autor',
|
||||||
|
upload: 'Subir',
|
||||||
|
browse: 'Navegar',
|
||||||
|
content: 'Contenido',
|
||||||
|
cut: 'Cortar',
|
||||||
|
copy: 'Copiar',
|
||||||
|
paste: 'Pegar',
|
||||||
|
duplicate: 'Duplicar',
|
||||||
|
tools: 'Herramientas',
|
||||||
seconds: 'Segundos',
|
seconds: 'Segundos',
|
||||||
deleteConfirm: 'Confirmas la cancelación de',
|
all: 'Todos',
|
||||||
uploadFile: 'Cargar fichero'
|
new: 'Nuevo',
|
||||||
|
select: 'Seleccionar',
|
||||||
|
change: 'Cambiar',
|
||||||
|
include: 'Agregar',
|
||||||
|
includes: 'Agregados',
|
||||||
|
completed: 'Completado',
|
||||||
|
aborted: 'Cancelado',
|
||||||
|
disabled: 'Deshabilitado',
|
||||||
|
enable: 'Habilitar',
|
||||||
|
disable: 'Desabilitar',
|
||||||
|
contributors: 'Colaboradores',
|
||||||
|
pin: 'Fijar',
|
||||||
|
unpin: 'Desfijar',
|
||||||
|
folder: 'Carpeta | Carpetas',
|
||||||
|
none: 'Ninguno',
|
||||||
|
singleQuote: 'Comillas simples',
|
||||||
|
doubleQuote: 'Comillas dobles',
|
||||||
|
deleteConfirm: 'Confirmar la cancelación de',
|
||||||
|
uploadFile: 'Cargar fichero',
|
||||||
|
format: 'Formato', // Format code
|
||||||
|
history: 'Histórico',
|
||||||
|
filter: 'Filtro',
|
||||||
|
manualValue: 'Valor manual',
|
||||||
|
selectAll: 'Seleccionar todo',
|
||||||
|
pageNumber: 'Número de página',
|
||||||
|
directoryPath: 'Ruta de directorio',
|
||||||
|
actionSuccessful: '{action} exitoso',
|
||||||
|
outputFormat: 'Formato de salida',
|
||||||
|
singleFile: 'Fichero {ext} único',
|
||||||
|
zipCompressedFile: 'Fichero ZIP {ext} comprimido',
|
||||||
|
copyName: 'Copiar nombre',
|
||||||
|
search: 'Búsqueda',
|
||||||
|
title: 'Título',
|
||||||
|
archive: 'Archivo', // verb
|
||||||
|
undo: 'Deshacer',
|
||||||
|
moveTo: 'Mover a'
|
||||||
},
|
},
|
||||||
connection: {
|
connection: { // Database connection
|
||||||
|
connection: 'Conexión',
|
||||||
connectionName: 'Nombre de la conexión',
|
connectionName: 'Nombre de la conexión',
|
||||||
client: 'Cliente',
|
client: 'Cliente',
|
||||||
hostName: 'Servidor',
|
hostName: 'Servidor',
|
||||||
@@ -35,6 +95,17 @@ export const esES = {
|
|||||||
connected: 'Conectado',
|
connected: 'Conectado',
|
||||||
disconnect: 'Desconectar',
|
disconnect: 'Desconectar',
|
||||||
disconnected: 'Desconectado',
|
disconnected: 'Desconectado',
|
||||||
|
ssl: 'SSL',
|
||||||
|
enableSsl: 'Habilitar SSL',
|
||||||
|
privateKey: 'Clave privada',
|
||||||
|
certificate: 'Certificado',
|
||||||
|
caCertificate: 'Certificado CA',
|
||||||
|
ciphers: 'Cifrado',
|
||||||
|
untrustedConnection: 'Conexión no confiable',
|
||||||
|
passphrase: 'Frase de paso',
|
||||||
|
sshTunnel: 'Túnel SSH',
|
||||||
|
enableSsh: 'Habilitar SSH',
|
||||||
|
connectionString: 'Cadena de conexión',
|
||||||
addConnection: 'Añadir conexión',
|
addConnection: 'Añadir conexión',
|
||||||
createConnection: 'Crear conexión',
|
createConnection: 'Crear conexión',
|
||||||
createNewConnection: 'Crear nueva conexión',
|
createNewConnection: 'Crear nueva conexión',
|
||||||
@@ -42,26 +113,216 @@ export const esES = {
|
|||||||
testConnection: 'Comprobar conexión',
|
testConnection: 'Comprobar conexión',
|
||||||
editConnection: 'Editar conexión',
|
editConnection: 'Editar conexión',
|
||||||
deleteConnection: 'Eliminar conexión',
|
deleteConnection: 'Eliminar conexión',
|
||||||
connectionSuccessfullyMade: 'Conexión realizada correctamente!'
|
connectionSuccessfullyMade: 'Conexión realizada correctamente!',
|
||||||
|
readOnlyMode: 'Solo lectura',
|
||||||
|
allConnections: 'Todas las conexiones',
|
||||||
|
searchForConnections: 'Buscar por conexiones',
|
||||||
|
keepAliveInterval: 'Tiempo de mantenimiento de conexión',
|
||||||
|
singleConnection: 'Conexión única'
|
||||||
},
|
},
|
||||||
database: {
|
database: { // Database related terms
|
||||||
schema: 'Esquema',
|
schema: 'Esquema',
|
||||||
type: 'Tipo',
|
type: 'Tipo',
|
||||||
unableEditFieldWithoutPrimary: 'No se puede editar una campo sin Llave Primaria en el registro',
|
insert: 'Insertar',
|
||||||
editCell: 'Editar celda',
|
indexes: 'Índices',
|
||||||
|
foreignKeys: 'Claves Foráneas',
|
||||||
|
tablaChecks: 'Validación de tabla',
|
||||||
|
length: 'Longitud',
|
||||||
|
unsigned: 'Sin signo',
|
||||||
|
default: 'Por defecto',
|
||||||
|
comment: 'Comentario',
|
||||||
|
key: 'Clave | Claves',
|
||||||
|
order: 'Orden',
|
||||||
|
expression: 'Expresión',
|
||||||
|
autoIncrement: 'Autoincremental',
|
||||||
|
engine: 'Motor',
|
||||||
|
field: 'Campo | Campos',
|
||||||
|
approximately: 'Aproximadamente',
|
||||||
|
total: 'Total',
|
||||||
|
table: 'Tabla | Tablas',
|
||||||
|
view: 'Vista | Vistas',
|
||||||
|
materializedView: 'Vista Materializada | Vistas Materializadas',
|
||||||
|
definer: 'Definidor',
|
||||||
|
algorithm: 'Algoritmo',
|
||||||
|
trigger: 'Disparador | Disparadores',
|
||||||
|
storedRoutine: 'Procedimiento almacenado | Procedimientos almacenados',
|
||||||
|
scheduler: 'Planificador | Planificadores',
|
||||||
|
event: 'Evento',
|
||||||
|
parameters: 'Parámetros',
|
||||||
|
function: 'Función | Funciones',
|
||||||
|
deterministic: 'Determinístico',
|
||||||
|
context: 'Contexto',
|
||||||
|
export: 'Exportar',
|
||||||
|
import: 'Importar',
|
||||||
|
returns: 'Retorno',
|
||||||
|
timing: 'Timing',
|
||||||
|
state: 'Estado',
|
||||||
|
execution: 'Ejecución',
|
||||||
|
starts: 'Inicio',
|
||||||
|
ends: 'Final',
|
||||||
|
variables: 'Variables',
|
||||||
|
processes: 'Procesos',
|
||||||
|
database: 'Base de Datos',
|
||||||
|
array: 'Tupla',
|
||||||
|
structure: 'Estructura',
|
||||||
|
row: 'Fila | Filas',
|
||||||
|
cell: 'Celda | Celdas',
|
||||||
|
triggerFunction: 'Función disparadora | Funciones disparadoras',
|
||||||
|
routine: 'Rutina | Rutinas',
|
||||||
|
drop: 'Abandonar',
|
||||||
|
commit: 'Commit',
|
||||||
|
rollback: 'Marcha atrás',
|
||||||
|
ddl: 'DDL',
|
||||||
|
collation: 'Colación',
|
||||||
|
resultsTable: 'Tabla de resultados',
|
||||||
|
unableEditFieldWithoutPrimary: 'No es posible modificar un campo sin una clave primaria en el set de resultados',
|
||||||
|
editCell: 'Modificar celda',
|
||||||
deleteRows: 'Eliminar fila | Eliminar {count} filas',
|
deleteRows: 'Eliminar fila | Eliminar {count} filas',
|
||||||
confirmToDeleteRows: '¿Quiere realmente eliminar una fila? | ¿Quiere realmente eliminar {count} filas?',
|
confirmToDeleteRows: '¿Quiere realmente eliminar una fila? | ¿Quiere realmente eliminar {count} filas?',
|
||||||
addNewRow: 'Añadir nueva fila',
|
addNewRow: 'Añadir nueva fila',
|
||||||
numberOfInserts: 'Numero de inserciones',
|
numberOfInserts: 'Número de inserciones',
|
||||||
affectedRows: 'Filas afectadas'
|
affectedRows: 'Líneas afectadas',
|
||||||
|
createNewDatabase: 'Crear nueva Base de Datos',
|
||||||
|
databaseName: 'Nombre de Base de Datos',
|
||||||
|
serverDefault: 'Servidor por defecto',
|
||||||
|
deleteDatabase: 'Eliminar Base de Datos',
|
||||||
|
editDatabase: 'Modificar Base de Datos',
|
||||||
|
clearChanges: 'Deshacer cambios',
|
||||||
|
addNewField: 'Añadir nuevo campo',
|
||||||
|
manageIndexes: 'Administrar índices',
|
||||||
|
manageForeignKeys: 'Administrar claves foráneas',
|
||||||
|
manageTableChecks: 'Administrar validaciones de tabla',
|
||||||
|
allowNull: 'Permitir NULL',
|
||||||
|
zeroFill: 'Rellenar con ceros',
|
||||||
|
customValue: 'Valor predeterminado',
|
||||||
|
onUpdate: 'On UPDATE',
|
||||||
|
deleteField: 'Eliminar campo',
|
||||||
|
createNewIndex: 'Crear nuevo índice',
|
||||||
|
createNewCheck: 'Crear nueva verificación',
|
||||||
|
checkClause: 'Comprobar cláusula',
|
||||||
|
addToIndex: 'Añadir al índice',
|
||||||
|
createNewTable: 'Crear nueva tabla',
|
||||||
|
emptyTable: 'Tabla vacía',
|
||||||
|
duplicateTable: 'Duplicar tabla',
|
||||||
|
deleteTable: 'Eliminar tabla',
|
||||||
|
exportTable: 'Exportar tabla',
|
||||||
|
emptyConfirm: 'Confirmar vaciado',
|
||||||
|
thereAreNoIndexes: 'No hay índices',
|
||||||
|
thereAreNoForeign: 'No hay claves foráneas',
|
||||||
|
thereAreNoTableChecks: 'No hay validaciones de tabla',
|
||||||
|
createNewForeign: 'Crear nueva clave foránea',
|
||||||
|
referenceTable: 'Ref. tabla',
|
||||||
|
referenceField: 'Ref. campo',
|
||||||
|
foreignFields: 'Campos foráneos',
|
||||||
|
invalidDefault: 'Valor por defecto no válido',
|
||||||
|
onDelete: 'On DELETE',
|
||||||
|
selectStatement: 'Declaración SELECT',
|
||||||
|
triggerStatement: 'Declaración TRIGGER',
|
||||||
|
sqlSecurity: 'Seguridad SQL',
|
||||||
|
updateOption: 'Opción UPDATE',
|
||||||
|
deleteView: 'Eliminar vista',
|
||||||
|
createNewView: 'Crear nueva vista',
|
||||||
|
createNewMaterializedView: 'Crear nueva vista materializada',
|
||||||
|
deleteTrigger: 'Eliminar disparador',
|
||||||
|
createNewTrigger: 'Crear nuevo disparador',
|
||||||
|
currentUser: 'Usuario actual',
|
||||||
|
routineBody: 'Cuerpo de rutina',
|
||||||
|
dataAccess: 'Acceso a datos',
|
||||||
|
thereAreNoParameters: 'No hay parámetros',
|
||||||
|
createNewParameter: 'Crear nuevo parámetro',
|
||||||
|
createNewRoutine: 'Crear nuevo procedimiento almacenado',
|
||||||
|
deleteRoutine: 'Eliminar procedimiento almacenado',
|
||||||
|
functionBody: 'Cuerpo de función',
|
||||||
|
createNewFunction: 'Crear nueva función',
|
||||||
|
deleteFunction: 'Eliminar función',
|
||||||
|
schedulerBody: 'Cuerpo de planificador',
|
||||||
|
createNewScheduler: 'Crear nuevo planificador',
|
||||||
|
deleteScheduler: 'Eliminar planificador',
|
||||||
|
preserveOnCompletion: 'Mantener al finalizar',
|
||||||
|
tableFiller: 'Rellenador de tabla',
|
||||||
|
fakeDataLanguage: 'Lenguaje de datos dummy',
|
||||||
|
queryDuration: 'Duración de la consulta',
|
||||||
|
setNull: 'Establecer a NULL',
|
||||||
|
processesList: 'Lista de procesos',
|
||||||
|
processInfo: 'Información de proceso',
|
||||||
|
manageUsers: 'Administrar usuarios',
|
||||||
|
createNewSchema: 'Crear nuevo esquema',
|
||||||
|
schemaName: 'Nombre de esquema',
|
||||||
|
editSchema: 'Modificar esquema',
|
||||||
|
deleteSchema: 'Eliminar esquema',
|
||||||
|
noSchema: 'No hay esquemas',
|
||||||
|
runQuery: 'Ejecutar consulta',
|
||||||
|
thereAreNoTableFields: 'No hay campos en la tabla',
|
||||||
|
newTable: 'Nueva tabla',
|
||||||
|
newView: 'Nueva vista',
|
||||||
|
newMaterializedView: 'Nueva vista materializada',
|
||||||
|
newTrigger: 'Nuevo disparador',
|
||||||
|
newRoutine: 'Nueva rutina',
|
||||||
|
newFunction: 'Nueva función',
|
||||||
|
newScheduler: 'Nuevo planificador',
|
||||||
|
newTriggerFunction: 'Nueva función de disparador',
|
||||||
|
thereAreNoQueriesYet: 'No quedan mas consultas',
|
||||||
|
searchForQueries: 'Buscar consultas',
|
||||||
|
killProcess: 'Matar proceso',
|
||||||
|
exportSchema: 'Exportar esquema',
|
||||||
|
importSchema: 'Importar esquema',
|
||||||
|
newInsertStmtEvery: 'Nueva declaración INSERT',
|
||||||
|
processingTableExport: 'Procesando {table}',
|
||||||
|
fetchingTableExport: 'Obteniendo datos de {table}',
|
||||||
|
writingTableExport: 'Escribiendo datos de {table}',
|
||||||
|
checkAllTables: 'Verificar todas las tablas',
|
||||||
|
uncheckAllTables: 'Desmarcar todas las tablas',
|
||||||
|
killQuery: 'Matar consulta',
|
||||||
|
insertRow: 'Añadir fila | Añadir filas',
|
||||||
|
commitMode: 'Modo de Commit',
|
||||||
|
autoCommit: 'Automático',
|
||||||
|
manualCommit: 'Manual',
|
||||||
|
importQueryErrors: 'Atención: {n} de error encontrado | Atención: {n} errores encontrados',
|
||||||
|
executedQueries: '{n} consulta ejecutada | {n} consultas ejecutadas',
|
||||||
|
disableFKChecks: 'Deshabilitar comprobación de claves foráneas',
|
||||||
|
formatQuery: 'Formato de consulta',
|
||||||
|
queryHistory: 'Histórico de consultas',
|
||||||
|
clearQuery: 'Limpiar consulta',
|
||||||
|
fillCell: 'Rellenar celda',
|
||||||
|
executeSelectedQuery: 'Ejecutar consulta seleccionada',
|
||||||
|
noResultsPresent: 'No se obtuvieron resultados',
|
||||||
|
sqlExportOptions: 'Opciones de exportación de SQL',
|
||||||
|
targetTable: 'Tabla objetivo',
|
||||||
|
switchDatabase: 'Cambiar de Base de datos',
|
||||||
|
searchForElements: 'Buscar por elementos',
|
||||||
|
searchForSchemas: 'Buscar por esquemas',
|
||||||
|
savedQueries: 'Consultas almacenadas'
|
||||||
},
|
},
|
||||||
application: {
|
application: {
|
||||||
settings: 'Configuración',
|
settings: 'Configuración',
|
||||||
|
console: 'Consola',
|
||||||
general: 'General',
|
general: 'General',
|
||||||
themes: 'Temas',
|
themes: 'Temas',
|
||||||
update: 'Actualizar',
|
update: 'Actualizar',
|
||||||
about: 'Sobre',
|
about: 'Sobre',
|
||||||
language: 'Idioma',
|
language: 'Idioma',
|
||||||
|
shortcuts: 'Atajos',
|
||||||
|
key: 'Tecla | Teclas', // Keyboard key
|
||||||
|
event: 'Evento',
|
||||||
|
light: 'Claro',
|
||||||
|
dark: 'Oscuro',
|
||||||
|
autoCompletion: 'Autocompletado',
|
||||||
|
application: 'Aplicación',
|
||||||
|
editor: 'Editor',
|
||||||
|
changelog: 'Histórico de cambios',
|
||||||
|
small: 'Pequeño',
|
||||||
|
medium: 'Mediano',
|
||||||
|
large: 'Grande',
|
||||||
|
appearance: 'Apariencia',
|
||||||
|
color: 'Color',
|
||||||
|
label: 'Etiqueta',
|
||||||
|
icon: 'Icono',
|
||||||
|
customIcon: 'Icono personalizado',
|
||||||
|
fileName: 'Nombre de fichero',
|
||||||
|
choseFile: 'Elegir fichero',
|
||||||
|
data: 'Datos',
|
||||||
|
password: 'Contraseña',
|
||||||
|
required: 'Requerido',
|
||||||
madeWithJS: 'Hecho con 💛 y JavaScript!',
|
madeWithJS: 'Hecho con 💛 y JavaScript!',
|
||||||
checkForUpdates: 'Comprobar actualizaciones',
|
checkForUpdates: 'Comprobar actualizaciones',
|
||||||
noUpdatesAvailable: 'No hay actualizaciones',
|
noUpdatesAvailable: 'No hay actualizaciones',
|
||||||
@@ -71,7 +332,255 @@ export const esES = {
|
|||||||
downloadingUpdate: 'Descargando actualización',
|
downloadingUpdate: 'Descargando actualización',
|
||||||
updateDownloaded: 'Descargada actualización',
|
updateDownloaded: 'Descargada actualización',
|
||||||
restartToInstall: 'Reiniciar Antares para instalar',
|
restartToInstall: 'Reiniciar Antares para instalar',
|
||||||
|
includeBetaUpdates: 'Incluir actualizaciones en fase beta',
|
||||||
notificationsTimeout: 'Tiempo de espera',
|
notificationsTimeout: 'Tiempo de espera',
|
||||||
openNewTab: 'Abrir nueva pestaña'
|
openNewTab: 'Abrir nueva pestaña',
|
||||||
|
unsavedChanges: 'Cambios sin guardar',
|
||||||
|
discardUnsavedChanges: 'Tiene algunos cambios sin guardar. Al cerrar esta pestaña, serán descartados.',
|
||||||
|
applicationTheme: 'Tema de la Aplicación',
|
||||||
|
editorTheme: 'Editor de Tema',
|
||||||
|
wrapLongLines: 'Mantener lineas largas',
|
||||||
|
markdownSupported: 'Markdown soportado',
|
||||||
|
plantATree: 'Planta un arbol',
|
||||||
|
dataTabPageSize: 'Resultados por página',
|
||||||
|
noOpenTabs: 'No hay pestañas abiertas. Navega por la barra de la izquierda o:',
|
||||||
|
restorePreviousSession: 'Restablecer la sesión anterior',
|
||||||
|
closeTab: 'Cerrar pestaña',
|
||||||
|
goToDownloadPage: 'Ir a la página de descargas',
|
||||||
|
disableBlur: 'Deshabilitar opacidad',
|
||||||
|
missingOrIncompleteTranslation: '¿No hay traducción o hay algo incorrecto?',
|
||||||
|
findOutHowToContribute: 'Mira como puedes contribuir',
|
||||||
|
reportABug: 'Informar de un problema',
|
||||||
|
nextTab: 'Siguiente pestaña',
|
||||||
|
previousTab: 'Anterior pestaña',
|
||||||
|
selectTabNumber: 'Selecciona numero de pestaña {param}',
|
||||||
|
toggleConsole: 'Alternar vista de consola',
|
||||||
|
addShortcut: 'Añadir atajo',
|
||||||
|
editShortcut: 'Modificar atajo',
|
||||||
|
deleteShortcut: 'Eliminar atajo',
|
||||||
|
restoreDefaults: 'Restablecer valores por defecto',
|
||||||
|
restoreDefaultsQuestion: '¿Está seguro que quiere establecer los valores por defecto?',
|
||||||
|
registerAShortcut: 'Registrar un atajo',
|
||||||
|
invalidShortcutMessage: 'Combinación no válida, por favor intente otra',
|
||||||
|
shortcutAlreadyExists: 'El atajo ya existe',
|
||||||
|
saveContent: 'Guardar contenido',
|
||||||
|
openAllConnections: 'Abrir todas las conexiones',
|
||||||
|
openSettings: 'Abrir configuración',
|
||||||
|
runOrReload: 'Ejecutar o recargar',
|
||||||
|
openFilter: 'Abrir filtro',
|
||||||
|
nextResultsPage: 'Siguiente pagina de resultados',
|
||||||
|
previousResultsPage: 'Anterior página de resultados',
|
||||||
|
editFolder: 'Modificar carpeta',
|
||||||
|
folderName: 'Nombre de carpeta',
|
||||||
|
deleteFolder: 'Eliminar carpeta',
|
||||||
|
newFolder: 'Crear nueva carpeta',
|
||||||
|
outOfFolder: 'Fuera de la carpeta',
|
||||||
|
editConnectionAppearance: 'Modificar apariencia de conexión',
|
||||||
|
defaultCopyType: 'Default copy type',
|
||||||
|
showTableSize: 'Mostrar tamaño de tabla en la barra lateral',
|
||||||
|
showTableSizeDescription: 'Solo para MySQL/MariaDB. Habilitar esta opción puede afectar al rendimiento en esquemas con muchas tablas.',
|
||||||
|
switchSearchMethod: 'Switch search method',
|
||||||
|
phpArray: 'Array de PHP',
|
||||||
|
closeAllTabs: 'Cerrar todas las pestañas',
|
||||||
|
closeOtherTabs: 'Cerrar las otras pestañas',
|
||||||
|
closeTabsToLeft: 'Cerrar las pestañas a la izquierda',
|
||||||
|
closeTabsToRight: 'Cerrar las pestañas a la derecha',
|
||||||
|
csvFieldDelimiter: 'Delimitador de campos',
|
||||||
|
csvLinesTerminator: 'Terminador de líneas',
|
||||||
|
csvStringDelimiter: 'Delimitador de cadenas',
|
||||||
|
csvIncludeHeader: 'Incluir cabecera',
|
||||||
|
csvExportOptions: 'Opciones de exportación de CSV',
|
||||||
|
exportData: 'Exportar datos',
|
||||||
|
exportDataExplanation: 'Exportar conexiones guardadas en Antares. Se le preguntará por una contraseña para encriptar el fichero exportado.',
|
||||||
|
importData: 'Importar datos',
|
||||||
|
importDataExplanation: 'Importará un fichero con extensión .antares que contiene conexiones. Necesitará la contraseña con la que se encriptó el mismo.',
|
||||||
|
includeConnectionPasswords: 'Incluir contraseñas de conexión',
|
||||||
|
includeFolders: 'Incluir carpetas',
|
||||||
|
encryptionPassword: 'Encryption password',
|
||||||
|
encryptionPasswordError: 'The encryption password must be at least 8 characters long.',
|
||||||
|
ignoreDuplicates: 'Ignore duplicates',
|
||||||
|
wrongImportPassword: 'Wrong import password',
|
||||||
|
wrongFileFormat: 'Wrong file format',
|
||||||
|
dataImportSuccess: 'Data successfully imported',
|
||||||
|
note: 'Note | Notes',
|
||||||
|
thereAreNoNotesYet: 'There are no notes yet',
|
||||||
|
addNote: 'Add note',
|
||||||
|
editNote: 'Edit note',
|
||||||
|
saveAsNote: 'Save as note',
|
||||||
|
showArchivedNotes: 'Show archived notes',
|
||||||
|
hideArchivedNotes: 'Hide archived notes',
|
||||||
|
tag: 'Tag', // Note tag,
|
||||||
|
saveFile: 'Save file',
|
||||||
|
saveFileAs: 'Save file as',
|
||||||
|
openFile: 'Open file',
|
||||||
|
openNotes: 'Open notes',
|
||||||
|
debugConsole: 'Debug console', // <- console tab name
|
||||||
|
executedQueries: 'Executed queries', // <- console tab name
|
||||||
|
sizeLimitError: 'Maximum size of {size} exceeded'
|
||||||
|
},
|
||||||
|
faker: { // Faker.js methods, used in random generated content
|
||||||
|
address: 'Dirección',
|
||||||
|
commerce: 'Comercio',
|
||||||
|
company: 'Compañía',
|
||||||
|
database: 'Base de datos',
|
||||||
|
date: 'Fecha',
|
||||||
|
finance: 'Finanzas',
|
||||||
|
git: 'Git',
|
||||||
|
hacker: 'Hacker',
|
||||||
|
internet: 'Internet',
|
||||||
|
lorem: 'Lorem',
|
||||||
|
name: 'Nombre',
|
||||||
|
music: 'Música',
|
||||||
|
phone: 'Teléfono',
|
||||||
|
random: 'Aleatorio',
|
||||||
|
system: 'Sistema',
|
||||||
|
time: 'Hora',
|
||||||
|
vehicle: 'Vehículo',
|
||||||
|
zipCode: 'Código Postal',
|
||||||
|
zipCodeByState: 'Código Postal por Estado',
|
||||||
|
city: 'Ciudad',
|
||||||
|
cityPrefix: 'Prefijo de ciudad',
|
||||||
|
citySuffix: 'Sufijo de ciudad',
|
||||||
|
streetName: 'Nombre de calle',
|
||||||
|
streetAddress: 'Dirección',
|
||||||
|
streetSuffix: 'Sufijo de calle',
|
||||||
|
streetPrefix: 'Prefijo de calle',
|
||||||
|
secondaryAddress: 'Dirección secundaria',
|
||||||
|
county: 'Condado',
|
||||||
|
country: 'País',
|
||||||
|
countryCode: 'Código de país',
|
||||||
|
state: 'Estado',
|
||||||
|
stateAbbr: 'Abreviatura de Estado',
|
||||||
|
latitude: 'Latitud',
|
||||||
|
longitude: 'Longitud',
|
||||||
|
direction: 'Dirección',
|
||||||
|
cardinalDirection: 'Dirección cardinal',
|
||||||
|
ordinalDirection: 'Dirección ordinal',
|
||||||
|
nearbyGPSCoordinate: 'Coordenadas GPS',
|
||||||
|
timeZone: 'Zona horaria',
|
||||||
|
color: 'Color',
|
||||||
|
department: 'Departmento',
|
||||||
|
productName: 'Nombre de producto',
|
||||||
|
price: 'Precio',
|
||||||
|
productAdjective: 'Adjetivo de producto',
|
||||||
|
productMaterial: 'Material de producto',
|
||||||
|
product: 'Producto',
|
||||||
|
productDescription: 'Descripción de producto',
|
||||||
|
suffixes: 'Sufijos',
|
||||||
|
companyName: 'Nombre de compañía',
|
||||||
|
companySuffix: 'Sufijo de compañía',
|
||||||
|
catchPhrase: 'Catch phrase',
|
||||||
|
bs: 'BS',
|
||||||
|
catchPhraseAdjective: 'Catch phrase adjective',
|
||||||
|
catchPhraseDescriptor: 'Catch phrase descriptor',
|
||||||
|
catchPhraseNoun: 'Catch phrase noun',
|
||||||
|
bsAdjective: 'BS adjective',
|
||||||
|
bsBuzz: 'BS buzz',
|
||||||
|
bsNoun: 'BS noun',
|
||||||
|
column: 'Columna',
|
||||||
|
type: 'Tipo',
|
||||||
|
collation: 'Colación',
|
||||||
|
engine: 'Motor',
|
||||||
|
past: 'Pasado',
|
||||||
|
now: 'Ahora',
|
||||||
|
future: 'Futuro',
|
||||||
|
between: 'Entre',
|
||||||
|
recent: 'Reciente',
|
||||||
|
soon: 'Pronto',
|
||||||
|
month: 'Mes',
|
||||||
|
weekday: 'Día de la semana',
|
||||||
|
account: 'Cuenta',
|
||||||
|
accountName: 'Nombre de cuenta',
|
||||||
|
routingNumber: 'Número de enrutamiento',
|
||||||
|
mask: 'Máscara',
|
||||||
|
amount: 'Cantidad',
|
||||||
|
transactionType: 'Tipo de transacción',
|
||||||
|
currencyCode: 'Código de Moneda',
|
||||||
|
currencyName: 'Nombre de Moneda',
|
||||||
|
currencySymbol: 'Símbolo de Moneda',
|
||||||
|
bitcoinAddress: 'Dirección Bitcoin',
|
||||||
|
litecoinAddress: 'Dirección Litecoin',
|
||||||
|
creditCardNumber: 'Número de tarjeta',
|
||||||
|
creditCardCVV: 'CVV',
|
||||||
|
ethereumAddress: 'Dirección Ethereum',
|
||||||
|
iban: 'IBAN',
|
||||||
|
bic: 'BIC',
|
||||||
|
transactionDescription: 'Descripción de transacción',
|
||||||
|
branch: 'Rama',
|
||||||
|
commitEntry: 'Entrada de Commit',
|
||||||
|
commitMessage: 'Mensaje de Commit',
|
||||||
|
commitSha: 'SHA de Commit',
|
||||||
|
shortSha: 'SHA corto',
|
||||||
|
abbreviation: 'Abreviatura',
|
||||||
|
adjective: 'Adjetivo',
|
||||||
|
noun: 'Sustantivo',
|
||||||
|
verb: 'Verbo',
|
||||||
|
ingverb: 'Adverbio',
|
||||||
|
phrase: 'Frase',
|
||||||
|
avatar: 'Avatar',
|
||||||
|
email: 'Email',
|
||||||
|
exampleEmail: 'Email de ejemplo',
|
||||||
|
userName: 'Nombre de usuario',
|
||||||
|
protocol: 'Protocolo',
|
||||||
|
url: 'URL',
|
||||||
|
domainName: 'Dominio',
|
||||||
|
domainSuffix: 'Prefijo de dominio',
|
||||||
|
domainWord: 'Palabra de dominio',
|
||||||
|
ip: 'IP',
|
||||||
|
ipv6: 'IPv6',
|
||||||
|
userAgent: 'Agente de Usuario',
|
||||||
|
mac: 'MAC',
|
||||||
|
password: 'Contraseña',
|
||||||
|
word: 'Palabra',
|
||||||
|
words: 'Palabras',
|
||||||
|
sentence: 'Sentencia',
|
||||||
|
slug: 'Slug',
|
||||||
|
sentences: 'Sentencias',
|
||||||
|
paragraph: 'Frase',
|
||||||
|
paragraphs: 'Frases',
|
||||||
|
text: 'Texto',
|
||||||
|
lines: 'Lineas',
|
||||||
|
genre: 'Género',
|
||||||
|
firstName: 'Nombre',
|
||||||
|
lastName: 'Apellido',
|
||||||
|
middleName: 'Apellido',
|
||||||
|
findName: 'Nombre completo',
|
||||||
|
jobTitle: 'Ocupación',
|
||||||
|
gender: 'Género',
|
||||||
|
prefix: 'Prefijo',
|
||||||
|
suffix: 'Sufijo',
|
||||||
|
title: 'Título',
|
||||||
|
jobDescriptor: 'Descripción de trabajo',
|
||||||
|
jobArea: 'Area de trabajo',
|
||||||
|
jobType: 'Tipo de trabajo',
|
||||||
|
phoneNumber: 'Número de teléfono',
|
||||||
|
phoneNumberFormat: 'Formato de número de teléfono',
|
||||||
|
phoneFormats: 'Formatos de teléfono',
|
||||||
|
number: 'Número',
|
||||||
|
float: 'Decimal',
|
||||||
|
arrayElement: 'Elemento Array',
|
||||||
|
arrayElements: 'Elementos de Array',
|
||||||
|
objectElement: 'Elemento Objeto',
|
||||||
|
uuid: 'UUID',
|
||||||
|
boolean: 'Booleano',
|
||||||
|
image: 'Imagen',
|
||||||
|
locale: 'Conf. regional',
|
||||||
|
alpha: 'Alpha',
|
||||||
|
alphaNumeric: 'Alfanumérico',
|
||||||
|
hexaDecimal: 'Hexadecimal',
|
||||||
|
fileName: 'Nombre de fichero',
|
||||||
|
commonFileName: 'Common file name',
|
||||||
|
mimeType: 'Mime-Type',
|
||||||
|
commonFileType: 'Common file type',
|
||||||
|
commonFileExt: 'Common file extension',
|
||||||
|
fileType: 'Tipo de fichero',
|
||||||
|
fileExt: 'Extension de fichero',
|
||||||
|
directoryPath: 'Ruta de directorio',
|
||||||
|
filePath: 'Ruta de fichero',
|
||||||
|
semver: 'SemVer',
|
||||||
|
manufacturer: 'Fabricante',
|
||||||
|
model: 'Modelo',
|
||||||
|
fuel: 'Combustible',
|
||||||
|
vin: 'VIN'
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@@ -140,7 +140,7 @@ export const heIL = {
|
|||||||
total: 'סך הכל',
|
total: 'סך הכל',
|
||||||
table: 'טבלה | טבלאות',
|
table: 'טבלה | טבלאות',
|
||||||
view: 'תצוגה | תצוגות',
|
view: 'תצוגה | תצוגות',
|
||||||
materializedview: 'תצוגה ממומשת | תצוגות ממומשות',
|
materializedView: 'תצוגה ממומשת | תצוגות ממומשות',
|
||||||
definer: 'מגדיר',
|
definer: 'מגדיר',
|
||||||
algorithm: 'אלגוריתם',
|
algorithm: 'אלגוריתם',
|
||||||
trigger: 'טריגר | טריגרים',
|
trigger: 'טריגר | טריגרים',
|
||||||
|
@@ -275,7 +275,7 @@ export const nlNL = {
|
|||||||
savedQueries: 'Opgeslagen queries',
|
savedQueries: 'Opgeslagen queries',
|
||||||
searchForElements: 'Zoek naar elementen',
|
searchForElements: 'Zoek naar elementen',
|
||||||
searchForSchemas: 'Zoek naar schema\'s',
|
searchForSchemas: 'Zoek naar schema\'s',
|
||||||
materializedview: 'Materialized view | Materialized views',
|
materializedView: 'Materialized view | Materialized views',
|
||||||
createNewMaterializedView: 'Materialized view maken',
|
createNewMaterializedView: 'Materialized view maken',
|
||||||
newMaterializedView: 'Nieuwe materialized view'
|
newMaterializedView: 'Nieuwe materialized view'
|
||||||
},
|
},
|
||||||
|
@@ -270,7 +270,7 @@ export const ruRU = {
|
|||||||
importQueryErrors: 'Внимание: {n} ошибка возникла | Внимание: {n} ошибок произошло',
|
importQueryErrors: 'Внимание: {n} ошибка возникла | Внимание: {n} ошибок произошло',
|
||||||
executedQueries: '{n} запрос выполнен | {n} запросов выполнено',
|
executedQueries: '{n} запрос выполнен | {n} запросов выполнено',
|
||||||
insert: 'Вставить',
|
insert: 'Вставить',
|
||||||
materializedview: 'Материализованное представление | Материализованные представления',
|
materializedView: 'Материализованное представление | Материализованные представления',
|
||||||
exportTable: 'Экспорт таблицы',
|
exportTable: 'Экспорт таблицы',
|
||||||
createNewMaterializedView: 'Создать новое материализованное представление',
|
createNewMaterializedView: 'Создать новое материализованное представление',
|
||||||
newMaterializedView: 'Новое материализованное представление',
|
newMaterializedView: 'Новое материализованное представление',
|
||||||
|
@@ -270,7 +270,7 @@ export const uzUZ = {
|
|||||||
importQueryErrors: 'Diqqat: {n} xato yuz berdi | Diqqat: {n} xatolar yuz berdi',
|
importQueryErrors: 'Diqqat: {n} xato yuz berdi | Diqqat: {n} xatolar yuz berdi',
|
||||||
executedQueries: '{n} soʻrov bajarildi | {n} soʻrovlar bajarildi',
|
executedQueries: '{n} soʻrov bajarildi | {n} soʻrovlar bajarildi',
|
||||||
insert: 'Kiritish',
|
insert: 'Kiritish',
|
||||||
materializedview: 'Materializatsiya qilingan ko‘rinish | Materializatsiya qilingan ko‘rinishlar',
|
materializedView: 'Materializatsiya qilingan ko‘rinish | Materializatsiya qilingan ko‘rinishlar',
|
||||||
exportTable: 'Jadvalni eksport qilish',
|
exportTable: 'Jadvalni eksport qilish',
|
||||||
createNewMaterializedView: 'Yangi materializatsiya qilingan ko‘rinish yaratish',
|
createNewMaterializedView: 'Yangi materializatsiya qilingan ko‘rinish yaratish',
|
||||||
newMaterializedView: 'Yangi materializatsiya qilingan ko‘rinish',
|
newMaterializedView: 'Yangi materializatsiya qilingan ko‘rinish',
|
||||||
|
@@ -117,6 +117,7 @@ export const zhCN = {
|
|||||||
insert: '插入',
|
insert: '插入',
|
||||||
indexes: '索引',
|
indexes: '索引',
|
||||||
foreignKeys: '外键',
|
foreignKeys: '外键',
|
||||||
|
tableChecks: '表检查',
|
||||||
length: '长度',
|
length: '长度',
|
||||||
unsigned: '无符号',
|
unsigned: '无符号',
|
||||||
default: '默认',
|
default: '默认',
|
||||||
@@ -131,6 +132,7 @@ export const zhCN = {
|
|||||||
total: '总计',
|
total: '总计',
|
||||||
table: '表 | 表',
|
table: '表 | 表',
|
||||||
view: '视图 | 视图',
|
view: '视图 | 视图',
|
||||||
|
materializedView: '实体化视图 | 实体化视图',
|
||||||
definer: '定义者',
|
definer: '定义者',
|
||||||
algorithm: '算法',
|
algorithm: '算法',
|
||||||
trigger: '触发器 | 触发器',
|
trigger: '触发器 | 触发器',
|
||||||
@@ -180,12 +182,15 @@ export const zhCN = {
|
|||||||
addNewField: '添加新字段',
|
addNewField: '添加新字段',
|
||||||
manageIndexes: '管理索引',
|
manageIndexes: '管理索引',
|
||||||
manageForeignKeys: '管理外键',
|
manageForeignKeys: '管理外键',
|
||||||
|
manageTableChecks: '管理表 check 约束',
|
||||||
allowNull: '允许 NULL',
|
allowNull: '允许 NULL',
|
||||||
zeroFill: '零填充',
|
zeroFill: '零填充',
|
||||||
customValue: '自定义值',
|
customValue: '自定义值',
|
||||||
onUpdate: '在更新',
|
onUpdate: '在更新',
|
||||||
deleteField: '删除字段',
|
deleteField: '删除字段',
|
||||||
createNewIndex: '创建新索引',
|
createNewIndex: '创建新索引',
|
||||||
|
createNewCheck: '创建新 check 约束',
|
||||||
|
checkClause: 'Check 约束',
|
||||||
addToIndex: '添加到索引',
|
addToIndex: '添加到索引',
|
||||||
createNewTable: '创建新表',
|
createNewTable: '创建新表',
|
||||||
emptyTable: '清空表',
|
emptyTable: '清空表',
|
||||||
@@ -195,6 +200,7 @@ export const zhCN = {
|
|||||||
emptyConfirm: '您是否确认清空',
|
emptyConfirm: '您是否确认清空',
|
||||||
thereAreNoIndexes: '没有索引',
|
thereAreNoIndexes: '没有索引',
|
||||||
thereAreNoForeign: '没有外键',
|
thereAreNoForeign: '没有外键',
|
||||||
|
thereAreNoTableChecks: '没有表 check 约束',
|
||||||
createNewForeign: '创建新外键',
|
createNewForeign: '创建新外键',
|
||||||
referenceTable: '参考表',
|
referenceTable: '参考表',
|
||||||
referenceField: '参考字段',
|
referenceField: '参考字段',
|
||||||
@@ -207,6 +213,7 @@ export const zhCN = {
|
|||||||
updateOption: '更新选项',
|
updateOption: '更新选项',
|
||||||
deleteView: '删除视图',
|
deleteView: '删除视图',
|
||||||
createNewView: '创建新视图',
|
createNewView: '创建新视图',
|
||||||
|
createNewMaterializedView: '创建新实体化视图',
|
||||||
deleteTrigger: '删除触发器',
|
deleteTrigger: '删除触发器',
|
||||||
createNewTrigger: '创建新触发器',
|
createNewTrigger: '创建新触发器',
|
||||||
currentUser: '当前用户',
|
currentUser: '当前用户',
|
||||||
@@ -239,6 +246,7 @@ export const zhCN = {
|
|||||||
thereAreNoTableFields: '没有表的字段',
|
thereAreNoTableFields: '没有表的字段',
|
||||||
newTable: '新表',
|
newTable: '新表',
|
||||||
newView: '新视图',
|
newView: '新视图',
|
||||||
|
newMaterializedView: '新实体化视图',
|
||||||
newTrigger: '新触发器',
|
newTrigger: '新触发器',
|
||||||
newRoutine: '新例程',
|
newRoutine: '新例程',
|
||||||
newFunction: '新函数',
|
newFunction: '新函数',
|
||||||
@@ -300,6 +308,7 @@ export const zhCN = {
|
|||||||
color: '颜色',
|
color: '颜色',
|
||||||
label: '标签',
|
label: '标签',
|
||||||
icon: '图标',
|
icon: '图标',
|
||||||
|
customIcon: '定制图标',
|
||||||
fileName: '文件名称',
|
fileName: '文件名称',
|
||||||
choseFile: '选择文件',
|
choseFile: '选择文件',
|
||||||
data: '数据',
|
data: '数据',
|
||||||
@@ -324,7 +333,7 @@ export const zhCN = {
|
|||||||
wrapLongLines: '将长行换行显示',
|
wrapLongLines: '将长行换行显示',
|
||||||
markdownSupported: '支持 Markdown',
|
markdownSupported: '支持 Markdown',
|
||||||
plantATree: '种植一棵树',
|
plantATree: '种植一棵树',
|
||||||
dataTabPageSize: '数据标签的页面大小',
|
dataTabPageSize: '每页结果',
|
||||||
noOpenTabs: '没有打开的标签, 请在左侧栏上导航或:',
|
noOpenTabs: '没有打开的标签, 请在左侧栏上导航或:',
|
||||||
restorePreviousSession: '恢复上一个会话',
|
restorePreviousSession: '恢复上一个会话',
|
||||||
closeTab: '关闭标签',
|
closeTab: '关闭标签',
|
||||||
@@ -348,7 +357,6 @@ export const zhCN = {
|
|||||||
saveContent: '保存内容',
|
saveContent: '保存内容',
|
||||||
openAllConnections: '打开所有连接',
|
openAllConnections: '打开所有连接',
|
||||||
openSettings: '打开设置',
|
openSettings: '打开设置',
|
||||||
openScratchpad: '打开草稿栏',
|
|
||||||
runOrReload: '运行或重新加载',
|
runOrReload: '运行或重新加载',
|
||||||
openFilter: '打开过滤器',
|
openFilter: '打开过滤器',
|
||||||
nextResultsPage: '下一个结果页',
|
nextResultsPage: '下一个结果页',
|
||||||
@@ -356,6 +364,8 @@ export const zhCN = {
|
|||||||
editFolder: '编辑文件夹',
|
editFolder: '编辑文件夹',
|
||||||
folderName: '文件夹名称',
|
folderName: '文件夹名称',
|
||||||
deleteFolder: '删除文件夹',
|
deleteFolder: '删除文件夹',
|
||||||
|
newFolder: '新文件夹',
|
||||||
|
outOfFolder: '',
|
||||||
editConnectionAppearance: '编辑连接的外观',
|
editConnectionAppearance: '编辑连接的外观',
|
||||||
defaultCopyType: '默认复制类型',
|
defaultCopyType: '默认复制类型',
|
||||||
showTableSize: '在侧边栏显示表大小',
|
showTableSize: '在侧边栏显示表大小',
|
||||||
@@ -394,7 +404,10 @@ export const zhCN = {
|
|||||||
saveFile: '保存文件',
|
saveFile: '保存文件',
|
||||||
saveFileAs: '将文件另存为',
|
saveFileAs: '将文件另存为',
|
||||||
openFile: '打开文件',
|
openFile: '打开文件',
|
||||||
openNotes: '打开笔记'
|
openNotes: '打开笔记',
|
||||||
|
debugConsole: '调试控制台',
|
||||||
|
executedQueries: '执行的查询',
|
||||||
|
sizeLimitError: '超过 {size} 的最大大小'
|
||||||
},
|
},
|
||||||
faker: { // Faker.js 方法,用于随机生成的内容
|
faker: { // Faker.js 方法,用于随机生成的内容
|
||||||
address: '地址',
|
address: '地址',
|
||||||
|
@@ -29,13 +29,7 @@ $explorebar-width: 14rem;
|
|||||||
$footer-height: 1.5rem;
|
$footer-height: 1.5rem;
|
||||||
|
|
||||||
@function get-excluding-size() {
|
@function get-excluding-size() {
|
||||||
@if $platform == linux {
|
@return $footer-height + $titlebar-height;
|
||||||
@return $footer-height;
|
|
||||||
}
|
|
||||||
|
|
||||||
@else {
|
|
||||||
@return $footer-height + $titlebar-height;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* stylelint-disable-next-line function-no-unknown */
|
/* stylelint-disable-next-line function-no-unknown */
|
||||||
|
@@ -20,6 +20,7 @@
|
|||||||
|
|
||||||
body {
|
body {
|
||||||
user-select: none;
|
user-select: none;
|
||||||
|
background-color: #000;
|
||||||
}
|
}
|
||||||
|
|
||||||
a {
|
a {
|
||||||
|
@@ -1,5 +1,7 @@
|
|||||||
/* stylelint-disable function-no-unknown */
|
/* stylelint-disable function-no-unknown */
|
||||||
.theme-light {
|
.theme-light {
|
||||||
|
background: $body-bg;
|
||||||
|
|
||||||
::-webkit-scrollbar-track {
|
::-webkit-scrollbar-track {
|
||||||
background: #fff;
|
background: #fff;
|
||||||
}
|
}
|
||||||
|
@@ -25,12 +25,13 @@ export interface SidebarElement {
|
|||||||
|
|
||||||
export interface CustomIcon {base64: string; uid: string}
|
export interface CustomIcon {base64: string; uid: string}
|
||||||
|
|
||||||
if (!key) { // If no key in local storace
|
if (!key) { // If no key in local storage
|
||||||
const storedKey = ipcRenderer.sendSync('get-key');// Ask for key stored on disk
|
const storedKey = ipcRenderer.sendSync('get-key');// Ask for key stored on disk
|
||||||
|
|
||||||
if (!storedKey) { // Of nop stored key on disk
|
if (!storedKey) { // If not stored key on disk
|
||||||
const newKey = crypto.randomBytes(16).toString('hex');
|
const newKey = crypto.randomBytes(16).toString('hex');
|
||||||
localStorage.setItem('key', newKey);
|
localStorage.setItem('key', newKey);
|
||||||
|
ipcRenderer.send('set-key', newKey);
|
||||||
key = newKey;
|
key = newKey;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
1
src/renderer/untyped.d.ts
vendored
1
src/renderer/untyped.d.ts
vendored
@@ -3,6 +3,7 @@
|
|||||||
declare module '@/App.vue';
|
declare module '@/App.vue';
|
||||||
declare module 'v-mask';
|
declare module 'v-mask';
|
||||||
declare module 'json2php';
|
declare module 'json2php';
|
||||||
|
declare module '*/encoding_charset.js';
|
||||||
declare module 'vuedraggable' {// <- to export as default
|
declare module 'vuedraggable' {// <- to export as default
|
||||||
const draggableComponent: import('vue').DefineComponent<{
|
const draggableComponent: import('vue').DefineComponent<{
|
||||||
list: {
|
list: {
|
||||||
|
@@ -1,8 +1,7 @@
|
|||||||
const path = require('path');
|
const path = require('path');
|
||||||
const webpack = require('webpack');
|
|
||||||
const ProgressPlugin = require('progress-webpack-plugin');
|
const ProgressPlugin = require('progress-webpack-plugin');
|
||||||
|
|
||||||
const { dependencies, devDependencies, version } = require('./package.json');
|
const { dependencies, devDependencies } = require('./package.json');
|
||||||
|
|
||||||
const externals = Object.keys(dependencies).concat(Object.keys(devDependencies));
|
const externals = Object.keys(dependencies).concat(Object.keys(devDependencies));
|
||||||
const isDevMode = process.env.NODE_ENV === 'development';
|
const isDevMode = process.env.NODE_ENV === 'development';
|
||||||
@@ -48,13 +47,7 @@ module.exports = { // Main
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
plugins: [
|
plugins: [
|
||||||
new ProgressPlugin(true),
|
new ProgressPlugin(true)
|
||||||
new webpack.DefinePlugin({
|
|
||||||
'process.env': {
|
|
||||||
PACKAGE_VERSION: `"${version}"`,
|
|
||||||
DISTRIBUTION: `"${process.env.DISTRIBUTION || 'none'}"`
|
|
||||||
}
|
|
||||||
})
|
|
||||||
],
|
],
|
||||||
module: {
|
module: {
|
||||||
rules: [
|
rules: [
|
||||||
|
Reference in New Issue
Block a user