Files
huangguo_server/common/pageopt/match.go
T
rootandClaude Opus 5 8679200f41 Initial commit
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-15 13:57:10 +08:00

466 lines
6.6 KiB
Go

package pageopt
import (
"reflect"
"time"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/bson/primitive"
)
// M M from Map
type M = bson.M
// Matcher
type Matcher interface {
Filter() M
}
// MergeM
func MergeM(mats []Matcher) M {
merge := M{}
for _, m := range mats {
if m == nil {
continue
}
ql := m.Filter()
for k, v := range ql {
merge[k] = v
}
}
return merge
}
type MergeMatch struct {
merge M
}
func NewMergeMatch(mats ...Matcher) Matcher {
mergeM := MergeM(mats)
return &MergeMatch{mergeM}
}
func (m *MergeMatch) Filter() M {
return m.merge
}
// AssignMatch
type AssignMatch struct {
Key string
Val interface{}
}
func NewAssignMatch(key string, val interface{}) Matcher {
return &AssignMatch{
key,
val,
}
}
func (m *AssignMatch) Filter() M {
if IsEmpt(m.Val) {
return M{}
}
return M{
m.Key: m.Val,
}
}
// RegexMatch
type RegexMatch struct {
Key string
Val interface{}
Options string
}
func NewRegexMatch(key string, val interface{}, opt string) Matcher {
return &RegexMatch{
Key: key,
Val: val,
Options: opt,
}
}
func (r *RegexMatch) Filter() M {
if IsEmpt(r.Val) {
return M{}
}
return M{
r.Key: M{"$regex": r.Val, "$options": r.Options},
}
}
func IsNil(i interface{}) bool {
vi := reflect.ValueOf(i)
return vi.IsNil()
}
func IsEmpt(i interface{}) bool {
v := reflect.ValueOf(i)
switch v.Kind() {
case reflect.Ptr:
return v.IsNil()
case reflect.Slice, reflect.Array:
return v.Len() == 0
}
return false
}
type NEMatch struct {
Key string
NE interface{}
}
func (m *NEMatch) Filter() M {
if IsEmpt(m.NE) {
return M{}
}
return M{m.Key: M{"$ne": m.NE}}
}
func NewNEMatch(Key string, ne interface{}) Matcher {
return &NEMatch{
Key: Key,
NE: ne,
}
}
// GTEMatch
type GTEMatch struct {
Key string
GTE interface{}
}
func NewGTEMatch(Key string, gte interface{}) Matcher {
return &GTEMatch{
Key: Key,
GTE: gte,
}
}
func (m *GTEMatch) Filter() M {
if IsEmpt(m.GTE) {
return M{}
}
return M{m.Key: M{"$gte": m.GTE}}
}
// GTMatch
type GTMatch struct {
Key string
GT interface{}
}
func NewGTMatch(Key string, gt interface{}) Matcher {
return &GTMatch{
Key: Key,
GT: gt,
}
}
func (m *GTMatch) Filter() M {
if IsEmpt(m.GT) {
return M{}
}
return M{m.Key: M{"$gt": m.GT}}
}
// LTMatch
type LTMatch struct {
Key string
LT interface{}
}
func NewLTMatch(Key string, lt interface{}) Matcher {
return &LTMatch{
Key: Key,
LT: lt,
}
}
func (m *LTMatch) Filter() M {
if IsEmpt(m.LT) {
return M{}
}
return M{m.Key: M{"$lt": m.LT}}
}
// LTEMatch
type LTEMatch struct {
Key string
LTE interface{}
}
func NewLTEMatch(Key string, lte interface{}) Matcher {
return &LTEMatch{
Key: Key,
LTE: lte,
}
}
func (m *LTEMatch) Filter() M {
if IsEmpt(m.LTE) {
return M{}
}
return M{m.Key: M{"$lte": m.LTE}}
}
// GTEAndLTEMatch
type GTEAndLTEMatch struct {
Key string
GTE interface{}
LTE interface{}
}
func NewGTEAndLTEMatch(Key string, gte, lte interface{}) Matcher {
return &GTEAndLTEMatch{
Key,
gte,
lte,
}
}
func (m *GTEAndLTEMatch) Filter() M {
if IsEmpt(m.GTE) || IsEmpt(m.LTE) {
return M{}
}
return M{
m.Key: M{
"$gte": m.GTE,
"$lte": m.LTE,
},
}
}
// GTEAndLTMatch
type GTEAndLTMatch struct {
Key string
GTE interface{}
LT interface{}
}
func NewGTEAndLTMatch(key string, gte, lt interface{}) Matcher {
return &GTEAndLTMatch{
Key: key,
GTE: gte,
LT: lt,
}
}
func (m *GTEAndLTMatch) Filter() M {
if IsEmpt(m.GTE) || IsEmpt(m.LT) {
return M{}
}
return M{
m.Key: M{
"$gte": m.GTE,
"$lt": m.LT,
},
}
}
// ExistsMatch
type ExistsMatch struct {
Key string
IsExisted *bool
}
func NewExistsMatch(key string, isExisted *bool) Matcher {
return &ExistsMatch{
Key: key,
IsExisted: isExisted,
}
}
func (e *ExistsMatch) Filter() M {
if IsEmpt(e.IsExisted) {
return M{}
}
return M{
e.Key: M{"$exists": e.IsExisted},
}
}
// InMatch
type InMatch struct {
Key string
Slice interface{}
}
func NewInMatch(key string, slice interface{}) Matcher {
return &InMatch{
Key: key,
Slice: slice,
}
}
func (i *InMatch) Filter() M {
if IsNil(i.Slice) {
return M{}
}
return M{
i.Key: M{"$in": i.Slice},
}
}
// NinMatch
type NinMatch struct {
Key string
Slice interface{}
}
func NewNinMatch(key string, slice interface{}) Matcher {
return &NinMatch{
Key: key,
Slice: slice,
}
}
func (n *NinMatch) Filter() M {
if IsNil(n.Slice) {
return M{}
}
return M{
n.Key: M{"$nin": n.Slice},
}
}
// ManualOrMatch
type ManualOrMatch struct {
Key string
Mats []Matcher
}
func NewManualOrMatch(key string, mats []Matcher) Matcher {
return &ManualOrMatch{
Key: key,
Mats: mats,
}
}
func (o *ManualOrMatch) Filter() M {
if len(o.Mats) == 0 {
return M{}
}
fs := []interface{}{}
for _, v := range o.Mats {
f := v.Filter()
if len(f) != 0 {
fs = append(fs, v.Filter())
}
}
if len(fs) == 0 {
return M{}
}
return M{"$or": fs}
}
// BitsAllSetMatch
type BitsAllSetMatch struct {
Key string
Bits []int
}
func NewBitsAllSetMatch(key string, bits []int) Matcher {
return &BitsAllSetMatch{
Key: key,
Bits: bits,
}
}
func (b *BitsAllSetMatch) Filter() M {
if len(b.Bits) == 0 {
return M{}
}
return M{
b.Key: M{"$bitsAllSet": b.Bits},
}
}
// BitsAllClearMatch
type BitsAllClearMatch struct {
Key string
Bits []int
}
func NewBitsAllClearMatch(key string, bits []int) Matcher {
return &BitsAllClearMatch{
Key: key,
Bits: bits,
}
}
func (b *BitsAllClearMatch) Filter() M {
if len(b.Bits) == 0 {
return M{}
}
return M{
b.Key: M{"$bitsAllClear": b.Bits},
}
}
// UIDMatch
type UIDMatch struct {
UID *uint64
}
func (u *UIDMatch) New() Matcher {
return NewAssignMatch("uid", u.UID)
}
// UIDInMatch
type UIDInMatch struct {
UIDS []uint64
}
func (u *UIDInMatch) New() Matcher {
return NewInMatch("uid", u.UIDS)
}
// IDMatch
type IDMatch struct {
ID *primitive.ObjectID
}
func (i *IDMatch) New() Matcher {
return NewAssignMatch("_id", i.ID)
}
// IDInMatch
type IDInMatch struct {
IDs []primitive.ObjectID
}
func (c *IDInMatch) New() Matcher {
return NewInMatch("_id", c.IDs)
}
// CreatedAtGTEMatch
type CreatedAtGTEMatch struct {
GTE *time.Time
}
func (c *CreatedAtGTEMatch) New() Matcher {
return NewGTEMatch("createdAt", c.GTE)
}
// CreatedAtLTMatch
type CreatedAtLTMatch struct {
LT *time.Time
}
func (c *CreatedAtLTMatch) New() Matcher {
return NewLTMatch("createdAt", c.LT)
}
// CreatedAtGTEAndLTMatch
type CreatedAtGTEAndLTMatch struct {
GTE *time.Time
LT *time.Time
}
func (c *CreatedAtGTEAndLTMatch) New() Matcher {
return NewGTEAndLTMatch("createdAt", c.GTE, c.LT)
}