102 lines
3.9 KiB
JavaScript
102 lines
3.9 KiB
JavaScript
const pg = require('pg');
|
|
const { S3Client, ListBucketsCommand, ListObjectsV2Command } = require('@aws-sdk/client-s3');
|
|
|
|
const DATABASE_URL = process.env.DATABASE_URL || 'postgresql://edumanager:EduManager2026!Seguro@postgres:5432/edumanager';
|
|
const pool = new pg.Pool({ connectionString: DATABASE_URL });
|
|
|
|
const MINIO_ENDPOINT = process.env.MINIO_ENDPOINT || 'minio';
|
|
const MINIO_PORT = process.env.MINIO_PORT || '9000';
|
|
const MINIO_ACCESS_KEY = process.env.MINIO_ACCESS_KEY || 'minioadmin';
|
|
const MINIO_SECRET_KEY = process.env.MINIO_SECRET_KEY || 'MiniO2026!Seguro';
|
|
|
|
const s3Client = new S3Client({
|
|
endpoint: `http://${MINIO_ENDPOINT}:${MINIO_PORT}`,
|
|
region: 'us-east-1',
|
|
credentials: {
|
|
accessKeyId: MINIO_ACCESS_KEY,
|
|
secretAccessKey: MINIO_SECRET_KEY,
|
|
},
|
|
forcePathStyle: true,
|
|
});
|
|
|
|
async function main() {
|
|
try {
|
|
console.log('--- 1. BUSCANDO TODAS AS TABELAS E DADOS DO POSTGRESQL ---');
|
|
const { rows: tables } = await pool.query("SELECT table_name FROM information_schema.tables WHERE table_schema = 'public'");
|
|
console.log(`Encontradas ${tables.length} tabelas no banco de dados.`);
|
|
|
|
let dbContentDump = '';
|
|
for (const t of tables) {
|
|
const tableName = t.table_name;
|
|
try {
|
|
const { rows } = await pool.query(`SELECT * FROM "${tableName}"`);
|
|
dbContentDump += JSON.stringify(rows) + ' ';
|
|
} catch (err) {
|
|
console.warn(`Aviso: não foi possível ler a tabela ${tableName}:`, err.message);
|
|
}
|
|
}
|
|
console.log(`Dumping de referências concluído (${(dbContentDump.length / 1024 / 1024).toFixed(2)} MB).`);
|
|
|
|
console.log('\n--- 2. LISTANDO ARQUIVOS NO STORAGE MINIO ---');
|
|
const bucketsData = await s3Client.send(new ListBucketsCommand({}));
|
|
const buckets = bucketsData.Buckets || [];
|
|
console.log(`Encontrados ${buckets.length} buckets no MinIO.`);
|
|
|
|
const allFiles = [];
|
|
let totalStorageSize = 0;
|
|
|
|
for (const bucket of buckets) {
|
|
try {
|
|
const objects = await s3Client.send(new ListObjectsV2Command({ Bucket: bucket.Name }));
|
|
const contents = objects.Contents || [];
|
|
console.log(`Bucket [${bucket.Name}]: ${contents.length} arquivos encontrados.`);
|
|
for (const obj of contents) {
|
|
totalStorageSize += obj.Size || 0;
|
|
allFiles.push({
|
|
bucket: bucket.Name,
|
|
key: obj.Key,
|
|
size: obj.Size || 0,
|
|
url: `/storage/${bucket.Name}/${obj.Key}`
|
|
});
|
|
}
|
|
} catch (err) {
|
|
console.warn(`Não foi possível listar objetos do bucket ${bucket.Name}:`, err.message);
|
|
}
|
|
}
|
|
console.log(`Total geral no MinIO: ${(totalStorageSize / 1024 / 1024).toFixed(2)} MB (${allFiles.length} arquivos).`);
|
|
|
|
console.log('\n--- 3. FILTRANDO ARQUIVOS NÃO UTILIZADOS ---');
|
|
const unusedFiles = [];
|
|
const usedFiles = [];
|
|
|
|
for (const file of allFiles) {
|
|
const hasReference = dbContentDump.includes(file.key) || dbContentDump.includes(file.url);
|
|
if (hasReference) {
|
|
usedFiles.push(file);
|
|
} else {
|
|
unusedFiles.push(file);
|
|
}
|
|
}
|
|
|
|
const totalUnusedSize = unusedFiles.reduce((acc, curr) => acc + curr.size, 0);
|
|
console.log(`\nRESULTADOS:`);
|
|
console.log(`- Arquivos em Uso: ${usedFiles.length}`);
|
|
console.log(`- Arquivos Órfãos (NÃO usados): ${unusedFiles.length}`);
|
|
console.log(`- Espaço sendo desperdiçado: ${(totalUnusedSize / 1024 / 1024).toFixed(2)} MB`);
|
|
|
|
if (unusedFiles.length > 0) {
|
|
console.log('\n--- LISTA DE ARQUIVOS NÃO UTILIZADOS ---');
|
|
unusedFiles.forEach((file, index) => {
|
|
console.log(`${index + 1}. Bucket: [${file.bucket}] | Arquivo: ${file.key} | Tamanho: ${(file.size / 1024).toFixed(2)} KB`);
|
|
});
|
|
} else {
|
|
console.log('\nExcelente! Todos os arquivos armazenados no MinIO estão sendo referenciados no banco de dados!');
|
|
}
|
|
} catch (error) {
|
|
console.error('Erro na execução:', error);
|
|
} finally {
|
|
await pool.end();
|
|
}
|
|
}
|
|
main();
|