274 lines
5.4 KiB
Go
274 lines
5.4 KiB
Go
package mdbc
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
|
|
"go.mongodb.org/mongo-driver/mongo"
|
|
"go.mongodb.org/mongo-driver/mongo/options"
|
|
)
|
|
|
|
// KeySort 排序方式 类型别名
|
|
type KeySort = int
|
|
|
|
const (
|
|
ASC KeySort = 1 // 正序排列
|
|
DESC KeySort = -1 // 倒序排列
|
|
)
|
|
|
|
// IndexCard 索引信息
|
|
type IndexCard struct {
|
|
Version int32 `bson:"v"` // 版本信息
|
|
Name string `bson:"name"` // 索引名
|
|
Key map[string]KeySort `bson:"key"` // 索引方式
|
|
}
|
|
|
|
// IndexList 索引列表
|
|
type IndexList []*IndexCard
|
|
|
|
type IndexScope struct {
|
|
scope *Scope
|
|
cw *ctxWrap
|
|
iv mongo.IndexView
|
|
cursor *mongo.Cursor
|
|
ims []mongo.IndexModel
|
|
err error
|
|
lOpts *options.ListIndexesOptions
|
|
dOpts *options.DropIndexesOptions
|
|
cOpts *options.CreateIndexesOptions
|
|
execResult interface{}
|
|
}
|
|
|
|
func (is *IndexScope) assertErr() {
|
|
if is.err == nil {
|
|
return
|
|
}
|
|
|
|
err, ok := is.err.(mongo.CommandError)
|
|
if !ok {
|
|
return
|
|
}
|
|
if err.HasErrorMessage(context.DeadlineExceeded.Error()) {
|
|
is.err = &ErrRequestBroken
|
|
}
|
|
}
|
|
|
|
func (is *IndexScope) doClear() {
|
|
if is.cw != nil && is.cw.cancel != nil {
|
|
is.cw.cancel()
|
|
}
|
|
is.scope.debug = false
|
|
is.scope.execT = 0
|
|
}
|
|
|
|
// doGet 拿到 iv 后续的 增删改查都基于 iv 对象
|
|
func (is *IndexScope) doGet() {
|
|
is.iv = db.Collection(is.scope.tableName).Indexes(is.getContext())
|
|
}
|
|
|
|
// doCursor 拿到 cursor
|
|
func (is *IndexScope) doCursor() {
|
|
if is.lOpts == nil {
|
|
is.lOpts = &options.ListIndexesOptions{}
|
|
}
|
|
is.cursor, is.err = is.iv.List(is.getContext(), is.lOpts)
|
|
is.assertErr()
|
|
}
|
|
|
|
// SetContext 设定 Context
|
|
func (is *IndexScope) SetContext(ctx context.Context) *IndexScope {
|
|
if is.cw == nil {
|
|
is.cw = &ctxWrap{}
|
|
}
|
|
is.cw.ctx = ctx
|
|
return is
|
|
}
|
|
|
|
// SetListIndexesOption 设定 ListIndexesOptions
|
|
func (is *IndexScope) SetListIndexesOption(opts options.ListIndexesOptions) *IndexScope {
|
|
is.lOpts = &opts
|
|
return is
|
|
}
|
|
|
|
// SetDropIndexesOption 设定 DropIndexesOptions
|
|
func (is *IndexScope) SetDropIndexesOption(opts options.DropIndexesOptions) *IndexScope {
|
|
is.dOpts = &opts
|
|
return is
|
|
}
|
|
|
|
// SetCreateIndexesOption 设定 CreateIndexesOptions
|
|
func (is *IndexScope) SetCreateIndexesOption(opts options.CreateIndexesOptions) *IndexScope {
|
|
is.cOpts = &opts
|
|
return is
|
|
}
|
|
|
|
// getContext 获取ctx
|
|
func (is *IndexScope) getContext() context.Context {
|
|
return is.cw.ctx
|
|
}
|
|
|
|
// GetIndexList 获取索引列表
|
|
func (is *IndexScope) GetIndexList(data *IndexList) error {
|
|
defer is.doClear()
|
|
is.doGet()
|
|
|
|
is.doCursor()
|
|
|
|
if is.err != nil {
|
|
return is.err
|
|
}
|
|
|
|
is.err = is.cursor.All(is.getContext(), data)
|
|
|
|
is.assertErr()
|
|
|
|
if is.err != nil {
|
|
return is.err
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// GetListCursor 获取结果集的指针
|
|
func (is *IndexScope) GetListCursor() (*mongo.Cursor, error) {
|
|
defer is.doClear()
|
|
|
|
is.doGet()
|
|
|
|
is.doCursor()
|
|
|
|
if is.err != nil {
|
|
return nil, is.err
|
|
}
|
|
|
|
return is.cursor, nil
|
|
}
|
|
|
|
// DropOne 删除一个索引 name 为索引名称
|
|
func (is *IndexScope) DropOne(name string) error {
|
|
defer is.doClear()
|
|
|
|
is.doGet()
|
|
|
|
is.doDropOne(name)
|
|
|
|
if is.err != nil {
|
|
return is.err
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// DropAll 删除所有的索引
|
|
func (is *IndexScope) DropAll() error {
|
|
defer is.doClear()
|
|
|
|
is.doGet()
|
|
|
|
is.doDropAll()
|
|
if is.err != nil {
|
|
return is.err
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (is *IndexScope) doDropAll() {
|
|
if is.dOpts == nil {
|
|
is.dOpts = &options.DropIndexesOptions{}
|
|
}
|
|
|
|
is.execResult, is.err = is.iv.DropAll(is.getContext(), is.dOpts)
|
|
|
|
is.assertErr()
|
|
}
|
|
|
|
// doDropOne 删除一个索引
|
|
func (is *IndexScope) doDropOne(name string) {
|
|
if is.dOpts == nil {
|
|
is.dOpts = &options.DropIndexesOptions{}
|
|
}
|
|
|
|
is.execResult, is.err = is.iv.DropOne(is.getContext(), name, is.dOpts)
|
|
|
|
is.assertErr()
|
|
}
|
|
|
|
// CreateOne 创建单个索引
|
|
// 在调用本方法前,需要调用 AddIndexModel() 添加
|
|
// 当添加了多个 indexModel 后仅会创建第一个索引
|
|
// 返回 res 索引名称 err 创建时错误信息
|
|
func (is *IndexScope) CreateOne() (res string, err error) {
|
|
defer is.doClear()
|
|
|
|
is.doGet()
|
|
|
|
is.doCreateOne()
|
|
|
|
if is.err != nil {
|
|
return "", is.err
|
|
}
|
|
|
|
res, ok := is.execResult.(string)
|
|
if !ok {
|
|
return "", fmt.Errorf("create success but get index name empty")
|
|
}
|
|
|
|
return res, nil
|
|
}
|
|
|
|
// CreateMany 创建多个索引,在调用本方法前,需要调用 AddIndexModel() 添加
|
|
func (is *IndexScope) CreateMany() (res []string, err error) {
|
|
defer is.doClear()
|
|
|
|
is.doGet()
|
|
|
|
is.doCreateMany()
|
|
|
|
if is.err != nil {
|
|
return nil, is.err
|
|
}
|
|
|
|
res, ok := is.execResult.([]string)
|
|
if !ok {
|
|
return nil, fmt.Errorf("create success but get index names empty")
|
|
}
|
|
|
|
return res, nil
|
|
}
|
|
|
|
func (is *IndexScope) doCreateOne() {
|
|
if len(is.ims) == 0 {
|
|
is.err = fmt.Errorf("no such index model, you need to use AddIndexModel() to add one")
|
|
return
|
|
}
|
|
if is.cOpts == nil {
|
|
is.cOpts = &options.CreateIndexesOptions{}
|
|
}
|
|
|
|
is.execResult, is.err = is.iv.CreateOne(is.getContext(), is.ims[0], is.cOpts)
|
|
is.assertErr()
|
|
}
|
|
|
|
func (is *IndexScope) doCreateMany() {
|
|
if len(is.ims) == 0 {
|
|
is.err = fmt.Errorf("no such index model, you need to use AddIndexModel() to add some")
|
|
return
|
|
}
|
|
if is.cOpts == nil {
|
|
is.cOpts = &options.CreateIndexesOptions{}
|
|
}
|
|
is.execResult, is.err = is.iv.CreateMany(is.getContext(), is.ims, is.cOpts)
|
|
is.assertErr()
|
|
}
|
|
|
|
// AddIndexModels 添加 indexModel
|
|
func (is *IndexScope) AddIndexModels(obj ...mongo.IndexModel) *IndexScope {
|
|
if len(obj) == 0 {
|
|
is.err = fmt.Errorf("add index model empty")
|
|
return is
|
|
}
|
|
is.ims = append(is.ims, obj...)
|
|
return is
|
|
}
|