// Code generated by gorm.io/gen. DO NOT EDIT.
// Code generated by gorm.io/gen. DO NOT EDIT.
// Code generated by gorm.io/gen. DO NOT EDIT.

package query

import (
	"context"
	"database/sql"

	"gorm.io/gorm"
	"gorm.io/gorm/clause"
	"gorm.io/gorm/schema"

	"gorm.io/gen"
	"gorm.io/gen/field"

	"gorm.io/plugin/dbresolver"

	"stream.api/internal/database/model"
)

func newPlan(db *gorm.DB, opts ...gen.DOOption) plan {
	_plan := plan{}

	_plan.planDo.UseDB(db, opts...)
	_plan.planDo.UseModel(&model.Plan{})

	tableName := _plan.planDo.TableName()
	_plan.ALL = field.NewAsterisk(tableName)
	_plan.ID = field.NewString(tableName, "id")
	_plan.Name = field.NewString(tableName, "name")
	_plan.Description = field.NewString(tableName, "description")
	_plan.Price = field.NewFloat64(tableName, "price")
	_plan.Cycle = field.NewString(tableName, "cycle")
	_plan.StorageLimit = field.NewInt64(tableName, "storage_limit")
	_plan.UploadLimit = field.NewInt32(tableName, "upload_limit")
	_plan.DurationLimit = field.NewInt32(tableName, "duration_limit")
	_plan.QualityLimit = field.NewString(tableName, "quality_limit")
	_plan.Features = field.NewField(tableName, "features")
	_plan.IsActive = field.NewBool(tableName, "is_active")
	_plan.Version = field.NewInt64(tableName, "version")

	_plan.fillFieldMap()

	return _plan
}

type plan struct {
	planDo planDo

	ALL           field.Asterisk
	ID            field.String
	Name          field.String
	Description   field.String
	Price         field.Float64
	Cycle         field.String
	StorageLimit  field.Int64
	UploadLimit   field.Int32
	DurationLimit field.Int32
	QualityLimit  field.String
	Features      field.Field
	IsActive      field.Bool
	Version       field.Int64

	fieldMap map[string]field.Expr
}

func (p plan) Table(newTableName string) *plan {
	p.planDo.UseTable(newTableName)
	return p.updateTableName(newTableName)
}

func (p plan) As(alias string) *plan {
	p.planDo.DO = *(p.planDo.As(alias).(*gen.DO))
	return p.updateTableName(alias)
}

func (p *plan) updateTableName(table string) *plan {
	p.ALL = field.NewAsterisk(table)
	p.ID = field.NewString(table, "id")
	p.Name = field.NewString(table, "name")
	p.Description = field.NewString(table, "description")
	p.Price = field.NewFloat64(table, "price")
	p.Cycle = field.NewString(table, "cycle")
	p.StorageLimit = field.NewInt64(table, "storage_limit")
	p.UploadLimit = field.NewInt32(table, "upload_limit")
	p.DurationLimit = field.NewInt32(table, "duration_limit")
	p.QualityLimit = field.NewString(table, "quality_limit")
	p.Features = field.NewField(table, "features")
	p.IsActive = field.NewBool(table, "is_active")
	p.Version = field.NewInt64(table, "version")

	p.fillFieldMap()

	return p
}

func (p *plan) WithContext(ctx context.Context) IPlanDo { return p.planDo.WithContext(ctx) }

func (p plan) TableName() string { return p.planDo.TableName() }

func (p plan) Alias() string { return p.planDo.Alias() }

func (p plan) Columns(cols ...field.Expr) gen.Columns { return p.planDo.Columns(cols...) }

func (p *plan) GetFieldByName(fieldName string) (field.OrderExpr, bool) {
	_f, ok := p.fieldMap[fieldName]
	if !ok || _f == nil {
		return nil, false
	}
	_oe, ok := _f.(field.OrderExpr)
	return _oe, ok
}

