| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195 | package moimport (	"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 OIDfunc (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 作为绑定类型// 用法参见 TestUnmarshalExtJSONfunc UnmarshalExtJSON(data []byte, canonical bool, val any) error {	return bson.UnmarshalExtJSON(data, canonical, val)}// MarshalExtJSON 将 bson 结构编码为 json 类型func MarshalExtJSON(val any, canonical, escapeHTML bool) ([]byte, error) {	return bson.MarshalExtJSON(val, canonical, escapeHTML)}// Marshal 将 v 作为 bson 进行编码func Marshal(v any) ([]byte, error) {	return bson.Marshal(v)}// Unmarshal 将 data 作为 bson 解析到 valfunc 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 表示 uniquefunc 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 any) error {	ctx, cancel := context.WithTimeout(context.Background(), DefaultTimout)	defer func() {		_ = cursor.Close(ctx)		cancel()	}()	return cursor.All(ctx, v)}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 DecodeAll[V, T any](m []V, dst *[]T) error {	if len(*dst) < len(m) {		*dst = make([]T, len(m))	}	for i, row := range m {		var v T		if err := Decode(row, &v); err != nil {			return err		}		(*dst)[i] = v	}	return nil}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}
 |