// 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"

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

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

	"gorm.io/plugin/dbresolver"

	"gadmin/internal/gorm/model"
)

func newMenu(db *gorm.DB, opts ...gen.DOOption) menu {
	_menu := menu{}

	_menu.menuDo.UseDB(db, opts...)
	_menu.menuDo.UseModel(&model.Menu{})

	tableName := _menu.menuDo.TableName()
	_menu.ALL = field.NewAsterisk(tableName)
	_menu.ID = field.NewInt64(tableName, "id")
	_menu.Environment = field.NewString(tableName, "environment")
	_menu.Pid = field.NewInt64(tableName, "pid")
	_menu.Title = field.NewString(tableName, "title")
	_menu.Name = field.NewString(tableName, "name")
	_menu.Path = field.NewString(tableName, "path")
	_menu.Icon = field.NewString(tableName, "icon")
	_menu.Type = field.NewBool(tableName, "type")
	_menu.Redirect = field.NewString(tableName, "redirect")
	_menu.Permissions = field.NewString(tableName, "permissions")
	_menu.PermissionName = field.NewString(tableName, "permission_name")
	_menu.Component = field.NewString(tableName, "component")
	_menu.AlwaysShow = field.NewBool(tableName, "always_show")
	_menu.ActiveMenu = field.NewString(tableName, "active_menu")
	_menu.IsRoot = field.NewBool(tableName, "is_root")
	_menu.IsFrame = field.NewBool(tableName, "is_frame")
	_menu.FrameSrc = field.NewString(tableName, "frame_src")
	_menu.KeepAlive = field.NewBool(tableName, "keep_alive")
	_menu.Hidden = field.NewBool(tableName, "hidden")
	_menu.Affix = field.NewBool(tableName, "affix")
	_menu.Level = field.NewInt32(tableName, "level")
	_menu.Tree = field.NewString(tableName, "tree")
	_menu.Sort = field.NewInt32(tableName, "sort")
	_menu.Remark = field.NewString(tableName, "remark")
	_menu.Status = field.NewBool(tableName, "status")
	_menu.CreatedAt = field.NewTime(tableName, "created_at")
	_menu.UpdatedAt = field.NewTime(tableName, "updated_at")

	_menu.fillFieldMap()

	return _menu
}

type menu struct {
	menuDo

	ALL            field.Asterisk
	ID             field.Int64  // 菜单ID
	Environment    field.String // 环境
	Pid            field.Int64  // 父菜单ID
	Title          field.String // 菜单名称
	Name           field.String // 名称编码
	Path           field.String // 路由地址
	Icon           field.String // 菜单图标
	Type           field.Bool   // 菜单类型（1目录 2菜单 3按钮）
	Redirect       field.String // 重定向地址
	Permissions    field.String // 菜单包含权限集合
	PermissionName field.String // 权限名称
	Component      field.String // 组件路径
	AlwaysShow     field.Bool   // 取消自动计算根路由模式
	ActiveMenu     field.String // 高亮菜单编码
	IsRoot         field.Bool   // 是否跟路由
	IsFrame        field.Bool   // 是否内嵌
	FrameSrc       field.String // 内联外部地址
	KeepAlive      field.Bool   // 缓存该路由
	Hidden         field.Bool   // 是否隐藏
	Affix          field.Bool   // 是否固定
	Level          field.Int32  // 级别
	Tree           field.String // 树
	Sort           field.Int32  // 排序
	Remark         field.String // 备注
	Status         field.Bool   // 菜单状态
	CreatedAt      field.Time   // 创建时间
	UpdatedAt      field.Time   // 更新时间

	fieldMap map[string]field.Expr
}

func (m menu) Table(newTableName string) *menu {
	m.menuDo.UseTable(newTableName)
	return m.updateTableName(newTableName)
}

func (m menu) As(alias string) *menu {
	m.menuDo.DO = *(m.menuDo.As(alias).(*gen.DO))
	return m.updateTableName(alias)
}

