mirror of
https://github.com/Fabio286/antares.git
synced 2025-06-05 21:59:22 +02:00
Compare commits
27 Commits
Author | SHA1 | Date | |
---|---|---|---|
c46224635a | |||
cc99491fe4 | |||
fe8435531e | |||
5d48fe08c7 | |||
4437d44486 | |||
9fe3680bbb | |||
da1947e4ef | |||
37a848df9d | |||
|
9816965e18 | ||
98165cacaa | |||
7ad3096b4e | |||
7d345cf795 | |||
f40e9c592e | |||
7671c585f5 | |||
93b4a7063b | |||
3efeb45c46 | |||
3fc227d2de | |||
604b371920 | |||
fd321beece | |||
9fe4e6b9e3 | |||
|
57bf90481b | ||
|
6062a32c1c | ||
94c899eb82 | |||
44a4ca75bd | |||
|
c8e1605b08 | ||
f2fcc98839 | |||
c54438d6d3 |
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"projectName": "Antares",
|
||||
"projectName": "antares",
|
||||
"projectOwner": "Fabio286",
|
||||
"repoType": "github",
|
||||
"repoHost": "https://github.com",
|
||||
@@ -111,7 +111,17 @@
|
||||
"contributions": [
|
||||
"platform"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "kilianstallz",
|
||||
"name": "Kilian Stallinger",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/5290318?v=4",
|
||||
"profile": "https://kilianstallinger.com",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
}
|
||||
],
|
||||
"contributorsPerLine": 7
|
||||
"contributorsPerLine": 7,
|
||||
"skipCi": true
|
||||
}
|
||||
|
3
.vscode/settings.json
vendored
3
.vscode/settings.json
vendored
@@ -3,7 +3,8 @@
|
||||
"UI",
|
||||
"core",
|
||||
"MySQL",
|
||||
"PostgreSQL"
|
||||
"PostgreSQL",
|
||||
"SQLite"
|
||||
],
|
||||
"svg.preview.background": "transparent"
|
||||
}
|
30
CHANGELOG.md
30
CHANGELOG.md
@@ -2,6 +2,36 @@
|
||||
|
||||
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.4.0](https://github.com/Fabio286/antares/compare/v0.3.9...v0.4.0) (2021-11-24)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **MySQL:** read-only mode ([4437d44](https://github.com/Fabio286/antares/commit/4437d44486c4f20b0bec4bf89d56016b08e36e79))
|
||||
* **PostgreSQL:** read-only mode ([5d48fe0](https://github.com/Fabio286/antares/commit/5d48fe08c77755ed18b3f7a9ea834268e317e7ef))
|
||||
* **SQLite:** cell update in data tabs ([604b371](https://github.com/Fabio286/antares/commit/604b3719204f7473ce4846624f08f8be9eec8b8f))
|
||||
* **SQLite:** connection add/edit masks ([c54438d](https://github.com/Fabio286/antares/commit/c54438d6d3bad38bc76dfcd61f58929fe30279cb))
|
||||
* **SQLite:** keys support ([fd321be](https://github.com/Fabio286/antares/commit/fd321beece075d3ad23fdd8541f9beb5727045a5))
|
||||
* **SQLite:** readonly mode ([3fc227d](https://github.com/Fabio286/antares/commit/3fc227d2de53aae115226ad3c965bfb6e9f3eca6))
|
||||
* **SQLite:** table data visualization ([f2fcc98](https://github.com/Fabio286/antares/commit/f2fcc9883972402eab4d51ef2a9796638dde2d3d))
|
||||
* **SQLite:** tables management ([3efeb45](https://github.com/Fabio286/antares/commit/3efeb45c460f178b794de72367f8d542fd8ddd56))
|
||||
* **SQLite:** triggers management ([f40e9c5](https://github.com/Fabio286/antares/commit/f40e9c592eeffd204aba21a0a0767a0c523fca49))
|
||||
* **SQLite:** views management ([7671c58](https://github.com/Fabio286/antares/commit/7671c585f5f8049bd863db190d4fc60d8f0c6c66))
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **SQLite:** hide schema creation ([98165ca](https://github.com/Fabio286/antares/commit/98165cacaa158c85ead0490d3caf579e2a17319f))
|
||||
* **UI:** hide tools menu if no tools available ([da1947e](https://github.com/Fabio286/antares/commit/da1947e4efa7f0a26d6a231fadf750be055fbdd5))
|
||||
* **UI:** notifications timeout anomalies ([cc99491](https://github.com/Fabio286/antares/commit/cc99491fe4a15812368f6c928b8c7801d7b255aa))
|
||||
|
||||
|
||||
### Improvements
|
||||
|
||||
* **SQLite:** improvements in data visualization ([94c899e](https://github.com/Fabio286/antares/commit/94c899eb8288b41a5962ac3d24365227e1f9f485))
|
||||
* **SQLite:** improvements in field length detection ([93b4a70](https://github.com/Fabio286/antares/commit/93b4a7063beeb5a7001cb06a74f05b23105212f5))
|
||||
* update italian traslation ([9fe3680](https://github.com/Fabio286/antares/commit/9fe3680bbb17c192cffa85348e68794ab49beb81))
|
||||
|
||||
### [0.3.9](https://github.com/Fabio286/antares/compare/v0.3.8...v0.3.9) (2021-11-14)
|
||||
|
||||
|
||||
|
13
README.md
13
README.md
@@ -12,7 +12,7 @@
|
||||
Antares is an SQL client based on [Electron.js](https://github.com/electron/electron) and [Vue.js](https://github.com/vuejs/vue) that aims to become a useful tool, especially for developers.
|
||||
Our target is to support as many databases as possible, and all major operating systems, including the ARM versions.
|
||||
|
||||
**At the moment this application is in development state, many features will come in future updates**, and supports only MySQL/MariaDB and PostgreSQL.
|
||||
**At the moment this application is in development state, many features will come in future updates**, and supports only MySQL/MariaDB, PostgreSQL and SQLite.
|
||||
At the moment, however, there are all the features necessary to have a pleasant database management experience, so give it a chance and send us your feedback, we would really appreciate it.
|
||||
We are actively working on it, hoping to provide new cool features, improvements and fixes as soon as possible.
|
||||
|
||||
@@ -68,12 +68,12 @@ On macOS you can run `.dmg` distribution following [this guide](https://support.
|
||||
|
||||
This is a roadmap with major features will come in near future.
|
||||
|
||||
- Support for other databases.
|
||||
- Database tools.
|
||||
- Users management (add/edit/delete).
|
||||
- More context menu shortcuts.
|
||||
- More keyboard shortcuts.
|
||||
- Import/export and migration.
|
||||
- Support for other databases.
|
||||
- Apple Silicon distribution
|
||||
|
||||
## Currently supported
|
||||
@@ -82,7 +82,7 @@ This is a roadmap with major features will come in near future.
|
||||
|
||||
- [x] MySQL/MariaDB
|
||||
- [x] PostgreSQL
|
||||
- [ ] SQLite
|
||||
- [x] SQLite
|
||||
- [ ] MSSQL
|
||||
- [ ] OracleDB
|
||||
- [ ] More...
|
||||
@@ -116,9 +116,9 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d
|
||||
<!-- markdownlint-disable -->
|
||||
<table>
|
||||
<tr>
|
||||
<td align="center"><a href="https://fabiodistasio.it/"><img src="https://avatars.githubusercontent.com/u/31471771?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Fabio Di Stasio</b></sub></a><br /><a href="https://github.com/Fabio286/Antares/commits?author=Fabio286" title="Code">💻</a> <a href="#translation-Fabio286" title="Translation">🌍</a> <a href="https://github.com/Fabio286/Antares/commits?author=Fabio286" title="Documentation">📖</a></td>
|
||||
<td align="center"><a href="https://www.linkedin.com/in/giulioganci/"><img src="https://avatars.githubusercontent.com/u/4192159?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Giulio Ganci</b></sub></a><br /><a href="https://github.com/Fabio286/Antares/commits?author=toriphes" title="Code">💻</a></td>
|
||||
<td align="center"><a href="https://christianratz.de/"><img src="https://avatars.githubusercontent.com/u/2630316?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Christian Ratz</b></sub></a><br /><a href="https://github.com/Fabio286/Antares/commits?author=digitalgopnik" title="Code">💻</a> <a href="#translation-digitalgopnik" title="Translation">🌍</a></td>
|
||||
<td align="center"><a href="https://fabiodistasio.it/"><img src="https://avatars.githubusercontent.com/u/31471771?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Fabio Di Stasio</b></sub></a><br /><a href="https://github.com/Fabio286/antares/commits?author=Fabio286" title="Code">💻</a> <a href="#translation-Fabio286" title="Translation">🌍</a> <a href="https://github.com/Fabio286/antares/commits?author=Fabio286" title="Documentation">📖</a></td>
|
||||
<td align="center"><a href="https://www.linkedin.com/in/giulioganci/"><img src="https://avatars.githubusercontent.com/u/4192159?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Giulio Ganci</b></sub></a><br /><a href="https://github.com/Fabio286/antares/commits?author=toriphes" title="Code">💻</a></td>
|
||||
<td align="center"><a href="https://christianratz.de/"><img src="https://avatars.githubusercontent.com/u/2630316?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Christian Ratz</b></sub></a><br /><a href="https://github.com/Fabio286/antares/commits?author=digitalgopnik" title="Code">💻</a> <a href="#translation-digitalgopnik" title="Translation">🌍</a></td>
|
||||
<td align="center"><a href="https://reverb6821.github.io/"><img src="https://avatars.githubusercontent.com/u/55198803?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Giuseppe Gigliotti</b></sub></a><br /><a href="#translation-reverb6821" title="Translation">🌍</a></td>
|
||||
<td align="center"><a href="https://github.com/Mohd-PH"><img src="https://avatars.githubusercontent.com/u/9362157?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Mohd-PH</b></sub></a><br /><a href="#translation-Mohd-PH" title="Translation">🌍</a></td>
|
||||
<td align="center"><a href="https://github.com/hongkfui"><img src="https://avatars.githubusercontent.com/u/37477191?v=4?s=100" width="100px;" alt=""/><br /><sub><b>hongkfui</b></sub></a><br /><a href="#translation-hongkfui" title="Translation">🌍</a></td>
|
||||
@@ -129,6 +129,7 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d
|
||||
<td align="center"><a href="https://ngoquocdat.com/"><img src="https://avatars.githubusercontent.com/u/56961917?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Ngô Quốc Đạt</b></sub></a><br /><a href="#translation-datlechin" title="Translation">🌍</a></td>
|
||||
<td align="center"><a href="https://github.com/IsamuSugi"><img src="https://avatars.githubusercontent.com/u/7746658?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Isamu Sugiura</b></sub></a><br /><a href="#translation-IsamuSugi" title="Translation">🌍</a></td>
|
||||
<td align="center"><a href="http://rsacchetto.nexxontech.it/"><img src="https://avatars.githubusercontent.com/u/18429412?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Riccardo Sacchetto</b></sub></a><br /><a href="#platform-Occhioverde" title="Packaging/porting to new platform">📦</a></td>
|
||||
<td align="center"><a href="https://kilianstallinger.com"><img src="https://avatars.githubusercontent.com/u/5290318?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Kilian Stallinger</b></sub></a><br /><a href="https://github.com/Fabio286/antares/commits?author=kilianstallz" title="Code">💻</a></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
|
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "antares",
|
||||
"productName": "Antares",
|
||||
"version": "0.3.9",
|
||||
"version": "0.4.0",
|
||||
"description": "A modern, fast and productivity driven SQL client with a focus in UX.",
|
||||
"license": "MIT",
|
||||
"repository": "https://github.com/Fabio286/antares.git",
|
||||
@@ -14,7 +14,7 @@
|
||||
"build": "cross-env NODE_ENV=production npm run compile",
|
||||
"build:local": "npm run build && electron-builder",
|
||||
"build:appx": "npm run build:local -- --win appx",
|
||||
"rebuild:electron": "npm run postinstall && electron-rebuild",
|
||||
"rebuild:electron": "npm run postinstall",
|
||||
"release": "standard-version",
|
||||
"release:pre": "npm run release -- --prerelease alpha",
|
||||
"postinstall": "electron-builder install-app-deps",
|
||||
@@ -30,6 +30,7 @@
|
||||
"appId": "com.fabio286.antares",
|
||||
"artifactName": "${productName}-${version}-${os}_${arch}.${ext}",
|
||||
"asar": true,
|
||||
"buildDependenciesFromSource": true,
|
||||
"directories": {
|
||||
"output": "build",
|
||||
"buildResources": "assets"
|
||||
@@ -104,6 +105,7 @@
|
||||
"@electron/remote": "^2.0.1",
|
||||
"@mdi/font": "^6.1.95",
|
||||
"ace-builds": "^1.4.13",
|
||||
"better-sqlite3": "^7.4.4",
|
||||
"electron-log": "^4.4.1",
|
||||
"electron-store": "^8.0.1",
|
||||
"electron-updater": "^4.3.9",
|
||||
@@ -131,10 +133,9 @@
|
||||
"clean-webpack-plugin": "^4.0.0",
|
||||
"cross-env": "^7.0.2",
|
||||
"css-loader": "^6.5.0",
|
||||
"electron": "^15.3.0",
|
||||
"electron": "^16.0.1",
|
||||
"electron-builder": "^22.13.1",
|
||||
"electron-devtools-installer": "^3.2.0",
|
||||
"electron-rebuild": "^3.2.3",
|
||||
"eslint": "^7.32.0",
|
||||
"eslint-config-standard": "^16.0.3",
|
||||
"eslint-plugin-import": "^2.24.2",
|
||||
|
@@ -8,6 +8,9 @@ module.exports = {
|
||||
collations: false,
|
||||
engines: false,
|
||||
connectionSchema: false,
|
||||
sslConnection: false,
|
||||
sshConnection: false,
|
||||
fileConnection: false,
|
||||
// Tools
|
||||
processesList: false,
|
||||
usersManagement: false,
|
||||
@@ -33,7 +36,11 @@ module.exports = {
|
||||
schedulerAdd: false,
|
||||
databaseEdit: false,
|
||||
schemaEdit: false,
|
||||
schemaDrop: false,
|
||||
tableSettings: false,
|
||||
tableOptions: false,
|
||||
tableArray: false,
|
||||
tableRealCount: false,
|
||||
viewSettings: false,
|
||||
triggerSettings: false,
|
||||
triggerFunctionSettings: false,
|
||||
@@ -45,14 +52,13 @@ module.exports = {
|
||||
sortableFields: false,
|
||||
unsigned: false,
|
||||
nullable: false,
|
||||
nullablePrimary: false,
|
||||
zerofill: false,
|
||||
tableOptions: false,
|
||||
autoIncrement: false,
|
||||
comment: false,
|
||||
collation: false,
|
||||
definer: false,
|
||||
onUpdate: false,
|
||||
tableArray: false,
|
||||
viewAlgorithm: false,
|
||||
viewSqlSecurity: false,
|
||||
viewUpdateOption: false,
|
||||
@@ -76,5 +82,6 @@ module.exports = {
|
||||
triggerFunctionSql: false,
|
||||
triggerFunctionlanguages: false,
|
||||
parametersLength: false,
|
||||
languages: false
|
||||
languages: false,
|
||||
readOnlyMode: false
|
||||
};
|
||||
|
@@ -1,5 +1,6 @@
|
||||
module.exports = {
|
||||
maria: require('./mysql'),
|
||||
mysql: require('./mysql'),
|
||||
pg: require('./postgresql')
|
||||
pg: require('./postgresql'),
|
||||
sqlite: require('./sqlite')
|
||||
};
|
||||
|
@@ -10,6 +10,8 @@ module.exports = {
|
||||
connectionSchema: true,
|
||||
collations: true,
|
||||
engines: true,
|
||||
sslConnection: true,
|
||||
sshConnection: true,
|
||||
// Tools
|
||||
processesList: true,
|
||||
// Structure
|
||||
@@ -30,6 +32,7 @@ module.exports = {
|
||||
functionAdd: true,
|
||||
schedulerAdd: true,
|
||||
schemaEdit: true,
|
||||
schemaDrop: true,
|
||||
tableSettings: true,
|
||||
viewSettings: true,
|
||||
triggerSettings: true,
|
||||
@@ -59,5 +62,6 @@ module.exports = {
|
||||
functionDeterministic: true,
|
||||
functionDataAccess: true,
|
||||
functionSql: 'BEGIN\r\n\r\nEND',
|
||||
parametersLength: true
|
||||
parametersLength: true,
|
||||
readOnlyMode: true
|
||||
};
|
||||
|
@@ -8,9 +8,12 @@ module.exports = {
|
||||
defaultDatabase: 'postgres',
|
||||
// Core
|
||||
database: true,
|
||||
sslConnection: true,
|
||||
sshConnection: true,
|
||||
// Tools
|
||||
processesList: true,
|
||||
// Structure
|
||||
schemas: true,
|
||||
tables: true,
|
||||
views: true,
|
||||
triggers: true,
|
||||
@@ -26,6 +29,7 @@ module.exports = {
|
||||
triggerFunctionAdd: true,
|
||||
routineAdd: true,
|
||||
functionAdd: true,
|
||||
schemaDrop: true,
|
||||
databaseEdit: false,
|
||||
tableSettings: true,
|
||||
viewSettings: true,
|
||||
@@ -51,5 +55,6 @@ module.exports = {
|
||||
triggerTableInName: true,
|
||||
triggerOnlyRename: false,
|
||||
triggerEnableDisable: true,
|
||||
languages: ['sql', 'plpgsql', 'c', 'internal']
|
||||
languages: ['sql', 'plpgsql', 'c', 'internal'],
|
||||
readOnlyMode: true
|
||||
};
|
||||
|
27
src/common/customizations/sqlite.js
Normal file
27
src/common/customizations/sqlite.js
Normal file
@@ -0,0 +1,27 @@
|
||||
module.exports = {
|
||||
// Core
|
||||
fileConnection: true,
|
||||
// Structure
|
||||
schemas: false,
|
||||
tables: true,
|
||||
views: true,
|
||||
triggers: true,
|
||||
// Settings
|
||||
elementsWrapper: '',
|
||||
stringsWrapper: '"',
|
||||
tableAdd: true,
|
||||
viewAdd: true,
|
||||
triggerAdd: true,
|
||||
schemaEdit: false,
|
||||
tableSettings: true,
|
||||
tableRealCount: true,
|
||||
viewSettings: true,
|
||||
triggerSettings: true,
|
||||
indexes: true,
|
||||
foreigns: true,
|
||||
sortableFields: true,
|
||||
nullable: true,
|
||||
nullablePrimary: true,
|
||||
triggerSql: 'BEGIN\r\n\r\nEND',
|
||||
readOnlyMode: true
|
||||
};
|
137
src/common/data-types/sqlite.js
Normal file
137
src/common/data-types/sqlite.js
Normal file
@@ -0,0 +1,137 @@
|
||||
module.exports = [
|
||||
{
|
||||
group: 'integer',
|
||||
types: [
|
||||
{
|
||||
name: 'INT',
|
||||
length: true,
|
||||
collation: false,
|
||||
unsigned: true,
|
||||
zerofill: true
|
||||
},
|
||||
{
|
||||
name: 'INTEGER',
|
||||
length: true,
|
||||
collation: false,
|
||||
unsigned: true,
|
||||
zerofill: true
|
||||
},
|
||||
{
|
||||
name: 'BIGINT',
|
||||
length: true,
|
||||
collation: false,
|
||||
unsigned: true,
|
||||
zerofill: true
|
||||
},
|
||||
{
|
||||
name: 'NUMERIC',
|
||||
length: true,
|
||||
collation: false,
|
||||
unsigned: true,
|
||||
zerofill: true
|
||||
},
|
||||
{
|
||||
name: 'BOOLEAN',
|
||||
length: false,
|
||||
collation: false,
|
||||
unsigned: true,
|
||||
zerofill: true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
group: 'float',
|
||||
types: [
|
||||
{
|
||||
name: 'FLOAT',
|
||||
length: true,
|
||||
collation: false,
|
||||
unsigned: false,
|
||||
zerofill: false
|
||||
},
|
||||
{
|
||||
name: 'REAL',
|
||||
length: true,
|
||||
collation: false,
|
||||
unsigned: false,
|
||||
zerofill: false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
group: 'string',
|
||||
types: [
|
||||
{
|
||||
name: 'CHAR',
|
||||
length: true,
|
||||
collation: true,
|
||||
unsigned: false,
|
||||
zerofill: false
|
||||
},
|
||||
{
|
||||
name: 'VARCHAR',
|
||||
length: true,
|
||||
collation: true,
|
||||
unsigned: false,
|
||||
zerofill: false
|
||||
},
|
||||
{
|
||||
name: 'TEXT',
|
||||
length: true,
|
||||
collation: true,
|
||||
unsigned: false,
|
||||
zerofill: false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
group: 'binary',
|
||||
types: [
|
||||
{
|
||||
name: 'BLOB',
|
||||
length: true,
|
||||
collation: false,
|
||||
unsigned: false,
|
||||
zerofill: false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
group: 'time',
|
||||
types: [
|
||||
{
|
||||
name: 'DATE',
|
||||
length: false,
|
||||
collation: false,
|
||||
unsigned: false,
|
||||
zerofill: false
|
||||
},
|
||||
{
|
||||
name: 'TIME',
|
||||
length: true,
|
||||
collation: false,
|
||||
unsigned: false,
|
||||
zerofill: false
|
||||
},
|
||||
{
|
||||
name: 'DATETIME',
|
||||
length: true,
|
||||
collation: false,
|
||||
unsigned: false,
|
||||
zerofill: false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
group: 'other',
|
||||
types: [
|
||||
{
|
||||
name: 'NONE',
|
||||
length: false,
|
||||
collation: false,
|
||||
unsigned: false,
|
||||
zerofill: false
|
||||
}
|
||||
]
|
||||
}
|
||||
];
|
5
src/common/index-types/sqlite.js
Normal file
5
src/common/index-types/sqlite.js
Normal file
@@ -0,0 +1,5 @@
|
||||
module.exports = [
|
||||
'PRIMARY',
|
||||
'INDEX',
|
||||
'UNIQUE'
|
||||
];
|
@@ -9,12 +9,16 @@ export default connections => {
|
||||
port: +conn.port,
|
||||
user: conn.user,
|
||||
password: conn.password,
|
||||
application_name: 'Antares SQL'
|
||||
application_name: 'Antares SQL',
|
||||
readonly: conn.readonly
|
||||
};
|
||||
|
||||
if (conn.database)
|
||||
params.database = conn.database;
|
||||
|
||||
if (conn.databasePath)
|
||||
params.databasePath = conn.databasePath;
|
||||
|
||||
if (conn.ssl) {
|
||||
params.ssl = {
|
||||
key: conn.key ? fs.readFileSync(conn.key) : null,
|
||||
@@ -62,12 +66,16 @@ export default connections => {
|
||||
port: +conn.port,
|
||||
user: conn.user,
|
||||
password: conn.password,
|
||||
application_name: 'Antares SQL'
|
||||
application_name: 'Antares SQL',
|
||||
readonly: conn.readonly
|
||||
};
|
||||
|
||||
if (conn.database)
|
||||
params.database = conn.database;
|
||||
|
||||
if (conn.databasePath)
|
||||
params.databasePath = conn.databasePath;
|
||||
|
||||
if (conn.schema)
|
||||
params.schema = conn.schema;
|
||||
|
||||
|
@@ -102,6 +102,9 @@ export default (connections) => {
|
||||
case 'pg':
|
||||
escapedParam = `'${params.content.replaceAll('\'', '\'\'')}'`;
|
||||
break;
|
||||
case 'sqlite':
|
||||
escapedParam = `'${params.content.replaceAll('\'', '\'\'')}'`;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (ARRAY.includes(params.type))
|
||||
@@ -122,6 +125,10 @@ export default (connections) => {
|
||||
fileBlob = fs.readFileSync(params.content);
|
||||
escapedParam = `decode('${fileBlob.toString('hex')}', 'hex')`;
|
||||
break;
|
||||
case 'sqlite':
|
||||
fileBlob = fs.readFileSync(params.content);
|
||||
escapedParam = `X'${fileBlob.toString('hex')}'`;
|
||||
break;
|
||||
}
|
||||
reload = true;
|
||||
}
|
||||
@@ -134,6 +141,9 @@ export default (connections) => {
|
||||
case 'pg':
|
||||
escapedParam = 'decode(\'\', \'hex\')';
|
||||
break;
|
||||
case 'sqlite':
|
||||
escapedParam = 'X\'\'';
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -188,7 +198,7 @@ export default (connections) => {
|
||||
const fieldName = Object.keys(row)[0].includes('.') ? `${params.table}.${params.primary}` : params.primary;
|
||||
|
||||
return typeof row[fieldName] === 'string'
|
||||
? `"${row[fieldName]}"`
|
||||
? `'${row[fieldName]}'`
|
||||
: row[fieldName];
|
||||
}).join(',');
|
||||
|
||||
|
@@ -1,6 +1,7 @@
|
||||
'use strict';
|
||||
import { MySQLClient } from './clients/MySQLClient';
|
||||
import { PostgreSQLClient } from './clients/PostgreSQLClient';
|
||||
import { SQLiteClient } from './clients/SQLiteClient';
|
||||
|
||||
const queryLogger = sql => {
|
||||
// Remove comments, newlines and multiple spaces
|
||||
@@ -37,6 +38,8 @@ export class ClientsFactory {
|
||||
return new MySQLClient(args);
|
||||
case 'pg':
|
||||
return new PostgreSQLClient(args);
|
||||
case 'sqlite':
|
||||
return new SQLiteClient(args);
|
||||
default:
|
||||
throw new Error(`Unknown database client: ${args.client}`);
|
||||
}
|
||||
|
@@ -133,8 +133,12 @@ export class MySQLClient extends AntaresCore {
|
||||
}
|
||||
}
|
||||
|
||||
if (!this._poolSize)
|
||||
if (!this._poolSize) {
|
||||
this._connection = await mysql.createConnection(dbConfig);
|
||||
|
||||
if (this._params.readonly)
|
||||
await this.raw('SET SESSION TRANSACTION READ ONLY');
|
||||
}
|
||||
else {
|
||||
this._connection = mysql.createPool({
|
||||
...dbConfig,
|
||||
@@ -146,6 +150,12 @@ export class MySQLClient extends AntaresCore {
|
||||
return next();
|
||||
}
|
||||
});
|
||||
|
||||
if (this._params.readonly) {
|
||||
this._connection.on('connection', connection => {
|
||||
connection.query('SET SESSION TRANSACTION READ ONLY');
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -571,7 +581,7 @@ export class MySQLClient extends AntaresCore {
|
||||
/**
|
||||
* CREATE DATABASE
|
||||
*
|
||||
* @returns {Array.<Object>} parameters
|
||||
* @returns {Promise<null>}
|
||||
* @memberof MySQLClient
|
||||
*/
|
||||
async createSchema (params) {
|
||||
@@ -581,7 +591,7 @@ export class MySQLClient extends AntaresCore {
|
||||
/**
|
||||
* ALTER DATABASE
|
||||
*
|
||||
* @returns {Array.<Object>} parameters
|
||||
* @returns {Promise<null>}
|
||||
* @memberof MySQLClient
|
||||
*/
|
||||
async alterSchema (params) {
|
||||
@@ -591,7 +601,7 @@ export class MySQLClient extends AntaresCore {
|
||||
/**
|
||||
* DROP DATABASE
|
||||
*
|
||||
* @returns {Array.<Object>} parameters
|
||||
* @returns {Promise<null>}
|
||||
* @memberof MySQLClient
|
||||
*/
|
||||
async dropSchema (params) {
|
||||
@@ -631,7 +641,7 @@ export class MySQLClient extends AntaresCore {
|
||||
/**
|
||||
* DROP VIEW
|
||||
*
|
||||
* @returns {Array.<Object>} parameters
|
||||
* @returns {Promise<null>}
|
||||
* @memberof MySQLClient
|
||||
*/
|
||||
async dropView (params) {
|
||||
@@ -642,7 +652,7 @@ export class MySQLClient extends AntaresCore {
|
||||
/**
|
||||
* ALTER VIEW
|
||||
*
|
||||
* @returns {Array.<Object>} parameters
|
||||
* @returns {Promise<null>}
|
||||
* @memberof MySQLClient
|
||||
*/
|
||||
async alterView (params) {
|
||||
@@ -663,7 +673,7 @@ export class MySQLClient extends AntaresCore {
|
||||
/**
|
||||
* CREATE VIEW
|
||||
*
|
||||
* @returns {Array.<Object>} parameters
|
||||
* @returns {Promise<null>}
|
||||
* @memberof MySQLClient
|
||||
*/
|
||||
async createView (params) {
|
||||
@@ -696,7 +706,7 @@ export class MySQLClient extends AntaresCore {
|
||||
/**
|
||||
* DROP TRIGGER
|
||||
*
|
||||
* @returns {Array.<Object>} parameters
|
||||
* @returns {Promise<null>}
|
||||
* @memberof MySQLClient
|
||||
*/
|
||||
async dropTrigger (params) {
|
||||
@@ -707,7 +717,7 @@ export class MySQLClient extends AntaresCore {
|
||||
/**
|
||||
* ALTER TRIGGER
|
||||
*
|
||||
* @returns {Array.<Object>} parameters
|
||||
* @returns {Promise<null>}
|
||||
* @memberof MySQLClient
|
||||
*/
|
||||
async alterTrigger (params) {
|
||||
@@ -729,7 +739,7 @@ export class MySQLClient extends AntaresCore {
|
||||
/**
|
||||
* CREATE TRIGGER
|
||||
*
|
||||
* @returns {Array.<Object>} parameters
|
||||
* @returns {Promise<null>}
|
||||
* @memberof MySQLClient
|
||||
*/
|
||||
async createTrigger (params) {
|
||||
@@ -803,7 +813,7 @@ export class MySQLClient extends AntaresCore {
|
||||
/**
|
||||
* DROP PROCEDURE
|
||||
*
|
||||
* @returns {Array.<Object>} parameters
|
||||
* @returns {Promise<null>}
|
||||
* @memberof MySQLClient
|
||||
*/
|
||||
async dropRoutine (params) {
|
||||
@@ -814,7 +824,7 @@ export class MySQLClient extends AntaresCore {
|
||||
/**
|
||||
* ALTER PROCEDURE
|
||||
*
|
||||
* @returns {Array.<Object>} parameters
|
||||
* @returns {Promise<null>}
|
||||
* @memberof MySQLClient
|
||||
*/
|
||||
async alterRoutine (params) {
|
||||
@@ -836,7 +846,7 @@ export class MySQLClient extends AntaresCore {
|
||||
/**
|
||||
* CREATE PROCEDURE
|
||||
*
|
||||
* @returns {Array.<Object>} parameters
|
||||
* @returns {Promise<null>}
|
||||
* @memberof MySQLClient
|
||||
*/
|
||||
async createRoutine (params) {
|
||||
@@ -930,7 +940,7 @@ export class MySQLClient extends AntaresCore {
|
||||
/**
|
||||
* DROP FUNCTION
|
||||
*
|
||||
* @returns {Array.<Object>} parameters
|
||||
* @returns {Promise<null>}
|
||||
* @memberof MySQLClient
|
||||
*/
|
||||
async dropFunction (params) {
|
||||
@@ -941,7 +951,7 @@ export class MySQLClient extends AntaresCore {
|
||||
/**
|
||||
* ALTER FUNCTION
|
||||
*
|
||||
* @returns {Array.<Object>} parameters
|
||||
* @returns {Promise<null>}
|
||||
* @memberof MySQLClient
|
||||
*/
|
||||
async alterFunction (params) {
|
||||
@@ -963,7 +973,7 @@ export class MySQLClient extends AntaresCore {
|
||||
/**
|
||||
* CREATE FUNCTION
|
||||
*
|
||||
* @returns {Array.<Object>} parameters
|
||||
* @returns {Promise<null>}
|
||||
* @memberof MySQLClient
|
||||
*/
|
||||
async createFunction (params) {
|
||||
@@ -1024,7 +1034,7 @@ export class MySQLClient extends AntaresCore {
|
||||
/**
|
||||
* DROP EVENT
|
||||
*
|
||||
* @returns {Array.<Object>} parameters
|
||||
* @returns {Promise<null>}
|
||||
* @memberof MySQLClient
|
||||
*/
|
||||
async dropEvent (params) {
|
||||
@@ -1035,7 +1045,7 @@ export class MySQLClient extends AntaresCore {
|
||||
/**
|
||||
* ALTER EVENT
|
||||
*
|
||||
* @returns {Array.<Object>} parameters
|
||||
* @returns {Promise<null>}
|
||||
* @memberof MySQLClient
|
||||
*/
|
||||
async alterEvent (params) {
|
||||
@@ -1061,7 +1071,7 @@ export class MySQLClient extends AntaresCore {
|
||||
/**
|
||||
* CREATE EVENT
|
||||
*
|
||||
* @returns {Array.<Object>} parameters
|
||||
* @returns {Promise<null>}
|
||||
* @memberof MySQLClient
|
||||
*/
|
||||
async createEvent (params) {
|
||||
@@ -1205,7 +1215,7 @@ export class MySQLClient extends AntaresCore {
|
||||
/**
|
||||
* CREATE TABLE
|
||||
*
|
||||
* @returns {Array.<Object>} parameters
|
||||
* @returns {Promise<null>}
|
||||
* @memberof MySQLClient
|
||||
*/
|
||||
async createTable (params) {
|
||||
@@ -1267,7 +1277,7 @@ export class MySQLClient extends AntaresCore {
|
||||
/**
|
||||
* ALTER TABLE
|
||||
*
|
||||
* @returns {Array.<Object>} parameters
|
||||
* @returns {Promise<null>}
|
||||
* @memberof MySQLClient
|
||||
*/
|
||||
async alterTable (params) {
|
||||
@@ -1402,7 +1412,7 @@ export class MySQLClient extends AntaresCore {
|
||||
/**
|
||||
* DUPLICATE TABLE
|
||||
*
|
||||
* @returns {Array.<Object>} parameters
|
||||
* @returns {Promise<null>}
|
||||
* @memberof MySQLClient
|
||||
*/
|
||||
async duplicateTable (params) {
|
||||
@@ -1413,7 +1423,7 @@ export class MySQLClient extends AntaresCore {
|
||||
/**
|
||||
* TRUNCATE TABLE
|
||||
*
|
||||
* @returns {Array.<Object>} parameters
|
||||
* @returns {Promise<null>}
|
||||
* @memberof MySQLClient
|
||||
*/
|
||||
async truncateTable (params) {
|
||||
@@ -1424,7 +1434,7 @@ export class MySQLClient extends AntaresCore {
|
||||
/**
|
||||
* DROP TABLE
|
||||
*
|
||||
* @returns {Array.<Object>} parameters
|
||||
* @returns {Promise<null>}
|
||||
* @memberof MySQLClient
|
||||
*/
|
||||
async dropTable (params) {
|
||||
|
@@ -105,10 +105,19 @@ export class PostgreSQLClient extends AntaresCore {
|
||||
const client = new Client(dbConfig);
|
||||
await client.connect();
|
||||
this._connection = client;
|
||||
|
||||
if (this._params.readonly)
|
||||
await this.raw('SET SESSION CHARACTERISTICS AS TRANSACTION READ ONLY');
|
||||
}
|
||||
else {
|
||||
const pool = new Pool({ ...dbConfig, max: this._poolSize });
|
||||
this._connection = pool;
|
||||
|
||||
if (this._params.readonly) {
|
||||
this._connection.on('connect', connection => {
|
||||
connection.query('SET SESSION CHARACTERISTICS AS TRANSACTION READ ONLY');
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -506,7 +515,7 @@ export class PostgreSQLClient extends AntaresCore {
|
||||
/**
|
||||
* CREATE SCHEMA
|
||||
*
|
||||
* @returns {Array.<Object>} parameters
|
||||
* @returns {Promise<null>}
|
||||
* @memberof MySQLClient
|
||||
*/
|
||||
async createSchema (params) {
|
||||
@@ -516,7 +525,7 @@ export class PostgreSQLClient extends AntaresCore {
|
||||
/**
|
||||
* ALTER DATABASE
|
||||
*
|
||||
* @returns {Array.<Object>} parameters
|
||||
* @returns {Promise<null>}
|
||||
* @memberof MySQLClient
|
||||
*/
|
||||
async alterSchema (params) {
|
||||
@@ -526,7 +535,7 @@ export class PostgreSQLClient extends AntaresCore {
|
||||
/**
|
||||
* DROP DATABASE
|
||||
*
|
||||
* @returns {Array.<Object>} parameters
|
||||
* @returns {Promise<null>}
|
||||
* @memberof MySQLClient
|
||||
*/
|
||||
async dropSchema (params) {
|
||||
@@ -558,7 +567,7 @@ export class PostgreSQLClient extends AntaresCore {
|
||||
/**
|
||||
* DROP VIEW
|
||||
*
|
||||
* @returns {Array.<Object>} parameters
|
||||
* @returns {Promise<null>}
|
||||
* @memberof PostgreSQLClient
|
||||
*/
|
||||
async dropView (params) {
|
||||
@@ -569,7 +578,7 @@ export class PostgreSQLClient extends AntaresCore {
|
||||
/**
|
||||
* ALTER VIEW
|
||||
*
|
||||
* @returns {Array.<Object>} parameters
|
||||
* @returns {Promise<null>}
|
||||
* @memberof PostgreSQLClient
|
||||
*/
|
||||
async alterView (params) {
|
||||
@@ -585,7 +594,7 @@ export class PostgreSQLClient extends AntaresCore {
|
||||
/**
|
||||
* CREATE VIEW
|
||||
*
|
||||
* @returns {Array.<Object>} parameters
|
||||
* @returns {Promise<null>}
|
||||
* @memberof PostgreSQLClient
|
||||
*/
|
||||
async createView (params) {
|
||||
@@ -640,7 +649,7 @@ export class PostgreSQLClient extends AntaresCore {
|
||||
/**
|
||||
* DROP TRIGGER
|
||||
*
|
||||
* @returns {Array.<Object>} parameters
|
||||
* @returns {Promise<null>}
|
||||
* @memberof PostgreSQLClient
|
||||
*/
|
||||
async dropTrigger (params) {
|
||||
@@ -652,7 +661,7 @@ export class PostgreSQLClient extends AntaresCore {
|
||||
/**
|
||||
* ALTER TRIGGER
|
||||
*
|
||||
* @returns {Array.<Object>} parameters
|
||||
* @returns {Promise<null>}
|
||||
* @memberof PostgreSQLClient
|
||||
*/
|
||||
async alterTrigger (params) {
|
||||
@@ -674,7 +683,7 @@ export class PostgreSQLClient extends AntaresCore {
|
||||
/**
|
||||
* CREATE TRIGGER
|
||||
*
|
||||
* @returns {Array.<Object>} parameters
|
||||
* @returns {Promise<null>}
|
||||
* @memberof PostgreSQLClient
|
||||
*/
|
||||
async createTrigger (params) {
|
||||
@@ -1086,7 +1095,7 @@ export class PostgreSQLClient extends AntaresCore {
|
||||
/**
|
||||
* CREATE TABLE
|
||||
*
|
||||
* @returns {Array.<Object>} parameters
|
||||
* @returns {Promise<null>}
|
||||
* @memberof PostgreSQLClient
|
||||
*/
|
||||
async createTable (params) {
|
||||
@@ -1144,7 +1153,7 @@ export class PostgreSQLClient extends AntaresCore {
|
||||
/**
|
||||
* ALTER TABLE
|
||||
*
|
||||
* @returns {Array.<Object>} parameters
|
||||
* @returns {Promise<null>}
|
||||
* @memberof PostgreSQLClient
|
||||
*/
|
||||
async alterTable (params) {
|
||||
@@ -1290,7 +1299,7 @@ export class PostgreSQLClient extends AntaresCore {
|
||||
/**
|
||||
* DUPLICATE TABLE
|
||||
*
|
||||
* @returns {Array.<Object>} parameters
|
||||
* @returns {Promise<null>}
|
||||
* @memberof PostgreSQLClient
|
||||
*/
|
||||
async duplicateTable (params) {
|
||||
@@ -1301,7 +1310,7 @@ export class PostgreSQLClient extends AntaresCore {
|
||||
/**
|
||||
* TRUNCATE TABLE
|
||||
*
|
||||
* @returns {Array.<Object>} parameters
|
||||
* @returns {Promise<null>}
|
||||
* @memberof PostgreSQLClient
|
||||
*/
|
||||
async truncateTable (params) {
|
||||
@@ -1312,7 +1321,7 @@ export class PostgreSQLClient extends AntaresCore {
|
||||
/**
|
||||
* DROP TABLE
|
||||
*
|
||||
* @returns {Array.<Object>} parameters
|
||||
* @returns {Promise<null>}
|
||||
* @memberof PostgreSQLClient
|
||||
*/
|
||||
async dropTable (params) {
|
||||
|
806
src/main/libs/clients/SQLiteClient.js
Normal file
806
src/main/libs/clients/SQLiteClient.js
Normal file
@@ -0,0 +1,806 @@
|
||||
'use strict';
|
||||
import sqlite from 'better-sqlite3';
|
||||
import { AntaresCore } from '../AntaresCore';
|
||||
import dataTypes from 'common/data-types/mysql';
|
||||
import { NUMBER, FLOAT, TIME, DATETIME } from 'common/fieldTypes';
|
||||
|
||||
export class SQLiteClient extends AntaresCore {
|
||||
constructor (args) {
|
||||
super(args);
|
||||
|
||||
this._schema = null;
|
||||
}
|
||||
|
||||
_getTypeInfo (type) {
|
||||
return dataTypes
|
||||
.reduce((acc, group) => [...acc, ...group.types], [])
|
||||
.filter(_type => _type.name === type.toUpperCase())[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* @memberof SQLiteClient
|
||||
*/
|
||||
async connect () {
|
||||
this._connection = sqlite(this._params.databasePath, {
|
||||
fileMustExist: true,
|
||||
readonly: this._params.readonly
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @memberof SQLiteClient
|
||||
*/
|
||||
destroy () {}
|
||||
|
||||
/**
|
||||
* Executes an USE query
|
||||
*
|
||||
* @memberof SQLiteClient
|
||||
*/
|
||||
use () {}
|
||||
|
||||
/**
|
||||
* @param {Array} schemas list
|
||||
* @returns {Array.<Object>} databases scructure
|
||||
* @memberof SQLiteClient
|
||||
*/
|
||||
async getStructure (schemas) {
|
||||
const { rows: databases } = await this.raw('SELECT * FROM pragma_database_list');
|
||||
|
||||
const filteredDatabases = databases;
|
||||
|
||||
const tablesArr = [];
|
||||
const triggersArr = [];
|
||||
let schemaSize = 0;
|
||||
|
||||
for (const db of filteredDatabases) {
|
||||
if (!schemas.has(db.name)) continue;
|
||||
|
||||
let { rows: tables } = await this.raw(`
|
||||
SELECT *
|
||||
FROM "${db.name}".sqlite_master
|
||||
WHERE type IN ('table', 'view')
|
||||
AND name NOT LIKE 'sqlite_%'
|
||||
ORDER BY name
|
||||
`);
|
||||
if (tables.length) {
|
||||
tables = tables.map(table => {
|
||||
table.Db = db.name;
|
||||
return table;
|
||||
});
|
||||
tablesArr.push(...tables);
|
||||
}
|
||||
|
||||
let { rows: triggers } = await this.raw(`SELECT * FROM "${db.name}".sqlite_master WHERE type='trigger'`);
|
||||
if (triggers.length) {
|
||||
triggers = triggers.map(trigger => {
|
||||
trigger.Db = db.name;
|
||||
return trigger;
|
||||
});
|
||||
triggersArr.push(...triggers);
|
||||
}
|
||||
}
|
||||
|
||||
return filteredDatabases.map(db => {
|
||||
if (schemas.has(db.name)) {
|
||||
// TABLES
|
||||
const remappedTables = tablesArr.filter(table => table.Db === db.name).map(table => {
|
||||
const tableSize = 0;
|
||||
schemaSize += tableSize;
|
||||
|
||||
return {
|
||||
name: table.name,
|
||||
type: table.type,
|
||||
rows: false,
|
||||
size: false
|
||||
};
|
||||
});
|
||||
|
||||
// TRIGGERS
|
||||
const remappedTriggers = triggersArr.filter(trigger => trigger.Db === db.name).map(trigger => {
|
||||
return {
|
||||
name: trigger.name,
|
||||
table: trigger.tbl_name
|
||||
};
|
||||
});
|
||||
|
||||
return {
|
||||
name: db.name,
|
||||
size: schemaSize,
|
||||
tables: remappedTables,
|
||||
functions: [],
|
||||
procedures: [],
|
||||
triggers: remappedTriggers,
|
||||
schedulers: []
|
||||
};
|
||||
}
|
||||
else {
|
||||
return {
|
||||
name: db.name,
|
||||
size: 0,
|
||||
tables: [],
|
||||
functions: [],
|
||||
procedures: [],
|
||||
triggers: [],
|
||||
schedulers: []
|
||||
};
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Object} params
|
||||
* @param {String} params.schema
|
||||
* @param {String} params.table
|
||||
* @returns {Object} table scructure
|
||||
* @memberof SQLiteClient
|
||||
*/
|
||||
async getTableColumns ({ schema, table }) {
|
||||
const { rows: fields } = await this.raw(`SELECT * FROM "${schema}".pragma_table_info('${table}')`);
|
||||
|
||||
return fields.map(field => {
|
||||
const [type, length] = field.type.includes('(')
|
||||
? field.type.replace(')', '').split('(').map(el => {
|
||||
if (!isNaN(el)) el = +el;
|
||||
return el;
|
||||
})
|
||||
: [field.type, null];
|
||||
|
||||
return {
|
||||
name: field.name,
|
||||
key: null,
|
||||
type: type.trim(),
|
||||
schema: schema,
|
||||
table: table,
|
||||
numPrecision: [...NUMBER, ...FLOAT].includes(type) ? length : null,
|
||||
datePrecision: null,
|
||||
charLength: ![...NUMBER, ...FLOAT].includes(type) ? length : null,
|
||||
nullable: !field.notnull,
|
||||
unsigned: null,
|
||||
zerofill: null,
|
||||
order: field.cid + 1,
|
||||
default: field.dflt_value,
|
||||
charset: null,
|
||||
collation: null,
|
||||
autoIncrement: false,
|
||||
onUpdate: null,
|
||||
comment: ''
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Object} params
|
||||
* @param {String} params.schema
|
||||
* @param {String} params.table
|
||||
* @returns {Object} table row count
|
||||
* @memberof SQLiteClient
|
||||
*/
|
||||
async getTableApproximateCount ({ schema, table }) {
|
||||
const { rows } = await this.raw(`SELECT COUNT(*) AS count FROM "${schema}"."${table}"`);
|
||||
|
||||
return rows.length ? rows[0].count : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Object} params
|
||||
* @param {String} params.schema
|
||||
* @param {String} params.table
|
||||
* @returns {Object} table options
|
||||
* @memberof SQLiteClient
|
||||
*/
|
||||
async getTableOptions ({ schema, table }) {
|
||||
return { name: table };
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Object} params
|
||||
* @param {String} params.schema
|
||||
* @param {String} params.table
|
||||
* @returns {Object} table indexes
|
||||
* @memberof SQLiteClient
|
||||
*/
|
||||
async getTableIndexes ({ schema, table }) {
|
||||
const remappedIndexes = [];
|
||||
const { rows: primaryKeys } = await this.raw(`SELECT * FROM "${schema}".pragma_table_info('${table}') WHERE pk != 0`);
|
||||
|
||||
for (const key of primaryKeys) {
|
||||
remappedIndexes.push({
|
||||
name: 'PRIMARY',
|
||||
column: key.name,
|
||||
indexType: null,
|
||||
type: 'PRIMARY',
|
||||
cardinality: null,
|
||||
comment: '',
|
||||
indexComment: ''
|
||||
});
|
||||
}
|
||||
|
||||
const { rows: indexes } = await this.raw(`SELECT * FROM "${schema}".pragma_index_list('${table}');`);
|
||||
|
||||
for (const index of indexes) {
|
||||
const { rows: details } = await this.raw(`SELECT * FROM "${schema}".pragma_index_info('${index.name}');`);
|
||||
|
||||
for (const detail of details) {
|
||||
remappedIndexes.push({
|
||||
name: index.name,
|
||||
column: detail.name,
|
||||
indexType: null,
|
||||
type: index.unique === 1 ? 'UNIQUE' : 'INDEX',
|
||||
cardinality: null,
|
||||
comment: '',
|
||||
indexComment: ''
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return remappedIndexes;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Object} params
|
||||
* @param {String} params.schema
|
||||
* @param {String} params.table
|
||||
* @returns {Object} table key usage
|
||||
* @memberof SQLiteClient
|
||||
*/
|
||||
async getKeyUsage ({ schema, table }) {
|
||||
const { rows } = await this.raw(`SELECT * FROM "${schema}".pragma_foreign_key_list('${table}');`);
|
||||
|
||||
return rows.map(field => {
|
||||
return {
|
||||
schema: schema,
|
||||
table: table,
|
||||
field: field.from,
|
||||
position: field.id + 1,
|
||||
constraintPosition: null,
|
||||
constraintName: field.id,
|
||||
refSchema: schema,
|
||||
refTable: field.table,
|
||||
refField: field.to,
|
||||
onUpdate: field.on_update,
|
||||
onDelete: field.on_delete
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
async getUsers () {}
|
||||
|
||||
/**
|
||||
* SHOW CREATE VIEW
|
||||
*
|
||||
* @returns {Array.<Object>} view informations
|
||||
* @memberof SQLiteClient
|
||||
*/
|
||||
async getViewInformations ({ schema, view }) {
|
||||
const sql = `SELECT "sql" FROM "${schema}".sqlite_master WHERE "type"='view' AND name='${view}'`;
|
||||
const results = await this.raw(sql);
|
||||
|
||||
return results.rows.map(row => {
|
||||
return {
|
||||
sql: row.sql.match(/(?<=AS ).*?$/gs)[0],
|
||||
name: view
|
||||
};
|
||||
})[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* DROP VIEW
|
||||
*
|
||||
* @returns {Array.<Object>} parameters
|
||||
* @memberof SQLiteClient
|
||||
*/
|
||||
async dropView (params) {
|
||||
const sql = `DROP VIEW "${params.schema}"."${params.view}"`;
|
||||
return await this.raw(sql);
|
||||
}
|
||||
|
||||
/**
|
||||
* ALTER VIEW
|
||||
*
|
||||
* @returns {Array.<Object>} parameters
|
||||
* @memberof SQLiteClient
|
||||
*/
|
||||
async alterView (params) {
|
||||
const { view } = params;
|
||||
try {
|
||||
await this.dropView({ schema: view.schema, view: view.oldName });
|
||||
await this.createView(view);
|
||||
}
|
||||
catch (err) {
|
||||
return Promise.reject(err);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* CREATE VIEW
|
||||
*
|
||||
* @returns {Array.<Object>} parameters
|
||||
* @memberof SQLiteClient
|
||||
*/
|
||||
async createView (params) {
|
||||
const sql = `CREATE VIEW "${params.schema}"."${params.name}" AS ${params.sql}`;
|
||||
return await this.raw(sql);
|
||||
}
|
||||
|
||||
/**
|
||||
* SHOW CREATE TRIGGER
|
||||
*
|
||||
* @returns {Array.<Object>} view informations
|
||||
* @memberof SQLiteClient
|
||||
*/
|
||||
async getTriggerInformations ({ schema, trigger }) {
|
||||
const sql = `SELECT "sql" FROM "${schema}".sqlite_master WHERE "type"='trigger' AND name='${trigger}'`;
|
||||
const results = await this.raw(sql);
|
||||
|
||||
return results.rows.map(row => {
|
||||
return {
|
||||
sql: row.sql.match(/(BEGIN|begin)(.*)(END|end)/gs)[0],
|
||||
name: trigger,
|
||||
table: row.sql.match(/(?<=ON `).*?(?=`)/gs)[0],
|
||||
activation: row.sql.match(/(BEFORE|AFTER)/gs)[0],
|
||||
event: row.sql.match(/(INSERT|UPDATE|DELETE)/gs)[0]
|
||||
};
|
||||
})[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* DROP TRIGGER
|
||||
*
|
||||
* @returns {Array.<Object>} parameters
|
||||
* @memberof SQLiteClient
|
||||
*/
|
||||
async dropTrigger (params) {
|
||||
const sql = `DROP TRIGGER \`${params.schema}\`.\`${params.trigger}\``;
|
||||
return await this.raw(sql);
|
||||
}
|
||||
|
||||
/**
|
||||
* ALTER TRIGGER
|
||||
*
|
||||
* @returns {Array.<Object>} parameters
|
||||
* @memberof SQLiteClient
|
||||
*/
|
||||
async alterTrigger (params) {
|
||||
const { trigger } = params;
|
||||
const tempTrigger = Object.assign({}, trigger);
|
||||
tempTrigger.name = `Antares_${tempTrigger.name}_tmp`;
|
||||
|
||||
try {
|
||||
await this.createTrigger(tempTrigger);
|
||||
await this.dropTrigger({ schema: trigger.schema, trigger: tempTrigger.name });
|
||||
await this.dropTrigger({ schema: trigger.schema, trigger: trigger.oldName });
|
||||
await this.createTrigger(trigger);
|
||||
}
|
||||
catch (err) {
|
||||
return Promise.reject(err);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* CREATE TRIGGER
|
||||
*
|
||||
* @returns {Array.<Object>} parameters
|
||||
* @memberof SQLiteClient
|
||||
*/
|
||||
async createTrigger (params) {
|
||||
const sql = `CREATE ${params.definer ? `DEFINER=${params.definer} ` : ''}TRIGGER \`${params.schema}\`.\`${params.name}\` ${params.activation} ${params.event} ON \`${params.table}\` FOR EACH ROW ${params.sql}`;
|
||||
return await this.raw(sql, { split: false });
|
||||
}
|
||||
|
||||
/**
|
||||
* SHOW COLLATION
|
||||
*
|
||||
* @returns {Array.<Object>} collations list
|
||||
* @memberof SQLiteClient
|
||||
*/
|
||||
async getCollations () {
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
* SHOW VARIABLES
|
||||
*
|
||||
* @returns {Array.<Object>} variables list
|
||||
* @memberof SQLiteClient
|
||||
*/
|
||||
async getVariables () {
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
* SHOW ENGINES
|
||||
*
|
||||
* @returns {Array.<Object>} engines list
|
||||
* @memberof SQLiteClient
|
||||
*/
|
||||
async getEngines () {
|
||||
return {
|
||||
name: 'SQLite',
|
||||
support: 'YES',
|
||||
comment: '',
|
||||
isDefault: true
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* SHOW VARIABLES LIKE '%vers%'
|
||||
*
|
||||
* @returns {Array.<Object>} version parameters
|
||||
* @memberof SQLiteClient
|
||||
*/
|
||||
async getVersion () {
|
||||
const os = require('os');
|
||||
const sql = 'SELECT sqlite_version() AS version';
|
||||
const { rows } = await this.raw(sql);
|
||||
|
||||
return {
|
||||
number: rows[0].version,
|
||||
name: 'SQLite',
|
||||
arch: process.arch,
|
||||
os: `${os.type()} ${os.release()}`
|
||||
};
|
||||
}
|
||||
|
||||
async getProcesses () {}
|
||||
|
||||
async killProcess () {}
|
||||
|
||||
/**
|
||||
* CREATE TABLE
|
||||
*
|
||||
* @returns {Promise<null>}
|
||||
* @memberof SQLiteClient
|
||||
*/
|
||||
async createTable (params) {
|
||||
const {
|
||||
schema,
|
||||
fields,
|
||||
foreigns,
|
||||
indexes,
|
||||
options
|
||||
} = params;
|
||||
const newColumns = [];
|
||||
const newIndexes = [];
|
||||
const manageIndexes = [];
|
||||
const newForeigns = [];
|
||||
|
||||
let sql = `CREATE TABLE "${schema}"."${options.name}"`;
|
||||
|
||||
// ADD FIELDS
|
||||
fields.forEach(field => {
|
||||
const typeInfo = this._getTypeInfo(field.type);
|
||||
const length = typeInfo?.length ? field.enumValues || field.numLength || field.charLength || field.datePrecision : false;
|
||||
|
||||
newColumns.push(`"${field.name}"
|
||||
${field.type.toUpperCase()}${length && length !== true ? `(${length})` : ''}
|
||||
${field.unsigned ? 'UNSIGNED' : ''}
|
||||
${field.nullable ? 'NULL' : 'NOT NULL'}
|
||||
${field.autoIncrement ? 'AUTO_INCREMENT' : ''}
|
||||
${field.default ? `DEFAULT ${field.default}` : ''}
|
||||
${field.onUpdate ? `ON UPDATE ${field.onUpdate}` : ''}`);
|
||||
});
|
||||
|
||||
// ADD INDEX
|
||||
indexes.forEach(index => {
|
||||
const fields = index.fields.map(field => `"${field}"`).join(',');
|
||||
const type = index.type;
|
||||
|
||||
if (type === 'PRIMARY')
|
||||
newIndexes.push(`PRIMARY KEY (${fields})`);
|
||||
else
|
||||
manageIndexes.push(`CREATE ${type === 'UNIQUE' ? type : ''} INDEX "${index.name}" ON "${options.name}" (${fields})`);
|
||||
});
|
||||
|
||||
// ADD FOREIGN KEYS
|
||||
foreigns.forEach(foreign => {
|
||||
newForeigns.push(`CONSTRAINT "${foreign.constraintName}" FOREIGN KEY ("${foreign.field}") REFERENCES "${foreign.refTable}" ("${foreign.refField}") ON UPDATE ${foreign.onUpdate} ON DELETE ${foreign.onDelete}`);
|
||||
});
|
||||
|
||||
sql = `${sql} (${[...newColumns, ...newIndexes, ...newForeigns].join(', ')})`;
|
||||
if (manageIndexes.length) sql = `${sql}; ${manageIndexes.join(';')}`;
|
||||
|
||||
return await this.raw(sql);
|
||||
}
|
||||
|
||||
/**
|
||||
* ALTER TABLE
|
||||
*
|
||||
* @returns {Promise<null>}
|
||||
* @memberof SQLiteClient
|
||||
*/
|
||||
async alterTable (params) {
|
||||
try {
|
||||
await this.raw('BEGIN TRANSACTION');
|
||||
await this.raw('PRAGMA foreign_keys = 0');
|
||||
|
||||
const tmpName = `Antares_${params.table}_tmp`;
|
||||
await this.raw(`CREATE TABLE "${tmpName}" AS SELECT * FROM "${params.table}"`);
|
||||
await this.dropTable(params);
|
||||
|
||||
const createTableParams = {
|
||||
schema: params.schema,
|
||||
fields: params.tableStructure.fields,
|
||||
foreigns: params.tableStructure.foreigns,
|
||||
indexes: params.tableStructure.indexes.filter(index => !index.name.includes('sqlite_autoindex')),
|
||||
options: { name: params.tableStructure.name }
|
||||
};
|
||||
await this.createTable(createTableParams);
|
||||
const insertFields = createTableParams.fields
|
||||
.filter(field => {
|
||||
return (
|
||||
params.additions.every(add => add.name !== field.name) &&
|
||||
params.deletions.every(del => del.name !== field.name)
|
||||
);
|
||||
})
|
||||
.reduce((acc, curr) => {
|
||||
acc.push(`"${curr.name}"`);
|
||||
return acc;
|
||||
}, []);
|
||||
|
||||
const selectFields = insertFields.map(field => {
|
||||
const renamedField = params.changes.find(change => `"${change.name}"` === field);
|
||||
if (renamedField)
|
||||
return `"${renamedField.orgName}"`;
|
||||
return field;
|
||||
});
|
||||
|
||||
await this.raw(`INSERT INTO "${createTableParams.options.name}" (${insertFields.join(',')}) SELECT ${selectFields.join(',')} FROM "${tmpName}"`);
|
||||
|
||||
await this.dropTable({ schema: params.schema, table: tmpName });
|
||||
await this.raw('PRAGMA foreign_keys = 1');
|
||||
await this.raw('COMMIT');
|
||||
}
|
||||
catch (err) {
|
||||
await this.raw('ROLLBACK');
|
||||
return Promise.reject(err);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* DUPLICATE TABLE
|
||||
*
|
||||
* @returns {Promise<null>}
|
||||
* @memberof SQLiteClient
|
||||
*/
|
||||
async duplicateTable (params) { // TODO: retrive table informations and create a copy
|
||||
const sql = `CREATE TABLE "${params.schema}"."${params.table}_copy" AS SELECT * FROM "${params.schema}"."${params.table}"`;
|
||||
return await this.raw(sql);
|
||||
}
|
||||
|
||||
/**
|
||||
* TRUNCATE TABLE
|
||||
*
|
||||
* @returns {Promise<null>}
|
||||
* @memberof SQLiteClient
|
||||
*/
|
||||
async truncateTable (params) {
|
||||
const sql = `DELETE FROM "${params.schema}"."${params.table}"`;
|
||||
return await this.raw(sql);
|
||||
}
|
||||
|
||||
/**
|
||||
* DROP TABLE
|
||||
*
|
||||
* @returns {Promise<null>}
|
||||
* @memberof SQLiteClient
|
||||
*/
|
||||
async dropTable (params) {
|
||||
const sql = `DROP TABLE "${params.schema}"."${params.table}"`;
|
||||
return await this.raw(sql);
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {String} SQL string
|
||||
* @memberof SQLiteClient
|
||||
*/
|
||||
getSQL () {
|
||||
// SELECT
|
||||
const selectArray = this._query.select.reduce(this._reducer, []);
|
||||
let selectRaw = '';
|
||||
|
||||
if (selectArray.length)
|
||||
selectRaw = selectArray.length ? `SELECT ${selectArray.join(', ')} ` : 'SELECT * ';
|
||||
|
||||
// FROM
|
||||
let fromRaw = '';
|
||||
|
||||
if (!this._query.update.length && !Object.keys(this._query.insert).length && !!this._query.from)
|
||||
fromRaw = 'FROM';
|
||||
else if (Object.keys(this._query.insert).length)
|
||||
fromRaw = 'INTO';
|
||||
|
||||
fromRaw += this._query.from ? ` ${this._query.schema ? `"${this._query.schema}".` : ''}"${this._query.from}" ` : '';
|
||||
|
||||
// WHERE
|
||||
const whereArray = this._query.where
|
||||
.reduce(this._reducer, [])
|
||||
?.map(clausole => clausole.replace('= null', 'IS NULL'));
|
||||
const whereRaw = whereArray.length ? `WHERE ${whereArray.join(' AND ')} ` : '';
|
||||
|
||||
// UPDATE
|
||||
const updateArray = this._query.update.reduce(this._reducer, []);
|
||||
const updateRaw = updateArray.length ? `SET ${updateArray.join(', ')} ` : '';
|
||||
|
||||
// INSERT
|
||||
let insertRaw = '';
|
||||
|
||||
if (this._query.insert.length) {
|
||||
const fieldsList = Object.keys(this._query.insert[0]);
|
||||
const rowsList = this._query.insert.map(el => `(${Object.values(el).join(', ')})`);
|
||||
|
||||
insertRaw = `(${fieldsList.join(', ')}) VALUES ${rowsList.join(', ')} `;
|
||||
}
|
||||
|
||||
// GROUP BY
|
||||
const groupByArray = this._query.groupBy.reduce(this._reducer, []);
|
||||
const groupByRaw = groupByArray.length ? `GROUP BY ${groupByArray.join(', ')} ` : '';
|
||||
|
||||
// ORDER BY
|
||||
const orderByArray = this._query.orderBy.reduce(this._reducer, []);
|
||||
const orderByRaw = orderByArray.length ? `ORDER BY ${orderByArray.join(', ')} ` : '';
|
||||
|
||||
// LIMIT
|
||||
const limitRaw = this._query.limit.length ? `LIMIT ${this._query.limit.join(', ')} ` : '';
|
||||
|
||||
// OFFSET
|
||||
const offsetRaw = this._query.offset.length ? `OFFSET ${this._query.offset.join(', ')} ` : '';
|
||||
|
||||
return `${selectRaw}${updateRaw ? 'UPDATE' : ''}${insertRaw ? 'INSERT ' : ''}${this._query.delete ? 'DELETE ' : ''}${fromRaw}${updateRaw}${whereRaw}${groupByRaw}${orderByRaw}${limitRaw}${offsetRaw}${insertRaw}`;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} sql raw SQL query
|
||||
* @param {object} args
|
||||
* @param {boolean} args.nest
|
||||
* @param {boolean} args.details
|
||||
* @param {boolean} args.split
|
||||
* @returns {Promise}
|
||||
* @memberof SQLiteClient
|
||||
*/
|
||||
async raw (sql, args) {
|
||||
if (process.env.NODE_ENV === 'development') this._logger(sql);// TODO: replace BLOB content with a placeholder
|
||||
|
||||
args = {
|
||||
nest: false,
|
||||
details: false,
|
||||
split: true,
|
||||
comments: true,
|
||||
...args
|
||||
};
|
||||
|
||||
if (!args.comments)
|
||||
sql = sql.replace(/(\/\*(.|[\r\n])*?\*\/)|(--(.*|[\r\n]))/gm, '');// Remove comments
|
||||
|
||||
const resultsArr = [];
|
||||
let paramsArr = [];
|
||||
const queries = args.split
|
||||
? sql.split(/((?:[^;'"]*(?:"(?:\\.|[^"])*"|'(?:\\.|[^'])*')[^;'"]*)+)|;/gm)
|
||||
.filter(Boolean)
|
||||
.map(q => q.trim())
|
||||
: [sql];
|
||||
const connection = this._connection;
|
||||
|
||||
for (const query of queries) {
|
||||
if (!query) continue;
|
||||
const timeStart = new Date();
|
||||
let timeStop;
|
||||
const keysArr = [];
|
||||
|
||||
const { rows, report, fields, keys, duration } = await new Promise((resolve, reject) => {
|
||||
(async () => {
|
||||
let queryResult;
|
||||
let affectedRows;
|
||||
let fields;
|
||||
const detectedTypes = {};
|
||||
|
||||
try {
|
||||
const stmt = connection.prepare(query);
|
||||
|
||||
if (stmt.reader) {
|
||||
queryResult = stmt.all();
|
||||
fields = stmt.columns();
|
||||
|
||||
if (queryResult.length) {
|
||||
fields.forEach(field => {
|
||||
detectedTypes[field.name] = typeof queryResult[0][field.name];
|
||||
});
|
||||
}
|
||||
}
|
||||
else {
|
||||
const info = queryResult = stmt.run();
|
||||
affectedRows = info.changes;
|
||||
}
|
||||
}
|
||||
catch (err) {
|
||||
reject(err);
|
||||
}
|
||||
|
||||
timeStop = new Date();
|
||||
|
||||
let remappedFields = fields
|
||||
? fields.map(field => {
|
||||
let [parsedType, length] = field.type?.includes('(')
|
||||
? field.type.replace(')', '').split('(').map(el => {
|
||||
if (!isNaN(el))
|
||||
el = +el;
|
||||
else
|
||||
el = el.trim();
|
||||
return el;
|
||||
})
|
||||
: [field.type, null];
|
||||
|
||||
if ([...TIME, ...DATETIME].includes(parsedType)) {
|
||||
const firstNotNull = queryResult.find(res => res[field.name] !== null);
|
||||
if (firstNotNull[field.name].includes('.'))
|
||||
length = firstNotNull[field.name].split('.').pop().length;
|
||||
}
|
||||
|
||||
return {
|
||||
name: field.name,
|
||||
alias: field.name,
|
||||
orgName: field.column,
|
||||
schema: field.database,
|
||||
table: field.table,
|
||||
tableAlias: field.table,
|
||||
orgTable: field.table,
|
||||
type: field.type !== null ? parsedType : detectedTypes[field.name],
|
||||
length
|
||||
};
|
||||
}).filter(Boolean)
|
||||
: [];
|
||||
|
||||
if (args.details) {
|
||||
paramsArr = remappedFields.map(field => {
|
||||
return {
|
||||
table: field.table,
|
||||
schema: field.schema
|
||||
};
|
||||
}).filter((val, i, arr) => arr.findIndex(el => el.schema === val.schema && el.table === val.table) === i);
|
||||
|
||||
for (const paramObj of paramsArr) {
|
||||
if (!paramObj.table || !paramObj.schema) continue;
|
||||
|
||||
try {
|
||||
const indexes = await this.getTableIndexes(paramObj);
|
||||
|
||||
remappedFields = remappedFields.map(field => {
|
||||
// const detailedField = columns.find(f => f.name === field.name);
|
||||
const fieldIndex = indexes.find(i => i.column === field.name);
|
||||
if (field.table === paramObj.table && field.schema === paramObj.schema) {
|
||||
// if (detailedField) {
|
||||
// const length = detailedField.numPrecision || detailedField.charLength || detailedField.datePrecision || null;
|
||||
// field = { ...field, ...detailedField, length };
|
||||
// }
|
||||
|
||||
if (fieldIndex) {
|
||||
const key = fieldIndex.type === 'PRIMARY' ? 'pri' : fieldIndex.type === 'UNIQUE' ? 'uni' : 'mul';
|
||||
field = { ...field, key };
|
||||
};
|
||||
}
|
||||
|
||||
return field;
|
||||
});
|
||||
}
|
||||
catch (err) {
|
||||
reject(err);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
resolve({
|
||||
duration: timeStop - timeStart,
|
||||
rows: Array.isArray(queryResult) ? queryResult.some(el => Array.isArray(el)) ? [] : queryResult : false,
|
||||
report: affectedRows !== undefined ? { affectedRows } : null,
|
||||
fields: remappedFields,
|
||||
keys: keysArr
|
||||
});
|
||||
})();
|
||||
});
|
||||
|
||||
resultsArr.push({ rows, report, fields, keys, duration });
|
||||
}
|
||||
|
||||
return resultsArr.length === 1 ? resultsArr[0] : resultsArr;
|
||||
}
|
||||
}
|
@@ -107,14 +107,14 @@ else {
|
||||
mainWindow = await createMainWindow();
|
||||
createAppMenu();
|
||||
|
||||
if (isDevelopment)
|
||||
mainWindow.webContents.openDevTools();
|
||||
// if (isDevelopment)
|
||||
// mainWindow.webContents.openDevTools();
|
||||
|
||||
process.on('uncaughtException', (error) => {
|
||||
process.on('uncaughtException', error => {
|
||||
mainWindow.webContents.send('unhandled-exception', error);
|
||||
});
|
||||
|
||||
process.on('unhandledRejection', (error) => {
|
||||
process.on('unhandledRejection', error => {
|
||||
mainWindow.webContents.send('unhandled-exception', error);
|
||||
});
|
||||
});
|
||||
|
@@ -40,15 +40,13 @@ export default {
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
notifications: {
|
||||
deep: true,
|
||||
handler: function (notification) {
|
||||
if (notification.length) {
|
||||
this.timeouts[notification[0].uid] = setTimeout(() => {
|
||||
this.removeNotification(notification[0].uid);
|
||||
delete this.timeouts[notification.uid];
|
||||
}, this.notificationsTimeout * 1000);
|
||||
}
|
||||
'notifications.length': function (val) {
|
||||
if (val > 0) {
|
||||
const nUid = this.notifications[0].uid;
|
||||
this.timeouts[nUid] = setTimeout(() => {
|
||||
this.removeNotification(nUid);
|
||||
delete this.timeouts[nUid];
|
||||
}, this.notificationsTimeout * 1000);
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -63,11 +61,14 @@ export default {
|
||||
}
|
||||
},
|
||||
rearmTimeouts () {
|
||||
const delay = 50;
|
||||
let i = this.notifications.length * delay;
|
||||
for (const notification of this.notifications) {
|
||||
this.timeouts[notification.uid] = setTimeout(() => {
|
||||
this.removeNotification(notification.uid);
|
||||
delete this.timeouts[notification.uid];
|
||||
}, this.notificationsTimeout * 1000);
|
||||
}, (this.notificationsTimeout * 1000) + i);
|
||||
i = i > delay ? i - delay : 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -256,7 +256,11 @@
|
||||
</span>
|
||||
</a>
|
||||
</li>
|
||||
<li slot="header" class="tab-item dropdown tools-dropdown">
|
||||
<li
|
||||
v-if="workspace.customizations.processesList"
|
||||
slot="header"
|
||||
class="tab-item dropdown tools-dropdown"
|
||||
>
|
||||
<a
|
||||
class="tab-link workspace-tools-link dropdown-toggle"
|
||||
tabindex="0"
|
||||
@@ -264,8 +268,8 @@
|
||||
>
|
||||
<i class="mdi mdi-24px mdi-tools" />
|
||||
</a>
|
||||
<ul class="menu text-left text-uppercase">
|
||||
<li v-if="workspace.customizations.processesList" class="menu-item">
|
||||
<ul v-if="hasTools" class="menu text-left text-uppercase">
|
||||
<li class="menu-item">
|
||||
<a class="c-hand p-vcentered" @click="showProcessesModal">
|
||||
<i class="mdi mdi-memory mr-1 tool-icon" />
|
||||
<span>{{ $t('message.processesList') }}</span>
|
||||
@@ -569,6 +573,11 @@ export default {
|
||||
if (this.workspace.breadcrumbs[key]) return this.workspace.breadcrumbs[key];
|
||||
}
|
||||
return false;
|
||||
},
|
||||
hasTools () {
|
||||
return this.workspace.customizations.processesList ||
|
||||
this.workspace.customizations.usersManagement ||
|
||||
this.workspace.customizations.variables;
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
|
@@ -11,6 +11,7 @@
|
||||
<a class="tab-link">{{ $t('word.general') }}</a>
|
||||
</li>
|
||||
<li
|
||||
v-if="customizations.sslConnection"
|
||||
class="tab-item c-hand"
|
||||
:class="{'active': selectedTab === 'ssl'}"
|
||||
@click="selectTab('ssl')"
|
||||
@@ -18,6 +19,7 @@
|
||||
<a class="tab-link">{{ $t('word.ssl') }}</a>
|
||||
</li>
|
||||
<li
|
||||
v-if="customizations.sshConnection"
|
||||
class="tab-item c-hand"
|
||||
:class="{'active': selectedTab === 'ssh'}"
|
||||
@click="selectTab('ssh')"
|
||||
@@ -49,25 +51,17 @@
|
||||
</div>
|
||||
<div class="column col-8 col-sm-12">
|
||||
<select v-model="connection.client" class="form-select">
|
||||
<option value="mysql">
|
||||
MySQL
|
||||
<option
|
||||
v-for="client in clients"
|
||||
:key="client.slug"
|
||||
:value="client.slug"
|
||||
>
|
||||
{{ client.name }}
|
||||
</option>
|
||||
<option value="maria">
|
||||
MariaDB
|
||||
</option>
|
||||
<option value="pg">
|
||||
PostgreSQL
|
||||
</option>
|
||||
<!-- <option value="mssql">
|
||||
Microsoft SQL
|
||||
</option>
|
||||
<option value="oracledb">
|
||||
Oracle DB
|
||||
</option> -->
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group columns">
|
||||
<div v-if="!customizations.fileConnection" class="form-group columns">
|
||||
<div class="column col-4 col-sm-12">
|
||||
<label class="form-label">{{ $t('word.hostName') }}/IP</label>
|
||||
</div>
|
||||
@@ -79,7 +73,20 @@
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group columns">
|
||||
<div v-if="customizations.fileConnection" class="form-group columns">
|
||||
<div class="column col-4 col-sm-12">
|
||||
<label class="form-label">{{ $t('word.database') }}</label>
|
||||
</div>
|
||||
<div class="column col-8 col-sm-12">
|
||||
<BaseUploadInput
|
||||
:value="connection.databasePath"
|
||||
:message="$t('word.browse')"
|
||||
@clear="pathClear('databasePath')"
|
||||
@change="pathSelection($event, 'databasePath')"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="!customizations.fileConnection" class="form-group columns">
|
||||
<div class="column col-4 col-sm-12">
|
||||
<label class="form-label">{{ $t('word.port') }}</label>
|
||||
</div>
|
||||
@@ -105,7 +112,7 @@
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group columns">
|
||||
<div v-if="!customizations.fileConnection" class="form-group columns">
|
||||
<div class="column col-4 col-sm-12">
|
||||
<label class="form-label">{{ $t('word.user') }}</label>
|
||||
</div>
|
||||
@@ -118,7 +125,7 @@
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group columns">
|
||||
<div v-if="!customizations.fileConnection" class="form-group columns">
|
||||
<div class="column col-4 col-sm-12">
|
||||
<label class="form-label">{{ $t('word.password') }}</label>
|
||||
</div>
|
||||
@@ -144,7 +151,15 @@
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group columns">
|
||||
<div v-if="customizations.readOnlyMode" class="form-group columns">
|
||||
<div class="column col-4 col-sm-12" />
|
||||
<div class="column col-8 col-sm-12">
|
||||
<label class="form-checkbox form-inline">
|
||||
<input v-model="connection.readonly" type="checkbox"><i class="form-icon" /> {{ $t('message.readOnlyMode') }}
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="!customizations.fileConnection" class="form-group columns">
|
||||
<div class="column col-4 col-sm-12" />
|
||||
<div class="column col-8 col-sm-12">
|
||||
<label class="form-checkbox form-inline">
|
||||
@@ -369,15 +384,23 @@ export default {
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
clients: [
|
||||
{ name: 'MySQL', slug: 'mysql' },
|
||||
{ name: 'MariaDB', slug: 'maria' },
|
||||
{ name: 'PostgreSQL', slug: 'pg' },
|
||||
{ name: 'SQLite', slug: 'sqlite' }
|
||||
],
|
||||
connection: {
|
||||
name: '',
|
||||
client: 'mysql',
|
||||
host: '127.0.0.1',
|
||||
database: null,
|
||||
databasePath: '',
|
||||
port: null,
|
||||
user: null,
|
||||
password: '',
|
||||
ask: false,
|
||||
readonly: false,
|
||||
uid: uidGen('C'),
|
||||
ssl: false,
|
||||
cert: '',
|
||||
|
@@ -11,6 +11,7 @@
|
||||
<a class="tab-link">{{ $t('word.general') }}</a>
|
||||
</li>
|
||||
<li
|
||||
v-if="customizations.sslConnection"
|
||||
class="tab-item c-hand"
|
||||
:class="{'active': selectedTab === 'ssl'}"
|
||||
@click="selectTab('ssl')"
|
||||
@@ -18,6 +19,7 @@
|
||||
<a class="tab-link">{{ $t('word.ssl') }}</a>
|
||||
</li>
|
||||
<li
|
||||
v-if="customizations.sshConnection"
|
||||
class="tab-item c-hand"
|
||||
:class="{'active': selectedTab === 'ssh'}"
|
||||
@click="selectTab('ssh')"
|
||||
@@ -49,19 +51,17 @@
|
||||
</div>
|
||||
<div class="column col-8 col-sm-12">
|
||||
<select v-model="localConnection.client" class="form-select">
|
||||
<option value="mysql">
|
||||
MySQL
|
||||
</option>
|
||||
<option value="maria">
|
||||
MariaDB
|
||||
</option>
|
||||
<option value="pg">
|
||||
PostgreSQL
|
||||
<option
|
||||
v-for="client in clients"
|
||||
:key="client.slug"
|
||||
:value="client.slug"
|
||||
>
|
||||
{{ client.name }}
|
||||
</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group columns">
|
||||
<div v-if="!customizations.fileConnection" class="form-group columns">
|
||||
<div class="column col-4 col-sm-12">
|
||||
<label class="form-label">{{ $t('word.hostName') }}/IP</label>
|
||||
</div>
|
||||
@@ -73,7 +73,20 @@
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group columns">
|
||||
<div v-if="customizations.fileConnection" class="form-group columns">
|
||||
<div class="column col-4 col-sm-12">
|
||||
<label class="form-label">{{ $t('word.database') }}</label>
|
||||
</div>
|
||||
<div class="column col-8 col-sm-12">
|
||||
<BaseUploadInput
|
||||
:value="localConnection.databasePath"
|
||||
:message="$t('word.browse')"
|
||||
@clear="pathClear('databasePath')"
|
||||
@change="pathSelection($event, 'databasePath')"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="!customizations.fileConnection" class="form-group columns">
|
||||
<div class="column col-4 col-sm-12">
|
||||
<label class="form-label">{{ $t('word.port') }}</label>
|
||||
</div>
|
||||
@@ -99,7 +112,7 @@
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group columns">
|
||||
<div v-if="!customizations.fileConnection" class="form-group columns">
|
||||
<div class="column col-4 col-sm-12">
|
||||
<label class="form-label">{{ $t('word.user') }}</label>
|
||||
</div>
|
||||
@@ -112,7 +125,7 @@
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group columns">
|
||||
<div v-if="!customizations.fileConnection" class="form-group columns">
|
||||
<div class="column col-4 col-sm-12">
|
||||
<label class="form-label">{{ $t('word.password') }}</label>
|
||||
</div>
|
||||
@@ -138,7 +151,15 @@
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group columns">
|
||||
<div v-if="customizations.readOnlyMode" class="form-group columns">
|
||||
<div class="column col-4 col-sm-12" />
|
||||
<div class="column col-8 col-sm-12">
|
||||
<label class="form-checkbox form-inline">
|
||||
<input v-model="localConnection.readonly" type="checkbox"><i class="form-icon" /> {{ $t('message.readOnlyMode') }}
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="!customizations.fileConnection" class="form-group columns">
|
||||
<div class="column col-4 col-sm-12" />
|
||||
<div class="column col-8 col-sm-12">
|
||||
<label class="form-checkbox form-inline">
|
||||
@@ -374,6 +395,12 @@ export default {
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
clients: [
|
||||
{ name: 'MySQL', slug: 'mysql' },
|
||||
{ name: 'MariaDB', slug: 'maria' },
|
||||
{ name: 'PostgreSQL', slug: 'pg' },
|
||||
{ name: 'SQLite', slug: 'sqlite' }
|
||||
],
|
||||
isConnecting: false,
|
||||
isTesting: false,
|
||||
isAsking: false,
|
||||
@@ -383,7 +410,7 @@ export default {
|
||||
},
|
||||
computed: {
|
||||
customizations () {
|
||||
return customizations[this.connection.client];
|
||||
return customizations[this.localConnection.client];
|
||||
},
|
||||
isBusy () {
|
||||
return this.isConnecting || this.isTesting;
|
||||
|
@@ -13,6 +13,7 @@
|
||||
<span class="workspace-explorebar-title">{{ connectionName }}</span>
|
||||
<span v-if="workspace.connectionStatus === 'connected'" class="workspace-explorebar-tools">
|
||||
<i
|
||||
v-if="customizations.schemas"
|
||||
class="mdi mdi-18px mdi-database-plus c-hand mr-2"
|
||||
:title="$t('message.createNewSchema')"
|
||||
@click="showNewDBModal"
|
||||
|
@@ -43,7 +43,7 @@
|
||||
<span v-html="highlightWord(table.name)" />
|
||||
</a>
|
||||
<div
|
||||
v-if="table.type === 'table'"
|
||||
v-if="table.type === 'table' && table.size !== false"
|
||||
class="table-size tooltip tooltip-left mr-1"
|
||||
:data-tooltip="formatBytes(table.size)"
|
||||
>
|
||||
|
@@ -65,7 +65,11 @@
|
||||
>
|
||||
<span class="d-flex"><i class="mdi mdi-18px mdi-database-edit text-light pr-1" /> {{ $t('word.edit') }}</span>
|
||||
</div>
|
||||
<div class="context-element" @click="showDeleteModal">
|
||||
<div
|
||||
v-if="workspace.customizations.schemaDrop"
|
||||
class="context-element"
|
||||
@click="showDeleteModal"
|
||||
>
|
||||
<span class="d-flex"><i class="mdi mdi-18px mdi-database-remove text-light pr-1" /> {{ $t('word.delete') }}</span>
|
||||
</div>
|
||||
|
||||
|
@@ -506,6 +506,12 @@ export default {
|
||||
uid: this.connection.uid,
|
||||
schema: this.schema,
|
||||
table: this.table,
|
||||
tableStructure: {
|
||||
name: this.localOptions.name,
|
||||
fields: this.localFields,
|
||||
foreigns: this.localKeyUsage,
|
||||
indexes: this.localIndexes
|
||||
},
|
||||
additions,
|
||||
changes,
|
||||
deletions,
|
||||
|
@@ -367,7 +367,8 @@ export default {
|
||||
getWorkspace: 'workspaces/getWorkspace'
|
||||
}),
|
||||
localLength () {
|
||||
return this.localRow.numLength || this.localRow.charLength || this.localRow.datePrecision || this.localRow.numPrecision || 0;
|
||||
const localLength = this.localRow.numLength || this.localRow.charLength || this.localRow.datePrecision || this.localRow.numPrecision || 0;
|
||||
return localLength === true ? null : localLength;
|
||||
},
|
||||
fieldType () {
|
||||
const fieldType = this.dataTypes.reduce((acc, group) => [...acc, ...group.types], []).filter(type =>
|
||||
@@ -391,7 +392,7 @@ export default {
|
||||
return this.indexes.some(index => ['PRIMARY', 'UNIQUE'].includes(index.type));
|
||||
},
|
||||
isNullable () {
|
||||
return !this.indexes.some(index => ['PRIMARY'].includes(index.type));
|
||||
return this.customizations.nullablePrimary || !this.indexes.some(index => ['PRIMARY'].includes(index.type));
|
||||
},
|
||||
isInDataTypes () {
|
||||
let typeNames = [];
|
||||
|
@@ -93,7 +93,7 @@
|
||||
<div v-if="resultsCount">
|
||||
{{ $t('word.results') }}: <b>{{ resultsCount.toLocaleString() }}</b>
|
||||
</div>
|
||||
<div v-if="affectedCount">
|
||||
<div v-if="affectedCount !== null">
|
||||
{{ $t('message.affectedRows') }}: <b>{{ affectedCount }}</b>
|
||||
</div>
|
||||
<div class="input-group" :title="$t('word.schema')">
|
||||
@@ -170,7 +170,7 @@ export default {
|
||||
selectedSchema: null,
|
||||
resultsCount: 0,
|
||||
durationsCount: 0,
|
||||
affectedCount: 0,
|
||||
affectedCount: null,
|
||||
editorHeight: 200,
|
||||
isHistoryOpen: false
|
||||
};
|
||||
@@ -255,9 +255,14 @@ export default {
|
||||
|
||||
if (status === 'success') {
|
||||
this.results = Array.isArray(response) ? response : [response];
|
||||
this.resultsCount += this.results.reduce((acc, curr) => acc + (curr.rows ? curr.rows.length : 0), 0);
|
||||
this.durationsCount += this.results.reduce((acc, curr) => acc + curr.duration, 0);
|
||||
this.affectedCount += this.results.reduce((acc, curr) => acc + (curr.report ? curr.report.affectedRows : 0), 0);
|
||||
this.resultsCount = this.results.reduce((acc, curr) => acc + (curr.rows ? curr.rows.length : 0), 0);
|
||||
this.durationsCount = this.results.reduce((acc, curr) => acc + curr.duration, 0);
|
||||
this.affectedCount = this.results
|
||||
.filter(result => result.report !== null)
|
||||
.reduce((acc, curr) => {
|
||||
if (acc === null) acc = 0;
|
||||
return acc + (curr.report ? curr.report.affectedRows : 0);
|
||||
}, null);
|
||||
|
||||
this.updateTabContent({
|
||||
uid: this.connection.uid,
|
||||
@@ -285,7 +290,7 @@ export default {
|
||||
this.results = [];
|
||||
this.resultsCount = 0;
|
||||
this.durationsCount = 0;
|
||||
this.affectedCount = 0;
|
||||
this.affectedCount = null;
|
||||
},
|
||||
resize (e) {
|
||||
const el = this.$refs.queryEditor.$el;
|
||||
|
@@ -120,7 +120,12 @@
|
||||
{{ $t('word.results') }}: <b>{{ results[0].rows.length | localeString }}</b>
|
||||
</div>
|
||||
<div v-if="hasApproximately || (page > 1 && approximateCount)">
|
||||
{{ $t('word.total') }}: <b :title="$t('word.approximately')">≈ {{ approximateCount | localeString }}</b>
|
||||
{{ $t('word.total') }}: <b
|
||||
:title="!customizations.tableRealCount ? $t('word.approximately') : ''"
|
||||
>
|
||||
<span v-if="!customizations.tableRealCount">≈</span>
|
||||
{{ approximateCount | localeString }}
|
||||
</b>
|
||||
</div>
|
||||
<div class="d-flex" :title="$t('word.schema')">
|
||||
<i class="mdi mdi-18px mdi-database mr-1" /><b>{{ schema }}</b>
|
||||
@@ -231,6 +236,9 @@ export default {
|
||||
workspace () {
|
||||
return this.getWorkspace(this.connection.uid);
|
||||
},
|
||||
customizations () {
|
||||
return this.workspace.customizations;
|
||||
},
|
||||
isTable () {
|
||||
return !!this.workspace.breadcrumbs.table;
|
||||
},
|
||||
|
@@ -250,7 +250,8 @@ module.exports = {
|
||||
searchForQueries: 'Search for queries',
|
||||
killProcess: 'Kill process',
|
||||
closeTab: 'Close tab',
|
||||
goToDownloadPage: 'Go to download page'
|
||||
goToDownloadPage: 'Go to download page',
|
||||
readOnlyMode: 'Read-only mode'
|
||||
},
|
||||
faker: {
|
||||
address: 'Address',
|
||||
|
@@ -121,7 +121,10 @@ module.exports = {
|
||||
history: 'Cronologia',
|
||||
select: 'Seleziona',
|
||||
passphrase: 'Passphrase',
|
||||
filter: 'Filtra'
|
||||
filter: 'Filtra',
|
||||
disabled: 'Disabilitato',
|
||||
enable: 'Abilita',
|
||||
disable: 'Disabilita'
|
||||
},
|
||||
message: {
|
||||
appWelcome: 'Benvenuto in Antares SQL Client!',
|
||||
@@ -233,7 +236,22 @@ module.exports = {
|
||||
duplicateTable: 'Duplica tabella',
|
||||
noOpenTabs: 'Non ci sono tab aperte, naviga nella barra sinistra o:',
|
||||
noSchema: 'Nessuno schema',
|
||||
restorePreviourSession: 'Ripristina sessione precedente'
|
||||
restorePreviourSession: 'Ripristina sessione precedente',
|
||||
runQuery: 'Esegui query',
|
||||
thereAreNoTableFields: 'Non ci sono campi della tabella',
|
||||
newTable: 'Nuova tabella',
|
||||
newView: 'Nuova vista',
|
||||
newTrigger: 'Nuovo trigger',
|
||||
newRoutine: 'Nuova routine',
|
||||
newFunction: 'Nuova funzione',
|
||||
newScheduler: 'Nuovo scheduler',
|
||||
newTriggerFunction: 'Nuova funzione di trigger',
|
||||
thereIsNoQueriesYet: 'Non ci sono ancora query',
|
||||
searchForQueries: 'Cerca query',
|
||||
killProcess: 'Uccidi processo',
|
||||
closeTab: 'Chiudi tab',
|
||||
goToDownloadPage: 'Vai alla pagina di download',
|
||||
readOnlyMode: 'Modalità sola lettura'
|
||||
},
|
||||
faker: {
|
||||
address: 'Indirizzo',
|
||||
|
Before Width: | Height: | Size: 1004 B After Width: | Height: | Size: 1004 B |
@@ -17,10 +17,12 @@
|
||||
(
|
||||
"char": $string-color,
|
||||
"varchar": $string-color,
|
||||
"longvarchar": $string-color,
|
||||
"text": $string-color,
|
||||
"tinytext": $string-color,
|
||||
"mediumtext": $string-color,
|
||||
"longtext": $string-color,
|
||||
"string": $string-color,
|
||||
"json": $string-color,
|
||||
"name": $string-color,
|
||||
"character": $string-color,
|
||||
@@ -50,6 +52,7 @@
|
||||
"oid": $number-color,
|
||||
"xid": $number-color,
|
||||
"money": $number-color,
|
||||
"number": $number-color,
|
||||
"datetime": $date-color,
|
||||
"date": $date-color,
|
||||
"time": $date-color,
|
||||
|
@@ -20,6 +20,10 @@
|
||||
background-image: url("../images/svg/pg.svg");
|
||||
}
|
||||
|
||||
&.dbi-sqlite {
|
||||
background-image: url("../images/svg/sqlite.svg");
|
||||
}
|
||||
|
||||
&.dbi-oracledb {
|
||||
background-image: url("../images/svg/oracledb.svg");
|
||||
}
|
||||
|
@@ -24,12 +24,24 @@ export default {
|
||||
getConnections: state => state.connections,
|
||||
getConnectionName: state => uid => {
|
||||
const connection = state.connections.filter(connection => connection.uid === uid)[0];
|
||||
if (!connection) return '';
|
||||
return connection.name
|
||||
? connection.name
|
||||
: connection.ask
|
||||
? `${connection.host}:${connection.port}`
|
||||
: `${connection.user + '@'}${connection.host}:${connection.port}`;
|
||||
let connectionName = '';
|
||||
|
||||
if (connection.name)
|
||||
connectionName = connection.name;
|
||||
else if (connection.ask)
|
||||
connectionName = `${connection.host}:${connection.port}`;
|
||||
else if (connection.databasePath) {
|
||||
let string = connection.databasePath.split(/[/\\]+/).pop();
|
||||
|
||||
if (string.length >= 30)
|
||||
string = `...${string.slice(-30)}`;
|
||||
|
||||
connectionName = string;
|
||||
}
|
||||
else
|
||||
connectionName = `${connection.user + '@'}${connection.host}:${connection.port}`;
|
||||
|
||||
return connectionName;
|
||||
}
|
||||
},
|
||||
mutations: {
|
||||
|
@@ -412,6 +412,11 @@ export default {
|
||||
indexTypes = require('common/index-types/postgresql');
|
||||
customizations = require('common/customizations/postgresql');
|
||||
break;
|
||||
case 'sqlite':
|
||||
dataTypes = require('common/data-types/sqlite');
|
||||
indexTypes = require('common/index-types/sqlite');
|
||||
customizations = require('common/customizations/sqlite');
|
||||
break;
|
||||
}
|
||||
|
||||
const { status, response: version } = await Schema.getVersion(connection.uid);
|
||||
|
Reference in New Issue
Block a user