-
Notifications
You must be signed in to change notification settings - Fork 7.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
How to Pass db to router functions #932
Comments
I usually create a middleware that sets a context value. func Site(activeSite *sites.Site) gin.HandlerFunc {
return func(c *gin.Context) {
c.Set(constants.CONTEXT_SITE, activeSite)
c.Next()
}
} r.Use(middleware.Site(site)) And then inside your handler: site := c.MustGet(constants.CONTEXT_SITE).(*sites.Site) Same concept applies to database objects :) |
@mysticmode you can put db into a custom Env type: type Env struct {
db *sql.DB
}
func (e *Env) GetHomePage(c *gin.Context) {
//e.db.Query("SELECT * FROM USER")
//omitted..
}
func (e *Env) GetSignIn(c *gin.Context) {
//omitted...
}
func (e *Env) PostSignIn(c *gin.Context) {
//omitted...
}
func main() {
db, _ := sql.Open("sqlite3", "./libreread.db")
r := gin.New()
env := &Env{db: db}
r.GET("/", env.GetHomePage)
r.GET("/signin", env.GetSignIn)
r.POST("/signin", env.PostSignIn)
} |
+ Poke the db handle into an Env struct so all the routes can access it. gin-gonic/gin#932
would this not effect performance since the environment receiver will be needed for every request which essentially makes it synchronous or at the very least is vulnerable to a data race? |
Just open db connection as global concurrency variable and get access to it from any function, goroutine etc. // DB is safe to be accessed from multiple goroutines
// https://golang.org/pkg/database/sql/#DB
var DBPointer, _ = sql.Open("sqlite3", "./libreread.db")
func DBTestHandler(c *gin.Context) {
rows, err := DBPointer.Query("select * from Products")
if err != nil {
panic(err)
}
defer rows.Close()
}
func main() {
r := gin.New()
r.GET("/test", DBTestHandler)
srv := &http.Server{
Handler: r,
Addr: "127.0.0.1:5050",
WriteTimeout: 15 * time.Second,
ReadTimeout: 15 * time.Second,
}
log.Fatal(srv.ListenAndServe())
}``` |
@McGiver- No, this is totally fine. The database object is safe to use asynchronously. And also, you should treat the struct as a holder object only / something to group your endpoints in, and not as an active data source for operations within your handler functions if that makes any sense. |
I'm opening the sqlite database in the main function
And I have these router handlers
How to pass that db value through the router handler
func PostSignin(c *gin.Context)
?So that I could avoid opening and closing the database each time in the functions.
Thanks!
The text was updated successfully, but these errors were encountered: