///////////////////////////////////////////////////////////
// THIS FILE IS AUTO GENERATED by gormgen, DON'T EDIT IT //
//        ANY CHANGES DONE HERE WILL BE LOST             //
///////////////////////////////////////////////////////////

package menu_repo

import (
	"fmt"
	"time"

	"github.com/xinliangnote/go-gin-api/internal/api/repository/db_repo"

	"github.com/pkg/errors"
	"gorm.io/gorm"
)

func NewModel() *Menu {
	return new(Menu)
}

func NewQueryBuilder() *menuRepoQueryBuilder {
	return new(menuRepoQueryBuilder)
}

func (t *Menu) Create(db *gorm.DB) (id int32, err error) {
	if err = db.Create(t).Error; err != nil {
		return 0, errors.Wrap(err, "create err")
	}
	return t.Id, nil
}

type menuRepoQueryBuilder struct {
	order []string
	where []struct {
		prefix string
		value  interface{}
	}
	limit  int
	offset int
}

func (qb *menuRepoQueryBuilder) buildQuery(db *gorm.DB) *gorm.DB {
	ret := db
	for _, where := range qb.where {
		ret = ret.Where(where.prefix, where.value)
	}
	for _, order := range qb.order {
		ret = ret.Order(order)
	}
	ret = ret.Limit(qb.limit).Offset(qb.offset)
	return ret
}

func (qb *menuRepoQueryBuilder) Updates(db *gorm.DB, m map[string]interface{}) (err error) {
	db = db.Model(&Menu{})

	for _, where := range qb.where {
		db.Where(where.prefix, where.value)
	}

	if err = db.Updates(m).Error; err != nil {
		return errors.Wrap(err, "updates err")
	}
	return nil
}

func (qb *menuRepoQueryBuilder) Delete(db *gorm.DB) (err error) {
	for _, where := range qb.where {
		db = db.Where(where.prefix, where.value)
	}

	if err = db.Delete(&Menu{}).Error; err != nil {
		return errors.Wrap(err, "delete err")
	}
	return nil
}

func (qb *menuRepoQueryBuilder) Count(db *gorm.DB) (int64, error) {
	var c int64
	res := qb.buildQuery(db).Model(&Menu{}).Count(&c)
	if res.Error != nil && res.Error == gorm.ErrRecordNotFound {
		c = 0
	}
	return c, res.Error
}

func (qb *menuRepoQueryBuilder) First(db *gorm.DB) (*Menu, error) {
	ret := &Menu{}
	res := qb.buildQuery(db).First(ret)
	if res.Error != nil && res.Error == gorm.ErrRecordNotFound {
		ret = nil
	}
	return ret, res.Error
}

func (qb *menuRepoQueryBuilder) QueryOne(db *gorm.DB) (*Menu, error) {
	qb.limit = 1
	ret, err := qb.QueryAll(db)
	if len(ret) > 0 {
		return ret[0], err
	}
	return nil, err
}

func (qb *menuRepoQueryBuilder) QueryAll(db *gorm.DB) ([]*Menu, error) {
	var ret []*Menu
	err := qb.buildQuery(db).Find(&ret).Error
	return ret, err
}

func (qb *menuRepoQueryBuilder) Limit(limit int) *menuRepoQueryBuilder {
	qb.limit = limit
	return qb
}

func (qb *menuRepoQueryBuilder) Offset(offset int) *menuRepoQueryBuilder {
	qb.offset = offset
	return qb
}

func (qb *menuRepoQueryBuilder) WhereId(p db_repo.Predicate, value int32) *menuRepoQueryBuilder {
	qb.where = append(qb.where, struct {
		prefix string
		value  interface{}
	}{
		fmt.Sprintf("%v %v ?", "id", p),
		value,
	})
	return qb
}

