From 74db0c15aec3fdb649b1d8df365851512b691b7e Mon Sep 17 00:00:00 2001 From: yangjianbo Date: Mon, 29 Dec 2025 19:24:29 +0800 Subject: [PATCH] =?UTF-8?q?chore(=E7=94=9F=E6=88=90=E4=BB=A3=E7=A0=81):=20?= =?UTF-8?q?=E6=9B=B4=E6=96=B0=20ent=20=E5=AE=A2=E6=88=B7=E7=AB=AF=E4=B8=8E?= =?UTF-8?q?=E4=BA=8B=E5=8A=A1=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 同步生成文件以匹配最新的 schema 与运行时变更 --- backend/ent/client.go | 28 ++++++++++++++++++++++++++++ backend/ent/generate.go | 3 ++- backend/ent/tx.go | 28 ++++++++++++++++++++++++++++ 3 files changed, 58 insertions(+), 1 deletion(-) diff --git a/backend/ent/client.go b/backend/ent/client.go index 00d992cc..113dc7ff 100644 --- a/backend/ent/client.go +++ b/backend/ent/client.go @@ -25,6 +25,8 @@ import ( "github.com/Wei-Shaw/sub2api/ent/user" "github.com/Wei-Shaw/sub2api/ent/userallowedgroup" "github.com/Wei-Shaw/sub2api/ent/usersubscription" + + stdsql "database/sql" ) // Client is the client that holds all ent builders. @@ -1948,3 +1950,29 @@ type ( UserAllowedGroup, UserSubscription []ent.Interceptor } ) + +// ExecContext 透传到底层 driver,用于在 ent 事务中执行原生 SQL(例如同步 legacy 字段)。 +// ExecContext allows calling the underlying ExecContext method of the driver if it is supported by it. +// See, database/sql#DB.ExecContext for more information. +func (c *config) ExecContext(ctx context.Context, query string, args ...any) (stdsql.Result, error) { + ex, ok := c.driver.(interface { + ExecContext(context.Context, string, ...any) (stdsql.Result, error) + }) + if !ok { + return nil, fmt.Errorf("Driver.ExecContext is not supported") + } + return ex.ExecContext(ctx, query, args...) +} + +// QueryContext 透传到底层 driver,用于在事务内执行原生查询并共享锁/一致性语义。 +// QueryContext allows calling the underlying QueryContext method of the driver if it is supported by it. +// See, database/sql#DB.QueryContext for more information. +func (c *config) QueryContext(ctx context.Context, query string, args ...any) (*stdsql.Rows, error) { + q, ok := c.driver.(interface { + QueryContext(context.Context, string, ...any) (*stdsql.Rows, error) + }) + if !ok { + return nil, fmt.Errorf("Driver.QueryContext is not supported") + } + return q.QueryContext(ctx, query, args...) +} diff --git a/backend/ent/generate.go b/backend/ent/generate.go index f2165ed8..ed48678f 100644 --- a/backend/ent/generate.go +++ b/backend/ent/generate.go @@ -1,3 +1,4 @@ package ent -//go:generate go run -mod=mod entgo.io/ent/cmd/ent generate --feature sql/upsert,intercept --idtype int64 ./schema +// 启用 sql/execquery 以生成 ExecContext/QueryContext 的透传接口,便于事务内执行原生 SQL。 +//go:generate go run -mod=mod entgo.io/ent/cmd/ent generate --feature sql/upsert,intercept,sql/execquery --idtype int64 ./schema diff --git a/backend/ent/tx.go b/backend/ent/tx.go index cf5b510d..fbb68edf 100644 --- a/backend/ent/tx.go +++ b/backend/ent/tx.go @@ -4,6 +4,8 @@ package ent import ( "context" + stdsql "database/sql" + "fmt" "sync" "entgo.io/ent/dialect" @@ -235,3 +237,29 @@ func (tx *txDriver) Query(ctx context.Context, query string, args, v any) error } var _ dialect.Driver = (*txDriver)(nil) + +// ExecContext 透传到底层事务,用于在 ent 事务中执行原生 SQL(与 ent 写入保持同一事务)。 +// ExecContext allows calling the underlying ExecContext method of the transaction if it is supported by it. +// See, database/sql#Tx.ExecContext for more information. +func (tx *txDriver) ExecContext(ctx context.Context, query string, args ...any) (stdsql.Result, error) { + ex, ok := tx.tx.(interface { + ExecContext(context.Context, string, ...any) (stdsql.Result, error) + }) + if !ok { + return nil, fmt.Errorf("Tx.ExecContext is not supported") + } + return ex.ExecContext(ctx, query, args...) +} + +// QueryContext 透传到底层事务,用于在 ent 事务中执行原生查询并共享锁语义。 +// QueryContext allows calling the underlying QueryContext method of the transaction if it is supported by it. +// See, database/sql#Tx.QueryContext for more information. +func (tx *txDriver) QueryContext(ctx context.Context, query string, args ...any) (*stdsql.Rows, error) { + q, ok := tx.tx.(interface { + QueryContext(context.Context, string, ...any) (*stdsql.Rows, error) + }) + if !ok { + return nil, fmt.Errorf("Tx.QueryContext is not supported") + } + return q.QueryContext(ctx, query, args...) +}