func (m *menu) updateTableName(table string) *menu {
	m.ALL = field.NewAsterisk(table)
	m.ID = field.NewInt64(table, "id")
	m.Environment = field.NewString(table, "environment")
	m.Pid = field.NewInt64(table, "pid")
	m.Title = field.NewString(table, "title")
	m.Name = field.NewString(table, "name")
	m.Path = field.NewString(table, "path")
	m.Icon = field.NewString(table, "icon")
	m.Type = field.NewBool(table, "type")
	m.Redirect = field.NewString(table, "redirect")
	m.Permissions = field.NewString(table, "permissions")
	m.PermissionName = field.NewString(table, "permission_name")
	m.Component = field.NewString(table, "component")
	m.AlwaysShow = field.NewBool(table, "always_show")
	m.ActiveMenu = field.NewString(table, "active_menu")
	m.IsRoot = field.NewBool(table, "is_root")
	m.IsFrame = field.NewBool(table, "is_frame")
	m.FrameSrc = field.NewString(table, "frame_src")
	m.KeepAlive = field.NewBool(table, "keep_alive")
	m.Hidden = field.NewBool(table, "hidden")
	m.Affix = field.NewBool(table, "affix")
	m.Level = field.NewInt32(table, "level")
	m.Tree = field.NewString(table, "tree")
	m.Sort = field.NewInt32(table, "sort")
	m.Remark = field.NewString(table, "remark")
	m.Status = field.NewBool(table, "status")
	m.CreatedAt = field.NewTime(table, "created_at")
	m.UpdatedAt = field.NewTime(table, "updated_at")

	m.fillFieldMap()

	return m
}

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

func (m *menu) fillFieldMap() {
	m.fieldMap = make(map[string]field.Expr, 27)
	m.fieldMap["id"] = m.ID
	m.fieldMap["environment"] = m.Environment
	m.fieldMap["pid"] = m.Pid
	m.fieldMap["title"] = m.Title
	m.fieldMap["name"] = m.Name
	m.fieldMap["path"] = m.Path
	m.fieldMap["icon"] = m.Icon
	m.fieldMap["type"] = m.Type
	m.fieldMap["redirect"] = m.Redirect
	m.fieldMap["permissions"] = m.Permissions
	m.fieldMap["permission_name"] = m.PermissionName
	m.fieldMap["component"] = m.Component
	m.fieldMap["always_show"] = m.AlwaysShow
	m.fieldMap["active_menu"] = m.ActiveMenu
	m.fieldMap["is_root"] = m.IsRoot
	m.fieldMap["is_frame"] = m.IsFrame
	m.fieldMap["frame_src"] = m.FrameSrc
	m.fieldMap["keep_alive"] = m.KeepAlive
	m.fieldMap["hidden"] = m.Hidden
	m.fieldMap["affix"] = m.Affix
	m.fieldMap["level"] = m.Level
	m.fieldMap["tree"] = m.Tree
	m.fieldMap["sort"] = m.Sort
	m.fieldMap["remark"] = m.Remark
	m.fieldMap["status"] = m.Status
	m.fieldMap["created_at"] = m.CreatedAt
	m.fieldMap["updated_at"] = m.UpdatedAt
}

func (m menu) clone(db *gorm.DB) menu {
	m.menuDo.ReplaceConnPool(db.Statement.ConnPool)
	return m
}

func (m menu) replaceDB(db *gorm.DB) menu {
	m.menuDo.ReplaceDB(db)
	return m
}

type menuDo struct{ gen.DO }

func (m menuDo) Debug() *menuDo {
	return m.withDO(m.DO.Debug())
}

func (m menuDo) WithContext(ctx context.Context) *menuDo {
	return m.withDO(m.DO.WithContext(ctx))
}

func (m menuDo) ReadDB() *menuDo {
	return m.Clauses(dbresolver.Read)
}

func (m menuDo) WriteDB() *menuDo {
	return m.Clauses(dbresolver.Write)
}

func (m menuDo) Session(config *gorm.Session) *menuDo {
	return m.withDO(m.DO.Session(config))
}

func (m menuDo) Clauses(conds ...clause.Expression) *menuDo {
	return m.withDO(m.DO.Clauses(conds...))
}

func (m menuDo) Returning(value interface{}, columns ...string) *menuDo {
	return m.withDO(m.DO.Returning(value, columns...))
}

func (m menuDo) Not(conds ...gen.Condition) *menuDo {
	return m.withDO(m.DO.Not(conds...))
}

func (m menuDo) Or(conds ...gen.Condition) *menuDo {
	return m.withDO(m.DO.Or(conds...))
}

func (m menuDo) Select(conds ...field.Expr) *menuDo {
	return m.withDO(m.DO.Select(conds...))
}

func (m menuDo) Where(conds ...gen.Condition) *menuDo {
	return m.withDO(m.DO.Where(conds...))
}

func (m menuDo) Exists(subquery interface{ UnderlyingDB() *gorm.DB }) *menuDo {
	return m.Where(field.CompareSubQuery(field.ExistsOp, nil, subquery.UnderlyingDB()))
}