func (qb *menuRepoQueryBuilder) WhereIdIn(value []int32) *menuRepoQueryBuilder {
	qb.where = append(qb.where, struct {
		prefix string
		value  interface{}
	}{
		fmt.Sprintf("%v %v ?", "id", "IN"),
		value,
	})
	return qb
}

func (qb *menuRepoQueryBuilder) WhereIdNotIn(value []int32) *menuRepoQueryBuilder {
	qb.where = append(qb.where, struct {
		prefix string
		value  interface{}
	}{
		fmt.Sprintf("%v %v ?", "id", "NOT IN"),
		value,
	})
	return qb
}

func (qb *menuRepoQueryBuilder) OrderById(asc bool) *menuRepoQueryBuilder {
	order := "DESC"
	if asc {
		order = "ASC"
	}

	qb.order = append(qb.order, "id "+order)
	return qb
}

func (qb *menuRepoQueryBuilder) WherePid(p db_repo.Predicate, value int32) *menuRepoQueryBuilder {
	qb.where = append(qb.where, struct {
		prefix string
		value  interface{}
	}{
		fmt.Sprintf("%v %v ?", "pid", p),
		value,
	})
	return qb
}

func (qb *menuRepoQueryBuilder) WherePidIn(value []int32) *menuRepoQueryBuilder {
	qb.where = append(qb.where, struct {
		prefix string
		value  interface{}
	}{
		fmt.Sprintf("%v %v ?", "pid", "IN"),
		value,
	})
	return qb
}

func (qb *menuRepoQueryBuilder) WherePidNotIn(value []int32) *menuRepoQueryBuilder {
	qb.where = append(qb.where, struct {
		prefix string
		value  interface{}
	}{
		fmt.Sprintf("%v %v ?", "pid", "NOT IN"),
		value,
	})
	return qb
}

func (qb *menuRepoQueryBuilder) OrderByPid(asc bool) *menuRepoQueryBuilder {
	order := "DESC"
	if asc {
		order = "ASC"
	}

	qb.order = append(qb.order, "pid "+order)
	return qb
}

func (qb *menuRepoQueryBuilder) WhereName(p db_repo.Predicate, value string) *menuRepoQueryBuilder {
	qb.where = append(qb.where, struct {
		prefix string
		value  interface{}
	}{
		fmt.Sprintf("%v %v ?", "name", p),
		value,
	})
	return qb
}

func (qb *menuRepoQueryBuilder) WhereNameIn(value []string) *menuRepoQueryBuilder {
	qb.where = append(qb.where, struct {
		prefix string
		value  interface{}
	}{
		fmt.Sprintf("%v %v ?", "name", "IN"),
		value,
	})
	return qb
}

func (qb *menuRepoQueryBuilder) WhereNameNotIn(value []string) *menuRepoQueryBuilder {
	qb.where = append(qb.where, struct {
		prefix string
		value  interface{}
	}{
		fmt.Sprintf("%v %v ?", "name", "NOT IN"),
		value,
	})
	return qb
}

func (qb *menuRepoQueryBuilder) OrderByName(asc bool) *menuRepoQueryBuilder {
	order := "DESC"
	if asc {
		order = "ASC"
	}

	qb.order = append(qb.order, "name "+order)
	return qb
}

func (qb *menuRepoQueryBuilder) WhereLink(p db_repo.Predicate, value string) *menuRepoQueryBuilder {
	qb.where = append(qb.where, struct {
		prefix string
		value  interface{}
	}{
		fmt.Sprintf("%v %v ?", "link", p),
		value,
	})
	return qb
}

func (qb *menuRepoQueryBuilder) WhereLinkIn(value []string) *menuRepoQueryBuilder {
	qb.where = append(qb.where, struct {
		prefix string
		value  interface{}
	}{
		fmt.Sprintf("%v %v ?", "link", "IN"),
		value,
	})
	return qb
}

