From 597d8ae9481a098ddcfd4d4c8e454d05483c6ed1 Mon Sep 17 00:00:00 2001 From: Nick Zeng Date: Thu, 7 May 2026 14:21:30 +0800 Subject: [PATCH] add daily paid view --- ...00200_create_orders_daily_by_paid_view.php | 69 +++++++++++++++++++ .../System/MaterializedViewSmokeTest.php | 69 +++++++++++++++++++ 2 files changed, 138 insertions(+) create mode 100644 backend/migrations/2026_05_07_100200_create_orders_daily_by_paid_view.php create mode 100644 backend/test/Cases/Integration/System/MaterializedViewSmokeTest.php diff --git a/backend/migrations/2026_05_07_100200_create_orders_daily_by_paid_view.php b/backend/migrations/2026_05_07_100200_create_orders_daily_by_paid_view.php new file mode 100644 index 0000000..d9b9468 --- /dev/null +++ b/backend/migrations/2026_05_07_100200_create_orders_daily_by_paid_view.php @@ -0,0 +1,69 @@ + INTERVAL '3 days', + end_offset => INTERVAL '1 hour', + schedule_interval => INTERVAL '1 hour' +); +SQL); + } + + public function down(): void + { + // 先 remove policy,再 drop 视图 CASCADE。 + // if_exists => true 处理 by_created 视图已被 P22.1 down CASCADE 间接带走的情况。 + Db::statement("SELECT remove_continuous_aggregate_policy('orders_daily_by_created', if_exists => true)"); + + // CASCADE 一并 drop UNIQUE 索引和 5 复合索引。 + Db::statement('DROP MATERIALIZED VIEW IF EXISTS orders_daily_by_paid CASCADE'); + } +}; diff --git a/backend/test/Cases/Integration/System/MaterializedViewSmokeTest.php b/backend/test/Cases/Integration/System/MaterializedViewSmokeTest.php new file mode 100644 index 0000000..1173f1c --- /dev/null +++ b/backend/test/Cases/Integration/System/MaterializedViewSmokeTest.php @@ -0,0 +1,69 @@ + 0) { + return $callback(); + } + + $result = null; + $exception = null; + \Swoole\Coroutine\run(static function () use ($callback, &$result, &$exception): void { + try { + $result = $callback(); + } catch (\Throwable $e) { + $exception = $e; + } + }); + if ($exception !== null) { + throw $exception; + } + return $result; + } + + public function test_orders_daily_by_paid_matview_exists(): void + { + $rows = $this->runInCoroutine(static fn () => Db::select( + "SELECT matviewname FROM pg_matviews WHERE matviewname = 'orders_daily_by_paid'" + )); + $this->assertCount(1, $rows); + } + + public function test_orders_daily_by_paid_has_six_indexes(): void + { + $rows = $this->runInCoroutine(static fn () => Db::select( + "SELECT indexname FROM pg_indexes WHERE tablename = 'orders_daily_by_paid'" + )); + $this->assertCount(6, $rows, '应有 1 UNIQUE + 5 复合 = 6 个索引'); + } + + public function test_orders_daily_by_created_refresh_policy_registered(): void + { + $rows = $this->runInCoroutine(static fn () => Db::select( + "SELECT job_id FROM timescaledb_information.jobs + WHERE proc_name = 'policy_refresh_continuous_aggregate' + AND hypertable_name = 'orders_daily_by_created'" + )); + $this->assertCount(1, $rows); + } +}