feat: refs #7562 deleteDeprecatedObjects #6
|
@ -1,2 +1,4 @@
|
||||||
.DS_Store
|
.DS_Store
|
||||||
node_modules
|
node_modules
|
||||||
|
db
|
||||||
|
myt.config.yml
|
|
@ -6,6 +6,11 @@ mockFunctions:
|
||||||
- mockTime
|
- mockTime
|
||||||
- mockUtcTime
|
- mockUtcTime
|
||||||
sumViews: true
|
sumViews: true
|
||||||
|
defaultDefiner: root@localhost
|
||||||
|
deprecMarkRegex: __$
|
||||||
|
deprecCommentRegex: ^@deprecated [0-9]{4}-[0-9]{2}-[0-9]{2}
|
||||||
|
deprecDateRegex: '[0-9]{4}-[0-9]{2}-[0-9]{2}'
|
||||||
|
deprecRetentionPeriod: 60 # Days
|
||||||
privileges:
|
privileges:
|
||||||
userTable: global_priv
|
userTable: global_priv
|
||||||
userWhere: >-
|
userWhere: >-
|
||||||
|
|
|
@ -43,7 +43,7 @@ class Create extends Command {
|
||||||
const params = {
|
const params = {
|
||||||
schema,
|
schema,
|
||||||
name,
|
name,
|
||||||
definer: 'root@localhost'
|
definer: opts.defaultDefiner
|
||||||
};
|
};
|
||||||
|
|
||||||
switch (opts.type) {
|
switch (opts.type) {
|
||||||
|
|
120
myt-version.js
120
myt-version.js
|
@ -1,6 +1,7 @@
|
||||||
const Myt = require('./myt');
|
const Myt = require('./myt');
|
||||||
const Command = require('./lib/command');
|
const Command = require('./lib/command');
|
||||||
const fs = require('fs-extra');
|
const fs = require('fs-extra');
|
||||||
|
const SqlString = require('sqlstring');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new version.
|
* Creates a new version.
|
||||||
|
@ -18,7 +19,7 @@ class Version extends Command {
|
||||||
static opts = {
|
static opts = {
|
||||||
alias: {
|
alias: {
|
||||||
name: 'n',
|
name: 'n',
|
||||||
guillermo marked this conversation as resolved
|
|||||||
deprecate: 'kk'
|
deprecate: 'p'
|
||||||
},
|
},
|
||||||
string: [
|
string: [
|
||||||
'name'
|
'name'
|
||||||
|
@ -128,11 +129,14 @@ class Version extends Command {
|
||||||
);
|
);
|
||||||
await fs.mkdir(newVersionDir);
|
await fs.mkdir(newVersionDir);
|
||||||
|
|
||||||
|
if (opts.deprecate) {
|
||||||
|
this.emit('deprecate');
|
||||||
|
await deprecate(conn, opts, newVersionDir);
|
||||||
|
}
|
||||||
|
else
|
||||||
guillermo marked this conversation as resolved
juan
commented
`else` y `}` deben estar en la misma linea: `} else`
|
|||||||
await fs.writeFile(
|
await fs.writeFile(
|
||||||
`${newVersionDir}/00-firstScript.sql`,
|
`${newVersionDir}/00-firstScript.sql`,
|
||||||
opts.deprecate
|
'-- Place your SQL code here\n'
|
||||||
? (this.emit('deprecate'), await deprecate(conn))
|
|
||||||
: '-- Place your SQL code here\n'
|
|
||||||
);
|
);
|
||||||
|
|
||||||
this.emit('versionCreated', versionFolder);
|
this.emit('versionCreated', versionFolder);
|
||||||
|
@ -147,67 +151,103 @@ class Version extends Command {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function deprecate(conn) {
|
async function deprecate(conn, opts, newVersionDir) {
|
||||||
const [[config]] = await conn.query(`
|
const now = new Date();
|
||||||
SELECT dateRegex,
|
const minDeprecDate = new Date(now.getTime() - opts.deprecRetentionPeriod * 24 * 60 * 60 * 1000);
|
||||||
deprecatedMarkRegex,
|
const deprecMarkRegex = opts.deprecMarkRegex;
|
||||||
VN_CURDATE() - INTERVAL daysKeepDeprecatedObjects DAY dated
|
const deprecCommentRegex = opts.deprecCommentRegex;
|
||||||
FROM config
|
const deprecDateRegex = opts.deprecDateRegex;
|
||||||
`);
|
const filePath = `${newVersionDir}/00-deprecate.sql`;
|
||||||
|
|
||||||
if (!config || Object.values(config).some(value => value == null || value === ''))
|
// Generate the drops of the primary keys
|
||||||
throw new Error('missing configuration variables');
|
const [primaryKeys] = await conn.query(`
|
||||||
|
SELECT c.TABLE_SCHEMA 'schema', c.TABLE_NAME 'table'
|
||||||
const [sql] = await conn.query(`
|
|
||||||
WITH variables AS (
|
|
||||||
SELECT ? markRegex, ? dateRegex, ? dated
|
|
||||||
)
|
|
||||||
SELECT CONCAT('ALTER TABLE ', c.TABLE_SCHEMA, '.', c.TABLE_NAME, ' DROP PRIMARY KEY;') "sql"
|
|
||||||
FROM information_schema.COLUMNS c
|
FROM information_schema.COLUMNS c
|
||||||
LEFT JOIN information_schema.VIEWS v ON v.TABLE_SCHEMA = c.TABLE_SCHEMA
|
LEFT JOIN information_schema.VIEWS v ON v.TABLE_SCHEMA = c.TABLE_SCHEMA
|
||||||
AND v.TABLE_NAME = c.TABLE_NAME
|
AND v.TABLE_NAME = c.TABLE_NAME
|
||||||
JOIN information_schema.STATISTICS s ON s.TABLE_SCHEMA = c.TABLE_SCHEMA
|
JOIN information_schema.STATISTICS s ON s.TABLE_SCHEMA = c.TABLE_SCHEMA
|
||||||
AND s.TABLE_NAME = c.TABLE_NAME
|
AND s.TABLE_NAME = c.TABLE_NAME
|
||||||
AND s.COLUMN_NAME = c.COLUMN_NAME
|
AND s.COLUMN_NAME = c.COLUMN_NAME
|
||||||
JOIN variables var
|
WHERE c.COLUMN_NAME REGEXP ? COLLATE utf8mb4_unicode_ci
|
||||||
WHERE c.COLUMN_NAME REGEXP var.markRegex COLLATE utf8mb4_unicode_ci
|
AND c.COLUMN_COMMENT REGEXP ? COLLATE utf8mb4_unicode_ci
|
||||||
AND REGEXP_SUBSTR(c.COLUMN_COMMENT, var.dateRegex COLLATE utf8mb4_unicode_ci) < var.dated
|
AND REGEXP_SUBSTR(c.COLUMN_COMMENT, ? COLLATE utf8mb4_unicode_ci) < ?
|
||||||
AND v.TABLE_NAME IS NULL
|
AND v.TABLE_NAME IS NULL
|
||||||
AND s.INDEX_NAME = 'PRIMARY'
|
AND s.INDEX_NAME = 'PRIMARY'
|
||||||
UNION
|
`, [deprecMarkRegex, deprecCommentRegex, deprecDateRegex, minDeprecDate]);
|
||||||
SELECT CONCAT('ALTER TABLE ', c.TABLE_SCHEMA, '.', c.TABLE_NAME, ' DROP FOREIGN KEY ', kcu.CONSTRAINT_NAME, ';')
|
|
||||||
|
primaryKeys.map(async row => {
|
||||||
|
await fs.appendFile(
|
||||||
|
filePath,
|
||||||
|
'ALTER TABLE ' + SqlString.escapeId(row.schema, true) + '.' +
|
||||||
|
SqlString.escapeId(row.table, true) + ' DROP PRIMARY KEY;\n'
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Generate the drops of the foreign keys
|
||||||
|
const [foreignKeys] = await conn.query(`
|
||||||
|
SELECT c.TABLE_SCHEMA 'schema', c.TABLE_NAME 'table', kcu.CONSTRAINT_NAME 'constraint'
|
||||||
FROM information_schema.COLUMNS c
|
FROM information_schema.COLUMNS c
|
||||||
LEFT JOIN information_schema.VIEWS v ON v.TABLE_SCHEMA = c.TABLE_SCHEMA
|
LEFT JOIN information_schema.VIEWS v ON v.TABLE_SCHEMA = c.TABLE_SCHEMA
|
||||||
AND v.TABLE_NAME = c.TABLE_NAME
|
AND v.TABLE_NAME = c.TABLE_NAME
|
||||||
JOIN information_schema.KEY_COLUMN_USAGE kcu ON kcu.TABLE_SCHEMA = c.TABLE_SCHEMA
|
JOIN information_schema.KEY_COLUMN_USAGE kcu ON kcu.TABLE_SCHEMA = c.TABLE_SCHEMA
|
||||||
AND kcu.TABLE_NAME = c.TABLE_NAME
|
AND kcu.TABLE_NAME = c.TABLE_NAME
|
||||||
AND kcu.COLUMN_NAME = c.COLUMN_NAME
|
AND kcu.COLUMN_NAME = c.COLUMN_NAME
|
||||||
JOIN variables var
|
WHERE c.COLUMN_NAME REGEXP ? COLLATE utf8mb4_unicode_ci
|
||||||
WHERE c.COLUMN_NAME REGEXP var.markRegex COLLATE utf8mb4_unicode_ci
|
AND c.COLUMN_COMMENT REGEXP ? COLLATE utf8mb4_unicode_ci
|
||||||
AND REGEXP_SUBSTR(c.COLUMN_COMMENT, var.dateRegex COLLATE utf8mb4_unicode_ci) < var.dated
|
AND REGEXP_SUBSTR(c.COLUMN_COMMENT, ? COLLATE utf8mb4_unicode_ci) < ?
|
||||||
AND v.TABLE_NAME IS NULL
|
AND v.TABLE_NAME IS NULL
|
||||||
AND kcu.REFERENCED_COLUMN_NAME IS NOT NULL
|
AND kcu.REFERENCED_COLUMN_NAME IS NOT NULL
|
||||||
UNION
|
`, [deprecMarkRegex, deprecCommentRegex, deprecDateRegex, minDeprecDate]);
|
||||||
SELECT CONCAT('ALTER TABLE ', c.TABLE_SCHEMA, '.', c.TABLE_NAME, ' DROP COLUMN ', c.COLUMN_NAME, ';')
|
|
||||||
|
foreignKeys.map(async row => {
|
||||||
|
await fs.appendFile(
|
||||||
|
filePath,
|
||||||
|
'ALTER TABLE ' + SqlString.escapeId(row.schema, true) + '.' +
|
||||||
|
SqlString.escapeId(row.table, true) + ' DROP FOREIGN KEY ' +
|
||||||
|
SqlString.escapeId(row.constraint, true) + ';\n'
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Generate the drops of the columns
|
||||||
|
const [columns] = await conn.query(`
|
||||||
|
SELECT c.TABLE_SCHEMA 'schema', c.TABLE_NAME 'table', c.COLUMN_NAME 'column'
|
||||||
FROM information_schema.COLUMNS c
|
FROM information_schema.COLUMNS c
|
||||||
LEFT JOIN information_schema.VIEWS v ON v.TABLE_SCHEMA = c.TABLE_SCHEMA
|
LEFT JOIN information_schema.VIEWS v ON v.TABLE_SCHEMA = c.TABLE_SCHEMA
|
||||||
AND v.TABLE_NAME = c.TABLE_NAME
|
AND v.TABLE_NAME = c.TABLE_NAME
|
||||||
LEFT JOIN information_schema.KEY_COLUMN_USAGE kcu ON kcu.TABLE_SCHEMA = c.TABLE_SCHEMA
|
LEFT JOIN information_schema.KEY_COLUMN_USAGE kcu ON kcu.TABLE_SCHEMA = c.TABLE_SCHEMA
|
||||||
AND kcu.TABLE_NAME = c.TABLE_NAME
|
AND kcu.TABLE_NAME = c.TABLE_NAME
|
||||||
AND kcu.COLUMN_NAME = c.COLUMN_NAME
|
AND kcu.COLUMN_NAME = c.COLUMN_NAME
|
||||||
JOIN variables var
|
WHERE c.COLUMN_NAME REGEXP ? COLLATE utf8mb4_unicode_ci
|
||||||
WHERE c.COLUMN_NAME REGEXP var.markRegex COLLATE utf8mb4_unicode_ci
|
AND c.COLUMN_COMMENT REGEXP ? COLLATE utf8mb4_unicode_ci
|
||||||
AND REGEXP_SUBSTR(c.COLUMN_COMMENT, var.dateRegex COLLATE utf8mb4_unicode_ci) < var.dated
|
AND REGEXP_SUBSTR(c.COLUMN_COMMENT, ? COLLATE utf8mb4_unicode_ci) <?
|
||||||
AND v.TABLE_NAME IS NULL
|
AND v.TABLE_NAME IS NULL
|
||||||
UNION
|
`, [deprecMarkRegex, deprecCommentRegex, deprecDateRegex, minDeprecDate]);
|
||||||
SELECT CONCAT('DROP TABLE ', t.TABLE_SCHEMA, '.', t.TABLE_NAME, ';')
|
|
||||||
FROM information_schema.TABLES t
|
|
||||||
JOIN variables var
|
|
||||||
WHERE t.TABLE_NAME REGEXP var.markRegex COLLATE utf8mb4_unicode_ci
|
|
||||||
AND REGEXP_SUBSTR(t.TABLE_COMMENT, var.dateRegex COLLATE utf8mb4_unicode_ci) < var.dated
|
|
||||||
`, [config.deprecatedMarkRegex, config.dateRegex, config.dated]);
|
|
||||||
|
|
||||||
return sql.map(row => row.sql).join('\n');
|
columns.map(async row => {
|
||||||
|
await fs.appendFile(
|
||||||
|
filePath,
|
||||||
|
'ALTER TABLE ' + SqlString.escapeId(row.schema, true) + '.' +
|
||||||
|
SqlString.escapeId(row.table, true) + ' DROP COLUMN ' +
|
||||||
|
SqlString.escapeId(row.column, true) + ';\n'
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Generate the drops of the tables
|
||||||
|
const [tables] = await conn.query(`
|
||||||
|
SELECT TABLE_SCHEMA 'schema', TABLE_NAME 'table'
|
||||||
|
FROM information_schema.TABLES
|
||||||
|
WHERE TABLE_NAME REGEXP ? COLLATE utf8mb4_unicode_ci
|
||||||
|
AND TABLE_COMMENT REGEXP ? COLLATE utf8mb4_unicode_ci
|
||||||
|
AND REGEXP_SUBSTR(TABLE_COMMENT, ? COLLATE utf8mb4_unicode_ci) < ?
|
||||||
|
`, [deprecMarkRegex, deprecCommentRegex, deprecDateRegex, minDeprecDate]);
|
||||||
|
|
||||||
|
tables.map(async row => {
|
||||||
|
await fs.appendFile(
|
||||||
|
filePath,
|
||||||
|
'DROP TABLE ' + SqlString.escapeId(row.schema, true) + '.' +
|
||||||
|
SqlString.escapeId(row.table, true) + ';\n'
|
||||||
|
);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function randomName() {
|
function randomName() {
|
||||||
|
|
Loading…
Reference in New Issue
Los alias solo tienen que tener una letra y hacer referencia a una palabra inglesa, ej:
-p