Организация кода Golang aka нужно ли вызывать db.Close ()? - PullRequest
0 голосов
/ 10 июня 2018

До сих пор самой сложной частью Go было понимание того, как организовать код.На первый взгляд это кажется невероятно простым, но каждый раз, когда я пытался сделать что-либо, я сталкиваюсь с циклическим импортом или чем-то вроде «exported func Start» возвращает неэкспортированный тип models.dbStore, который может раздражать использование ».

Используя следующий код, как я называю db.Close(), или я действительно не понимаю, как я должен предоставлять базу данных для моих моделей.Вот что у меня есть:

App.go

package app

import (
    "database/sql"

    // Comment
    _ "github.com/mattn/go-sqlite3"
)

var (
    // DB The database connection
    db *sql.DB
)

// Setup Sets up the many many app settings
func Setup() {
    d, err := sql.Open("sqlite3", "./foo.db")
    if err != nil {
        panic(err)
    }

    // TODO: How does the DB get closed?
    // defer db.Close()
    db = d
}

// GetDB Returns a reference to the database
func GetDB() *sql.DB {
    return db
}

Users.go

package models

import (
    "github.com/proj/org/app"
)

// User struct
type User struct {
    ID int
}

// CreateUser Creates a user
func (u *User) CreateUser() (int64, error) {

    // For the sake of brevity just make sure you can
    // "connect" to the database
    if err := app.GetDB().Ping(); err != nil {
        panic(err)
    }

    return 1234, nil
}

main.go

package main

import (
    "fmt"
    "net/http"

    _ "github.com/mattn/go-sqlite3"
    "github.com/proj/org/app"
    "github.com/proj/org/models"
)

func homeHandler(w http.ResponseWriter, r *http.Request) {
    fmt.Fprintf(w, "You are home")
}

func subscribeHandler(w http.ResponseWriter, r *http.Request) {
    fmt.Fprintf(w, "Subscribing...")
    u := models.User{}

    u.CreateUser()

}

func main() {
    fmt.Println("Running")

    app.Setup()

    http.HandleFunc("/", homeHandler)
    http.HandleFunc("/subscribe", subscribeHandler)

    err := http.ListenAndServe(":9090", nil)
    if err != nil {
        panic(err)
    }
}

Iдумал о создании app.Shutdown(), но это не сработало бы для моего наиболее нормального варианта использования, который является CTRL-C.Казалось бы, если я не закрою базу данных, соединения с БД будут только расти ... Просто пытаюсь понять.

1 Ответ

0 голосов
/ 11 июня 2018

Нет необходимости закрывать БД.

Возвращенная БД безопасна для одновременного использования несколькими программами и поддерживает собственный пул незанятых соединений.Таким образом, функция Open должна вызываться только один раз.Редко необходимо закрывать БД.

From: https://golang.org/pkg/database/sql/#Open

Когда ваша программа завершает работу, любое открытое соединение закрывается, оно не остается открытым где-то в эфире в ожиданиичтобы ваша программа запустилась снова, поэтому не беспокойтесь о "растущих" соединениях, когда вы нажимаете CTRL-C в своем приложении.


Если, однако, вы все равно хотите закрыть его, то вы можете просто экспортироватьCloseDB работает так же, как и с GetDB.

App.go

// ...

func CloseDB() error {
    return db.Close()
}

main.go

// ...

func main() {
    // ...

    app.Setup()
    defer app.CloseDB()

    // ...

}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...