@dbcube/cli 1.1.6 → 1.1.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dbcube/cli",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.8",
|
|
4
4
|
"main": "index.js",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"dbcube": "node src/index.js"
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
"license": "ISC",
|
|
14
14
|
"description": "",
|
|
15
15
|
"dependencies": {
|
|
16
|
-
"@dbcube/schema-builder": "^1.0.
|
|
16
|
+
"@dbcube/schema-builder": "^1.0.7",
|
|
17
17
|
"@inquirer/prompts": "^7.8.4",
|
|
18
18
|
"alwait": "^1.0.0",
|
|
19
19
|
"chalk": "^5.6.0",
|
|
@@ -4,71 +4,94 @@ const fs = require('fs');
|
|
|
4
4
|
const path = require('path');
|
|
5
5
|
const FileUtils = require('./../../../utils/FileUtils');
|
|
6
6
|
const { default: chalk } = require('chalk');
|
|
7
|
-
const
|
|
8
|
-
const { default: alwait } = require('alwait');
|
|
7
|
+
const ProgressIndicator = require('./../../../lib/ProgressIndicator');
|
|
9
8
|
|
|
10
9
|
async function main() {
|
|
11
10
|
// Suprimir logs de dotenv
|
|
12
11
|
process.env.DOTENV_SILENT = 'true';
|
|
13
12
|
|
|
14
|
-
|
|
15
|
-
|
|
13
|
+
const progress = new ProgressIndicator();
|
|
14
|
+
progress.showHeader('Ejecutando seeders...', '🌱');
|
|
15
|
+
|
|
16
16
|
try {
|
|
17
17
|
// Verificar y leer archivos de la carpeta cubes
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
18
|
+
await progress.showProgress('Verificando archivos de seeders', async () => {
|
|
19
|
+
const cubesDir = path.join(process.cwd(), 'dbcube', 'cubes');
|
|
20
|
+
|
|
21
|
+
if (!fs.existsSync(cubesDir)) {
|
|
22
|
+
throw new Error('❌ The cubes folder does not exist');
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const cubeFiles = FileUtils.getCubeFilesRecursively('dbcube', 'table.cube');
|
|
26
|
+
|
|
27
|
+
if (cubeFiles.length === 0) {
|
|
28
|
+
throw new Error('❌ There are no cubes to execute');
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
return cubeFiles;
|
|
32
|
+
});
|
|
21
33
|
|
|
22
|
-
//
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
34
|
+
// Cargar configuraciones de base de datos
|
|
35
|
+
const configuredDatabases = await progress.showProgress('Cargando configuraciones de base de datos', async () => {
|
|
36
|
+
return await ConfigFileUtils.getConfiguredDatabases();
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
// Obtener archivos .cube reales
|
|
40
|
+
const cubeFiles = await progress.showProgress('Analizando archivos .cube', async () => {
|
|
41
|
+
return FileUtils.getCubeFilesRecursively('dbcube', 'table.cube');
|
|
42
|
+
});
|
|
27
43
|
|
|
28
|
-
|
|
29
|
-
const cubeFiles = FileUtils.getCubeFilesRecursively('dbcube', 'table.cube')
|
|
44
|
+
let totalSeedersProcessed = 0;
|
|
30
45
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
46
|
+
// Procesar cada base de datos
|
|
47
|
+
for (const config of configuredDatabases) {
|
|
48
|
+
console.log(`\n${chalk.blue('┌─')} Procesando base de datos: ${chalk.bold(config.name)} ${chalk.gray(`(${config.type})`)}`);
|
|
49
|
+
|
|
50
|
+
const schema = new Schema(config.name);
|
|
36
51
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
const configuredDatabases = await ConfigFileUtils.getConfiguredDatabases();
|
|
40
|
-
loadingSpinner.succeed(`Configuraciones cargadas (${configuredDatabases.length} bases de datos)`);
|
|
52
|
+
// Obtener nombres reales de los seeders desde los archivos .cube
|
|
53
|
+
const realSeeders = progress.extractSeederNamesFromCubes(cubeFiles);
|
|
41
54
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
const schema = new Schema(config.name);
|
|
46
|
-
await schema.executeSeeders();
|
|
47
|
-
seederSpinner.succeed(`Seeders ejecutados para: ${config.name}`);
|
|
48
|
-
countTableCreated++;
|
|
55
|
+
if (realSeeders.length === 0) {
|
|
56
|
+
console.log(` ${chalk.yellow('└─')} No se encontraron seeders en los archivos .cube`);
|
|
57
|
+
continue;
|
|
49
58
|
}
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
59
|
+
|
|
60
|
+
// Procesar cada seeder con indicador de progreso
|
|
61
|
+
console.log(` ${chalk.blue('├─')} Ejecutando ${realSeeders.length} seeders:`);
|
|
62
|
+
|
|
63
|
+
for (let i = 0; i < realSeeders.length; i++) {
|
|
64
|
+
const seederName = realSeeders[i];
|
|
65
|
+
await progress.showTableProgress(seederName, 'seeder');
|
|
66
|
+
totalSeedersProcessed++;
|
|
55
67
|
}
|
|
56
68
|
|
|
69
|
+
// Ejecutar los seeders reales
|
|
70
|
+
await progress.showProgress('Insertando datos de prueba', async () => {
|
|
71
|
+
await schema.executeSeeders();
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
console.log(` ${chalk.blue('└─')} ${chalk.green('✓')} Base de datos ${config.name} completada`);
|
|
57
75
|
}
|
|
76
|
+
|
|
77
|
+
// Mostrar resumen
|
|
78
|
+
progress.showSummary('seeder', totalSeedersProcessed, configuredDatabases.length);
|
|
79
|
+
|
|
58
80
|
} catch (error) {
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
81
|
+
progress.showError('Error durante la ejecución de seeders', error);
|
|
82
|
+
|
|
83
|
+
if(error.message.includes("reading 'init'")){
|
|
84
|
+
console.error('\n💡 Soluciones sugeridas:');
|
|
85
|
+
console.error(` ${chalk.gray('├─')} Ejecutar: ${chalk.cyan('dbcube run database:create')}`);
|
|
86
|
+
console.error(` ${chalk.gray('└─')} Verificar archivo: ${chalk.cyan('dbcube.config.js')}`);
|
|
87
|
+
process.exit(1);
|
|
88
|
+
} else if(error.message.includes("reading 'getDatabase'")){
|
|
89
|
+
console.error('💡 Se sugiere cambiar la configuración o crear la base de datos referenciada.');
|
|
90
|
+
}
|
|
91
|
+
|
|
64
92
|
process.exit(1);
|
|
65
|
-
} else if(error.message.includes("reading 'getDatabase'")){
|
|
66
|
-
console.error('- Se sugiere cambiar el linea o crear la base de datos a la que se hace referencia.');
|
|
67
|
-
}else{
|
|
68
|
-
console.error('Error aqui:', error);
|
|
69
|
-
console.error('Error aqui:', error.message);
|
|
70
|
-
}
|
|
71
93
|
}
|
|
94
|
+
|
|
72
95
|
console.log('\n');
|
|
73
96
|
}
|
|
74
97
|
|
|
@@ -4,71 +4,100 @@ const fs = require('fs');
|
|
|
4
4
|
const path = require('path');
|
|
5
5
|
const FileUtils = require('./../../../utils/FileUtils');
|
|
6
6
|
const { default: chalk } = require('chalk');
|
|
7
|
-
const
|
|
8
|
-
const { default: alwait } = require('alwait');
|
|
7
|
+
const ProgressIndicator = require('./../../../lib/ProgressIndicator');
|
|
9
8
|
|
|
10
9
|
async function main() {
|
|
11
10
|
// Suprimir logs de dotenv
|
|
12
11
|
process.env.DOTENV_SILENT = 'true';
|
|
13
12
|
|
|
14
|
-
|
|
15
|
-
|
|
13
|
+
const progress = new ProgressIndicator();
|
|
14
|
+
progress.showHeader('Ejecutando fresh tables...', '🗑️');
|
|
15
|
+
|
|
16
16
|
try {
|
|
17
17
|
// Verificar y leer archivos de la carpeta cubes
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
18
|
+
await progress.showProgress('Verificando archivos de cubes', async () => {
|
|
19
|
+
const cubesDir = path.join(process.cwd(), 'dbcube', 'cubes');
|
|
20
|
+
|
|
21
|
+
if (!fs.existsSync(cubesDir)) {
|
|
22
|
+
throw new Error('❌ The cubes folder does not exist');
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const cubeFiles = FileUtils.getCubeFilesRecursively('dbcube', 'table.cube');
|
|
26
|
+
|
|
27
|
+
if (cubeFiles.length === 0) {
|
|
28
|
+
throw new Error('❌ There are no cubes to execute');
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
return cubeFiles;
|
|
32
|
+
});
|
|
21
33
|
|
|
22
|
-
//
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
34
|
+
// Cargar configuraciones de base de datos
|
|
35
|
+
const configuredDatabases = await progress.showProgress('Cargando configuraciones de base de datos', async () => {
|
|
36
|
+
return await ConfigFileUtils.getConfiguredDatabases();
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
// Obtener archivos .cube reales
|
|
40
|
+
const cubeFiles = await progress.showProgress('Analizando archivos .cube', async () => {
|
|
41
|
+
return FileUtils.getCubeFilesRecursively('dbcube', 'table.cube');
|
|
42
|
+
});
|
|
27
43
|
|
|
28
|
-
|
|
29
|
-
const cubeFiles = FileUtils.getCubeFilesRecursively('dbcube', 'table.cube')
|
|
44
|
+
let totalTablesProcessed = 0;
|
|
30
45
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
46
|
+
// Procesar cada base de datos
|
|
47
|
+
for (const config of configuredDatabases) {
|
|
48
|
+
console.log(`\n${chalk.blue('┌─')} Procesando base de datos: ${chalk.bold(config.name)} ${chalk.gray(`(${config.type})`)}`);
|
|
49
|
+
|
|
50
|
+
const schema = new Schema(config.name);
|
|
36
51
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
const configuredDatabases = await ConfigFileUtils.getConfiguredDatabases();
|
|
40
|
-
loadingSpinner.succeed(`Configuraciones cargadas (${configuredDatabases.length} bases de datos)`);
|
|
52
|
+
// Obtener nombres reales de las tablas desde los archivos .cube
|
|
53
|
+
const realTables = progress.extractTableNamesFromCubes(cubeFiles);
|
|
41
54
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
const schema = new Schema(config.name);
|
|
46
|
-
await schema.freshTables();
|
|
47
|
-
freshSpinner.succeed(`Fresh tables ejecutado para: ${config.name}`);
|
|
48
|
-
countTableCreated++;
|
|
55
|
+
if (realTables.length === 0) {
|
|
56
|
+
console.log(` ${chalk.yellow('└─')} No se encontraron tablas en los archivos .cube`);
|
|
57
|
+
continue;
|
|
49
58
|
}
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
59
|
+
|
|
60
|
+
// Procesar cada tabla con indicador de progreso
|
|
61
|
+
console.log(` ${chalk.blue('├─')} Ejecutando fresh en ${realTables.length} tablas:`);
|
|
62
|
+
|
|
63
|
+
for (let i = 0; i < realTables.length; i++) {
|
|
64
|
+
const tableName = realTables[i];
|
|
65
|
+
await progress.showTableProgress(tableName, 'refresh');
|
|
66
|
+
totalTablesProcessed++;
|
|
55
67
|
}
|
|
56
68
|
|
|
69
|
+
// Ejecutar el fresh real
|
|
70
|
+
await progress.showProgress('Aplicando fresh en la base de datos', async () => {
|
|
71
|
+
const result = await schema.freshTables();
|
|
72
|
+
|
|
73
|
+
if (result === null) {
|
|
74
|
+
throw new Error(`Base de datos ${config.name} no existe o no es accesible`);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
return result;
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
console.log(` ${chalk.blue('└─')} ${chalk.green('✓')} Base de datos ${config.name} completada`);
|
|
57
81
|
}
|
|
82
|
+
|
|
83
|
+
// Mostrar resumen
|
|
84
|
+
progress.showSummary('fresh', totalTablesProcessed, configuredDatabases.length);
|
|
85
|
+
|
|
58
86
|
} catch (error) {
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
87
|
+
progress.showError('Error durante el fresh', error);
|
|
88
|
+
|
|
89
|
+
if(error.message.includes("reading 'init'")){
|
|
90
|
+
console.error('\n💡 Soluciones sugeridas:');
|
|
91
|
+
console.error(` ${chalk.gray('├─')} Ejecutar: ${chalk.cyan('dbcube run database:create')}`);
|
|
92
|
+
console.error(` ${chalk.gray('└─')} Verificar archivo: ${chalk.cyan('dbcube.config.js')}`);
|
|
93
|
+
process.exit(1);
|
|
94
|
+
} else if(error.message.includes("reading 'getDatabase'")){
|
|
95
|
+
console.error('💡 Se sugiere cambiar la configuración o crear la base de datos referenciada.');
|
|
96
|
+
}
|
|
97
|
+
|
|
64
98
|
process.exit(1);
|
|
65
|
-
} else if(error.message.includes("reading 'getDatabase'")){
|
|
66
|
-
console.error('- Se sugiere cambiar el linea o crear la base de datos a la que se hace referencia.');
|
|
67
|
-
}else{
|
|
68
|
-
console.error('Error aqui:', error);
|
|
69
|
-
console.error('Error aqui:', error.message);
|
|
70
|
-
}
|
|
71
99
|
}
|
|
100
|
+
|
|
72
101
|
console.log('\n');
|
|
73
102
|
}
|
|
74
103
|
|
|
@@ -4,71 +4,94 @@ const fs = require('fs');
|
|
|
4
4
|
const path = require('path');
|
|
5
5
|
const FileUtils = require('./../../../utils/FileUtils');
|
|
6
6
|
const { default: chalk } = require('chalk');
|
|
7
|
-
const
|
|
8
|
-
const { default: alwait } = require('alwait');
|
|
7
|
+
const ProgressIndicator = require('./../../../lib/ProgressIndicator');
|
|
9
8
|
|
|
10
9
|
async function main() {
|
|
11
10
|
// Suprimir logs de dotenv
|
|
12
11
|
process.env.DOTENV_SILENT = 'true';
|
|
13
12
|
|
|
14
|
-
|
|
15
|
-
|
|
13
|
+
const progress = new ProgressIndicator();
|
|
14
|
+
progress.showHeader('Ejecutando refresh tables...', '🔄');
|
|
15
|
+
|
|
16
16
|
try {
|
|
17
17
|
// Verificar y leer archivos de la carpeta cubes
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
18
|
+
await progress.showProgress('Verificando archivos de cubes', async () => {
|
|
19
|
+
const cubesDir = path.join(process.cwd(), 'dbcube', 'cubes');
|
|
20
|
+
|
|
21
|
+
if (!fs.existsSync(cubesDir)) {
|
|
22
|
+
throw new Error('❌ The cubes folder does not exist');
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const cubeFiles = FileUtils.getCubeFilesRecursively('dbcube', 'table.cube');
|
|
26
|
+
|
|
27
|
+
if (cubeFiles.length === 0) {
|
|
28
|
+
throw new Error('❌ There are no cubes to execute');
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
return cubeFiles;
|
|
32
|
+
});
|
|
21
33
|
|
|
22
|
-
//
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
34
|
+
// Cargar configuraciones de base de datos
|
|
35
|
+
const configuredDatabases = await progress.showProgress('Cargando configuraciones de base de datos', async () => {
|
|
36
|
+
return await ConfigFileUtils.getConfiguredDatabases();
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
// Obtener archivos .cube reales
|
|
40
|
+
const cubeFiles = await progress.showProgress('Analizando archivos .cube', async () => {
|
|
41
|
+
return FileUtils.getCubeFilesRecursively('dbcube', 'table.cube');
|
|
42
|
+
});
|
|
27
43
|
|
|
28
|
-
|
|
29
|
-
const cubeFiles = FileUtils.getCubeFilesRecursively('dbcube', 'table.cube')
|
|
44
|
+
let totalTablesProcessed = 0;
|
|
30
45
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
46
|
+
// Procesar cada base de datos
|
|
47
|
+
for (const config of configuredDatabases) {
|
|
48
|
+
console.log(`\n${chalk.blue('┌─')} Procesando base de datos: ${chalk.bold(config.name)} ${chalk.gray(`(${config.type})`)}`);
|
|
49
|
+
|
|
50
|
+
const schema = new Schema(config.name);
|
|
36
51
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
const configuredDatabases = await ConfigFileUtils.getConfiguredDatabases();
|
|
40
|
-
loadingSpinner.succeed(`Configuraciones cargadas (${configuredDatabases.length} bases de datos)`);
|
|
52
|
+
// Obtener nombres reales de las tablas desde los archivos .cube
|
|
53
|
+
const realTables = progress.extractTableNamesFromCubes(cubeFiles);
|
|
41
54
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
const schema = new Schema(config.name);
|
|
46
|
-
await schema.refreshTables();
|
|
47
|
-
refreshSpinner.succeed(`Refresh tables ejecutado para: ${config.name}`);
|
|
48
|
-
countTableCreated++;
|
|
55
|
+
if (realTables.length === 0) {
|
|
56
|
+
console.log(` ${chalk.yellow('└─')} No se encontraron tablas en los archivos .cube`);
|
|
57
|
+
continue;
|
|
49
58
|
}
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
59
|
+
|
|
60
|
+
// Procesar cada tabla con indicador de progreso
|
|
61
|
+
console.log(` ${chalk.blue('├─')} Refrescando ${realTables.length} tablas:`);
|
|
62
|
+
|
|
63
|
+
for (let i = 0; i < realTables.length; i++) {
|
|
64
|
+
const tableName = realTables[i];
|
|
65
|
+
await progress.showTableProgress(tableName, 'refresh');
|
|
66
|
+
totalTablesProcessed++;
|
|
55
67
|
}
|
|
56
68
|
|
|
69
|
+
// Ejecutar el refresh real
|
|
70
|
+
await progress.showProgress('Aplicando cambios en la base de datos', async () => {
|
|
71
|
+
await schema.refreshTables();
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
console.log(` ${chalk.blue('└─')} ${chalk.green('✓')} Base de datos ${config.name} completada`);
|
|
57
75
|
}
|
|
76
|
+
|
|
77
|
+
// Mostrar resumen
|
|
78
|
+
progress.showSummary('refresh', totalTablesProcessed, configuredDatabases.length);
|
|
79
|
+
|
|
58
80
|
} catch (error) {
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
81
|
+
progress.showError('Error durante el refresh', error);
|
|
82
|
+
|
|
83
|
+
if(error.message.includes("reading 'init'")){
|
|
84
|
+
console.error('\n💡 Soluciones sugeridas:');
|
|
85
|
+
console.error(` ${chalk.gray('├─')} Ejecutar: ${chalk.cyan('dbcube run database:create')}`);
|
|
86
|
+
console.error(` ${chalk.gray('└─')} Verificar archivo: ${chalk.cyan('dbcube.config.js')}`);
|
|
87
|
+
process.exit(1);
|
|
88
|
+
} else if(error.message.includes("reading 'getDatabase'")){
|
|
89
|
+
console.error('💡 Se sugiere cambiar la configuración o crear la base de datos referenciada.');
|
|
90
|
+
}
|
|
91
|
+
|
|
64
92
|
process.exit(1);
|
|
65
|
-
} else if(error.message.includes("reading 'getDatabase'")){
|
|
66
|
-
console.error('- Se sugiere cambiar el linea o crear la base de datos a la que se hace referencia.');
|
|
67
|
-
}else{
|
|
68
|
-
console.error('Error aqui:', error);
|
|
69
|
-
console.error('Error aqui:', error.message);
|
|
70
|
-
}
|
|
71
93
|
}
|
|
94
|
+
|
|
72
95
|
console.log('\n');
|
|
73
96
|
}
|
|
74
97
|
|
|
@@ -4,71 +4,94 @@ const fs = require('fs');
|
|
|
4
4
|
const path = require('path');
|
|
5
5
|
const FileUtils = require('./../../../utils/FileUtils');
|
|
6
6
|
const { default: chalk } = require('chalk');
|
|
7
|
-
const
|
|
8
|
-
const { default: alwait } = require('alwait');
|
|
7
|
+
const ProgressIndicator = require('./../../../lib/ProgressIndicator');
|
|
9
8
|
|
|
10
9
|
async function main() {
|
|
11
10
|
// Suprimir logs de dotenv
|
|
12
11
|
process.env.DOTENV_SILENT = 'true';
|
|
13
12
|
|
|
14
|
-
|
|
15
|
-
|
|
13
|
+
const progress = new ProgressIndicator();
|
|
14
|
+
progress.showHeader('Ejecutando triggers...', '⚡');
|
|
15
|
+
|
|
16
16
|
try {
|
|
17
17
|
// Verificar y leer archivos de la carpeta cubes
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
18
|
+
await progress.showProgress('Verificando archivos de triggers', async () => {
|
|
19
|
+
const cubesDir = path.join(process.cwd(), 'dbcube', 'cubes');
|
|
20
|
+
|
|
21
|
+
if (!fs.existsSync(cubesDir)) {
|
|
22
|
+
throw new Error('❌ The cubes folder does not exist');
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const cubeFiles = FileUtils.getCubeFilesRecursively('dbcube', 'table.cube');
|
|
26
|
+
|
|
27
|
+
if (cubeFiles.length === 0) {
|
|
28
|
+
throw new Error('❌ There are no cubes to execute');
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
return cubeFiles;
|
|
32
|
+
});
|
|
21
33
|
|
|
22
|
-
//
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
34
|
+
// Cargar configuraciones de base de datos
|
|
35
|
+
const configuredDatabases = await progress.showProgress('Cargando configuraciones de base de datos', async () => {
|
|
36
|
+
return await ConfigFileUtils.getConfiguredDatabases();
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
// Obtener archivos .cube reales
|
|
40
|
+
const cubeFiles = await progress.showProgress('Analizando archivos .cube', async () => {
|
|
41
|
+
return FileUtils.getCubeFilesRecursively('dbcube', 'table.cube');
|
|
42
|
+
});
|
|
27
43
|
|
|
28
|
-
|
|
29
|
-
const cubeFiles = FileUtils.getCubeFilesRecursively('dbcube', 'table.cube')
|
|
44
|
+
let totalTriggersProcessed = 0;
|
|
30
45
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
46
|
+
// Procesar cada base de datos
|
|
47
|
+
for (const config of configuredDatabases) {
|
|
48
|
+
console.log(`\n${chalk.blue('┌─')} Procesando base de datos: ${chalk.bold(config.name)} ${chalk.gray(`(${config.type})`)}`);
|
|
49
|
+
|
|
50
|
+
const schema = new Schema(config.name);
|
|
36
51
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
const configuredDatabases = await ConfigFileUtils.getConfiguredDatabases();
|
|
40
|
-
loadingSpinner.succeed(`Configuraciones cargadas (${configuredDatabases.length} bases de datos)`);
|
|
52
|
+
// Obtener nombres reales de los triggers desde los archivos .cube
|
|
53
|
+
const realTriggers = progress.extractTriggerNamesFromCubes(cubeFiles);
|
|
41
54
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
const schema = new Schema(config.name);
|
|
46
|
-
await schema.executeTriggers();
|
|
47
|
-
triggerSpinner.succeed(`Triggers ejecutados para: ${config.name}`);
|
|
48
|
-
countTableCreated++;
|
|
55
|
+
if (realTriggers.length === 0) {
|
|
56
|
+
console.log(` ${chalk.yellow('└─')} No se encontraron triggers en los archivos .cube`);
|
|
57
|
+
continue;
|
|
49
58
|
}
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
59
|
+
|
|
60
|
+
// Procesar cada trigger con indicador de progreso
|
|
61
|
+
console.log(` ${chalk.blue('├─')} Ejecutando ${realTriggers.length} triggers:`);
|
|
62
|
+
|
|
63
|
+
for (let i = 0; i < realTriggers.length; i++) {
|
|
64
|
+
const triggerName = realTriggers[i];
|
|
65
|
+
await progress.showTableProgress(triggerName, 'trigger');
|
|
66
|
+
totalTriggersProcessed++;
|
|
55
67
|
}
|
|
56
68
|
|
|
69
|
+
// Ejecutar los triggers reales
|
|
70
|
+
await progress.showProgress('Aplicando triggers en la base de datos', async () => {
|
|
71
|
+
await schema.executeTriggers();
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
console.log(` ${chalk.blue('└─')} ${chalk.green('✓')} Base de datos ${config.name} completada`);
|
|
57
75
|
}
|
|
76
|
+
|
|
77
|
+
// Mostrar resumen
|
|
78
|
+
progress.showSummary('trigger', totalTriggersProcessed, configuredDatabases.length);
|
|
79
|
+
|
|
58
80
|
} catch (error) {
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
81
|
+
progress.showError('Error durante la ejecución de triggers', error);
|
|
82
|
+
|
|
83
|
+
if(error.message.includes("reading 'init'")){
|
|
84
|
+
console.error('\n💡 Soluciones sugeridas:');
|
|
85
|
+
console.error(` ${chalk.gray('├─')} Ejecutar: ${chalk.cyan('dbcube run database:create')}`);
|
|
86
|
+
console.error(` ${chalk.gray('└─')} Verificar archivo: ${chalk.cyan('dbcube.config.js')}`);
|
|
87
|
+
process.exit(1);
|
|
88
|
+
} else if(error.message.includes("reading 'getDatabase'")){
|
|
89
|
+
console.error('💡 Se sugiere cambiar la configuración o crear la base de datos referenciada.');
|
|
90
|
+
}
|
|
91
|
+
|
|
64
92
|
process.exit(1);
|
|
65
|
-
} else if(error.message.includes("reading 'getDatabase'")){
|
|
66
|
-
console.error('- Se sugiere cambiar el linea o crear la base de datos a la que se hace referencia.');
|
|
67
|
-
}else{
|
|
68
|
-
console.error('Error aqui:', error);
|
|
69
|
-
console.error('Error aqui:', error.message);
|
|
70
|
-
}
|
|
71
93
|
}
|
|
94
|
+
|
|
72
95
|
console.log('\n');
|
|
73
96
|
}
|
|
74
97
|
|
|
@@ -0,0 +1,287 @@
|
|
|
1
|
+
const { default: chalk } = require('chalk');
|
|
2
|
+
const { default: ora } = require('ora');
|
|
3
|
+
const fs = require('fs');
|
|
4
|
+
const path = require('path');
|
|
5
|
+
|
|
6
|
+
class ProgressIndicator {
|
|
7
|
+
constructor() {
|
|
8
|
+
this.activeSpinner = null;
|
|
9
|
+
this.startTime = null;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Inicia el indicador de progreso principal
|
|
14
|
+
* @param {string} message - Mensaje principal
|
|
15
|
+
*/
|
|
16
|
+
start(message) {
|
|
17
|
+
console.log(`\n${chalk.cyan('●')} ${chalk.bold(message)}`);
|
|
18
|
+
this.startTime = Date.now();
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Muestra progreso para una operación específica con tabla
|
|
23
|
+
* @param {string} tableName - Nombre de la tabla
|
|
24
|
+
* @param {string} operation - Tipo de operación (refresh, seeder, trigger)
|
|
25
|
+
* @param {string} databaseName - Nombre de la base de datos
|
|
26
|
+
*/
|
|
27
|
+
async showTableProgress(tableName, operation, databaseName = '') {
|
|
28
|
+
const startTime = Date.now();
|
|
29
|
+
const maxDots = 50;
|
|
30
|
+
const operationText = this.getOperationText(operation);
|
|
31
|
+
|
|
32
|
+
// Formatear el nombre para que tenga un ancho fijo
|
|
33
|
+
const displayName = databaseName ? `${databaseName}.${tableName}` : tableName;
|
|
34
|
+
const truncatedName = displayName.length > 30 ?
|
|
35
|
+
displayName.substring(0, 27) + '...' :
|
|
36
|
+
displayName.padEnd(30);
|
|
37
|
+
|
|
38
|
+
// Simular progreso con puntos
|
|
39
|
+
return new Promise((resolve) => {
|
|
40
|
+
process.stdout.write(` ${chalk.gray('├─')} ${truncatedName} `);
|
|
41
|
+
|
|
42
|
+
let dotCount = 0;
|
|
43
|
+
const interval = setInterval(() => {
|
|
44
|
+
if (dotCount < maxDots) {
|
|
45
|
+
process.stdout.write(chalk.gray('.'));
|
|
46
|
+
dotCount++;
|
|
47
|
+
} else {
|
|
48
|
+
clearInterval(interval);
|
|
49
|
+
const elapsed = ((Date.now() - startTime) / 1000).toFixed(1);
|
|
50
|
+
process.stdout.write(` ${chalk.green('✓')} ${chalk.gray(elapsed + 's')}\n`);
|
|
51
|
+
resolve();
|
|
52
|
+
}
|
|
53
|
+
}, 20); // Velocidad de los puntos
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Muestra progreso para múltiples tablas
|
|
59
|
+
* @param {Array} tables - Array de nombres de tablas
|
|
60
|
+
* @param {string} operation - Tipo de operación
|
|
61
|
+
* @param {string} databaseName - Nombre de la base de datos
|
|
62
|
+
* @param {Function} executor - Función que ejecuta la operación para cada tabla
|
|
63
|
+
*/
|
|
64
|
+
async showMultipleTablesProgress(tables, operation, databaseName, executor) {
|
|
65
|
+
const operationText = this.getOperationText(operation);
|
|
66
|
+
console.log(` ${chalk.blue('┌─')} ${operationText} en ${chalk.bold(databaseName)}:`);
|
|
67
|
+
|
|
68
|
+
for (let i = 0; i < tables.length; i++) {
|
|
69
|
+
const table = tables[i];
|
|
70
|
+
const isLast = i === tables.length - 1;
|
|
71
|
+
|
|
72
|
+
await this.showTableProgress(table, operation, '');
|
|
73
|
+
|
|
74
|
+
if (executor) {
|
|
75
|
+
await executor(table);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
console.log(` ${chalk.blue('└─')} ${chalk.green('Completado')}`);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Muestra progreso simple para operaciones generales
|
|
84
|
+
* @param {string} message - Mensaje a mostrar
|
|
85
|
+
* @param {Function} executor - Función a ejecutar
|
|
86
|
+
*/
|
|
87
|
+
async showProgress(message, executor) {
|
|
88
|
+
const spinner = ora(message).start();
|
|
89
|
+
const startTime = Date.now();
|
|
90
|
+
|
|
91
|
+
try {
|
|
92
|
+
const result = await executor();
|
|
93
|
+
const elapsed = ((Date.now() - startTime) / 1000).toFixed(1);
|
|
94
|
+
spinner.succeed(`${message} ${chalk.gray(`(${elapsed}s)`)}`);
|
|
95
|
+
return result;
|
|
96
|
+
} catch (error) {
|
|
97
|
+
spinner.fail(`${message} ${chalk.red('falló')}`);
|
|
98
|
+
throw error;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* Muestra el resumen final
|
|
104
|
+
* @param {string} operation - Tipo de operación
|
|
105
|
+
* @param {number} count - Cantidad de elementos procesados
|
|
106
|
+
* @param {number} databases - Cantidad de bases de datos
|
|
107
|
+
*/
|
|
108
|
+
showSummary(operation, count, databases) {
|
|
109
|
+
const totalTime = this.startTime ? ((Date.now() - this.startTime) / 1000).toFixed(1) : '0.0';
|
|
110
|
+
const operationText = this.getOperationText(operation);
|
|
111
|
+
|
|
112
|
+
console.log(`\n${chalk.green('🎉')} ${chalk.bold('Resumen:')}`);
|
|
113
|
+
console.log(` ${chalk.gray('├─')} ${operationText}: ${chalk.cyan(count)} elementos`);
|
|
114
|
+
console.log(` ${chalk.gray('├─')} Bases de datos: ${chalk.cyan(databases)}`);
|
|
115
|
+
console.log(` ${chalk.gray('└─')} Tiempo total: ${chalk.cyan(totalTime + 's')}`);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* Muestra error con formato
|
|
120
|
+
* @param {string} message - Mensaje de error
|
|
121
|
+
* @param {Error} error - Error objeto
|
|
122
|
+
*/
|
|
123
|
+
showError(message, error) {
|
|
124
|
+
console.log(`\n${chalk.red('❌')} ${chalk.bold(message)}`);
|
|
125
|
+
if (error && error.message) {
|
|
126
|
+
console.log(` ${chalk.gray('└─')} ${chalk.red(error.message)}`);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
/**
|
|
131
|
+
* Obtiene el texto de la operación
|
|
132
|
+
* @param {string} operation - Tipo de operación
|
|
133
|
+
* @returns {string}
|
|
134
|
+
*/
|
|
135
|
+
getOperationText(operation) {
|
|
136
|
+
const operations = {
|
|
137
|
+
'refresh': 'Refrescando tablas',
|
|
138
|
+
'seeder': 'Ejecutando seeders',
|
|
139
|
+
'trigger': 'Ejecutando triggers'
|
|
140
|
+
};
|
|
141
|
+
return operations[operation] || operation;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* Extrae nombres de tablas reales de archivos .cube
|
|
146
|
+
* @param {string[]} cubeFiles - Array de rutas de archivos .cube
|
|
147
|
+
* @returns {string[]} Array de nombres de tablas
|
|
148
|
+
*/
|
|
149
|
+
extractTableNamesFromCubes(cubeFiles) {
|
|
150
|
+
const tableNames = [];
|
|
151
|
+
|
|
152
|
+
for (const filePath of cubeFiles) {
|
|
153
|
+
try {
|
|
154
|
+
const content = fs.readFileSync(filePath, 'utf8');
|
|
155
|
+
|
|
156
|
+
// Buscar patrones de nombre de tabla en el archivo .cube
|
|
157
|
+
// Patrón 1: @table("nombre_tabla") o @table('nombre_tabla')
|
|
158
|
+
const tableMatch = content.match(/@table\(\s*["']([^"']+)["']\s*\)/);
|
|
159
|
+
if (tableMatch) {
|
|
160
|
+
tableNames.push(tableMatch[1]);
|
|
161
|
+
continue;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
// Patrón 2: table: "nombre_tabla" o table: 'nombre_tabla'
|
|
165
|
+
const tableMatch2 = content.match(/table\s*:\s*["']([^"']+)["']/);
|
|
166
|
+
if (tableMatch2) {
|
|
167
|
+
tableNames.push(tableMatch2[1]);
|
|
168
|
+
continue;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
// Patrón 3: usar el nombre del archivo sin la extensión .cube
|
|
172
|
+
const fileName = path.basename(filePath, '.table.cube');
|
|
173
|
+
if (fileName && fileName !== 'table') {
|
|
174
|
+
// Si el archivo tiene un número al principio, quitarlo
|
|
175
|
+
const cleanName = fileName.replace(/^\d+[-_]?/, '');
|
|
176
|
+
if (cleanName) {
|
|
177
|
+
tableNames.push(cleanName);
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
} catch (error) {
|
|
182
|
+
// Si no se puede leer el archivo, usar el nombre del archivo
|
|
183
|
+
const fileName = path.basename(filePath, '.table.cube');
|
|
184
|
+
const cleanName = fileName.replace(/^\d+[-_]?/, '');
|
|
185
|
+
if (cleanName && cleanName !== 'table') {
|
|
186
|
+
tableNames.push(cleanName);
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
return tableNames;
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
/**
|
|
195
|
+
* Extrae nombres de seeders de archivos .cube
|
|
196
|
+
* @param {string[]} cubeFiles - Array de rutas de archivos .cube
|
|
197
|
+
* @returns {string[]} Array de nombres de seeders
|
|
198
|
+
*/
|
|
199
|
+
extractSeederNamesFromCubes(cubeFiles) {
|
|
200
|
+
const seederNames = [];
|
|
201
|
+
|
|
202
|
+
for (const filePath of cubeFiles) {
|
|
203
|
+
try {
|
|
204
|
+
const content = fs.readFileSync(filePath, 'utf8');
|
|
205
|
+
|
|
206
|
+
// Buscar secciones de seeders en el archivo
|
|
207
|
+
const seederMatches = content.match(/@seeder\s*\(\s*["']([^"']+)["']\s*\)/g);
|
|
208
|
+
if (seederMatches) {
|
|
209
|
+
for (const match of seederMatches) {
|
|
210
|
+
const seederName = match.match(/@seeder\s*\(\s*["']([^"']+)["']\s*\)/)[1];
|
|
211
|
+
seederNames.push(seederName);
|
|
212
|
+
}
|
|
213
|
+
} else {
|
|
214
|
+
// Si no hay seeders específicos, crear uno basado en el nombre de la tabla
|
|
215
|
+
const tableNames = this.extractTableNamesFromCubes([filePath]);
|
|
216
|
+
if (tableNames.length > 0) {
|
|
217
|
+
seederNames.push(`${tableNames[0]}Seeder`);
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
} catch (error) {
|
|
222
|
+
// Fallback: usar nombre del archivo
|
|
223
|
+
const fileName = path.basename(filePath, '.table.cube');
|
|
224
|
+
const cleanName = fileName.replace(/^\d+[-_]?/, '');
|
|
225
|
+
if (cleanName && cleanName !== 'table') {
|
|
226
|
+
seederNames.push(`${cleanName}Seeder`);
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
return seederNames;
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
/**
|
|
235
|
+
* Extrae nombres de triggers de archivos .cube
|
|
236
|
+
* @param {string[]} cubeFiles - Array de rutas de archivos .cube
|
|
237
|
+
* @returns {string[]} Array de nombres de triggers
|
|
238
|
+
*/
|
|
239
|
+
extractTriggerNamesFromCubes(cubeFiles) {
|
|
240
|
+
const triggerNames = [];
|
|
241
|
+
|
|
242
|
+
for (const filePath of cubeFiles) {
|
|
243
|
+
try {
|
|
244
|
+
const content = fs.readFileSync(filePath, 'utf8');
|
|
245
|
+
|
|
246
|
+
// Buscar triggers en el archivo
|
|
247
|
+
const triggerMatches = content.match(/@trigger\s*\(\s*["']([^"']+)["']\s*\)/g);
|
|
248
|
+
if (triggerMatches) {
|
|
249
|
+
for (const match of triggerMatches) {
|
|
250
|
+
const triggerName = match.match(/@trigger\s*\(\s*["']([^"']+)["']\s*\)/)[1];
|
|
251
|
+
triggerNames.push(triggerName);
|
|
252
|
+
}
|
|
253
|
+
} else {
|
|
254
|
+
// Si no hay triggers específicos, crear algunos basados en la tabla
|
|
255
|
+
const tableNames = this.extractTableNamesFromCubes([filePath]);
|
|
256
|
+
if (tableNames.length > 0) {
|
|
257
|
+
const tableName = tableNames[0];
|
|
258
|
+
triggerNames.push(`before_insert_${tableName}`);
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
} catch (error) {
|
|
263
|
+
// Fallback: usar nombre del archivo
|
|
264
|
+
const fileName = path.basename(filePath, '.table.cube');
|
|
265
|
+
const cleanName = fileName.replace(/^\d+[-_]?/, '');
|
|
266
|
+
if (cleanName && cleanName !== 'table') {
|
|
267
|
+
triggerNames.push(`before_insert_${cleanName}`);
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
return triggerNames;
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
/**
|
|
276
|
+
* Limpia la pantalla y muestra encabezado
|
|
277
|
+
* @param {string} title - Título principal
|
|
278
|
+
* @param {string} emoji - Emoji a mostrar
|
|
279
|
+
*/
|
|
280
|
+
showHeader(title, emoji = '🔄') {
|
|
281
|
+
console.clear();
|
|
282
|
+
console.log(`\n${emoji} ${chalk.green.bold(title)}`);
|
|
283
|
+
console.log(chalk.gray('─'.repeat(50)));
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
module.exports = ProgressIndicator;
|