Commit ec87f39d authored by shaw's avatar shaw
Browse files

feat: 从 gorm 迁移到 ent (#92)

## 主要变更

- 将 ORM 从 GORM 迁移到 Ent
- 使用 SQL 文件迁移替代 GORM AutoMigrate
- 新增迁移运行器支持分布式锁和校验和验证
- 优化 Repository 层查询,新增轻量级存在性检查方法
- 新增完整的单元测试覆盖删除操作

## 迁移优势

- 类型安全与编译期校验
- 关系建模更清晰(Edge/Through)
- 查询一致性更好
- 迁移可控(SQL 文件作为唯一事实来源)
- 可维护性提升

## 新增迁移文件

- 005_schema_parity.sql: 字段对齐
- 006_fix_invalid_subscription_expires_at.sql: 修复过期时间
- 007_add_user_allowed_groups.sql: 用户允许分组表
- 008_seed_default_group.sql: 默认分组种子
- 009_fix_usage_logs_cache_columns.sql: 缓存列修复
parents fb883f00 3d296d88
// 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/redeemcode"
)
// RedeemCodeDelete is the builder for deleting a RedeemCode entity.
type RedeemCodeDelete struct {
config
hooks []Hook
mutation *RedeemCodeMutation
}
// Where appends a list predicates to the RedeemCodeDelete builder.
func (_d *RedeemCodeDelete) Where(ps ...predicate.RedeemCode) *RedeemCodeDelete {
_d.mutation.Where(ps...)
return _d
}
// Exec executes the deletion query and returns how many vertices were deleted.
func (_d *RedeemCodeDelete) 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 *RedeemCodeDelete) ExecX(ctx context.Context) int {
n, err := _d.Exec(ctx)
if err != nil {
panic(err)
}
return n
}
func (_d *RedeemCodeDelete) sqlExec(ctx context.Context) (int, error) {
_spec := sqlgraph.NewDeleteSpec(redeemcode.Table, sqlgraph.NewFieldSpec(redeemcode.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
}
// RedeemCodeDeleteOne is the builder for deleting a single RedeemCode entity.
type RedeemCodeDeleteOne struct {
_d *RedeemCodeDelete
}
// Where appends a list predicates to the RedeemCodeDelete builder.
func (_d *RedeemCodeDeleteOne) Where(ps ...predicate.RedeemCode) *RedeemCodeDeleteOne {
_d._d.mutation.Where(ps...)
return _d
}
// Exec executes the deletion query.
func (_d *RedeemCodeDeleteOne) Exec(ctx context.Context) error {
n, err := _d._d.Exec(ctx)
switch {
case err != nil:
return err
case n == 0:
return &NotFoundError{redeemcode.Label}
default:
return nil
}
}
// ExecX is like Exec, but panics if an error occurs.
func (_d *RedeemCodeDeleteOne) ExecX(ctx context.Context) {
if err := _d.Exec(ctx); err != nil {
panic(err)
}
}
// Code generated by ent, DO NOT EDIT.
package ent
import (
"context"
"fmt"
"math"
"entgo.io/ent"
"entgo.io/ent/dialect/sql"
"entgo.io/ent/dialect/sql/sqlgraph"
"entgo.io/ent/schema/field"
"github.com/Wei-Shaw/sub2api/ent/group"
"github.com/Wei-Shaw/sub2api/ent/predicate"
"github.com/Wei-Shaw/sub2api/ent/redeemcode"
"github.com/Wei-Shaw/sub2api/ent/user"
)
// RedeemCodeQuery is the builder for querying RedeemCode entities.
type RedeemCodeQuery struct {
config
ctx *QueryContext
order []redeemcode.OrderOption
inters []Interceptor
predicates []predicate.RedeemCode
withUser *UserQuery
withGroup *GroupQuery
// intermediate query (i.e. traversal path).
sql *sql.Selector
path func(context.Context) (*sql.Selector, error)
}
// Where adds a new predicate for the RedeemCodeQuery builder.
func (_q *RedeemCodeQuery) Where(ps ...predicate.RedeemCode) *RedeemCodeQuery {
_q.predicates = append(_q.predicates, ps...)
return _q
}
// Limit the number of records to be returned by this query.
func (_q *RedeemCodeQuery) Limit(limit int) *RedeemCodeQuery {
_q.ctx.Limit = &limit
return _q
}
// Offset to start from.
func (_q *RedeemCodeQuery) Offset(offset int) *RedeemCodeQuery {
_q.ctx.Offset = &offset
return _q
}
// Unique configures the query builder to filter duplicate records on query.
// By default, unique is set to true, and can be disabled using this method.
func (_q *RedeemCodeQuery) Unique(unique bool) *RedeemCodeQuery {
_q.ctx.Unique = &unique
return _q
}
// Order specifies how the records should be ordered.
func (_q *RedeemCodeQuery) Order(o ...redeemcode.OrderOption) *RedeemCodeQuery {
_q.order = append(_q.order, o...)
return _q
}
// QueryUser chains the current query on the "user" edge.
func (_q *RedeemCodeQuery) QueryUser() *UserQuery {
query := (&UserClient{config: _q.config}).Query()
query.path = func(ctx context.Context) (fromU *sql.Selector, err error) {
if err := _q.prepareQuery(ctx); err != nil {
return nil, err
}
selector := _q.sqlQuery(ctx)
if err := selector.Err(); err != nil {
return nil, err
}
step := sqlgraph.NewStep(
sqlgraph.From(redeemcode.Table, redeemcode.FieldID, selector),
sqlgraph.To(user.Table, user.FieldID),
sqlgraph.Edge(sqlgraph.M2O, true, redeemcode.UserTable, redeemcode.UserColumn),
)
fromU = sqlgraph.SetNeighbors(_q.driver.Dialect(), step)
return fromU, nil
}
return query
}
// QueryGroup chains the current query on the "group" edge.
func (_q *RedeemCodeQuery) QueryGroup() *GroupQuery {
query := (&GroupClient{config: _q.config}).Query()
query.path = func(ctx context.Context) (fromU *sql.Selector, err error) {
if err := _q.prepareQuery(ctx); err != nil {
return nil, err
}
selector := _q.sqlQuery(ctx)
if err := selector.Err(); err != nil {
return nil, err
}
step := sqlgraph.NewStep(
sqlgraph.From(redeemcode.Table, redeemcode.FieldID, selector),
sqlgraph.To(group.Table, group.FieldID),
sqlgraph.Edge(sqlgraph.M2O, true, redeemcode.GroupTable, redeemcode.GroupColumn),
)
fromU = sqlgraph.SetNeighbors(_q.driver.Dialect(), step)
return fromU, nil
}
return query
}
// First returns the first RedeemCode entity from the query.
// Returns a *NotFoundError when no RedeemCode was found.
func (_q *RedeemCodeQuery) First(ctx context.Context) (*RedeemCode, error) {
nodes, err := _q.Limit(1).All(setContextOp(ctx, _q.ctx, ent.OpQueryFirst))
if err != nil {
return nil, err
}
if len(nodes) == 0 {
return nil, &NotFoundError{redeemcode.Label}
}
return nodes[0], nil
}
// FirstX is like First, but panics if an error occurs.
func (_q *RedeemCodeQuery) FirstX(ctx context.Context) *RedeemCode {
node, err := _q.First(ctx)
if err != nil && !IsNotFound(err) {
panic(err)
}
return node
}
// FirstID returns the first RedeemCode ID from the query.
// Returns a *NotFoundError when no RedeemCode ID was found.
func (_q *RedeemCodeQuery) FirstID(ctx context.Context) (id int64, err error) {
var ids []int64
if ids, err = _q.Limit(1).IDs(setContextOp(ctx, _q.ctx, ent.OpQueryFirstID)); err != nil {
return
}
if len(ids) == 0 {
err = &NotFoundError{redeemcode.Label}
return
}
return ids[0], nil
}
// FirstIDX is like FirstID, but panics if an error occurs.
func (_q *RedeemCodeQuery) FirstIDX(ctx context.Context) int64 {
id, err := _q.FirstID(ctx)
if err != nil && !IsNotFound(err) {
panic(err)
}
return id
}
// Only returns a single RedeemCode entity found by the query, ensuring it only returns one.
// Returns a *NotSingularError when more than one RedeemCode entity is found.
// Returns a *NotFoundError when no RedeemCode entities are found.
func (_q *RedeemCodeQuery) Only(ctx context.Context) (*RedeemCode, error) {
nodes, err := _q.Limit(2).All(setContextOp(ctx, _q.ctx, ent.OpQueryOnly))
if err != nil {
return nil, err
}
switch len(nodes) {
case 1:
return nodes[0], nil
case 0:
return nil, &NotFoundError{redeemcode.Label}
default:
return nil, &NotSingularError{redeemcode.Label}
}
}
// OnlyX is like Only, but panics if an error occurs.
func (_q *RedeemCodeQuery) OnlyX(ctx context.Context) *RedeemCode {
node, err := _q.Only(ctx)
if err != nil {
panic(err)
}
return node
}
// OnlyID is like Only, but returns the only RedeemCode ID in the query.
// Returns a *NotSingularError when more than one RedeemCode ID is found.
// Returns a *NotFoundError when no entities are found.
func (_q *RedeemCodeQuery) OnlyID(ctx context.Context) (id int64, err error) {
var ids []int64
if ids, err = _q.Limit(2).IDs(setContextOp(ctx, _q.ctx, ent.OpQueryOnlyID)); err != nil {
return
}
switch len(ids) {
case 1:
id = ids[0]
case 0:
err = &NotFoundError{redeemcode.Label}
default:
err = &NotSingularError{redeemcode.Label}
}
return
}
// OnlyIDX is like OnlyID, but panics if an error occurs.
func (_q *RedeemCodeQuery) OnlyIDX(ctx context.Context) int64 {
id, err := _q.OnlyID(ctx)
if err != nil {
panic(err)
}
return id
}
// All executes the query and returns a list of RedeemCodes.
func (_q *RedeemCodeQuery) All(ctx context.Context) ([]*RedeemCode, error) {
ctx = setContextOp(ctx, _q.ctx, ent.OpQueryAll)
if err := _q.prepareQuery(ctx); err != nil {
return nil, err
}
qr := querierAll[[]*RedeemCode, *RedeemCodeQuery]()
return withInterceptors[[]*RedeemCode](ctx, _q, qr, _q.inters)
}
// AllX is like All, but panics if an error occurs.
func (_q *RedeemCodeQuery) AllX(ctx context.Context) []*RedeemCode {
nodes, err := _q.All(ctx)
if err != nil {
panic(err)
}
return nodes
}
// IDs executes the query and returns a list of RedeemCode IDs.
func (_q *RedeemCodeQuery) IDs(ctx context.Context) (ids []int64, err error) {
if _q.ctx.Unique == nil && _q.path != nil {
_q.Unique(true)
}
ctx = setContextOp(ctx, _q.ctx, ent.OpQueryIDs)
if err = _q.Select(redeemcode.FieldID).Scan(ctx, &ids); err != nil {
return nil, err
}
return ids, nil
}
// IDsX is like IDs, but panics if an error occurs.
func (_q *RedeemCodeQuery) IDsX(ctx context.Context) []int64 {
ids, err := _q.IDs(ctx)
if err != nil {
panic(err)
}
return ids
}
// Count returns the count of the given query.
func (_q *RedeemCodeQuery) Count(ctx context.Context) (int, error) {
ctx = setContextOp(ctx, _q.ctx, ent.OpQueryCount)
if err := _q.prepareQuery(ctx); err != nil {
return 0, err
}
return withInterceptors[int](ctx, _q, querierCount[*RedeemCodeQuery](), _q.inters)
}
// CountX is like Count, but panics if an error occurs.
func (_q *RedeemCodeQuery) CountX(ctx context.Context) int {
count, err := _q.Count(ctx)
if err != nil {
panic(err)
}
return count
}
// Exist returns true if the query has elements in the graph.
func (_q *RedeemCodeQuery) Exist(ctx context.Context) (bool, error) {
ctx = setContextOp(ctx, _q.ctx, ent.OpQueryExist)
switch _, err := _q.FirstID(ctx); {
case IsNotFound(err):
return false, nil
case err != nil:
return false, fmt.Errorf("ent: check existence: %w", err)
default:
return true, nil
}
}
// ExistX is like Exist, but panics if an error occurs.
func (_q *RedeemCodeQuery) ExistX(ctx context.Context) bool {
exist, err := _q.Exist(ctx)
if err != nil {
panic(err)
}
return exist
}
// Clone returns a duplicate of the RedeemCodeQuery builder, including all associated steps. It can be
// used to prepare common query builders and use them differently after the clone is made.
func (_q *RedeemCodeQuery) Clone() *RedeemCodeQuery {
if _q == nil {
return nil
}
return &RedeemCodeQuery{
config: _q.config,
ctx: _q.ctx.Clone(),
order: append([]redeemcode.OrderOption{}, _q.order...),
inters: append([]Interceptor{}, _q.inters...),
predicates: append([]predicate.RedeemCode{}, _q.predicates...),
withUser: _q.withUser.Clone(),
withGroup: _q.withGroup.Clone(),
// clone intermediate query.
sql: _q.sql.Clone(),
path: _q.path,
}
}
// WithUser tells the query-builder to eager-load the nodes that are connected to
// the "user" edge. The optional arguments are used to configure the query builder of the edge.
func (_q *RedeemCodeQuery) WithUser(opts ...func(*UserQuery)) *RedeemCodeQuery {
query := (&UserClient{config: _q.config}).Query()
for _, opt := range opts {
opt(query)
}
_q.withUser = query
return _q
}
// WithGroup tells the query-builder to eager-load the nodes that are connected to
// the "group" edge. The optional arguments are used to configure the query builder of the edge.
func (_q *RedeemCodeQuery) WithGroup(opts ...func(*GroupQuery)) *RedeemCodeQuery {
query := (&GroupClient{config: _q.config}).Query()
for _, opt := range opts {
opt(query)
}
_q.withGroup = query
return _q
}
// GroupBy is used to group vertices by one or more fields/columns.
// It is often used with aggregate functions, like: count, max, mean, min, sum.
//
// Example:
//
// var v []struct {
// Code string `json:"code,omitempty"`
// Count int `json:"count,omitempty"`
// }
//
// client.RedeemCode.Query().
// GroupBy(redeemcode.FieldCode).
// Aggregate(ent.Count()).
// Scan(ctx, &v)
func (_q *RedeemCodeQuery) GroupBy(field string, fields ...string) *RedeemCodeGroupBy {
_q.ctx.Fields = append([]string{field}, fields...)
grbuild := &RedeemCodeGroupBy{build: _q}
grbuild.flds = &_q.ctx.Fields
grbuild.label = redeemcode.Label
grbuild.scan = grbuild.Scan
return grbuild
}
// Select allows the selection one or more fields/columns for the given query,
// instead of selecting all fields in the entity.
//
// Example:
//
// var v []struct {
// Code string `json:"code,omitempty"`
// }
//
// client.RedeemCode.Query().
// Select(redeemcode.FieldCode).
// Scan(ctx, &v)
func (_q *RedeemCodeQuery) Select(fields ...string) *RedeemCodeSelect {
_q.ctx.Fields = append(_q.ctx.Fields, fields...)
sbuild := &RedeemCodeSelect{RedeemCodeQuery: _q}
sbuild.label = redeemcode.Label
sbuild.flds, sbuild.scan = &_q.ctx.Fields, sbuild.Scan
return sbuild
}
// Aggregate returns a RedeemCodeSelect configured with the given aggregations.
func (_q *RedeemCodeQuery) Aggregate(fns ...AggregateFunc) *RedeemCodeSelect {
return _q.Select().Aggregate(fns...)
}
func (_q *RedeemCodeQuery) prepareQuery(ctx context.Context) error {
for _, inter := range _q.inters {
if inter == nil {
return fmt.Errorf("ent: uninitialized interceptor (forgotten import ent/runtime?)")
}
if trv, ok := inter.(Traverser); ok {
if err := trv.Traverse(ctx, _q); err != nil {
return err
}
}
}
for _, f := range _q.ctx.Fields {
if !redeemcode.ValidColumn(f) {
return &ValidationError{Name: f, err: fmt.Errorf("ent: invalid field %q for query", f)}
}
}
if _q.path != nil {
prev, err := _q.path(ctx)
if err != nil {
return err
}
_q.sql = prev
}
return nil
}
func (_q *RedeemCodeQuery) sqlAll(ctx context.Context, hooks ...queryHook) ([]*RedeemCode, error) {
var (
nodes = []*RedeemCode{}
_spec = _q.querySpec()
loadedTypes = [2]bool{
_q.withUser != nil,
_q.withGroup != nil,
}
)
_spec.ScanValues = func(columns []string) ([]any, error) {
return (*RedeemCode).scanValues(nil, columns)
}
_spec.Assign = func(columns []string, values []any) error {
node := &RedeemCode{config: _q.config}
nodes = append(nodes, node)
node.Edges.loadedTypes = loadedTypes
return node.assignValues(columns, values)
}
for i := range hooks {
hooks[i](ctx, _spec)
}
if err := sqlgraph.QueryNodes(ctx, _q.driver, _spec); err != nil {
return nil, err
}
if len(nodes) == 0 {
return nodes, nil
}
if query := _q.withUser; query != nil {
if err := _q.loadUser(ctx, query, nodes, nil,
func(n *RedeemCode, e *User) { n.Edges.User = e }); err != nil {
return nil, err
}
}
if query := _q.withGroup; query != nil {
if err := _q.loadGroup(ctx, query, nodes, nil,
func(n *RedeemCode, e *Group) { n.Edges.Group = e }); err != nil {
return nil, err
}
}
return nodes, nil
}
func (_q *RedeemCodeQuery) loadUser(ctx context.Context, query *UserQuery, nodes []*RedeemCode, init func(*RedeemCode), assign func(*RedeemCode, *User)) error {
ids := make([]int64, 0, len(nodes))
nodeids := make(map[int64][]*RedeemCode)
for i := range nodes {
if nodes[i].UsedBy == nil {
continue
}
fk := *nodes[i].UsedBy
if _, ok := nodeids[fk]; !ok {
ids = append(ids, fk)
}
nodeids[fk] = append(nodeids[fk], nodes[i])
}
if len(ids) == 0 {
return nil
}
query.Where(user.IDIn(ids...))
neighbors, err := query.All(ctx)
if err != nil {
return err
}
for _, n := range neighbors {
nodes, ok := nodeids[n.ID]
if !ok {
return fmt.Errorf(`unexpected foreign-key "used_by" returned %v`, n.ID)
}
for i := range nodes {
assign(nodes[i], n)
}
}
return nil
}
func (_q *RedeemCodeQuery) loadGroup(ctx context.Context, query *GroupQuery, nodes []*RedeemCode, init func(*RedeemCode), assign func(*RedeemCode, *Group)) error {
ids := make([]int64, 0, len(nodes))
nodeids := make(map[int64][]*RedeemCode)
for i := range nodes {
if nodes[i].GroupID == nil {
continue
}
fk := *nodes[i].GroupID
if _, ok := nodeids[fk]; !ok {
ids = append(ids, fk)
}
nodeids[fk] = append(nodeids[fk], nodes[i])
}
if len(ids) == 0 {
return nil
}
query.Where(group.IDIn(ids...))
neighbors, err := query.All(ctx)
if err != nil {
return err
}
for _, n := range neighbors {
nodes, ok := nodeids[n.ID]
if !ok {
return fmt.Errorf(`unexpected foreign-key "group_id" returned %v`, n.ID)
}
for i := range nodes {
assign(nodes[i], n)
}
}
return nil
}
func (_q *RedeemCodeQuery) sqlCount(ctx context.Context) (int, error) {
_spec := _q.querySpec()
_spec.Node.Columns = _q.ctx.Fields
if len(_q.ctx.Fields) > 0 {
_spec.Unique = _q.ctx.Unique != nil && *_q.ctx.Unique
}
return sqlgraph.CountNodes(ctx, _q.driver, _spec)
}
func (_q *RedeemCodeQuery) querySpec() *sqlgraph.QuerySpec {
_spec := sqlgraph.NewQuerySpec(redeemcode.Table, redeemcode.Columns, sqlgraph.NewFieldSpec(redeemcode.FieldID, field.TypeInt64))
_spec.From = _q.sql
if unique := _q.ctx.Unique; unique != nil {
_spec.Unique = *unique
} else if _q.path != nil {
_spec.Unique = true
}
if fields := _q.ctx.Fields; len(fields) > 0 {
_spec.Node.Columns = make([]string, 0, len(fields))
_spec.Node.Columns = append(_spec.Node.Columns, redeemcode.FieldID)
for i := range fields {
if fields[i] != redeemcode.FieldID {
_spec.Node.Columns = append(_spec.Node.Columns, fields[i])
}
}
if _q.withUser != nil {
_spec.Node.AddColumnOnce(redeemcode.FieldUsedBy)
}
if _q.withGroup != nil {
_spec.Node.AddColumnOnce(redeemcode.FieldGroupID)
}
}
if ps := _q.predicates; len(ps) > 0 {
_spec.Predicate = func(selector *sql.Selector) {
for i := range ps {
ps[i](selector)
}
}
}
if limit := _q.ctx.Limit; limit != nil {
_spec.Limit = *limit
}
if offset := _q.ctx.Offset; offset != nil {
_spec.Offset = *offset
}
if ps := _q.order; len(ps) > 0 {
_spec.Order = func(selector *sql.Selector) {
for i := range ps {
ps[i](selector)
}
}
}
return _spec
}
func (_q *RedeemCodeQuery) sqlQuery(ctx context.Context) *sql.Selector {
builder := sql.Dialect(_q.driver.Dialect())
t1 := builder.Table(redeemcode.Table)
columns := _q.ctx.Fields
if len(columns) == 0 {
columns = redeemcode.Columns
}
selector := builder.Select(t1.Columns(columns...)...).From(t1)
if _q.sql != nil {
selector = _q.sql
selector.Select(selector.Columns(columns...)...)
}
if _q.ctx.Unique != nil && *_q.ctx.Unique {
selector.Distinct()
}
for _, p := range _q.predicates {
p(selector)
}
for _, p := range _q.order {
p(selector)
}
if offset := _q.ctx.Offset; offset != nil {
// limit is mandatory for offset clause. We start
// with default value, and override it below if needed.
selector.Offset(*offset).Limit(math.MaxInt32)
}
if limit := _q.ctx.Limit; limit != nil {
selector.Limit(*limit)
}
return selector
}
// RedeemCodeGroupBy is the group-by builder for RedeemCode entities.
type RedeemCodeGroupBy struct {
selector
build *RedeemCodeQuery
}
// Aggregate adds the given aggregation functions to the group-by query.
func (_g *RedeemCodeGroupBy) Aggregate(fns ...AggregateFunc) *RedeemCodeGroupBy {
_g.fns = append(_g.fns, fns...)
return _g
}
// Scan applies the selector query and scans the result into the given value.
func (_g *RedeemCodeGroupBy) Scan(ctx context.Context, v any) error {
ctx = setContextOp(ctx, _g.build.ctx, ent.OpQueryGroupBy)
if err := _g.build.prepareQuery(ctx); err != nil {
return err
}
return scanWithInterceptors[*RedeemCodeQuery, *RedeemCodeGroupBy](ctx, _g.build, _g, _g.build.inters, v)
}
func (_g *RedeemCodeGroupBy) sqlScan(ctx context.Context, root *RedeemCodeQuery, v any) error {
selector := root.sqlQuery(ctx).Select()
aggregation := make([]string, 0, len(_g.fns))
for _, fn := range _g.fns {
aggregation = append(aggregation, fn(selector))
}
if len(selector.SelectedColumns()) == 0 {
columns := make([]string, 0, len(*_g.flds)+len(_g.fns))
for _, f := range *_g.flds {
columns = append(columns, selector.C(f))
}
columns = append(columns, aggregation...)
selector.Select(columns...)
}
selector.GroupBy(selector.Columns(*_g.flds...)...)
if err := selector.Err(); err != nil {
return err
}
rows := &sql.Rows{}
query, args := selector.Query()
if err := _g.build.driver.Query(ctx, query, args, rows); err != nil {
return err
}
defer rows.Close()
return sql.ScanSlice(rows, v)
}
// RedeemCodeSelect is the builder for selecting fields of RedeemCode entities.
type RedeemCodeSelect struct {
*RedeemCodeQuery
selector
}
// Aggregate adds the given aggregation functions to the selector query.
func (_s *RedeemCodeSelect) Aggregate(fns ...AggregateFunc) *RedeemCodeSelect {
_s.fns = append(_s.fns, fns...)
return _s
}
// Scan applies the selector query and scans the result into the given value.
func (_s *RedeemCodeSelect) Scan(ctx context.Context, v any) error {
ctx = setContextOp(ctx, _s.ctx, ent.OpQuerySelect)
if err := _s.prepareQuery(ctx); err != nil {
return err
}
return scanWithInterceptors[*RedeemCodeQuery, *RedeemCodeSelect](ctx, _s.RedeemCodeQuery, _s, _s.inters, v)
}
func (_s *RedeemCodeSelect) sqlScan(ctx context.Context, root *RedeemCodeQuery, v any) error {
selector := root.sqlQuery(ctx)
aggregation := make([]string, 0, len(_s.fns))
for _, fn := range _s.fns {
aggregation = append(aggregation, fn(selector))
}
switch n := len(*_s.selector.flds); {
case n == 0 && len(aggregation) > 0:
selector.Select(aggregation...)
case n != 0 && len(aggregation) > 0:
selector.AppendSelect(aggregation...)
}
rows := &sql.Rows{}
query, args := selector.Query()
if err := _s.driver.Query(ctx, query, args, rows); err != nil {
return err
}
defer rows.Close()
return sql.ScanSlice(rows, v)
}
// Code generated by ent, DO NOT EDIT.
package ent
import (
"context"
"errors"
"fmt"
"time"
"entgo.io/ent/dialect/sql"
"entgo.io/ent/dialect/sql/sqlgraph"
"entgo.io/ent/schema/field"
"github.com/Wei-Shaw/sub2api/ent/group"
"github.com/Wei-Shaw/sub2api/ent/predicate"
"github.com/Wei-Shaw/sub2api/ent/redeemcode"
"github.com/Wei-Shaw/sub2api/ent/user"
)
// RedeemCodeUpdate is the builder for updating RedeemCode entities.
type RedeemCodeUpdate struct {
config
hooks []Hook
mutation *RedeemCodeMutation
}
// Where appends a list predicates to the RedeemCodeUpdate builder.
func (_u *RedeemCodeUpdate) Where(ps ...predicate.RedeemCode) *RedeemCodeUpdate {
_u.mutation.Where(ps...)
return _u
}
// SetCode sets the "code" field.
func (_u *RedeemCodeUpdate) SetCode(v string) *RedeemCodeUpdate {
_u.mutation.SetCode(v)
return _u
}
// SetNillableCode sets the "code" field if the given value is not nil.
func (_u *RedeemCodeUpdate) SetNillableCode(v *string) *RedeemCodeUpdate {
if v != nil {
_u.SetCode(*v)
}
return _u
}
// SetType sets the "type" field.
func (_u *RedeemCodeUpdate) SetType(v string) *RedeemCodeUpdate {
_u.mutation.SetType(v)
return _u
}
// SetNillableType sets the "type" field if the given value is not nil.
func (_u *RedeemCodeUpdate) SetNillableType(v *string) *RedeemCodeUpdate {
if v != nil {
_u.SetType(*v)
}
return _u
}
// SetValue sets the "value" field.
func (_u *RedeemCodeUpdate) SetValue(v float64) *RedeemCodeUpdate {
_u.mutation.ResetValue()
_u.mutation.SetValue(v)
return _u
}
// SetNillableValue sets the "value" field if the given value is not nil.
func (_u *RedeemCodeUpdate) SetNillableValue(v *float64) *RedeemCodeUpdate {
if v != nil {
_u.SetValue(*v)
}
return _u
}
// AddValue adds value to the "value" field.
func (_u *RedeemCodeUpdate) AddValue(v float64) *RedeemCodeUpdate {
_u.mutation.AddValue(v)
return _u
}
// SetStatus sets the "status" field.
func (_u *RedeemCodeUpdate) SetStatus(v string) *RedeemCodeUpdate {
_u.mutation.SetStatus(v)
return _u
}
// SetNillableStatus sets the "status" field if the given value is not nil.
func (_u *RedeemCodeUpdate) SetNillableStatus(v *string) *RedeemCodeUpdate {
if v != nil {
_u.SetStatus(*v)
}
return _u
}
// SetUsedBy sets the "used_by" field.
func (_u *RedeemCodeUpdate) SetUsedBy(v int64) *RedeemCodeUpdate {
_u.mutation.SetUsedBy(v)
return _u
}
// SetNillableUsedBy sets the "used_by" field if the given value is not nil.
func (_u *RedeemCodeUpdate) SetNillableUsedBy(v *int64) *RedeemCodeUpdate {
if v != nil {
_u.SetUsedBy(*v)
}
return _u
}
// ClearUsedBy clears the value of the "used_by" field.
func (_u *RedeemCodeUpdate) ClearUsedBy() *RedeemCodeUpdate {
_u.mutation.ClearUsedBy()
return _u
}
// SetUsedAt sets the "used_at" field.
func (_u *RedeemCodeUpdate) SetUsedAt(v time.Time) *RedeemCodeUpdate {
_u.mutation.SetUsedAt(v)
return _u
}
// SetNillableUsedAt sets the "used_at" field if the given value is not nil.
func (_u *RedeemCodeUpdate) SetNillableUsedAt(v *time.Time) *RedeemCodeUpdate {
if v != nil {
_u.SetUsedAt(*v)
}
return _u
}
// ClearUsedAt clears the value of the "used_at" field.
func (_u *RedeemCodeUpdate) ClearUsedAt() *RedeemCodeUpdate {
_u.mutation.ClearUsedAt()
return _u
}
// SetNotes sets the "notes" field.
func (_u *RedeemCodeUpdate) SetNotes(v string) *RedeemCodeUpdate {
_u.mutation.SetNotes(v)
return _u
}
// SetNillableNotes sets the "notes" field if the given value is not nil.
func (_u *RedeemCodeUpdate) SetNillableNotes(v *string) *RedeemCodeUpdate {
if v != nil {
_u.SetNotes(*v)
}
return _u
}
// ClearNotes clears the value of the "notes" field.
func (_u *RedeemCodeUpdate) ClearNotes() *RedeemCodeUpdate {
_u.mutation.ClearNotes()
return _u
}
// SetGroupID sets the "group_id" field.
func (_u *RedeemCodeUpdate) SetGroupID(v int64) *RedeemCodeUpdate {
_u.mutation.SetGroupID(v)
return _u
}
// SetNillableGroupID sets the "group_id" field if the given value is not nil.
func (_u *RedeemCodeUpdate) SetNillableGroupID(v *int64) *RedeemCodeUpdate {
if v != nil {
_u.SetGroupID(*v)
}
return _u
}
// ClearGroupID clears the value of the "group_id" field.
func (_u *RedeemCodeUpdate) ClearGroupID() *RedeemCodeUpdate {
_u.mutation.ClearGroupID()
return _u
}
// SetValidityDays sets the "validity_days" field.
func (_u *RedeemCodeUpdate) SetValidityDays(v int) *RedeemCodeUpdate {
_u.mutation.ResetValidityDays()
_u.mutation.SetValidityDays(v)
return _u
}
// SetNillableValidityDays sets the "validity_days" field if the given value is not nil.
func (_u *RedeemCodeUpdate) SetNillableValidityDays(v *int) *RedeemCodeUpdate {
if v != nil {
_u.SetValidityDays(*v)
}
return _u
}
// AddValidityDays adds value to the "validity_days" field.
func (_u *RedeemCodeUpdate) AddValidityDays(v int) *RedeemCodeUpdate {
_u.mutation.AddValidityDays(v)
return _u
}
// SetUserID sets the "user" edge to the User entity by ID.
func (_u *RedeemCodeUpdate) SetUserID(id int64) *RedeemCodeUpdate {
_u.mutation.SetUserID(id)
return _u
}
// SetNillableUserID sets the "user" edge to the User entity by ID if the given value is not nil.
func (_u *RedeemCodeUpdate) SetNillableUserID(id *int64) *RedeemCodeUpdate {
if id != nil {
_u = _u.SetUserID(*id)
}
return _u
}
// SetUser sets the "user" edge to the User entity.
func (_u *RedeemCodeUpdate) SetUser(v *User) *RedeemCodeUpdate {
return _u.SetUserID(v.ID)
}
// SetGroup sets the "group" edge to the Group entity.
func (_u *RedeemCodeUpdate) SetGroup(v *Group) *RedeemCodeUpdate {
return _u.SetGroupID(v.ID)
}
// Mutation returns the RedeemCodeMutation object of the builder.
func (_u *RedeemCodeUpdate) Mutation() *RedeemCodeMutation {
return _u.mutation
}
// ClearUser clears the "user" edge to the User entity.
func (_u *RedeemCodeUpdate) ClearUser() *RedeemCodeUpdate {
_u.mutation.ClearUser()
return _u
}
// ClearGroup clears the "group" edge to the Group entity.
func (_u *RedeemCodeUpdate) ClearGroup() *RedeemCodeUpdate {
_u.mutation.ClearGroup()
return _u
}
// Save executes the query and returns the number of nodes affected by the update operation.
func (_u *RedeemCodeUpdate) Save(ctx context.Context) (int, error) {
return withHooks(ctx, _u.sqlSave, _u.mutation, _u.hooks)
}
// SaveX is like Save, but panics if an error occurs.
func (_u *RedeemCodeUpdate) SaveX(ctx context.Context) int {
affected, err := _u.Save(ctx)
if err != nil {
panic(err)
}
return affected
}
// Exec executes the query.
func (_u *RedeemCodeUpdate) Exec(ctx context.Context) error {
_, err := _u.Save(ctx)
return err
}
// ExecX is like Exec, but panics if an error occurs.
func (_u *RedeemCodeUpdate) ExecX(ctx context.Context) {
if err := _u.Exec(ctx); err != nil {
panic(err)
}
}
// check runs all checks and user-defined validators on the builder.
func (_u *RedeemCodeUpdate) check() error {
if v, ok := _u.mutation.Code(); ok {
if err := redeemcode.CodeValidator(v); err != nil {
return &ValidationError{Name: "code", err: fmt.Errorf(`ent: validator failed for field "RedeemCode.code": %w`, err)}
}
}
if v, ok := _u.mutation.GetType(); ok {
if err := redeemcode.TypeValidator(v); err != nil {
return &ValidationError{Name: "type", err: fmt.Errorf(`ent: validator failed for field "RedeemCode.type": %w`, err)}
}
}
if v, ok := _u.mutation.Status(); ok {
if err := redeemcode.StatusValidator(v); err != nil {
return &ValidationError{Name: "status", err: fmt.Errorf(`ent: validator failed for field "RedeemCode.status": %w`, err)}
}
}
return nil
}
func (_u *RedeemCodeUpdate) sqlSave(ctx context.Context) (_node int, err error) {
if err := _u.check(); err != nil {
return _node, err
}
_spec := sqlgraph.NewUpdateSpec(redeemcode.Table, redeemcode.Columns, sqlgraph.NewFieldSpec(redeemcode.FieldID, field.TypeInt64))
if ps := _u.mutation.predicates; len(ps) > 0 {
_spec.Predicate = func(selector *sql.Selector) {
for i := range ps {
ps[i](selector)
}
}
}
if value, ok := _u.mutation.Code(); ok {
_spec.SetField(redeemcode.FieldCode, field.TypeString, value)
}
if value, ok := _u.mutation.GetType(); ok {
_spec.SetField(redeemcode.FieldType, field.TypeString, value)
}
if value, ok := _u.mutation.Value(); ok {
_spec.SetField(redeemcode.FieldValue, field.TypeFloat64, value)
}
if value, ok := _u.mutation.AddedValue(); ok {
_spec.AddField(redeemcode.FieldValue, field.TypeFloat64, value)
}
if value, ok := _u.mutation.Status(); ok {
_spec.SetField(redeemcode.FieldStatus, field.TypeString, value)
}
if value, ok := _u.mutation.UsedAt(); ok {
_spec.SetField(redeemcode.FieldUsedAt, field.TypeTime, value)
}
if _u.mutation.UsedAtCleared() {
_spec.ClearField(redeemcode.FieldUsedAt, field.TypeTime)
}
if value, ok := _u.mutation.Notes(); ok {
_spec.SetField(redeemcode.FieldNotes, field.TypeString, value)
}
if _u.mutation.NotesCleared() {
_spec.ClearField(redeemcode.FieldNotes, field.TypeString)
}
if value, ok := _u.mutation.ValidityDays(); ok {
_spec.SetField(redeemcode.FieldValidityDays, field.TypeInt, value)
}
if value, ok := _u.mutation.AddedValidityDays(); ok {
_spec.AddField(redeemcode.FieldValidityDays, field.TypeInt, value)
}
if _u.mutation.UserCleared() {
edge := &sqlgraph.EdgeSpec{
Rel: sqlgraph.M2O,
Inverse: true,
Table: redeemcode.UserTable,
Columns: []string{redeemcode.UserColumn},
Bidi: false,
Target: &sqlgraph.EdgeTarget{
IDSpec: sqlgraph.NewFieldSpec(user.FieldID, field.TypeInt64),
},
}
_spec.Edges.Clear = append(_spec.Edges.Clear, edge)
}
if nodes := _u.mutation.UserIDs(); len(nodes) > 0 {
edge := &sqlgraph.EdgeSpec{
Rel: sqlgraph.M2O,
Inverse: true,
Table: redeemcode.UserTable,
Columns: []string{redeemcode.UserColumn},
Bidi: false,
Target: &sqlgraph.EdgeTarget{
IDSpec: sqlgraph.NewFieldSpec(user.FieldID, field.TypeInt64),
},
}
for _, k := range nodes {
edge.Target.Nodes = append(edge.Target.Nodes, k)
}
_spec.Edges.Add = append(_spec.Edges.Add, edge)
}
if _u.mutation.GroupCleared() {
edge := &sqlgraph.EdgeSpec{
Rel: sqlgraph.M2O,
Inverse: true,
Table: redeemcode.GroupTable,
Columns: []string{redeemcode.GroupColumn},
Bidi: false,
Target: &sqlgraph.EdgeTarget{
IDSpec: sqlgraph.NewFieldSpec(group.FieldID, field.TypeInt64),
},
}
_spec.Edges.Clear = append(_spec.Edges.Clear, edge)
}
if nodes := _u.mutation.GroupIDs(); len(nodes) > 0 {
edge := &sqlgraph.EdgeSpec{
Rel: sqlgraph.M2O,
Inverse: true,
Table: redeemcode.GroupTable,
Columns: []string{redeemcode.GroupColumn},
Bidi: false,
Target: &sqlgraph.EdgeTarget{
IDSpec: sqlgraph.NewFieldSpec(group.FieldID, field.TypeInt64),
},
}
for _, k := range nodes {
edge.Target.Nodes = append(edge.Target.Nodes, k)
}
_spec.Edges.Add = append(_spec.Edges.Add, edge)
}
if _node, err = sqlgraph.UpdateNodes(ctx, _u.driver, _spec); err != nil {
if _, ok := err.(*sqlgraph.NotFoundError); ok {
err = &NotFoundError{redeemcode.Label}
} else if sqlgraph.IsConstraintError(err) {
err = &ConstraintError{msg: err.Error(), wrap: err}
}
return 0, err
}
_u.mutation.done = true
return _node, nil
}
// RedeemCodeUpdateOne is the builder for updating a single RedeemCode entity.
type RedeemCodeUpdateOne struct {
config
fields []string
hooks []Hook
mutation *RedeemCodeMutation
}
// SetCode sets the "code" field.
func (_u *RedeemCodeUpdateOne) SetCode(v string) *RedeemCodeUpdateOne {
_u.mutation.SetCode(v)
return _u
}
// SetNillableCode sets the "code" field if the given value is not nil.
func (_u *RedeemCodeUpdateOne) SetNillableCode(v *string) *RedeemCodeUpdateOne {
if v != nil {
_u.SetCode(*v)
}
return _u
}
// SetType sets the "type" field.
func (_u *RedeemCodeUpdateOne) SetType(v string) *RedeemCodeUpdateOne {
_u.mutation.SetType(v)
return _u
}
// SetNillableType sets the "type" field if the given value is not nil.
func (_u *RedeemCodeUpdateOne) SetNillableType(v *string) *RedeemCodeUpdateOne {
if v != nil {
_u.SetType(*v)
}
return _u
}
// SetValue sets the "value" field.
func (_u *RedeemCodeUpdateOne) SetValue(v float64) *RedeemCodeUpdateOne {
_u.mutation.ResetValue()
_u.mutation.SetValue(v)
return _u
}
// SetNillableValue sets the "value" field if the given value is not nil.
func (_u *RedeemCodeUpdateOne) SetNillableValue(v *float64) *RedeemCodeUpdateOne {
if v != nil {
_u.SetValue(*v)
}
return _u
}
// AddValue adds value to the "value" field.
func (_u *RedeemCodeUpdateOne) AddValue(v float64) *RedeemCodeUpdateOne {
_u.mutation.AddValue(v)
return _u
}
// SetStatus sets the "status" field.
func (_u *RedeemCodeUpdateOne) SetStatus(v string) *RedeemCodeUpdateOne {
_u.mutation.SetStatus(v)
return _u
}
// SetNillableStatus sets the "status" field if the given value is not nil.
func (_u *RedeemCodeUpdateOne) SetNillableStatus(v *string) *RedeemCodeUpdateOne {
if v != nil {
_u.SetStatus(*v)
}
return _u
}
// SetUsedBy sets the "used_by" field.
func (_u *RedeemCodeUpdateOne) SetUsedBy(v int64) *RedeemCodeUpdateOne {
_u.mutation.SetUsedBy(v)
return _u
}
// SetNillableUsedBy sets the "used_by" field if the given value is not nil.
func (_u *RedeemCodeUpdateOne) SetNillableUsedBy(v *int64) *RedeemCodeUpdateOne {
if v != nil {
_u.SetUsedBy(*v)
}
return _u
}
// ClearUsedBy clears the value of the "used_by" field.
func (_u *RedeemCodeUpdateOne) ClearUsedBy() *RedeemCodeUpdateOne {
_u.mutation.ClearUsedBy()
return _u
}
// SetUsedAt sets the "used_at" field.
func (_u *RedeemCodeUpdateOne) SetUsedAt(v time.Time) *RedeemCodeUpdateOne {
_u.mutation.SetUsedAt(v)
return _u
}
// SetNillableUsedAt sets the "used_at" field if the given value is not nil.
func (_u *RedeemCodeUpdateOne) SetNillableUsedAt(v *time.Time) *RedeemCodeUpdateOne {
if v != nil {
_u.SetUsedAt(*v)
}
return _u
}
// ClearUsedAt clears the value of the "used_at" field.
func (_u *RedeemCodeUpdateOne) ClearUsedAt() *RedeemCodeUpdateOne {
_u.mutation.ClearUsedAt()
return _u
}
// SetNotes sets the "notes" field.
func (_u *RedeemCodeUpdateOne) SetNotes(v string) *RedeemCodeUpdateOne {
_u.mutation.SetNotes(v)
return _u
}
// SetNillableNotes sets the "notes" field if the given value is not nil.
func (_u *RedeemCodeUpdateOne) SetNillableNotes(v *string) *RedeemCodeUpdateOne {
if v != nil {
_u.SetNotes(*v)
}
return _u
}
// ClearNotes clears the value of the "notes" field.
func (_u *RedeemCodeUpdateOne) ClearNotes() *RedeemCodeUpdateOne {
_u.mutation.ClearNotes()
return _u
}
// SetGroupID sets the "group_id" field.
func (_u *RedeemCodeUpdateOne) SetGroupID(v int64) *RedeemCodeUpdateOne {
_u.mutation.SetGroupID(v)
return _u
}
// SetNillableGroupID sets the "group_id" field if the given value is not nil.
func (_u *RedeemCodeUpdateOne) SetNillableGroupID(v *int64) *RedeemCodeUpdateOne {
if v != nil {
_u.SetGroupID(*v)
}
return _u
}
// ClearGroupID clears the value of the "group_id" field.
func (_u *RedeemCodeUpdateOne) ClearGroupID() *RedeemCodeUpdateOne {
_u.mutation.ClearGroupID()
return _u
}
// SetValidityDays sets the "validity_days" field.
func (_u *RedeemCodeUpdateOne) SetValidityDays(v int) *RedeemCodeUpdateOne {
_u.mutation.ResetValidityDays()
_u.mutation.SetValidityDays(v)
return _u
}
// SetNillableValidityDays sets the "validity_days" field if the given value is not nil.
func (_u *RedeemCodeUpdateOne) SetNillableValidityDays(v *int) *RedeemCodeUpdateOne {
if v != nil {
_u.SetValidityDays(*v)
}
return _u
}
// AddValidityDays adds value to the "validity_days" field.
func (_u *RedeemCodeUpdateOne) AddValidityDays(v int) *RedeemCodeUpdateOne {
_u.mutation.AddValidityDays(v)
return _u
}
// SetUserID sets the "user" edge to the User entity by ID.
func (_u *RedeemCodeUpdateOne) SetUserID(id int64) *RedeemCodeUpdateOne {
_u.mutation.SetUserID(id)
return _u
}
// SetNillableUserID sets the "user" edge to the User entity by ID if the given value is not nil.
func (_u *RedeemCodeUpdateOne) SetNillableUserID(id *int64) *RedeemCodeUpdateOne {
if id != nil {
_u = _u.SetUserID(*id)
}
return _u
}
// SetUser sets the "user" edge to the User entity.
func (_u *RedeemCodeUpdateOne) SetUser(v *User) *RedeemCodeUpdateOne {
return _u.SetUserID(v.ID)
}
// SetGroup sets the "group" edge to the Group entity.
func (_u *RedeemCodeUpdateOne) SetGroup(v *Group) *RedeemCodeUpdateOne {
return _u.SetGroupID(v.ID)
}
// Mutation returns the RedeemCodeMutation object of the builder.
func (_u *RedeemCodeUpdateOne) Mutation() *RedeemCodeMutation {
return _u.mutation
}
// ClearUser clears the "user" edge to the User entity.
func (_u *RedeemCodeUpdateOne) ClearUser() *RedeemCodeUpdateOne {
_u.mutation.ClearUser()
return _u
}
// ClearGroup clears the "group" edge to the Group entity.
func (_u *RedeemCodeUpdateOne) ClearGroup() *RedeemCodeUpdateOne {
_u.mutation.ClearGroup()
return _u
}
// Where appends a list predicates to the RedeemCodeUpdate builder.
func (_u *RedeemCodeUpdateOne) Where(ps ...predicate.RedeemCode) *RedeemCodeUpdateOne {
_u.mutation.Where(ps...)
return _u
}
// Select allows selecting one or more fields (columns) of the returned entity.
// The default is selecting all fields defined in the entity schema.
func (_u *RedeemCodeUpdateOne) Select(field string, fields ...string) *RedeemCodeUpdateOne {
_u.fields = append([]string{field}, fields...)
return _u
}
// Save executes the query and returns the updated RedeemCode entity.
func (_u *RedeemCodeUpdateOne) Save(ctx context.Context) (*RedeemCode, error) {
return withHooks(ctx, _u.sqlSave, _u.mutation, _u.hooks)
}
// SaveX is like Save, but panics if an error occurs.
func (_u *RedeemCodeUpdateOne) SaveX(ctx context.Context) *RedeemCode {
node, err := _u.Save(ctx)
if err != nil {
panic(err)
}
return node
}
// Exec executes the query on the entity.
func (_u *RedeemCodeUpdateOne) Exec(ctx context.Context) error {
_, err := _u.Save(ctx)
return err
}
// ExecX is like Exec, but panics if an error occurs.
func (_u *RedeemCodeUpdateOne) ExecX(ctx context.Context) {
if err := _u.Exec(ctx); err != nil {
panic(err)
}
}
// check runs all checks and user-defined validators on the builder.
func (_u *RedeemCodeUpdateOne) check() error {
if v, ok := _u.mutation.Code(); ok {
if err := redeemcode.CodeValidator(v); err != nil {
return &ValidationError{Name: "code", err: fmt.Errorf(`ent: validator failed for field "RedeemCode.code": %w`, err)}
}
}
if v, ok := _u.mutation.GetType(); ok {
if err := redeemcode.TypeValidator(v); err != nil {
return &ValidationError{Name: "type", err: fmt.Errorf(`ent: validator failed for field "RedeemCode.type": %w`, err)}
}
}
if v, ok := _u.mutation.Status(); ok {
if err := redeemcode.StatusValidator(v); err != nil {
return &ValidationError{Name: "status", err: fmt.Errorf(`ent: validator failed for field "RedeemCode.status": %w`, err)}
}
}
return nil
}
func (_u *RedeemCodeUpdateOne) sqlSave(ctx context.Context) (_node *RedeemCode, err error) {
if err := _u.check(); err != nil {
return _node, err
}
_spec := sqlgraph.NewUpdateSpec(redeemcode.Table, redeemcode.Columns, sqlgraph.NewFieldSpec(redeemcode.FieldID, field.TypeInt64))
id, ok := _u.mutation.ID()
if !ok {
return nil, &ValidationError{Name: "id", err: errors.New(`ent: missing "RedeemCode.id" for update`)}
}
_spec.Node.ID.Value = id
if fields := _u.fields; len(fields) > 0 {
_spec.Node.Columns = make([]string, 0, len(fields))
_spec.Node.Columns = append(_spec.Node.Columns, redeemcode.FieldID)
for _, f := range fields {
if !redeemcode.ValidColumn(f) {
return nil, &ValidationError{Name: f, err: fmt.Errorf("ent: invalid field %q for query", f)}
}
if f != redeemcode.FieldID {
_spec.Node.Columns = append(_spec.Node.Columns, f)
}
}
}
if ps := _u.mutation.predicates; len(ps) > 0 {
_spec.Predicate = func(selector *sql.Selector) {
for i := range ps {
ps[i](selector)
}
}
}
if value, ok := _u.mutation.Code(); ok {
_spec.SetField(redeemcode.FieldCode, field.TypeString, value)
}
if value, ok := _u.mutation.GetType(); ok {
_spec.SetField(redeemcode.FieldType, field.TypeString, value)
}
if value, ok := _u.mutation.Value(); ok {
_spec.SetField(redeemcode.FieldValue, field.TypeFloat64, value)
}
if value, ok := _u.mutation.AddedValue(); ok {
_spec.AddField(redeemcode.FieldValue, field.TypeFloat64, value)
}
if value, ok := _u.mutation.Status(); ok {
_spec.SetField(redeemcode.FieldStatus, field.TypeString, value)
}
if value, ok := _u.mutation.UsedAt(); ok {
_spec.SetField(redeemcode.FieldUsedAt, field.TypeTime, value)
}
if _u.mutation.UsedAtCleared() {
_spec.ClearField(redeemcode.FieldUsedAt, field.TypeTime)
}
if value, ok := _u.mutation.Notes(); ok {
_spec.SetField(redeemcode.FieldNotes, field.TypeString, value)
}
if _u.mutation.NotesCleared() {
_spec.ClearField(redeemcode.FieldNotes, field.TypeString)
}
if value, ok := _u.mutation.ValidityDays(); ok {
_spec.SetField(redeemcode.FieldValidityDays, field.TypeInt, value)
}
if value, ok := _u.mutation.AddedValidityDays(); ok {
_spec.AddField(redeemcode.FieldValidityDays, field.TypeInt, value)
}
if _u.mutation.UserCleared() {
edge := &sqlgraph.EdgeSpec{
Rel: sqlgraph.M2O,
Inverse: true,
Table: redeemcode.UserTable,
Columns: []string{redeemcode.UserColumn},
Bidi: false,
Target: &sqlgraph.EdgeTarget{
IDSpec: sqlgraph.NewFieldSpec(user.FieldID, field.TypeInt64),
},
}
_spec.Edges.Clear = append(_spec.Edges.Clear, edge)
}
if nodes := _u.mutation.UserIDs(); len(nodes) > 0 {
edge := &sqlgraph.EdgeSpec{
Rel: sqlgraph.M2O,
Inverse: true,
Table: redeemcode.UserTable,
Columns: []string{redeemcode.UserColumn},
Bidi: false,
Target: &sqlgraph.EdgeTarget{
IDSpec: sqlgraph.NewFieldSpec(user.FieldID, field.TypeInt64),
},
}
for _, k := range nodes {
edge.Target.Nodes = append(edge.Target.Nodes, k)
}
_spec.Edges.Add = append(_spec.Edges.Add, edge)
}
if _u.mutation.GroupCleared() {
edge := &sqlgraph.EdgeSpec{
Rel: sqlgraph.M2O,
Inverse: true,
Table: redeemcode.GroupTable,
Columns: []string{redeemcode.GroupColumn},
Bidi: false,
Target: &sqlgraph.EdgeTarget{
IDSpec: sqlgraph.NewFieldSpec(group.FieldID, field.TypeInt64),
},
}
_spec.Edges.Clear = append(_spec.Edges.Clear, edge)
}
if nodes := _u.mutation.GroupIDs(); len(nodes) > 0 {
edge := &sqlgraph.EdgeSpec{
Rel: sqlgraph.M2O,
Inverse: true,
Table: redeemcode.GroupTable,
Columns: []string{redeemcode.GroupColumn},
Bidi: false,
Target: &sqlgraph.EdgeTarget{
IDSpec: sqlgraph.NewFieldSpec(group.FieldID, field.TypeInt64),
},
}
for _, k := range nodes {
edge.Target.Nodes = append(edge.Target.Nodes, k)
}
_spec.Edges.Add = append(_spec.Edges.Add, edge)
}
_node = &RedeemCode{config: _u.config}
_spec.Assign = _node.assignValues
_spec.ScanValues = _node.scanValues
if err = sqlgraph.UpdateNode(ctx, _u.driver, _spec); err != nil {
if _, ok := err.(*sqlgraph.NotFoundError); ok {
err = &NotFoundError{redeemcode.Label}
} else if sqlgraph.IsConstraintError(err) {
err = &ConstraintError{msg: err.Error(), wrap: err}
}
return nil, err
}
_u.mutation.done = true
return _node, nil
}
// Code generated by ent, DO NOT EDIT.
package ent
// The schema-stitching logic is generated in github.com/Wei-Shaw/sub2api/ent/runtime/runtime.go
// Code generated by ent, DO NOT EDIT.
package runtime
import (
"time"
"github.com/Wei-Shaw/sub2api/ent/account"
"github.com/Wei-Shaw/sub2api/ent/accountgroup"
"github.com/Wei-Shaw/sub2api/ent/apikey"
"github.com/Wei-Shaw/sub2api/ent/group"
"github.com/Wei-Shaw/sub2api/ent/proxy"
"github.com/Wei-Shaw/sub2api/ent/redeemcode"
"github.com/Wei-Shaw/sub2api/ent/schema"
"github.com/Wei-Shaw/sub2api/ent/setting"
"github.com/Wei-Shaw/sub2api/ent/user"
"github.com/Wei-Shaw/sub2api/ent/userallowedgroup"
"github.com/Wei-Shaw/sub2api/ent/usersubscription"
)
// The init function reads all schema descriptors with runtime code
// (default values, validators, hooks and policies) and stitches it
// to their package variables.
func init() {
accountMixin := schema.Account{}.Mixin()
accountMixinHooks1 := accountMixin[1].Hooks()
account.Hooks[0] = accountMixinHooks1[0]
accountMixinInters1 := accountMixin[1].Interceptors()
account.Interceptors[0] = accountMixinInters1[0]
accountMixinFields0 := accountMixin[0].Fields()
_ = accountMixinFields0
accountFields := schema.Account{}.Fields()
_ = accountFields
// accountDescCreatedAt is the schema descriptor for created_at field.
accountDescCreatedAt := accountMixinFields0[0].Descriptor()
// account.DefaultCreatedAt holds the default value on creation for the created_at field.
account.DefaultCreatedAt = accountDescCreatedAt.Default.(func() time.Time)
// accountDescUpdatedAt is the schema descriptor for updated_at field.
accountDescUpdatedAt := accountMixinFields0[1].Descriptor()
// account.DefaultUpdatedAt holds the default value on creation for the updated_at field.
account.DefaultUpdatedAt = accountDescUpdatedAt.Default.(func() time.Time)
// account.UpdateDefaultUpdatedAt holds the default value on update for the updated_at field.
account.UpdateDefaultUpdatedAt = accountDescUpdatedAt.UpdateDefault.(func() time.Time)
// accountDescName is the schema descriptor for name field.
accountDescName := accountFields[0].Descriptor()
// account.NameValidator is a validator for the "name" field. It is called by the builders before save.
account.NameValidator = func() func(string) error {
validators := accountDescName.Validators
fns := [...]func(string) error{
validators[0].(func(string) error),
validators[1].(func(string) error),
}
return func(name string) error {
for _, fn := range fns {
if err := fn(name); err != nil {
return err
}
}
return nil
}
}()
// accountDescPlatform is the schema descriptor for platform field.
accountDescPlatform := accountFields[1].Descriptor()
// account.PlatformValidator is a validator for the "platform" field. It is called by the builders before save.
account.PlatformValidator = func() func(string) error {
validators := accountDescPlatform.Validators
fns := [...]func(string) error{
validators[0].(func(string) error),
validators[1].(func(string) error),
}
return func(platform string) error {
for _, fn := range fns {
if err := fn(platform); err != nil {
return err
}
}
return nil
}
}()
// accountDescType is the schema descriptor for type field.
accountDescType := accountFields[2].Descriptor()
// account.TypeValidator is a validator for the "type" field. It is called by the builders before save.
account.TypeValidator = func() func(string) error {
validators := accountDescType.Validators
fns := [...]func(string) error{
validators[0].(func(string) error),
validators[1].(func(string) error),
}
return func(_type string) error {
for _, fn := range fns {
if err := fn(_type); err != nil {
return err
}
}
return nil
}
}()
// accountDescCredentials is the schema descriptor for credentials field.
accountDescCredentials := accountFields[3].Descriptor()
// account.DefaultCredentials holds the default value on creation for the credentials field.
account.DefaultCredentials = accountDescCredentials.Default.(func() map[string]interface{})
// accountDescExtra is the schema descriptor for extra field.
accountDescExtra := accountFields[4].Descriptor()
// account.DefaultExtra holds the default value on creation for the extra field.
account.DefaultExtra = accountDescExtra.Default.(func() map[string]interface{})
// accountDescConcurrency is the schema descriptor for concurrency field.
accountDescConcurrency := accountFields[6].Descriptor()
// account.DefaultConcurrency holds the default value on creation for the concurrency field.
account.DefaultConcurrency = accountDescConcurrency.Default.(int)
// accountDescPriority is the schema descriptor for priority field.
accountDescPriority := accountFields[7].Descriptor()
// account.DefaultPriority holds the default value on creation for the priority field.
account.DefaultPriority = accountDescPriority.Default.(int)
// accountDescStatus is the schema descriptor for status field.
accountDescStatus := accountFields[8].Descriptor()
// account.DefaultStatus holds the default value on creation for the status field.
account.DefaultStatus = accountDescStatus.Default.(string)
// account.StatusValidator is a validator for the "status" field. It is called by the builders before save.
account.StatusValidator = accountDescStatus.Validators[0].(func(string) error)
// accountDescSchedulable is the schema descriptor for schedulable field.
accountDescSchedulable := accountFields[11].Descriptor()
// account.DefaultSchedulable holds the default value on creation for the schedulable field.
account.DefaultSchedulable = accountDescSchedulable.Default.(bool)
// accountDescSessionWindowStatus is the schema descriptor for session_window_status field.
accountDescSessionWindowStatus := accountFields[17].Descriptor()
// account.SessionWindowStatusValidator is a validator for the "session_window_status" field. It is called by the builders before save.
account.SessionWindowStatusValidator = accountDescSessionWindowStatus.Validators[0].(func(string) error)
accountgroupFields := schema.AccountGroup{}.Fields()
_ = accountgroupFields
// accountgroupDescPriority is the schema descriptor for priority field.
accountgroupDescPriority := accountgroupFields[2].Descriptor()
// accountgroup.DefaultPriority holds the default value on creation for the priority field.
accountgroup.DefaultPriority = accountgroupDescPriority.Default.(int)
// accountgroupDescCreatedAt is the schema descriptor for created_at field.
accountgroupDescCreatedAt := accountgroupFields[3].Descriptor()
// accountgroup.DefaultCreatedAt holds the default value on creation for the created_at field.
accountgroup.DefaultCreatedAt = accountgroupDescCreatedAt.Default.(func() time.Time)
apikeyMixin := schema.ApiKey{}.Mixin()
apikeyMixinHooks1 := apikeyMixin[1].Hooks()
apikey.Hooks[0] = apikeyMixinHooks1[0]
apikeyMixinInters1 := apikeyMixin[1].Interceptors()
apikey.Interceptors[0] = apikeyMixinInters1[0]
apikeyMixinFields0 := apikeyMixin[0].Fields()
_ = apikeyMixinFields0
apikeyFields := schema.ApiKey{}.Fields()
_ = apikeyFields
// apikeyDescCreatedAt is the schema descriptor for created_at field.
apikeyDescCreatedAt := apikeyMixinFields0[0].Descriptor()
// apikey.DefaultCreatedAt holds the default value on creation for the created_at field.
apikey.DefaultCreatedAt = apikeyDescCreatedAt.Default.(func() time.Time)
// apikeyDescUpdatedAt is the schema descriptor for updated_at field.
apikeyDescUpdatedAt := apikeyMixinFields0[1].Descriptor()
// apikey.DefaultUpdatedAt holds the default value on creation for the updated_at field.
apikey.DefaultUpdatedAt = apikeyDescUpdatedAt.Default.(func() time.Time)
// apikey.UpdateDefaultUpdatedAt holds the default value on update for the updated_at field.
apikey.UpdateDefaultUpdatedAt = apikeyDescUpdatedAt.UpdateDefault.(func() time.Time)
// apikeyDescKey is the schema descriptor for key field.
apikeyDescKey := apikeyFields[1].Descriptor()
// apikey.KeyValidator is a validator for the "key" field. It is called by the builders before save.
apikey.KeyValidator = func() func(string) error {
validators := apikeyDescKey.Validators
fns := [...]func(string) error{
validators[0].(func(string) error),
validators[1].(func(string) error),
}
return func(key string) error {
for _, fn := range fns {
if err := fn(key); err != nil {
return err
}
}
return nil
}
}()
// apikeyDescName is the schema descriptor for name field.
apikeyDescName := apikeyFields[2].Descriptor()
// apikey.NameValidator is a validator for the "name" field. It is called by the builders before save.
apikey.NameValidator = func() func(string) error {
validators := apikeyDescName.Validators
fns := [...]func(string) error{
validators[0].(func(string) error),
validators[1].(func(string) error),
}
return func(name string) error {
for _, fn := range fns {
if err := fn(name); err != nil {
return err
}
}
return nil
}
}()
// apikeyDescStatus is the schema descriptor for status field.
apikeyDescStatus := apikeyFields[4].Descriptor()
// apikey.DefaultStatus holds the default value on creation for the status field.
apikey.DefaultStatus = apikeyDescStatus.Default.(string)
// apikey.StatusValidator is a validator for the "status" field. It is called by the builders before save.
apikey.StatusValidator = apikeyDescStatus.Validators[0].(func(string) error)
groupMixin := schema.Group{}.Mixin()
groupMixinHooks1 := groupMixin[1].Hooks()
group.Hooks[0] = groupMixinHooks1[0]
groupMixinInters1 := groupMixin[1].Interceptors()
group.Interceptors[0] = groupMixinInters1[0]
groupMixinFields0 := groupMixin[0].Fields()
_ = groupMixinFields0
groupFields := schema.Group{}.Fields()
_ = groupFields
// groupDescCreatedAt is the schema descriptor for created_at field.
groupDescCreatedAt := groupMixinFields0[0].Descriptor()
// group.DefaultCreatedAt holds the default value on creation for the created_at field.
group.DefaultCreatedAt = groupDescCreatedAt.Default.(func() time.Time)
// groupDescUpdatedAt is the schema descriptor for updated_at field.
groupDescUpdatedAt := groupMixinFields0[1].Descriptor()
// group.DefaultUpdatedAt holds the default value on creation for the updated_at field.
group.DefaultUpdatedAt = groupDescUpdatedAt.Default.(func() time.Time)
// group.UpdateDefaultUpdatedAt holds the default value on update for the updated_at field.
group.UpdateDefaultUpdatedAt = groupDescUpdatedAt.UpdateDefault.(func() time.Time)
// groupDescName is the schema descriptor for name field.
groupDescName := groupFields[0].Descriptor()
// group.NameValidator is a validator for the "name" field. It is called by the builders before save.
group.NameValidator = func() func(string) error {
validators := groupDescName.Validators
fns := [...]func(string) error{
validators[0].(func(string) error),
validators[1].(func(string) error),
}
return func(name string) error {
for _, fn := range fns {
if err := fn(name); err != nil {
return err
}
}
return nil
}
}()
// groupDescRateMultiplier is the schema descriptor for rate_multiplier field.
groupDescRateMultiplier := groupFields[2].Descriptor()
// group.DefaultRateMultiplier holds the default value on creation for the rate_multiplier field.
group.DefaultRateMultiplier = groupDescRateMultiplier.Default.(float64)
// groupDescIsExclusive is the schema descriptor for is_exclusive field.
groupDescIsExclusive := groupFields[3].Descriptor()
// group.DefaultIsExclusive holds the default value on creation for the is_exclusive field.
group.DefaultIsExclusive = groupDescIsExclusive.Default.(bool)
// groupDescStatus is the schema descriptor for status field.
groupDescStatus := groupFields[4].Descriptor()
// group.DefaultStatus holds the default value on creation for the status field.
group.DefaultStatus = groupDescStatus.Default.(string)
// group.StatusValidator is a validator for the "status" field. It is called by the builders before save.
group.StatusValidator = groupDescStatus.Validators[0].(func(string) error)
// groupDescPlatform is the schema descriptor for platform field.
groupDescPlatform := groupFields[5].Descriptor()
// group.DefaultPlatform holds the default value on creation for the platform field.
group.DefaultPlatform = groupDescPlatform.Default.(string)
// group.PlatformValidator is a validator for the "platform" field. It is called by the builders before save.
group.PlatformValidator = groupDescPlatform.Validators[0].(func(string) error)
// groupDescSubscriptionType is the schema descriptor for subscription_type field.
groupDescSubscriptionType := groupFields[6].Descriptor()
// group.DefaultSubscriptionType holds the default value on creation for the subscription_type field.
group.DefaultSubscriptionType = groupDescSubscriptionType.Default.(string)
// group.SubscriptionTypeValidator is a validator for the "subscription_type" field. It is called by the builders before save.
group.SubscriptionTypeValidator = groupDescSubscriptionType.Validators[0].(func(string) error)
proxyMixin := schema.Proxy{}.Mixin()
proxyMixinHooks1 := proxyMixin[1].Hooks()
proxy.Hooks[0] = proxyMixinHooks1[0]
proxyMixinInters1 := proxyMixin[1].Interceptors()
proxy.Interceptors[0] = proxyMixinInters1[0]
proxyMixinFields0 := proxyMixin[0].Fields()
_ = proxyMixinFields0
proxyFields := schema.Proxy{}.Fields()
_ = proxyFields
// proxyDescCreatedAt is the schema descriptor for created_at field.
proxyDescCreatedAt := proxyMixinFields0[0].Descriptor()
// proxy.DefaultCreatedAt holds the default value on creation for the created_at field.
proxy.DefaultCreatedAt = proxyDescCreatedAt.Default.(func() time.Time)
// proxyDescUpdatedAt is the schema descriptor for updated_at field.
proxyDescUpdatedAt := proxyMixinFields0[1].Descriptor()
// proxy.DefaultUpdatedAt holds the default value on creation for the updated_at field.
proxy.DefaultUpdatedAt = proxyDescUpdatedAt.Default.(func() time.Time)
// proxy.UpdateDefaultUpdatedAt holds the default value on update for the updated_at field.
proxy.UpdateDefaultUpdatedAt = proxyDescUpdatedAt.UpdateDefault.(func() time.Time)
// proxyDescName is the schema descriptor for name field.
proxyDescName := proxyFields[0].Descriptor()
// proxy.NameValidator is a validator for the "name" field. It is called by the builders before save.
proxy.NameValidator = func() func(string) error {
validators := proxyDescName.Validators
fns := [...]func(string) error{
validators[0].(func(string) error),
validators[1].(func(string) error),
}
return func(name string) error {
for _, fn := range fns {
if err := fn(name); err != nil {
return err
}
}
return nil
}
}()
// proxyDescProtocol is the schema descriptor for protocol field.
proxyDescProtocol := proxyFields[1].Descriptor()
// proxy.ProtocolValidator is a validator for the "protocol" field. It is called by the builders before save.
proxy.ProtocolValidator = func() func(string) error {
validators := proxyDescProtocol.Validators
fns := [...]func(string) error{
validators[0].(func(string) error),
validators[1].(func(string) error),
}
return func(protocol string) error {
for _, fn := range fns {
if err := fn(protocol); err != nil {
return err
}
}
return nil
}
}()
// proxyDescHost is the schema descriptor for host field.
proxyDescHost := proxyFields[2].Descriptor()
// proxy.HostValidator is a validator for the "host" field. It is called by the builders before save.
proxy.HostValidator = func() func(string) error {
validators := proxyDescHost.Validators
fns := [...]func(string) error{
validators[0].(func(string) error),
validators[1].(func(string) error),
}
return func(host string) error {
for _, fn := range fns {
if err := fn(host); err != nil {
return err
}
}
return nil
}
}()
// proxyDescUsername is the schema descriptor for username field.
proxyDescUsername := proxyFields[4].Descriptor()
// proxy.UsernameValidator is a validator for the "username" field. It is called by the builders before save.
proxy.UsernameValidator = proxyDescUsername.Validators[0].(func(string) error)
// proxyDescPassword is the schema descriptor for password field.
proxyDescPassword := proxyFields[5].Descriptor()
// proxy.PasswordValidator is a validator for the "password" field. It is called by the builders before save.
proxy.PasswordValidator = proxyDescPassword.Validators[0].(func(string) error)
// proxyDescStatus is the schema descriptor for status field.
proxyDescStatus := proxyFields[6].Descriptor()
// proxy.DefaultStatus holds the default value on creation for the status field.
proxy.DefaultStatus = proxyDescStatus.Default.(string)
// proxy.StatusValidator is a validator for the "status" field. It is called by the builders before save.
proxy.StatusValidator = proxyDescStatus.Validators[0].(func(string) error)
redeemcodeFields := schema.RedeemCode{}.Fields()
_ = redeemcodeFields
// redeemcodeDescCode is the schema descriptor for code field.
redeemcodeDescCode := redeemcodeFields[0].Descriptor()
// redeemcode.CodeValidator is a validator for the "code" field. It is called by the builders before save.
redeemcode.CodeValidator = func() func(string) error {
validators := redeemcodeDescCode.Validators
fns := [...]func(string) error{
validators[0].(func(string) error),
validators[1].(func(string) error),
}
return func(code string) error {
for _, fn := range fns {
if err := fn(code); err != nil {
return err
}
}
return nil
}
}()
// redeemcodeDescType is the schema descriptor for type field.
redeemcodeDescType := redeemcodeFields[1].Descriptor()
// redeemcode.DefaultType holds the default value on creation for the type field.
redeemcode.DefaultType = redeemcodeDescType.Default.(string)
// redeemcode.TypeValidator is a validator for the "type" field. It is called by the builders before save.
redeemcode.TypeValidator = redeemcodeDescType.Validators[0].(func(string) error)
// redeemcodeDescValue is the schema descriptor for value field.
redeemcodeDescValue := redeemcodeFields[2].Descriptor()
// redeemcode.DefaultValue holds the default value on creation for the value field.
redeemcode.DefaultValue = redeemcodeDescValue.Default.(float64)
// redeemcodeDescStatus is the schema descriptor for status field.
redeemcodeDescStatus := redeemcodeFields[3].Descriptor()
// redeemcode.DefaultStatus holds the default value on creation for the status field.
redeemcode.DefaultStatus = redeemcodeDescStatus.Default.(string)
// redeemcode.StatusValidator is a validator for the "status" field. It is called by the builders before save.
redeemcode.StatusValidator = redeemcodeDescStatus.Validators[0].(func(string) error)
// redeemcodeDescCreatedAt is the schema descriptor for created_at field.
redeemcodeDescCreatedAt := redeemcodeFields[7].Descriptor()
// redeemcode.DefaultCreatedAt holds the default value on creation for the created_at field.
redeemcode.DefaultCreatedAt = redeemcodeDescCreatedAt.Default.(func() time.Time)
// redeemcodeDescValidityDays is the schema descriptor for validity_days field.
redeemcodeDescValidityDays := redeemcodeFields[9].Descriptor()
// redeemcode.DefaultValidityDays holds the default value on creation for the validity_days field.
redeemcode.DefaultValidityDays = redeemcodeDescValidityDays.Default.(int)
settingFields := schema.Setting{}.Fields()
_ = settingFields
// settingDescKey is the schema descriptor for key field.
settingDescKey := settingFields[0].Descriptor()
// setting.KeyValidator is a validator for the "key" field. It is called by the builders before save.
setting.KeyValidator = func() func(string) error {
validators := settingDescKey.Validators
fns := [...]func(string) error{
validators[0].(func(string) error),
validators[1].(func(string) error),
}
return func(key string) error {
for _, fn := range fns {
if err := fn(key); err != nil {
return err
}
}
return nil
}
}()
// settingDescValue is the schema descriptor for value field.
settingDescValue := settingFields[1].Descriptor()
// setting.ValueValidator is a validator for the "value" field. It is called by the builders before save.
setting.ValueValidator = settingDescValue.Validators[0].(func(string) error)
// settingDescUpdatedAt is the schema descriptor for updated_at field.
settingDescUpdatedAt := settingFields[2].Descriptor()
// setting.DefaultUpdatedAt holds the default value on creation for the updated_at field.
setting.DefaultUpdatedAt = settingDescUpdatedAt.Default.(func() time.Time)
// setting.UpdateDefaultUpdatedAt holds the default value on update for the updated_at field.
setting.UpdateDefaultUpdatedAt = settingDescUpdatedAt.UpdateDefault.(func() time.Time)
userMixin := schema.User{}.Mixin()
userMixinHooks1 := userMixin[1].Hooks()
user.Hooks[0] = userMixinHooks1[0]
userMixinInters1 := userMixin[1].Interceptors()
user.Interceptors[0] = userMixinInters1[0]
userMixinFields0 := userMixin[0].Fields()
_ = userMixinFields0
userFields := schema.User{}.Fields()
_ = userFields
// userDescCreatedAt is the schema descriptor for created_at field.
userDescCreatedAt := userMixinFields0[0].Descriptor()
// user.DefaultCreatedAt holds the default value on creation for the created_at field.
user.DefaultCreatedAt = userDescCreatedAt.Default.(func() time.Time)
// userDescUpdatedAt is the schema descriptor for updated_at field.
userDescUpdatedAt := userMixinFields0[1].Descriptor()
// user.DefaultUpdatedAt holds the default value on creation for the updated_at field.
user.DefaultUpdatedAt = userDescUpdatedAt.Default.(func() time.Time)
// user.UpdateDefaultUpdatedAt holds the default value on update for the updated_at field.
user.UpdateDefaultUpdatedAt = userDescUpdatedAt.UpdateDefault.(func() time.Time)
// userDescEmail is the schema descriptor for email field.
userDescEmail := userFields[0].Descriptor()
// user.EmailValidator is a validator for the "email" field. It is called by the builders before save.
user.EmailValidator = func() func(string) error {
validators := userDescEmail.Validators
fns := [...]func(string) error{
validators[0].(func(string) error),
validators[1].(func(string) error),
}
return func(email string) error {
for _, fn := range fns {
if err := fn(email); err != nil {
return err
}
}
return nil
}
}()
// userDescPasswordHash is the schema descriptor for password_hash field.
userDescPasswordHash := userFields[1].Descriptor()
// user.PasswordHashValidator is a validator for the "password_hash" field. It is called by the builders before save.
user.PasswordHashValidator = func() func(string) error {
validators := userDescPasswordHash.Validators
fns := [...]func(string) error{
validators[0].(func(string) error),
validators[1].(func(string) error),
}
return func(password_hash string) error {
for _, fn := range fns {
if err := fn(password_hash); err != nil {
return err
}
}
return nil
}
}()
// userDescRole is the schema descriptor for role field.
userDescRole := userFields[2].Descriptor()
// user.DefaultRole holds the default value on creation for the role field.
user.DefaultRole = userDescRole.Default.(string)
// user.RoleValidator is a validator for the "role" field. It is called by the builders before save.
user.RoleValidator = userDescRole.Validators[0].(func(string) error)
// userDescBalance is the schema descriptor for balance field.
userDescBalance := userFields[3].Descriptor()
// user.DefaultBalance holds the default value on creation for the balance field.
user.DefaultBalance = userDescBalance.Default.(float64)
// userDescConcurrency is the schema descriptor for concurrency field.
userDescConcurrency := userFields[4].Descriptor()
// user.DefaultConcurrency holds the default value on creation for the concurrency field.
user.DefaultConcurrency = userDescConcurrency.Default.(int)
// userDescStatus is the schema descriptor for status field.
userDescStatus := userFields[5].Descriptor()
// user.DefaultStatus holds the default value on creation for the status field.
user.DefaultStatus = userDescStatus.Default.(string)
// user.StatusValidator is a validator for the "status" field. It is called by the builders before save.
user.StatusValidator = userDescStatus.Validators[0].(func(string) error)
// userDescUsername is the schema descriptor for username field.
userDescUsername := userFields[6].Descriptor()
// user.DefaultUsername holds the default value on creation for the username field.
user.DefaultUsername = userDescUsername.Default.(string)
// user.UsernameValidator is a validator for the "username" field. It is called by the builders before save.
user.UsernameValidator = userDescUsername.Validators[0].(func(string) error)
// userDescWechat is the schema descriptor for wechat field.
userDescWechat := userFields[7].Descriptor()
// user.DefaultWechat holds the default value on creation for the wechat field.
user.DefaultWechat = userDescWechat.Default.(string)
// user.WechatValidator is a validator for the "wechat" field. It is called by the builders before save.
user.WechatValidator = userDescWechat.Validators[0].(func(string) error)
// userDescNotes is the schema descriptor for notes field.
userDescNotes := userFields[8].Descriptor()
// user.DefaultNotes holds the default value on creation for the notes field.
user.DefaultNotes = userDescNotes.Default.(string)
userallowedgroupFields := schema.UserAllowedGroup{}.Fields()
_ = userallowedgroupFields
// userallowedgroupDescCreatedAt is the schema descriptor for created_at field.
userallowedgroupDescCreatedAt := userallowedgroupFields[2].Descriptor()
// userallowedgroup.DefaultCreatedAt holds the default value on creation for the created_at field.
userallowedgroup.DefaultCreatedAt = userallowedgroupDescCreatedAt.Default.(func() time.Time)
usersubscriptionMixin := schema.UserSubscription{}.Mixin()
usersubscriptionMixinFields0 := usersubscriptionMixin[0].Fields()
_ = usersubscriptionMixinFields0
usersubscriptionFields := schema.UserSubscription{}.Fields()
_ = usersubscriptionFields
// usersubscriptionDescCreatedAt is the schema descriptor for created_at field.
usersubscriptionDescCreatedAt := usersubscriptionMixinFields0[0].Descriptor()
// usersubscription.DefaultCreatedAt holds the default value on creation for the created_at field.
usersubscription.DefaultCreatedAt = usersubscriptionDescCreatedAt.Default.(func() time.Time)
// usersubscriptionDescUpdatedAt is the schema descriptor for updated_at field.
usersubscriptionDescUpdatedAt := usersubscriptionMixinFields0[1].Descriptor()
// usersubscription.DefaultUpdatedAt holds the default value on creation for the updated_at field.
usersubscription.DefaultUpdatedAt = usersubscriptionDescUpdatedAt.Default.(func() time.Time)
// usersubscription.UpdateDefaultUpdatedAt holds the default value on update for the updated_at field.
usersubscription.UpdateDefaultUpdatedAt = usersubscriptionDescUpdatedAt.UpdateDefault.(func() time.Time)
// usersubscriptionDescStatus is the schema descriptor for status field.
usersubscriptionDescStatus := usersubscriptionFields[4].Descriptor()
// usersubscription.DefaultStatus holds the default value on creation for the status field.
usersubscription.DefaultStatus = usersubscriptionDescStatus.Default.(string)
// usersubscription.StatusValidator is a validator for the "status" field. It is called by the builders before save.
usersubscription.StatusValidator = usersubscriptionDescStatus.Validators[0].(func(string) error)
// usersubscriptionDescDailyUsageUsd is the schema descriptor for daily_usage_usd field.
usersubscriptionDescDailyUsageUsd := usersubscriptionFields[8].Descriptor()
// usersubscription.DefaultDailyUsageUsd holds the default value on creation for the daily_usage_usd field.
usersubscription.DefaultDailyUsageUsd = usersubscriptionDescDailyUsageUsd.Default.(float64)
// usersubscriptionDescWeeklyUsageUsd is the schema descriptor for weekly_usage_usd field.
usersubscriptionDescWeeklyUsageUsd := usersubscriptionFields[9].Descriptor()
// usersubscription.DefaultWeeklyUsageUsd holds the default value on creation for the weekly_usage_usd field.
usersubscription.DefaultWeeklyUsageUsd = usersubscriptionDescWeeklyUsageUsd.Default.(float64)
// usersubscriptionDescMonthlyUsageUsd is the schema descriptor for monthly_usage_usd field.
usersubscriptionDescMonthlyUsageUsd := usersubscriptionFields[10].Descriptor()
// usersubscription.DefaultMonthlyUsageUsd holds the default value on creation for the monthly_usage_usd field.
usersubscription.DefaultMonthlyUsageUsd = usersubscriptionDescMonthlyUsageUsd.Default.(float64)
// usersubscriptionDescAssignedAt is the schema descriptor for assigned_at field.
usersubscriptionDescAssignedAt := usersubscriptionFields[12].Descriptor()
// usersubscription.DefaultAssignedAt holds the default value on creation for the assigned_at field.
usersubscription.DefaultAssignedAt = usersubscriptionDescAssignedAt.Default.(func() time.Time)
}
const (
Version = "v0.14.5" // Version of ent codegen.
Sum = "h1:Rj2WOYJtCkWyFo6a+5wB3EfBRP0rnx1fMk6gGA0UUe4=" // Sum of ent codegen.
)
// Package schema 定义 Ent ORM 的数据库 schema。
// 每个文件对应一个数据库实体(表),定义其字段、边(关联)和索引。
package schema
import (
"github.com/Wei-Shaw/sub2api/ent/schema/mixins"
"github.com/Wei-Shaw/sub2api/internal/service"
"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"
)
// Account 定义 AI API 账户实体的 schema。
//
// 账户是系统的核心资源,代表一个可用于调用 AI API 的凭证。
// 例如:一个 Claude API 账户、一个 Gemini OAuth 账户等。
//
// 主要功能:
// - 存储不同平台(Claude、Gemini、OpenAI 等)的 API 凭证
// - 支持多种认证类型(api_key、oauth、cookie 等)
// - 管理账户的调度状态(可调度、速率限制、过载等)
// - 通过分组机制实现账户的灵活分配
type Account struct {
ent.Schema
}
// Annotations 返回 schema 的注解配置。
// 这里指定数据库表名为 "accounts"。
func (Account) Annotations() []schema.Annotation {
return []schema.Annotation{
entsql.Annotation{Table: "accounts"},
}
}
// Mixin 返回该 schema 使用的混入组件。
// - TimeMixin: 自动管理 created_at 和 updated_at 时间戳
// - SoftDeleteMixin: 提供软删除功能(deleted_at)
func (Account) Mixin() []ent.Mixin {
return []ent.Mixin{
mixins.TimeMixin{},
mixins.SoftDeleteMixin{},
}
}
// Fields 定义账户实体的所有字段。
func (Account) Fields() []ent.Field {
return []ent.Field{
// name: 账户显示名称,用于在界面中标识账户
field.String("name").
MaxLen(100).
NotEmpty(),
// platform: 所属平台,如 "claude", "gemini", "openai" 等
field.String("platform").
MaxLen(50).
NotEmpty(),
// type: 认证类型,如 "api_key", "oauth", "cookie" 等
// 不同类型决定了 credentials 中存储的数据结构
field.String("type").
MaxLen(20).
NotEmpty(),
// credentials: 认证凭证,以 JSONB 格式存储
// 结构取决于 type 字段:
// - api_key: {"api_key": "sk-xxx"}
// - oauth: {"access_token": "...", "refresh_token": "...", "expires_at": "..."}
// - cookie: {"session_key": "..."}
field.JSON("credentials", map[string]any{}).
Default(func() map[string]any { return map[string]any{} }).
SchemaType(map[string]string{dialect.Postgres: "jsonb"}),
// extra: 扩展数据,存储平台特定的额外信息
// 如 CRS 账户的 crs_account_id、组织信息等
field.JSON("extra", map[string]any{}).
Default(func() map[string]any { return map[string]any{} }).
SchemaType(map[string]string{dialect.Postgres: "jsonb"}),
// proxy_id: 关联的代理配置 ID(可选)
// 用于需要通过特定代理访问 API 的场景
field.Int64("proxy_id").
Optional().
Nillable(),
// concurrency: 账户最大并发请求数
// 用于限制同一时间对该账户发起的请求数量
field.Int("concurrency").
Default(3),
// priority: 账户优先级,数值越小优先级越高
// 调度器会优先使用高优先级的账户
field.Int("priority").
Default(50),
// status: 账户状态,如 "active", "error", "disabled"
field.String("status").
MaxLen(20).
Default(service.StatusActive),
// error_message: 错误信息,记录账户异常时的详细信息
field.String("error_message").
Optional().
Nillable().
SchemaType(map[string]string{dialect.Postgres: "text"}),
// last_used_at: 最后使用时间,用于统计和调度
field.Time("last_used_at").
Optional().
Nillable().
SchemaType(map[string]string{dialect.Postgres: "timestamptz"}),
// ========== 调度和速率限制相关字段 ==========
// 这些字段在 migrations/005_schema_parity.sql 中添加
// schedulable: 是否可被调度器选中
// false 表示账户暂时不参与请求分配(如正在刷新 token)
field.Bool("schedulable").
Default(true),
// rate_limited_at: 触发速率限制的时间
// 当收到 429 错误时记录
field.Time("rate_limited_at").
Optional().
Nillable().
SchemaType(map[string]string{dialect.Postgres: "timestamptz"}),
// rate_limit_reset_at: 速率限制预计解除的时间
// 调度器会在此时间之前避免使用该账户
field.Time("rate_limit_reset_at").
Optional().
Nillable().
SchemaType(map[string]string{dialect.Postgres: "timestamptz"}),
// overload_until: 过载状态解除时间
// 当收到 529 错误(API 过载)时设置
field.Time("overload_until").
Optional().
Nillable().
SchemaType(map[string]string{dialect.Postgres: "timestamptz"}),
// session_window_*: 会话窗口相关字段
// 用于管理某些需要会话时间窗口的 API(如 Claude Pro)
field.Time("session_window_start").
Optional().
Nillable().
SchemaType(map[string]string{dialect.Postgres: "timestamptz"}),
field.Time("session_window_end").
Optional().
Nillable().
SchemaType(map[string]string{dialect.Postgres: "timestamptz"}),
field.String("session_window_status").
Optional().
Nillable().
MaxLen(20),
}
}
// Edges 定义账户实体的关联关系。
func (Account) Edges() []ent.Edge {
return []ent.Edge{
// groups: 账户所属的分组(多对多关系)
// 通过 account_groups 中间表实现
// 一个账户可以属于多个分组,一个分组可以包含多个账户
edge.To("groups", Group.Type).
Through("account_groups", AccountGroup.Type),
}
}
// Indexes 定义数据库索引,优化查询性能。
// 每个索引对应一个常用的查询条件。
func (Account) Indexes() []ent.Index {
return []ent.Index{
index.Fields("platform"), // 按平台筛选
index.Fields("type"), // 按认证类型筛选
index.Fields("status"), // 按状态筛选
index.Fields("proxy_id"), // 按代理筛选
index.Fields("priority"), // 按优先级排序
index.Fields("last_used_at"), // 按最后使用时间排序
index.Fields("schedulable"), // 筛选可调度账户
index.Fields("rate_limited_at"), // 筛选速率限制账户
index.Fields("rate_limit_reset_at"), // 筛选速率限制解除时间
index.Fields("overload_until"), // 筛选过载账户
index.Fields("deleted_at"), // 软删除查询优化
}
}
package schema
import (
"time"
"entgo.io/ent"
"entgo.io/ent/dialect/entsql"
"entgo.io/ent/schema"
"entgo.io/ent/schema/edge"
"entgo.io/ent/schema/field"
"entgo.io/ent/schema/index"
)
// AccountGroup holds the edge schema definition for the account_groups relationship.
// It stores extra fields (priority, created_at) and uses a composite primary key.
type AccountGroup struct {
ent.Schema
}
func (AccountGroup) Annotations() []schema.Annotation {
return []schema.Annotation{
entsql.Annotation{Table: "account_groups"},
// Composite primary key: (account_id, group_id).
field.ID("account_id", "group_id"),
}
}
func (AccountGroup) Fields() []ent.Field {
return []ent.Field{
field.Int64("account_id"),
field.Int64("group_id"),
field.Int("priority").
Default(50),
field.Time("created_at").
Immutable().
Default(time.Now),
}
}
func (AccountGroup) Edges() []ent.Edge {
return []ent.Edge{
edge.To("account", Account.Type).
Unique().
Required().
Field("account_id"),
edge.To("group", Group.Type).
Unique().
Required().
Field("group_id"),
}
}
func (AccountGroup) Indexes() []ent.Index {
return []ent.Index{
index.Fields("group_id"),
index.Fields("priority"),
}
}
package schema
import (
"github.com/Wei-Shaw/sub2api/ent/schema/mixins"
"github.com/Wei-Shaw/sub2api/internal/service"
"entgo.io/ent"
"entgo.io/ent/dialect/entsql"
"entgo.io/ent/schema"
"entgo.io/ent/schema/edge"
"entgo.io/ent/schema/field"
"entgo.io/ent/schema/index"
)
// ApiKey holds the schema definition for the ApiKey entity.
type ApiKey struct {
ent.Schema
}
func (ApiKey) Annotations() []schema.Annotation {
return []schema.Annotation{
entsql.Annotation{Table: "api_keys"},
}
}
func (ApiKey) Mixin() []ent.Mixin {
return []ent.Mixin{
mixins.TimeMixin{},
mixins.SoftDeleteMixin{},
}
}
func (ApiKey) Fields() []ent.Field {
return []ent.Field{
field.Int64("user_id"),
field.String("key").
MaxLen(128).
NotEmpty().
Unique(),
field.String("name").
MaxLen(100).
NotEmpty(),
field.Int64("group_id").
Optional().
Nillable(),
field.String("status").
MaxLen(20).
Default(service.StatusActive),
}
}
func (ApiKey) Edges() []ent.Edge {
return []ent.Edge{
edge.From("user", User.Type).
Ref("api_keys").
Field("user_id").
Unique().
Required(),
edge.From("group", Group.Type).
Ref("api_keys").
Field("group_id").
Unique(),
}
}
func (ApiKey) Indexes() []ent.Index {
return []ent.Index{
index.Fields("key").Unique(),
index.Fields("user_id"),
index.Fields("group_id"),
index.Fields("status"),
index.Fields("deleted_at"),
}
}
package schema
import (
"github.com/Wei-Shaw/sub2api/ent/schema/mixins"
"github.com/Wei-Shaw/sub2api/internal/service"
"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"
)
// Group holds the schema definition for the Group entity.
type Group struct {
ent.Schema
}
func (Group) Annotations() []schema.Annotation {
return []schema.Annotation{
entsql.Annotation{Table: "groups"},
}
}
func (Group) Mixin() []ent.Mixin {
return []ent.Mixin{
mixins.TimeMixin{},
mixins.SoftDeleteMixin{},
}
}
func (Group) Fields() []ent.Field {
return []ent.Field{
field.String("name").
MaxLen(100).
NotEmpty().
Unique(),
field.String("description").
Optional().
Nillable().
SchemaType(map[string]string{dialect.Postgres: "text"}),
field.Float("rate_multiplier").
SchemaType(map[string]string{dialect.Postgres: "decimal(10,4)"}).
Default(1.0),
field.Bool("is_exclusive").
Default(false),
field.String("status").
MaxLen(20).
Default(service.StatusActive),
// Subscription-related fields (added by migration 003)
field.String("platform").
MaxLen(50).
Default(service.PlatformAnthropic),
field.String("subscription_type").
MaxLen(20).
Default(service.SubscriptionTypeStandard),
field.Float("daily_limit_usd").
Optional().
Nillable().
SchemaType(map[string]string{dialect.Postgres: "decimal(20,8)"}),
field.Float("weekly_limit_usd").
Optional().
Nillable().
SchemaType(map[string]string{dialect.Postgres: "decimal(20,8)"}),
field.Float("monthly_limit_usd").
Optional().
Nillable().
SchemaType(map[string]string{dialect.Postgres: "decimal(20,8)"}),
}
}
func (Group) Edges() []ent.Edge {
return []ent.Edge{
edge.To("api_keys", ApiKey.Type),
edge.To("redeem_codes", RedeemCode.Type),
edge.To("subscriptions", UserSubscription.Type),
edge.From("accounts", Account.Type).
Ref("groups").
Through("account_groups", AccountGroup.Type),
edge.From("allowed_users", User.Type).
Ref("allowed_groups").
Through("user_allowed_groups", UserAllowedGroup.Type),
}
}
func (Group) Indexes() []ent.Index {
return []ent.Index{
index.Fields("name").Unique(),
index.Fields("status"),
index.Fields("platform"),
index.Fields("subscription_type"),
index.Fields("is_exclusive"),
index.Fields("deleted_at"),
}
}
// Package mixins 提供 Ent schema 的可复用混入组件。
// 包括时间戳混入、软删除混入等通用功能。
package mixins
import (
"context"
"fmt"
"time"
"entgo.io/ent"
"entgo.io/ent/dialect"
"entgo.io/ent/dialect/sql"
"entgo.io/ent/schema/field"
"entgo.io/ent/schema/mixin"
"github.com/Wei-Shaw/sub2api/ent/intercept"
)
// SoftDeleteMixin 实现基于 deleted_at 时间戳的软删除功能。
//
// 软删除特性:
// - 删除操作不会真正删除数据库记录,而是设置 deleted_at 时间戳
// - 所有查询默认自动过滤 deleted_at IS NULL,只返回"未删除"的记录
// - 通过 SkipSoftDelete(ctx) 可以绕过软删除过滤器,查询或真正删除记录
//
// 实现原理:
// - 使用 Ent 的 Interceptor 拦截所有查询,自动添加 deleted_at IS NULL 条件
// - 使用 Ent 的 Hook 拦截删除操作,将 DELETE 转换为 UPDATE SET deleted_at = NOW()
//
// 使用示例:
//
// func (User) Mixin() []ent.Mixin {
// return []ent.Mixin{
// mixins.SoftDeleteMixin{},
// }
// }
type SoftDeleteMixin struct {
mixin.Schema
}
// Fields 定义软删除所需的字段。
// deleted_at 字段:
// - 类型为 TIMESTAMPTZ,精确记录删除时间
// - Optional 和 Nillable 确保新记录时该字段为 NULL
// - NULL 表示记录未被删除,非 NULL 表示已软删除
func (SoftDeleteMixin) Fields() []ent.Field {
return []ent.Field{
field.Time("deleted_at").
Optional().
Nillable().
SchemaType(map[string]string{
dialect.Postgres: "timestamptz",
}),
}
}
// softDeleteKey 是用于在 context 中标记跳过软删除的键类型。
// 使用空结构体作为键可以避免与其他包的键冲突。
type softDeleteKey struct{}
// SkipSoftDelete 返回一个新的 context,用于跳过软删除的拦截器和变更器。
//
// 使用场景:
// - 查询已软删除的记录(如管理员查看回收站)
// - 执行真正的物理删除(如彻底清理数据)
// - 恢复软删除的记录
//
// 示例:
//
// // 查询包含已删除记录的所有用户
// users, err := client.User.Query().All(mixins.SkipSoftDelete(ctx))
//
// // 真正删除记录
// client.User.DeleteOneID(id).Exec(mixins.SkipSoftDelete(ctx))
func SkipSoftDelete(parent context.Context) context.Context {
return context.WithValue(parent, softDeleteKey{}, true)
}
// Interceptors 返回查询拦截器列表。
// 拦截器会自动为所有查询添加 deleted_at IS NULL 条件,
// 确保软删除的记录不会出现在普通查询结果中。
func (d SoftDeleteMixin) Interceptors() []ent.Interceptor {
return []ent.Interceptor{
intercept.TraverseFunc(func(ctx context.Context, q intercept.Query) error {
// 检查是否需要跳过软删除过滤
if skip, _ := ctx.Value(softDeleteKey{}).(bool); skip {
return nil
}
// 为查询添加 deleted_at IS NULL 条件
d.applyPredicate(q)
return nil
}),
}
}
// Hooks 返回变更钩子列表。
// 钩子会拦截 DELETE 操作,将其转换为 UPDATE SET deleted_at = NOW()。
// 这样删除操作实际上只是标记记录为已删除,而不是真正删除。
func (d SoftDeleteMixin) Hooks() []ent.Hook {
return []ent.Hook{
func(next ent.Mutator) ent.Mutator {
return ent.MutateFunc(func(ctx context.Context, m ent.Mutation) (ent.Value, error) {
// 只处理删除操作
if m.Op() != ent.OpDelete && m.Op() != ent.OpDeleteOne {
return next.Mutate(ctx, m)
}
// 检查是否需要执行真正的删除
if skip, _ := ctx.Value(softDeleteKey{}).(bool); skip {
return next.Mutate(ctx, m)
}
// 类型断言,获取 mutation 的扩展接口
mx, ok := m.(interface {
SetOp(ent.Op)
SetDeletedAt(time.Time)
WhereP(...func(*sql.Selector))
})
if !ok {
return nil, fmt.Errorf("unexpected mutation type %T", m)
}
// 添加软删除过滤条件,确保不会影响已删除的记录
d.applyPredicate(mx)
// 将 DELETE 操作转换为 UPDATE 操作
mx.SetOp(ent.OpUpdate)
// 设置删除时间为当前时间
mx.SetDeletedAt(time.Now())
return next.Mutate(ctx, m)
})
},
}
}
// applyPredicate 为查询添加 deleted_at IS NULL 条件。
// 这是软删除过滤的核心实现。
func (d SoftDeleteMixin) applyPredicate(w interface{ WhereP(...func(*sql.Selector)) }) {
w.WhereP(
sql.FieldIsNull(d.Fields()[0].Descriptor().Name),
)
}
package mixins
import (
"time"
"entgo.io/ent"
"entgo.io/ent/dialect"
"entgo.io/ent/schema/field"
"entgo.io/ent/schema/mixin"
)
// TimeMixin provides created_at and updated_at fields compatible with the existing schema.
type TimeMixin struct {
mixin.Schema
}
func (TimeMixin) Fields() []ent.Field {
return []ent.Field{
field.Time("created_at").
Immutable().
Default(time.Now).
SchemaType(map[string]string{
dialect.Postgres: "timestamptz",
}),
field.Time("updated_at").
Default(time.Now).
UpdateDefault(time.Now).
SchemaType(map[string]string{
dialect.Postgres: "timestamptz",
}),
}
}
package schema
import (
"github.com/Wei-Shaw/sub2api/ent/schema/mixins"
"entgo.io/ent"
"entgo.io/ent/dialect/entsql"
"entgo.io/ent/schema"
"entgo.io/ent/schema/field"
"entgo.io/ent/schema/index"
)
// Proxy holds the schema definition for the Proxy entity.
type Proxy struct {
ent.Schema
}
func (Proxy) Annotations() []schema.Annotation {
return []schema.Annotation{
entsql.Annotation{Table: "proxies"},
}
}
func (Proxy) Mixin() []ent.Mixin {
return []ent.Mixin{
mixins.TimeMixin{},
mixins.SoftDeleteMixin{},
}
}
func (Proxy) Fields() []ent.Field {
return []ent.Field{
field.String("name").
MaxLen(100).
NotEmpty(),
field.String("protocol").
MaxLen(20).
NotEmpty(),
field.String("host").
MaxLen(255).
NotEmpty(),
field.Int("port"),
field.String("username").
MaxLen(100).
Optional().
Nillable(),
field.String("password").
MaxLen(100).
Optional().
Nillable(),
field.String("status").
MaxLen(20).
Default("active"),
}
}
func (Proxy) Indexes() []ent.Index {
return []ent.Index{
index.Fields("status"),
index.Fields("deleted_at"),
}
}
package schema
import (
"time"
"github.com/Wei-Shaw/sub2api/internal/service"
"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"
)
// RedeemCode holds the schema definition for the RedeemCode entity.
type RedeemCode struct {
ent.Schema
}
func (RedeemCode) Annotations() []schema.Annotation {
return []schema.Annotation{
entsql.Annotation{Table: "redeem_codes"},
}
}
func (RedeemCode) Fields() []ent.Field {
return []ent.Field{
field.String("code").
MaxLen(32).
NotEmpty().
Unique(),
field.String("type").
MaxLen(20).
Default(service.RedeemTypeBalance),
field.Float("value").
SchemaType(map[string]string{dialect.Postgres: "decimal(20,8)"}).
Default(0),
field.String("status").
MaxLen(20).
Default(service.StatusUnused),
field.Int64("used_by").
Optional().
Nillable(),
field.Time("used_at").
Optional().
Nillable().
SchemaType(map[string]string{dialect.Postgres: "timestamptz"}),
field.String("notes").
Optional().
Nillable().
SchemaType(map[string]string{dialect.Postgres: "text"}),
field.Time("created_at").
Immutable().
Default(time.Now).
SchemaType(map[string]string{dialect.Postgres: "timestamptz"}),
field.Int64("group_id").
Optional().
Nillable(),
field.Int("validity_days").
Default(30),
}
}
func (RedeemCode) Edges() []ent.Edge {
return []ent.Edge{
edge.From("user", User.Type).
Ref("redeem_codes").
Field("used_by").
Unique(),
edge.From("group", Group.Type).
Ref("redeem_codes").
Field("group_id").
Unique(),
}
}
func (RedeemCode) Indexes() []ent.Index {
return []ent.Index{
index.Fields("code").Unique(),
index.Fields("status"),
index.Fields("used_by"),
index.Fields("group_id"),
}
}
package schema
import (
"time"
"entgo.io/ent"
"entgo.io/ent/dialect"
"entgo.io/ent/dialect/entsql"
"entgo.io/ent/schema"
"entgo.io/ent/schema/field"
"entgo.io/ent/schema/index"
)
// Setting holds the schema definition for the Setting entity.
type Setting struct {
ent.Schema
}
func (Setting) Annotations() []schema.Annotation {
return []schema.Annotation{
entsql.Annotation{Table: "settings"},
}
}
func (Setting) Fields() []ent.Field {
return []ent.Field{
field.String("key").
MaxLen(100).
NotEmpty().
Unique(),
field.String("value").
NotEmpty().
SchemaType(map[string]string{
dialect.Postgres: "text",
}),
field.Time("updated_at").
Default(time.Now).
UpdateDefault(time.Now).
SchemaType(map[string]string{
dialect.Postgres: "timestamptz",
}),
}
}
func (Setting) Indexes() []ent.Index {
return []ent.Index{
index.Fields("key").Unique(),
}
}
package schema
import (
"github.com/Wei-Shaw/sub2api/ent/schema/mixins"
"github.com/Wei-Shaw/sub2api/internal/service"
"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"
)
// User holds the schema definition for the User entity.
type User struct {
ent.Schema
}
func (User) Annotations() []schema.Annotation {
return []schema.Annotation{
entsql.Annotation{Table: "users"},
}
}
func (User) Mixin() []ent.Mixin {
return []ent.Mixin{
mixins.TimeMixin{},
mixins.SoftDeleteMixin{},
}
}
func (User) Fields() []ent.Field {
return []ent.Field{
field.String("email").
MaxLen(255).
NotEmpty().
Unique(),
field.String("password_hash").
MaxLen(255).
NotEmpty(),
field.String("role").
MaxLen(20).
Default(service.RoleUser),
field.Float("balance").
SchemaType(map[string]string{dialect.Postgres: "decimal(20,8)"}).
Default(0),
field.Int("concurrency").
Default(5),
field.String("status").
MaxLen(20).
Default(service.StatusActive),
// Optional profile fields (added later; default '' in DB migration)
field.String("username").
MaxLen(100).
Default(""),
field.String("wechat").
MaxLen(100).
Default(""),
field.String("notes").
SchemaType(map[string]string{dialect.Postgres: "text"}).
Default(""),
}
}
func (User) Edges() []ent.Edge {
return []ent.Edge{
edge.To("api_keys", ApiKey.Type),
edge.To("redeem_codes", RedeemCode.Type),
edge.To("subscriptions", UserSubscription.Type),
edge.To("assigned_subscriptions", UserSubscription.Type),
edge.To("allowed_groups", Group.Type).
Through("user_allowed_groups", UserAllowedGroup.Type),
}
}
func (User) Indexes() []ent.Index {
return []ent.Index{
index.Fields("email").Unique(),
index.Fields("status"),
index.Fields("deleted_at"),
}
}
package schema
import (
"time"
"entgo.io/ent"
"entgo.io/ent/dialect/entsql"
"entgo.io/ent/schema"
"entgo.io/ent/schema/edge"
"entgo.io/ent/schema/field"
"entgo.io/ent/schema/index"
)
// UserAllowedGroup holds the edge schema definition for the user_allowed_groups relationship.
// It replaces the legacy users.allowed_groups BIGINT[] column.
type UserAllowedGroup struct {
ent.Schema
}
func (UserAllowedGroup) Annotations() []schema.Annotation {
return []schema.Annotation{
entsql.Annotation{Table: "user_allowed_groups"},
// Composite primary key: (user_id, group_id).
field.ID("user_id", "group_id"),
}
}
func (UserAllowedGroup) Fields() []ent.Field {
return []ent.Field{
field.Int64("user_id"),
field.Int64("group_id"),
field.Time("created_at").
Immutable().
Default(time.Now),
}
}
func (UserAllowedGroup) Edges() []ent.Edge {
return []ent.Edge{
edge.To("user", User.Type).
Unique().
Required().
Field("user_id"),
edge.To("group", Group.Type).
Unique().
Required().
Field("group_id"),
}
}
func (UserAllowedGroup) Indexes() []ent.Index {
return []ent.Index{
index.Fields("group_id"),
}
}
package schema
import (
"time"
"github.com/Wei-Shaw/sub2api/ent/schema/mixins"
"github.com/Wei-Shaw/sub2api/internal/service"
"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"
)
// UserSubscription holds the schema definition for the UserSubscription entity.
type UserSubscription struct {
ent.Schema
}
func (UserSubscription) Annotations() []schema.Annotation {
return []schema.Annotation{
entsql.Annotation{Table: "user_subscriptions"},
}
}
func (UserSubscription) Mixin() []ent.Mixin {
return []ent.Mixin{
mixins.TimeMixin{},
}
}
func (UserSubscription) Fields() []ent.Field {
return []ent.Field{
field.Int64("user_id"),
field.Int64("group_id"),
field.Time("starts_at").
SchemaType(map[string]string{dialect.Postgres: "timestamptz"}),
field.Time("expires_at").
SchemaType(map[string]string{dialect.Postgres: "timestamptz"}),
field.String("status").
MaxLen(20).
Default(service.SubscriptionStatusActive),
field.Time("daily_window_start").
Optional().
Nillable().
SchemaType(map[string]string{dialect.Postgres: "timestamptz"}),
field.Time("weekly_window_start").
Optional().
Nillable().
SchemaType(map[string]string{dialect.Postgres: "timestamptz"}),
field.Time("monthly_window_start").
Optional().
Nillable().
SchemaType(map[string]string{dialect.Postgres: "timestamptz"}),
field.Float("daily_usage_usd").
SchemaType(map[string]string{dialect.Postgres: "decimal(20,10)"}).
Default(0),
field.Float("weekly_usage_usd").
SchemaType(map[string]string{dialect.Postgres: "decimal(20,10)"}).
Default(0),
field.Float("monthly_usage_usd").
SchemaType(map[string]string{dialect.Postgres: "decimal(20,10)"}).
Default(0),
field.Int64("assigned_by").
Optional().
Nillable(),
field.Time("assigned_at").
Default(time.Now).
SchemaType(map[string]string{dialect.Postgres: "timestamptz"}),
field.String("notes").
Optional().
Nillable().
SchemaType(map[string]string{dialect.Postgres: "text"}),
}
}
func (UserSubscription) Edges() []ent.Edge {
return []ent.Edge{
edge.From("user", User.Type).
Ref("subscriptions").
Field("user_id").
Unique().
Required(),
edge.From("group", Group.Type).
Ref("subscriptions").
Field("group_id").
Unique().
Required(),
edge.From("assigned_by_user", User.Type).
Ref("assigned_subscriptions").
Field("assigned_by").
Unique(),
}
}
func (UserSubscription) Indexes() []ent.Index {
return []ent.Index{
index.Fields("user_id"),
index.Fields("group_id"),
index.Fields("status"),
index.Fields("expires_at"),
index.Fields("assigned_by"),
index.Fields("user_id", "group_id").Unique(),
}
}
// Code generated by ent, DO NOT EDIT.
package ent
import (
"fmt"
"strings"
"time"
"entgo.io/ent"
"entgo.io/ent/dialect/sql"
"github.com/Wei-Shaw/sub2api/ent/setting"
)
// Setting is the model entity for the Setting schema.
type Setting struct {
config `json:"-"`
// ID of the ent.
ID int64 `json:"id,omitempty"`
// Key holds the value of the "key" field.
Key string `json:"key,omitempty"`
// Value holds the value of the "value" field.
Value string `json:"value,omitempty"`
// UpdatedAt holds the value of the "updated_at" field.
UpdatedAt time.Time `json:"updated_at,omitempty"`
selectValues sql.SelectValues
}
// scanValues returns the types for scanning values from sql.Rows.
func (*Setting) scanValues(columns []string) ([]any, error) {
values := make([]any, len(columns))
for i := range columns {
switch columns[i] {
case setting.FieldID:
values[i] = new(sql.NullInt64)
case setting.FieldKey, setting.FieldValue:
values[i] = new(sql.NullString)
case setting.FieldUpdatedAt:
values[i] = new(sql.NullTime)
default:
values[i] = new(sql.UnknownType)
}
}
return values, nil
}
// assignValues assigns the values that were returned from sql.Rows (after scanning)
// to the Setting fields.
func (_m *Setting) assignValues(columns []string, values []any) error {
if m, n := len(values), len(columns); m < n {
return fmt.Errorf("mismatch number of scan values: %d != %d", m, n)
}
for i := range columns {
switch columns[i] {
case setting.FieldID:
value, ok := values[i].(*sql.NullInt64)
if !ok {
return fmt.Errorf("unexpected type %T for field id", value)
}
_m.ID = int64(value.Int64)
case setting.FieldKey:
if value, ok := values[i].(*sql.NullString); !ok {
return fmt.Errorf("unexpected type %T for field key", values[i])
} else if value.Valid {
_m.Key = value.String
}
case setting.FieldValue:
if value, ok := values[i].(*sql.NullString); !ok {
return fmt.Errorf("unexpected type %T for field value", values[i])
} else if value.Valid {
_m.Value = value.String
}
case setting.FieldUpdatedAt:
if value, ok := values[i].(*sql.NullTime); !ok {
return fmt.Errorf("unexpected type %T for field updated_at", values[i])
} else if value.Valid {
_m.UpdatedAt = value.Time
}
default:
_m.selectValues.Set(columns[i], values[i])
}
}
return nil
}
// GetValue returns the ent.Value that was dynamically selected and assigned to the Setting.
// This includes values selected through modifiers, order, etc.
func (_m *Setting) GetValue(name string) (ent.Value, error) {
return _m.selectValues.Get(name)
}
// Update returns a builder for updating this Setting.
// Note that you need to call Setting.Unwrap() before calling this method if this Setting
// was returned from a transaction, and the transaction was committed or rolled back.
func (_m *Setting) Update() *SettingUpdateOne {
return NewSettingClient(_m.config).UpdateOne(_m)
}
// Unwrap unwraps the Setting entity that was returned from a transaction after it was closed,
// so that all future queries will be executed through the driver which created the transaction.
func (_m *Setting) Unwrap() *Setting {
_tx, ok := _m.config.driver.(*txDriver)
if !ok {
panic("ent: Setting is not a transactional entity")
}
_m.config.driver = _tx.drv
return _m
}
// String implements the fmt.Stringer.
func (_m *Setting) String() string {
var builder strings.Builder
builder.WriteString("Setting(")
builder.WriteString(fmt.Sprintf("id=%v, ", _m.ID))
builder.WriteString("key=")
builder.WriteString(_m.Key)
builder.WriteString(", ")
builder.WriteString("value=")
builder.WriteString(_m.Value)
builder.WriteString(", ")
builder.WriteString("updated_at=")
builder.WriteString(_m.UpdatedAt.Format(time.ANSIC))
builder.WriteByte(')')
return builder.String()
}
// Settings is a parsable slice of Setting.
type Settings []*Setting
// Code generated by ent, DO NOT EDIT.
package setting
import (
"time"
"entgo.io/ent/dialect/sql"
)
const (
// Label holds the string label denoting the setting type in the database.
Label = "setting"
// FieldID holds the string denoting the id field in the database.
FieldID = "id"
// FieldKey holds the string denoting the key field in the database.
FieldKey = "key"
// FieldValue holds the string denoting the value field in the database.
FieldValue = "value"
// FieldUpdatedAt holds the string denoting the updated_at field in the database.
FieldUpdatedAt = "updated_at"
// Table holds the table name of the setting in the database.
Table = "settings"
)
// Columns holds all SQL columns for setting fields.
var Columns = []string{
FieldID,
FieldKey,
FieldValue,
FieldUpdatedAt,
}
// ValidColumn reports if the column name is valid (part of the table columns).
func ValidColumn(column string) bool {
for i := range Columns {
if column == Columns[i] {
return true
}
}
return false
}
var (
// KeyValidator is a validator for the "key" field. It is called by the builders before save.
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 func() time.Time
// UpdateDefaultUpdatedAt holds the default value on update for the "updated_at" field.
UpdateDefaultUpdatedAt func() time.Time
)
// OrderOption defines the ordering options for the Setting queries.
type OrderOption func(*sql.Selector)
// ByID orders the results by the id field.
func ByID(opts ...sql.OrderTermOption) OrderOption {
return sql.OrderByField(FieldID, opts...).ToFunc()
}
// ByKey orders the results by the key field.
func ByKey(opts ...sql.OrderTermOption) OrderOption {
return sql.OrderByField(FieldKey, opts...).ToFunc()
}
// ByValue orders the results by the value field.
func ByValue(opts ...sql.OrderTermOption) OrderOption {
return sql.OrderByField(FieldValue, opts...).ToFunc()
}
// ByUpdatedAt orders the results by the updated_at field.
func ByUpdatedAt(opts ...sql.OrderTermOption) OrderOption {
return sql.OrderByField(FieldUpdatedAt, opts...).ToFunc()
}
// Code generated by ent, DO NOT EDIT.
package setting
import (
"time"
"entgo.io/ent/dialect/sql"
"github.com/Wei-Shaw/sub2api/ent/predicate"
)
// ID filters vertices based on their ID field.
func ID(id int64) predicate.Setting {
return predicate.Setting(sql.FieldEQ(FieldID, id))
}
// IDEQ applies the EQ predicate on the ID field.
func IDEQ(id int64) predicate.Setting {
return predicate.Setting(sql.FieldEQ(FieldID, id))
}
// IDNEQ applies the NEQ predicate on the ID field.
func IDNEQ(id int64) predicate.Setting {
return predicate.Setting(sql.FieldNEQ(FieldID, id))
}
// IDIn applies the In predicate on the ID field.
func IDIn(ids ...int64) predicate.Setting {
return predicate.Setting(sql.FieldIn(FieldID, ids...))
}
// IDNotIn applies the NotIn predicate on the ID field.
func IDNotIn(ids ...int64) predicate.Setting {
return predicate.Setting(sql.FieldNotIn(FieldID, ids...))
}
// IDGT applies the GT predicate on the ID field.
func IDGT(id int64) predicate.Setting {
return predicate.Setting(sql.FieldGT(FieldID, id))
}
// IDGTE applies the GTE predicate on the ID field.
func IDGTE(id int64) predicate.Setting {
return predicate.Setting(sql.FieldGTE(FieldID, id))
}
// IDLT applies the LT predicate on the ID field.
func IDLT(id int64) predicate.Setting {
return predicate.Setting(sql.FieldLT(FieldID, id))
}
// IDLTE applies the LTE predicate on the ID field.
func IDLTE(id int64) predicate.Setting {
return predicate.Setting(sql.FieldLTE(FieldID, id))
}
// Key applies equality check predicate on the "key" field. It's identical to KeyEQ.
func Key(v string) predicate.Setting {
return predicate.Setting(sql.FieldEQ(FieldKey, v))
}
// Value applies equality check predicate on the "value" field. It's identical to ValueEQ.
func Value(v string) predicate.Setting {
return predicate.Setting(sql.FieldEQ(FieldValue, v))
}
// UpdatedAt applies equality check predicate on the "updated_at" field. It's identical to UpdatedAtEQ.
func UpdatedAt(v time.Time) predicate.Setting {
return predicate.Setting(sql.FieldEQ(FieldUpdatedAt, v))
}
// KeyEQ applies the EQ predicate on the "key" field.
func KeyEQ(v string) predicate.Setting {
return predicate.Setting(sql.FieldEQ(FieldKey, v))
}
// KeyNEQ applies the NEQ predicate on the "key" field.
func KeyNEQ(v string) predicate.Setting {
return predicate.Setting(sql.FieldNEQ(FieldKey, v))
}
// KeyIn applies the In predicate on the "key" field.
func KeyIn(vs ...string) predicate.Setting {
return predicate.Setting(sql.FieldIn(FieldKey, vs...))
}
// KeyNotIn applies the NotIn predicate on the "key" field.
func KeyNotIn(vs ...string) predicate.Setting {
return predicate.Setting(sql.FieldNotIn(FieldKey, vs...))
}
// KeyGT applies the GT predicate on the "key" field.
func KeyGT(v string) predicate.Setting {
return predicate.Setting(sql.FieldGT(FieldKey, v))
}
// KeyGTE applies the GTE predicate on the "key" field.
func KeyGTE(v string) predicate.Setting {
return predicate.Setting(sql.FieldGTE(FieldKey, v))
}
// KeyLT applies the LT predicate on the "key" field.
func KeyLT(v string) predicate.Setting {
return predicate.Setting(sql.FieldLT(FieldKey, v))
}
// KeyLTE applies the LTE predicate on the "key" field.
func KeyLTE(v string) predicate.Setting {
return predicate.Setting(sql.FieldLTE(FieldKey, v))
}
// KeyContains applies the Contains predicate on the "key" field.
func KeyContains(v string) predicate.Setting {
return predicate.Setting(sql.FieldContains(FieldKey, v))
}
// KeyHasPrefix applies the HasPrefix predicate on the "key" field.
func KeyHasPrefix(v string) predicate.Setting {
return predicate.Setting(sql.FieldHasPrefix(FieldKey, v))
}
// KeyHasSuffix applies the HasSuffix predicate on the "key" field.
func KeyHasSuffix(v string) predicate.Setting {
return predicate.Setting(sql.FieldHasSuffix(FieldKey, v))
}
// KeyEqualFold applies the EqualFold predicate on the "key" field.
func KeyEqualFold(v string) predicate.Setting {
return predicate.Setting(sql.FieldEqualFold(FieldKey, v))
}
// KeyContainsFold applies the ContainsFold predicate on the "key" field.
func KeyContainsFold(v string) predicate.Setting {
return predicate.Setting(sql.FieldContainsFold(FieldKey, v))
}
// ValueEQ applies the EQ predicate on the "value" field.
func ValueEQ(v string) predicate.Setting {
return predicate.Setting(sql.FieldEQ(FieldValue, v))
}
// ValueNEQ applies the NEQ predicate on the "value" field.
func ValueNEQ(v string) predicate.Setting {
return predicate.Setting(sql.FieldNEQ(FieldValue, v))
}
// ValueIn applies the In predicate on the "value" field.
func ValueIn(vs ...string) predicate.Setting {
return predicate.Setting(sql.FieldIn(FieldValue, vs...))
}
// ValueNotIn applies the NotIn predicate on the "value" field.
func ValueNotIn(vs ...string) predicate.Setting {
return predicate.Setting(sql.FieldNotIn(FieldValue, vs...))
}
// ValueGT applies the GT predicate on the "value" field.
func ValueGT(v string) predicate.Setting {
return predicate.Setting(sql.FieldGT(FieldValue, v))
}
// ValueGTE applies the GTE predicate on the "value" field.
func ValueGTE(v string) predicate.Setting {
return predicate.Setting(sql.FieldGTE(FieldValue, v))
}
// ValueLT applies the LT predicate on the "value" field.
func ValueLT(v string) predicate.Setting {
return predicate.Setting(sql.FieldLT(FieldValue, v))
}
// ValueLTE applies the LTE predicate on the "value" field.
func ValueLTE(v string) predicate.Setting {
return predicate.Setting(sql.FieldLTE(FieldValue, v))
}
// ValueContains applies the Contains predicate on the "value" field.
func ValueContains(v string) predicate.Setting {
return predicate.Setting(sql.FieldContains(FieldValue, v))
}
// ValueHasPrefix applies the HasPrefix predicate on the "value" field.
func ValueHasPrefix(v string) predicate.Setting {
return predicate.Setting(sql.FieldHasPrefix(FieldValue, v))
}
// ValueHasSuffix applies the HasSuffix predicate on the "value" field.
func ValueHasSuffix(v string) predicate.Setting {
return predicate.Setting(sql.FieldHasSuffix(FieldValue, v))
}
// ValueEqualFold applies the EqualFold predicate on the "value" field.
func ValueEqualFold(v string) predicate.Setting {
return predicate.Setting(sql.FieldEqualFold(FieldValue, v))
}
// ValueContainsFold applies the ContainsFold predicate on the "value" field.
func ValueContainsFold(v string) predicate.Setting {
return predicate.Setting(sql.FieldContainsFold(FieldValue, v))
}
// UpdatedAtEQ applies the EQ predicate on the "updated_at" field.
func UpdatedAtEQ(v time.Time) predicate.Setting {
return predicate.Setting(sql.FieldEQ(FieldUpdatedAt, v))
}
// UpdatedAtNEQ applies the NEQ predicate on the "updated_at" field.
func UpdatedAtNEQ(v time.Time) predicate.Setting {
return predicate.Setting(sql.FieldNEQ(FieldUpdatedAt, v))
}
// UpdatedAtIn applies the In predicate on the "updated_at" field.
func UpdatedAtIn(vs ...time.Time) predicate.Setting {
return predicate.Setting(sql.FieldIn(FieldUpdatedAt, vs...))
}
// UpdatedAtNotIn applies the NotIn predicate on the "updated_at" field.
func UpdatedAtNotIn(vs ...time.Time) predicate.Setting {
return predicate.Setting(sql.FieldNotIn(FieldUpdatedAt, vs...))
}
// UpdatedAtGT applies the GT predicate on the "updated_at" field.
func UpdatedAtGT(v time.Time) predicate.Setting {
return predicate.Setting(sql.FieldGT(FieldUpdatedAt, v))
}
// UpdatedAtGTE applies the GTE predicate on the "updated_at" field.
func UpdatedAtGTE(v time.Time) predicate.Setting {
return predicate.Setting(sql.FieldGTE(FieldUpdatedAt, v))
}
// UpdatedAtLT applies the LT predicate on the "updated_at" field.
func UpdatedAtLT(v time.Time) predicate.Setting {
return predicate.Setting(sql.FieldLT(FieldUpdatedAt, v))
}
// UpdatedAtLTE applies the LTE predicate on the "updated_at" field.
func UpdatedAtLTE(v time.Time) predicate.Setting {
return predicate.Setting(sql.FieldLTE(FieldUpdatedAt, v))
}
// And groups predicates with the AND operator between them.
func And(predicates ...predicate.Setting) predicate.Setting {
return predicate.Setting(sql.AndPredicates(predicates...))
}
// Or groups predicates with the OR operator between them.
func Or(predicates ...predicate.Setting) predicate.Setting {
return predicate.Setting(sql.OrPredicates(predicates...))
}
// Not applies the not operator on the given predicate.
func Not(p predicate.Setting) predicate.Setting {
return predicate.Setting(sql.NotPredicates(p))
}
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