func (qb *menuRepoQueryBuilder) WhereLinkNotIn(value []string) *menuRepoQueryBuilder {
	qb.where = append(qb.where, struct {
		prefix string
		value  interface{}
	}{
		fmt.Sprintf("%v %v ?", "link", "NOT IN"),
		value,
	})
	return qb
}

func (qb *menuRepoQueryBuilder) OrderByLink(asc bool) *menuRepoQueryBuilder {
	order := "DESC"
	if asc {
		order = "ASC"
	}

	qb.order = append(qb.order, "link "+order)
	return qb
}

func (qb *menuRepoQueryBuilder) WhereIcon(p db_repo.Predicate, value string) *menuRepoQueryBuilder {
	qb.where = append(qb.where, struct {
		prefix string
		value  interface{}
	}{
		fmt.Sprintf("%v %v ?", "icon", p),
		value,
	})
	return qb
}

func (qb *menuRepoQueryBuilder) WhereIconIn(value []string) *menuRepoQueryBuilder {
	qb.where = append(qb.where, struct {
		prefix string
		value  interface{}
	}{
		fmt.Sprintf("%v %v ?", "icon", "IN"),
		value,
	})
	return qb
}

func (qb *menuRepoQueryBuilder) WhereIconNotIn(value []string) *menuRepoQueryBuilder {
	qb.where = append(qb.where, struct {
		prefix string
		value  interface{}
	}{
		fmt.Sprintf("%v %v ?", "icon", "NOT IN"),
		value,
	})
	return qb
}

func (qb *menuRepoQueryBuilder) OrderByIcon(asc bool) *menuRepoQueryBuilder {
	order := "DESC"
	if asc {
		order = "ASC"
	}

	qb.order = append(qb.order, "icon "+order)
	return qb
}

func (qb *menuRepoQueryBuilder) WhereLevel(p db_repo.Predicate, value int32) *menuRepoQueryBuilder {
	qb.where = append(qb.where, struct {
		prefix string
		value  interface{}
	}{
		fmt.Sprintf("%v %v ?", "level", p),
		value,
	})
	return qb
}

func (qb *menuRepoQueryBuilder) WhereLevelIn(value []int32) *menuRepoQueryBuilder {
	qb.where = append(qb.where, struct {
		prefix string
		value  interface{}
	}{
		fmt.Sprintf("%v %v ?", "level", "IN"),
		value,
	})
	return qb
}

func (qb *menuRepoQueryBuilder) WhereLevelNotIn(value []int32) *menuRepoQueryBuilder {
	qb.where = append(qb.where, struct {
		prefix string
		value  interface{}
	}{
		fmt.Sprintf("%v %v ?", "level", "NOT IN"),
		value,
	})
	return qb
}

func (qb *menuRepoQueryBuilder) OrderByLevel(asc bool) *menuRepoQueryBuilder {
	order := "DESC"
	if asc {
		order = "ASC"
	}

	qb.order = append(qb.order, "level "+order)
	return qb
}

func (qb *menuRepoQueryBuilder) WhereSort(p db_repo.Predicate, value int32) *menuRepoQueryBuilder {
	qb.where = append(qb.where, struct {
		prefix string
		value  interface{}
	}{
		fmt.Sprintf("%v %v ?", "sort", p),
		value,
	})
	return qb
}

func (qb *menuRepoQueryBuilder) WhereSortIn(value []int32) *menuRepoQueryBuilder {
	qb.where = append(qb.where, struct {
		prefix string
		value  interface{}
	}{
		fmt.Sprintf("%v %v ?", "sort", "IN"),
		value,
	})
	return qb
}

func (qb *menuRepoQueryBuilder) WhereSortNotIn(value []int32) *menuRepoQueryBuilder {
	qb.where = append(qb.where, struct {
		prefix string
		value  interface{}
	}{
		fmt.Sprintf("%v %v ?", "sort", "NOT IN"),
		value,
	})
	return qb
}

