github.com/mendersoftware/go-lib-micro@v0.0.0-20240304135804-e8e39c59b148/mongo/migrate/db.go (about) 1 // Copyright 2023 Northern.tech AS 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 package migrate 15 16 import ( 17 "context" 18 "time" 19 20 "github.com/mendersoftware/go-lib-micro/store" 21 "github.com/pkg/errors" 22 "go.mongodb.org/mongo-driver/bson" 23 "go.mongodb.org/mongo-driver/mongo" 24 mopts "go.mongodb.org/mongo-driver/mongo/options" 25 ) 26 27 // this is a small internal data layer for the migration utils, may be shared by diff migrators 28 const ( 29 DbMigrationsColl = "migration_info" 30 ) 31 32 type MigrationEntry struct { 33 Version Version `bson:"version"` 34 Timestamp time.Time `bson:"timestamp"` 35 } 36 37 // GetMigrationInfo retrieves a list of migrations applied to the db. 38 // On success the function returns the MigrationEntries present in the db 39 // sorted by the version in decending order. 40 func GetMigrationInfo(ctx context.Context, sess *mongo.Client, db string) ([]MigrationEntry, error) { 41 c := sess.Database(db).Collection(DbMigrationsColl) 42 findOpts := mopts.Find() 43 findOpts.SetSort(bson.D{{ 44 Key: "version.major", Value: -1, 45 }, { 46 Key: "version.minor", Value: -1, 47 }, { 48 Key: "version.patch", Value: -1, 49 }}) 50 51 cursor, err := c.Find(ctx, bson.M{ 52 "version": bson.M{"$exists": true}, 53 }, findOpts) 54 if cursor == nil || err != nil { 55 return nil, errors.Wrap(err, "db: failed to get migration info") 56 } 57 58 var infoArray []MigrationEntry 59 err = cursor.All(ctx, &infoArray) 60 return infoArray, err 61 } 62 63 // UpdateMigrationInfo inserts a migration entry in the migration info collection. 64 func UpdateMigrationInfo(ctx context.Context, version Version, sess *mongo.Client, db string) error { 65 c := sess.Database(db).Collection(DbMigrationsColl) 66 67 entry := MigrationEntry{ 68 Version: version, 69 Timestamp: time.Now(), 70 } 71 _, err := c.InsertOne(ctx, entry) 72 if err != nil { 73 return errors.Wrap(err, "db: failed to insert migration info") 74 } 75 // result.InsertedID (InsertOneResult) 76 77 return nil 78 } 79 80 func GetTenantDbs(ctx context.Context, client *mongo.Client, matcher store.TenantDbMatchFunc) ([]string, error) { 81 result, err := client.ListDatabaseNames(ctx, bson.M{}) 82 if err != nil { 83 return nil, err 84 } 85 86 tenantDbs := make([]string, len(result)) 87 j := 0 88 for _, db := range result { 89 if matcher(db) { 90 tenantDbs[j] = db 91 j++ 92 } 93 } 94 tenantDbs = tenantDbs[:j] 95 96 return tenantDbs, nil 97 }