Commit 7331220e authored by Edric Li's avatar Edric Li
Browse files

Merge remote-tracking branch 'upstream/main'

# Conflicts:
#	frontend/src/components/account/CreateAccountModal.vue
parents fb86002e 4f13c8de
...@@ -33,10 +33,11 @@ func (Group) Mixin() []ent.Mixin { ...@@ -33,10 +33,11 @@ func (Group) Mixin() []ent.Mixin {
func (Group) Fields() []ent.Field { func (Group) Fields() []ent.Field {
return []ent.Field{ return []ent.Field{
// 唯一约束通过部分索引实现(WHERE deleted_at IS NULL),支持软删除后重用
// 见迁移文件 016_soft_delete_partial_unique_indexes.sql
field.String("name"). field.String("name").
MaxLen(100). MaxLen(100).
NotEmpty(). NotEmpty(),
Unique(),
field.String("description"). field.String("description").
Optional(). Optional().
Nillable(). Nillable().
...@@ -69,6 +70,8 @@ func (Group) Fields() []ent.Field { ...@@ -69,6 +70,8 @@ func (Group) Fields() []ent.Field {
Optional(). Optional().
Nillable(). Nillable().
SchemaType(map[string]string{dialect.Postgres: "decimal(20,8)"}), SchemaType(map[string]string{dialect.Postgres: "decimal(20,8)"}),
field.Int("default_validity_days").
Default(30),
} }
} }
...@@ -77,6 +80,7 @@ func (Group) Edges() []ent.Edge { ...@@ -77,6 +80,7 @@ func (Group) Edges() []ent.Edge {
edge.To("api_keys", ApiKey.Type), edge.To("api_keys", ApiKey.Type),
edge.To("redeem_codes", RedeemCode.Type), edge.To("redeem_codes", RedeemCode.Type),
edge.To("subscriptions", UserSubscription.Type), edge.To("subscriptions", UserSubscription.Type),
edge.To("usage_logs", UsageLog.Type),
edge.From("accounts", Account.Type). edge.From("accounts", Account.Type).
Ref("groups"). Ref("groups").
Through("account_groups", AccountGroup.Type), Through("account_groups", AccountGroup.Type),
...@@ -88,7 +92,7 @@ func (Group) Edges() []ent.Edge { ...@@ -88,7 +92,7 @@ func (Group) Edges() []ent.Edge {
func (Group) Indexes() []ent.Index { func (Group) Indexes() []ent.Index {
return []ent.Index{ return []ent.Index{
index.Fields("name").Unique(), // name 字段已在 Fields() 中声明 Unique(),无需重复索引
index.Fields("status"), index.Fields("status"),
index.Fields("platform"), index.Fields("platform"),
index.Fields("subscription_type"), index.Fields("subscription_type"),
......
...@@ -12,6 +12,7 @@ import ( ...@@ -12,6 +12,7 @@ import (
"entgo.io/ent/dialect/sql" "entgo.io/ent/dialect/sql"
"entgo.io/ent/schema/field" "entgo.io/ent/schema/field"
"entgo.io/ent/schema/mixin" "entgo.io/ent/schema/mixin"
dbent "github.com/Wei-Shaw/sub2api/ent"
"github.com/Wei-Shaw/sub2api/ent/intercept" "github.com/Wei-Shaw/sub2api/ent/intercept"
) )
...@@ -112,6 +113,7 @@ func (d SoftDeleteMixin) Hooks() []ent.Hook { ...@@ -112,6 +113,7 @@ func (d SoftDeleteMixin) Hooks() []ent.Hook {
SetOp(ent.Op) SetOp(ent.Op)
SetDeletedAt(time.Time) SetDeletedAt(time.Time)
WhereP(...func(*sql.Selector)) WhereP(...func(*sql.Selector))
Client() *dbent.Client
}) })
if !ok { if !ok {
return nil, fmt.Errorf("unexpected mutation type %T", m) return nil, fmt.Errorf("unexpected mutation type %T", m)
...@@ -122,7 +124,7 @@ func (d SoftDeleteMixin) Hooks() []ent.Hook { ...@@ -122,7 +124,7 @@ func (d SoftDeleteMixin) Hooks() []ent.Hook {
mx.SetOp(ent.OpUpdate) mx.SetOp(ent.OpUpdate)
// 设置删除时间为当前时间 // 设置删除时间为当前时间
mx.SetDeletedAt(time.Now()) mx.SetDeletedAt(time.Now())
return next.Mutate(ctx, m) return mx.Client().Mutate(ctx, m)
}) })
}, },
} }
......
...@@ -6,6 +6,7 @@ import ( ...@@ -6,6 +6,7 @@ import (
"entgo.io/ent" "entgo.io/ent"
"entgo.io/ent/dialect/entsql" "entgo.io/ent/dialect/entsql"
"entgo.io/ent/schema" "entgo.io/ent/schema"
"entgo.io/ent/schema/edge"
"entgo.io/ent/schema/field" "entgo.io/ent/schema/field"
"entgo.io/ent/schema/index" "entgo.io/ent/schema/index"
) )
...@@ -54,6 +55,15 @@ func (Proxy) Fields() []ent.Field { ...@@ -54,6 +55,15 @@ func (Proxy) Fields() []ent.Field {
} }
} }
// Edges 定义代理实体的关联关系。
func (Proxy) Edges() []ent.Edge {
return []ent.Edge{
// accounts: 使用此代理的账户(反向边)
edge.From("accounts", Account.Type).
Ref("proxy"),
}
}
func (Proxy) Indexes() []ent.Index { func (Proxy) Indexes() []ent.Index {
return []ent.Index{ return []ent.Index{
index.Fields("status"), index.Fields("status"),
......
...@@ -15,6 +15,14 @@ import ( ...@@ -15,6 +15,14 @@ import (
) )
// RedeemCode holds the schema definition for the RedeemCode entity. // RedeemCode holds the schema definition for the RedeemCode entity.
//
// 删除策略:硬删除
// RedeemCode 使用硬删除而非软删除,原因如下:
// - 兑换码具有一次性使用特性,删除后无需保留历史记录
// - 已使用的兑换码通过 status 和 used_at 字段追踪,无需依赖软删除
// - 减少数据库存储压力和查询复杂度
//
// 如需审计已删除的兑换码,建议在删除前将关键信息写入审计日志表。
type RedeemCode struct { type RedeemCode struct {
ent.Schema ent.Schema
} }
...@@ -78,7 +86,7 @@ func (RedeemCode) Edges() []ent.Edge { ...@@ -78,7 +86,7 @@ func (RedeemCode) Edges() []ent.Edge {
func (RedeemCode) Indexes() []ent.Index { func (RedeemCode) Indexes() []ent.Index {
return []ent.Index{ return []ent.Index{
index.Fields("code").Unique(), // code 字段已在 Fields() 中声明 Unique(),无需重复索引
index.Fields("status"), index.Fields("status"),
index.Fields("used_by"), index.Fields("used_by"),
index.Fields("group_id"), index.Fields("group_id"),
......
...@@ -8,10 +8,17 @@ import ( ...@@ -8,10 +8,17 @@ import (
"entgo.io/ent/dialect/entsql" "entgo.io/ent/dialect/entsql"
"entgo.io/ent/schema" "entgo.io/ent/schema"
"entgo.io/ent/schema/field" "entgo.io/ent/schema/field"
"entgo.io/ent/schema/index"
) )
// Setting holds the schema definition for the Setting entity. // Setting holds the schema definition for the Setting entity.
//
// 删除策略:硬删除
// Setting 使用硬删除而非软删除,原因如下:
// - 系统设置是简单的键值对,删除即意味着恢复默认值
// - 设置变更通常通过应用日志追踪,无需在数据库层面保留历史
// - 保持表结构简洁,避免无效数据积累
//
// 如需设置变更审计,建议在更新/删除前将变更记录写入审计日志表。
type Setting struct { type Setting struct {
ent.Schema ent.Schema
} }
...@@ -29,7 +36,6 @@ func (Setting) Fields() []ent.Field { ...@@ -29,7 +36,6 @@ func (Setting) Fields() []ent.Field {
NotEmpty(). NotEmpty().
Unique(), Unique(),
field.String("value"). field.String("value").
NotEmpty().
SchemaType(map[string]string{ SchemaType(map[string]string{
dialect.Postgres: "text", dialect.Postgres: "text",
}), }),
...@@ -43,7 +49,6 @@ func (Setting) Fields() []ent.Field { ...@@ -43,7 +49,6 @@ func (Setting) Fields() []ent.Field {
} }
func (Setting) Indexes() []ent.Index { func (Setting) Indexes() []ent.Index {
return []ent.Index{ // key 字段已在 Fields() 中声明 Unique(),无需额外索引
index.Fields("key").Unique(), return nil
}
} }
// Package schema 定义 Ent ORM 的数据库 schema。
package schema
import (
"time"
"entgo.io/ent"
"entgo.io/ent/dialect"
"entgo.io/ent/dialect/entsql"
"entgo.io/ent/schema"
"entgo.io/ent/schema/edge"
"entgo.io/ent/schema/field"
"entgo.io/ent/schema/index"
)
// UsageLog 定义使用日志实体的 schema。
//
// 使用日志记录每次 API 调用的详细信息,包括 token 使用量、成本计算等。
// 这是一个只追加的表,不支持更新和删除。
type UsageLog struct {
ent.Schema
}
// Annotations 返回 schema 的注解配置。
func (UsageLog) Annotations() []schema.Annotation {
return []schema.Annotation{
entsql.Annotation{Table: "usage_logs"},
}
}
// Fields 定义使用日志实体的所有字段。
func (UsageLog) Fields() []ent.Field {
return []ent.Field{
// 关联字段
field.Int64("user_id"),
field.Int64("api_key_id"),
field.Int64("account_id"),
field.String("request_id").
MaxLen(64).
NotEmpty(),
field.String("model").
MaxLen(100).
NotEmpty(),
field.Int64("group_id").
Optional().
Nillable(),
field.Int64("subscription_id").
Optional().
Nillable(),
// Token 计数字段
field.Int("input_tokens").
Default(0),
field.Int("output_tokens").
Default(0),
field.Int("cache_creation_tokens").
Default(0),
field.Int("cache_read_tokens").
Default(0),
field.Int("cache_creation_5m_tokens").
Default(0),
field.Int("cache_creation_1h_tokens").
Default(0),
// 成本字段
field.Float("input_cost").
Default(0).
SchemaType(map[string]string{dialect.Postgres: "decimal(20,10)"}),
field.Float("output_cost").
Default(0).
SchemaType(map[string]string{dialect.Postgres: "decimal(20,10)"}),
field.Float("cache_creation_cost").
Default(0).
SchemaType(map[string]string{dialect.Postgres: "decimal(20,10)"}),
field.Float("cache_read_cost").
Default(0).
SchemaType(map[string]string{dialect.Postgres: "decimal(20,10)"}),
field.Float("total_cost").
Default(0).
SchemaType(map[string]string{dialect.Postgres: "decimal(20,10)"}),
field.Float("actual_cost").
Default(0).
SchemaType(map[string]string{dialect.Postgres: "decimal(20,10)"}),
field.Float("rate_multiplier").
Default(1).
SchemaType(map[string]string{dialect.Postgres: "decimal(10,4)"}),
// 其他字段
field.Int8("billing_type").
Default(0),
field.Bool("stream").
Default(false),
field.Int("duration_ms").
Optional().
Nillable(),
field.Int("first_token_ms").
Optional().
Nillable(),
// 时间戳(只有 created_at,日志不可修改)
field.Time("created_at").
Default(time.Now).
Immutable().
SchemaType(map[string]string{dialect.Postgres: "timestamptz"}),
}
}
// Edges 定义使用日志实体的关联关系。
func (UsageLog) Edges() []ent.Edge {
return []ent.Edge{
edge.From("user", User.Type).
Ref("usage_logs").
Field("user_id").
Required().
Unique(),
edge.From("api_key", ApiKey.Type).
Ref("usage_logs").
Field("api_key_id").
Required().
Unique(),
edge.From("account", Account.Type).
Ref("usage_logs").
Field("account_id").
Required().
Unique(),
edge.From("group", Group.Type).
Ref("usage_logs").
Field("group_id").
Unique(),
edge.From("subscription", UserSubscription.Type).
Ref("usage_logs").
Field("subscription_id").
Unique(),
}
}
// Indexes 定义数据库索引,优化查询性能。
func (UsageLog) Indexes() []ent.Index {
return []ent.Index{
index.Fields("user_id"),
index.Fields("api_key_id"),
index.Fields("account_id"),
index.Fields("group_id"),
index.Fields("subscription_id"),
index.Fields("created_at"),
index.Fields("model"),
index.Fields("request_id"),
// 复合索引用于时间范围查询
index.Fields("user_id", "created_at"),
index.Fields("api_key_id", "created_at"),
}
}
...@@ -33,10 +33,11 @@ func (User) Mixin() []ent.Mixin { ...@@ -33,10 +33,11 @@ func (User) Mixin() []ent.Mixin {
func (User) Fields() []ent.Field { func (User) Fields() []ent.Field {
return []ent.Field{ return []ent.Field{
// 唯一约束通过部分索引实现(WHERE deleted_at IS NULL),支持软删除后重用
// 见迁移文件 016_soft_delete_partial_unique_indexes.sql
field.String("email"). field.String("email").
MaxLen(255). MaxLen(255).
NotEmpty(). NotEmpty(),
Unique(),
field.String("password_hash"). field.String("password_hash").
MaxLen(255). MaxLen(255).
NotEmpty(), NotEmpty(),
...@@ -73,12 +74,13 @@ func (User) Edges() []ent.Edge { ...@@ -73,12 +74,13 @@ func (User) Edges() []ent.Edge {
edge.To("assigned_subscriptions", UserSubscription.Type), edge.To("assigned_subscriptions", UserSubscription.Type),
edge.To("allowed_groups", Group.Type). edge.To("allowed_groups", Group.Type).
Through("user_allowed_groups", UserAllowedGroup.Type), Through("user_allowed_groups", UserAllowedGroup.Type),
edge.To("usage_logs", UsageLog.Type),
} }
} }
func (User) Indexes() []ent.Index { func (User) Indexes() []ent.Index {
return []ent.Index{ return []ent.Index{
index.Fields("email").Unique(), // email 字段已在 Fields() 中声明 Unique(),无需重复索引
index.Fields("status"), index.Fields("status"),
index.Fields("deleted_at"), index.Fields("deleted_at"),
} }
......
...@@ -4,6 +4,7 @@ import ( ...@@ -4,6 +4,7 @@ import (
"time" "time"
"entgo.io/ent" "entgo.io/ent"
"entgo.io/ent/dialect"
"entgo.io/ent/dialect/entsql" "entgo.io/ent/dialect/entsql"
"entgo.io/ent/schema" "entgo.io/ent/schema"
"entgo.io/ent/schema/edge" "entgo.io/ent/schema/edge"
...@@ -31,7 +32,8 @@ func (UserAllowedGroup) Fields() []ent.Field { ...@@ -31,7 +32,8 @@ func (UserAllowedGroup) Fields() []ent.Field {
field.Int64("group_id"), field.Int64("group_id"),
field.Time("created_at"). field.Time("created_at").
Immutable(). Immutable().
Default(time.Now), Default(time.Now).
SchemaType(map[string]string{dialect.Postgres: "timestamptz"}),
} }
} }
......
...@@ -29,6 +29,7 @@ func (UserSubscription) Annotations() []schema.Annotation { ...@@ -29,6 +29,7 @@ func (UserSubscription) Annotations() []schema.Annotation {
func (UserSubscription) Mixin() []ent.Mixin { func (UserSubscription) Mixin() []ent.Mixin {
return []ent.Mixin{ return []ent.Mixin{
mixins.TimeMixin{}, mixins.TimeMixin{},
mixins.SoftDeleteMixin{},
} }
} }
...@@ -97,6 +98,7 @@ func (UserSubscription) Edges() []ent.Edge { ...@@ -97,6 +98,7 @@ func (UserSubscription) Edges() []ent.Edge {
Ref("assigned_subscriptions"). Ref("assigned_subscriptions").
Field("assigned_by"). Field("assigned_by").
Unique(), Unique(),
edge.To("usage_logs", UsageLog.Type),
} }
} }
...@@ -107,6 +109,9 @@ func (UserSubscription) Indexes() []ent.Index { ...@@ -107,6 +109,9 @@ func (UserSubscription) Indexes() []ent.Index {
index.Fields("status"), index.Fields("status"),
index.Fields("expires_at"), index.Fields("expires_at"),
index.Fields("assigned_by"), index.Fields("assigned_by"),
index.Fields("user_id", "group_id").Unique(), // 唯一约束通过部分索引实现(WHERE deleted_at IS NULL),支持软删除后重新订阅
// 见迁移文件 016_soft_delete_partial_unique_indexes.sql
index.Fields("user_id", "group_id"),
index.Fields("deleted_at"),
} }
} }
...@@ -44,8 +44,6 @@ func ValidColumn(column string) bool { ...@@ -44,8 +44,6 @@ func ValidColumn(column string) bool {
var ( var (
// KeyValidator is a validator for the "key" field. It is called by the builders before save. // KeyValidator is a validator for the "key" field. It is called by the builders before save.
KeyValidator func(string) error KeyValidator func(string) error
// ValueValidator is a validator for the "value" field. It is called by the builders before save.
ValueValidator func(string) error
// DefaultUpdatedAt holds the default value on creation for the "updated_at" field. // DefaultUpdatedAt holds the default value on creation for the "updated_at" field.
DefaultUpdatedAt func() time.Time DefaultUpdatedAt func() time.Time
// UpdateDefaultUpdatedAt holds the default value on update for the "updated_at" field. // UpdateDefaultUpdatedAt holds the default value on update for the "updated_at" field.
......
...@@ -102,11 +102,6 @@ func (_c *SettingCreate) check() error { ...@@ -102,11 +102,6 @@ func (_c *SettingCreate) check() error {
if _, ok := _c.mutation.Value(); !ok { if _, ok := _c.mutation.Value(); !ok {
return &ValidationError{Name: "value", err: errors.New(`ent: missing required field "Setting.value"`)} return &ValidationError{Name: "value", err: errors.New(`ent: missing required field "Setting.value"`)}
} }
if v, ok := _c.mutation.Value(); ok {
if err := setting.ValueValidator(v); err != nil {
return &ValidationError{Name: "value", err: fmt.Errorf(`ent: validator failed for field "Setting.value": %w`, err)}
}
}
if _, ok := _c.mutation.UpdatedAt(); !ok { if _, ok := _c.mutation.UpdatedAt(); !ok {
return &ValidationError{Name: "updated_at", err: errors.New(`ent: missing required field "Setting.updated_at"`)} return &ValidationError{Name: "updated_at", err: errors.New(`ent: missing required field "Setting.updated_at"`)}
} }
......
...@@ -110,11 +110,6 @@ func (_u *SettingUpdate) check() error { ...@@ -110,11 +110,6 @@ func (_u *SettingUpdate) check() error {
return &ValidationError{Name: "key", err: fmt.Errorf(`ent: validator failed for field "Setting.key": %w`, err)} return &ValidationError{Name: "key", err: fmt.Errorf(`ent: validator failed for field "Setting.key": %w`, err)}
} }
} }
if v, ok := _u.mutation.Value(); ok {
if err := setting.ValueValidator(v); err != nil {
return &ValidationError{Name: "value", err: fmt.Errorf(`ent: validator failed for field "Setting.value": %w`, err)}
}
}
return nil return nil
} }
...@@ -254,11 +249,6 @@ func (_u *SettingUpdateOne) check() error { ...@@ -254,11 +249,6 @@ func (_u *SettingUpdateOne) check() error {
return &ValidationError{Name: "key", err: fmt.Errorf(`ent: validator failed for field "Setting.key": %w`, err)} return &ValidationError{Name: "key", err: fmt.Errorf(`ent: validator failed for field "Setting.key": %w`, err)}
} }
} }
if v, ok := _u.mutation.Value(); ok {
if err := setting.ValueValidator(v); err != nil {
return &ValidationError{Name: "value", err: fmt.Errorf(`ent: validator failed for field "Setting.value": %w`, err)}
}
}
return nil return nil
} }
......
...@@ -28,6 +28,8 @@ type Tx struct { ...@@ -28,6 +28,8 @@ type Tx struct {
RedeemCode *RedeemCodeClient RedeemCode *RedeemCodeClient
// Setting is the client for interacting with the Setting builders. // Setting is the client for interacting with the Setting builders.
Setting *SettingClient Setting *SettingClient
// UsageLog is the client for interacting with the UsageLog builders.
UsageLog *UsageLogClient
// User is the client for interacting with the User builders. // User is the client for interacting with the User builders.
User *UserClient User *UserClient
// UserAllowedGroup is the client for interacting with the UserAllowedGroup builders. // UserAllowedGroup is the client for interacting with the UserAllowedGroup builders.
...@@ -172,6 +174,7 @@ func (tx *Tx) init() { ...@@ -172,6 +174,7 @@ func (tx *Tx) init() {
tx.Proxy = NewProxyClient(tx.config) tx.Proxy = NewProxyClient(tx.config)
tx.RedeemCode = NewRedeemCodeClient(tx.config) tx.RedeemCode = NewRedeemCodeClient(tx.config)
tx.Setting = NewSettingClient(tx.config) tx.Setting = NewSettingClient(tx.config)
tx.UsageLog = NewUsageLogClient(tx.config)
tx.User = NewUserClient(tx.config) tx.User = NewUserClient(tx.config)
tx.UserAllowedGroup = NewUserAllowedGroupClient(tx.config) tx.UserAllowedGroup = NewUserAllowedGroupClient(tx.config)
tx.UserSubscription = NewUserSubscriptionClient(tx.config) tx.UserSubscription = NewUserSubscriptionClient(tx.config)
...@@ -238,7 +241,6 @@ func (tx *txDriver) Query(ctx context.Context, query string, args, v any) error ...@@ -238,7 +241,6 @@ func (tx *txDriver) Query(ctx context.Context, query string, args, v any) error
var _ dialect.Driver = (*txDriver)(nil) 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. // ExecContext allows calling the underlying ExecContext method of the transaction if it is supported by it.
// See, database/sql#Tx.ExecContext for more information. // See, database/sql#Tx.ExecContext for more information.
func (tx *txDriver) ExecContext(ctx context.Context, query string, args ...any) (stdsql.Result, error) { func (tx *txDriver) ExecContext(ctx context.Context, query string, args ...any) (stdsql.Result, error) {
...@@ -251,7 +253,6 @@ func (tx *txDriver) ExecContext(ctx context.Context, query string, args ...any) ...@@ -251,7 +253,6 @@ func (tx *txDriver) ExecContext(ctx context.Context, query string, args ...any)
return ex.ExecContext(ctx, query, args...) return ex.ExecContext(ctx, query, args...)
} }
// QueryContext 透传到底层事务,用于在 ent 事务中执行原生查询并共享锁语义。
// QueryContext allows calling the underlying QueryContext method of the transaction if it is supported by it. // QueryContext allows calling the underlying QueryContext method of the transaction if it is supported by it.
// See, database/sql#Tx.QueryContext for more information. // See, database/sql#Tx.QueryContext for more information.
func (tx *txDriver) QueryContext(ctx context.Context, query string, args ...any) (*stdsql.Rows, error) { func (tx *txDriver) QueryContext(ctx context.Context, query string, args ...any) (*stdsql.Rows, error) {
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
// Code generated by ent, DO NOT EDIT.
package ent
import (
"context"
"entgo.io/ent/dialect/sql"
"entgo.io/ent/dialect/sql/sqlgraph"
"entgo.io/ent/schema/field"
"github.com/Wei-Shaw/sub2api/ent/predicate"
"github.com/Wei-Shaw/sub2api/ent/usagelog"
)
// UsageLogDelete is the builder for deleting a UsageLog entity.
type UsageLogDelete struct {
config
hooks []Hook
mutation *UsageLogMutation
}
// Where appends a list predicates to the UsageLogDelete builder.
func (_d *UsageLogDelete) Where(ps ...predicate.UsageLog) *UsageLogDelete {
_d.mutation.Where(ps...)
return _d
}
// Exec executes the deletion query and returns how many vertices were deleted.
func (_d *UsageLogDelete) Exec(ctx context.Context) (int, error) {
return withHooks(ctx, _d.sqlExec, _d.mutation, _d.hooks)
}
// ExecX is like Exec, but panics if an error occurs.
func (_d *UsageLogDelete) ExecX(ctx context.Context) int {
n, err := _d.Exec(ctx)
if err != nil {
panic(err)
}
return n
}
func (_d *UsageLogDelete) sqlExec(ctx context.Context) (int, error) {
_spec := sqlgraph.NewDeleteSpec(usagelog.Table, sqlgraph.NewFieldSpec(usagelog.FieldID, field.TypeInt64))
if ps := _d.mutation.predicates; len(ps) > 0 {
_spec.Predicate = func(selector *sql.Selector) {
for i := range ps {
ps[i](selector)
}
}
}
affected, err := sqlgraph.DeleteNodes(ctx, _d.driver, _spec)
if err != nil && sqlgraph.IsConstraintError(err) {
err = &ConstraintError{msg: err.Error(), wrap: err}
}
_d.mutation.done = true
return affected, err
}
// UsageLogDeleteOne is the builder for deleting a single UsageLog entity.
type UsageLogDeleteOne struct {
_d *UsageLogDelete
}
// Where appends a list predicates to the UsageLogDelete builder.
func (_d *UsageLogDeleteOne) Where(ps ...predicate.UsageLog) *UsageLogDeleteOne {
_d._d.mutation.Where(ps...)
return _d
}
// Exec executes the deletion query.
func (_d *UsageLogDeleteOne) Exec(ctx context.Context) error {
n, err := _d._d.Exec(ctx)
switch {
case err != nil:
return err
case n == 0:
return &NotFoundError{usagelog.Label}
default:
return nil
}
}
// ExecX is like Exec, but panics if an error occurs.
func (_d *UsageLogDeleteOne) ExecX(ctx context.Context) {
if err := _d.Exec(ctx); err != nil {
panic(err)
}
}
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment