466 lines
6.6 KiB
Go
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 >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)
|
|
}
|