mirror of
https://github.com/truewhile/MeBox.git
synced 2026-10-12 08:16:37 +08:00
66 lines
2.2 KiB
Go
66 lines
2.2 KiB
Go
package repository
|
|
|
|
import (
|
|
"context"
|
|
"strings"
|
|
"testing"
|
|
|
|
"github.com/truewhile/MeBox/internal/model"
|
|
)
|
|
|
|
// TestHistoryProgressUpsertQualifiesConflictWhereColumns 守住 PostgreSQL 下进度上报
|
|
// 的 upsert 语句合法性。
|
|
//
|
|
// ON CONFLICT DO UPDATE 的 WHERE 里如果不给列名加表限定,PostgreSQL 会因为这些列
|
|
// 同时出现在本次插入的行里而拒绝该语句:
|
|
//
|
|
// column reference "session_started_at_ms" is ambiguous (SQLSTATE 42702)
|
|
//
|
|
// 后果是 POST /api/history 全部 500,观看进度与续播完全存不下来。SQLite 不做这项
|
|
// 检查(旧写法在 SQLite 下一直正常),所以只能在 PostgreSQL 方言下断言。
|
|
func TestHistoryProgressUpsertQualifiesConflictWhereColumns(t *testing.T) {
|
|
repos, rec := newPostgresDryRunRepos(t)
|
|
ctx := context.Background()
|
|
|
|
if err := repos.History.UpsertProgress(ctx, &model.PlaybackHistory{
|
|
UserID: "u-1",
|
|
MediaID: "m-1",
|
|
PositionMs: 1_000,
|
|
DurationMs: 2_000,
|
|
SessionID: "session-1",
|
|
SessionStartedAtMs: 111,
|
|
Sequence: 2,
|
|
}); err != nil {
|
|
t.Fatalf("build upsert: %v", err)
|
|
}
|
|
|
|
sql := rec.all()
|
|
if strings.TrimSpace(sql) == "" {
|
|
t.Fatal("no SQL captured from UpsertProgress")
|
|
}
|
|
if !strings.Contains(sql, "ON CONFLICT") {
|
|
t.Fatalf("expected an ON CONFLICT upsert, got:\n%s", sql)
|
|
}
|
|
|
|
// 只看 ON CONFLICT 之后的部分:SET 的赋值目标和 CASE 里的 duration_ms 引用
|
|
// 属于另一套语法规则,不在这里断言。
|
|
conflict := sql[strings.Index(sql, "ON CONFLICT"):]
|
|
whereIdx := strings.Index(conflict, " WHERE ")
|
|
if whereIdx < 0 {
|
|
t.Fatalf("ON CONFLICT clause has no DO UPDATE ... WHERE guard:\n%s", sql)
|
|
}
|
|
where := conflict[whereIdx:]
|
|
|
|
for _, want := range []string{
|
|
`"playback_histories"."session_started_at_ms"`,
|
|
`"playback_histories"."sequence"`,
|
|
} {
|
|
if !strings.Contains(where, want) {
|
|
t.Fatalf("DO UPDATE WHERE is missing the table-qualified %s; it is ambiguous on PostgreSQL:\n%s", want, sql)
|
|
}
|
|
}
|
|
if strings.Contains(where, `("session_started_at_ms"`) || strings.Contains(where, ` AND "sequence"`) {
|
|
t.Fatalf("DO UPDATE WHERE still references unqualified columns:\n%s", sql)
|
|
}
|
|
}
|