func (s *S) TestObjectIdJSONUnmarshaling(c *C) { data := []byte(`{"Id":"4d88e15b60f486e428412dc9"}`) v := jsonType{} err := json.Unmarshal(data, &v) c.Assert(err, IsNil) c.Assert(*v.Id, Equals, bson.ObjectIdHex("4d88e15b60f486e428412dc9")) }
func (s *S) TestObjectIdJSONMarshaling(c *C) { id := bson.ObjectIdHex("4d88e15b60f486e428412dc9") v := jsonType{Id: &id} data, err := json.Marshal(&v) c.Assert(err, IsNil) c.Assert(string(data), Equals, `{"Id":"4d88e15b60f486e428412dc9"}`) }
// PurgeMissing removes from collections any state that refers to transaction // documents that for whatever reason have been lost from the system (removed // by accident or lost in a hard crash, for example). // // This method should very rarely be needed, if at all, and should never be // used during the normal operation of an application. Its purpose is to put // a system that has seen unavoidable corruption back in a working state. func (r *Runner) PurgeMissing(collections ...string) error { type M map[string]interface{} type S []interface{} pipeline := []M{ {"$project": M{"_id": 1, "txn-queue": 1}}, {"$unwind": "$txn-queue"}, {"$sort": M{"_id": 1, "txn-queue": 1}}, //{"$group": M{"_id": M{"$substr": S{"$txn-queue", 0, 24}}, "docids": M{"$push": "$_id"}}}, } type TRef struct { DocId interface{} "_id" TxnId string "txn-queue" } found := make(map[bson.ObjectId]bool) colls := make(map[string]bool) sort.Strings(collections) for _, collection := range collections { c := r.tc.Database.C(collection) iter := c.Pipe(pipeline).Iter() var tref TRef for iter.Next(&tref) { txnId := bson.ObjectIdHex(tref.TxnId[:24]) if found[txnId] { continue } if r.tc.FindId(txnId).One(nil) == nil { found[txnId] = true continue } logf("WARNING: purging from document %s/%v the missing transaction id %s", collection, tref.DocId, txnId) err := c.UpdateId(tref.DocId, M{"$pull": M{"txn-queue": M{"$regex": "^" + txnId.Hex() + "_*"}}}) if err != nil { return fmt.Errorf("error purging missing transaction %s: %v", txnId.Hex(), err) } } colls[collection] = true } type StashTRef struct { Id docKey "_id" TxnId string "txn-queue" } iter := r.sc.Pipe(pipeline).Iter() var stref StashTRef for iter.Next(&stref) { txnId := bson.ObjectIdHex(stref.TxnId[:24]) if found[txnId] { continue } if r.tc.FindId(txnId).One(nil) == nil { found[txnId] = true continue } logf("WARNING: purging from stash document %s/%v the missing transaction id %s", stref.Id.C, stref.Id.Id, txnId) err := r.sc.UpdateId(stref.Id, M{"$pull": M{"txn-queue": M{"$regex": "^" + txnId.Hex() + "_*"}}}) if err != nil { return fmt.Errorf("error purging missing transaction %s: %v", txnId.Hex(), err) } } return nil }
func (tt token) id() bson.ObjectId { return bson.ObjectIdHex(string(tt[:24])) }
func (s *S) TestObjectIdHex(c *C) { id := bson.ObjectIdHex("4d88e15b60f486e428412dc9") c.Assert(id.String(), Equals, `ObjectIdHex("4d88e15b60f486e428412dc9")`) c.Assert(id.Hex(), Equals, "4d88e15b60f486e428412dc9") }
} // -------------------------------------------------------------------------- // ObjectId parts extraction tests. type objectIdParts struct { id bson.ObjectId timestamp int64 machine []byte pid uint16 counter int32 } var objectIds = []objectIdParts{ objectIdParts{ bson.ObjectIdHex("4d88e15b60f486e428412dc9"), 1300816219, []byte{0x60, 0xf4, 0x86}, 0xe428, 4271561, }, objectIdParts{ bson.ObjectIdHex("000000000000000000000000"), 0, []byte{0x00, 0x00, 0x00}, 0x0000, 0, }, objectIdParts{ bson.ObjectIdHex("00000000aabbccddee000001"), 0,