func loadNewsItem(path string) ([]*NewsItem, os.Error) { var item *NewsItem items := make([]*NewsItem, 1) cachedItem, found := cachedNewsItems[path] if found { t := time.Seconds() if (t - cachedItem.CachedAt) < (60 * 10) { // cache for 10 minutes items[0] = cachedItem.NewsItem return items, nil } } mongo, err := mgo.Mongo("localhost") if err != nil { return nil, err } defer mongo.Close() c := mongo.DB(*database).C("newsitems") item = &NewsItem{} err = c.Find(bson.M{"page.permalink": path}).One(item) go cacheNewsItem(item) items[0] = item return items, err }
func (s *S) TestRemoveAll(c *C) { session, err := mgo.Mongo("localhost:40001") c.Assert(err, IsNil) defer session.Close() coll := session.DB("mydb").C("mycoll") ns := []int{40, 41, 42, 43, 44, 45, 46} for _, n := range ns { err := coll.Insert(M{"n": n}) c.Assert(err, IsNil) } err = coll.RemoveAll(M{"n": M{"$gt": 42}}) c.Assert(err, IsNil) result := &struct{ N int }{} err = coll.Find(M{"n": 42}).One(result) c.Assert(err, IsNil) c.Assert(result.N, Equals, 42) err = coll.Find(M{"n": 43}).One(result) c.Assert(err, Equals, mgo.NotFound) err = coll.Find(M{"n": 44}).One(result) c.Assert(err, Equals, mgo.NotFound) }
func (s *S) TestFindIterTwiceWithSameQuery(c *C) { session, err := mgo.Mongo("localhost:40001") c.Assert(err, IsNil) defer session.Close() coll := session.DB("mydb").C("mycoll") for i := 40; i != 47; i++ { coll.Insert(M{"n": i}) } query := coll.Find(M{}).Sort(M{"n": 1}) result1, err := query.Skip(1).Iter() c.Assert(err, IsNil) result2, err := query.Skip(2).Iter() c.Assert(err, IsNil) result := struct{ N int }{} err = result2.Next(&result) c.Assert(err, IsNil) c.Assert(result.N, Equals, 42) err = result1.Next(&result) c.Assert(err, IsNil) c.Assert(result.N, Equals, 41) }
func (s *S) TestEnsureIndexDropIndex(c *C) { session, err := mgo.Mongo("localhost:40001") c.Assert(err, IsNil) defer session.Close() coll := session.DB("mydb").C("mycoll") err = coll.EnsureIndexKey([]string{"a"}) c.Assert(err, IsNil) err = coll.EnsureIndexKey([]string{"-b"}) c.Assert(err, IsNil) err = coll.DropIndex([]string{"-b"}) c.Assert(err, IsNil) sysidx := session.DB("mydb").C("system.indexes") dummy := &struct{}{} err = sysidx.Find(M{"name": "a_1"}).One(dummy) c.Assert(err, IsNil) err = sysidx.Find(M{"name": "b_1"}).One(dummy) c.Assert(err, Equals, mgo.NotFound) err = coll.DropIndex([]string{"a"}) c.Assert(err, IsNil) err = sysidx.Find(M{"name": "a_1"}).One(dummy) c.Assert(err, Equals, mgo.NotFound) err = coll.DropIndex([]string{"a"}) c.Assert(err, Matches, "index not found") }
func (s *S) TestMapReduceFinalize(c *C) { session, err := mgo.Mongo("localhost:40001") c.Assert(err, IsNil) defer session.Close() coll := session.DB("mydb").C("mycoll") for _, i := range []int{1, 4, 6, 2, 2, 3, 4} { coll.Insert(M{"n": i}) } job := mgo.MapReduce{ Map: "function() { emit(this.n, 1) }", Reduce: "function(key, values) { return Array.sum(values) }", Finalize: "function(key, count) { return {count: count} }", } var result []struct { Id int "_id" Value struct{ Count int } } _, err = coll.Find(nil).MapReduce(job, &result) c.Assert(err, IsNil) expected := map[int]int{1: 1, 2: 2, 3: 1, 4: 2, 6: 1} for _, item := range result { c.Logf("Item: %#v", &item) c.Assert(item.Value.Count, Equals, expected[item.Id]) expected[item.Id] = -1 } }
func (s *S) TestSort(c *C) { session, err := mgo.Mongo("localhost:40001") c.Assert(err, IsNil) defer session.Close() coll := session.DB("mydb").C("mycoll") coll.Insert(M{"a": 1, "b": 1}) coll.Insert(M{"a": 2, "b": 2}) coll.Insert(M{"a": 2, "b": 1}) coll.Insert(M{"a": 0, "b": 1}) coll.Insert(M{"a": 2, "b": 0}) coll.Insert(M{"a": 0, "b": 2}) coll.Insert(M{"a": 1, "b": 2}) coll.Insert(M{"a": 0, "b": 0}) coll.Insert(M{"a": 1, "b": 0}) query := coll.Find(M{}) query.Sort(bson.D{{"a", -1}}) // Should be ignored. iter, err := query.Sort(bson.D{{"b", -1}, {"a", 1}}).Iter() c.Assert(err, IsNil) l := make([]int, 18) r := struct{ A, B int }{} for i := 0; i != len(l); i += 2 { err := iter.Next(&r) c.Assert(err, IsNil) l[i] = r.A l[i+1] = r.B } c.Assert(l, Equals, []int{0, 2, 1, 2, 2, 2, 0, 1, 1, 1, 2, 1, 0, 0, 1, 0, 2, 0}) }
func (s *S) TestSafeSetting(c *C) { session, err := mgo.Mongo("localhost:40001") c.Assert(err, IsNil) defer session.Close() // Check the default safe := session.Safe() c.Assert(safe.W, Equals, 0) c.Assert(safe.WTimeout, Equals, 0) c.Assert(safe.FSync, Equals, false) // Tweak it session.SetSafe(&mgo.Safe{W: 1, WTimeout: 2, FSync: true}) safe = session.Safe() c.Assert(safe.W, Equals, 1) c.Assert(safe.WTimeout, Equals, 2) c.Assert(safe.FSync, Equals, true) // Reset it again. session.SetSafe(&mgo.Safe{}) safe = session.Safe() c.Assert(safe.W, Equals, 0) c.Assert(safe.WTimeout, Equals, 0) c.Assert(safe.FSync, Equals, false) // Ensure safety to something higher. session.SetSafe(&mgo.Safe{W: 5, WTimeout: 6, FSync: true}) safe = session.Safe() c.Assert(safe.W, Equals, 5) c.Assert(safe.WTimeout, Equals, 6) c.Assert(safe.FSync, Equals, true) // Ensure safety to something less conservative won't change it. session.EnsureSafe(&mgo.Safe{W: 4, WTimeout: 7, FSync: false}) safe = session.Safe() c.Assert(safe.W, Equals, 5) c.Assert(safe.WTimeout, Equals, 6) c.Assert(safe.FSync, Equals, true) // But to something more conservative will. session.EnsureSafe(&mgo.Safe{W: 6, WTimeout: 4}) safe = session.Safe() c.Assert(safe.W, Equals, 6) c.Assert(safe.WTimeout, Equals, 4) c.Assert(safe.FSync, Equals, true) // EnsureSafe with nil does nothing. session.EnsureSafe(nil) safe = session.Safe() c.Assert(safe.W, Equals, 6) c.Assert(safe.WTimeout, Equals, 4) c.Assert(safe.FSync, Equals, true) // Changing the safety of a cloned session doesn't touch the original. clone := session.Clone() defer clone.Close() clone.EnsureSafe(&mgo.Safe{W: 100}) safe = session.Safe() c.Assert(safe.W, Equals, 6) }
func (s *S) TestDirect(c *C) { session, err := mgo.Mongo("localhost:40012?connect=direct") c.Assert(err, IsNil) defer session.Close() // We know that server is a slave. session.SetMode(mgo.Monotonic, true) result := &struct{ Host string }{} err = session.Run("serverStatus", result) c.Assert(err, IsNil) c.Assert(strings.HasSuffix(result.Host, ":40012"), Equals, true) stats := mgo.GetStats() c.Assert(stats.SocketsAlive, Equals, 1) c.Assert(stats.SocketsInUse, Equals, 1) c.Assert(stats.SocketRefs, Equals, 1) // We've got no master, so it'll timeout. session.SetSyncTimeout(5e8) coll := session.DB("mydb").C("mycoll") err = coll.Insert(M{"test": 1}) c.Assert(err, Matches, "no reachable servers") // Slave is still reachable. result.Host = "" err = session.Run("serverStatus", result) c.Assert(err, IsNil) c.Assert(strings.HasSuffix(result.Host, ":40012"), Equals, true) }
func (s *S) TestGridFSOpen(c *C) { session, err := mgo.Mongo("localhost:40011") c.Assert(err, IsNil) defer session.Close() db := session.DB("mydb") gfs := db.GridFS("fs") file, err := gfs.Create("myfile.txt") c.Assert(err, IsNil) file.Write([]byte{'1'}) file.Close() file, err = gfs.Create("myfile.txt") c.Assert(err, IsNil) file.Write([]byte{'2'}) file.Close() file, err = gfs.Open("myfile.txt") c.Assert(err, IsNil) defer file.Close() var b [1]byte _, err = file.Read(b[:]) c.Assert(err, IsNil) c.Assert(string(b[:]), Equals, "2") }
func (s *S) TestPrimaryShutdownStrong(c *C) { if *fast { c.Skip("-fast") } session, err := mgo.Mongo("localhost:40021") c.Assert(err, IsNil) defer session.Close() // With strong consistency, this will open a socket to the master. result := &struct{ Host string }{} err = session.Run("serverStatus", result) c.Assert(err, IsNil) // Kill the master. host := result.Host s.Stop(host) // This must fail, since the connection was broken. err = session.Run("serverStatus", result) c.Assert(err, Equals, io.EOF) // With strong consistency, it fails again until reset. err = session.Run("serverStatus", result) c.Assert(err, Equals, io.EOF) session.Refresh() // Now we should be able to talk to the new master. err = session.Run("serverStatus", result) c.Assert(err, IsNil) c.Assert(result.Host, Not(Equals), host) }
func (s *S) TestPrimaryShutdownEventual(c *C) { if *fast { c.Skip("-fast") } session, err := mgo.Mongo("localhost:40021") c.Assert(err, IsNil) defer session.Close() result := &struct{ Host string }{} err = session.Run("serverStatus", result) c.Assert(err, IsNil) master := result.Host session.SetMode(mgo.Eventual, true) // Should connect to the master when needed. coll := session.DB("mydb").C("mycoll") err = coll.Insert(M{"a": 1}) c.Assert(err, IsNil) // Kill the master. s.Stop(master) // Should still work, with the new master now. coll = session.DB("mydb").C("mycoll") err = coll.Insert(M{"a": 1}) c.Assert(err, IsNil) err = session.Run("serverStatus", result) c.Assert(err, IsNil) c.Assert(result.Host, Not(Equals), master) }
func (s *S) TestSetModeMonotonicAfterStrong(c *C) { // Test that a strong session shifting to a monotonic // one preserves the socket untouched. session, err := mgo.Mongo("localhost:40012") c.Assert(err, IsNil) defer session.Close() // Insert something to force a connection to the master. coll := session.DB("mydb").C("mycoll") err = coll.Insert(M{"a": 1}) c.Assert(err, IsNil) session.SetMode(mgo.Monotonic, false) // Wait since the sync also uses sockets. for len(session.LiveServers()) != 3 { c.Log("Waiting for cluster sync to finish...") time.Sleep(5e8) } // Master socket should still be reserved. stats := mgo.GetStats() c.Assert(stats.SocketsInUse, Equals, 1) // Confirm it's the master even though it's Monotonic by now. result := M{} cmd := session.DB("admin").C("$cmd") err = cmd.Find(M{"ismaster": 1}).One(&result) c.Assert(err, IsNil) c.Assert(result["ismaster"], Equals, true) }
// test function to test that MongoDB works func Test() { log.Println("DB Test") session, err := mgo.Mongo("localhost") if err != nil { panic(err) } defer session.Close() //db.Run(mgo.D{{"create", "mycollection"}, {"size", 1024}}) c := session.DB("try").C("try") err = c.Insert(&Server{Id: 1, Name: "kcode.de"}, &Server{Id: 2, Name: "MyServer 3 [Dedicated]"}) if err != nil { panic(err) } result := Server{} qry := c.Find(bson.M{"id": 1}) err = qry.One(&result) if err != nil { panic(err) } log.Println(result) var result2 *Server qry.For(&result2, func() os.Error { //fmt.Printf("r2: %v\n", result2) fmt.Printf("r2: %d %s\n", result2.Id, result2.Name) return nil }) }
func init() { var err error session, err = mgo.Mongo(Env("MONGO_URL", "localhost")) if err != nil { log.Fatal(err) } }
func main() { flag.Parse() go hub() var err error session, err = mgo.Mongo("localhost") if err != nil { panic("main > Mongo: " + err.Error()) } defer session.Close() pfx := "/static/" h := http.StripPrefix(pfx, http.FileServer(http.Dir("../static/"))) http.Handle(pfx, h) // It is absurd I had to work that hard to serve static files. Let's shove them on AWS or something and forget about it http.HandleFunc("/tickle", doTickle) http.HandleFunc("/keys", viewKeys) http.HandleFunc("/keys/add", addKey) http.HandleFunc("/keys/check", checkKey) http.HandleFunc("/links/send", sendLink) http.HandleFunc("/register", registerHandler) http.HandleFunc("/openid/callback", openID) http.HandleFunc("/openid/callback/chrome", openID) http.HandleFunc("/users/validate", validateUser) http.HandleFunc("/logout", doLogout) http.HandleFunc("/login", doLogin) http.HandleFunc("/links/", linksList) http.HandleFunc("/", rootHandler) http.Handle("/ws", websocket.Handler(wsHandler)) if err := http.ListenAndServe(*addr, nil); err != nil { log.Fatal("ListenAndServe:", err) } }
func (s *S) TestGridFSRemove(c *C) { session, err := mgo.Mongo("localhost:40011") c.Assert(err, IsNil) defer session.Close() db := session.DB("mydb") gfs := db.GridFS("fs") file, err := gfs.Create("myfile.txt") c.Assert(err, IsNil) file.Write([]byte{'1'}) file.Close() file, err = gfs.Create("myfile.txt") c.Assert(err, IsNil) file.Write([]byte{'2'}) file.Close() err = gfs.Remove("myfile.txt") c.Assert(err, IsNil) _, err = gfs.Open("myfile.txt") c.Assert(err == mgo.NotFound, Equals, true) n, err := db.C("fs.chunks").Find(nil).Count() c.Assert(err, IsNil) c.Assert(n, Equals, 0) }
func (s *S) TestFindForStopOnError(c *C) { session, err := mgo.Mongo("localhost:40001") c.Assert(err, IsNil) defer session.Close() coll := session.DB("mydb").C("mycoll") ns := []int{40, 41, 42, 43, 44, 45, 46} for _, n := range ns { coll.Insert(M{"n": n}) } query := coll.Find(M{"n": M{"$gte": 42}}) i := 2 var result *struct{ N int } err = query.For(&result, func() os.Error { c.Assert(i < 4, Equals, true) c.Assert(result.N, Equals, ns[i]) if i == 3 { return os.NewError("stop!") } i++ return nil }) c.Assert(err, Matches, "stop!") }
func TestMongo(t *testing.T) { t.Log("Looking for mongo daemon") session, err := mgo.Mongo("localhost") if err != nil { panic(err) } defer session.Close() // Optional. Switch the session to a monotonic behavior. session.SetMode(mgo.Monotonic, true) c := session.DB("test").C("people") err = c.Insert(&Customer{"Ale", "+55 53 8116 9639"}, &Customer{"Cla", "+55 53 8402 8510"}) if err != nil { panic(err) } result := Customer{} err = c.Find(bson.M{"name": "Ale"}).One(&result) if err != nil { panic(err) } fmt.Println("Phone:", result.Phone) }
func (s *S) TestPrefetching(c *C) { session, err := mgo.Mongo("localhost:40001") c.Assert(err, IsNil) defer session.Close() coll := session.DB("mydb").C("mycoll") docs := make([]interface{}, 200) for i := 0; i != 200; i++ { docs[i] = M{"n": i} } coll.Insert(docs...) // Same test three times. Once with prefetching via query, then with the // default prefetching, and a third time tweaking the default settings in // the session. for testi := 0; testi != 3; testi++ { mgo.ResetStats() var iter *mgo.Iter var nextn int switch testi { case 0: // First, using query methods. iter, err = coll.Find(M{}).Prefetch(0.27).Batch(100).Iter() c.Assert(err, IsNil) nextn = 73 case 1: // Then, the default session value. session.SetBatch(100) iter, err = coll.Find(M{}).Iter() c.Assert(err, IsNil) nextn = 75 case 2: // Then, tweaking the session value. session.SetBatch(100) session.SetPrefetch(0.27) iter, err = coll.Find(M{}).Iter() c.Assert(err, IsNil) nextn = 73 } result := struct{ N int }{} for i := 0; i != nextn; i++ { iter.Next(&result) } stats := mgo.GetStats() c.Assert(stats.ReceivedDocs, Equals, 100) iter.Next(&result) // Ping the database just to wait for the fetch above // to get delivered. session.Run("ping", M{}) // XXX Should support nil here. stats = mgo.GetStats() c.Assert(stats.ReceivedDocs, Equals, 201) // 200 + the ping result } }
func edit(w http.ResponseWriter, c *http.Request, s goweb.Result, path ...string) goweb.Result { title := path[0] session, err := mgo.Mongo(server) check(err) defer session.Close() result, err := getPage(session, title) if c.Method == "GET" { if err == mgo.NotFound { result.Title = title } else { check(err) } createtpl.Execute(w, result) } else if c.Method == "POST" { page := new(Page) page.Title = title page.Body = c.FormValue("body") ctx := session.DB(dbname).C("pages") if err == mgo.NotFound { err := ctx.Insert(page) check(err) } else { check(err) _, err := ctx.Upsert(result, page) check(err) } http.Redirect(w, c, "/view/"+title, 302) } return s }
func (s *S) TestSafeInsert(c *C) { session, err := mgo.Mongo("localhost:40001") c.Assert(err, IsNil) defer session.Close() coll := session.DB("mydb").C("mycoll") // Insert an element with a predefined key. err = coll.Insert(M{"_id": 1}) c.Assert(err, IsNil) mgo.ResetStats() // Session should be safe by default, so inserting it again must fail. err = coll.Insert(M{"_id": 1}) c.Assert(err, Matches, "E11000 duplicate.*") c.Assert(err.(*mgo.LastError).Code, Equals, 11000) // It must have sent two operations (INSERT_OP + getLastError QUERY_OP) stats := mgo.GetStats() c.Assert(stats.SentOps, Equals, 2) mgo.ResetStats() // If we disable safety, though, it won't complain. session.SetSafe(nil) err = coll.Insert(M{"_id": 1}) c.Assert(err, IsNil) // Must have sent a single operation this time (just the INSERT_OP) stats = mgo.GetStats() c.Assert(stats.SentOps, Equals, 1) }
func main() { session, err := mgo.Mongo("localhost") if err != nil { panic(err) } defer session.Close() // Optional. Switch the session to a monotonic behavior. session.SetMode(mgo.Monotonic, true) c := session.DB("test").C("people") err = c.Insert(&Person{"Ale", "+55 53 8116 9639"}, &Person{"Cla", "+55 53 8402 8510"}) if err != nil { panic(err) } result := Person{} err = c.Find(bson.M{"name": "Ale"}).One(&result) if err != nil { panic(err) } fmt.Println("Phone:", result.Phone) }
func (s *S) TestEnsureIndexGetIndexes(c *C) { session, err := mgo.Mongo("localhost:40001") c.Assert(err, IsNil) defer session.Close() coll := session.DB("mydb").C("mycoll") err = coll.EnsureIndexKey([]string{"-b"}) c.Assert(err, IsNil) err = coll.EnsureIndexKey([]string{"a"}) c.Assert(err, IsNil) err = coll.EnsureIndexKey([]string{"@c"}) c.Assert(err, IsNil) indexes, err := coll.Indexes() c.Assert(indexes[0].Name, Equals, "_id_") c.Assert(indexes[1].Name, Equals, "a_1") c.Assert(indexes[1].Key, Equals, []string{"a"}) c.Assert(indexes[2].Name, Equals, "b_-1") c.Assert(indexes[2].Key, Equals, []string{"-b"}) c.Assert(indexes[3].Name, Equals, "c_") c.Assert(indexes[3].Key, Equals, []string{"@c"}) }
func main() { session, err := mgo.Mongo("mongotest") if err != nil { panic(err) } defer session.Close() session.SetMode(mgo.Monotonic, true) c := session.DB("test").C("people") err = c.Insert(&Person{"Ale", "+55 53 8116 9639"}, &Person{"Cla", "+55 53 8402 8510"}) if err != nil { panic(err) } var result *Person iter, err := c.Find(nil).Iter() if err != nil { panic(err) } for { err = iter.Next(&result) if err != nil { break } fmt.Println(result.Name, " Phone:", result.Phone) } if err != mgo.NotFound { panic(err) } }
func (s *S) TestUpdateAll(c *C) { session, err := mgo.Mongo("localhost:40001") c.Assert(err, IsNil) defer session.Close() coll := session.DB("mydb").C("mycoll") ns := []int{40, 41, 42, 43, 44, 45, 46} for _, n := range ns { err := coll.Insert(M{"k": n, "n": n}) c.Assert(err, IsNil) } err = coll.UpdateAll(M{"k": M{"$gt": 42}}, M{"$inc": M{"n": 1}}) c.Assert(err, IsNil) result := make(M) err = coll.Find(M{"k": 42}).One(result) c.Assert(err, IsNil) c.Assert(result["n"], Equals, 42) err = coll.Find(M{"k": 43}).One(result) c.Assert(err, IsNil) c.Assert(result["n"], Equals, 44) err = coll.Find(M{"k": 44}).One(result) c.Assert(err, IsNil) c.Assert(result["n"], Equals, 45) err = coll.UpdateAll(M{"k": 47}, M{"k": 47, "n": 47}) c.Assert(err, Equals, mgo.NotFound) }
func init() { bean("Session", func() interface{} { session, _ := mgo.Mongo("127.0.0.1") session.SetMode(mgo.Monotonic, true) return session }) }
func (s *S) TestQueryExplain(c *C) { session, err := mgo.Mongo("localhost:40001") c.Assert(err, IsNil) defer session.Close() coll := session.DB("mydb").C("mycoll") ns := []int{40, 41, 42} for _, n := range ns { err := coll.Insert(M{"n": n}) c.Assert(err, IsNil) } m := M{} query := coll.Find(nil).Batch(1).Limit(2) err = query.Batch(2).Explain(m) c.Assert(err, IsNil) c.Assert(m["cursor"], Equals, "BasicCursor") c.Assert(m["nscanned"], Equals, 2) c.Assert(m["n"], Equals, 2) n := 0 var result M err = query.For(&result, func() os.Error { n++ return nil }) c.Assert(err, IsNil) c.Assert(n, Equals, 2) }
func initMongo() { var err error mSession, err = mgo.Mongo(config.Get("mongohost")) if err != nil { panic(err) } }
func (s *S) TestTopologySyncWithSlaveSeed(c *C) { // That's supposed to be a slave. Must run discovery // and find out master to insert successfully. session, err := mgo.Mongo("localhost:40012") c.Assert(err, IsNil) defer session.Close() coll := session.DB("mydb").C("mycoll") coll.Insert(M{"a": 1, "b": 2}) result := struct{ Ok bool }{} err = session.Run("getLastError", &result) c.Assert(err, IsNil) c.Assert(result.Ok, Equals, true) // One connection to each during discovery. Master // socket recycled for insert. stats := mgo.GetStats() c.Assert(stats.MasterConns, Equals, 1) c.Assert(stats.SlaveConns, Equals, 2) // Only one socket reference alive, in the master socket owned // by the above session. c.Assert(stats.SocketsInUse, Equals, 1) // Refresh it, and it must be gone. session.Refresh() stats = mgo.GetStats() c.Assert(stats.SocketsInUse, Equals, 0) }
func mongoConnect() { session, err := mgo.Mongo(MONGO_URL) check(err) collection = session.DB(MONGO_DB).C(MONGO_COL_FTBFS) causes = session.DB(MONGO_DB).C(MONGO_COL_CAUSES) }