Search code examples
sqlgoent

ent.go saying sql: databse is closed on any query


db/db.go

    func DbClient(cfg *config.Config, logger log.Logger) *ent.Client {
    // "host=<host> port=<port> user=<user> dbname=<database> password=<pass>"
    psqlInfo := fmt.Sprintf("host=%s port=%s user=%s dbname=%s password=%s",
        cfg.DB_HOST, cfg.DB_PORT, cfg.DB_USER, cfg.DB_NAME, cfg.DB_PASS)
    client, err := ent.Open("postgres", psqlInfo)
    if err != nil {
        logger.Fatal(err)
    }
    defer client.Close()
    logger.Info("Database Connected")
    if err := client.Schema.Create(context.Background()); !errors.Is(err, nil) {
        logger.Fatalf("Error: failed creating schema resources %v\n", err)
    }

    return client
}

services/userservice.go

func CreateUser(client *ent.Client, input *model.NewUser) (*ent.User, error) {
    user, err := client.Debug().User.Create().SetName(input.Name).SetUsername(input.Username).SetEmail(input.Email).SetPassword(input.Password).Save(context.Background())
    if err != nil {
        return &ent.User{}, err
    }
    return user, nil
}

ent client creating all necessary tables and showing database is connected. But when I am executing CreateUser() it is returning sql: database is closed. Can anyone tell me why this is happening?


Solution

  • There is a database connection Close call in your bootstrap code:

    func DbClient(cfg *config.Config, logger log.Logger) *ent.Client {
      // "host=<host> port=<port> user=<user> dbname=<database> password=<pass>"
      psqlInfo := fmt.Sprintf("host=%s port=%s user=%s dbname=%s password=%s",
    cfg.DB_HOST, cfg.DB_PORT, cfg.DB_USER, cfg.DB_NAME, cfg.DB_PASS)
      client, err := ent.Open("postgres", psqlInfo)
      if err != nil {
          logger.Fatal(err)
      }
      defer client.Close() // <- this one
      logger.Info("Database Connected")
      if err := client.Schema.Create(context.Background()); !errors.Is(err, nil) {
        logger.Fatalf("Error: failed creating schema resources %v\n", err)
      }
      return client
    }
    

    This call close connection after returning client. If it necessary to close a connection, close it in from the CreateUser() func.

    func CreateUser(client *ent.Client, input *model.NewUser) (*ent.User, error) {
        user, err := client.Debug().User.Create().SetName(input.Name).SetUsername(input.Username).SetEmail(input.Email).SetPassword(input.Password).Save(context.Background())
        if err != nil {
            return &ent.User{}, err
        }
        defer client.Close() // <- here
        return user, nil
    }