Golang标准包装结构

时间:2018-01-24 20:49:21

标签: go

我非常喜欢Go,我正在尝试使用Ben Johnson的网页创建一个结构化的应用程序。不幸的是,他的例子不是一个完整的工作应用程序。

他的网页是https://medium.com/@benbjohnson/standard-package-layout-7cdbc8391fc1

我试图使用他的方法,我不断收到“Undefined:db”错误。它没有告诉我导致错误的行,只是文件“MSSQL.go”

有人可以帮助我帮忙修复此错误吗?

使用已接受的解决方案编辑代码。

StatementPrinter.go

    package statementprinter

    type Statement struct {
      CustomerId   string
      CustomerName string
    }

    type StatementService interface {
      Statement(id string) (*Statement, error)
    }

main.go

            package main

            import (
              "fmt"
              "log"
              "github.com/ybenjolin/StatementPrinter"
              "github.com/ybenjolin/StatementPrinter/mssql"
              "database/sql"
              _ "github.com/alexbrainman/odbc"
            )

            const DB_INFO = "Driver={SQL Server};Server=cdc-edb2;Database=CostarReports;Trusted_Connection=yes;"

            var db *sql.DB

            func init() {
              var err error
              db, err = sql.Open("odbc", DB_INFO)
              if err != nil {
                log.Fatal("Error opening database connection.\n", err.Error())
              }
              err = db.Ping()
              if err != nil {
                log.Fatal("Error pinging database server.\n", err.Error())
              }
              fmt.Println("Database connection established.")
            }

            func main () {
              var err error
              defer db.Close()

              // Create services
              // Changes required here. Was ss := &statementprinter.Stat..
              ss := &mssql.StatementService{DB: db}

              // Use service
              var s *statementprinter.Statement
              s, err = ss.Statement("101583")
              if err != nil {
                log.Fatal("Query failed:", err.Error())
              }
              fmt.Printf("Statement: %+v\n", s)
            }

mssql.go

    package mssql  

    import (
      _ "github.com/alexbrainman/odbc"
      "database/sql"
      "github.com/ybenjolin/StatementPrinter"
    )

    // StatementService represents a MSSQL implementation of statemenetprinter.StatementService.
    type StatementService struct {
      DB *sql.DB
    }

    // Statement returns a statement for a given customer.
    func (s *StatementService) Statement(customer string) (*statementprinter.Statement, error) {
      var err error
      var t statementprinter.Statement
      // Changes required here. Was row := db.Query......
      row := s.DB.QueryRow(`Select Customer, CustomerName From AccountsReceivable.rptfARStatementHeader(?)`, customer)
      if row.Scan(&t.CustomerId, &t.CustomerName); err != nil {
        return nil, err
      }
      return &t, nil

1 个答案:

答案 0 :(得分:1)

这似乎只是一个错字。似乎有问题的一行是在方法

 func (s *StatementService) Statement(customer string) 

在mssql.go中,

  row := db.QueryRow(`Select Customer, CustomerName From AccountsReceivable.rptfARStatementHeader(?)`, customer)

QueryRow应该是db的方法,但db未定义。但是,在struct

type StatementService struct {
  DB *sql.DB
}

*sql.DB个实例。您使用的方法有一个*StatementService参数s。所以,我的猜测是打算访问sql.DB中的s字段,如此

func (s *StatementService) Statement(customer string) (*statementprinter.Statement, error) {
  var err error
  var t statementprinter.Statement
   //CHANGED LINE:
  row := s.DB.QueryRow(`Select Customer, CustomerName From AccountsReceivable.rptfARStatementHeader(?)`, customer)
  if row.Scan(&t.CustomerId, &t.CustomerName); err != nil {
    return nil, err
  }
  return &t, nil

然后,在main.go中调用该方法,并传递包含数据库的StatementService实例:

ss := &statementprinter.StatementService{DB: db}

我相信您需要将此行更改为

ss := &mssql.StatementService{DB: db}

因为实际的接口实现。您现在拥有的行将StatementService接口视为不能编译的结构。 main.go中的全局db在应用程序的生命周期内存在。它只是一个被复制的指针供使用。