2015-07-03 2 views
1

У меня есть пакет базы данных, содержащий следующий код.Как высушить код базы данных

package database 

import (
    "log" 

    "github.com/jinzhu/gorm" 
    // required by gorm 
    _ "github.com/mattn/go-sqlite3" 
) 

type Podcast struct { 
    ID  int `sql:"index"` 
    Title string 
    RssURL string `sql:"unique_index"` 
    Paused bool 
    Episodes []Episode 
} 

type Episode struct { 
    ID   int `sql:"index"` 
    PodcastID int 
    Title  string 
    EnclosureURL string `sql:"unique_index"` 
    Downloaded bool 
    GUID   string `sql:"unique_index"` 
    PubDate  string 
} 

func DBSession() (db gorm.DB) { 
    sqliteSession, err := gorm.Open("sqlite3", cache.db) 
    if err != nil { 
     log.Fatal(err) 
    } 

    return sqliteSession 
} 

Вслед за кучей методов, которые начинаются со следующего кода.

FindSomethingByID(id int) { 
    db := DBSession() 
    db.LogMode(false) 

    // code 
} 

FindSomethingElse { 
    db := DBSession() 
    db.LogMode(false) 

    // code 
} 

Вызов DBSession и настройка LogMode в каждой функции кажется плохим. Я просто не знаю, как это сделать лучше. Может ли кто-нибудь помочь?

ответ

5

Вызов gorm.Open внутри каждой функции не очень эффективен: Open открывает новый пул соединений и должен вызываться только один раз (see the database/sql docs, который охватывает обводку).

Простым улучшением является создание глобального gorm.DB, его инициализировать в init() из всех ваших функций - например,

package database 

var db gorm.DB 

func init() { 
    var err error 
    // Note we use an = and not a := as our variables 
    // are already initialised 
    db, err = gorm.Open("sqlite3", "cache.db") 
    if err != nil { 
     log.Fatal(err) 
    } 

    // Turn off logging globally 
    db.LogMode(false) 
} 

FindSomethingByID(id int) { 
    err := db.Query("...") 
    // code 
} 

Это быстрый выигрыш и сокращение повторения.

В более крупном приложении, как правило, имеет смысл передавать зависимости (например, пулы БД, параметры конфигурации и т. Д.) Более подробно, обертывая их типами и создавая пользовательские обработчики.

Вы также можете инициализировать соединение в вашем package main и передать *gorm.DB ваших database пакета через func New(db *gorm.DB) функцию, которая устанавливает частные, уровень пакета переменной.

+0

Я изменил свой код, как вы упомянули выше, но я получаю сообщение об ошибке сейчас src/database/database.go: 48: не могу назначить gorm.DB для db (type * gorm.DB) в нескольких присваиваниях – gregf

+0

I ' Ве сделал редактирование. 'gorm' возвращает значение, а не указатель, в отличие от большинства других пакетов, которые обертывают базу данных/sql. – elithrar

+0

Строка 48 - это db, err = gorm.Open («sqlite3», «cache.db») – gregf

0

Наиболее очевидное упрощение было бы переместить db.LogMode(false) вызова в функцию DBSession(), и дать DBSession() короче имя, как DB():

func DB() (db gorm.DB) { 
    sqliteSession, err := gorm.Open("sqlite3", cache.db) 
    if err != nil { 
     log.Fatal(err) 
    } 

    sqliteSession.LogMode(false) 
    return sqliteSession 
} 

И использовать его:

FindSomethingByID(id int) { 
    db := DB() 
    // code 
} 

Теперь есть только 1 строка в каждой из ваших функций, используя сеанс db, один простой вызов функции. Вы не можете сделать это короче, если вам всегда нужен новый сеанс db.

Смежные вопросы