func (p *plan) fillFieldMap() {
	p.fieldMap = make(map[string]field.Expr, 12)
	p.fieldMap["id"] = p.ID
	p.fieldMap["name"] = p.Name
	p.fieldMap["description"] = p.Description
	p.fieldMap["price"] = p.Price
	p.fieldMap["cycle"] = p.Cycle
	p.fieldMap["storage_limit"] = p.StorageLimit
	p.fieldMap["upload_limit"] = p.UploadLimit
	p.fieldMap["duration_limit"] = p.DurationLimit
	p.fieldMap["quality_limit"] = p.QualityLimit
	p.fieldMap["features"] = p.Features
	p.fieldMap["is_active"] = p.IsActive
	p.fieldMap["version"] = p.Version
}

func (p plan) clone(db *gorm.DB) plan {
	p.planDo.ReplaceConnPool(db.Statement.ConnPool)
	return p
}

func (p plan) replaceDB(db *gorm.DB) plan {
	p.planDo.ReplaceDB(db)
	return p
}

type planDo struct{ gen.DO }

type IPlanDo interface {
	gen.SubQuery
	Debug() IPlanDo
	WithContext(ctx context.Context) IPlanDo
	WithResult(fc func(tx gen.Dao)) gen.ResultInfo
	ReplaceDB(db *gorm.DB)
	ReadDB() IPlanDo
	WriteDB() IPlanDo
	As(alias string) gen.Dao
	Session(config *gorm.Session) IPlanDo
	Columns(cols ...field.Expr) gen.Columns
	Clauses(conds ...clause.Expression) IPlanDo
	Not(conds ...gen.Condition) IPlanDo
	Or(conds ...gen.Condition) IPlanDo
	Select(conds ...field.Expr) IPlanDo
	Where(conds ...gen.Condition) IPlanDo
	Order(conds ...field.Expr) IPlanDo
	Distinct(cols ...field.Expr) IPlanDo
	Omit(cols ...field.Expr) IPlanDo
	Join(table schema.Tabler, on ...field.Expr) IPlanDo
	LeftJoin(table schema.Tabler, on ...field.Expr) IPlanDo
	RightJoin(table schema.Tabler, on ...field.Expr) IPlanDo
	Group(cols ...field.Expr) IPlanDo
	Having(conds ...gen.Condition) IPlanDo
	Limit(limit int) IPlanDo
	Offset(offset int) IPlanDo
	Count() (count int64, err error)
	Scopes(funcs ...func(gen.Dao) gen.Dao) IPlanDo
	Unscoped() IPlanDo
	Create(values ...*model.Plan) error
	CreateInBatches(values []*model.Plan, batchSize int) error
	Save(values ...*model.Plan) error
	First() (*model.Plan, error)
	Take() (*model.Plan, error)
	Last() (*model.Plan, error)
	Find() ([]*model.Plan, error)
	FindInBatch(batchSize int, fc func(tx gen.Dao, batch int) error) (results []*model.Plan, err error)
	FindInBatches(result *[]*model.Plan, batchSize int, fc func(tx gen.Dao, batch int) error) error
	Pluck(column field.Expr, dest interface{}) error
	Delete(...*model.Plan) (info gen.ResultInfo, err error)
	Update(column field.Expr, value interface{}) (info gen.ResultInfo, err error)
	UpdateSimple(columns ...field.AssignExpr) (info gen.ResultInfo, err error)
	Updates(value interface{}) (info gen.ResultInfo, err error)
	UpdateColumn(column field.Expr, value interface{}) (info gen.ResultInfo, err error)
	UpdateColumnSimple(columns ...field.AssignExpr) (info gen.ResultInfo, err error)
	UpdateColumns(value interface{}) (info gen.ResultInfo, err error)
	UpdateFrom(q gen.SubQuery) gen.Dao
	Attrs(attrs ...field.AssignExpr) IPlanDo
	Assign(attrs ...field.AssignExpr) IPlanDo
	Joins(fields ...field.RelationField) IPlanDo
	Preload(fields ...field.RelationField) IPlanDo
	FirstOrInit() (*model.Plan, error)
	FirstOrCreate() (*model.Plan, error)
	FindByPage(offset int, limit int) (result []*model.Plan, count int64, err error)
	ScanByPage(result interface{}, offset int, limit int) (count int64, err error)
	Rows() (*sql.Rows, error)
	Row() *sql.Row
	Scan(result interface{}) (err error)
	Returning(value interface{}, columns ...string) IPlanDo
	UnderlyingDB() *gorm.DB
	schema.Tabler
}

