2222package mongo
2323
2424import (
25+ "context"
2526 "fmt"
27+ "reflect"
2628 "strings"
2729 "sync"
2830
29- "reflect"
30-
3131 db "github.com/upper/db/v4"
3232 "github.com/upper/db/v4/internal/adapter"
33- mgo "gopkg.in/mgo.v2 "
34- "gopkg.in/mgo.v2/bson "
33+ "go.mongodb.org/mongo-driver/bson "
34+ "go.mongodb.org/mongo-driver/mongo "
3535)
3636
3737// Collection represents a mongodb collection.
3838type Collection struct {
3939 parent * Source
40- collection * mgo .Collection
40+ collection * mongo .Collection
4141}
4242
4343var (
@@ -108,9 +108,15 @@ func compare(field string, cmp *adapter.Comparison) (string, interface{}) {
108108 }
109109 return field , bson.M {"$ne" : value }
110110 case adapter .ComparisonOperatorRegExp , adapter .ComparisonOperatorLike :
111- return field , bson.RegEx {Pattern : value .(string ), Options : "" }
111+ return field , bson.M {
112+ "$regex" : value .(string ),
113+ }
112114 case adapter .ComparisonOperatorNotRegExp , adapter .ComparisonOperatorNotLike :
113- return field , bson.M {"$not" : bson.RegEx {Pattern : value .(string ), Options : "" }}
115+ return field , bson.M {
116+ "$not" : bson.M {
117+ "$regex" : value .(string ),
118+ },
119+ }
114120 }
115121
116122 if cmpOp , ok := comparisonOperators [op ]; ok {
@@ -122,8 +128,8 @@ func compare(field string, cmp *adapter.Comparison) (string, interface{}) {
122128 panic (fmt .Sprintf ("Unsupported operator %v" , op ))
123129}
124130
125- // compileStatement transforms conditions into something *mgo.Session can
126- // understand.
131+ // compileStatement transforms upper-db conditions into something that the
132+ // adapter can understand.
127133func compileStatement (cond db.Cond ) bson.M {
128134 conds := bson.M {}
129135
@@ -170,10 +176,7 @@ func compileStatement(cond db.Cond) bson.M {
170176 return conds
171177}
172178
173- // compileConditions compiles terms into something *mgo.Session can
174- // understand.
175179func (col * Collection ) compileConditions (term interface {}) interface {} {
176-
177180 switch t := term .(type ) {
178181 case []interface {}:
179182 values := []interface {}{}
@@ -208,8 +211,6 @@ func (col *Collection) compileConditions(term interface{}) interface{} {
208211 return nil
209212}
210213
211- // compileQuery compiles terms into something that *mgo.Session can
212- // understand.
213214func (col * Collection ) compileQuery (terms ... interface {}) interface {} {
214215 compiled := col .compileConditions (terms )
215216 if compiled == nil {
@@ -236,13 +237,12 @@ func (col *Collection) compileQuery(terms ...interface{}) interface{} {
236237
237238// Name returns the name of the table or tables that form the collection.
238239func (col * Collection ) Name () string {
239- return col .collection .Name
240+ return col .collection .Name ()
240241}
241242
242243// Truncate deletes all rows from the table.
243244func (col * Collection ) Truncate () error {
244- err := col .collection .DropCollection ()
245-
245+ err := col .collection .Drop (context .Background ())
246246 if err != nil {
247247 return err
248248 }
@@ -268,100 +268,33 @@ func (col *Collection) UpdateReturning(item interface{}) error {
268268
269269// Insert inserts a record (map or struct) into the collection.
270270func (col * Collection ) Insert (item interface {}) (db.InsertResult , error ) {
271- var err error
271+ ctx := context . Background ()
272272
273- id := getID (item )
274-
275- if col .parent .versionAtLeast (2 , 6 , 0 , 0 ) {
276- // this breaks MongoDb older than 2.6
277- if _ , err = col .collection .Upsert (bson.M {"_id" : id }, item ); err != nil {
278- return nil , err
279- }
280- } else {
281- // Allocating a new ID.
282- if err = col .collection .Insert (bson.M {"_id" : id }); err != nil {
283- return nil , err
284- }
285-
286- // Now append data the user wants to append.
287- if err = col .collection .Update (bson.M {"_id" : id }, item ); err != nil {
288- // Cleanup allocated ID
289- if err := col .collection .Remove (bson.M {"_id" : id }); err != nil {
290- return nil , err
291- }
292- return nil , err
293- }
273+ res , err := col .collection .InsertOne (ctx , item )
274+ if err != nil {
275+ return nil , err
294276 }
295277
296- return db .NewInsertResult (id ), nil
278+ return db .NewInsertResult (res . InsertedID ), nil
297279}
298280
299281// Exists returns true if the collection exists.
300282func (col * Collection ) Exists () (bool , error ) {
301- query := col .parent .database .C (`system.namespaces` ).Find (map [string ]string {`name` : fmt .Sprintf (`%s.%s` , col .parent .database .Name , col .collection .Name )})
302- count , err := query .Count ()
303- return count > 0 , err
304- }
283+ ctx := context .Background ()
284+ mcol := col .parent .database .Collection ("system.namespaces" )
305285
306- // Fetches object _id or generates a new one if object doesn't have one or the one it has is invalid
307- func getID (item interface {}) interface {} {
308- v := reflect .ValueOf (item ) // convert interface to Value
309- v = reflect .Indirect (v ) // convert pointers
310-
311- switch v .Kind () {
312- case reflect .Map :
313- if inItem , ok := item .(map [string ]interface {}); ok {
314- if id , ok := inItem ["_id" ]; ok {
315- bsonID , ok := id .(bson.ObjectId )
316- if ok {
317- return bsonID
318- }
319- }
320- }
321- case reflect .Struct :
322- t := v .Type ()
323-
324- idCacheMutex .RLock ()
325- fieldName , found := idCache [t ]
326- idCacheMutex .RUnlock ()
327-
328- if ! found {
329- for n := 0 ; n < t .NumField (); n ++ {
330- field := t .Field (n )
331- if field .PkgPath != "" {
332- continue // Private field
333- }
334-
335- tag := field .Tag .Get ("bson" )
336- if tag == "" {
337- tag = field .Tag .Get ("db" )
338- }
339-
340- if tag == "" {
341- continue
342- }
343-
344- parts := strings .Split (tag , "," )
345-
346- if parts [0 ] == "_id" {
347- fieldName = field .Name
348- idCacheMutex .RLock ()
349- idCache [t ] = fieldName
350- idCacheMutex .RUnlock ()
351- break
352- }
353- }
354- }
355- if fieldName != "" {
356- if bsonID , ok := v .FieldByName (fieldName ).Interface ().(bson.ObjectId ); ok {
357- if bsonID .Valid () {
358- return bsonID
359- }
360- } else {
361- return v .FieldByName (fieldName ).Interface ()
362- }
363- }
286+ mcur , err := mcol .Find (ctx , bson.M {
287+ "name" : fmt .Sprintf ("%s.%s" , col .parent .database .Name (), col .collection .Name ()),
288+ })
289+ if err != nil {
290+ return false , err
291+ }
292+ defer mcur .Close (ctx )
293+
294+ hasNext := mcur .Next (ctx )
295+ if err := mcur .Err (); err != nil {
296+ return false , err
364297 }
365298
366- return bson . NewObjectId ()
299+ return hasNext , nil
367300}
0 commit comments