mirror of https://github.com/Fabio286/antares.git
feat(SQLite): tables management
This commit is contained in:
parent
3fc227d2de
commit
3efeb45c46
|
@ -36,6 +36,7 @@ module.exports = {
|
|||
schedulerAdd: false,
|
||||
databaseEdit: false,
|
||||
schemaEdit: false,
|
||||
schemaDrop: false,
|
||||
tableSettings: false,
|
||||
tableOptions: false,
|
||||
tableArray: false,
|
||||
|
@ -51,6 +52,7 @@ module.exports = {
|
|||
sortableFields: false,
|
||||
unsigned: false,
|
||||
nullable: false,
|
||||
nullablePrimary: false,
|
||||
zerofill: false,
|
||||
autoIncrement: false,
|
||||
comment: false,
|
||||
|
|
|
@ -32,6 +32,7 @@ module.exports = {
|
|||
functionAdd: true,
|
||||
schedulerAdd: true,
|
||||
schemaEdit: true,
|
||||
schemaDrop: true,
|
||||
tableSettings: true,
|
||||
viewSettings: true,
|
||||
triggerSettings: true,
|
||||
|
|
|
@ -28,6 +28,7 @@ module.exports = {
|
|||
triggerFunctionAdd: true,
|
||||
routineAdd: true,
|
||||
functionAdd: true,
|
||||
schemaDrop: true,
|
||||
databaseEdit: false,
|
||||
tableSettings: true,
|
||||
viewSettings: true,
|
||||
|
|
|
@ -25,7 +25,7 @@ module.exports = {
|
|||
// Settings
|
||||
elementsWrapper: '',
|
||||
stringsWrapper: '"',
|
||||
tableAdd: false,
|
||||
tableAdd: true,
|
||||
viewAdd: false,
|
||||
triggerAdd: false,
|
||||
triggerFunctionAdd: false,
|
||||
|
@ -34,7 +34,7 @@ module.exports = {
|
|||
schedulerAdd: false,
|
||||
databaseEdit: false,
|
||||
schemaEdit: false,
|
||||
tableSettings: false,
|
||||
tableSettings: true,
|
||||
tableArray: false,
|
||||
tableRealCount: true,
|
||||
viewSettings: false,
|
||||
|
@ -43,11 +43,12 @@ module.exports = {
|
|||
routineSettings: false,
|
||||
functionSettings: false,
|
||||
schedulerSettings: false,
|
||||
indexes: false,
|
||||
foreigns: false,
|
||||
sortableFields: false,
|
||||
indexes: true,
|
||||
foreigns: true,
|
||||
sortableFields: true,
|
||||
unsigned: false,
|
||||
nullable: false,
|
||||
nullable: true,
|
||||
nullablePrimary: true,
|
||||
zerofill: false,
|
||||
tableOptions: false,
|
||||
autoIncrement: false,
|
||||
|
|
|
@ -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: true,
|
||||
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'
|
||||
];
|
|
@ -571,7 +571,7 @@ export class MySQLClient extends AntaresCore {
|
|||
/**
|
||||
* CREATE DATABASE
|
||||
*
|
||||
* @returns {Array.<Object>} parameters
|
||||
* @returns {Promise<null>}
|
||||
* @memberof MySQLClient
|
||||
*/
|
||||
async createSchema (params) {
|
||||
|
@ -581,7 +581,7 @@ export class MySQLClient extends AntaresCore {
|
|||
/**
|
||||
* ALTER DATABASE
|
||||
*
|
||||
* @returns {Array.<Object>} parameters
|
||||
* @returns {Promise<null>}
|
||||
* @memberof MySQLClient
|
||||
*/
|
||||
async alterSchema (params) {
|
||||
|
@ -591,7 +591,7 @@ export class MySQLClient extends AntaresCore {
|
|||
/**
|
||||
* DROP DATABASE
|
||||
*
|
||||
* @returns {Array.<Object>} parameters
|
||||
* @returns {Promise<null>}
|
||||
* @memberof MySQLClient
|
||||
*/
|
||||
async dropSchema (params) {
|
||||
|
@ -631,7 +631,7 @@ export class MySQLClient extends AntaresCore {
|
|||
/**
|
||||
* DROP VIEW
|
||||
*
|
||||
* @returns {Array.<Object>} parameters
|
||||
* @returns {Promise<null>}
|
||||
* @memberof MySQLClient
|
||||
*/
|
||||
async dropView (params) {
|
||||
|
@ -642,7 +642,7 @@ export class MySQLClient extends AntaresCore {
|
|||
/**
|
||||
* ALTER VIEW
|
||||
*
|
||||
* @returns {Array.<Object>} parameters
|
||||
* @returns {Promise<null>}
|
||||
* @memberof MySQLClient
|
||||
*/
|
||||
async alterView (params) {
|
||||
|
@ -663,7 +663,7 @@ export class MySQLClient extends AntaresCore {
|
|||
/**
|
||||
* CREATE VIEW
|
||||
*
|
||||
* @returns {Array.<Object>} parameters
|
||||
* @returns {Promise<null>}
|
||||
* @memberof MySQLClient
|
||||
*/
|
||||
async createView (params) {
|
||||
|
@ -696,7 +696,7 @@ export class MySQLClient extends AntaresCore {
|
|||
/**
|
||||
* DROP TRIGGER
|
||||
*
|
||||
* @returns {Array.<Object>} parameters
|
||||
* @returns {Promise<null>}
|
||||
* @memberof MySQLClient
|
||||
*/
|
||||
async dropTrigger (params) {
|
||||
|
@ -707,7 +707,7 @@ export class MySQLClient extends AntaresCore {
|
|||
/**
|
||||
* ALTER TRIGGER
|
||||
*
|
||||
* @returns {Array.<Object>} parameters
|
||||
* @returns {Promise<null>}
|
||||
* @memberof MySQLClient
|
||||
*/
|
||||
async alterTrigger (params) {
|
||||
|
@ -729,7 +729,7 @@ export class MySQLClient extends AntaresCore {
|
|||
/**
|
||||
* CREATE TRIGGER
|
||||
*
|
||||
* @returns {Array.<Object>} parameters
|
||||
* @returns {Promise<null>}
|
||||
* @memberof MySQLClient
|
||||
*/
|
||||
async createTrigger (params) {
|
||||
|
@ -803,7 +803,7 @@ export class MySQLClient extends AntaresCore {
|
|||
/**
|
||||
* DROP PROCEDURE
|
||||
*
|
||||
* @returns {Array.<Object>} parameters
|
||||
* @returns {Promise<null>}
|
||||
* @memberof MySQLClient
|
||||
*/
|
||||
async dropRoutine (params) {
|
||||
|
@ -814,7 +814,7 @@ export class MySQLClient extends AntaresCore {
|
|||
/**
|
||||
* ALTER PROCEDURE
|
||||
*
|
||||
* @returns {Array.<Object>} parameters
|
||||
* @returns {Promise<null>}
|
||||
* @memberof MySQLClient
|
||||
*/
|
||||
async alterRoutine (params) {
|
||||
|
@ -836,7 +836,7 @@ export class MySQLClient extends AntaresCore {
|
|||
/**
|
||||
* CREATE PROCEDURE
|
||||
*
|
||||
* @returns {Array.<Object>} parameters
|
||||
* @returns {Promise<null>}
|
||||
* @memberof MySQLClient
|
||||
*/
|
||||
async createRoutine (params) {
|
||||
|
@ -930,7 +930,7 @@ export class MySQLClient extends AntaresCore {
|
|||
/**
|
||||
* DROP FUNCTION
|
||||
*
|
||||
* @returns {Array.<Object>} parameters
|
||||
* @returns {Promise<null>}
|
||||
* @memberof MySQLClient
|
||||
*/
|
||||
async dropFunction (params) {
|
||||
|
@ -941,7 +941,7 @@ export class MySQLClient extends AntaresCore {
|
|||
/**
|
||||
* ALTER FUNCTION
|
||||
*
|
||||
* @returns {Array.<Object>} parameters
|
||||
* @returns {Promise<null>}
|
||||
* @memberof MySQLClient
|
||||
*/
|
||||
async alterFunction (params) {
|
||||
|
@ -963,7 +963,7 @@ export class MySQLClient extends AntaresCore {
|
|||
/**
|
||||
* CREATE FUNCTION
|
||||
*
|
||||
* @returns {Array.<Object>} parameters
|
||||
* @returns {Promise<null>}
|
||||
* @memberof MySQLClient
|
||||
*/
|
||||
async createFunction (params) {
|
||||
|
@ -1024,7 +1024,7 @@ export class MySQLClient extends AntaresCore {
|
|||
/**
|
||||
* DROP EVENT
|
||||
*
|
||||
* @returns {Array.<Object>} parameters
|
||||
* @returns {Promise<null>}
|
||||
* @memberof MySQLClient
|
||||
*/
|
||||
async dropEvent (params) {
|
||||
|
@ -1035,7 +1035,7 @@ export class MySQLClient extends AntaresCore {
|
|||
/**
|
||||
* ALTER EVENT
|
||||
*
|
||||
* @returns {Array.<Object>} parameters
|
||||
* @returns {Promise<null>}
|
||||
* @memberof MySQLClient
|
||||
*/
|
||||
async alterEvent (params) {
|
||||
|
@ -1061,7 +1061,7 @@ export class MySQLClient extends AntaresCore {
|
|||
/**
|
||||
* CREATE EVENT
|
||||
*
|
||||
* @returns {Array.<Object>} parameters
|
||||
* @returns {Promise<null>}
|
||||
* @memberof MySQLClient
|
||||
*/
|
||||
async createEvent (params) {
|
||||
|
@ -1205,7 +1205,7 @@ export class MySQLClient extends AntaresCore {
|
|||
/**
|
||||
* CREATE TABLE
|
||||
*
|
||||
* @returns {Array.<Object>} parameters
|
||||
* @returns {Promise<null>}
|
||||
* @memberof MySQLClient
|
||||
*/
|
||||
async createTable (params) {
|
||||
|
@ -1267,7 +1267,7 @@ export class MySQLClient extends AntaresCore {
|
|||
/**
|
||||
* ALTER TABLE
|
||||
*
|
||||
* @returns {Array.<Object>} parameters
|
||||
* @returns {Promise<null>}
|
||||
* @memberof MySQLClient
|
||||
*/
|
||||
async alterTable (params) {
|
||||
|
@ -1402,7 +1402,7 @@ export class MySQLClient extends AntaresCore {
|
|||
/**
|
||||
* DUPLICATE TABLE
|
||||
*
|
||||
* @returns {Array.<Object>} parameters
|
||||
* @returns {Promise<null>}
|
||||
* @memberof MySQLClient
|
||||
*/
|
||||
async duplicateTable (params) {
|
||||
|
@ -1413,7 +1413,7 @@ export class MySQLClient extends AntaresCore {
|
|||
/**
|
||||
* TRUNCATE TABLE
|
||||
*
|
||||
* @returns {Array.<Object>} parameters
|
||||
* @returns {Promise<null>}
|
||||
* @memberof MySQLClient
|
||||
*/
|
||||
async truncateTable (params) {
|
||||
|
@ -1424,7 +1424,7 @@ export class MySQLClient extends AntaresCore {
|
|||
/**
|
||||
* DROP TABLE
|
||||
*
|
||||
* @returns {Array.<Object>} parameters
|
||||
* @returns {Promise<null>}
|
||||
* @memberof MySQLClient
|
||||
*/
|
||||
async dropTable (params) {
|
||||
|
|
|
@ -506,7 +506,7 @@ export class PostgreSQLClient extends AntaresCore {
|
|||
/**
|
||||
* CREATE SCHEMA
|
||||
*
|
||||
* @returns {Array.<Object>} parameters
|
||||
* @returns {Promise<null>}
|
||||
* @memberof MySQLClient
|
||||
*/
|
||||
async createSchema (params) {
|
||||
|
@ -516,7 +516,7 @@ export class PostgreSQLClient extends AntaresCore {
|
|||
/**
|
||||
* ALTER DATABASE
|
||||
*
|
||||
* @returns {Array.<Object>} parameters
|
||||
* @returns {Promise<null>}
|
||||
* @memberof MySQLClient
|
||||
*/
|
||||
async alterSchema (params) {
|
||||
|
@ -526,7 +526,7 @@ export class PostgreSQLClient extends AntaresCore {
|
|||
/**
|
||||
* DROP DATABASE
|
||||
*
|
||||
* @returns {Array.<Object>} parameters
|
||||
* @returns {Promise<null>}
|
||||
* @memberof MySQLClient
|
||||
*/
|
||||
async dropSchema (params) {
|
||||
|
@ -558,7 +558,7 @@ export class PostgreSQLClient extends AntaresCore {
|
|||
/**
|
||||
* DROP VIEW
|
||||
*
|
||||
* @returns {Array.<Object>} parameters
|
||||
* @returns {Promise<null>}
|
||||
* @memberof PostgreSQLClient
|
||||
*/
|
||||
async dropView (params) {
|
||||
|
@ -569,7 +569,7 @@ export class PostgreSQLClient extends AntaresCore {
|
|||
/**
|
||||
* ALTER VIEW
|
||||
*
|
||||
* @returns {Array.<Object>} parameters
|
||||
* @returns {Promise<null>}
|
||||
* @memberof PostgreSQLClient
|
||||
*/
|
||||
async alterView (params) {
|
||||
|
@ -585,7 +585,7 @@ export class PostgreSQLClient extends AntaresCore {
|
|||
/**
|
||||
* CREATE VIEW
|
||||
*
|
||||
* @returns {Array.<Object>} parameters
|
||||
* @returns {Promise<null>}
|
||||
* @memberof PostgreSQLClient
|
||||
*/
|
||||
async createView (params) {
|
||||
|
@ -640,7 +640,7 @@ export class PostgreSQLClient extends AntaresCore {
|
|||
/**
|
||||
* DROP TRIGGER
|
||||
*
|
||||
* @returns {Array.<Object>} parameters
|
||||
* @returns {Promise<null>}
|
||||
* @memberof PostgreSQLClient
|
||||
*/
|
||||
async dropTrigger (params) {
|
||||
|
@ -652,7 +652,7 @@ export class PostgreSQLClient extends AntaresCore {
|
|||
/**
|
||||
* ALTER TRIGGER
|
||||
*
|
||||
* @returns {Array.<Object>} parameters
|
||||
* @returns {Promise<null>}
|
||||
* @memberof PostgreSQLClient
|
||||
*/
|
||||
async alterTrigger (params) {
|
||||
|
@ -674,7 +674,7 @@ export class PostgreSQLClient extends AntaresCore {
|
|||
/**
|
||||
* CREATE TRIGGER
|
||||
*
|
||||
* @returns {Array.<Object>} parameters
|
||||
* @returns {Promise<null>}
|
||||
* @memberof PostgreSQLClient
|
||||
*/
|
||||
async createTrigger (params) {
|
||||
|
@ -1086,7 +1086,7 @@ export class PostgreSQLClient extends AntaresCore {
|
|||
/**
|
||||
* CREATE TABLE
|
||||
*
|
||||
* @returns {Array.<Object>} parameters
|
||||
* @returns {Promise<null>}
|
||||
* @memberof PostgreSQLClient
|
||||
*/
|
||||
async createTable (params) {
|
||||
|
@ -1144,7 +1144,7 @@ export class PostgreSQLClient extends AntaresCore {
|
|||
/**
|
||||
* ALTER TABLE
|
||||
*
|
||||
* @returns {Array.<Object>} parameters
|
||||
* @returns {Promise<null>}
|
||||
* @memberof PostgreSQLClient
|
||||
*/
|
||||
async alterTable (params) {
|
||||
|
@ -1290,7 +1290,7 @@ export class PostgreSQLClient extends AntaresCore {
|
|||
/**
|
||||
* DUPLICATE TABLE
|
||||
*
|
||||
* @returns {Array.<Object>} parameters
|
||||
* @returns {Promise<null>}
|
||||
* @memberof PostgreSQLClient
|
||||
*/
|
||||
async duplicateTable (params) {
|
||||
|
@ -1301,7 +1301,7 @@ export class PostgreSQLClient extends AntaresCore {
|
|||
/**
|
||||
* TRUNCATE TABLE
|
||||
*
|
||||
* @returns {Array.<Object>} parameters
|
||||
* @returns {Promise<null>}
|
||||
* @memberof PostgreSQLClient
|
||||
*/
|
||||
async truncateTable (params) {
|
||||
|
@ -1312,7 +1312,7 @@ export class PostgreSQLClient extends AntaresCore {
|
|||
/**
|
||||
* DROP TABLE
|
||||
*
|
||||
* @returns {Array.<Object>} parameters
|
||||
* @returns {Promise<null>}
|
||||
* @memberof PostgreSQLClient
|
||||
*/
|
||||
async dropTable (params) {
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
import sqlite from 'better-sqlite3';
|
||||
import { AntaresCore } from '../AntaresCore';
|
||||
import dataTypes from 'common/data-types/mysql';
|
||||
import { NUMBER, FLOAT } from 'common/fieldTypes';
|
||||
|
||||
export class SQLiteClient extends AntaresCore {
|
||||
constructor (args) {
|
||||
|
@ -136,95 +137,35 @@ export class SQLiteClient extends AntaresCore {
|
|||
* @memberof SQLiteClient
|
||||
*/
|
||||
async getTableColumns ({ schema, table }) {
|
||||
const { rows } = await this
|
||||
.select('*')
|
||||
.schema('information_schema')
|
||||
.from('COLUMNS')
|
||||
.where({ TABLE_SCHEMA: `= '${schema}'`, TABLE_NAME: `= '${table}'` })
|
||||
.orderBy({ ORDINAL_POSITION: 'ASC' })
|
||||
.run();
|
||||
const { rows: fields } = await this.raw(`SELECT * FROM "${schema}".pragma_table_info('${table}')`);
|
||||
|
||||
const { rows: fields } = await this.raw(`SHOW CREATE TABLE \`${schema}\`.\`${table}\``);
|
||||
|
||||
const remappedFields = fields.map(row => {
|
||||
if (!row['Create Table']) return false;
|
||||
|
||||
let n = 0;
|
||||
return row['Create Table']
|
||||
.split('')
|
||||
.reduce((acc, curr) => {
|
||||
if (curr === ')') n--;
|
||||
if (n !== 0) acc += curr;
|
||||
if (curr === '(') n++;
|
||||
return acc;
|
||||
}, '')
|
||||
.replaceAll('\n', '')
|
||||
.split(',')
|
||||
.map(f => {
|
||||
try {
|
||||
const fieldArr = f.trim().split(' ');
|
||||
const nameAndType = fieldArr.slice(0, 2);
|
||||
if (nameAndType[0].charAt(0) !== '`') return false;
|
||||
|
||||
const details = fieldArr.slice(2).join(' ');
|
||||
let defaultValue = null;
|
||||
if (details.includes('DEFAULT'))
|
||||
defaultValue = details.match(/(?<=DEFAULT ).*?$/gs)[0].split(' COMMENT')[0];
|
||||
// const defaultValueArr = defaultValue.split('');
|
||||
// if (defaultValueArr[0] === '\'') {
|
||||
// defaultValueArr.shift();
|
||||
// defaultValueArr.pop();
|
||||
// defaultValue = defaultValueArr.join('');
|
||||
// }
|
||||
|
||||
const typeAndLength = nameAndType[1].replace(')', '').split('(');
|
||||
|
||||
return {
|
||||
name: nameAndType[0].replaceAll('`', ''),
|
||||
type: typeAndLength[0].toUpperCase(),
|
||||
length: typeAndLength[1] ? typeAndLength[1] : null,
|
||||
default: defaultValue
|
||||
};
|
||||
}
|
||||
catch (err) {
|
||||
return false;
|
||||
}
|
||||
return fields.map(field => {
|
||||
const [type, length] = field.type.includes('(')
|
||||
? field.type.replace(')', '').split('(').map(el => {
|
||||
if (!isNaN(el)) el = +el;
|
||||
return el;
|
||||
})
|
||||
.filter(Boolean)
|
||||
.reduce((acc, curr) => {
|
||||
acc[curr.name] = curr;
|
||||
return acc;
|
||||
}, {});
|
||||
})[0];
|
||||
|
||||
return rows.map(field => {
|
||||
let numLength = field.COLUMN_TYPE.match(/int\(([^)]+)\)/);
|
||||
numLength = numLength ? +numLength.pop() : null;
|
||||
const enumValues = /(enum|set)/.test(field.COLUMN_TYPE)
|
||||
? field.COLUMN_TYPE.match(/\(([^)]+)\)/)[0].slice(1, -1)
|
||||
: null;
|
||||
: [field.type, null];
|
||||
|
||||
return {
|
||||
name: field.COLUMN_NAME,
|
||||
key: field.COLUMN_KEY.toLowerCase(),
|
||||
type: remappedFields ? remappedFields[field.COLUMN_NAME].type : field.DATA_TYPE,
|
||||
schema: field.TABLE_SCHEMA,
|
||||
table: field.TABLE_NAME,
|
||||
numPrecision: field.NUMERIC_PRECISION,
|
||||
numLength,
|
||||
enumValues,
|
||||
datePrecision: field.DATETIME_PRECISION,
|
||||
charLength: field.CHARACTER_MAXIMUM_LENGTH,
|
||||
nullable: field.IS_NULLABLE.includes('YES'),
|
||||
unsigned: field.COLUMN_TYPE.includes('unsigned'),
|
||||
zerofill: field.COLUMN_TYPE.includes('zerofill'),
|
||||
order: field.ORDINAL_POSITION,
|
||||
default: remappedFields ? remappedFields[field.COLUMN_NAME].default : field.COLUMN_DEFAULT,
|
||||
charset: field.CHARACTER_SET_NAME,
|
||||
collation: field.COLLATION_NAME,
|
||||
autoIncrement: field.EXTRA.includes('auto_increment'),
|
||||
onUpdate: field.EXTRA.toLowerCase().includes('on update') ? field.EXTRA.replace('on update', '') : '',
|
||||
comment: field.COLUMN_COMMENT
|
||||
name: field.name,
|
||||
key: null,
|
||||
type,
|
||||
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: ''
|
||||
};
|
||||
});
|
||||
}
|
||||
|
@ -250,33 +191,7 @@ export class SQLiteClient extends AntaresCore {
|
|||
* @memberof SQLiteClient
|
||||
*/
|
||||
async getTableOptions ({ schema, table }) {
|
||||
const { rows } = await this.raw(`SHOW TABLE STATUS FROM \`${schema}\` WHERE Name = '${table}'`);
|
||||
|
||||
if (rows.length) {
|
||||
let tableType;
|
||||
switch (rows[0].Comment) {
|
||||
case 'VIEW':
|
||||
tableType = 'view';
|
||||
break;
|
||||
default:
|
||||
tableType = 'table';
|
||||
break;
|
||||
}
|
||||
|
||||
return {
|
||||
name: rows[0].Name,
|
||||
type: tableType,
|
||||
rows: rows[0].Rows,
|
||||
created: rows[0].Create_time,
|
||||
updated: rows[0].Update_time,
|
||||
engine: rows[0].Engine,
|
||||
comment: rows[0].Comment,
|
||||
size: rows[0].Data_length + rows[0].Index_length,
|
||||
autoIncrement: rows[0].Auto_increment,
|
||||
collation: rows[0].Collation
|
||||
};
|
||||
};
|
||||
return {};
|
||||
return { name: table };
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -331,78 +246,27 @@ export class SQLiteClient extends AntaresCore {
|
|||
* @memberof SQLiteClient
|
||||
*/
|
||||
async getKeyUsage ({ schema, table }) {
|
||||
const { rows } = await this
|
||||
.select('*')
|
||||
.schema('information_schema')
|
||||
.from('KEY_COLUMN_USAGE')
|
||||
.where({ TABLE_SCHEMA: `= '${schema}'`, TABLE_NAME: `= '${table}'`, REFERENCED_TABLE_NAME: 'IS NOT NULL' })
|
||||
.run();
|
||||
|
||||
const { rows: extras } = await this
|
||||
.select('*')
|
||||
.schema('information_schema')
|
||||
.from('REFERENTIAL_CONSTRAINTS')
|
||||
.where({ CONSTRAINT_SCHEMA: `= '${schema}'`, TABLE_NAME: `= '${table}'`, REFERENCED_TABLE_NAME: 'IS NOT NULL' })
|
||||
.run();
|
||||
const { rows } = await this.raw(`SELECT * FROM "${schema}".pragma_foreign_key_list('${table}');`);
|
||||
|
||||
return rows.map(field => {
|
||||
const extra = extras.find(x => x.CONSTRAINT_NAME === field.CONSTRAINT_NAME);
|
||||
return {
|
||||
schema: field.TABLE_SCHEMA,
|
||||
table: field.TABLE_NAME,
|
||||
field: field.COLUMN_NAME,
|
||||
position: field.ORDINAL_POSITION,
|
||||
constraintPosition: field.POSITION_IN_UNIQUE_CONSTRAINT,
|
||||
constraintName: field.CONSTRAINT_NAME,
|
||||
refSchema: field.REFERENCED_TABLE_SCHEMA,
|
||||
refTable: field.REFERENCED_TABLE_NAME,
|
||||
refField: field.REFERENCED_COLUMN_NAME,
|
||||
onUpdate: extra.UPDATE_RULE,
|
||||
onDelete: extra.DELETE_RULE
|
||||
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 () {}
|
||||
|
||||
/**
|
||||
* CREATE DATABASE
|
||||
*
|
||||
* @returns {Array.<Object>} parameters
|
||||
* @memberof SQLiteClient
|
||||
*/
|
||||
async createSchema (params) {
|
||||
return await this.raw(`CREATE DATABASE \`${params.name}\` COLLATE ${params.collation}`);
|
||||
}
|
||||
|
||||
/**
|
||||
* ALTER DATABASE
|
||||
*
|
||||
* @returns {Array.<Object>} parameters
|
||||
* @memberof SQLiteClient
|
||||
*/
|
||||
async alterSchema (params) {
|
||||
return await this.raw(`ALTER DATABASE \`${params.name}\` COLLATE ${params.collation}`);
|
||||
}
|
||||
|
||||
/**
|
||||
* DROP DATABASE
|
||||
*
|
||||
* @returns {Array.<Object>} parameters
|
||||
* @memberof SQLiteClient
|
||||
*/
|
||||
async dropSchema (params) {
|
||||
return await this.raw(`DROP DATABASE \`${params.database}\``);
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {Array.<Object>} parameters
|
||||
* @memberof SQLiteClient
|
||||
*/
|
||||
async getDatabaseCollation (params) {
|
||||
return await this.raw(`SELECT \`DEFAULT_COLLATION_NAME\` FROM \`information_schema\`.\`SCHEMATA\` WHERE \`SCHEMA_NAME\`='${params.database}'`);
|
||||
}
|
||||
|
||||
/**
|
||||
* SHOW CREATE VIEW
|
||||
*
|
||||
|
@ -534,357 +398,6 @@ export class SQLiteClient extends AntaresCore {
|
|||
return await this.raw(sql, { split: false });
|
||||
}
|
||||
|
||||
/**
|
||||
* SHOW CREATE PROCEDURE
|
||||
*
|
||||
* @returns {Array.<Object>} view informations
|
||||
* @memberof SQLiteClient
|
||||
*/
|
||||
async getRoutineInformations ({ schema, routine }) {
|
||||
const sql = `SHOW CREATE PROCEDURE \`${schema}\`.\`${routine}\``;
|
||||
const results = await this.raw(sql);
|
||||
|
||||
return results.rows.map(async row => {
|
||||
if (!row['Create Procedure']) {
|
||||
return {
|
||||
definer: null,
|
||||
sql: '',
|
||||
parameters: [],
|
||||
name: row.Procedure,
|
||||
comment: '',
|
||||
security: 'DEFINER',
|
||||
deterministic: false,
|
||||
dataAccess: 'CONTAINS SQL'
|
||||
};
|
||||
}
|
||||
|
||||
const sql = `SELECT *
|
||||
FROM information_schema.parameters
|
||||
WHERE SPECIFIC_NAME = '${routine}'
|
||||
AND SPECIFIC_SCHEMA = '${schema}'
|
||||
ORDER BY ORDINAL_POSITION
|
||||
`;
|
||||
|
||||
const results = await this.raw(sql);
|
||||
|
||||
const parameters = results.rows.map(row => {
|
||||
return {
|
||||
name: row.PARAMETER_NAME,
|
||||
type: row.DATA_TYPE.toUpperCase(),
|
||||
length: row.NUMERIC_PRECISION || row.DATETIME_PRECISION || row.CHARACTER_MAXIMUM_LENGTH || '',
|
||||
context: row.PARAMETER_MODE
|
||||
};
|
||||
});
|
||||
|
||||
let dataAccess = 'CONTAINS SQL';
|
||||
if (row['Create Procedure'].includes('NO SQL'))
|
||||
dataAccess = 'NO SQL';
|
||||
if (row['Create Procedure'].includes('READS SQL DATA'))
|
||||
dataAccess = 'READS SQL DATA';
|
||||
if (row['Create Procedure'].includes('MODIFIES SQL DATA'))
|
||||
dataAccess = 'MODIFIES SQL DATA';
|
||||
|
||||
return {
|
||||
definer: row['Create Procedure'].match(/(?<=DEFINER=).*?(?=\s)/gs)[0],
|
||||
sql: row['Create Procedure'].match(/(BEGIN|begin)(.*)(END|end)/gs)[0],
|
||||
parameters: parameters || [],
|
||||
name: row.Procedure,
|
||||
comment: row['Create Procedure'].match(/(?<=COMMENT ').*?(?=')/gs) ? row['Create Procedure'].match(/(?<=COMMENT ').*?(?=')/gs)[0] : '',
|
||||
security: row['Create Procedure'].includes('SQL SECURITY INVOKER') ? 'INVOKER' : 'DEFINER',
|
||||
deterministic: row['Create Procedure'].includes('DETERMINISTIC'),
|
||||
dataAccess
|
||||
};
|
||||
})[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* DROP PROCEDURE
|
||||
*
|
||||
* @returns {Array.<Object>} parameters
|
||||
* @memberof SQLiteClient
|
||||
*/
|
||||
async dropRoutine (params) {
|
||||
const sql = `DROP PROCEDURE \`${params.schema}\`.\`${params.routine}\``;
|
||||
return await this.raw(sql);
|
||||
}
|
||||
|
||||
/**
|
||||
* ALTER PROCEDURE
|
||||
*
|
||||
* @returns {Array.<Object>} parameters
|
||||
* @memberof SQLiteClient
|
||||
*/
|
||||
async alterRoutine (params) {
|
||||
const { routine } = params;
|
||||
const tempProcedure = Object.assign({}, routine);
|
||||
tempProcedure.name = `Antares_${tempProcedure.name}_tmp`;
|
||||
|
||||
try {
|
||||
await this.createRoutine(tempProcedure);
|
||||
await this.dropRoutine({ schema: routine.schema, routine: tempProcedure.name });
|
||||
await this.dropRoutine({ schema: routine.schema, routine: routine.oldName });
|
||||
await this.createRoutine(routine);
|
||||
}
|
||||
catch (err) {
|
||||
return Promise.reject(err);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* CREATE PROCEDURE
|
||||
*
|
||||
* @returns {Array.<Object>} parameters
|
||||
* @memberof SQLiteClient
|
||||
*/
|
||||
async createRoutine (params) {
|
||||
const parameters = 'parameters' in params
|
||||
? params.parameters.reduce((acc, curr) => {
|
||||
acc.push(`${curr.context} \`${curr.name}\` ${curr.type}${curr.length ? `(${curr.length})` : ''}`);
|
||||
return acc;
|
||||
}, []).join(',')
|
||||
: '';
|
||||
|
||||
const sql = `CREATE ${params.definer ? `DEFINER=${params.definer} ` : ''}PROCEDURE \`${params.schema}\`.\`${params.name}\`(${parameters})
|
||||
LANGUAGE SQL
|
||||
${params.deterministic ? 'DETERMINISTIC' : 'NOT DETERMINISTIC'}
|
||||
${params.dataAccess}
|
||||
SQL SECURITY ${params.security}
|
||||
COMMENT '${params.comment}'
|
||||
${params.sql}`;
|
||||
|
||||
return await this.raw(sql, { split: false });
|
||||
}
|
||||
|
||||
/**
|
||||
* SHOW CREATE FUNCTION
|
||||
*
|
||||
* @returns {Array.<Object>} view informations
|
||||
* @memberof SQLiteClient
|
||||
*/
|
||||
async getFunctionInformations ({ schema, func }) {
|
||||
const sql = `SHOW CREATE FUNCTION \`${schema}\`.\`${func}\``;
|
||||
const results = await this.raw(sql);
|
||||
|
||||
return results.rows.map(async row => {
|
||||
if (!row['Create Function']) {
|
||||
return {
|
||||
definer: null,
|
||||
sql: '',
|
||||
parameters: [],
|
||||
name: row.Procedure,
|
||||
comment: '',
|
||||
security: 'DEFINER',
|
||||
deterministic: false,
|
||||
dataAccess: 'CONTAINS SQL',
|
||||
returns: 'INT',
|
||||
returnsLength: null
|
||||
};
|
||||
}
|
||||
|
||||
const sql = `SELECT *
|
||||
FROM information_schema.parameters
|
||||
WHERE SPECIFIC_NAME = '${func}'
|
||||
AND SPECIFIC_SCHEMA = '${schema}'
|
||||
ORDER BY ORDINAL_POSITION
|
||||
`;
|
||||
|
||||
const results = await this.raw(sql);
|
||||
|
||||
const parameters = results.rows.filter(row => row.PARAMETER_MODE).map(row => {
|
||||
return {
|
||||
name: row.PARAMETER_NAME,
|
||||
type: row.DATA_TYPE.toUpperCase(),
|
||||
length: row.NUMERIC_PRECISION || row.DATETIME_PRECISION || row.CHARACTER_MAXIMUM_LENGTH || '',
|
||||
context: row.PARAMETER_MODE
|
||||
};
|
||||
});
|
||||
|
||||
let dataAccess = 'CONTAINS SQL';
|
||||
if (row['Create Function'].includes('NO SQL'))
|
||||
dataAccess = 'NO SQL';
|
||||
if (row['Create Function'].includes('READS SQL DATA'))
|
||||
dataAccess = 'READS SQL DATA';
|
||||
if (row['Create Function'].includes('MODIFIES SQL DATA'))
|
||||
dataAccess = 'MODIFIES SQL DATA';
|
||||
|
||||
const output = row['Create Function'].match(/(?<=RETURNS ).*?(?=\s)/gs).length ? row['Create Function'].match(/(?<=RETURNS ).*?(?=\s)/gs)[0].replace(')', '').split('(') : ['', null];
|
||||
|
||||
return {
|
||||
definer: row['Create Function'].match(/(?<=DEFINER=).*?(?=\s)/gs)[0],
|
||||
sql: row['Create Function'].match(/(BEGIN|begin)(.*)(END|end)/gs)[0],
|
||||
parameters: parameters || [],
|
||||
name: row.Function,
|
||||
comment: row['Create Function'].match(/(?<=COMMENT ').*?(?=')/gs) ? row['Create Function'].match(/(?<=COMMENT ').*?(?=')/gs)[0] : '',
|
||||
security: row['Create Function'].includes('SQL SECURITY INVOKER') ? 'INVOKER' : 'DEFINER',
|
||||
deterministic: row['Create Function'].includes('DETERMINISTIC'),
|
||||
dataAccess,
|
||||
returns: output[0].toUpperCase(),
|
||||
returnsLength: +output[1]
|
||||
};
|
||||
})[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* DROP FUNCTION
|
||||
*
|
||||
* @returns {Array.<Object>} parameters
|
||||
* @memberof SQLiteClient
|
||||
*/
|
||||
async dropFunction (params) {
|
||||
const sql = `DROP FUNCTION \`${params.schema}\`.\`${params.func}\``;
|
||||
return await this.raw(sql);
|
||||
}
|
||||
|
||||
/**
|
||||
* ALTER FUNCTION
|
||||
*
|
||||
* @returns {Array.<Object>} parameters
|
||||
* @memberof SQLiteClient
|
||||
*/
|
||||
async alterFunction (params) {
|
||||
const { func } = params;
|
||||
const tempProcedure = Object.assign({}, func);
|
||||
tempProcedure.name = `Antares_${tempProcedure.name}_tmp`;
|
||||
|
||||
try {
|
||||
await this.createFunction(tempProcedure);
|
||||
await this.dropFunction({ schema: func.schema, func: tempProcedure.name });
|
||||
await this.dropFunction({ schema: func.schema, func: func.oldName });
|
||||
await this.createFunction(func);
|
||||
}
|
||||
catch (err) {
|
||||
return Promise.reject(err);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* CREATE FUNCTION
|
||||
*
|
||||
* @returns {Array.<Object>} parameters
|
||||
* @memberof SQLiteClient
|
||||
*/
|
||||
async createFunction (params) {
|
||||
const parameters = 'parameters' in params
|
||||
? params.parameters.reduce((acc, curr) => {
|
||||
acc.push(`\`${curr.name}\` ${curr.type}${curr.length ? `(${curr.length})` : ''}`);
|
||||
return acc;
|
||||
}, []).join(',')
|
||||
: '';
|
||||
|
||||
const body = params.returns ? params.sql : 'BEGIN\n RETURN 0;\nEND';
|
||||
|
||||
const sql = `CREATE ${params.definer ? `DEFINER=${params.definer} ` : ''}FUNCTION \`${params.schema}\`.\`${params.name}\`(${parameters}) RETURNS ${params.returns || 'SMALLINT'}${params.returnsLength ? `(${params.returnsLength})` : ''}
|
||||
LANGUAGE SQL
|
||||
${params.deterministic ? 'DETERMINISTIC' : 'NOT DETERMINISTIC'}
|
||||
${params.dataAccess}
|
||||
SQL SECURITY ${params.security}
|
||||
COMMENT '${params.comment}'
|
||||
${body}`;
|
||||
|
||||
return await this.raw(sql, { split: false });
|
||||
}
|
||||
|
||||
/**
|
||||
* SHOW CREATE EVENT
|
||||
*
|
||||
* @returns {Array.<Object>} view informations
|
||||
* @memberof SQLiteClient
|
||||
*/
|
||||
async getEventInformations ({ schema, scheduler }) {
|
||||
const sql = `SHOW CREATE EVENT \`${schema}\`.\`${scheduler}\``;
|
||||
const results = await this.raw(sql);
|
||||
|
||||
return results.rows.map(row => {
|
||||
const schedule = row['Create Event'];
|
||||
const execution = schedule.includes('EVERY') ? 'EVERY' : 'ONCE';
|
||||
const every = execution === 'EVERY' ? row['Create Event'].match(/(?<=EVERY )(\s*([^\s]+)){0,2}/gs)[0].replaceAll('\'', '').split(' ') : [];
|
||||
const starts = execution === 'EVERY' && schedule.includes('STARTS') ? schedule.match(/(?<=STARTS ').*?(?='\s)/gs)[0] : '';
|
||||
const ends = execution === 'EVERY' && schedule.includes('ENDS') ? schedule.match(/(?<=ENDS ').*?(?='\s)/gs)[0] : '';
|
||||
const at = execution === 'ONCE' && schedule.includes('AT') ? schedule.match(/(?<=AT ').*?(?='\s)/gs)[0] : '';
|
||||
|
||||
return {
|
||||
definer: row['Create Event'].match(/(?<=DEFINER=).*?(?=\s)/gs)[0],
|
||||
sql: row['Create Event'].match(/(?<=DO )(.*)/gs)[0],
|
||||
name: row.Event,
|
||||
comment: row['Create Event'].match(/(?<=COMMENT ').*?(?=')/gs) ? row['Create Event'].match(/(?<=COMMENT ').*?(?=')/gs)[0] : '',
|
||||
state: row['Create Event'].includes('ENABLE') ? 'ENABLE' : row['Create Event'].includes('DISABLE ON SLAVE') ? 'DISABLE ON SLAVE' : 'DISABLE',
|
||||
preserve: row['Create Event'].includes('ON COMPLETION PRESERVE'),
|
||||
execution,
|
||||
every,
|
||||
starts,
|
||||
ends,
|
||||
at
|
||||
};
|
||||
})[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* DROP EVENT
|
||||
*
|
||||
* @returns {Array.<Object>} parameters
|
||||
* @memberof SQLiteClient
|
||||
*/
|
||||
async dropEvent (params) {
|
||||
const sql = `DROP EVENT \`${params.schema}\`.\`${params.scheduler}\``;
|
||||
return await this.raw(sql);
|
||||
}
|
||||
|
||||
/**
|
||||
* ALTER EVENT
|
||||
*
|
||||
* @returns {Array.<Object>} parameters
|
||||
* @memberof SQLiteClient
|
||||
*/
|
||||
async alterEvent (params) {
|
||||
const { scheduler } = params;
|
||||
|
||||
if (scheduler.execution === 'EVERY' && scheduler.every[0].includes('-'))
|
||||
scheduler.every[0] = `'${scheduler.every[0]}'`;
|
||||
|
||||
const sql = `ALTER ${scheduler.definer ? ` DEFINER=${scheduler.definer}` : ''} EVENT \`${scheduler.schema}\`.\`${scheduler.oldName}\`
|
||||
ON SCHEDULE
|
||||
${scheduler.execution === 'EVERY'
|
||||
? `EVERY ${scheduler.every.join(' ')}${scheduler.starts ? ` STARTS '${scheduler.starts}'` : ''}${scheduler.ends ? ` ENDS '${scheduler.ends}'` : ''}`
|
||||
: `AT '${scheduler.at}'`}
|
||||
ON COMPLETION${!scheduler.preserve ? ' NOT' : ''} PRESERVE
|
||||
${scheduler.name !== scheduler.oldName ? `RENAME TO \`${scheduler.schema}\`.\`${scheduler.name}\`` : ''}
|
||||
${scheduler.state}
|
||||
COMMENT '${scheduler.comment}'
|
||||
DO ${scheduler.sql}`;
|
||||
|
||||
return await this.raw(sql, { split: false });
|
||||
}
|
||||
|
||||
/**
|
||||
* CREATE EVENT
|
||||
*
|
||||
* @returns {Array.<Object>} parameters
|
||||
* @memberof SQLiteClient
|
||||
*/
|
||||
async createEvent (params) {
|
||||
const sql = `CREATE ${params.definer ? ` DEFINER=${params.definer}` : ''} EVENT \`${params.schema}\`.\`${params.name}\`
|
||||
ON SCHEDULE
|
||||
${params.execution === 'EVERY'
|
||||
? `EVERY ${params.every.join(' ')}${params.starts ? ` STARTS '${params.starts}'` : ''}${params.ends ? ` ENDS '${params.ends}'` : ''}`
|
||||
: `AT '${params.at}'`}
|
||||
ON COMPLETION${!params.preserve ? ' NOT' : ''} PRESERVE
|
||||
${params.state}
|
||||
COMMENT '${params.comment}'
|
||||
DO ${params.sql}`;
|
||||
|
||||
return await this.raw(sql, { split: false });
|
||||
}
|
||||
|
||||
async enableEvent ({ schema, scheduler }) {
|
||||
const sql = `ALTER EVENT \`${schema}\`.\`${scheduler}\` ENABLE`;
|
||||
return await this.raw(sql, { split: false });
|
||||
}
|
||||
|
||||
async disableEvent ({ schema, scheduler }) {
|
||||
const sql = `ALTER EVENT \`${schema}\`.\`${scheduler}\` DISABLE`;
|
||||
return await this.raw(sql, { split: false });
|
||||
}
|
||||
|
||||
/**
|
||||
* SHOW COLLATION
|
||||
*
|
||||
|
@ -946,7 +459,7 @@ export class SQLiteClient extends AntaresCore {
|
|||
/**
|
||||
* CREATE TABLE
|
||||
*
|
||||
* @returns {Array.<Object>} parameters
|
||||
* @returns {Promise<null>}
|
||||
* @memberof SQLiteClient
|
||||
*/
|
||||
async createTable (params) {
|
||||
|
@ -959,48 +472,43 @@ export class SQLiteClient extends AntaresCore {
|
|||
} = params;
|
||||
const newColumns = [];
|
||||
const newIndexes = [];
|
||||
const manageIndexes = [];
|
||||
const newForeigns = [];
|
||||
|
||||
let sql = `CREATE TABLE \`${schema}\`.\`${options.name}\``;
|
||||
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;
|
||||
const length = typeInfo?.length ? field.enumValues || field.numLength || field.charLength || field.datePrecision : false;
|
||||
|
||||
newColumns.push(`\`${field.name}\`
|
||||
${field.type.toUpperCase()}${length ? `(${length})` : ''}
|
||||
newColumns.push(`"${field.name}"
|
||||
${field.type.toUpperCase()}${length && length !== true ? `(${length})` : ''}
|
||||
${field.unsigned ? 'UNSIGNED' : ''}
|
||||
${field.zerofill ? 'ZEROFILL' : ''}
|
||||
${field.nullable ? 'NULL' : 'NOT NULL'}
|
||||
${field.autoIncrement ? 'AUTO_INCREMENT' : ''}
|
||||
${field.default ? `DEFAULT ${field.default}` : ''}
|
||||
${field.comment ? `COMMENT '${field.comment}'` : ''}
|
||||
${field.collation ? `COLLATE ${field.collation}` : ''}
|
||||
${field.onUpdate ? `ON UPDATE ${field.onUpdate}` : ''}`);
|
||||
});
|
||||
|
||||
// ADD INDEX
|
||||
indexes.forEach(index => {
|
||||
const fields = index.fields.map(field => `\`${field}\``).join(',');
|
||||
let type = index.type;
|
||||
const fields = index.fields.map(field => `"${field}"`).join(',');
|
||||
const type = index.type;
|
||||
|
||||
if (type === 'PRIMARY')
|
||||
newIndexes.push(`PRIMARY KEY (${fields})`);
|
||||
else {
|
||||
if (type === 'UNIQUE')
|
||||
type = 'UNIQUE INDEX';
|
||||
|
||||
newIndexes.push(`${type} \`${index.name}\` (${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}`);
|
||||
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(', ')}) COMMENT='${options.comment}', COLLATE='${options.collation}', ENGINE=${options.engine}`;
|
||||
sql = `${sql} (${[...newColumns, ...newIndexes, ...newForeigns].join(', ')})`;
|
||||
if (manageIndexes.length) sql = `${sql}; ${manageIndexes.join(';')}`;
|
||||
|
||||
return await this.raw(sql);
|
||||
}
|
||||
|
@ -1008,168 +516,87 @@ export class SQLiteClient extends AntaresCore {
|
|||
/**
|
||||
* ALTER TABLE
|
||||
*
|
||||
* @returns {Array.<Object>} parameters
|
||||
* @returns {Promise<null>}
|
||||
* @memberof SQLiteClient
|
||||
*/
|
||||
async alterTable (params) {
|
||||
const {
|
||||
table,
|
||||
schema,
|
||||
additions,
|
||||
deletions,
|
||||
changes,
|
||||
indexChanges,
|
||||
foreignChanges,
|
||||
options
|
||||
} = params;
|
||||
try {
|
||||
await this.raw('BEGIN TRANSACTION');
|
||||
await this.raw('PRAGMA foreign_keys = 0');
|
||||
|
||||
let sql = `ALTER TABLE \`${schema}\`.\`${table}\` `;
|
||||
const alterColumns = [];
|
||||
const tmpName = `Antares_${params.table}_tmp`;
|
||||
await this.raw(`CREATE TABLE "${tmpName}" AS SELECT * FROM "${params.table}"`);
|
||||
await this.dropTable(params);
|
||||
|
||||
// OPTIONS
|
||||
if ('comment' in options) alterColumns.push(`COMMENT='${options.comment}'`);
|
||||
if ('engine' in options) alterColumns.push(`ENGINE=${options.engine}`);
|
||||
if ('autoIncrement' in options) alterColumns.push(`AUTO_INCREMENT=${+options.autoIncrement}`);
|
||||
if ('collation' in options) alterColumns.push(`COLLATE='${options.collation}'`);
|
||||
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;
|
||||
}, []);
|
||||
|
||||
// ADD FIELDS
|
||||
additions.forEach(addition => {
|
||||
const typeInfo = this._getTypeInfo(addition.type);
|
||||
const length = typeInfo.length ? addition.enumValues || addition.numLength || addition.charLength || addition.datePrecision : false;
|
||||
const selectFields = insertFields.map(field => {
|
||||
const renamedField = params.changes.find(change => `"${change.name}"` === field);
|
||||
if (renamedField)
|
||||
return `"${renamedField.orgName}"`;
|
||||
return field;
|
||||
});
|
||||
|
||||
alterColumns.push(`ADD COLUMN \`${addition.name}\`
|
||||
${addition.type.toUpperCase()}${length ? `(${length})` : ''}
|
||||
${addition.unsigned ? 'UNSIGNED' : ''}
|
||||
${addition.zerofill ? 'ZEROFILL' : ''}
|
||||
${addition.nullable ? 'NULL' : 'NOT NULL'}
|
||||
${addition.autoIncrement ? 'AUTO_INCREMENT' : ''}
|
||||
${addition.default ? `DEFAULT ${addition.default}` : ''}
|
||||
${addition.comment ? `COMMENT '${addition.comment}'` : ''}
|
||||
${addition.collation ? `COLLATE ${addition.collation}` : ''}
|
||||
${addition.onUpdate ? `ON UPDATE ${addition.onUpdate}` : ''}
|
||||
${addition.after ? `AFTER \`${addition.after}\`` : 'FIRST'}`);
|
||||
});
|
||||
await this.raw(`INSERT INTO "${createTableParams.options.name}" (${insertFields.join(',')}) SELECT ${selectFields.join(',')} FROM "${tmpName}"`);
|
||||
|
||||
// ADD INDEX
|
||||
indexChanges.additions.forEach(addition => {
|
||||
const fields = addition.fields.map(field => `\`${field}\``).join(',');
|
||||
let type = addition.type;
|
||||
|
||||
if (type === 'PRIMARY')
|
||||
alterColumns.push(`ADD PRIMARY KEY (${fields})`);
|
||||
else {
|
||||
if (type === 'UNIQUE')
|
||||
type = 'UNIQUE INDEX';
|
||||
|
||||
alterColumns.push(`ADD ${type} \`${addition.name}\` (${fields})`);
|
||||
}
|
||||
});
|
||||
|
||||
// ADD FOREIGN KEYS
|
||||
foreignChanges.additions.forEach(addition => {
|
||||
alterColumns.push(`ADD CONSTRAINT \`${addition.constraintName}\` FOREIGN KEY (\`${addition.field}\`) REFERENCES \`${addition.refTable}\` (\`${addition.refField}\`) ON UPDATE ${addition.onUpdate} ON DELETE ${addition.onDelete}`);
|
||||
});
|
||||
|
||||
// CHANGE FIELDS
|
||||
changes.forEach(change => {
|
||||
const typeInfo = this._getTypeInfo(change.type);
|
||||
const length = typeInfo.length ? change.enumValues || change.numLength || change.charLength || change.datePrecision : false;
|
||||
|
||||
alterColumns.push(`CHANGE COLUMN \`${change.orgName}\` \`${change.name}\`
|
||||
${change.type.toUpperCase()}${length ? `(${length})` : ''}
|
||||
${change.unsigned ? 'UNSIGNED' : ''}
|
||||
${change.zerofill ? 'ZEROFILL' : ''}
|
||||
${change.nullable ? 'NULL' : 'NOT NULL'}
|
||||
${change.autoIncrement ? 'AUTO_INCREMENT' : ''}
|
||||
${change.default ? `DEFAULT ${change.default}` : ''}
|
||||
${change.comment ? `COMMENT '${change.comment}'` : ''}
|
||||
${change.collation ? `COLLATE ${change.collation}` : ''}
|
||||
${change.onUpdate ? `ON UPDATE ${change.onUpdate}` : ''}
|
||||
${change.after ? `AFTER \`${change.after}\`` : 'FIRST'}`);
|
||||
});
|
||||
|
||||
// CHANGE INDEX
|
||||
indexChanges.changes.forEach(change => {
|
||||
if (change.oldType === 'PRIMARY')
|
||||
alterColumns.push('DROP PRIMARY KEY');
|
||||
else
|
||||
alterColumns.push(`DROP INDEX \`${change.oldName}\``);
|
||||
|
||||
const fields = change.fields.map(field => `\`${field}\``).join(',');
|
||||
let type = change.type;
|
||||
|
||||
if (type === 'PRIMARY')
|
||||
alterColumns.push(`ADD PRIMARY KEY (${fields})`);
|
||||
else {
|
||||
if (type === 'UNIQUE')
|
||||
type = 'UNIQUE INDEX';
|
||||
|
||||
alterColumns.push(`ADD ${type} \`${change.name}\` (${fields})`);
|
||||
}
|
||||
});
|
||||
|
||||
// CHANGE FOREIGN KEYS
|
||||
foreignChanges.changes.forEach(change => {
|
||||
alterColumns.push(`DROP FOREIGN KEY \`${change.oldName}\``);
|
||||
alterColumns.push(`ADD CONSTRAINT \`${change.constraintName}\` FOREIGN KEY (\`${change.field}\`) REFERENCES \`${change.refTable}\` (\`${change.refField}\`) ON UPDATE ${change.onUpdate} ON DELETE ${change.onDelete}`);
|
||||
});
|
||||
|
||||
// DROP FIELDS
|
||||
deletions.forEach(deletion => {
|
||||
alterColumns.push(`DROP COLUMN \`${deletion.name}\``);
|
||||
});
|
||||
|
||||
// DROP INDEX
|
||||
indexChanges.deletions.forEach(deletion => {
|
||||
if (deletion.type === 'PRIMARY')
|
||||
alterColumns.push('DROP PRIMARY KEY');
|
||||
else
|
||||
alterColumns.push(`DROP INDEX \`${deletion.name}\``);
|
||||
});
|
||||
|
||||
// DROP FOREIGN KEYS
|
||||
foreignChanges.deletions.forEach(deletion => {
|
||||
alterColumns.push(`DROP FOREIGN KEY \`${deletion.constraintName}\``);
|
||||
});
|
||||
|
||||
sql += alterColumns.join(', ');
|
||||
|
||||
// RENAME
|
||||
if (options.name) sql += `; RENAME TABLE \`${schema}\`.\`${table}\` TO \`${schema}\`.\`${options.name}\``;
|
||||
|
||||
return await this.raw(sql);
|
||||
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 {Array.<Object>} parameters
|
||||
* @returns {Promise<null>}
|
||||
* @memberof SQLiteClient
|
||||
*/
|
||||
async duplicateTable (params) {
|
||||
const sql = `CREATE TABLE \`${params.schema}\`.\`${params.table}_copy\` LIKE \`${params.schema}\`.\`${params.table}\``;
|
||||
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 {Array.<Object>} parameters
|
||||
* @returns {Promise<null>}
|
||||
* @memberof SQLiteClient
|
||||
*/
|
||||
async truncateTable (params) {
|
||||
const sql = `TRUNCATE TABLE \`${params.schema}\`.\`${params.table}\``;
|
||||
const sql = `DELETE FROM "${params.schema}"."${params.table}"`;
|
||||
return await this.raw(sql);
|
||||
}
|
||||
|
||||
/**
|
||||
* DROP TABLE
|
||||
*
|
||||
* @returns {Array.<Object>} parameters
|
||||
* @returns {Promise<null>}
|
||||
* @memberof SQLiteClient
|
||||
*/
|
||||
async dropTable (params) {
|
||||
const sql = `DROP TABLE \`${params.schema}\`.\`${params.table}\``;
|
||||
const sql = `DROP TABLE "${params.schema}"."${params.table}"`;
|
||||
return await this.raw(sql);
|
||||
}
|
||||
|
||||
|
@ -1303,6 +730,10 @@ export class SQLiteClient extends AntaresCore {
|
|||
|
||||
let remappedFields = fields
|
||||
? fields.map(field => {
|
||||
const parsedType = field.type?.includes('(')
|
||||
? field.type.split('(')[0]
|
||||
: field.type;
|
||||
|
||||
return {
|
||||
name: field.name,
|
||||
alias: field.name,
|
||||
|
@ -1311,7 +742,7 @@ export class SQLiteClient extends AntaresCore {
|
|||
table: field.table,
|
||||
tableAlias: field.table,
|
||||
orgTable: field.table,
|
||||
type: field.type !== null ? field.type : detectedTypes[field.name]
|
||||
type: field.type !== null ? parsedType : detectedTypes[field.name]
|
||||
};
|
||||
}).filter(Boolean)
|
||||
: [];
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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 = [];
|
||||
|
|
|
@ -413,8 +413,8 @@ export default {
|
|||
customizations = require('common/customizations/postgresql');
|
||||
break;
|
||||
case 'sqlite':
|
||||
// dataTypes = require('common/data-types/sqlite');
|
||||
// indexTypes = require('common/index-types/sqlite');
|
||||
dataTypes = require('common/data-types/sqlite');
|
||||
indexTypes = require('common/index-types/sqlite');
|
||||
customizations = require('common/customizations/sqlite');
|
||||
break;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue