diff --git a/database/database.go b/database/database.go index ca71d16a..184d0d30 100644 --- a/database/database.go +++ b/database/database.go @@ -131,7 +131,7 @@ func NewCustomDB(ctx context.Context, dbName string, creds DBCredentials, logger if logger == nil { logger = &logrus.Logger{} } - err = ensureDBSchema(ctx, database, logger) + err = ensureDBSchema(ctx, database, Schema, logger) if err != nil { return nil, err } @@ -188,114 +188,7 @@ func connectionString(creds DBCredentials) string { // creates them if needed. // See https://docs.mongodb.com/manual/indexes/ // See https://docs.mongodb.com/manual/core/index-unique/ -func ensureDBSchema(ctx context.Context, db *mongo.Database, log *logrus.Logger) error { - // schema defines a mapping between a collection name and the indexes that - // must exist for that collection. - schema := map[string][]mongo.IndexModel{ - collUsers: { - { - Keys: bson.D{{"sub", 1}}, - Options: options.Index().SetName("sub_unique").SetUnique(true), - }, - }, - collSkylinks: { - { - Keys: bson.D{{"skylink", 1}}, - Options: options.Index().SetName("skylink_unique").SetUnique(true), - }, - }, - collUploads: { - { - Keys: bson.D{{"user_id", 1}}, - Options: options.Index().SetName("user_id"), - }, - { - Keys: bson.D{{"skylink_id", 1}}, - Options: options.Index().SetName("skylink_id"), - }, - }, - collDownloads: { - { - Keys: bson.D{{"user_id", 1}}, - Options: options.Index().SetName("user_id"), - }, - { - Keys: bson.D{{"skylink_id", 1}}, - Options: options.Index().SetName("skylink_id"), - }, - }, - collRegistryReads: { - { - Keys: bson.D{{"user_id", 1}}, - Options: options.Index().SetName("user_id"), - }, - }, - collRegistryWrites: { - { - Keys: bson.D{{"user_id", 1}}, - Options: options.Index().SetName("user_id"), - }, - }, - collEmails: { - { - Keys: bson.D{{"failed_attempts", 1}}, - Options: options.Index().SetName("failed_attempts"), - }, - { - Keys: bson.D{{"locked_by", 1}}, - Options: options.Index().SetName("locked_by"), - }, - { - Keys: bson.D{{"sent_at", 1}}, - Options: options.Index().SetName("sent_at"), - }, - { - Keys: bson.D{{"sent_by", 1}}, - Options: options.Index().SetName("sent_by"), - }, - }, - collChallenges: { - { - Keys: bson.D{{"challenge", 1}}, - Options: options.Index().SetName("challenge"), - }, - { - Keys: bson.D{{"type", 1}}, - Options: options.Index().SetName("type"), - }, - { - Keys: bson.D{{"expires_at", 1}}, - Options: options.Index().SetName("expires_at"), - }, - }, - collUnconfirmedUserUpdates: { - { - Keys: bson.D{{"challenge_id", 1}}, - Options: options.Index().SetName("challenge_id"), - }, - { - Keys: bson.D{{"expires_at", 1}}, - Options: options.Index().SetName("expires_at"), - }, - }, - collConfiguration: { - { - Keys: bson.D{{"key", 1}}, - Options: options.Index().SetName("key_unique").SetUnique(true), - }, - }, - collAPIKeys: { - { - Keys: bson.D{{"key", 1}}, - Options: options.Index().SetName("key_unique").SetUnique(true), - }, - { - Keys: bson.D{{"user_id", 1}}, - Options: options.Index().SetName("user_id"), - }, - }, - } - +func ensureDBSchema(ctx context.Context, db *mongo.Database, schema map[string][]mongo.IndexModel, log *logrus.Logger) error { for collName, models := range schema { coll, err := ensureCollection(ctx, db, collName) if err != nil { diff --git a/database/schema.go b/database/schema.go new file mode 100644 index 00000000..34138e35 --- /dev/null +++ b/database/schema.go @@ -0,0 +1,116 @@ +package database + +import ( + "go.mongodb.org/mongo-driver/bson" + "go.mongodb.org/mongo-driver/mongo" + "go.mongodb.org/mongo-driver/mongo/options" +) + +var ( + // Schema defines a mapping between a collection name and the indexes that + // must exist for that collection. + Schema = map[string][]mongo.IndexModel{ + collUsers: { + { + Keys: bson.D{{"sub", 1}}, + Options: options.Index().SetName("sub_unique").SetUnique(true), + }, + }, + collSkylinks: { + { + Keys: bson.D{{"skylink", 1}}, + Options: options.Index().SetName("skylink_unique").SetUnique(true), + }, + }, + collUploads: { + { + Keys: bson.D{{"user_id", 1}}, + Options: options.Index().SetName("user_id"), + }, + { + Keys: bson.D{{"skylink_id", 1}}, + Options: options.Index().SetName("skylink_id"), + }, + }, + collDownloads: { + { + Keys: bson.D{{"user_id", 1}}, + Options: options.Index().SetName("user_id"), + }, + { + Keys: bson.D{{"skylink_id", 1}}, + Options: options.Index().SetName("skylink_id"), + }, + }, + collRegistryReads: { + { + Keys: bson.D{{"user_id", 1}}, + Options: options.Index().SetName("user_id"), + }, + }, + collRegistryWrites: { + { + Keys: bson.D{{"user_id", 1}}, + Options: options.Index().SetName("user_id"), + }, + }, + collEmails: { + { + Keys: bson.D{{"failed_attempts", 1}}, + Options: options.Index().SetName("failed_attempts"), + }, + { + Keys: bson.D{{"locked_by", 1}}, + Options: options.Index().SetName("locked_by"), + }, + { + Keys: bson.D{{"sent_at", 1}}, + Options: options.Index().SetName("sent_at"), + }, + { + Keys: bson.D{{"sent_by", 1}}, + Options: options.Index().SetName("sent_by"), + }, + }, + collChallenges: { + { + Keys: bson.D{{"challenge", 1}}, + Options: options.Index().SetName("challenge"), + }, + { + Keys: bson.D{{"type", 1}}, + Options: options.Index().SetName("type"), + }, + { + Keys: bson.D{{"expires_at", 1}}, + Options: options.Index().SetName("expires_at"), + }, + }, + collUnconfirmedUserUpdates: { + { + Keys: bson.D{{"challenge_id", 1}}, + Options: options.Index().SetName("challenge_id"), + }, + { + Keys: bson.D{{"expires_at", 1}}, + Options: options.Index().SetName("expires_at"), + }, + }, + collConfiguration: { + { + Keys: bson.D{{"key", 1}}, + Options: options.Index().SetName("key_unique").SetUnique(true), + }, + }, + collAPIKeys: { + { + Keys: bson.D{{"key", 1}}, + Options: options.Index().SetName("key_unique").SetUnique(true), + }, + { + Keys: bson.D{{"user_id", 1}}, + Options: options.Index().SetName("user_id"), + }, + }, + } +)