func (p planDo) Debug() IPlanDo {
	return p.withDO(p.DO.Debug())
}

func (p planDo) WithContext(ctx context.Context) IPlanDo {
	return p.withDO(p.DO.WithContext(ctx))
}

func (p planDo) ReadDB() IPlanDo {
	return p.Clauses(dbresolver.Read)
}

func (p planDo) WriteDB() IPlanDo {
	return p.Clauses(dbresolver.Write)
}

func (p planDo) Session(config *gorm.Session) IPlanDo {
	return p.withDO(p.DO.Session(config))
}

func (p planDo) Clauses(conds ...clause.Expression) IPlanDo {
	return p.withDO(p.DO.Clauses(conds...))
}

func (p planDo) Returning(value interface{}, columns ...string) IPlanDo {
	return p.withDO(p.DO.Returning(value, columns...))
}

func (p planDo) Not(conds ...gen.Condition) IPlanDo {
	return p.withDO(p.DO.Not(conds...))
}

func (p planDo) Or(conds ...gen.Condition) IPlanDo {
	return p.withDO(p.DO.Or(conds...))
}

func (p planDo) Select(conds ...field.Expr) IPlanDo {
	return p.withDO(p.DO.Select(conds...))
}

func (p planDo) Where(conds ...gen.Condition) IPlanDo {
	return p.withDO(p.DO.Where(conds...))
}

func (p planDo) Order(conds ...field.Expr) IPlanDo {
	return p.withDO(p.DO.Order(conds...))
}

func (p planDo) Distinct(cols ...field.Expr) IPlanDo {
	return p.withDO(p.DO.Distinct(cols...))
}

func (p planDo) Omit(cols ...field.Expr) IPlanDo {
	return p.withDO(p.DO.Omit(cols...))
}

func (p planDo) Join(table schema.Tabler, on ...field.Expr) IPlanDo {
	return p.withDO(p.DO.Join(table, on...))
}

func (p planDo) LeftJoin(table schema.Tabler, on ...field.Expr) IPlanDo {
	return p.withDO(p.DO.LeftJoin(table, on...))
}

func (p planDo) RightJoin(table schema.Tabler, on ...field.Expr) IPlanDo {
	return p.withDO(p.DO.RightJoin(table, on...))
}

func (p planDo) Group(cols ...field.Expr) IPlanDo {
	return p.withDO(p.DO.Group(cols...))
}

func (p planDo) Having(conds ...gen.Condition) IPlanDo {
	return p.withDO(p.DO.Having(conds...))
}

func (p planDo) Limit(limit int) IPlanDo {
	return p.withDO(p.DO.Limit(limit))
}

func (p planDo) Offset(offset int) IPlanDo {
	return p.withDO(p.DO.Offset(offset))
}

func (p planDo) Scopes(funcs ...func(gen.Dao) gen.Dao) IPlanDo {
	return p.withDO(p.DO.Scopes(funcs...))
}

func (p planDo) Unscoped() IPlanDo {
	return p.withDO(p.DO.Unscoped())
}

func (p planDo) Create(values ...*model.Plan) error {
	if len(values) == 0 {
		return nil
	}
	return p.DO.Create(values)
}