func (qb *menuRepoQueryBuilder) OrderBySort(asc bool) *menuRepoQueryBuilder {
	order := "DESC"
	if asc {
		order = "ASC"
	}

	qb.order = append(qb.order, "sort "+order)
	return qb
}

func (qb *menuRepoQueryBuilder) WhereIsUsed(p db_repo.Predicate, value int32) *menuRepoQueryBuilder {
	qb.where = append(qb.where, struct {
		prefix string
		value  interface{}
	}{
		fmt.Sprintf("%v %v ?", "is_used", p),
		value,
	})
	return qb
}

func (qb *menuRepoQueryBuilder) WhereIsUsedIn(value []int32) *menuRepoQueryBuilder {
	qb.where = append(qb.where, struct {
		prefix string
		value  interface{}
	}{
		fmt.Sprintf("%v %v ?", "is_used", "IN"),
		value,
	})
	return qb
}

func (qb *menuRepoQueryBuilder) WhereIsUsedNotIn(value []int32) *menuRepoQueryBuilder {
	qb.where = append(qb.where, struct {
		prefix string
		value  interface{}
	}{
		fmt.Sprintf("%v %v ?", "is_used", "NOT IN"),
		value,
	})
	return qb
}

func (qb *menuRepoQueryBuilder) OrderByIsUsed(asc bool) *menuRepoQueryBuilder {
	order := "DESC"
	if asc {
		order = "ASC"
	}

	qb.order = append(qb.order, "is_used "+order)
	return qb
}

func (qb *menuRepoQueryBuilder) WhereIsDeleted(p db_repo.Predicate, value int32) *menuRepoQueryBuilder {
	qb.where = append(qb.where, struct {
		prefix string
		value  interface{}
	}{
		fmt.Sprintf("%v %v ?", "is_deleted", p),
		value,
	})
	return qb
}

func (qb *menuRepoQueryBuilder) WhereIsDeletedIn(value []int32) *menuRepoQueryBuilder {
	qb.where = append(qb.where, struct {
		prefix string
		value  interface{}
	}{
		fmt.Sprintf("%v %v ?", "is_deleted", "IN"),
		value,
	})
	return qb
}

func (qb *menuRepoQueryBuilder) WhereIsDeletedNotIn(value []int32) *menuRepoQueryBuilder {
	qb.where = append(qb.where, struct {
		prefix string
		value  interface{}
	}{
		fmt.Sprintf("%v %v ?", "is_deleted", "NOT IN"),
		value,
	})
	return qb
}

func (qb *menuRepoQueryBuilder) OrderByIsDeleted(asc bool) *menuRepoQueryBuilder {
	order := "DESC"
	if asc {
		order = "ASC"
	}

	qb.order = append(qb.order, "is_deleted "+order)
	return qb
}

func (qb *menuRepoQueryBuilder) WhereCreatedAt(p db_repo.Predicate, value time.Time) *menuRepoQueryBuilder {
	qb.where = append(qb.where, struct {
		prefix string
		value  interface{}
	}{
		fmt.Sprintf("%v %v ?", "created_at", p),
		value,
	})
	return qb
}

func (qb *menuRepoQueryBuilder) WhereCreatedAtIn(value []time.Time) *menuRepoQueryBuilder {
	qb.where = append(qb.where, struct {
		prefix string
		value  interface{}
	}{
		fmt.Sprintf("%v %v ?", "created_at", "IN"),
		value,
	})
	return qb
}

func (qb *menuRepoQueryBuilder) WhereCreatedAtNotIn(value []time.Time) *menuRepoQueryBuilder {
	qb.where = append(qb.where, struct {
		prefix string
		value  interface{}
	}{
		fmt.Sprintf("%v %v ?", "created_at", "NOT IN"),
		value,
	})
	return qb
}

func (qb *menuRepoQueryBuilder) OrderByCreatedAt(asc bool) *menuRepoQueryBuilder {
	order := "DESC"
	if asc {
		order = "ASC"
	}

	qb.order = append(qb.order, "created_at "+order)
	return qb
}

