- Add comprehensive health check system with multiple endpoints - Add Prometheus metrics endpoint - Add production logging configurations (5 strategies) - Add complete deployment documentation suite: * QUICKSTART.md - 30-minute deployment guide * DEPLOYMENT_CHECKLIST.md - Printable verification checklist * DEPLOYMENT_WORKFLOW.md - Complete deployment lifecycle * PRODUCTION_DEPLOYMENT.md - Comprehensive technical reference * production-logging.md - Logging configuration guide * ANSIBLE_DEPLOYMENT.md - Infrastructure as Code automation * README.md - Navigation hub * DEPLOYMENT_SUMMARY.md - Executive summary - Add deployment scripts and automation - Add DEPLOYMENT_PLAN.md - Concrete plan for immediate deployment - Update README with production-ready features All production infrastructure is now complete and ready for deployment.
159 lines
5.9 KiB
PHP
159 lines
5.9 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
require_once __DIR__ . '/../../src/Framework/Database/Schema/MaterializedView.php';
|
|
require_once __DIR__ . '/../../src/Framework/Database/MaterializedViews/MaterializedViewService.php';
|
|
|
|
use App\Framework\Database\Schema\MaterializedView;
|
|
use App\Framework\Database\MaterializedViews\MaterializedViewService;
|
|
|
|
echo "Testing PostgreSQL Materialized Views\n";
|
|
echo "======================================\n\n";
|
|
|
|
try {
|
|
$pdo = new PDO(
|
|
'pgsql:host=db;dbname=michaelschiemer',
|
|
'postgres',
|
|
'StartSimple2024!'
|
|
);
|
|
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
|
|
|
|
echo "✅ Database connection established\n\n";
|
|
|
|
$service = new MaterializedViewService($pdo);
|
|
|
|
// Cleanup
|
|
echo "Cleanup...\n";
|
|
$pdo->exec("DROP TABLE IF EXISTS test_sales CASCADE");
|
|
$pdo->exec("DROP MATERIALIZED VIEW IF EXISTS sales_summary");
|
|
$pdo->exec("DROP MATERIALIZED VIEW IF EXISTS top_products");
|
|
echo "✅ Cleanup complete\n\n";
|
|
|
|
// Create test table
|
|
echo "Test 1: Create Test Data\n";
|
|
echo "=========================\n";
|
|
$pdo->exec("
|
|
CREATE TABLE test_sales (
|
|
id SERIAL PRIMARY KEY,
|
|
product_name VARCHAR(100),
|
|
category VARCHAR(50),
|
|
amount NUMERIC(10,2),
|
|
sale_date DATE
|
|
)
|
|
");
|
|
|
|
$pdo->exec("
|
|
INSERT INTO test_sales (product_name, category, amount, sale_date) VALUES
|
|
('Laptop', 'Electronics', 1200.00, '2025-01-10'),
|
|
('Mouse', 'Electronics', 25.00, '2025-01-10'),
|
|
('Desk', 'Furniture', 350.00, '2025-01-11'),
|
|
('Chair', 'Furniture', 150.00, '2025-01-11'),
|
|
('Keyboard', 'Electronics', 75.00, '2025-01-12')
|
|
");
|
|
echo "✅ Test table created with 5 sales records\n\n";
|
|
|
|
// Test 2: Create Materialized View
|
|
echo "Test 2: Create Materialized View\n";
|
|
echo "=================================\n";
|
|
|
|
$view = new MaterializedView(
|
|
'sales_summary',
|
|
"SELECT category, COUNT(*) as total_sales, SUM(amount) as total_amount FROM test_sales GROUP BY category"
|
|
);
|
|
|
|
$service->create($view);
|
|
echo "✅ Materialized view 'sales_summary' created\n";
|
|
|
|
// Query materialized view
|
|
$stmt = $pdo->query("SELECT * FROM sales_summary ORDER BY category");
|
|
$results = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
|
echo " Initial data:\n";
|
|
foreach ($results as $row) {
|
|
echo " - {$row['category']}: {$row['total_sales']} sales, Total: €{$row['total_amount']}\n";
|
|
}
|
|
echo "\n";
|
|
|
|
// Test 3: Add more data (materialized view doesn't auto-update)
|
|
echo "Test 3: Add Data (View Doesn't Auto-Update)\n";
|
|
echo "============================================\n";
|
|
|
|
$pdo->exec("INSERT INTO test_sales (product_name, category, amount, sale_date) VALUES ('Monitor', 'Electronics', 300.00, '2025-01-13')");
|
|
echo "✅ Added new sale (Electronics, €300)\n";
|
|
|
|
$stmt = $pdo->query("SELECT * FROM sales_summary WHERE category = 'Electronics'");
|
|
$before = $stmt->fetch(PDO::FETCH_ASSOC);
|
|
echo " Electronics BEFORE refresh: {$before['total_sales']} sales, €{$before['total_amount']}\n";
|
|
echo " (Should still show old data)\n\n";
|
|
|
|
// Test 4: Refresh Materialized View
|
|
echo "Test 4: REFRESH Materialized View\n";
|
|
echo "==================================\n";
|
|
|
|
$service->refresh('sales_summary');
|
|
echo "✅ Materialized view refreshed\n";
|
|
|
|
$stmt = $pdo->query("SELECT * FROM sales_summary WHERE category = 'Electronics'");
|
|
$after = $stmt->fetch(PDO::FETCH_ASSOC);
|
|
echo " Electronics AFTER refresh: {$after['total_sales']} sales, €{$after['total_amount']}\n";
|
|
echo ($after['total_amount'] > $before['total_amount']) ? "✅ Data updated after refresh\n" : "❌ Should have updated\n";
|
|
echo "\n";
|
|
|
|
// Test 5: Create view with index (for CONCURRENTLY refresh)
|
|
echo "Test 5: View With Index (Concurrent Refresh)\n";
|
|
echo "=============================================\n";
|
|
|
|
$topProductsView = new MaterializedView(
|
|
'top_products',
|
|
"SELECT product_name, amount FROM test_sales ORDER BY amount DESC LIMIT 3"
|
|
);
|
|
|
|
$service->create($topProductsView);
|
|
echo "✅ Materialized view 'top_products' created\n";
|
|
|
|
// Create unique index (required for CONCURRENTLY)
|
|
$pdo->exec("CREATE UNIQUE INDEX top_products_idx ON top_products (product_name)");
|
|
echo "✅ Unique index created\n";
|
|
|
|
// Concurrent refresh
|
|
$service->refresh('top_products', concurrently: true);
|
|
echo "✅ Concurrent refresh successful\n\n";
|
|
|
|
// Test 6: List all materialized views
|
|
echo "Test 6: List All Materialized Views\n";
|
|
echo "====================================\n";
|
|
|
|
$views = $service->listAll();
|
|
echo "✅ Found " . count($views) . " materialized views:\n";
|
|
foreach ($views as $v) {
|
|
echo " - {$v['name']} (has_indexes: " . ($v['has_indexes'] ? 'yes' : 'no') . ")\n";
|
|
}
|
|
echo "\n";
|
|
|
|
// Test 7: exists() check
|
|
echo "Test 7: exists() Check\n";
|
|
echo "======================\n";
|
|
echo $service->exists('sales_summary') ? "✅ sales_summary exists\n" : "❌ Should exist\n";
|
|
echo !$service->exists('non_existent') ? "✅ non_existent doesn't exist\n" : "❌ Should not exist\n";
|
|
echo "\n";
|
|
|
|
// Cleanup
|
|
echo "Cleanup...\n";
|
|
$pdo->exec("DROP TABLE IF EXISTS test_sales CASCADE");
|
|
echo "✅ Test data cleaned up\n";
|
|
|
|
echo "\n✅ All Materialized View tests passed!\n";
|
|
echo "\nSummary:\n";
|
|
echo "========\n";
|
|
echo "✅ CREATE MATERIALIZED VIEW works\n";
|
|
echo "✅ Materialized views store computed results\n";
|
|
echo "✅ REFRESH MATERIALIZED VIEW updates data\n";
|
|
echo "✅ REFRESH ... CONCURRENTLY works with unique index\n";
|
|
echo "✅ Listing and checking existence works\n";
|
|
|
|
} catch (\Exception $e) {
|
|
echo "❌ Error: " . $e->getMessage() . "\n";
|
|
echo "Stack trace:\n" . $e->getTraceAsString() . "\n";
|
|
exit(1);
|
|
}
|