Alexander Karp
Alexander Karp

Reputation: 408

gorm get current db connection

How I can get current DB connection?

package main

import (
     "github.com/labstack/echo"
      "github.com/jinzhu/gorm"
    _ "github.com/jinzhu/gorm/dialects/mysql"
   )

 func main() {
     // Echo instance
    e := echo.New()
    db, _ := gorm.Open("mysql", "root:root@/golang")
    defer db.Close()

    gorm.AutoMigrate(&user.User{})
    e.Logger.Fatal(e.Start(":4000"))
}

And here is controller where I want to get user from db

 package controllers

 import (
  "github.com/labstack/echo"
 )

  func login(c echo.Context) error {
  username := c.QueryParam("username")
  }

how I can get db object or I need make gorm.Open one more time? Or create singleton for db object and import it?

Upvotes: 3

Views: 15280

Answers (2)

Ullaakut
Ullaakut

Reputation: 3744

The db variable that gorm.Open returns is your db handle. You just need to pass it as a *gorm.DB to whatever you want to be able to use it.

Here is an example of what you could do to pass your db handle properly to your user controller:

type UserRepository interface {
    Create(user model.User) error
}

type UserRepositoryMySQL struct {
    db *gorm.DB
}

// The repository you pass to your controller to provide
// an interface with the database
func (u *UserRepositoryMySQL) Create(user model.User) error {
    u.db.Create(&user)
    // handle errors here
    return nil
}

type UserController struct {
    users UserRepository
}

func (u *UserController) Create(ctx echo.Context) {
    var user model.User

    err := ctx.Bind(&user)
    // handle errors

    // validate user
    err := u.users.Create(user)
}

func main() {
    e := echo.New()

    db, _ := gorm.Open("mysql", "root:root@/golang")
    defer db.Close()

    userRepo := repo.UserRepositoryMySQL(db)
    userController := controller.UserController(userRepo)
    ...

    e.POST("/users", userController.Create)
    ...
    e.Logger.Fatal(e.Start(":4000"))
}

I recommend using an interface for the repository, as you might want to integrate multiple different databases later on, and it makes it easy to mock and it to test your controller.

Upvotes: 6

Himanshu
Himanshu

Reputation: 12685

There are two major ways to pass connection object. Either creating a global variable and pass it in methods as an argument you wants to use:

var db *sql.DB

func InitDB(dataSourceName string) {
    var err error
    db, err = sql.Open("postgres", dataSourceName)
    if err != nil {
        log.Panic(err)
    }

    if err = db.Ping(); err != nil {
        log.Panic(err)
    }
}

or you can create a struct and use it as method receiver to methods after creating an instance of db.

type DB struct {
   *sqlx.DB
}

func(db *DB) Get() (error)

But it should be pointer field to be used inside functions after initializing its instance once.

Upvotes: 3

Related Questions