mirror of https://github.com/Fabio286/antares.git
Merge pull request #141 from Fabio286/feat/sqlite-implementation
feat:sqlite implementation
This commit is contained in:
commit
7d345cf795
|
@ -3,7 +3,8 @@
|
||||||
"UI",
|
"UI",
|
||||||
"core",
|
"core",
|
||||||
"MySQL",
|
"MySQL",
|
||||||
"PostgreSQL"
|
"PostgreSQL",
|
||||||
|
"SQLite"
|
||||||
],
|
],
|
||||||
"svg.preview.background": "transparent"
|
"svg.preview.background": "transparent"
|
||||||
}
|
}
|
|
@ -14,7 +14,7 @@
|
||||||
"build": "cross-env NODE_ENV=production npm run compile",
|
"build": "cross-env NODE_ENV=production npm run compile",
|
||||||
"build:local": "npm run build && electron-builder",
|
"build:local": "npm run build && electron-builder",
|
||||||
"build:appx": "npm run build:local -- --win appx",
|
"build:appx": "npm run build:local -- --win appx",
|
||||||
"rebuild:electron": "npm run postinstall && electron-rebuild",
|
"rebuild:electron": "npm run postinstall",
|
||||||
"release": "standard-version",
|
"release": "standard-version",
|
||||||
"release:pre": "npm run release -- --prerelease alpha",
|
"release:pre": "npm run release -- --prerelease alpha",
|
||||||
"postinstall": "electron-builder install-app-deps",
|
"postinstall": "electron-builder install-app-deps",
|
||||||
|
@ -30,6 +30,7 @@
|
||||||
"appId": "com.fabio286.antares",
|
"appId": "com.fabio286.antares",
|
||||||
"artifactName": "${productName}-${version}-${os}_${arch}.${ext}",
|
"artifactName": "${productName}-${version}-${os}_${arch}.${ext}",
|
||||||
"asar": true,
|
"asar": true,
|
||||||
|
"buildDependenciesFromSource": true,
|
||||||
"directories": {
|
"directories": {
|
||||||
"output": "build",
|
"output": "build",
|
||||||
"buildResources": "assets"
|
"buildResources": "assets"
|
||||||
|
@ -104,6 +105,7 @@
|
||||||
"@electron/remote": "^2.0.1",
|
"@electron/remote": "^2.0.1",
|
||||||
"@mdi/font": "^6.1.95",
|
"@mdi/font": "^6.1.95",
|
||||||
"ace-builds": "^1.4.13",
|
"ace-builds": "^1.4.13",
|
||||||
|
"better-sqlite3": "^7.4.4",
|
||||||
"electron-log": "^4.4.1",
|
"electron-log": "^4.4.1",
|
||||||
"electron-store": "^8.0.1",
|
"electron-store": "^8.0.1",
|
||||||
"electron-updater": "^4.3.9",
|
"electron-updater": "^4.3.9",
|
||||||
|
@ -134,7 +136,6 @@
|
||||||
"electron": "^15.3.0",
|
"electron": "^15.3.0",
|
||||||
"electron-builder": "^22.13.1",
|
"electron-builder": "^22.13.1",
|
||||||
"electron-devtools-installer": "^3.2.0",
|
"electron-devtools-installer": "^3.2.0",
|
||||||
"electron-rebuild": "^3.2.3",
|
|
||||||
"eslint": "^7.32.0",
|
"eslint": "^7.32.0",
|
||||||
"eslint-config-standard": "^16.0.3",
|
"eslint-config-standard": "^16.0.3",
|
||||||
"eslint-plugin-import": "^2.24.2",
|
"eslint-plugin-import": "^2.24.2",
|
||||||
|
|
|
@ -8,6 +8,9 @@ module.exports = {
|
||||||
collations: false,
|
collations: false,
|
||||||
engines: false,
|
engines: false,
|
||||||
connectionSchema: false,
|
connectionSchema: false,
|
||||||
|
sslConnection: false,
|
||||||
|
sshConnection: false,
|
||||||
|
fileConnection: false,
|
||||||
// Tools
|
// Tools
|
||||||
processesList: false,
|
processesList: false,
|
||||||
usersManagement: false,
|
usersManagement: false,
|
||||||
|
@ -33,7 +36,11 @@ module.exports = {
|
||||||
schedulerAdd: false,
|
schedulerAdd: false,
|
||||||
databaseEdit: false,
|
databaseEdit: false,
|
||||||
schemaEdit: false,
|
schemaEdit: false,
|
||||||
|
schemaDrop: false,
|
||||||
tableSettings: false,
|
tableSettings: false,
|
||||||
|
tableOptions: false,
|
||||||
|
tableArray: false,
|
||||||
|
tableRealCount: false,
|
||||||
viewSettings: false,
|
viewSettings: false,
|
||||||
triggerSettings: false,
|
triggerSettings: false,
|
||||||
triggerFunctionSettings: false,
|
triggerFunctionSettings: false,
|
||||||
|
@ -45,14 +52,13 @@ module.exports = {
|
||||||
sortableFields: false,
|
sortableFields: false,
|
||||||
unsigned: false,
|
unsigned: false,
|
||||||
nullable: false,
|
nullable: false,
|
||||||
|
nullablePrimary: false,
|
||||||
zerofill: false,
|
zerofill: false,
|
||||||
tableOptions: false,
|
|
||||||
autoIncrement: false,
|
autoIncrement: false,
|
||||||
comment: false,
|
comment: false,
|
||||||
collation: false,
|
collation: false,
|
||||||
definer: false,
|
definer: false,
|
||||||
onUpdate: false,
|
onUpdate: false,
|
||||||
tableArray: false,
|
|
||||||
viewAlgorithm: false,
|
viewAlgorithm: false,
|
||||||
viewSqlSecurity: false,
|
viewSqlSecurity: false,
|
||||||
viewUpdateOption: false,
|
viewUpdateOption: false,
|
||||||
|
@ -76,5 +82,6 @@ module.exports = {
|
||||||
triggerFunctionSql: false,
|
triggerFunctionSql: false,
|
||||||
triggerFunctionlanguages: false,
|
triggerFunctionlanguages: false,
|
||||||
parametersLength: false,
|
parametersLength: false,
|
||||||
languages: false
|
languages: false,
|
||||||
|
readOnlyMode: false
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
module.exports = {
|
module.exports = {
|
||||||
maria: require('./mysql'),
|
maria: require('./mysql'),
|
||||||
mysql: require('./mysql'),
|
mysql: require('./mysql'),
|
||||||
pg: require('./postgresql')
|
pg: require('./postgresql'),
|
||||||
|
sqlite: require('./sqlite')
|
||||||
};
|
};
|
||||||
|
|
|
@ -10,6 +10,8 @@ module.exports = {
|
||||||
connectionSchema: true,
|
connectionSchema: true,
|
||||||
collations: true,
|
collations: true,
|
||||||
engines: true,
|
engines: true,
|
||||||
|
sslConnection: true,
|
||||||
|
sshConnection: true,
|
||||||
// Tools
|
// Tools
|
||||||
processesList: true,
|
processesList: true,
|
||||||
// Structure
|
// Structure
|
||||||
|
@ -30,6 +32,7 @@ module.exports = {
|
||||||
functionAdd: true,
|
functionAdd: true,
|
||||||
schedulerAdd: true,
|
schedulerAdd: true,
|
||||||
schemaEdit: true,
|
schemaEdit: true,
|
||||||
|
schemaDrop: true,
|
||||||
tableSettings: true,
|
tableSettings: true,
|
||||||
viewSettings: true,
|
viewSettings: true,
|
||||||
triggerSettings: true,
|
triggerSettings: true,
|
||||||
|
|
|
@ -8,6 +8,8 @@ module.exports = {
|
||||||
defaultDatabase: 'postgres',
|
defaultDatabase: 'postgres',
|
||||||
// Core
|
// Core
|
||||||
database: true,
|
database: true,
|
||||||
|
sslConnection: true,
|
||||||
|
sshConnection: true,
|
||||||
// Tools
|
// Tools
|
||||||
processesList: true,
|
processesList: true,
|
||||||
// Structure
|
// Structure
|
||||||
|
@ -26,6 +28,7 @@ module.exports = {
|
||||||
triggerFunctionAdd: true,
|
triggerFunctionAdd: true,
|
||||||
routineAdd: true,
|
routineAdd: true,
|
||||||
functionAdd: true,
|
functionAdd: true,
|
||||||
|
schemaDrop: true,
|
||||||
databaseEdit: false,
|
databaseEdit: false,
|
||||||
tableSettings: true,
|
tableSettings: true,
|
||||||
viewSettings: true,
|
viewSettings: true,
|
||||||
|
|
|
@ -0,0 +1,27 @@
|
||||||
|
module.exports = {
|
||||||
|
// Core
|
||||||
|
fileConnection: true,
|
||||||
|
// Structure
|
||||||
|
schemas: true,
|
||||||
|
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
|
||||||
|
};
|
|
@ -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
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
];
|
|
@ -0,0 +1,5 @@
|
||||||
|
module.exports = [
|
||||||
|
'PRIMARY',
|
||||||
|
'INDEX',
|
||||||
|
'UNIQUE'
|
||||||
|
];
|
|
@ -9,12 +9,16 @@ export default connections => {
|
||||||
port: +conn.port,
|
port: +conn.port,
|
||||||
user: conn.user,
|
user: conn.user,
|
||||||
password: conn.password,
|
password: conn.password,
|
||||||
application_name: 'Antares SQL'
|
application_name: 'Antares SQL',
|
||||||
|
readonly: conn.readonly
|
||||||
};
|
};
|
||||||
|
|
||||||
if (conn.database)
|
if (conn.database)
|
||||||
params.database = conn.database;
|
params.database = conn.database;
|
||||||
|
|
||||||
|
if (conn.databasePath)
|
||||||
|
params.databasePath = conn.databasePath;
|
||||||
|
|
||||||
if (conn.ssl) {
|
if (conn.ssl) {
|
||||||
params.ssl = {
|
params.ssl = {
|
||||||
key: conn.key ? fs.readFileSync(conn.key) : null,
|
key: conn.key ? fs.readFileSync(conn.key) : null,
|
||||||
|
@ -62,12 +66,16 @@ export default connections => {
|
||||||
port: +conn.port,
|
port: +conn.port,
|
||||||
user: conn.user,
|
user: conn.user,
|
||||||
password: conn.password,
|
password: conn.password,
|
||||||
application_name: 'Antares SQL'
|
application_name: 'Antares SQL',
|
||||||
|
readonly: conn.readonly
|
||||||
};
|
};
|
||||||
|
|
||||||
if (conn.database)
|
if (conn.database)
|
||||||
params.database = conn.database;
|
params.database = conn.database;
|
||||||
|
|
||||||
|
if (conn.databasePath)
|
||||||
|
params.databasePath = conn.databasePath;
|
||||||
|
|
||||||
if (conn.schema)
|
if (conn.schema)
|
||||||
params.schema = conn.schema;
|
params.schema = conn.schema;
|
||||||
|
|
||||||
|
|
|
@ -102,6 +102,9 @@ export default (connections) => {
|
||||||
case 'pg':
|
case 'pg':
|
||||||
escapedParam = `'${params.content.replaceAll('\'', '\'\'')}'`;
|
escapedParam = `'${params.content.replaceAll('\'', '\'\'')}'`;
|
||||||
break;
|
break;
|
||||||
|
case 'sqlite':
|
||||||
|
escapedParam = `'${params.content.replaceAll('\'', '\'\'')}'`;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (ARRAY.includes(params.type))
|
else if (ARRAY.includes(params.type))
|
||||||
|
@ -122,6 +125,10 @@ export default (connections) => {
|
||||||
fileBlob = fs.readFileSync(params.content);
|
fileBlob = fs.readFileSync(params.content);
|
||||||
escapedParam = `decode('${fileBlob.toString('hex')}', 'hex')`;
|
escapedParam = `decode('${fileBlob.toString('hex')}', 'hex')`;
|
||||||
break;
|
break;
|
||||||
|
case 'sqlite':
|
||||||
|
fileBlob = fs.readFileSync(params.content);
|
||||||
|
escapedParam = `X'${fileBlob.toString('hex')}'`;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
reload = true;
|
reload = true;
|
||||||
}
|
}
|
||||||
|
@ -134,6 +141,9 @@ export default (connections) => {
|
||||||
case 'pg':
|
case 'pg':
|
||||||
escapedParam = 'decode(\'\', \'hex\')';
|
escapedParam = 'decode(\'\', \'hex\')';
|
||||||
break;
|
break;
|
||||||
|
case 'sqlite':
|
||||||
|
escapedParam = 'X\'\'';
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
import { MySQLClient } from './clients/MySQLClient';
|
import { MySQLClient } from './clients/MySQLClient';
|
||||||
import { PostgreSQLClient } from './clients/PostgreSQLClient';
|
import { PostgreSQLClient } from './clients/PostgreSQLClient';
|
||||||
|
import { SQLiteClient } from './clients/SQLiteClient';
|
||||||
|
|
||||||
const queryLogger = sql => {
|
const queryLogger = sql => {
|
||||||
// Remove comments, newlines and multiple spaces
|
// Remove comments, newlines and multiple spaces
|
||||||
|
@ -37,6 +38,8 @@ export class ClientsFactory {
|
||||||
return new MySQLClient(args);
|
return new MySQLClient(args);
|
||||||
case 'pg':
|
case 'pg':
|
||||||
return new PostgreSQLClient(args);
|
return new PostgreSQLClient(args);
|
||||||
|
case 'sqlite':
|
||||||
|
return new SQLiteClient(args);
|
||||||
default:
|
default:
|
||||||
throw new Error(`Unknown database client: ${args.client}`);
|
throw new Error(`Unknown database client: ${args.client}`);
|
||||||
}
|
}
|
||||||
|
|
|
@ -571,7 +571,7 @@ export class MySQLClient extends AntaresCore {
|
||||||
/**
|
/**
|
||||||
* CREATE DATABASE
|
* CREATE DATABASE
|
||||||
*
|
*
|
||||||
* @returns {Array.<Object>} parameters
|
* @returns {Promise<null>}
|
||||||
* @memberof MySQLClient
|
* @memberof MySQLClient
|
||||||
*/
|
*/
|
||||||
async createSchema (params) {
|
async createSchema (params) {
|
||||||
|
@ -581,7 +581,7 @@ export class MySQLClient extends AntaresCore {
|
||||||
/**
|
/**
|
||||||
* ALTER DATABASE
|
* ALTER DATABASE
|
||||||
*
|
*
|
||||||
* @returns {Array.<Object>} parameters
|
* @returns {Promise<null>}
|
||||||
* @memberof MySQLClient
|
* @memberof MySQLClient
|
||||||
*/
|
*/
|
||||||
async alterSchema (params) {
|
async alterSchema (params) {
|
||||||
|
@ -591,7 +591,7 @@ export class MySQLClient extends AntaresCore {
|
||||||
/**
|
/**
|
||||||
* DROP DATABASE
|
* DROP DATABASE
|
||||||
*
|
*
|
||||||
* @returns {Array.<Object>} parameters
|
* @returns {Promise<null>}
|
||||||
* @memberof MySQLClient
|
* @memberof MySQLClient
|
||||||
*/
|
*/
|
||||||
async dropSchema (params) {
|
async dropSchema (params) {
|
||||||
|
@ -631,7 +631,7 @@ export class MySQLClient extends AntaresCore {
|
||||||
/**
|
/**
|
||||||
* DROP VIEW
|
* DROP VIEW
|
||||||
*
|
*
|
||||||
* @returns {Array.<Object>} parameters
|
* @returns {Promise<null>}
|
||||||
* @memberof MySQLClient
|
* @memberof MySQLClient
|
||||||
*/
|
*/
|
||||||
async dropView (params) {
|
async dropView (params) {
|
||||||
|
@ -642,7 +642,7 @@ export class MySQLClient extends AntaresCore {
|
||||||
/**
|
/**
|
||||||
* ALTER VIEW
|
* ALTER VIEW
|
||||||
*
|
*
|
||||||
* @returns {Array.<Object>} parameters
|
* @returns {Promise<null>}
|
||||||
* @memberof MySQLClient
|
* @memberof MySQLClient
|
||||||
*/
|
*/
|
||||||
async alterView (params) {
|
async alterView (params) {
|
||||||
|
@ -663,7 +663,7 @@ export class MySQLClient extends AntaresCore {
|
||||||
/**
|
/**
|
||||||
* CREATE VIEW
|
* CREATE VIEW
|
||||||
*
|
*
|
||||||
* @returns {Array.<Object>} parameters
|
* @returns {Promise<null>}
|
||||||
* @memberof MySQLClient
|
* @memberof MySQLClient
|
||||||
*/
|
*/
|
||||||
async createView (params) {
|
async createView (params) {
|
||||||
|
@ -696,7 +696,7 @@ export class MySQLClient extends AntaresCore {
|
||||||
/**
|
/**
|
||||||
* DROP TRIGGER
|
* DROP TRIGGER
|
||||||
*
|
*
|
||||||
* @returns {Array.<Object>} parameters
|
* @returns {Promise<null>}
|
||||||
* @memberof MySQLClient
|
* @memberof MySQLClient
|
||||||
*/
|
*/
|
||||||
async dropTrigger (params) {
|
async dropTrigger (params) {
|
||||||
|
@ -707,7 +707,7 @@ export class MySQLClient extends AntaresCore {
|
||||||
/**
|
/**
|
||||||
* ALTER TRIGGER
|
* ALTER TRIGGER
|
||||||
*
|
*
|
||||||
* @returns {Array.<Object>} parameters
|
* @returns {Promise<null>}
|
||||||
* @memberof MySQLClient
|
* @memberof MySQLClient
|
||||||
*/
|
*/
|
||||||
async alterTrigger (params) {
|
async alterTrigger (params) {
|
||||||
|
@ -729,7 +729,7 @@ export class MySQLClient extends AntaresCore {
|
||||||
/**
|
/**
|
||||||
* CREATE TRIGGER
|
* CREATE TRIGGER
|
||||||
*
|
*
|
||||||
* @returns {Array.<Object>} parameters
|
* @returns {Promise<null>}
|
||||||
* @memberof MySQLClient
|
* @memberof MySQLClient
|
||||||
*/
|
*/
|
||||||
async createTrigger (params) {
|
async createTrigger (params) {
|
||||||
|
@ -803,7 +803,7 @@ export class MySQLClient extends AntaresCore {
|
||||||
/**
|
/**
|
||||||
* DROP PROCEDURE
|
* DROP PROCEDURE
|
||||||
*
|
*
|
||||||
* @returns {Array.<Object>} parameters
|
* @returns {Promise<null>}
|
||||||
* @memberof MySQLClient
|
* @memberof MySQLClient
|
||||||
*/
|
*/
|
||||||
async dropRoutine (params) {
|
async dropRoutine (params) {
|
||||||
|
@ -814,7 +814,7 @@ export class MySQLClient extends AntaresCore {
|
||||||
/**
|
/**
|
||||||
* ALTER PROCEDURE
|
* ALTER PROCEDURE
|
||||||
*
|
*
|
||||||
* @returns {Array.<Object>} parameters
|
* @returns {Promise<null>}
|
||||||
* @memberof MySQLClient
|
* @memberof MySQLClient
|
||||||
*/
|
*/
|
||||||
async alterRoutine (params) {
|
async alterRoutine (params) {
|
||||||
|
@ -836,7 +836,7 @@ export class MySQLClient extends AntaresCore {
|
||||||
/**
|
/**
|
||||||
* CREATE PROCEDURE
|
* CREATE PROCEDURE
|
||||||
*
|
*
|
||||||
* @returns {Array.<Object>} parameters
|
* @returns {Promise<null>}
|
||||||
* @memberof MySQLClient
|
* @memberof MySQLClient
|
||||||
*/
|
*/
|
||||||
async createRoutine (params) {
|
async createRoutine (params) {
|
||||||
|
@ -930,7 +930,7 @@ export class MySQLClient extends AntaresCore {
|
||||||
/**
|
/**
|
||||||
* DROP FUNCTION
|
* DROP FUNCTION
|
||||||
*
|
*
|
||||||
* @returns {Array.<Object>} parameters
|
* @returns {Promise<null>}
|
||||||
* @memberof MySQLClient
|
* @memberof MySQLClient
|
||||||
*/
|
*/
|
||||||
async dropFunction (params) {
|
async dropFunction (params) {
|
||||||
|
@ -941,7 +941,7 @@ export class MySQLClient extends AntaresCore {
|
||||||
/**
|
/**
|
||||||
* ALTER FUNCTION
|
* ALTER FUNCTION
|
||||||
*
|
*
|
||||||
* @returns {Array.<Object>} parameters
|
* @returns {Promise<null>}
|
||||||
* @memberof MySQLClient
|
* @memberof MySQLClient
|
||||||
*/
|
*/
|
||||||
async alterFunction (params) {
|
async alterFunction (params) {
|
||||||
|
@ -963,7 +963,7 @@ export class MySQLClient extends AntaresCore {
|
||||||
/**
|
/**
|
||||||
* CREATE FUNCTION
|
* CREATE FUNCTION
|
||||||
*
|
*
|
||||||
* @returns {Array.<Object>} parameters
|
* @returns {Promise<null>}
|
||||||
* @memberof MySQLClient
|
* @memberof MySQLClient
|
||||||
*/
|
*/
|
||||||
async createFunction (params) {
|
async createFunction (params) {
|
||||||
|
@ -1024,7 +1024,7 @@ export class MySQLClient extends AntaresCore {
|
||||||
/**
|
/**
|
||||||
* DROP EVENT
|
* DROP EVENT
|
||||||
*
|
*
|
||||||
* @returns {Array.<Object>} parameters
|
* @returns {Promise<null>}
|
||||||
* @memberof MySQLClient
|
* @memberof MySQLClient
|
||||||
*/
|
*/
|
||||||
async dropEvent (params) {
|
async dropEvent (params) {
|
||||||
|
@ -1035,7 +1035,7 @@ export class MySQLClient extends AntaresCore {
|
||||||
/**
|
/**
|
||||||
* ALTER EVENT
|
* ALTER EVENT
|
||||||
*
|
*
|
||||||
* @returns {Array.<Object>} parameters
|
* @returns {Promise<null>}
|
||||||
* @memberof MySQLClient
|
* @memberof MySQLClient
|
||||||
*/
|
*/
|
||||||
async alterEvent (params) {
|
async alterEvent (params) {
|
||||||
|
@ -1061,7 +1061,7 @@ export class MySQLClient extends AntaresCore {
|
||||||
/**
|
/**
|
||||||
* CREATE EVENT
|
* CREATE EVENT
|
||||||
*
|
*
|
||||||
* @returns {Array.<Object>} parameters
|
* @returns {Promise<null>}
|
||||||
* @memberof MySQLClient
|
* @memberof MySQLClient
|
||||||
*/
|
*/
|
||||||
async createEvent (params) {
|
async createEvent (params) {
|
||||||
|
@ -1205,7 +1205,7 @@ export class MySQLClient extends AntaresCore {
|
||||||
/**
|
/**
|
||||||
* CREATE TABLE
|
* CREATE TABLE
|
||||||
*
|
*
|
||||||
* @returns {Array.<Object>} parameters
|
* @returns {Promise<null>}
|
||||||
* @memberof MySQLClient
|
* @memberof MySQLClient
|
||||||
*/
|
*/
|
||||||
async createTable (params) {
|
async createTable (params) {
|
||||||
|
@ -1267,7 +1267,7 @@ export class MySQLClient extends AntaresCore {
|
||||||
/**
|
/**
|
||||||
* ALTER TABLE
|
* ALTER TABLE
|
||||||
*
|
*
|
||||||
* @returns {Array.<Object>} parameters
|
* @returns {Promise<null>}
|
||||||
* @memberof MySQLClient
|
* @memberof MySQLClient
|
||||||
*/
|
*/
|
||||||
async alterTable (params) {
|
async alterTable (params) {
|
||||||
|
@ -1402,7 +1402,7 @@ export class MySQLClient extends AntaresCore {
|
||||||
/**
|
/**
|
||||||
* DUPLICATE TABLE
|
* DUPLICATE TABLE
|
||||||
*
|
*
|
||||||
* @returns {Array.<Object>} parameters
|
* @returns {Promise<null>}
|
||||||
* @memberof MySQLClient
|
* @memberof MySQLClient
|
||||||
*/
|
*/
|
||||||
async duplicateTable (params) {
|
async duplicateTable (params) {
|
||||||
|
@ -1413,7 +1413,7 @@ export class MySQLClient extends AntaresCore {
|
||||||
/**
|
/**
|
||||||
* TRUNCATE TABLE
|
* TRUNCATE TABLE
|
||||||
*
|
*
|
||||||
* @returns {Array.<Object>} parameters
|
* @returns {Promise<null>}
|
||||||
* @memberof MySQLClient
|
* @memberof MySQLClient
|
||||||
*/
|
*/
|
||||||
async truncateTable (params) {
|
async truncateTable (params) {
|
||||||
|
@ -1424,7 +1424,7 @@ export class MySQLClient extends AntaresCore {
|
||||||
/**
|
/**
|
||||||
* DROP TABLE
|
* DROP TABLE
|
||||||
*
|
*
|
||||||
* @returns {Array.<Object>} parameters
|
* @returns {Promise<null>}
|
||||||
* @memberof MySQLClient
|
* @memberof MySQLClient
|
||||||
*/
|
*/
|
||||||
async dropTable (params) {
|
async dropTable (params) {
|
||||||
|
|
|
@ -506,7 +506,7 @@ export class PostgreSQLClient extends AntaresCore {
|
||||||
/**
|
/**
|
||||||
* CREATE SCHEMA
|
* CREATE SCHEMA
|
||||||
*
|
*
|
||||||
* @returns {Array.<Object>} parameters
|
* @returns {Promise<null>}
|
||||||
* @memberof MySQLClient
|
* @memberof MySQLClient
|
||||||
*/
|
*/
|
||||||
async createSchema (params) {
|
async createSchema (params) {
|
||||||
|
@ -516,7 +516,7 @@ export class PostgreSQLClient extends AntaresCore {
|
||||||
/**
|
/**
|
||||||
* ALTER DATABASE
|
* ALTER DATABASE
|
||||||
*
|
*
|
||||||
* @returns {Array.<Object>} parameters
|
* @returns {Promise<null>}
|
||||||
* @memberof MySQLClient
|
* @memberof MySQLClient
|
||||||
*/
|
*/
|
||||||
async alterSchema (params) {
|
async alterSchema (params) {
|
||||||
|
@ -526,7 +526,7 @@ export class PostgreSQLClient extends AntaresCore {
|
||||||
/**
|
/**
|
||||||
* DROP DATABASE
|
* DROP DATABASE
|
||||||
*
|
*
|
||||||
* @returns {Array.<Object>} parameters
|
* @returns {Promise<null>}
|
||||||
* @memberof MySQLClient
|
* @memberof MySQLClient
|
||||||
*/
|
*/
|
||||||
async dropSchema (params) {
|
async dropSchema (params) {
|
||||||
|
@ -558,7 +558,7 @@ export class PostgreSQLClient extends AntaresCore {
|
||||||
/**
|
/**
|
||||||
* DROP VIEW
|
* DROP VIEW
|
||||||
*
|
*
|
||||||
* @returns {Array.<Object>} parameters
|
* @returns {Promise<null>}
|
||||||
* @memberof PostgreSQLClient
|
* @memberof PostgreSQLClient
|
||||||
*/
|
*/
|
||||||
async dropView (params) {
|
async dropView (params) {
|
||||||
|
@ -569,7 +569,7 @@ export class PostgreSQLClient extends AntaresCore {
|
||||||
/**
|
/**
|
||||||
* ALTER VIEW
|
* ALTER VIEW
|
||||||
*
|
*
|
||||||
* @returns {Array.<Object>} parameters
|
* @returns {Promise<null>}
|
||||||
* @memberof PostgreSQLClient
|
* @memberof PostgreSQLClient
|
||||||
*/
|
*/
|
||||||
async alterView (params) {
|
async alterView (params) {
|
||||||
|
@ -585,7 +585,7 @@ export class PostgreSQLClient extends AntaresCore {
|
||||||
/**
|
/**
|
||||||
* CREATE VIEW
|
* CREATE VIEW
|
||||||
*
|
*
|
||||||
* @returns {Array.<Object>} parameters
|
* @returns {Promise<null>}
|
||||||
* @memberof PostgreSQLClient
|
* @memberof PostgreSQLClient
|
||||||
*/
|
*/
|
||||||
async createView (params) {
|
async createView (params) {
|
||||||
|
@ -640,7 +640,7 @@ export class PostgreSQLClient extends AntaresCore {
|
||||||
/**
|
/**
|
||||||
* DROP TRIGGER
|
* DROP TRIGGER
|
||||||
*
|
*
|
||||||
* @returns {Array.<Object>} parameters
|
* @returns {Promise<null>}
|
||||||
* @memberof PostgreSQLClient
|
* @memberof PostgreSQLClient
|
||||||
*/
|
*/
|
||||||
async dropTrigger (params) {
|
async dropTrigger (params) {
|
||||||
|
@ -652,7 +652,7 @@ export class PostgreSQLClient extends AntaresCore {
|
||||||
/**
|
/**
|
||||||
* ALTER TRIGGER
|
* ALTER TRIGGER
|
||||||
*
|
*
|
||||||
* @returns {Array.<Object>} parameters
|
* @returns {Promise<null>}
|
||||||
* @memberof PostgreSQLClient
|
* @memberof PostgreSQLClient
|
||||||
*/
|
*/
|
||||||
async alterTrigger (params) {
|
async alterTrigger (params) {
|
||||||
|
@ -674,7 +674,7 @@ export class PostgreSQLClient extends AntaresCore {
|
||||||
/**
|
/**
|
||||||
* CREATE TRIGGER
|
* CREATE TRIGGER
|
||||||
*
|
*
|
||||||
* @returns {Array.<Object>} parameters
|
* @returns {Promise<null>}
|
||||||
* @memberof PostgreSQLClient
|
* @memberof PostgreSQLClient
|
||||||
*/
|
*/
|
||||||
async createTrigger (params) {
|
async createTrigger (params) {
|
||||||
|
@ -1086,7 +1086,7 @@ export class PostgreSQLClient extends AntaresCore {
|
||||||
/**
|
/**
|
||||||
* CREATE TABLE
|
* CREATE TABLE
|
||||||
*
|
*
|
||||||
* @returns {Array.<Object>} parameters
|
* @returns {Promise<null>}
|
||||||
* @memberof PostgreSQLClient
|
* @memberof PostgreSQLClient
|
||||||
*/
|
*/
|
||||||
async createTable (params) {
|
async createTable (params) {
|
||||||
|
@ -1144,7 +1144,7 @@ export class PostgreSQLClient extends AntaresCore {
|
||||||
/**
|
/**
|
||||||
* ALTER TABLE
|
* ALTER TABLE
|
||||||
*
|
*
|
||||||
* @returns {Array.<Object>} parameters
|
* @returns {Promise<null>}
|
||||||
* @memberof PostgreSQLClient
|
* @memberof PostgreSQLClient
|
||||||
*/
|
*/
|
||||||
async alterTable (params) {
|
async alterTable (params) {
|
||||||
|
@ -1290,7 +1290,7 @@ export class PostgreSQLClient extends AntaresCore {
|
||||||
/**
|
/**
|
||||||
* DUPLICATE TABLE
|
* DUPLICATE TABLE
|
||||||
*
|
*
|
||||||
* @returns {Array.<Object>} parameters
|
* @returns {Promise<null>}
|
||||||
* @memberof PostgreSQLClient
|
* @memberof PostgreSQLClient
|
||||||
*/
|
*/
|
||||||
async duplicateTable (params) {
|
async duplicateTable (params) {
|
||||||
|
@ -1301,7 +1301,7 @@ export class PostgreSQLClient extends AntaresCore {
|
||||||
/**
|
/**
|
||||||
* TRUNCATE TABLE
|
* TRUNCATE TABLE
|
||||||
*
|
*
|
||||||
* @returns {Array.<Object>} parameters
|
* @returns {Promise<null>}
|
||||||
* @memberof PostgreSQLClient
|
* @memberof PostgreSQLClient
|
||||||
*/
|
*/
|
||||||
async truncateTable (params) {
|
async truncateTable (params) {
|
||||||
|
@ -1312,7 +1312,7 @@ export class PostgreSQLClient extends AntaresCore {
|
||||||
/**
|
/**
|
||||||
* DROP TABLE
|
* DROP TABLE
|
||||||
*
|
*
|
||||||
* @returns {Array.<Object>} parameters
|
* @returns {Promise<null>}
|
||||||
* @memberof PostgreSQLClient
|
* @memberof PostgreSQLClient
|
||||||
*/
|
*/
|
||||||
async dropTable (params) {
|
async dropTable (params) {
|
||||||
|
|
|
@ -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();
|
mainWindow = await createMainWindow();
|
||||||
createAppMenu();
|
createAppMenu();
|
||||||
|
|
||||||
if (isDevelopment)
|
// if (isDevelopment)
|
||||||
mainWindow.webContents.openDevTools();
|
// mainWindow.webContents.openDevTools();
|
||||||
|
|
||||||
process.on('uncaughtException', (error) => {
|
process.on('uncaughtException', error => {
|
||||||
mainWindow.webContents.send('unhandled-exception', error);
|
mainWindow.webContents.send('unhandled-exception', error);
|
||||||
});
|
});
|
||||||
|
|
||||||
process.on('unhandledRejection', (error) => {
|
process.on('unhandledRejection', error => {
|
||||||
mainWindow.webContents.send('unhandled-exception', error);
|
mainWindow.webContents.send('unhandled-exception', error);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
<a class="tab-link">{{ $t('word.general') }}</a>
|
<a class="tab-link">{{ $t('word.general') }}</a>
|
||||||
</li>
|
</li>
|
||||||
<li
|
<li
|
||||||
|
v-if="customizations.sslConnection"
|
||||||
class="tab-item c-hand"
|
class="tab-item c-hand"
|
||||||
:class="{'active': selectedTab === 'ssl'}"
|
:class="{'active': selectedTab === 'ssl'}"
|
||||||
@click="selectTab('ssl')"
|
@click="selectTab('ssl')"
|
||||||
|
@ -18,6 +19,7 @@
|
||||||
<a class="tab-link">{{ $t('word.ssl') }}</a>
|
<a class="tab-link">{{ $t('word.ssl') }}</a>
|
||||||
</li>
|
</li>
|
||||||
<li
|
<li
|
||||||
|
v-if="customizations.sshConnection"
|
||||||
class="tab-item c-hand"
|
class="tab-item c-hand"
|
||||||
:class="{'active': selectedTab === 'ssh'}"
|
:class="{'active': selectedTab === 'ssh'}"
|
||||||
@click="selectTab('ssh')"
|
@click="selectTab('ssh')"
|
||||||
|
@ -49,25 +51,17 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="column col-8 col-sm-12">
|
<div class="column col-8 col-sm-12">
|
||||||
<select v-model="connection.client" class="form-select">
|
<select v-model="connection.client" class="form-select">
|
||||||
<option value="mysql">
|
<option
|
||||||
MySQL
|
v-for="client in clients"
|
||||||
|
:key="client.slug"
|
||||||
|
:value="client.slug"
|
||||||
|
>
|
||||||
|
{{ client.name }}
|
||||||
</option>
|
</option>
|
||||||
<option value="maria">
|
|
||||||
MariaDB
|
|
||||||
</option>
|
|
||||||
<option value="pg">
|
|
||||||
PostgreSQL
|
|
||||||
</option>
|
|
||||||
<!-- <option value="mssql">
|
|
||||||
Microsoft SQL
|
|
||||||
</option>
|
|
||||||
<option value="oracledb">
|
|
||||||
Oracle DB
|
|
||||||
</option> -->
|
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group columns">
|
<div v-if="!customizations.fileConnection" class="form-group columns">
|
||||||
<div class="column col-4 col-sm-12">
|
<div class="column col-4 col-sm-12">
|
||||||
<label class="form-label">{{ $t('word.hostName') }}/IP</label>
|
<label class="form-label">{{ $t('word.hostName') }}/IP</label>
|
||||||
</div>
|
</div>
|
||||||
|
@ -79,7 +73,20 @@
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
</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">
|
<div class="column col-4 col-sm-12">
|
||||||
<label class="form-label">{{ $t('word.port') }}</label>
|
<label class="form-label">{{ $t('word.port') }}</label>
|
||||||
</div>
|
</div>
|
||||||
|
@ -105,7 +112,7 @@
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group columns">
|
<div v-if="!customizations.fileConnection" class="form-group columns">
|
||||||
<div class="column col-4 col-sm-12">
|
<div class="column col-4 col-sm-12">
|
||||||
<label class="form-label">{{ $t('word.user') }}</label>
|
<label class="form-label">{{ $t('word.user') }}</label>
|
||||||
</div>
|
</div>
|
||||||
|
@ -118,7 +125,7 @@
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group columns">
|
<div v-if="!customizations.fileConnection" class="form-group columns">
|
||||||
<div class="column col-4 col-sm-12">
|
<div class="column col-4 col-sm-12">
|
||||||
<label class="form-label">{{ $t('word.password') }}</label>
|
<label class="form-label">{{ $t('word.password') }}</label>
|
||||||
</div>
|
</div>
|
||||||
|
@ -144,7 +151,15 @@
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
</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-4 col-sm-12" />
|
||||||
<div class="column col-8 col-sm-12">
|
<div class="column col-8 col-sm-12">
|
||||||
<label class="form-checkbox form-inline">
|
<label class="form-checkbox form-inline">
|
||||||
|
@ -369,15 +384,23 @@ export default {
|
||||||
},
|
},
|
||||||
data () {
|
data () {
|
||||||
return {
|
return {
|
||||||
|
clients: [
|
||||||
|
{ name: 'MySQL', slug: 'mysql' },
|
||||||
|
{ name: 'MariaDB', slug: 'maria' },
|
||||||
|
{ name: 'PostgreSQL', slug: 'pg' },
|
||||||
|
{ name: 'SQLite', slug: 'sqlite' }
|
||||||
|
],
|
||||||
connection: {
|
connection: {
|
||||||
name: '',
|
name: '',
|
||||||
client: 'mysql',
|
client: 'mysql',
|
||||||
host: '127.0.0.1',
|
host: '127.0.0.1',
|
||||||
database: null,
|
database: null,
|
||||||
|
databasePath: '',
|
||||||
port: null,
|
port: null,
|
||||||
user: null,
|
user: null,
|
||||||
password: '',
|
password: '',
|
||||||
ask: false,
|
ask: false,
|
||||||
|
readonly: false,
|
||||||
uid: uidGen('C'),
|
uid: uidGen('C'),
|
||||||
ssl: false,
|
ssl: false,
|
||||||
cert: '',
|
cert: '',
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
<a class="tab-link">{{ $t('word.general') }}</a>
|
<a class="tab-link">{{ $t('word.general') }}</a>
|
||||||
</li>
|
</li>
|
||||||
<li
|
<li
|
||||||
|
v-if="customizations.sslConnection"
|
||||||
class="tab-item c-hand"
|
class="tab-item c-hand"
|
||||||
:class="{'active': selectedTab === 'ssl'}"
|
:class="{'active': selectedTab === 'ssl'}"
|
||||||
@click="selectTab('ssl')"
|
@click="selectTab('ssl')"
|
||||||
|
@ -18,6 +19,7 @@
|
||||||
<a class="tab-link">{{ $t('word.ssl') }}</a>
|
<a class="tab-link">{{ $t('word.ssl') }}</a>
|
||||||
</li>
|
</li>
|
||||||
<li
|
<li
|
||||||
|
v-if="customizations.sshConnection"
|
||||||
class="tab-item c-hand"
|
class="tab-item c-hand"
|
||||||
:class="{'active': selectedTab === 'ssh'}"
|
:class="{'active': selectedTab === 'ssh'}"
|
||||||
@click="selectTab('ssh')"
|
@click="selectTab('ssh')"
|
||||||
|
@ -49,19 +51,17 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="column col-8 col-sm-12">
|
<div class="column col-8 col-sm-12">
|
||||||
<select v-model="localConnection.client" class="form-select">
|
<select v-model="localConnection.client" class="form-select">
|
||||||
<option value="mysql">
|
<option
|
||||||
MySQL
|
v-for="client in clients"
|
||||||
</option>
|
:key="client.slug"
|
||||||
<option value="maria">
|
:value="client.slug"
|
||||||
MariaDB
|
>
|
||||||
</option>
|
{{ client.name }}
|
||||||
<option value="pg">
|
|
||||||
PostgreSQL
|
|
||||||
</option>
|
</option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group columns">
|
<div v-if="!customizations.fileConnection" class="form-group columns">
|
||||||
<div class="column col-4 col-sm-12">
|
<div class="column col-4 col-sm-12">
|
||||||
<label class="form-label">{{ $t('word.hostName') }}/IP</label>
|
<label class="form-label">{{ $t('word.hostName') }}/IP</label>
|
||||||
</div>
|
</div>
|
||||||
|
@ -73,7 +73,20 @@
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
</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">
|
<div class="column col-4 col-sm-12">
|
||||||
<label class="form-label">{{ $t('word.port') }}</label>
|
<label class="form-label">{{ $t('word.port') }}</label>
|
||||||
</div>
|
</div>
|
||||||
|
@ -99,7 +112,7 @@
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group columns">
|
<div v-if="!customizations.fileConnection" class="form-group columns">
|
||||||
<div class="column col-4 col-sm-12">
|
<div class="column col-4 col-sm-12">
|
||||||
<label class="form-label">{{ $t('word.user') }}</label>
|
<label class="form-label">{{ $t('word.user') }}</label>
|
||||||
</div>
|
</div>
|
||||||
|
@ -112,7 +125,7 @@
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group columns">
|
<div v-if="!customizations.fileConnection" class="form-group columns">
|
||||||
<div class="column col-4 col-sm-12">
|
<div class="column col-4 col-sm-12">
|
||||||
<label class="form-label">{{ $t('word.password') }}</label>
|
<label class="form-label">{{ $t('word.password') }}</label>
|
||||||
</div>
|
</div>
|
||||||
|
@ -138,7 +151,15 @@
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
</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-4 col-sm-12" />
|
||||||
<div class="column col-8 col-sm-12">
|
<div class="column col-8 col-sm-12">
|
||||||
<label class="form-checkbox form-inline">
|
<label class="form-checkbox form-inline">
|
||||||
|
@ -374,6 +395,12 @@ export default {
|
||||||
},
|
},
|
||||||
data () {
|
data () {
|
||||||
return {
|
return {
|
||||||
|
clients: [
|
||||||
|
{ name: 'MySQL', slug: 'mysql' },
|
||||||
|
{ name: 'MariaDB', slug: 'maria' },
|
||||||
|
{ name: 'PostgreSQL', slug: 'pg' },
|
||||||
|
{ name: 'SQLite', slug: 'sqlite' }
|
||||||
|
],
|
||||||
isConnecting: false,
|
isConnecting: false,
|
||||||
isTesting: false,
|
isTesting: false,
|
||||||
isAsking: false,
|
isAsking: false,
|
||||||
|
@ -383,7 +410,7 @@ export default {
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
customizations () {
|
customizations () {
|
||||||
return customizations[this.connection.client];
|
return customizations[this.localConnection.client];
|
||||||
},
|
},
|
||||||
isBusy () {
|
isBusy () {
|
||||||
return this.isConnecting || this.isTesting;
|
return this.isConnecting || this.isTesting;
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
<span class="workspace-explorebar-title">{{ connectionName }}</span>
|
<span class="workspace-explorebar-title">{{ connectionName }}</span>
|
||||||
<span v-if="workspace.connectionStatus === 'connected'" class="workspace-explorebar-tools">
|
<span v-if="workspace.connectionStatus === 'connected'" class="workspace-explorebar-tools">
|
||||||
<i
|
<i
|
||||||
|
v-if="customizations.schemas"
|
||||||
class="mdi mdi-18px mdi-database-plus c-hand mr-2"
|
class="mdi mdi-18px mdi-database-plus c-hand mr-2"
|
||||||
:title="$t('message.createNewSchema')"
|
:title="$t('message.createNewSchema')"
|
||||||
@click="showNewDBModal"
|
@click="showNewDBModal"
|
||||||
|
|
|
@ -43,7 +43,7 @@
|
||||||
<span v-html="highlightWord(table.name)" />
|
<span v-html="highlightWord(table.name)" />
|
||||||
</a>
|
</a>
|
||||||
<div
|
<div
|
||||||
v-if="table.type === 'table'"
|
v-if="table.type === 'table' && table.size !== false"
|
||||||
class="table-size tooltip tooltip-left mr-1"
|
class="table-size tooltip tooltip-left mr-1"
|
||||||
:data-tooltip="formatBytes(table.size)"
|
: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>
|
<span class="d-flex"><i class="mdi mdi-18px mdi-database-edit text-light pr-1" /> {{ $t('word.edit') }}</span>
|
||||||
</div>
|
</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>
|
<span class="d-flex"><i class="mdi mdi-18px mdi-database-remove text-light pr-1" /> {{ $t('word.delete') }}</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
@ -506,6 +506,12 @@ export default {
|
||||||
uid: this.connection.uid,
|
uid: this.connection.uid,
|
||||||
schema: this.schema,
|
schema: this.schema,
|
||||||
table: this.table,
|
table: this.table,
|
||||||
|
tableStructure: {
|
||||||
|
name: this.localOptions.name,
|
||||||
|
fields: this.localFields,
|
||||||
|
foreigns: this.localKeyUsage,
|
||||||
|
indexes: this.localIndexes
|
||||||
|
},
|
||||||
additions,
|
additions,
|
||||||
changes,
|
changes,
|
||||||
deletions,
|
deletions,
|
||||||
|
|
|
@ -367,7 +367,8 @@ export default {
|
||||||
getWorkspace: 'workspaces/getWorkspace'
|
getWorkspace: 'workspaces/getWorkspace'
|
||||||
}),
|
}),
|
||||||
localLength () {
|
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 () {
|
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 =>
|
||||||
|
@ -391,7 +392,7 @@ export default {
|
||||||
return this.indexes.some(index => ['PRIMARY', 'UNIQUE'].includes(index.type));
|
return this.indexes.some(index => ['PRIMARY', 'UNIQUE'].includes(index.type));
|
||||||
},
|
},
|
||||||
isNullable () {
|
isNullable () {
|
||||||
return !this.indexes.some(index => ['PRIMARY'].includes(index.type));
|
return this.customizations.nullablePrimary || !this.indexes.some(index => ['PRIMARY'].includes(index.type));
|
||||||
},
|
},
|
||||||
isInDataTypes () {
|
isInDataTypes () {
|
||||||
let typeNames = [];
|
let typeNames = [];
|
||||||
|
|
|
@ -93,7 +93,7 @@
|
||||||
<div v-if="resultsCount">
|
<div v-if="resultsCount">
|
||||||
{{ $t('word.results') }}: <b>{{ resultsCount.toLocaleString() }}</b>
|
{{ $t('word.results') }}: <b>{{ resultsCount.toLocaleString() }}</b>
|
||||||
</div>
|
</div>
|
||||||
<div v-if="affectedCount">
|
<div v-if="affectedCount !== null">
|
||||||
{{ $t('message.affectedRows') }}: <b>{{ affectedCount }}</b>
|
{{ $t('message.affectedRows') }}: <b>{{ affectedCount }}</b>
|
||||||
</div>
|
</div>
|
||||||
<div class="input-group" :title="$t('word.schema')">
|
<div class="input-group" :title="$t('word.schema')">
|
||||||
|
@ -170,7 +170,7 @@ export default {
|
||||||
selectedSchema: null,
|
selectedSchema: null,
|
||||||
resultsCount: 0,
|
resultsCount: 0,
|
||||||
durationsCount: 0,
|
durationsCount: 0,
|
||||||
affectedCount: 0,
|
affectedCount: null,
|
||||||
editorHeight: 200,
|
editorHeight: 200,
|
||||||
isHistoryOpen: false
|
isHistoryOpen: false
|
||||||
};
|
};
|
||||||
|
@ -255,9 +255,14 @@ export default {
|
||||||
|
|
||||||
if (status === 'success') {
|
if (status === 'success') {
|
||||||
this.results = Array.isArray(response) ? response : [response];
|
this.results = Array.isArray(response) ? response : [response];
|
||||||
this.resultsCount += this.results.reduce((acc, curr) => acc + (curr.rows ? curr.rows.length : 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.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.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({
|
this.updateTabContent({
|
||||||
uid: this.connection.uid,
|
uid: this.connection.uid,
|
||||||
|
@ -285,7 +290,7 @@ export default {
|
||||||
this.results = [];
|
this.results = [];
|
||||||
this.resultsCount = 0;
|
this.resultsCount = 0;
|
||||||
this.durationsCount = 0;
|
this.durationsCount = 0;
|
||||||
this.affectedCount = 0;
|
this.affectedCount = null;
|
||||||
},
|
},
|
||||||
resize (e) {
|
resize (e) {
|
||||||
const el = this.$refs.queryEditor.$el;
|
const el = this.$refs.queryEditor.$el;
|
||||||
|
|
|
@ -120,7 +120,12 @@
|
||||||
{{ $t('word.results') }}: <b>{{ results[0].rows.length | localeString }}</b>
|
{{ $t('word.results') }}: <b>{{ results[0].rows.length | localeString }}</b>
|
||||||
</div>
|
</div>
|
||||||
<div v-if="hasApproximately || (page > 1 && approximateCount)">
|
<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>
|
||||||
<div class="d-flex" :title="$t('word.schema')">
|
<div class="d-flex" :title="$t('word.schema')">
|
||||||
<i class="mdi mdi-18px mdi-database mr-1" /><b>{{ schema }}</b>
|
<i class="mdi mdi-18px mdi-database mr-1" /><b>{{ schema }}</b>
|
||||||
|
@ -231,6 +236,9 @@ export default {
|
||||||
workspace () {
|
workspace () {
|
||||||
return this.getWorkspace(this.connection.uid);
|
return this.getWorkspace(this.connection.uid);
|
||||||
},
|
},
|
||||||
|
customizations () {
|
||||||
|
return this.workspace.customizations;
|
||||||
|
},
|
||||||
isTable () {
|
isTable () {
|
||||||
return !!this.workspace.breadcrumbs.table;
|
return !!this.workspace.breadcrumbs.table;
|
||||||
},
|
},
|
||||||
|
|
|
@ -250,7 +250,8 @@ module.exports = {
|
||||||
searchForQueries: 'Search for queries',
|
searchForQueries: 'Search for queries',
|
||||||
killProcess: 'Kill process',
|
killProcess: 'Kill process',
|
||||||
closeTab: 'Close tab',
|
closeTab: 'Close tab',
|
||||||
goToDownloadPage: 'Go to download page'
|
goToDownloadPage: 'Go to download page',
|
||||||
|
readOnlyMode: 'Read-only mode'
|
||||||
},
|
},
|
||||||
faker: {
|
faker: {
|
||||||
address: 'Address',
|
address: 'Address',
|
||||||
|
|
Before Width: | Height: | Size: 1004 B After Width: | Height: | Size: 1004 B |
|
@ -17,10 +17,12 @@
|
||||||
(
|
(
|
||||||
"char": $string-color,
|
"char": $string-color,
|
||||||
"varchar": $string-color,
|
"varchar": $string-color,
|
||||||
|
"longvarchar": $string-color,
|
||||||
"text": $string-color,
|
"text": $string-color,
|
||||||
"tinytext": $string-color,
|
"tinytext": $string-color,
|
||||||
"mediumtext": $string-color,
|
"mediumtext": $string-color,
|
||||||
"longtext": $string-color,
|
"longtext": $string-color,
|
||||||
|
"string": $string-color,
|
||||||
"json": $string-color,
|
"json": $string-color,
|
||||||
"name": $string-color,
|
"name": $string-color,
|
||||||
"character": $string-color,
|
"character": $string-color,
|
||||||
|
@ -50,6 +52,7 @@
|
||||||
"oid": $number-color,
|
"oid": $number-color,
|
||||||
"xid": $number-color,
|
"xid": $number-color,
|
||||||
"money": $number-color,
|
"money": $number-color,
|
||||||
|
"number": $number-color,
|
||||||
"datetime": $date-color,
|
"datetime": $date-color,
|
||||||
"date": $date-color,
|
"date": $date-color,
|
||||||
"time": $date-color,
|
"time": $date-color,
|
||||||
|
|
|
@ -20,6 +20,10 @@
|
||||||
background-image: url("../images/svg/pg.svg");
|
background-image: url("../images/svg/pg.svg");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&.dbi-sqlite {
|
||||||
|
background-image: url("../images/svg/sqlite.svg");
|
||||||
|
}
|
||||||
|
|
||||||
&.dbi-oracledb {
|
&.dbi-oracledb {
|
||||||
background-image: url("../images/svg/oracledb.svg");
|
background-image: url("../images/svg/oracledb.svg");
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,12 +24,24 @@ export default {
|
||||||
getConnections: state => state.connections,
|
getConnections: state => state.connections,
|
||||||
getConnectionName: state => uid => {
|
getConnectionName: state => uid => {
|
||||||
const connection = state.connections.filter(connection => connection.uid === uid)[0];
|
const connection = state.connections.filter(connection => connection.uid === uid)[0];
|
||||||
if (!connection) return '';
|
let connectionName = '';
|
||||||
return connection.name
|
|
||||||
? connection.name
|
if (connection.name)
|
||||||
: connection.ask
|
connectionName = connection.name;
|
||||||
? `${connection.host}:${connection.port}`
|
else if (connection.ask)
|
||||||
: `${connection.user + '@'}${connection.host}:${connection.port}`;
|
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: {
|
mutations: {
|
||||||
|
|
|
@ -412,6 +412,11 @@ export default {
|
||||||
indexTypes = require('common/index-types/postgresql');
|
indexTypes = require('common/index-types/postgresql');
|
||||||
customizations = require('common/customizations/postgresql');
|
customizations = require('common/customizations/postgresql');
|
||||||
break;
|
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);
|
const { status, response: version } = await Schema.getVersion(connection.uid);
|
||||||
|
|
Loading…
Reference in New Issue