func (qb *menuRepoQueryBuilder) WhereCreatedUser(p db_repo.Predicate, value string) *menuRepoQueryBuilder {
	qb.where = append(qb.where, struct {
		prefix string
		value  interface{}
	}{
		fmt.Sprintf("%v %v ?", "created_user", p),
		value,
	})
	return qb
}

func (qb *menuRepoQueryBuilder) WhereCreatedUserIn(value []string) *menuRepoQueryBuilder {
	qb.where = append(qb.where, struct {
		prefix string
		value  interface{}
	}{
		fmt.Sprintf("%v %v ?", "created_user", "IN"),
		value,
	})
	return qb
}

func (qb *menuRepoQueryBuilder) WhereCreatedUserNotIn(value []string) *menuRepoQueryBuilder {
	qb.where = append(qb.where, struct {
		prefix string
		value  interface{}
	}{
		fmt.Sprintf("%v %v ?", "created_user", "NOT IN"),
		value,
	})
	return qb
}

func (qb *menuRepoQueryBuilder) OrderByCreatedUser(asc bool) *menuRepoQueryBuilder {
	order := "DESC"
	if asc {
		order = "ASC"
	}

	qb.order = append(qb.order, "created_user "+order)
	return qb
}

func (qb *menuRepoQueryBuilder) WhereUpdatedAt(p db_repo.Predicate, value time.Time) *menuRepoQueryBuilder {
	qb.where = append(qb.where, struct {
		prefix string
		value  interface{}
	}{
		fmt.Sprintf("%v %v ?", "updated_at", p),
		value,
	})
	return qb
}

func (qb *menuRepoQueryBuilder) WhereUpdatedAtIn(value []time.Time) *menuRepoQueryBuilder {
	qb.where = append(qb.where, struct {
		prefix string
		value  interface{}
	}{
		fmt.Sprintf("%v %v ?", "updated_at", "IN"),
		value,
	})
	return qb
}

func (qb *menuRepoQueryBuilder) WhereUpdatedAtNotIn(value []time.Time) *menuRepoQueryBuilder {
	qb.where = append(qb.where, struct {
		prefix string
		value  interface{}
	}{
		fmt.Sprintf("%v %v ?", "updated_at", "NOT IN"),
		value,
	})
	return qb
}

func (qb *menuRepoQueryBuilder) OrderByUpdatedAt(asc bool) *menuRepoQueryBuilder {
	order := "DESC"
	if asc {
		order = "ASC"
	}

	qb.order = append(qb.order, "updated_at "+order)
	return qb
}

func (qb *menuRepoQueryBuilder) WhereUpdatedUser(p db_repo.Predicate, value string) *menuRepoQueryBuilder {
	qb.where = append(qb.where, struct {
		prefix string
		value  interface{}
	}{
		fmt.Sprintf("%v %v ?", "updated_user", p),
		value,
	})
	return qb
}

func (qb *menuRepoQueryBuilder) WhereUpdatedUserIn(value []string) *menuRepoQueryBuilder {
	qb.where = append(qb.where, struct {
		prefix string
		value  interface{}
	}{
		fmt.Sprintf("%v %v ?", "updated_user", "IN"),
		value,
	})
	return qb
}

func (qb *menuRepoQueryBuilder) WhereUpdatedUserNotIn(value []string) *menuRepoQueryBuilder {
	qb.where = append(qb.where, struct {
		prefix string
		value  interface{}
	}{
		fmt.Sprintf("%v %v ?", "updated_user", "NOT IN"),
		value,
	})
	return qb
}

func (qb *menuRepoQueryBuilder) OrderByUpdatedUser(asc bool) *menuRepoQueryBuilder {
	order := "DESC"
	if asc {
		order = "ASC"
	}

	qb.order = append(qb.order, "updated_user "+order)
	return qb
}
