@@ -27,6 +27,7 @@ import (
27
27
"time"
28
28
29
29
"github.com/juju/clock"
30
+ "github.com/juju/collections/set"
30
31
"github.com/juju/errors"
31
32
"github.com/juju/loggo"
32
33
"github.com/juju/retry"
@@ -750,6 +751,10 @@ func clearDatabases(session *mgo.Session) error {
750
751
}
751
752
752
753
func clearCollections (db * mgo.Database ) error {
754
+ capped , err := listCappedCollections (db )
755
+ if err != nil {
756
+ return errors .Annotatef (err , "getting capped collection list" )
757
+ }
753
758
collectionNames , err := db .CollectionNames ()
754
759
if err != nil {
755
760
return errors .Trace (err )
@@ -760,11 +765,7 @@ func clearCollections(db *mgo.Database) error {
760
765
}
761
766
collection := db .C (name )
762
767
clearFunc := clearNormalCollection
763
- capped , err := isCapped (collection )
764
- if err != nil {
765
- return errors .Trace (err )
766
- }
767
- if capped {
768
+ if capped .Contains (name ) {
768
769
clearFunc = clearCappedCollection
769
770
}
770
771
err = clearFunc (collection )
@@ -775,21 +776,48 @@ func clearCollections(db *mgo.Database) error {
775
776
return nil
776
777
}
777
778
778
- func isCapped (collection * mgo.Collection ) (bool , error ) {
779
- result := bson.M {}
780
- err := collection .Database .Run (bson.D {{"collstats" , collection .Name }}, & result )
779
+ func listCappedCollections (db * mgo.Database ) (set.Strings , error ) {
780
+ // Mostly pulled from mgo.DB.ListCollections
781
+ names := set .NewStrings ()
782
+ var result struct {
783
+ Collections []bson.Raw
784
+ Cursor struct {
785
+ FirstBatch []bson.Raw `bson:"firstBatch"`
786
+ NextBatch []bson.Raw `bson:"nextBatch"`
787
+ NS string `bson:"ns"`
788
+ ID int64 `bson:"id"`
789
+ }
790
+ }
791
+ err := db .Run (bson.D {{"listCollections" , 1 }, {"cursor" , bson.D {{"batchSize" , 10 }}}}, & result )
781
792
if err != nil {
782
- return false , errors .Trace (err )
793
+ return nil , errors .Trace (err )
783
794
}
784
- value , found := result [ "capped" ]
785
- if ! found {
786
- return false , nil
795
+ firstBatch := result . Collections
796
+ if firstBatch == nil {
797
+ firstBatch = result . Cursor . FirstBatch
787
798
}
788
- capped , ok := value .(bool )
789
- if ! ok {
790
- return false , errors .Errorf ("unexpected type for capped: %v" , value )
799
+ var iter * mgo.Iter
800
+ ns := strings .SplitN (result .Cursor .NS , "." , 2 )
801
+ if len (ns ) < 2 {
802
+ iter = db .C ("" ).NewIter (nil , firstBatch , result .Cursor .ID , nil )
803
+ } else {
804
+ iter = db .Session .DB (ns [0 ]).C (ns [1 ]).NewIter (nil , firstBatch , result .Cursor .ID , nil )
805
+ }
806
+ var coll struct {
807
+ Name string `bson:"name"`
808
+ Options struct {
809
+ Capped bool `bson:"capped"`
810
+ } `bson:"options"`
811
+ }
812
+ for iter .Next (& coll ) {
813
+ if coll .Options .Capped {
814
+ names .Add (coll .Name )
815
+ }
816
+ }
817
+ if err := iter .Close (); err != nil {
818
+ return nil , errors .Trace (err )
791
819
}
792
- return capped , nil
820
+ return names , nil
793
821
}
794
822
795
823
func clearNormalCollection (collection * mgo.Collection ) error {
0 commit comments