-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
3424e11
commit 80f4391
Showing
4 changed files
with
130 additions
and
56 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
package middlewares | ||
|
||
import ( | ||
"encoding/json" | ||
"github.com/labstack/echo/v4" | ||
"golang.org/x/net/context" | ||
"gorm.io/gorm" | ||
"net/http" | ||
"strings" | ||
) | ||
|
||
var DbContext = "db" | ||
var TxContext = "tx" | ||
|
||
type GraphQLRequest struct { | ||
Query string `json:"query"` | ||
} | ||
|
||
func TransactionMiddleware() echo.MiddlewareFunc { | ||
return func(next echo.HandlerFunc) echo.HandlerFunc { | ||
return func(c echo.Context) error { | ||
db, ok := c.Get(DbContext).(*gorm.DB) | ||
if !ok { | ||
return echo.NewHTTPError(http.StatusInternalServerError, "Database connection not found") | ||
} | ||
|
||
var gqlReq GraphQLRequest | ||
if err := json.NewDecoder(c.Request().Body).Decode(&gqlReq); err != nil { | ||
return echo.NewHTTPError(http.StatusBadRequest, "Invalid request payload") | ||
} | ||
|
||
// Check if the operation is a mutation | ||
if strings.HasPrefix(strings.TrimSpace(gqlReq.Query), "mutation") { | ||
tx := db.Begin() | ||
if tx.Error != nil { | ||
return echo.NewHTTPError(http.StatusInternalServerError, "Failed to start transaction") | ||
} | ||
|
||
defer func() { | ||
if r := recover(); r != nil { | ||
tx.Rollback() | ||
panic(r) | ||
} else if c.Response().Status >= http.StatusBadRequest { | ||
if err := tx.Rollback().Error; err != nil { | ||
c.Logger().Error("Failed to rollback transaction: ", err) | ||
} | ||
} else { | ||
if err := tx.Commit().Error; err != nil { | ||
c.Logger().Error("Failed to commit transaction: ", err) | ||
} | ||
} | ||
}() | ||
|
||
ctx := context.WithValue(c.Request().Context(), TxContext, tx) | ||
c.SetRequest(c.Request().WithContext(ctx)) | ||
} | ||
|
||
return next(c) | ||
} | ||
} | ||
} | ||
|
||
// GetDBFromContext retrieves the GORM DB transaction from the context | ||
func GetDBFromContext(ctx context.Context) *gorm.DB { | ||
tx, _ := ctx.Value(TxContext).(*gorm.DB) | ||
if tx != nil { | ||
return tx | ||
} | ||
// Fallback to the main DB connection if no transaction is found | ||
return ctx.Value(DbContext).(*gorm.DB) | ||
} |