@@ -0,0 +1,465 @@
|
||||
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 >EMatch{
|
||||
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 >Match{
|
||||
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 <Match{
|
||||
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 <EMatch{
|
||||
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 >EAndLTEMatch{
|
||||
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 >EAndLTMatch{
|
||||
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)
|
||||
}
|
||||
Reference in New Issue
Block a user