232 lines
7.8 KiB
JavaScript
Executable File
232 lines
7.8 KiB
JavaScript
Executable File
#!/usr/bin/env node
|
|
|
|
/**
|
|
* Chat Database Migration Verification Script
|
|
*
|
|
* This script verifies that the chat database migration was successful
|
|
* by comparing record counts and testing basic functionality.
|
|
*/
|
|
|
|
require('dotenv').config({ path: '../.env' });
|
|
const { Pool } = require('pg');
|
|
|
|
// Database configuration
|
|
const pool = new Pool({
|
|
host: process.env.CHAT_DB_HOST || 'localhost',
|
|
user: process.env.CHAT_DB_USER || 'rocketchat_user',
|
|
password: process.env.CHAT_DB_PASSWORD,
|
|
database: process.env.CHAT_DB_NAME || 'rocketchat_converted',
|
|
port: process.env.CHAT_DB_PORT || 5432,
|
|
});
|
|
|
|
const originalStats = process.argv[2] ? JSON.parse(process.argv[2]) : null;
|
|
|
|
async function verifyMigration() {
|
|
console.log('🔍 Starting migration verification...\n');
|
|
|
|
try {
|
|
// Test basic connection
|
|
console.log('🔗 Testing database connection...');
|
|
const versionResult = await pool.query('SELECT version()');
|
|
console.log('✅ Database connection successful');
|
|
console.log(` PostgreSQL version: ${versionResult.rows[0].version.split(' ')[1]}\n`);
|
|
|
|
// Get table statistics
|
|
console.log('📊 Checking table statistics...');
|
|
const statsResult = await pool.query(`
|
|
SELECT
|
|
tablename,
|
|
n_live_tup as row_count,
|
|
n_dead_tup as dead_rows,
|
|
schemaname
|
|
FROM pg_stat_user_tables
|
|
WHERE schemaname = 'public'
|
|
ORDER BY n_live_tup DESC
|
|
`);
|
|
|
|
if (statsResult.rows.length === 0) {
|
|
console.log('❌ No tables found! Migration may have failed.');
|
|
return false;
|
|
}
|
|
|
|
console.log('📋 Table Statistics:');
|
|
console.log(' Table Name | Row Count | Dead Rows');
|
|
console.log(' -------------------|-----------|----------');
|
|
|
|
let totalRows = 0;
|
|
const tableStats = {};
|
|
|
|
for (const row of statsResult.rows) {
|
|
const rowCount = parseInt(row.row_count) || 0;
|
|
const deadRows = parseInt(row.dead_rows) || 0;
|
|
totalRows += rowCount;
|
|
tableStats[row.tablename] = rowCount;
|
|
|
|
console.log(` ${row.tablename.padEnd(18)} | ${rowCount.toString().padStart(9)} | ${deadRows.toString().padStart(8)}`);
|
|
}
|
|
|
|
console.log(`\n Total rows across all tables: ${totalRows}\n`);
|
|
|
|
// Verify critical tables exist and have data
|
|
const criticalTables = ['users', 'message', 'room'];
|
|
console.log('🔑 Checking critical tables...');
|
|
|
|
for (const table of criticalTables) {
|
|
if (tableStats[table] > 0) {
|
|
console.log(`✅ ${table}: ${tableStats[table]} rows`);
|
|
} else if (tableStats[table] === 0) {
|
|
console.log(`⚠️ ${table}: table exists but is empty`);
|
|
} else {
|
|
console.log(`❌ ${table}: table not found`);
|
|
return false;
|
|
}
|
|
}
|
|
|
|
// Test specific functionality
|
|
console.log('\n🧪 Testing specific functionality...');
|
|
|
|
// Test users table
|
|
const userTest = await pool.query(`
|
|
SELECT COUNT(*) as total_users,
|
|
COUNT(*) FILTER (WHERE active = true) as active_users,
|
|
COUNT(*) FILTER (WHERE type = 'user') as regular_users
|
|
FROM users
|
|
`);
|
|
|
|
if (userTest.rows[0]) {
|
|
const { total_users, active_users, regular_users } = userTest.rows[0];
|
|
console.log(`✅ Users: ${total_users} total, ${active_users} active, ${regular_users} regular users`);
|
|
}
|
|
|
|
// Test messages table
|
|
const messageTest = await pool.query(`
|
|
SELECT COUNT(*) as total_messages,
|
|
COUNT(DISTINCT rid) as unique_rooms,
|
|
MIN(ts) as oldest_message,
|
|
MAX(ts) as newest_message
|
|
FROM message
|
|
`);
|
|
|
|
if (messageTest.rows[0]) {
|
|
const { total_messages, unique_rooms, oldest_message, newest_message } = messageTest.rows[0];
|
|
console.log(`✅ Messages: ${total_messages} total across ${unique_rooms} rooms`);
|
|
if (oldest_message && newest_message) {
|
|
console.log(` Date range: ${oldest_message.toISOString().split('T')[0]} to ${newest_message.toISOString().split('T')[0]}`);
|
|
}
|
|
}
|
|
|
|
// Test rooms table
|
|
const roomTest = await pool.query(`
|
|
SELECT COUNT(*) as total_rooms,
|
|
COUNT(*) FILTER (WHERE t = 'c') as channels,
|
|
COUNT(*) FILTER (WHERE t = 'p') as private_groups,
|
|
COUNT(*) FILTER (WHERE t = 'd') as direct_messages
|
|
FROM room
|
|
`);
|
|
|
|
if (roomTest.rows[0]) {
|
|
const { total_rooms, channels, private_groups, direct_messages } = roomTest.rows[0];
|
|
console.log(`✅ Rooms: ${total_rooms} total (${channels} channels, ${private_groups} private, ${direct_messages} DMs)`);
|
|
}
|
|
|
|
// Test file uploads if table exists
|
|
if (tableStats.uploads > 0) {
|
|
const uploadTest = await pool.query(`
|
|
SELECT COUNT(*) as total_uploads,
|
|
COUNT(DISTINCT typegroup) as file_types,
|
|
pg_size_pretty(SUM(size)) as total_size
|
|
FROM uploads
|
|
WHERE size IS NOT NULL
|
|
`);
|
|
|
|
if (uploadTest.rows[0]) {
|
|
const { total_uploads, file_types, total_size } = uploadTest.rows[0];
|
|
console.log(`✅ Uploads: ${total_uploads} files, ${file_types} types, ${total_size || 'unknown size'}`);
|
|
}
|
|
}
|
|
|
|
// Test server health endpoint simulation
|
|
console.log('\n🏥 Testing application endpoints simulation...');
|
|
|
|
try {
|
|
const healthTest = await pool.query(`
|
|
SELECT
|
|
(SELECT COUNT(*) FROM users WHERE active = true) as active_users,
|
|
(SELECT COUNT(*) FROM message) as total_messages,
|
|
(SELECT COUNT(*) FROM room) as total_rooms
|
|
`);
|
|
|
|
if (healthTest.rows[0]) {
|
|
const stats = healthTest.rows[0];
|
|
console.log('✅ Health check simulation passed');
|
|
console.log(` Active users: ${stats.active_users}`);
|
|
console.log(` Total messages: ${stats.total_messages}`);
|
|
console.log(` Total rooms: ${stats.total_rooms}`);
|
|
}
|
|
} catch (error) {
|
|
console.log(`⚠️ Health check simulation failed: ${error.message}`);
|
|
}
|
|
|
|
// Check indexes
|
|
console.log('\n📇 Checking database indexes...');
|
|
const indexResult = await pool.query(`
|
|
SELECT
|
|
schemaname,
|
|
tablename,
|
|
indexname,
|
|
indexdef
|
|
FROM pg_indexes
|
|
WHERE schemaname = 'public'
|
|
ORDER BY tablename, indexname
|
|
`);
|
|
|
|
const indexesByTable = {};
|
|
for (const idx of indexResult.rows) {
|
|
if (!indexesByTable[idx.tablename]) {
|
|
indexesByTable[idx.tablename] = [];
|
|
}
|
|
indexesByTable[idx.tablename].push(idx.indexname);
|
|
}
|
|
|
|
for (const [table, indexes] of Object.entries(indexesByTable)) {
|
|
console.log(` ${table}: ${indexes.length} indexes`);
|
|
}
|
|
|
|
console.log('\n🎉 Migration verification completed successfully!');
|
|
console.log('\n✅ Summary:');
|
|
console.log(` - Database connection: Working`);
|
|
console.log(` - Tables created: ${statsResult.rows.length}`);
|
|
console.log(` - Total data rows: ${totalRows}`);
|
|
console.log(` - Critical tables: All present`);
|
|
console.log(` - Indexes: ${indexResult.rows.length} total`);
|
|
|
|
console.log('\n🚀 Next steps:');
|
|
console.log(' 1. Update your application configuration');
|
|
console.log(' 2. Start your chat server');
|
|
console.log(' 3. Test chat functionality in the browser');
|
|
console.log(' 4. Monitor logs for any issues');
|
|
|
|
return true;
|
|
|
|
} catch (error) {
|
|
console.error('❌ Migration verification failed:', error.message);
|
|
console.error('\n🔧 Troubleshooting steps:');
|
|
console.error(' 1. Check database connection settings');
|
|
console.error(' 2. Verify database and user exist');
|
|
console.error(' 3. Check PostgreSQL logs');
|
|
console.error(' 4. Ensure import completed without errors');
|
|
return false;
|
|
} finally {
|
|
await pool.end();
|
|
}
|
|
}
|
|
|
|
// Run verification
|
|
if (require.main === module) {
|
|
verifyMigration().then(success => {
|
|
process.exit(success ? 0 : 1);
|
|
});
|
|
}
|
|
|
|
module.exports = { verifyMigration };
|