@@ -40,13 +40,17 @@ func NewMongoDB(ctx context.Context, connectionURI, databaseName, collectionName
4040 // Create indexes for better query performance
4141 models := []mongo.IndexModel {
4242 {
43- Keys : bson.D {{Key : "name" , Value : 1 }},
44- Options : options .Index ().SetUnique (true ),
43+ Keys : bson.D {{Key : "name" , Value : 1 }},
4544 },
4645 {
4746 Keys : bson.D {{Key : "id" , Value : 1 }},
4847 Options : options .Index ().SetUnique (true ),
4948 },
49+ // add an index for the combination of name and version
50+ {
51+ Keys : bson.D {{Key : "name" , Value : 1 }, {Key : "versiondetail.version" , Value : 1 }},
52+ Options : options .Index ().SetUnique (true ),
53+ },
5054 }
5155
5256 _ , err = collection .Indexes ().CreateMany (ctx , models )
@@ -73,7 +77,9 @@ func (db *MongoDB) List(ctx context.Context, filter map[string]interface{}, curs
7377 }
7478
7579 // Convert Go map to MongoDB filter
76- mongoFilter := bson.M {}
80+ mongoFilter := bson.M {
81+ "versiondetail.islatest" : true ,
82+ }
7783 // Map common filter keys to MongoDB document paths
7884 for k , v := range filter {
7985 // Handle nested fields with dot notation
@@ -164,6 +170,53 @@ func (db *MongoDB) GetByID(ctx context.Context, id string) (*model.ServerDetail,
164170 return & entry , nil
165171}
166172
173+ // Publish adds a new ServerDetail to the database
174+ func (db * MongoDB ) Publish (ctx context.Context , serverDetail * model.ServerDetail ) error {
175+ if ctx .Err () != nil {
176+ return ctx .Err ()
177+ }
178+ // find a server detail with the same name and check that the current version is greater than the existing one
179+ filter := bson.M {
180+ "name" : serverDetail .Name ,
181+ "versiondetail.islatest" : true ,
182+ }
183+
184+ var existingEntry model.ServerDetail
185+ err := db .collection .FindOne (ctx , filter ).Decode (& existingEntry )
186+ if err != nil && err != mongo .ErrNoDocuments {
187+ return fmt .Errorf ("error checking existing entry: %w" , err )
188+ }
189+
190+ // check that the current version is greater than the existing one
191+ if serverDetail .VersionDetail .Version <= existingEntry .VersionDetail .Version {
192+ return fmt .Errorf ("version must be greater than existing version" )
193+ }
194+
195+ // update the existing entry to not be the latest version
196+ if existingEntry .ID != "" {
197+ _ , err = db .collection .UpdateOne (ctx , bson.M {"id" : existingEntry .ID }, bson.M {"$set" : bson.M {"versiondetail.islatest" : false }})
198+ if err != nil {
199+ return fmt .Errorf ("error updating existing entry: %w" , err )
200+ }
201+
202+ }
203+
204+ serverDetail .ID = uuid .New ().String ()
205+ serverDetail .VersionDetail .IsLatest = true
206+ serverDetail .VersionDetail .ReleaseDate = time .Now ().Format (time .RFC3339 )
207+
208+ // Insert the entry into the database
209+ _ , err = db .collection .InsertOne (ctx , serverDetail )
210+ if err != nil {
211+ if mongo .IsDuplicateKeyError (err ) {
212+ return ErrAlreadyExists
213+ }
214+ return fmt .Errorf ("error inserting entry: %w" , err )
215+ }
216+
217+ return nil
218+ }
219+
167220// Close closes the database connection
168221func (db * MongoDB ) Close () error {
169222 return db .client .Disconnect (context .Background ())
0 commit comments