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

Compare commits

...

29 Commits

Author SHA1 Message Date
7a46a119d8 chore(release): 0.1.9 2021-05-23 11:35:54 +02:00
f1636f1528 fix(MySQL): can't access tables having UNIQUE KEY, closes #69 2021-05-23 11:12:09 +02:00
f839d5cd3c chore: Twitter link in about tab 2021-05-23 10:19:56 +02:00
8f4f1d393c chore: update README.md 2021-05-22 17:33:03 +02:00
ab17c6d4bf chore: update README.md 2021-05-22 17:26:32 +02:00
b4b2f3d0cf chore(release): 0.1.8 2021-05-22 16:25:52 +02:00
7a766f04e6 perf: improved the way how field default value are handled 2021-05-22 16:24:19 +02:00
f6b77d1243 build: update dependencies 2021-05-22 16:12:08 +02:00
840241c3cc refactor: better description in foreign key value select 2021-05-20 15:07:51 +02:00
0f10c9e824 fix: internal id not removed before row update 2021-05-20 12:45:49 +02:00
1e37f2a96f fix: unable to add new ENUM fields 2021-05-20 12:38:05 +02:00
0d6137195d fix: unable to delete table rows 2021-05-19 16:55:38 +02:00
d26f168250 build: update build script 2021-05-17 19:08:36 +02:00
5efcad4d3f chore(release): 0.1.7 2021-05-16 21:08:52 +02:00
0a872e7023 build: separate build configurations 2021-05-16 21:03:04 +02:00
0e425a9c6d build: removed linux arm64 build from build process 2021-05-16 19:50:06 +02:00
434711a360 perf(MySQL): improved connections pool handling 2021-05-15 21:47:30 +02:00
854472c7a3 fix: row loses internal id after cell update 2021-05-15 19:33:31 +02:00
9a7cd90d5c build: arm mac (apple silicon) build configuration 2021-05-14 22:24:50 +02:00
026400d242 build: arm linux build configuration 2021-05-14 18:59:58 +02:00
4bd8cbbf6c build: moved to sass from node-sass 2021-05-14 17:27:56 +02:00
1382bc9300 Merge pull request #64 from Fabio286/dependabot/npm_and_yarn/pgsql-ast-parser-8.1.1
build(deps): bump pgsql-ast-parser from 7.2.1 to 8.1.1
2021-05-14 17:21:10 +02:00
ae103e5477 perf(core): increased connection pool size to improve performance 2021-05-14 17:17:37 +02:00
6b0b8b19d7 fix(MySQL): connection loses schema in some conditions 2021-05-14 17:02:27 +02:00
475397ca34 fix: issue with ENUM and SET fields on table filler modal 2021-05-13 20:46:44 +02:00
7a62131cc7 fix: issue with ENUM and SET length when creating a new field 2021-05-13 15:45:54 +02:00
c7663be338 fix: multiple row select on sorted tables not work properly 2021-05-11 18:32:11 +02:00
496490b14a build: update dependencies and build config 2021-05-11 12:00:22 +02:00
dependabot[bot]
672573d8c2 build(deps): bump pgsql-ast-parser from 7.2.1 to 8.1.1
Bumps [pgsql-ast-parser](https://github.com/oguimbal/pgsql-ast-parser) from 7.2.1 to 8.1.1.
- [Release notes](https://github.com/oguimbal/pgsql-ast-parser/releases)
- [Changelog](https://github.com/oguimbal/pgsql-ast-parser/blob/master/changelog.md)
- [Commits](https://github.com/oguimbal/pgsql-ast-parser/compare/7.2.1...8.1.1)

Signed-off-by: dependabot[bot] <support@github.com>
2021-05-10 06:16:49 +00:00
17 changed files with 341 additions and 232 deletions

View File

@@ -1,4 +1,4 @@
name: Build/release name: Build/release [linux]
on: push on: push
@@ -8,8 +8,7 @@ jobs:
strategy: strategy:
matrix: matrix:
# os: [macos-latest, ubuntu-latest, windows-latest] os: [ubuntu-latest]
os: [macos-latest, ubuntu-latest]
steps: steps:
- name: Check out Git repository - name: Check out Git repository

26
.github/workflows/build-mac.yml vendored Normal file
View File

@@ -0,0 +1,26 @@
name: Build/release [mac]
on: push
jobs:
release:
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [macos-latest]
steps:
- name: Check out Git repository
uses: actions/checkout@v1
- name: Install Node.js, NPM and Yarn
uses: actions/setup-node@v1
with:
node-version: 12
- name: Build/release Electron app
uses: samuelmeuli/action-electron-builder@v1
with:
github_token: ${{ secrets.github_token }}
release: ${{ startsWith(github.ref, 'refs/tags/v') }}

26
.github/workflows/build-win.yml vendored Normal file
View File

@@ -0,0 +1,26 @@
name: Build/release [windows]
on: push
jobs:
release:
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [windows-latest]
steps:
- name: Check out Git repository
uses: actions/checkout@v1
- name: Install Node.js, NPM and Yarn
uses: actions/setup-node@v1
with:
node-version: 12
- name: Build/release Electron app
uses: samuelmeuli/action-electron-builder@v1
with:
github_token: ${{ secrets.github_token }}
release: ${{ startsWith(github.ref, 'refs/tags/v') }}

View File

@@ -2,6 +2,44 @@
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.1.9](https://github.com/Fabio286/antares/compare/v0.1.8...v0.1.9) (2021-05-23)
### Bug Fixes
* **MySQL:** can't access tables having UNIQUE KEY, closes [#69](https://github.com/Fabio286/antares/issues/69) ([f1636f1](https://github.com/Fabio286/antares/commit/f1636f1528b5765423535f84027fdc853c58ce80))
### [0.1.8](https://github.com/Fabio286/antares/compare/v0.1.7...v0.1.8) (2021-05-22)
### Bug Fixes
* internal id not removed before row update ([0f10c9e](https://github.com/Fabio286/antares/commit/0f10c9e824b679cfebd8a31085236da3d38a7953))
* unable to add new ENUM fields ([1e37f2a](https://github.com/Fabio286/antares/commit/1e37f2a96f660a36f2739fea57ca298059e9c31a))
* unable to delete table rows ([0d61371](https://github.com/Fabio286/antares/commit/0d6137195da9e0e9afe68f6d3ebcd50e913a888e))
### Improvements
* improved the way how field default value are handled ([7a766f0](https://github.com/Fabio286/antares/commit/7a766f04e668868e8844aac1d7d445bc2da21558))
### [0.1.7](https://github.com/Fabio286/antares/compare/v0.1.6...v0.1.7) (2021-05-16)
### Bug Fixes
* row loses internal id after cell update ([854472c](https://github.com/Fabio286/antares/commit/854472c7a3d8442b1eede12f978cad5aa684094e))
* **MySQL:** connection loses schema in some conditions ([6b0b8b1](https://github.com/Fabio286/antares/commit/6b0b8b19d7176ef8647d6f401a33315f8732fdf3))
* issue with ENUM and SET fields on table filler modal ([475397c](https://github.com/Fabio286/antares/commit/475397ca34c5b7d8925e2d97d32216d5b80d8211))
* issue with ENUM and SET length when creating a new field ([7a62131](https://github.com/Fabio286/antares/commit/7a62131cc707aa1c98bb12513de76229472b7c38))
* multiple row select on sorted tables not work properly ([c7663be](https://github.com/Fabio286/antares/commit/c7663be338ccb5ff31e241e824593531ad95bd32))
### Improvements
* **core:** increased connection pool size to improve performance ([ae103e5](https://github.com/Fabio286/antares/commit/ae103e5477ad190c541d0f29e277c41de6947063))
* **MySQL:** improved connections pool handling ([434711a](https://github.com/Fabio286/antares/commit/434711a360bd7539d2ec3adec92e7ccc96fa828e))
### [0.1.6](https://github.com/Fabio286/antares/compare/v0.1.5...v0.1.6) (2021-05-08) ### [0.1.6](https://github.com/Fabio286/antares/compare/v0.1.5...v0.1.6) (2021-05-08)

View File

@@ -4,7 +4,7 @@
# Antares SQL Client # Antares SQL Client
![GitHub package.json version](https://img.shields.io/github/package-json/v/fabio286/antares) ![GitHub All Releases](https://img.shields.io/github/downloads/fabio286/antares/total) ![GitHub](https://img.shields.io/github/license/fabio286/antares) [![antares](https://snapcraft.io/antares/badge.svg)](https://snapcraft.io/antares) [![antares](https://snapcraft.io/antares/trending.svg?name=0)](https://snapcraft.io/antares) [![Plant a Tree](https://raw.githubusercontent.com/Fabio286/treedom-badge/master/svg/plant-a-tree.svg)](https://www.treedom.net/en/user/fabio-di-stasio/event/antares-for-the-planet) ![GitHub package.json version](https://img.shields.io/github/package-json/v/fabio286/antares) [![Build Status](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Factions-badge.atrox.dev%2Ffabio286%2Fantares%2Fbadge&style=flat)](https://actions-badge.atrox.dev/fabio286/antares/goto) ![GitHub All Releases](https://img.shields.io/github/downloads/fabio286/antares/total) ![GitHub](https://img.shields.io/github/license/fabio286/antares) [![antares](https://snapcraft.io/antares/badge.svg)](https://snapcraft.io/antares) [![antares](https://snapcraft.io/antares/trending.svg?name=0)](https://snapcraft.io/antares) [![Twitter Follow](https://img.shields.io/twitter/follow/AntaresSQL?style=social)](https://twitter.com/AntaresSQL) [![Plant a Tree](https://raw.githubusercontent.com/Fabio286/treedom-badge/master/svg/plant-a-tree.svg)](https://www.treedom.net/en/user/fabio-di-stasio/event/antares-for-the-planet)
Antares is an SQL client based on [Electron.js](https://github.com/electron/electron) and [Vue.js](https://github.com/vuejs/vue) that aims to become a useful tool, especially for developers. Antares is an SQL client based on [Electron.js](https://github.com/electron/electron) and [Vue.js](https://github.com/vuejs/vue) that aims to become a useful tool, especially for developers.
My target is to support as many databases as possible, and all major operating systems, including the ARM versions. My target is to support as many databases as possible, and all major operating systems, including the ARM versions.
@@ -83,7 +83,7 @@ This is a roadmap with major features will come in near future.
#### • ARM #### • ARM
- [ ] Windows - [ ] Windows
- [ ] Linux - [x] Linux
- [ ] MacOS - [ ] MacOS
## Translations ## Translations

View File

@@ -1,20 +1,22 @@
{ {
"name": "antares", "name": "antares",
"productName": "Antares", "productName": "Antares",
"version": "0.1.6", "version": "0.1.9",
"description": "A cross-platform easy to use SQL client.", "description": "A cross-platform easy to use SQL client.",
"license": "MIT", "license": "MIT",
"repository": "https://github.com/Fabio286/antares.git", "repository": "https://github.com/Fabio286/antares.git",
"scripts": { "scripts": {
"dev": "cross-env NODE_ENV=development electron-webpack dev", "dev": "cross-env NODE_ENV=development electron-webpack dev",
"compile": "electron-webpack", "compile": "electron-webpack",
"build": "cross-env NODE_ENV=production npm run compile && electron-builder", "build": "cross-env NODE_ENV=production npm run compile",
"build:appx": "npm run build -- --win appx", "build:local": "npm run build && electron-builder",
"build:appx": "npm run build:local -- --win appx",
"release": "standard-version", "release": "standard-version",
"release:pre": "npm run release -- --prerelease alpha", "release:pre": "npm run release -- --prerelease alpha",
"test": "npm run lint", "test": "npm run lint",
"lint": "eslint . --ext .js,.vue && stylelint \"./src/**/*.{css,scss,sass,vue}\"", "lint": "eslint . --ext .js,.vue && stylelint \"./src/**/*.{css,scss,sass,vue}\"",
"lint:fix": "eslint . --ext .js,.vue --fix && stylelint \"./src/**/*.{css,scss,sass,vue}\" --fix" "lint:fix": "eslint . --ext .js,.vue --fix && stylelint \"./src/**/*.{css,scss,sass,vue}\" --fix",
"postinstall": "electron-builder install-app-deps"
}, },
"author": "Fabio Di Stasio <fabio286@gmail.com>", "author": "Fabio Di Stasio <fabio286@gmail.com>",
"build": { "build": {
@@ -26,24 +28,28 @@
"portable" "portable"
] ]
}, },
"dmg": { "mac": {
"contents": [ "target": {
{ "target": "default",
"x": 130, "arch": [
"y": 220 "x64"
},
{
"x": 410,
"y": 220,
"type": "link",
"path": "/Applications"
}
] ]
}
}, },
"linux": { "linux": {
"target": [ "target": [
"deb", {
"AppImage" "target": "deb",
"arch": "x64"
},
{
"target": "AppImage",
"arch": [
"x64",
"armv7l",
"arm64"
]
}
], ],
"category": "Development" "category": "Development"
}, },
@@ -59,6 +65,20 @@
"identityName": "62514FabioDiStasio.AntaresSQLClient", "identityName": "62514FabioDiStasio.AntaresSQLClient",
"publisher": "CN=1A2729ED-865C-41D2-9038-39AE2A63AA52", "publisher": "CN=1A2729ED-865C-41D2-9038-39AE2A63AA52",
"applicationId": "FabioDiStasio.AntaresSQLClient" "applicationId": "FabioDiStasio.AntaresSQLClient"
},
"dmg": {
"contents": [
{
"x": 130,
"y": 220
},
{
"x": 410,
"y": 220,
"type": "link",
"path": "/Applications"
}
]
} }
}, },
"electronWebpack": { "electronWebpack": {
@@ -72,8 +92,8 @@
"ace-builds": "^1.4.12", "ace-builds": "^1.4.12",
"electron-log": "^4.3.5", "electron-log": "^4.3.5",
"electron-store": "^8.0.0", "electron-store": "^8.0.0",
"electron-updater": "^4.3.5", "electron-updater": "^4.3.9",
"faker": "^5.3.1", "faker": "^5.5.3",
"marked": "^2.0.2", "marked": "^2.0.2",
"moment": "^2.29.1", "moment": "^2.29.1",
"mysql2": "^2.2.5", "mysql2": "^2.2.5",
@@ -85,13 +105,13 @@
"v-mask": "^2.2.4", "v-mask": "^2.2.4",
"vue-i18n": "^8.24.4", "vue-i18n": "^8.24.4",
"vuedraggable": "^2.24.3", "vuedraggable": "^2.24.3",
"vuex": "^3.6.0" "vuex": "^3.6.2"
}, },
"devDependencies": { "devDependencies": {
"@babel/eslint-parser": "^7.13.14", "@babel/eslint-parser": "^7.14.3",
"cross-env": "^7.0.2", "cross-env": "^7.0.2",
"electron": "^12.0.7", "electron": "^12.0.9",
"electron-builder": "^22.9.1", "electron-builder": "22.10.5",
"electron-devtools-installer": "^3.2.0", "electron-devtools-installer": "^3.2.0",
"electron-webpack": "^2.8.2", "electron-webpack": "^2.8.2",
"electron-webpack-vue": "^2.4.0", "electron-webpack-vue": "^2.4.0",
@@ -101,8 +121,8 @@
"eslint-plugin-node": "^11.1.0", "eslint-plugin-node": "^11.1.0",
"eslint-plugin-promise": "^5.1.0", "eslint-plugin-promise": "^5.1.0",
"eslint-plugin-vue": "^7.9.0", "eslint-plugin-vue": "^7.9.0",
"node-sass": "^5.0.0", "sass": "^1.32.13",
"sass-loader": "^10.1.1", "sass-loader": "^10.2.0",
"standard-version": "^9.3.0", "standard-version": "^9.3.0",
"stylelint": "^13.13.1", "stylelint": "^13.13.1",
"stylelint-config-standard": "^22.0.0", "stylelint-config-standard": "^22.0.0",

View File

@@ -71,7 +71,7 @@ export default connections => {
const connection = ClientsFactory.getConnection({ const connection = ClientsFactory.getConnection({
client: conn.client, client: conn.client,
params, params,
poolSize: 1 poolSize: 5
}); });
await connection.connect(); await connection.connect();

View File

@@ -128,7 +128,7 @@ export default connections => {
if (!query) return; if (!query) return;
try { try {
const result = await connections[uid].raw(query, { nest: true, details: true }); const result = await connections[uid].raw(query, { nest: true, details: true, schema });
return { status: 'success', response: result }; return { status: 'success', response: result };
} }

View File

@@ -1,5 +1,5 @@
'use strict'; 'use strict';
import mysql from 'mysql2'; import mysql from 'mysql2/promise';
import { AntaresCore } from '../AntaresCore'; import { AntaresCore } from '../AntaresCore';
import dataTypes from 'common/data-types/mysql'; import dataTypes from 'common/data-types/mysql';
@@ -102,8 +102,10 @@ export class MySQLClient extends AntaresCore {
* @memberof MySQLClient * @memberof MySQLClient
*/ */
async connect () { async connect () {
delete this._params.application_name;
if (!this._poolSize) if (!this._poolSize)
this._connection = mysql.createConnection(this._params); this._connection = await mysql.createConnection(this._params);
else { else {
this._connection = mysql.createPool({ this._connection = mysql.createPool({
...this._params, ...this._params,
@@ -307,6 +309,48 @@ export class MySQLClient extends AntaresCore {
.orderBy({ ORDINAL_POSITION: 'ASC' }) .orderBy({ ORDINAL_POSITION: 'ASC' })
.run(); .run();
const { rows: fields } = await this.raw(`SHOW CREATE TABLE ${schema}.${table}`);
const remappedFields = fields.map(row => {
let n = 0;
return row['Create Table']
.split('')
.reduce((acc, curr) => {
if (curr === ')') n--;
if (n !== 0) acc += curr;
if (curr === '(') n++;
return acc;
}, '')
.replaceAll('\n', '')
.split(',')
.map(f => {
try {
const fieldArr = f.trim().split(' ');
const nameAndType = fieldArr.slice(0, 2);
if (nameAndType[0].charAt(0) !== '`') return false;
const details = fieldArr.slice(2).join(' ');
const defaultValue = details.includes('DEFAULT') ? details.match(/(?<=DEFAULT ).*?$/gs)[0] : null;
const typeAndLength = nameAndType[1].replace(')', '').split('(');
return {
name: nameAndType[0].replaceAll('`', ''),
type: typeAndLength[0].toUpperCase(),
length: typeAndLength[1] ? typeAndLength[1] : null,
default: defaultValue
};
}
catch (err) {
return false;
}
})
.filter(Boolean)
.reduce((acc, curr) => {
acc[curr.name] = curr;
return acc;
}, {});
})[0];
return rows.map(field => { return rows.map(field => {
let numLength = field.COLUMN_TYPE.match(/int\(([^)]+)\)/); let numLength = field.COLUMN_TYPE.match(/int\(([^)]+)\)/);
numLength = numLength ? +numLength.pop() : null; numLength = numLength ? +numLength.pop() : null;
@@ -317,7 +361,7 @@ export class MySQLClient extends AntaresCore {
return { return {
name: field.COLUMN_NAME, name: field.COLUMN_NAME,
key: field.COLUMN_KEY.toLowerCase(), key: field.COLUMN_KEY.toLowerCase(),
type: field.DATA_TYPE.toUpperCase(), type: remappedFields[field.COLUMN_NAME].type,
schema: field.TABLE_SCHEMA, schema: field.TABLE_SCHEMA,
table: field.TABLE_NAME, table: field.TABLE_NAME,
numPrecision: field.NUMERIC_PRECISION, numPrecision: field.NUMERIC_PRECISION,
@@ -329,7 +373,7 @@ export class MySQLClient extends AntaresCore {
unsigned: field.COLUMN_TYPE.includes('unsigned'), unsigned: field.COLUMN_TYPE.includes('unsigned'),
zerofill: field.COLUMN_TYPE.includes('zerofill'), zerofill: field.COLUMN_TYPE.includes('zerofill'),
order: field.ORDINAL_POSITION, order: field.ORDINAL_POSITION,
default: field.COLUMN_DEFAULT, default: remappedFields[field.COLUMN_NAME].default,
charset: field.CHARACTER_SET_NAME, charset: field.CHARACTER_SET_NAME,
collation: field.COLLATION_NAME, collation: field.COLLATION_NAME,
autoIncrement: field.EXTRA.includes('auto_increment'), autoIncrement: field.EXTRA.includes('auto_increment'),
@@ -488,7 +532,7 @@ export class MySQLClient extends AntaresCore {
* @memberof MySQLClient * @memberof MySQLClient
*/ */
async dropView (params) { async dropView (params) {
const sql = `DROP VIEW \`${params.view}\``; const sql = `DROP VIEW \`${this._schema}\`.\`${params.view}\``;
return await this.raw(sql); return await this.raw(sql);
} }
@@ -500,10 +544,10 @@ export class MySQLClient extends AntaresCore {
*/ */
async alterView (params) { async alterView (params) {
const { view } = params; const { view } = params;
let sql = `ALTER ALGORITHM = ${view.algorithm}${view.definer ? ` DEFINER=${view.definer}` : ''} SQL SECURITY ${view.security} VIEW \`${view.oldName}\` AS ${view.sql} ${view.updateOption ? `WITH ${view.updateOption} CHECK OPTION` : ''}`; let sql = `ALTER ALGORITHM = ${view.algorithm}${view.definer ? ` DEFINER=${view.definer}` : ''} SQL SECURITY ${view.security} VIEW \`${this._schema}\`.\`${view.oldName}\` AS ${view.sql} ${view.updateOption ? `WITH ${view.updateOption} CHECK OPTION` : ''}`;
if (view.name !== view.oldName) if (view.name !== view.oldName)
sql += `; RENAME TABLE \`${view.oldName}\` TO \`${view.name}\``; sql += `; RENAME TABLE \`${this._schema}\`.\`${view.oldName}\` TO \`${this._schema}\`.\`${view.name}\``;
return await this.raw(sql); return await this.raw(sql);
} }
@@ -515,7 +559,7 @@ export class MySQLClient extends AntaresCore {
* @memberof MySQLClient * @memberof MySQLClient
*/ */
async createView (view) { async createView (view) {
const sql = `CREATE ALGORITHM = ${view.algorithm} ${view.definer ? `DEFINER=${view.definer} ` : ''}SQL SECURITY ${view.security} VIEW \`${view.name}\` AS ${view.sql} ${view.updateOption ? `WITH ${view.updateOption} CHECK OPTION` : ''}`; const sql = `CREATE ALGORITHM = ${view.algorithm} ${view.definer ? `DEFINER=${view.definer} ` : ''}SQL SECURITY ${view.security} VIEW \`${this._schema}\`.\`${view.name}\` AS ${view.sql} ${view.updateOption ? `WITH ${view.updateOption} CHECK OPTION` : ''}`;
return await this.raw(sql); return await this.raw(sql);
} }
@@ -548,7 +592,7 @@ export class MySQLClient extends AntaresCore {
* @memberof MySQLClient * @memberof MySQLClient
*/ */
async dropTrigger (params) { async dropTrigger (params) {
const sql = `DROP TRIGGER \`${params.trigger}\``; const sql = `DROP TRIGGER \`${this._schema}\`.\`${params.trigger}\``;
return await this.raw(sql); return await this.raw(sql);
} }
@@ -581,7 +625,7 @@ export class MySQLClient extends AntaresCore {
* @memberof MySQLClient * @memberof MySQLClient
*/ */
async createTrigger (trigger) { async createTrigger (trigger) {
const sql = `CREATE ${trigger.definer ? `DEFINER=${trigger.definer} ` : ''}TRIGGER \`${trigger.name}\` ${trigger.event1} ${trigger.event2} ON \`${trigger.table}\` FOR EACH ROW ${trigger.sql}`; const sql = `CREATE ${trigger.definer ? `DEFINER=${trigger.definer} ` : ''}TRIGGER \`${this._schema}\`.\`${trigger.name}\` ${trigger.event1} ${trigger.event2} ON \`${trigger.table}\` FOR EACH ROW ${trigger.sql}`;
return await this.raw(sql, { split: false }); return await this.raw(sql, { split: false });
} }
@@ -655,7 +699,7 @@ export class MySQLClient extends AntaresCore {
* @memberof MySQLClient * @memberof MySQLClient
*/ */
async dropRoutine (params) { async dropRoutine (params) {
const sql = `DROP PROCEDURE \`${params.routine}\``; const sql = `DROP PROCEDURE \`${this._schema}\`.\`${params.routine}\``;
return await this.raw(sql); return await this.raw(sql);
} }
@@ -782,7 +826,7 @@ export class MySQLClient extends AntaresCore {
* @memberof MySQLClient * @memberof MySQLClient
*/ */
async dropFunction (params) { async dropFunction (params) {
const sql = `DROP FUNCTION \`${params.func}\``; const sql = `DROP FUNCTION \`${this._schema}\`.\`${params.func}\``;
return await this.raw(sql); return await this.raw(sql);
} }
@@ -822,7 +866,7 @@ export class MySQLClient extends AntaresCore {
const body = func.returns ? func.sql : 'BEGIN\n RETURN 0;\nEND'; const body = func.returns ? func.sql : 'BEGIN\n RETURN 0;\nEND';
const sql = `CREATE ${func.definer ? `DEFINER=${func.definer} ` : ''}FUNCTION \`${func.name}\`(${parameters}) RETURNS ${func.returns || 'SMALLINT'}${func.returnsLength ? `(${func.returnsLength})` : ''} const sql = `CREATE ${func.definer ? `DEFINER=${func.definer} ` : ''}FUNCTION \`${this._schema}\`.\`${func.name}\`(${parameters}) RETURNS ${func.returns || 'SMALLINT'}${func.returnsLength ? `(${func.returnsLength})` : ''}
LANGUAGE SQL LANGUAGE SQL
${func.deterministic ? 'DETERMINISTIC' : 'NOT DETERMINISTIC'} ${func.deterministic ? 'DETERMINISTIC' : 'NOT DETERMINISTIC'}
${func.dataAccess} ${func.dataAccess}
@@ -874,7 +918,7 @@ export class MySQLClient extends AntaresCore {
* @memberof MySQLClient * @memberof MySQLClient
*/ */
async dropEvent (params) { async dropEvent (params) {
const sql = `DROP EVENT \`${params.scheduler}\``; const sql = `DROP EVENT \`${this._schema}\`.\`${params.scheduler}\``;
return await this.raw(sql); return await this.raw(sql);
} }
@@ -890,13 +934,13 @@ export class MySQLClient extends AntaresCore {
if (scheduler.execution === 'EVERY' && scheduler.every[0].includes('-')) if (scheduler.execution === 'EVERY' && scheduler.every[0].includes('-'))
scheduler.every[0] = `'${scheduler.every[0]}'`; scheduler.every[0] = `'${scheduler.every[0]}'`;
const sql = `ALTER ${scheduler.definer ? ` DEFINER=${scheduler.definer}` : ''} EVENT \`${scheduler.oldName}\` const sql = `ALTER ${scheduler.definer ? ` DEFINER=${scheduler.definer}` : ''} EVENT \`${this._schema}\`.\`${scheduler.oldName}\`
ON SCHEDULE ON SCHEDULE
${scheduler.execution === 'EVERY' ${scheduler.execution === 'EVERY'
? `EVERY ${scheduler.every.join(' ')}${scheduler.starts ? ` STARTS '${scheduler.starts}'` : ''}${scheduler.ends ? ` ENDS '${scheduler.ends}'` : ''}` ? `EVERY ${scheduler.every.join(' ')}${scheduler.starts ? ` STARTS '${scheduler.starts}'` : ''}${scheduler.ends ? ` ENDS '${scheduler.ends}'` : ''}`
: `AT '${scheduler.at}'`} : `AT '${scheduler.at}'`}
ON COMPLETION${!scheduler.preserve ? ' NOT' : ''} PRESERVE ON COMPLETION${!scheduler.preserve ? ' NOT' : ''} PRESERVE
${scheduler.name !== scheduler.oldName ? `RENAME TO \`${scheduler.name}\`` : ''} ${scheduler.name !== scheduler.oldName ? `RENAME TO \`${this._schema}\`.\`${scheduler.name}\`` : ''}
${scheduler.state} ${scheduler.state}
COMMENT '${scheduler.comment}' COMMENT '${scheduler.comment}'
DO ${scheduler.sql}`; DO ${scheduler.sql}`;
@@ -911,7 +955,7 @@ export class MySQLClient extends AntaresCore {
* @memberof MySQLClient * @memberof MySQLClient
*/ */
async createEvent (scheduler) { async createEvent (scheduler) {
const sql = `CREATE ${scheduler.definer ? ` DEFINER=${scheduler.definer}` : ''} EVENT \`${scheduler.name}\` const sql = `CREATE ${scheduler.definer ? ` DEFINER=${scheduler.definer}` : ''} EVENT \`${this._schema}\`.\`${scheduler.name}\`
ON SCHEDULE ON SCHEDULE
${scheduler.execution === 'EVERY' ${scheduler.execution === 'EVERY'
? `EVERY ${scheduler.every.join(' ')}${scheduler.starts ? ` STARTS '${scheduler.starts}'` : ''}${scheduler.ends ? ` ENDS '${scheduler.ends}'` : ''}` ? `EVERY ${scheduler.every.join(' ')}${scheduler.starts ? ` STARTS '${scheduler.starts}'` : ''}${scheduler.ends ? ` ENDS '${scheduler.ends}'` : ''}`
@@ -1048,7 +1092,7 @@ export class MySQLClient extends AntaresCore {
engine engine
} = params; } = params;
const sql = `CREATE TABLE \`${name}\` (\`${name}_ID\` INT NULL) COMMENT='${comment}', COLLATE='${collation}', ENGINE=${engine}`; const sql = `CREATE TABLE \`${this._schema}\`.\`${name}\` (\`${name}_ID\` INT NULL) COMMENT='${comment}', COLLATE='${collation}', ENGINE=${engine}`;
return await this.raw(sql); return await this.raw(sql);
} }
@@ -1082,7 +1126,7 @@ export class MySQLClient extends AntaresCore {
// ADD FIELDS // ADD FIELDS
additions.forEach(addition => { additions.forEach(addition => {
const typeInfo = this._getTypeInfo(addition.type); const typeInfo = this._getTypeInfo(addition.type);
const length = typeInfo.length ? addition.numLength || addition.charLength || addition.datePrecision : false; const length = typeInfo.length ? addition.enumValues || addition.numLength || addition.charLength || addition.datePrecision : false;
alterColumns.push(`ADD COLUMN \`${addition.name}\` alterColumns.push(`ADD COLUMN \`${addition.name}\`
${addition.type.toUpperCase()}${length ? `(${length})` : ''} ${addition.type.toUpperCase()}${length ? `(${length})` : ''}
@@ -1182,7 +1226,7 @@ export class MySQLClient extends AntaresCore {
sql += alterColumns.join(', '); sql += alterColumns.join(', ');
// RENAME // RENAME
if (options.name) sql += `; RENAME TABLE \`${table}\` TO \`${options.name}\``; if (options.name) sql += `; RENAME TABLE \`${this._schema}\`.\`${table}\` TO \`${this._schema}\`.\`${options.name}\``;
return await this.raw(sql); return await this.raw(sql);
} }
@@ -1273,18 +1317,24 @@ export class MySQLClient extends AntaresCore {
* @memberof MySQLClient * @memberof MySQLClient
*/ */
async raw (sql, args) { async raw (sql, args) {
if (process.env.NODE_ENV === 'development') this._logger(sql);// TODO: replace BLOB content with a placeholder
args = { args = {
nest: false, nest: false,
details: false, details: false,
split: true, split: true,
...args ...args
}; };
const nestTables = args.nest ? '.' : false; const nestTables = args.nest ? '.' : false;
const resultsArr = []; const resultsArr = [];
let paramsArr = []; let paramsArr = [];
const queries = args.split ? sql.split(/((?:[^;'"]*(?:"(?:\\.|[^"])*"|'(?:\\.|[^'])*')[^;'"]*)+)|;/gm) : [sql]; const queries = args.split ? sql.split(/((?:[^;'"]*(?:"(?:\\.|[^"])*"|'(?:\\.|[^'])*')[^;'"]*)+)|;/gm) : [sql];
const isPool = typeof this._connection.getConnection === 'function';
const connection = isPool ? await this._connection.getConnection() : this._connection;
if (process.env.NODE_ENV === 'development') this._logger(sql);// TODO: replace BLOB content with a placeholder if (args.schema)
await connection.query(`USE \`${args.schema}\``);
for (const query of queries) { for (const query of queries) {
if (!query) continue; if (!query) continue;
@@ -1293,13 +1343,10 @@ export class MySQLClient extends AntaresCore {
let keysArr = []; let keysArr = [];
const { rows, report, fields, keys, duration } = await new Promise((resolve, reject) => { const { rows, report, fields, keys, duration } = await new Promise((resolve, reject) => {
this._connection.query({ sql: query, nestTables }, async (err, response, fields) => { connection.query({ sql: query, nestTables }).then(async ([response, fields]) => {
timeStop = new Date(); timeStop = new Date();
const queryResult = response; const queryResult = response;
if (err)
reject(err);
else {
let remappedFields = fields let remappedFields = fields
? fields.map(field => { ? fields.map(field => {
if (!field || Array.isArray(field)) if (!field || Array.isArray(field))
@@ -1341,7 +1388,7 @@ export class MySQLClient extends AntaresCore {
remappedFields = remappedFields.map(field => { remappedFields = remappedFields.map(field => {
const detailedField = response.find(f => f.name === field.name); const detailedField = response.find(f => f.name === field.name);
if (detailedField && field.orgTable === paramObj.table && field.schema === paramObj.schema) if (detailedField && field.orgTable === paramObj.table && field.schema === paramObj.schema)
field = { ...detailedField, ...field }; field = { ...field, ...detailedField };
return field; return field;
}); });
} }
@@ -1367,13 +1414,14 @@ export class MySQLClient extends AntaresCore {
fields: remappedFields, fields: remappedFields,
keys: keysArr keys: keysArr
}); });
} }).catch(reject);
});
}); });
resultsArr.push({ rows, report, fields, keys, duration }); resultsArr.push({ rows, report, fields, keys, duration });
} }
if (isPool) connection.release();
return resultsArr.length === 1 ? resultsArr[0] : resultsArr; return resultsArr.length === 1 ? resultsArr[0] : resultsArr;
} }
} }

View File

@@ -816,97 +816,6 @@ export class PostgreSQLClient extends AntaresCore {
return await this.raw(sql, { split: false }); return await this.raw(sql, { split: false });
} }
/**
* SHOW CREATE EVENT
*
* @returns {Array.<Object>} view informations
* @memberof PostgreSQLClient
*/
// async getEventInformations ({ schema, scheduler }) {
// const sql = `SHOW CREATE EVENT \`${schema}\`.\`${scheduler}\``;
// const results = await this.raw(sql);
// return results.rows.map(row => {
// const schedule = row['Create Event'];
// const execution = schedule.includes('EVERY') ? 'EVERY' : 'ONCE';
// const every = execution === 'EVERY' ? row['Create Event'].match(/(?<=EVERY )(\s*([^\s]+)){0,2}/gs)[0].replaceAll('\'', '').split(' ') : [];
// const starts = execution === 'EVERY' && schedule.includes('STARTS') ? schedule.match(/(?<=STARTS ').*?(?='\s)/gs)[0] : '';
// const ends = execution === 'EVERY' && schedule.includes('ENDS') ? schedule.match(/(?<=ENDS ').*?(?='\s)/gs)[0] : '';
// const at = execution === 'ONCE' && schedule.includes('AT') ? schedule.match(/(?<=AT ').*?(?='\s)/gs)[0] : '';
// return {
// definer: row['Create Event'].match(/(?<=DEFINER=).*?(?=\s)/gs)[0],
// sql: row['Create Event'].match(/(?<=DO )(.*)/gs)[0],
// name: row.Event,
// comment: row['Create Event'].match(/(?<=COMMENT ').*?(?=')/gs) ? row['Create Event'].match(/(?<=COMMENT ').*?(?=')/gs)[0] : '',
// state: row['Create Event'].includes('ENABLE') ? 'ENABLE' : row['Create Event'].includes('DISABLE ON SLAVE') ? 'DISABLE ON SLAVE' : 'DISABLE',
// preserve: row['Create Event'].includes('ON COMPLETION PRESERVE'),
// execution,
// every,
// starts,
// ends,
// at
// };
// })[0];
// }
/**
* DROP EVENT
*
* @returns {Array.<Object>} parameters
* @memberof PostgreSQLClient
*/
// async dropEvent (params) {
// const sql = `DROP EVENT \`${params.scheduler}\``;
// return await this.raw(sql);
// }
/**
* ALTER EVENT
*
* @returns {Array.<Object>} parameters
* @memberof PostgreSQLClient
*/
// async alterEvent (params) {
// const { scheduler } = params;
// if (scheduler.execution === 'EVERY' && scheduler.every[0].includes('-'))
// scheduler.every[0] = `'${scheduler.every[0]}'`;
// const sql = `ALTER ${scheduler.definer ? ` DEFINER=${scheduler.definer}` : ''} EVENT \`${scheduler.oldName}\`
// ON SCHEDULE
// ${scheduler.execution === 'EVERY'
// ? `EVERY ${scheduler.every.join(' ')}${scheduler.starts ? ` STARTS '${scheduler.starts}'` : ''}${scheduler.ends ? ` ENDS '${scheduler.ends}'` : ''}`
// : `AT '${scheduler.at}'`}
// ON COMPLETION${!scheduler.preserve ? ' NOT' : ''} PRESERVE
// ${scheduler.name !== scheduler.oldName ? `RENAME TO \`${scheduler.name}\`` : ''}
// ${scheduler.state}
// COMMENT '${scheduler.comment}'
// DO ${scheduler.sql}`;
// return await this.raw(sql, { split: false });
// }
/**
* CREATE EVENT
*
* @returns {Array.<Object>} parameters
* @memberof PostgreSQLClient
*/
// async createEvent (scheduler) {
// const sql = `CREATE ${scheduler.definer ? ` DEFINER=${scheduler.definer}` : ''} EVENT \`${scheduler.name}\`
// ON SCHEDULE
// ${scheduler.execution === 'EVERY'
// ? `EVERY ${scheduler.every.join(' ')}${scheduler.starts ? ` STARTS '${scheduler.starts}'` : ''}${scheduler.ends ? ` ENDS '${scheduler.ends}'` : ''}`
// : `AT '${scheduler.at}'`}
// ON COMPLETION${!scheduler.preserve ? ' NOT' : ''} PRESERVE
// ${scheduler.state}
// COMMENT '${scheduler.comment}'
// DO ${scheduler.sql}`;
// return await this.raw(sql, { split: false });
// }
/** /**
* SELECT * FROM pg_collation * SELECT * FROM pg_collation
* *
@@ -1250,8 +1159,8 @@ export class PostgreSQLClient extends AntaresCore {
...args ...args
}; };
if (args.nest && this._schema !== 'public') if (args.schema && args.schema !== 'public')
await this.use(this._schema); await this.use(args.schema);
const resultsArr = []; const resultsArr = [];
let paramsArr = []; let paramsArr = [];

View File

@@ -66,6 +66,21 @@
:type="inputProps().type" :type="inputProps().type"
:disabled="!isChecked" :disabled="!isChecked"
> >
<select
v-else-if="enumArray"
v-model="selectedValue"
class="form-select"
:disabled="!isChecked"
@change="onChange"
>
<option
v-for="val in enumArray"
:key="val"
:value="val"
>
{{ val }}
</option>
</select>
<input <input
v-else v-else
ref="formInput" ref="formInput"
@@ -121,7 +136,8 @@ export default {
selectedMethod: '', selectedMethod: '',
selectedValue: '', selectedValue: '',
debounceTimeout: null, debounceTimeout: null,
methodParams: {} methodParams: {},
enumArray: null
}; };
}, },
computed: { computed: {
@@ -150,8 +166,14 @@ export default {
}, },
watch: { watch: {
fieldObj () { fieldObj () {
if (this.fieldObj) if (this.fieldObj) {
if (Array.isArray(this.fieldObj.value)) {
this.enumArray = this.fieldObj.value;
this.selectedValue = this.fieldObj.value[0];
}
else
this.selectedValue = this.fieldObj.value; this.selectedValue = this.fieldObj.value;
}
}, },
selectedGroup () { selectedGroup () {
if (this.fakerMethods.length) if (this.fakerMethods.length)

View File

@@ -51,7 +51,8 @@ export default {
}), }),
isValidDefault () { isValidDefault () {
if (!this.foreignList.length) return true; if (!this.foreignList.length) return true;
return this.value === null || this.foreignList.some(foreign => foreign.foreign_column.toString() === this.value.toString()); if (this.value === null) return false;
return this.foreignList.some(foreign => foreign.foreign_column.toString() === this.value.toString());
} }
}, },
async created () { async created () {
@@ -65,7 +66,7 @@ export default {
try { // Field data try { // Field data
const { status, response } = await Tables.getTableColumns(params); const { status, response } = await Tables.getTableColumns(params);
if (status === 'success') { if (status === 'success') {
const textField = response.find(field => [...TEXT, ...LONG_TEXT].includes(field.type)); const textField = response.find(field => [...TEXT, ...LONG_TEXT].includes(field.type) && field.name !== this.keyUsage.refField);
foreignDesc = textField ? textField.name : false; foreignDesc = textField ? textField.name : false;
} }
else else

View File

@@ -250,10 +250,15 @@ export default {
if (field.default === 'NULL') fieldDefault = null; if (field.default === 'NULL') fieldDefault = null;
else { else {
if ([...NUMBER, ...FLOAT].includes(field.type)) if ([...NUMBER, ...FLOAT].includes(field.type))
fieldDefault = +field.default; fieldDefault = Number.isNaN(+field.default) ? null : +field.default;
if ([...TEXT, ...LONG_TEXT].includes(field.type)) if ([...TEXT, ...LONG_TEXT].includes(field.type)) {
fieldDefault = field.default ? field.default.substring(1, field.default.length - 1) : ''; fieldDefault = field.default
? field.default.includes('\'')
? field.default.split('\'')[1]
: field.default
: '';
}
if ([...TIME, ...DATE].includes(field.type)) if ([...TIME, ...DATE].includes(field.type))
fieldDefault = field.default; fieldDefault = field.default;
@@ -269,6 +274,9 @@ export default {
fieldDefault = moment().format(`YYYY-MM-DD HH:mm:ss${datePrecision}`); fieldDefault = moment().format(`YYYY-MM-DD HH:mm:ss${datePrecision}`);
} }
} }
if (field.enumValues)
fieldDefault = field.enumValues.replaceAll('\'', '').split(',');
} }
rowObj[field.name] = { value: fieldDefault }; rowObj[field.name] = { value: fieldDefault };

View File

@@ -227,7 +227,7 @@
<h4>{{ appName }}</h4> <h4>{{ appName }}</h4>
<p> <p>
{{ $t('word.version') }} {{ appVersion }}<br> {{ $t('word.version') }} {{ appVersion }}<br>
<a class="c-hand" @click="openOutside('https://github.com/Fabio286/antares')">GitHub</a> | <a class="c-hand" @click="openOutside('https://antares-sql.app/')">Website</a><br> <a class="c-hand" @click="openOutside('https://github.com/Fabio286/antares')"><i class="mdi mdi-github d-inline" /> GitHub</a> <a class="c-hand" @click="openOutside('https://twitter.com/AntaresSQL')"><i class="mdi mdi-twitter d-inline" /> Twitter</a> <a class="c-hand" @click="openOutside('https://antares-sql.app/')"><i class="mdi mdi-web d-inline" /> Website</a><br>
<small>{{ $t('word.author') }} <a class="c-hand" @click="openOutside('https://github.com/Fabio286')">Fabio Di Stasio</a></small><br> <small>{{ $t('word.author') }} <a class="c-hand" @click="openOutside('https://github.com/Fabio286')">Fabio Di Stasio</a></small><br>
<small>{{ $t('message.madeWithJS') }}</small> <small>{{ $t('message.madeWithJS') }}</small>
</p> </p>

View File

@@ -96,8 +96,13 @@
class="cell-content" class="cell-content"
@dblclick="editON($event, localLength, 'length')" @dblclick="editON($event, localLength, 'length')"
> >
<span v-if="localRow.enumValues">
{{ localRow.enumValues }}
</span>
<span v-else>
{{ localLength }} {{ localLength }}
</span> </span>
</span>
<input <input
v-else-if="localRow.enumValues" v-else-if="localRow.enumValues"
ref="editField" ref="editField"
@@ -361,7 +366,7 @@ export default {
getWorkspace: 'workspaces/getWorkspace' getWorkspace: 'workspaces/getWorkspace'
}), }),
localLength () { localLength () {
return this.localRow.enumValues || this.localRow.numLength || this.localRow.charLength || this.localRow.datePrecision || this.localRow.numPrecision || 0; return this.localRow.numLength || this.localRow.charLength || this.localRow.datePrecision || this.localRow.numPrecision || 0;
}, },
fieldType () { fieldType () {
const fieldType = this.dataTypes.reduce((acc, group) => [...acc, ...group.types], []).filter(type => const fieldType = this.dataTypes.reduce((acc, group) => [...acc, ...group.types], []).filter(type =>
@@ -445,8 +450,13 @@ export default {
this.defaultValue.onUpdate = this.localRow.onUpdate; this.defaultValue.onUpdate = this.localRow.onUpdate;
this.defaultValue.type = this.localRow.defaultType; this.defaultValue.type = this.localRow.defaultType;
if (this.defaultValue.type === 'custom') if (this.defaultValue.type === 'custom') {
this.defaultValue.custom = this.localRow.default; this.defaultValue.custom = this.localRow.default
? this.localRow.default.includes('\'')
? this.localRow.default.split('\'')[1]
: this.localRow.default
: '';
}
if (this.defaultValue.type === 'expression') if (this.defaultValue.type === 'expression')
this.defaultValue.expression = this.localRow.default; this.defaultValue.expression = this.localRow.default;
}, },
@@ -492,11 +502,13 @@ export default {
this.localRow.numLength = null; this.localRow.numLength = null;
this.localRow.charLength = null; this.localRow.charLength = null;
this.localRow.datePrecision = null; this.localRow.datePrecision = null;
this.localRow.enumValues = '';
if (this.fieldType.length) { if (this.fieldType.length) {
if (['integer', 'float', 'binary', 'spatial'].includes(this.fieldType.group)) this.localRow.numLength = 11; if (['integer', 'float', 'binary', 'spatial'].includes(this.fieldType.group)) this.localRow.numLength = 11;
if (['string', 'other'].includes(this.fieldType.group)) this.localRow.charLength = 15; if (['string'].includes(this.fieldType.group)) this.localRow.charLength = 15;
if (['time'].includes(this.fieldType.group)) this.localRow.datePrecision = 0; if (['time'].includes(this.fieldType.group)) this.localRow.datePrecision = 0;
if (['other'].includes(this.fieldType.group)) this.localRow.enumValues = '\'valA\',\'valB\'';
} }
if (!this.fieldType.collation) if (!this.fieldType.collation)
@@ -523,7 +535,7 @@ export default {
break; break;
case 'custom': case 'custom':
this.localRow.autoIncrement = false; this.localRow.autoIncrement = false;
this.localRow.default = this.defaultValue.custom; this.localRow.default = Number.isNaN(+this.defaultValue.custom) ? `'${this.defaultValue.custom}'` : this.defaultValue.custom;
break; break;
case 'expression': case 'expression':
this.localRow.autoIncrement = false; this.localRow.autoIncrement = false;

View File

@@ -319,8 +319,6 @@ export default {
}, },
updateField (payload, row) { updateField (payload, row) {
const orgRow = this.localResults.find(lr => lr._id === row._id); const orgRow = this.localResults.find(lr => lr._id === row._id);
delete row._id;
delete orgRow._id;
Object.keys(orgRow).forEach(key => { // remap the row Object.keys(orgRow).forEach(key => { // remap the row
if (orgRow[key] instanceof Date && moment(orgRow[key]).isValid()) { // if datetime if (orgRow[key] instanceof Date && moment(orgRow[key]).isValid()) { // if datetime
@@ -370,7 +368,6 @@ export default {
}, },
setNull () { setNull () {
const row = this.localResults.find(row => this.selectedRows.includes(row._id)); const row = this.localResults.find(row => this.selectedRows.includes(row._id));
delete row._id;
const params = { const params = {
primary: this.primaryField.name, primary: this.primaryField.name,
@@ -408,15 +405,15 @@ export default {
this.selectedRows.push(row); this.selectedRows.push(row);
else { else {
const lastID = this.selectedRows.slice(-1)[0]; const lastID = this.selectedRows.slice(-1)[0];
const lastIndex = this.localResults.findIndex(el => el._id === lastID); const lastIndex = this.sortedResults.findIndex(el => el._id === lastID);
const clickedIndex = this.localResults.findIndex(el => el._id === row); const clickedIndex = this.sortedResults.findIndex(el => el._id === row);
if (lastIndex > clickedIndex) { if (lastIndex > clickedIndex) {
for (let i = clickedIndex; i < lastIndex; i++) for (let i = clickedIndex; i < lastIndex; i++)
this.selectedRows.push(this.localResults[i]._id); this.selectedRows.push(this.sortedResults[i]._id);
} }
else if (lastIndex < clickedIndex) { else if (lastIndex < clickedIndex) {
for (let i = clickedIndex; i > lastIndex; i--) for (let i = clickedIndex; i > lastIndex; i--)
this.selectedRows.push(this.localResults[i]._id); this.selectedRows.push(this.sortedResults[i]._id);
} }
} }
} }
@@ -435,6 +432,8 @@ export default {
sort (field) { sort (field) {
if (!this.isSortable) return; if (!this.isSortable) return;
this.selectedRows = [];
if (this.mode === 'query') if (this.mode === 'query')
field = `${this.getTable(this.resultsetIndex)}.${field}`; field = `${this.getTable(this.resultsetIndex)}.${field}`;

View File

@@ -19,6 +19,7 @@ export default class {
} }
static updateTableCell (params) { static updateTableCell (params) {
delete params.row._id;
return ipcRenderer.invoke('update-table-cell', params); return ipcRenderer.invoke('update-table-cell', params);
} }