func (p planDo) CreateInBatches(values []*model.Plan, batchSize int) error {
	return p.DO.CreateInBatches(values, batchSize)
}

// Save : !!! underlying implementation is different with GORM
// The method is equivalent to executing the statement: db.Clauses(clause.OnConflict{UpdateAll: true}).Create(values)
func (p planDo) Save(values ...*model.Plan) error {
	if len(values) == 0 {
		return nil
	}
	return p.DO.Save(values)
}

func (p planDo) First() (*model.Plan, error) {
	if result, err := p.DO.First(); err != nil {
		return nil, err
	} else {
		return result.(*model.Plan), nil
	}
}

func (p planDo) Take() (*model.Plan, error) {
	if result, err := p.DO.Take(); err != nil {
		return nil, err
	} else {
		return result.(*model.Plan), nil
	}
}

func (p planDo) Last() (*model.Plan, error) {
	if result, err := p.DO.Last(); err != nil {
		return nil, err
	} else {
		return result.(*model.Plan), nil
	}
}

func (p planDo) Find() ([]*model.Plan, error) {
	result, err := p.DO.Find()
	return result.([]*model.Plan), err
}

func (p planDo) FindInBatch(batchSize int, fc func(tx gen.Dao, batch int) error) (results []*model.Plan, err error) {
	buf := make([]*model.Plan, 0, batchSize)
	err = p.DO.FindInBatches(&buf, batchSize, func(tx gen.Dao, batch int) error {
		defer func() { results = append(results, buf...) }()
		return fc(tx, batch)
	})
	return results, err
}

func (p planDo) FindInBatches(result *[]*model.Plan, batchSize int, fc func(tx gen.Dao, batch int) error) error {
	return p.DO.FindInBatches(result, batchSize, fc)
}

func (p planDo) Attrs(attrs ...field.AssignExpr) IPlanDo {
	return p.withDO(p.DO.Attrs(attrs...))
}

func (p planDo) Assign(attrs ...field.AssignExpr) IPlanDo {
	return p.withDO(p.DO.Assign(attrs...))
}

func (p planDo) Joins(fields ...field.RelationField) IPlanDo {
	for _, _f := range fields {
		p = *p.withDO(p.DO.Joins(_f))
	}
	return &p
}

func (p planDo) Preload(fields ...field.RelationField) IPlanDo {
	for _, _f := range fields {
		p = *p.withDO(p.DO.Preload(_f))
	}
	return &p
}

func (p planDo) FirstOrInit() (*model.Plan, error) {
	if result, err := p.DO.FirstOrInit(); err != nil {
		return nil, err
	} else {
		return result.(*model.Plan), nil
	}
}

func (p planDo) FirstOrCreate() (*model.Plan, error) {
	if result, err := p.DO.FirstOrCreate(); err != nil {
		return nil, err
	} else {
		return result.(*model.Plan), nil
	}
}

func (p planDo) FindByPage(offset int, limit int) (result []*model.Plan, count int64, err error) {
	result, err = p.Offset(offset).Limit(limit).Find()
	if err != nil {
		return
	}

	if size := len(result); 0 < limit && 0 < size && size < limit {
		count = int64(size + offset)
		return
	}

	count, err = p.Offset(-1).Limit(-1).Count()
	return
}

func (p planDo) ScanByPage(result interface{}, offset int, limit int) (count int64, err error) {
	count, err = p.Count()
	if err != nil {
		return
	}

	err = p.Offset(offset).Limit(limit).Scan(result)
	return
}

func (p planDo) Scan(result interface{}) (err error) {
	return p.DO.Scan(result)
}

func (p planDo) Delete(models ...*model.Plan) (result gen.ResultInfo, err error) {
	return p.DO.Delete(models)
}

func (p *planDo) withDO(do gen.Dao) *planDo {
	p.DO = *do.(*gen.DO)
	return p
}