func (m menuDo) Order(conds ...field.Expr) *menuDo {
	return m.withDO(m.DO.Order(conds...))
}

func (m menuDo) Distinct(cols ...field.Expr) *menuDo {
	return m.withDO(m.DO.Distinct(cols...))
}

func (m menuDo) Omit(cols ...field.Expr) *menuDo {
	return m.withDO(m.DO.Omit(cols...))
}

func (m menuDo) Join(table schema.Tabler, on ...field.Expr) *menuDo {
	return m.withDO(m.DO.Join(table, on...))
}

func (m menuDo) LeftJoin(table schema.Tabler, on ...field.Expr) *menuDo {
	return m.withDO(m.DO.LeftJoin(table, on...))
}

func (m menuDo) RightJoin(table schema.Tabler, on ...field.Expr) *menuDo {
	return m.withDO(m.DO.RightJoin(table, on...))
}

func (m menuDo) Group(cols ...field.Expr) *menuDo {
	return m.withDO(m.DO.Group(cols...))
}

func (m menuDo) Having(conds ...gen.Condition) *menuDo {
	return m.withDO(m.DO.Having(conds...))
}

func (m menuDo) Limit(limit int) *menuDo {
	return m.withDO(m.DO.Limit(limit))
}

func (m menuDo) Offset(offset int) *menuDo {
	return m.withDO(m.DO.Offset(offset))
}

func (m menuDo) Scopes(funcs ...func(gen.Dao) gen.Dao) *menuDo {
	return m.withDO(m.DO.Scopes(funcs...))
}

func (m menuDo) Unscoped() *menuDo {
	return m.withDO(m.DO.Unscoped())
}

func (m menuDo) Create(values ...*model.Menu) error {
	if len(values) == 0 {
		return nil
	}
	return m.DO.Create(values)
}

func (m menuDo) CreateInBatches(values []*model.Menu, batchSize int) error {
	return m.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 (m menuDo) Save(values ...*model.Menu) error {
	if len(values) == 0 {
		return nil
	}
	return m.DO.Save(values)
}

func (m menuDo) First() (*model.Menu, error) {
	if result, err := m.DO.First(); err != nil {
		return nil, err
	} else {
		return result.(*model.Menu), nil
	}
}

func (m menuDo) Take() (*model.Menu, error) {
	if result, err := m.DO.Take(); err != nil {
		return nil, err
	} else {
		return result.(*model.Menu), nil
	}
}

func (m menuDo) Last() (*model.Menu, error) {
	if result, err := m.DO.Last(); err != nil {
		return nil, err
	} else {
		return result.(*model.Menu), nil
	}
}

func (m menuDo) Find() ([]*model.Menu, error) {
	result, err := m.DO.Find()
	return result.([]*model.Menu), err
}

func (m menuDo) FindInBatch(batchSize int, fc func(tx gen.Dao, batch int) error) (results []*model.Menu, err error) {
	buf := make([]*model.Menu, 0, batchSize)
	err = m.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 (m menuDo) FindInBatches(result *[]*model.Menu, batchSize int, fc func(tx gen.Dao, batch int) error) error {
	return m.DO.FindInBatches(result, batchSize, fc)
}

func (m menuDo) Attrs(attrs ...field.AssignExpr) *menuDo {
	return m.withDO(m.DO.Attrs(attrs...))
}

func (m menuDo) Assign(attrs ...field.AssignExpr) *menuDo {
	return m.withDO(m.DO.Assign(attrs...))
}

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

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

func (m menuDo) FirstOrInit() (*model.Menu, error) {
	if result, err := m.DO.FirstOrInit(); err != nil {
		return nil, err
	} else {
		return result.(*model.Menu), nil
	}
}

func (m menuDo) FirstOrCreate() (*model.Menu, error) {
	if result, err := m.DO.FirstOrCreate(); err != nil {
		return nil, err
	} else {
		return result.(*model.Menu), nil
	}
}

func (m menuDo) FindByPage(offset int, limit int) (result []*model.Menu, count int64, err error) {
	result, err = m.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 = m.Offset(-1).Limit(-1).Count()
	return
}

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

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

func (m menuDo) Scan(result interface{}) (err error) {
	return m.DO.Scan(result)
}

func (m menuDo) Delete(models ...*model.Menu) (result gen.ResultInfo, err error) {
	return m.DO.Delete(models)
}

func (m *menuDo) withDO(do gen.Dao) *menuDo {
	m.DO = *do.(*gen.DO)
	return m
}
