From 1b19adeb4758179692f1a9b7d34ef4716bbe54c4 Mon Sep 17 00:00:00 2001 From: Carlos Nieto <jose.carlos@menteslibres.net> Date: Mon, 14 Apr 2014 17:16:23 -0500 Subject: [PATCH] Adding db.Func{} support. --- mongo/collection.go | 30 ++++++++++++++++++++---------- mongo/database_test.go | 42 ++++++++++++++++++++++++++++++++++++++++++ mongo/result.go | 6 +++++- 3 files changed, 67 insertions(+), 11 deletions(-) diff --git a/mongo/collection.go b/mongo/collection.go index 97bf700a..f3fb164a 100644 --- a/mongo/collection.go +++ b/mongo/collection.go @@ -70,15 +70,19 @@ func (self *Collection) Find(terms ...interface{}) db.Result { } // Transforms conditions into something *mgo.Session can understand. -func compileStatement(where db.Cond) bson.M { +func compileStatement(cond db.Cond) bson.M { conds := bson.M{} - for key, val := range where { - key = strings.Trim(key, ` `) - chunks := strings.SplitN(key, ` `, 2) + // Walking over conditions + for field, value := range cond { + // Removing leading or trailing spaces. + field = strings.TrimSpace(field) + + chunks := strings.SplitN(field, ` `, 2) + + var op string if len(chunks) > 1 { - op := "" switch chunks[1] { case `>`: op = `$gt` @@ -91,11 +95,17 @@ func compileStatement(where db.Cond) bson.M { default: op = chunks[1] } - //conds[chunks[0]] = bson.M{op: toInternal(val)} - conds[chunks[0]] = bson.M{op: val} - } else { - //conds[key] = toInternal(val) - conds[key] = val + } + + switch value := value.(type) { + case db.Func: + conds[chunks[0]] = bson.M{value.Name: value.Args} + default: + if op == "" { + conds[chunks[0]] = value + } else { + conds[chunks[0]] = bson.M{op: value} + } } } diff --git a/mongo/database_test.go b/mongo/database_test.go index a071612f..12bc4535 100644 --- a/mongo/database_test.go +++ b/mongo/database_test.go @@ -532,6 +532,48 @@ func TestUpdate(t *testing.T) { } +// Test database functions +func TestFunction(t *testing.T) { + var err error + var res db.Result + + // Opening database. + sess, err := db.Open(wrapperName, settings) + + if err != nil { + t.Fatalf(err.Error()) + } + + // We should close the database when it's no longer in use. + defer sess.Close() + + // Getting a pointer to the "artist" collection. + artist, err := sess.Collection("artist") + + if err != nil { + t.Fatalf(err.Error()) + } + + row_s := struct { + Id uint64 + Name string + }{} + + res = artist.Find(db.Cond{"_id $nin": []int{0, -1}}) + + if err = res.One(&row_s); err != nil { + t.Fatalf("One: %q", err) + } + + res = artist.Find(db.Cond{"_id": db.Func{"$nin", []int{0, -1}}}) + + if err = res.One(&row_s); err != nil { + t.Fatalf("One: %q", err) + } + + res.Close() +} + // This test tries to remove some previously added rows. func TestRemove(t *testing.T) { diff --git a/mongo/result.go b/mongo/result.go index 473f7640..abc6487c 100644 --- a/mongo/result.go +++ b/mongo/result.go @@ -126,7 +126,11 @@ func (self *Result) Next(dst interface{}) error { success := self.iter.Next(dst) if success == false { - return db.ErrNoMoreRows + err := self.iter.Err() + if err == nil { + return db.ErrNoMoreRows + } + return err } return nil -- GitLab