Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 0d09d88

Browse files
committed
feat: upgrade mongo driver v2 + go 1.26
Signed-off-by: Stefano Cappa <[email protected]>
1 parent 015155e commit 0d09d88

29 files changed

Lines changed: 269 additions & 284 deletions

Dockerfile

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# syntax=docker/dockerfile:1
2-
FROM golang:1.25-alpine AS builder
2+
FROM golang:1.26-alpine AS builder
33
RUN apk update && apk add --no-cache \
44
protoc \
55
make gcc musl-dev
@@ -21,7 +21,7 @@ RUN make deps
2121

2222
RUN make build
2323

24-
FROM golang:1.25-alpine
24+
FROM golang:1.26-alpine
2525
WORKDIR /
2626
COPY --from=builder /app/build/api-server /api-server
2727
COPY --from=builder /app/.env_template /.env

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ GitHub releases [HERE](https://github.com/home-anthill/api-server/releases)
2121

2222
Versions:
2323

24+
- 12/03/2026 - 4.0.0
2425
- 25/12/2025 - 3.0.0
2526
- 02/09/2025 - 2.0.0
2627
- 20/08/2024 - 1.3.2

api/assign_device.go

Lines changed: 12 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,10 @@ import (
1111
"github.com/gin-contrib/sessions"
1212
"github.com/gin-gonic/gin"
1313
"github.com/go-playground/validator/v10"
14-
"go.mongodb.org/mongo-driver/bson"
15-
"go.mongodb.org/mongo-driver/bson/primitive"
16-
"go.mongodb.org/mongo-driver/mongo"
17-
"go.mongodb.org/mongo-driver/mongo/options"
18-
"go.mongodb.org/mongo-driver/mongo/writeconcern"
14+
"go.mongodb.org/mongo-driver/v2/bson"
15+
"go.mongodb.org/mongo-driver/v2/mongo"
16+
"go.mongodb.org/mongo-driver/v2/mongo/options"
17+
"go.mongodb.org/mongo-driver/v2/mongo/writeconcern"
1918
"go.uber.org/zap"
2019
)
2120

@@ -51,7 +50,7 @@ func NewAssignDevice(ctx context.Context, logger *zap.SugaredLogger, client *mon
5150
func (handler *AssignDevice) PutAssignDeviceToHomeRoom(c *gin.Context) {
5251
handler.logger.Info("REST - PUT - PutAssignDeviceToHomeRoom called")
5352

54-
deviceID, errID := primitive.ObjectIDFromHex(c.Param("id"))
53+
deviceID, errID := bson.ObjectIDFromHex(c.Param("id"))
5554
if errID != nil {
5655
handler.logger.Error("REST - PUT - PutAssignDeviceToHomeRoom - wrong format of device 'id' path param")
5756
c.JSON(http.StatusBadRequest, gin.H{"error": "wrong format of device 'id' path param"})
@@ -70,8 +69,8 @@ func (handler *AssignDevice) PutAssignDeviceToHomeRoom(c *gin.Context) {
7069
c.JSON(http.StatusBadRequest, gin.H{"error": "invalid request body, these fields are not valid:" + errFields})
7170
return
7271
}
73-
homeObjID, errHomeObjID := primitive.ObjectIDFromHex(assignDeviceReq.HomeID)
74-
roomObjID, errRoomObjID := primitive.ObjectIDFromHex(assignDeviceReq.RoomID)
72+
homeObjID, errHomeObjID := bson.ObjectIDFromHex(assignDeviceReq.HomeID)
73+
roomObjID, errRoomObjID := bson.ObjectIDFromHex(assignDeviceReq.RoomID)
7574
if errHomeObjID != nil || errRoomObjID != nil {
7675
handler.logger.Error("REST - PUT - PutAssignDeviceToHomeRoom - wrong format of one of the values in body")
7776
c.JSON(http.StatusBadRequest, gin.H{"error": "wrong format of one of the values in body"})
@@ -144,7 +143,7 @@ func (handler *AssignDevice) PutAssignDeviceToHomeRoom(c *gin.Context) {
144143
// Defers ending the session after the transaction is committed or ended
145144
defer dbSession.EndSession(context.TODO())
146145

147-
_, errTrans := dbSession.WithTransaction(context.TODO(), func(sessionCtx mongo.SessionContext) (interface{}, error) {
146+
_, errTrans := dbSession.WithTransaction(context.TODO(), func(sessionCtx context.Context) (interface{}, error) {
148147
// Official `mongo-driver` documentation state: "callback may be run
149148
// multiple times during WithTransaction due to retry attempts, so it must be idempotent."
150149

@@ -164,9 +163,9 @@ func (handler *AssignDevice) PutAssignDeviceToHomeRoom(c *gin.Context) {
164163

165164
// 5. assign device with id = `deviceID` to room with id = `roomObjID` of home with id = `homeObjID`
166165
filterHome := bson.D{bson.E{Key: "_id", Value: homeObjID}}
167-
arrayFiltersRoom := options.ArrayFilters{Filters: bson.A{bson.M{"x._id": roomObjID}}}
168-
opts := options.UpdateOptions{
169-
ArrayFilters: &arrayFiltersRoom,
166+
arrayFiltersRoom := bson.A{bson.M{"x._id": roomObjID}}
167+
opts := []options.Lister[options.UpdateOneOptions]{
168+
options.UpdateOne().SetArrayFilters(arrayFiltersRoom),
170169
}
171170
update := bson.M{
172171
"$addToSet": bson.M{
@@ -177,7 +176,7 @@ func (handler *AssignDevice) PutAssignDeviceToHomeRoom(c *gin.Context) {
177176
"modifiedAt": time.Now(),
178177
},
179178
}
180-
_, errUpdate := handler.collHomes.UpdateOne(sessionCtx, filterHome, update, &opts)
179+
_, errUpdate := handler.collHomes.UpdateOne(sessionCtx, filterHome, update, opts...)
181180
if errUpdate != nil {
182181
handler.logger.Errorf("REST - PUT - PutAssignDeviceToHomeRoom - cannot assign device to room, errUpdate = %#v", errUpdate)
183182
}

api/devices.go

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,10 @@ import (
1212

1313
"github.com/gin-contrib/sessions"
1414
"github.com/gin-gonic/gin"
15-
"go.mongodb.org/mongo-driver/bson"
16-
"go.mongodb.org/mongo-driver/bson/primitive"
17-
"go.mongodb.org/mongo-driver/mongo"
18-
"go.mongodb.org/mongo-driver/mongo/options"
19-
"go.mongodb.org/mongo-driver/mongo/writeconcern"
15+
"go.mongodb.org/mongo-driver/v2/bson"
16+
"go.mongodb.org/mongo-driver/v2/mongo"
17+
"go.mongodb.org/mongo-driver/v2/mongo/options"
18+
"go.mongodb.org/mongo-driver/v2/mongo/writeconcern"
2019
"go.uber.org/zap"
2120
)
2221

@@ -98,7 +97,7 @@ func (handler *Devices) GetDevices(c *gin.Context) {
9897
func (handler *Devices) DeleteDevice(c *gin.Context) {
9998
handler.logger.Info("REST - DELETE - DeleteDevice called")
10099

101-
objectID, errID := primitive.ObjectIDFromHex(c.Param("id"))
100+
objectID, errID := bson.ObjectIDFromHex(c.Param("id"))
102101
if errID != nil {
103102
handler.logger.Error("REST - GET - DeleteDevice - wrong format of device id")
104103
c.JSON(http.StatusBadRequest, gin.H{"error": "wrong format of device id"})
@@ -154,7 +153,7 @@ func (handler *Devices) DeleteDevice(c *gin.Context) {
154153
// Defers ending the session after the transaction is committed or ended
155154
defer dbSession.EndSession(context.TODO())
156155

157-
_, errTrans := dbSession.WithTransaction(context.TODO(), func(sessionCtx mongo.SessionContext) (interface{}, error) {
156+
_, errTrans := dbSession.WithTransaction(context.TODO(), func(sessionCtx context.Context) (interface{}, error) {
158157
// Official `mongo-driver` documentation state: "callback may be run
159158
// multiple times during WithTransaction due to retry attempts, so it must be idempotent."
160159

api/devices_values.go

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,8 @@ import (
1515
"github.com/gin-contrib/sessions"
1616
"github.com/gin-gonic/gin"
1717
"github.com/go-playground/validator/v10"
18-
"go.mongodb.org/mongo-driver/bson"
19-
"go.mongodb.org/mongo-driver/bson/primitive"
20-
"go.mongodb.org/mongo-driver/mongo"
18+
"go.mongodb.org/mongo-driver/v2/bson"
19+
"go.mongodb.org/mongo-driver/v2/mongo"
2120
"go.uber.org/zap"
2221
"google.golang.org/grpc"
2322
"google.golang.org/grpc/credentials/insecure"
@@ -61,7 +60,7 @@ func NewDevicesValues(ctx context.Context, logger *zap.SugaredLogger, client *mo
6160
func (handler *DevicesValues) GetValuesDevice(c *gin.Context) {
6261
handler.logger.Info("REST - GET - GetValuesDevice called")
6362

64-
objectID, errID := primitive.ObjectIDFromHex(c.Param("id"))
63+
objectID, errID := bson.ObjectIDFromHex(c.Param("id"))
6564
if errID != nil {
6665
handler.logger.Error("REST - GET - GetValuesDevice - wrong format of the path param 'id'")
6766
c.JSON(http.StatusBadRequest, gin.H{"error": "wrong format of the path param 'id'"})
@@ -164,7 +163,7 @@ func (handler *DevicesValues) GetValuesDevice(c *gin.Context) {
164163
func (handler *DevicesValues) PostValuesDevice(c *gin.Context) {
165164
handler.logger.Info("REST - POST - PostValuesDevice called")
166165

167-
objectID, errID := primitive.ObjectIDFromHex(c.Param("id"))
166+
objectID, errID := bson.ObjectIDFromHex(c.Param("id"))
168167
if errID != nil {
169168
handler.logger.Errorf("REST - GET - PostValuesDevice - wrong format of the path param 'id', err %#v", errID)
170169
c.JSON(http.StatusBadRequest, gin.H{"error": "wrong format of the path param 'id'"})
@@ -281,7 +280,7 @@ func (handler *DevicesValues) sendViaGrpc(device *models.Device, featureStates [
281280
return errSend
282281
}
283282

284-
func (handler *DevicesValues) getDevice(deviceID primitive.ObjectID) (models.Device, error) {
283+
func (handler *DevicesValues) getDevice(deviceID bson.ObjectID) (models.Device, error) {
285284
handler.logger.Debug("getDevice - searching device with objectId: ", deviceID)
286285
var device models.Device
287286
err := handler.collDevices.FindOne(handler.ctx, bson.M{

api/fcm_token.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@ import (
1313
"github.com/gin-contrib/sessions"
1414
"github.com/gin-gonic/gin"
1515
"github.com/go-playground/validator/v10"
16-
"go.mongodb.org/mongo-driver/bson"
17-
"go.mongodb.org/mongo-driver/mongo"
16+
"go.mongodb.org/mongo-driver/v2/bson"
17+
"go.mongodb.org/mongo-driver/v2/mongo"
1818
"go.uber.org/zap"
1919
)
2020

api/homes.go

Lines changed: 27 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,10 @@ import (
1111
"github.com/gin-contrib/sessions"
1212
"github.com/gin-gonic/gin"
1313
"github.com/go-playground/validator/v10"
14-
"go.mongodb.org/mongo-driver/bson"
15-
"go.mongodb.org/mongo-driver/bson/primitive"
16-
"go.mongodb.org/mongo-driver/mongo"
17-
"go.mongodb.org/mongo-driver/mongo/options"
18-
"go.mongodb.org/mongo-driver/mongo/writeconcern"
14+
"go.mongodb.org/mongo-driver/v2/bson"
15+
"go.mongodb.org/mongo-driver/v2/mongo"
16+
"go.mongodb.org/mongo-driver/v2/mongo/options"
17+
"go.mongodb.org/mongo-driver/v2/mongo/writeconcern"
1918
"go.uber.org/zap"
2019
)
2120

@@ -146,15 +145,15 @@ func (handler *Homes) PostHome(c *gin.Context) {
146145

147146
// create a Home document object
148147
var home models.Home
149-
home.ID = primitive.NewObjectID()
148+
home.ID = bson.NewObjectID()
150149
home.Name = newHome.Name
151150
home.Location = newHome.Location
152151
home.CreatedAt = newDate
153152
home.ModifiedAt = newDate
154153
home.Rooms = []models.Room{}
155154
for i := 0; i < len(newHome.Rooms); i++ {
156155
var room models.Room
157-
room.ID = primitive.NewObjectID()
156+
room.ID = bson.NewObjectID()
158157
room.Name = newHome.Rooms[i].Name
159158
room.Floor = newHome.Rooms[i].Floor
160159
room.CreatedAt = newDate
@@ -172,7 +171,7 @@ func (handler *Homes) PostHome(c *gin.Context) {
172171
// Defers ending the session after the transaction is committed or ended
173172
defer dbSession.EndSession(context.TODO())
174173

175-
_, errTrans := dbSession.WithTransaction(context.TODO(), func(sessionCtx mongo.SessionContext) (interface{}, error) {
174+
_, errTrans := dbSession.WithTransaction(context.TODO(), func(sessionCtx context.Context) (interface{}, error) {
176175
// Official `mongo-driver` documentation state: "callback may be run
177176
// multiple times during WithTransaction due to retry attempts, so it must be idempotent."
178177
_, err1 := handler.collHomes.InsertOne(sessionCtx, home)
@@ -204,7 +203,7 @@ func (handler *Homes) PostHome(c *gin.Context) {
204203
func (handler *Homes) PutHome(c *gin.Context) {
205204
handler.logger.Info("REST - PUT - PutHome called")
206205

207-
objectID, errID := primitive.ObjectIDFromHex(c.Param("id"))
206+
objectID, errID := bson.ObjectIDFromHex(c.Param("id"))
208207
if errID != nil {
209208
handler.logger.Error("REST - PUT - PutHome - wrong format of the path param 'id'")
210209
c.JSON(http.StatusBadRequest, gin.H{"error": "wrong format of the path param 'id'"})
@@ -257,7 +256,7 @@ func (handler *Homes) PutHome(c *gin.Context) {
257256
func (handler *Homes) DeleteHome(c *gin.Context) {
258257
handler.logger.Info("REST - DELETE - DeleteHome called")
259258

260-
objectID, errID := primitive.ObjectIDFromHex(c.Param("id"))
259+
objectID, errID := bson.ObjectIDFromHex(c.Param("id"))
261260
if errID != nil {
262261
handler.logger.Error("REST - DELETE - DeleteHome - wrong format of the path param 'id'")
263262
c.JSON(http.StatusBadRequest, gin.H{"error": "wrong format of the path param 'id'"})
@@ -281,7 +280,7 @@ func (handler *Homes) DeleteHome(c *gin.Context) {
281280
c.JSON(http.StatusUnauthorized, gin.H{"error": "cannot find profile in session"})
282281
return
283282
}
284-
var newHomes []primitive.ObjectID
283+
var newHomes []bson.ObjectID
285284
for _, homeID := range profile.Homes {
286285
if homeID != objectID {
287286
newHomes = append(newHomes, homeID)
@@ -298,7 +297,7 @@ func (handler *Homes) DeleteHome(c *gin.Context) {
298297
// Defers ending the session after the transaction is committed or ended
299298
defer dbSession.EndSession(context.TODO())
300299

301-
_, errTrans := dbSession.WithTransaction(context.TODO(), func(sessionCtx mongo.SessionContext) (interface{}, error) {
300+
_, errTrans := dbSession.WithTransaction(context.TODO(), func(sessionCtx context.Context) (interface{}, error) {
302301
// Official `mongo-driver` documentation state: "callback may be run
303302
// multiple times during WithTransaction due to retry attempts, so it must be idempotent."
304303
_, errUpd := handler.collProfiles.UpdateOne(sessionCtx, bson.M{
@@ -333,7 +332,7 @@ func (handler *Homes) DeleteHome(c *gin.Context) {
333332
func (handler *Homes) GetRooms(c *gin.Context) {
334333
handler.logger.Info("REST - GET - GetRooms called")
335334

336-
objectID, errID := primitive.ObjectIDFromHex(c.Param("id"))
335+
objectID, errID := bson.ObjectIDFromHex(c.Param("id"))
337336
if errID != nil {
338337
handler.logger.Error("REST - GET - GetRooms - wrong format of the path param 'id'")
339338
c.JSON(http.StatusBadRequest, gin.H{"error": "wrong format of the path param 'id'"})
@@ -366,7 +365,7 @@ func (handler *Homes) GetRooms(c *gin.Context) {
366365
func (handler *Homes) PostRoom(c *gin.Context) {
367366
handler.logger.Info("REST - POST - PostRoom called")
368367

369-
objectID, errID := primitive.ObjectIDFromHex(c.Param("id"))
368+
objectID, errID := bson.ObjectIDFromHex(c.Param("id"))
370369
if errID != nil {
371370
handler.logger.Error("REST - POST - PostRoom - wrong format of the path param 'id'")
372371
c.JSON(http.StatusBadRequest, gin.H{"error": "wrong format of the path param 'id'"})
@@ -412,7 +411,7 @@ func (handler *Homes) PostRoom(c *gin.Context) {
412411

413412
// create a Home document object
414413
var room models.Room
415-
room.ID = primitive.NewObjectID()
414+
room.ID = bson.NewObjectID()
416415
room.Name = newRoom.Name
417416
room.Floor = newRoom.Floor
418417
room.CreatedAt = newDate
@@ -442,8 +441,8 @@ func (handler *Homes) PostRoom(c *gin.Context) {
442441
func (handler *Homes) PutRoom(c *gin.Context) {
443442
handler.logger.Info("REST - PUT - PutRoom called")
444443

445-
homeID, errID := primitive.ObjectIDFromHex(c.Param("id"))
446-
roomID, errRid := primitive.ObjectIDFromHex(c.Param("rid"))
444+
homeID, errID := bson.ObjectIDFromHex(c.Param("id"))
445+
roomID, errRid := bson.ObjectIDFromHex(c.Param("rid"))
447446
if errID != nil || errRid != nil {
448447
handler.logger.Error("REST - PUT - PutRoom - wrong format of one of the path params")
449448
c.JSON(http.StatusBadRequest, gin.H{"error": "wrong format of one of the path params"})
@@ -498,12 +497,11 @@ func (handler *Homes) PutRoom(c *gin.Context) {
498497
}
499498

500499
// update room
501-
filter := bson.D{primitive.E{Key: "_id", Value: homeID}}
502-
arrayFilters := options.ArrayFilters{Filters: bson.A{bson.M{"x._id": roomID}}}
503-
upsert := true
504-
opts := options.UpdateOptions{
505-
ArrayFilters: &arrayFilters,
506-
Upsert: &upsert,
500+
filter := bson.D{bson.E{Key: "_id", Value: homeID}}
501+
arrayFilters := bson.A{bson.M{"x._id": roomID}}
502+
opts := []options.Lister[options.UpdateOneOptions]{
503+
options.UpdateOne().SetUpsert(true),
504+
options.UpdateOne().SetArrayFilters(arrayFilters),
507505
}
508506
update := bson.M{
509507
"$set": bson.M{
@@ -512,7 +510,7 @@ func (handler *Homes) PutRoom(c *gin.Context) {
512510
"rooms.$[x].modifiedAt": time.Now(),
513511
},
514512
}
515-
_, errUpdate := handler.collHomes.UpdateOne(handler.ctx, filter, update, &opts)
513+
_, errUpdate := handler.collHomes.UpdateOne(handler.ctx, filter, update, opts...)
516514
if errUpdate != nil {
517515
handler.logger.Errorf("REST - PUT - PutRoom - Cannot update a room in DB, errUpdate = %#v", errUpdate)
518516
c.JSON(http.StatusInternalServerError, gin.H{"error": "cannot update room"})
@@ -526,8 +524,8 @@ func (handler *Homes) PutRoom(c *gin.Context) {
526524
func (handler *Homes) DeleteRoom(c *gin.Context) {
527525
handler.logger.Info("REST - DELETE - DeleteRoom called")
528526

529-
objectID, errID := primitive.ObjectIDFromHex(c.Param("id"))
530-
objectRid, errRid := primitive.ObjectIDFromHex(c.Param("rid"))
527+
objectID, errID := bson.ObjectIDFromHex(c.Param("id"))
528+
objectRid, errRid := bson.ObjectIDFromHex(c.Param("rid"))
531529
if errID != nil || errRid != nil {
532530
handler.logger.Error("REST - PUT - PutRoom - wrong format of one of the path params")
533531
c.JSON(http.StatusBadRequest, gin.H{"error": "wrong format of one of the path params"})
@@ -568,10 +566,10 @@ func (handler *Homes) DeleteRoom(c *gin.Context) {
568566
}
569567

570568
// delete room by id
571-
filter := bson.D{primitive.E{Key: "_id", Value: objectID}}
569+
filter := bson.D{bson.E{Key: "_id", Value: objectID}}
572570
update := bson.M{
573571
"$pull": bson.M{
574-
"rooms": bson.D{primitive.E{Key: "_id", Value: objectRid}},
572+
"rooms": bson.D{bson.E{Key: "_id", Value: objectRid}},
575573
},
576574
}
577575
_, err2 := handler.collHomes.UpdateOne(handler.ctx, filter, update)
@@ -584,7 +582,7 @@ func (handler *Homes) DeleteRoom(c *gin.Context) {
584582
c.JSON(http.StatusOK, gin.H{"message": "room has been deleted"})
585583
}
586584

587-
func (handler *Homes) isHomeOwnedBy(session sessions.Session, objectID primitive.ObjectID) bool {
585+
func (handler *Homes) isHomeOwnedBy(session sessions.Session, objectID bson.ObjectID) bool {
588586
// you can update a home only if you are the owner of that home
589587
// read profile from db. This is required to get fresh data from db, because data in session could be outdated
590588

api/login_github.go

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,8 @@ import (
1717
"github.com/gin-gonic/gin"
1818
"github.com/google/go-github/github"
1919
"github.com/google/uuid"
20-
"go.mongodb.org/mongo-driver/bson"
21-
"go.mongodb.org/mongo-driver/bson/primitive"
22-
"go.mongodb.org/mongo-driver/mongo"
20+
"go.mongodb.org/mongo-driver/v2/bson"
21+
"go.mongodb.org/mongo-driver/v2/mongo"
2322
"go.uber.org/zap"
2423
"golang.org/x/oauth2"
2524
oauth2gh "golang.org/x/oauth2/github"
@@ -182,11 +181,11 @@ func (handler *LoginGitHub) OauthAuth() gin.HandlerFunc {
182181
currentDate := time.Now()
183182
// profile not found, so create a new profile
184183
var newProfile models.Profile
185-
newProfile.ID = primitive.NewObjectID()
184+
newProfile.ID = bson.NewObjectID()
186185
newProfile.Github = dbGithubUser
187186
newProfile.APIToken = uuid.NewString()
188-
newProfile.Homes = []primitive.ObjectID{} // empty slice of ObjectIDs
189-
newProfile.Devices = []primitive.ObjectID{} // empty slice of ObjectIDs
187+
newProfile.Homes = []bson.ObjectID{} // empty slice of ObjectIDs
188+
newProfile.Devices = []bson.ObjectID{} // empty slice of ObjectIDs
190189
newProfile.CreatedAt = currentDate
191190
newProfile.ModifiedAt = currentDate
192191

0 commit comments

Comments
 (0)