func (f *flusher) assert(t *transaction, revnos []int64, pull map[bson.ObjectId]*transaction) error {
	f.debugf("Asserting %s with revnos %v", t, revnos)
	if t.State != tprepared {
		panic(fmt.Errorf("asserting transaction in invalid state: %q", t.State))
	}
	qdoc := make(bson.D, 3)
	revno := make(map[docKey]int64)
	for i, op := range t.Ops {
		dkey := op.docKey()
		if _, ok := revno[dkey]; !ok {
			revno[dkey] = revnos[i]
		}
		if op.Assert == nil {
			continue
		}
		if op.Assert == DocMissing {
			if revnos[i] >= 0 {
				return f.abortOrReload(t, revnos, pull)
			}
			continue
		}
		if op.Insert != nil {
			return fmt.Errorf("Insert can only Assert txn.DocMissing", op.Assert)
		}
		// if revnos[i] < 0 { abort }?

		qdoc = append(qdoc[:0], bson.DocElem{"_id", op.Id})
		if op.Assert != DocMissing {
			var revnoq interface{}
			if n := revno[dkey]; n == 0 {
				revnoq = bson.D{{"$exists", false}}
			} else {
				revnoq = n
			}
			// XXX Add tt to the query here, once we're sure it's all working.
			//     Not having it increases the chances of breaking on bad logic.
			qdoc = append(qdoc, bson.DocElem{"txn-revno", revnoq})
			if op.Assert != DocExists {
				qdoc = append(qdoc, bson.DocElem{"$or", []interface{}{op.Assert}})
			}
		}

		c := f.tc.Database.C(op.C)
		if err := c.Find(qdoc).Select(bson.D{{"_id", 1}}).One(nil); err == mgo.ErrNotFound {
			// Assertion failed or someone else started applying.
			return f.abortOrReload(t, revnos, pull)
		} else if err != nil {
			return err
		}
	}
	f.debugf("Asserting %s succeeded", t)
	return nil
}
func (f *flusher) assert(t *transaction, revnos []int64, pull map[bson.ObjectId]*transaction) error {
	f.debugf("Asserting %s with revnos %v", t, revnos)
	if t.State != tprepared {
		panic(fmt.Errorf("asserting transaction in invalid state: %q", t.State))
	}
	qdoc := make(bson.D, 3)
	revno := make(map[docKey]int64)
	for i, op := range t.Ops {
		dkey := op.docKey()
		if _, ok := revno[dkey]; !ok {
			revno[dkey] = revnos[i]
		}
		if op.Assert == nil {
			continue
		}
		if op.Assert == DocMissing {
			if revnos[i] >= 0 {
				return f.abortOrReload(t, revnos, pull)
			}
			continue
		}
		if op.Insert != nil {
			return fmt.Errorf("Insert can only Assert txn.DocMissing", op.Assert)
		}
		// if revnos[i] < 0 { abort }?

		qdoc = append(qdoc[:0], bson.DocElem{"_id", op.Id})
		if op.Assert != DocMissing {
			var revnoq interface{}
			if n := revno[dkey]; n == 0 {
				revnoq = bson.D{{"$exists", false}}
			} else {
				revnoq = n
			}
			// XXX Add tt to the query here, once we're sure it's all working.
			//     Not having it increases the chances of breaking on bad logic.
			qdoc = append(qdoc, bson.DocElem{"txn-revno", revnoq})
			if op.Assert != DocExists {
				qdoc = append(qdoc, bson.DocElem{"$or", []interface{}{op.Assert}})
			}
		}

		c := f.tc.Database.C(op.C)
		if err := c.Find(qdoc).Select(bson.D{{"_id", 1}}).One(nil); err == mgo.ErrNotFound {
			// Assertion failed or someone else started applying.
			return f.abortOrReload(t, revnos, pull)
		} else if err != nil {
			return err
		}
	}
	f.debugf("Asserting %s succeeded", t)
	return nil
}
func ( f * flusher ) assert ( t * transaction , revnos [ ] int64 , pull map [ bson . ObjectId ] * transaction ) error { f . debugf ( " " , t , revnos ) if t . State != tprepared { panic ( fmt . Errorf ( " " , t . State ) ) } qdoc := make ( bson . D , 3 ) revno := make ( map [ docKey ] int64 ) for i , op := range t . Ops { dkey := op . docKey ( ) if _ , ok := revno [ dkey ] ; ! ok { revno [ dkey ] = revnos [ i ] } if op . Assert == nil { continue } if op . Assert == DocMissing { if revnos [ i ] >= 0 { return f . abortOrReload ( t , revnos , pull ) } continue } if op . Insert != nil { return fmt . Errorf ( " " , op . Assert ) } // if revnos[i] < 0 { abort }? qdoc = append ( qdoc [ : 0 ] , bson . DocElem { " " , op . Id } ) if op . Assert != DocMissing { var revnoq interface { } if n := revno [ dkey ] ; n == 0 { revnoq = bson . D { { " " , false } } } else { revnoq = n } // XXX Add tt to the query here, once we're sure it's all working. //     Not having it increases the chances of breaking on bad logic. qdoc = append ( qdoc , bson . DocElem { " " , revnoq } ) if op . Assert != DocExists { qdoc = append ( qdoc , bson . DocElem { " " , [ ] interface { } { op . Assert } } ) } } c := f . tc . Database . C ( op . C ) if err := c . Find ( qdoc ) . Select ( bson . D { { " " , 1 } } ) . One ( nil ) ; err == mgo . ErrNotFound { // Assertion failed or someone else started applying. return f . abortOrReload ( t , revnos , pull ) } else if err != nil { return err } } f . debugf ( " " , t ) return nil }
// assert verifies that all assertions in t match the content that t
// will be applied upon. If an assertion fails, the transaction state
// is changed to aborted.
assert verifies that all assertions in t match the content that t will be applied upon . If an assertion fails the transaction state is changed to aborted .