203 lines
7.1 KiB
JavaScript
203 lines
7.1 KiB
JavaScript
#!/usr/bin/env node
|
||
|
||
/**
|
||
* Media Library Database Test Script
|
||
* Tests all database operations for uploads and folders
|
||
*/
|
||
|
||
const { pool } = require("./config/database");
|
||
const logger = require("./config/logger");
|
||
|
||
async function testDatabaseOperations() {
|
||
console.log("\n🧪 Testing Media Library Database Operations\n");
|
||
console.log("=".repeat(60));
|
||
|
||
try {
|
||
// Test 1: Check database connection
|
||
console.log("\n1️⃣ Testing Database Connection...");
|
||
const connectionTest = await pool.query("SELECT NOW()");
|
||
console.log(" ✅ Database connected:", connectionTest.rows[0].now);
|
||
|
||
// Test 2: Check uploads table structure
|
||
console.log("\n2️⃣ Checking uploads table structure...");
|
||
const uploadsSchema = await pool.query(`
|
||
SELECT column_name, data_type, is_nullable
|
||
FROM information_schema.columns
|
||
WHERE table_name = 'uploads'
|
||
ORDER BY ordinal_position
|
||
`);
|
||
console.log(" ✅ Uploads table columns:");
|
||
uploadsSchema.rows.forEach((col) => {
|
||
console.log(
|
||
` - ${col.column_name} (${col.data_type}, nullable: ${col.is_nullable})`
|
||
);
|
||
});
|
||
|
||
// Test 3: Check media_folders table structure
|
||
console.log("\n3️⃣ Checking media_folders table structure...");
|
||
const foldersSchema = await pool.query(`
|
||
SELECT column_name, data_type, is_nullable
|
||
FROM information_schema.columns
|
||
WHERE table_name = 'media_folders'
|
||
ORDER BY ordinal_position
|
||
`);
|
||
console.log(" ✅ Media folders table columns:");
|
||
foldersSchema.rows.forEach((col) => {
|
||
console.log(
|
||
` - ${col.column_name} (${col.data_type}, nullable: ${col.is_nullable})`
|
||
);
|
||
});
|
||
|
||
// Test 4: Check foreign key constraints
|
||
console.log("\n4️⃣ Checking foreign key constraints...");
|
||
const constraints = await pool.query(`
|
||
SELECT
|
||
tc.constraint_name,
|
||
tc.table_name,
|
||
kcu.column_name,
|
||
ccu.table_name AS foreign_table_name,
|
||
ccu.column_name AS foreign_column_name
|
||
FROM information_schema.table_constraints AS tc
|
||
JOIN information_schema.key_column_usage AS kcu
|
||
ON tc.constraint_name = kcu.constraint_name
|
||
AND tc.table_schema = kcu.table_schema
|
||
JOIN information_schema.constraint_column_usage AS ccu
|
||
ON ccu.constraint_name = tc.constraint_name
|
||
AND ccu.table_schema = tc.table_schema
|
||
WHERE tc.constraint_type = 'FOREIGN KEY'
|
||
AND tc.table_name IN ('uploads', 'media_folders')
|
||
`);
|
||
console.log(" ✅ Foreign key constraints:");
|
||
constraints.rows.forEach((fk) => {
|
||
console.log(
|
||
` - ${fk.table_name}.${fk.column_name} → ${fk.foreign_table_name}.${fk.foreign_column_name}`
|
||
);
|
||
});
|
||
|
||
// Test 5: Count existing data
|
||
console.log("\n5️⃣ Counting existing data...");
|
||
const fileCount = await pool.query("SELECT COUNT(*) as count FROM uploads");
|
||
const folderCount = await pool.query(
|
||
"SELECT COUNT(*) as count FROM media_folders"
|
||
);
|
||
console.log(` ✅ Total files: ${fileCount.rows[0].count}`);
|
||
console.log(` ✅ Total folders: ${folderCount.rows[0].count}`);
|
||
|
||
// Test 6: List all files
|
||
if (parseInt(fileCount.rows[0].count) > 0) {
|
||
console.log("\n6️⃣ Listing all files in database...");
|
||
const files = await pool.query(`
|
||
SELECT id, original_name, file_size, folder_id, uploaded_by, created_at
|
||
FROM uploads
|
||
ORDER BY created_at DESC
|
||
LIMIT 10
|
||
`);
|
||
console.log(" ✅ Recent files:");
|
||
files.rows.forEach((file) => {
|
||
const size = (file.file_size / 1024).toFixed(2) + " KB";
|
||
const folder = file.folder_id ? `Folder #${file.folder_id}` : "Root";
|
||
console.log(
|
||
` - [ID: ${file.id}] ${file.original_name} (${size}) - ${folder}`
|
||
);
|
||
});
|
||
}
|
||
|
||
// Test 7: List all folders
|
||
if (parseInt(folderCount.rows[0].count) > 0) {
|
||
console.log("\n7️⃣ Listing all folders in database...");
|
||
const folders = await pool.query(`
|
||
SELECT id, name, parent_id, created_by, created_at,
|
||
(SELECT COUNT(*) FROM uploads WHERE folder_id = media_folders.id) as file_count
|
||
FROM media_folders
|
||
ORDER BY created_at DESC
|
||
`);
|
||
console.log(" ✅ Folders:");
|
||
folders.rows.forEach((folder) => {
|
||
const parent = folder.parent_id
|
||
? `Parent #${folder.parent_id}`
|
||
: "Root";
|
||
console.log(
|
||
` - [ID: ${folder.id}] ${folder.name} (${folder.file_count} files) - ${parent}`
|
||
);
|
||
});
|
||
}
|
||
|
||
// Test 8: Test folder query with file counts
|
||
console.log("\n8️⃣ Testing folder query with file counts...");
|
||
const foldersWithCounts = await pool.query(`
|
||
SELECT
|
||
mf.*,
|
||
COUNT(u.id) as file_count
|
||
FROM media_folders mf
|
||
LEFT JOIN uploads u ON u.folder_id = mf.id
|
||
GROUP BY mf.id
|
||
ORDER BY mf.created_at DESC
|
||
`);
|
||
console.log(
|
||
` ✅ Query returned ${foldersWithCounts.rows.length} folders with accurate file counts`
|
||
);
|
||
|
||
// Test 9: Test cascade delete (dry run)
|
||
console.log("\n9️⃣ Testing cascade delete rules...");
|
||
const cascadeRules = await pool.query(`
|
||
SELECT
|
||
tc.constraint_name,
|
||
rc.delete_rule
|
||
FROM information_schema.table_constraints tc
|
||
JOIN information_schema.referential_constraints rc
|
||
ON tc.constraint_name = rc.constraint_name
|
||
WHERE tc.table_name IN ('uploads', 'media_folders')
|
||
AND tc.constraint_type = 'FOREIGN KEY'
|
||
`);
|
||
console.log(" ✅ Delete rules:");
|
||
cascadeRules.rows.forEach((rule) => {
|
||
console.log(` - ${rule.constraint_name}: ${rule.delete_rule}`);
|
||
});
|
||
|
||
// Test 10: Verify indexes
|
||
console.log("\n🔟 Checking database indexes...");
|
||
const indexes = await pool.query(`
|
||
SELECT
|
||
tablename,
|
||
indexname,
|
||
indexdef
|
||
FROM pg_indexes
|
||
WHERE tablename IN ('uploads', 'media_folders')
|
||
AND schemaname = 'public'
|
||
ORDER BY tablename, indexname
|
||
`);
|
||
console.log(" ✅ Indexes:");
|
||
indexes.rows.forEach((idx) => {
|
||
console.log(` - ${idx.tablename}.${idx.indexname}`);
|
||
});
|
||
|
||
console.log("\n" + "=".repeat(60));
|
||
console.log("✅ All database tests passed successfully!\n");
|
||
|
||
console.log("📊 Summary:");
|
||
console.log(` - Database: Connected and operational`);
|
||
console.log(
|
||
` - Tables: uploads (${uploadsSchema.rows.length} columns), media_folders (${foldersSchema.rows.length} columns)`
|
||
);
|
||
console.log(
|
||
` - Data: ${fileCount.rows[0].count} files, ${folderCount.rows[0].count} folders`
|
||
);
|
||
console.log(
|
||
` - Constraints: ${constraints.rows.length} foreign keys configured`
|
||
);
|
||
console.log(` - Indexes: ${indexes.rows.length} indexes for performance`);
|
||
console.log(
|
||
"\n✅ Media library database is properly configured and operational!\n"
|
||
);
|
||
} catch (error) {
|
||
console.error("\n❌ Database test failed:", error.message);
|
||
console.error("Stack trace:", error.stack);
|
||
process.exit(1);
|
||
} finally {
|
||
await pool.end();
|
||
}
|
||
}
|
||
|
||
// Run tests
|
||
testDatabaseOperations();
|