| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201 | 
							- package mo
 
- import (
 
- 	"context"
 
- 	"strings"
 
- 	"time"
 
- 	"go.mongodb.org/mongo-driver/bson"
 
- 	"go.mongodb.org/mongo-driver/bson/primitive"
 
- )
 
- const (
 
- 	OID = "_id"
 
- )
 
- type oid struct{}
 
- // String fmt usd only. import use OID
 
- func (oid) String() string {
 
- 	return OID
 
- }
 
- func (oid) New() ObjectID {
 
- 	return primitive.NewObjectID()
 
- }
 
- func (oid) From(hex string) (ObjectID, error) {
 
- 	id, err := primitive.ObjectIDFromHex(hex)
 
- 	if err != nil {
 
- 		return NilObjectID, err
 
- 	}
 
- 	if id.IsZero() {
 
- 		return NilObjectID, ErrInvalidHex
 
- 	}
 
- 	return id, nil
 
- }
 
- func (oid) FromMust(hex string) ObjectID {
 
- 	id, err := primitive.ObjectIDFromHex(hex)
 
- 	if err != nil {
 
- 		panic(err)
 
- 	}
 
- 	if id.IsZero() {
 
- 		panic(ErrInvalidHex)
 
- 	}
 
- 	return id
 
- }
 
- func (o oid) IsValid(hex string) bool {
 
- 	_, err := o.From(hex)
 
- 	return err == nil
 
- }
 
- var (
 
- 	ID = oid{} // ID 用于 ObjectID 的 API
 
- )
 
- // UnmarshalExtJSON 将 json 字符串解析为 bson 类型
 
- // data 为字符串字节, canonical 是否为严格类型, val 需要绑定的类型
 
- // 可参考 https://www.mongodb.com/docs/manual/reference/mongodb-extended-json/#examples
 
- // 与 json.Unmarshal 不同的是: 当 val 为 D / M 时, 会保留 key 的顺序. 但由于 Go 语言 for 循环 map 时会打乱顺序, 因此如果对 key 的顺序
 
- // 有要求时请使用 D 作为绑定类型
 
- // 用法参见 TestUnmarshalExtJSON
 
- func UnmarshalExtJSON(data []byte, canonical bool, val any) error {
 
- 	return bson.UnmarshalExtJSON(data, canonical, val)
 
- }
 
- func MarshalExtJSON(val any, canonical, escapeHTML bool) ([]byte, error) {
 
- 	return bson.MarshalExtJSON(val, canonical, escapeHTML)
 
- }
 
- func Marshal(v any) ([]byte, error) {
 
- 	return bson.Marshal(v)
 
- }
 
- func Unmarshal(data []byte, val any) error {
 
- 	return bson.Unmarshal(data, val)
 
- }
 
- func NewDateTime() DateTime {
 
- 	return NewDateTimeFromTime(time.Now())
 
- }
 
- func NewDateTimeFromTime(t time.Time) DateTime {
 
- 	return primitive.NewDateTimeFromTime(t.Local())
 
- }
 
- func NewDecimal128(h, l uint64) Decimal128 {
 
- 	return primitive.NewDecimal128(h, l)
 
- }
 
- // ResolveIndexName 从 cursor 中解析出索引名称, 索引名称见 IndexName
 
- // bool 表示 unique
 
- func ResolveIndexName(cursor *Cursor) (map[string]bool, error) {
 
- 	var idxList A
 
- 	if err := CursorDecodeAll(cursor, &idxList); err != nil {
 
- 		return nil, err
 
- 	}
 
- 	idxMap := make(map[string]bool)
 
- 	for _, idx := range idxList {
 
- 		arr, ok := idx.(D)
 
- 		if !ok {
 
- 			panic(arr)
 
- 		}
 
- 		attrMap := ToMFast(arr)
 
- 		if name, on := attrMap["name"].(string); on {
 
- 			if strings.HasPrefix(name, OID) {
 
- 				continue
 
- 			}
 
- 			if unique, o := attrMap["unique"].(bool); o {
 
- 				idxMap[name] = unique
 
- 			} else {
 
- 				idxMap[name] = false
 
- 			}
 
- 		}
 
- 	}
 
- 	return idxMap, nil
 
- }
 
- func ResolveDateTime(value string) (DateTime, error) {
 
- 	return ResolveDateTimeFrom(ISODate, value)
 
- }
 
- func ResolveDateTimeFrom(layout string, value string) (DateTime, error) {
 
- 	t, err := time.ParseInLocation(layout, value, time.Local)
 
- 	if err != nil {
 
- 		return 0, err
 
- 	}
 
- 	return NewDateTimeFromTime(t), nil
 
- }
 
- func CursorDecodeAll(cursor *Cursor, v interface{}) error {
 
- 	ctx, cancel := context.WithTimeout(context.Background(), DefaultTimout)
 
- 	defer func() {
 
- 		_ = cursor.Close(ctx)
 
- 		cancel()
 
- 	}()
 
- 	return cursor.All(ctx, v)
 
- }
 
- func CursorDecode(cursor *Cursor, v interface{}) error {
 
- 	ctx, cancel := context.WithTimeout(context.Background(), DefaultTimout)
 
- 	defer func() {
 
- 		_ = cursor.Close(ctx)
 
- 		cancel()
 
- 	}()
 
- 	var err error
 
- 	for cursor.Next(ctx) {
 
- 		if err = cursor.Decode(v); err == nil {
 
- 			return nil
 
- 		}
 
- 	}
 
- 	return err
 
- }
 
- func HasOperator(pipe Pipeline, operator string) (int, any, bool) {
 
- 	for i, p := range pipe {
 
- 		if len(p) > 0 && p[0].Key == operator {
 
- 			return i, p[0].Value, true
 
- 		}
 
- 	}
 
- 	return -1, nil, false
 
- }
 
- func OperatorHas(doc D, operator string) bool {
 
- 	for _, ele := range doc {
 
- 		if ele.Key == operator {
 
- 			return true
 
- 		}
 
- 	}
 
- 	return false
 
- }
 
- func Decode(m, v any) error {
 
- 	b, err := Marshal(m)
 
- 	if err != nil {
 
- 		return err
 
- 	}
 
- 	return Unmarshal(b, v)
 
- }
 
- func DecodeJson(m, v any) error {
 
- 	b, err := MarshalExtJSON(m, true, true)
 
- 	if err != nil {
 
- 		return err
 
- 	}
 
- 	return UnmarshalExtJSON(b, true, &v)
 
- }
 
- func DeepCopy(src M) (M, error) {
 
- 	var dst M
 
- 	return dst, Decode(src, &dst)
 
- }
 
- func ToA[T any](src []T) A {
 
- 	s := make(A, len(src))
 
- 	for i := 0; i < len(src); i++ {
 
- 		s[i] = src[i]
 
- 	}
 
- 	return s
 
- }
 
 
  |